MCP server that gives AI agents a verified identity via BankID
This STDIO-based BankID authentication server has solid naming and descriptions, but lacks critical features for production use. All three tools are clearly named (start_authentication, complete_authentication, authenticated_fetch) and have descriptive text explaining their purpose. However, the server suffers from: (1) missing output schema documentation, no structured output types are declared, forcing LLMs to infer response structures; (2) incomplete parameter descriptions, the 'headers' parameter in authenticated_fetch lacks guidance on format/constraints; (3) no error categorization or recovery guidance, errors are returned as plain JSON with minimal actionable detail; (4) missing idempotence hints, complete_authentication appears idempotent (polling) but is not explicitly marked; (5) stateful token caching without session isolation, if multiple agents use the server concurrently, the global cachedToken variable creates a race condition and identity confusion. The descriptions themselves are good (115-180 chars, explaining prerequisites and expected flow), but the lack of schema documentation and error handling patterns significantly limits LLM confidence in tool composition.
Make an HTTP request with the agent's agentID identity token automatically attached as 'X-AgentID-Token'. The user must complete authentication first via start_authentication and complete_authentication.
Poll agentID for BankID authentication completion. Call this after the user has been shown the authUrl from start_authentication. It will poll every 3 seconds until the user completes BankID, then cache the JWT.
Start a BankID authentication session via agentID. Returns an authUrl that the user must open to complete BankID on their phone, and a sessionId to pass to complete_authentication.
No output schema documentation for any tool. Tools return JSON via textResult() but callers cannot determine the field names, types, or structure they should expect. LLMs must infer response shapes from implementation, increasing hallucination risk.
Global stateful token cache (cachedToken, tokenExpiresAt) without per-agent or per-session isolation. If multiple agents/users invoke this server concurrently, they share the same JWT token, causing authentication collisions and identity confusion.
Error responses lack actionable recovery guidance. Errors are returned as plain JSON (e.g., 'BankID authentication failed') without telling the LLM what to do next (retry? ask user? give up?). No error categorization (retryable vs fatal).
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 49 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 45 | - | v1 |
'headers' parameter in authenticated_fetch lacks type and format guidance. Description says 'Additional headers to include' but does not specify the exact type (Record<string, string>), whether all headers are allowed, or that X-AgentID-Token will be automatically set (users might try to override it).
No idempotence or destructiveness hints. complete_authentication is idempotent (polling the same sessionId multiple times is safe) but this is not declared. authenticated_fetch can be destructive (DELETE, POST with side effects) but has no destructiveHint annotation.
No timeout parameter or limit on authenticated_fetch. The tool can hang indefinitely if the downstream HTTP endpoint is slow or unresponsive, blocking the agent. Consider adding a timeout_ms parameter with a default (e.g., 30000).