Proof that a verified human is accountable for what an AI agent does. An MCP server gated by Door with layered authentication policies for different tool risk levels.
Project Door demonstrates a sophisticated access-control architecture but falls short on tool definition quality. All 4 tools have descriptions and basic schemas, but parameter descriptions are entirely absent. The ping tool is a deprecated MCP pattern (removed in 2026-07-28). Input schemas lack parameter-level type information and constraints. Descriptions are terse (10-100 chars) and do not explain WHEN to use each tool or what downstream actions they enable. No output schemas are documented. Error handling is implicit in the guard logic but not surfaced to the LLM. The server prioritizes security policy over agent usability.
List invoices for the accountable principal.
Health check. No attribution required.
Send a payment. Requires live human presence.
High-value wire. Live presence + biometric + treasury secret + 2 approvals + 15m cooling-off.
All parameter schemas lack descriptions. The 'amount' and 'to' parameters have no guidance on valid ranges, formats, or constraints. LLMs cannot infer whether amount is in cents or dollars, or whether 'to' expects an account number, email, or wire routing code.
No output schemas documented. Responses are text-only ('content' arrays with 'type: text'). LLMs cannot parse structured results or extract IDs for chaining. E.g., list_invoices returns a count but no invoice objects, IDs, or amounts.
ping tool is a deprecated MCP pattern (removed in spec 2026-07-28). It served health checks in older protocols but is no longer part of the standard. Remove it or replace with a stateless health endpoint.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 55 | 2026-07-28+ | v2 |
Parameter schemas use empty properties objects. E.g., list_invoices has {'type': 'object', 'properties': {}}, no indication of required fields, defaults, or constraints. This violates JSON Schema best practices and leaves LLMs guessing.
Error handling is opaque to the LLM. The guard.check() verdict returns HTTP status codes and www-authenticate headers, but the LLM sees only the HTTP response. No recovery guidance (e.g., 'Biometric required, retry with device unlock') is embedded in error messages.