-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture Note: Authorization
AI Agent --(transport: stdio | HTTP)--> gramps-web-mcp-rs --(auth)--> Gramps Web API
Authentication from the MCP server to Gramps Web uses Gramps Web's standard mechanism (username/password → JWT, auto-refreshed). One thing worth calling out explicitly: the credentials are held on the MCP side, not per-caller — so anyone who can reach the MCP server inherits whatever access that one Gramps Web account has. There's no per-agent identity once you're past the MCP boundary; the MCP server is the Gramps Web user.
This note is about the other boundary — AI agent → MCP server.
On stdio transport this isn't a network concern: the client launched the
server as a subprocess, and the OS process boundary is the trust boundary.
On http transport, this only becomes a problem when the MCP endpoint is
exposed beyond a private/local network — i.e. the case we're actually
addressing here is a server with the MCP port reachable from the public
internet, not a homelab box only reachable over LAN or VPN.
The MCP specification (2025-03-26 and later) treats any remote (HTTP) MCP server as an OAuth 2.1 resource server. The full model includes:
- Protected Resource Metadata discovery (RFC 9728,
/.well-known/oauth-protected-resource) - Authorization Server Metadata / OIDC discovery (RFC 8414)
- Client registration (pre-registration, CIMD, or Dynamic Client Registration)
- Authorization Code flow with mandatory PKCE (S256)
- Resource Indicators (RFC 8707) to bind tokens to this specific server
- Token validation, scope handling, step-up authorization on insufficient scope
This is the right model for a multi-tenant or enterprise MCP server, where many different users and clients need independently revocable, scoped access, and where an existing IdP (Okta, Entra, etc.) is the source of truth for identity. For a self-hosted, single-user genealogy server, this is significant machinery for no real benefit: one trusted operator, one (or a small, manually-managed set of) AI client(s), no multi-tenancy, no IdP to integrate with. Standing up a full Authorization Server to gate a personal Gramps tree is disproportionate to the actual threat model.
Use a static bearer token (MCP_AUTH_TOKEN) checked on every request to /mcp:
- Generated once by the operator:
openssl rand -hex 32(256 bits of entropy) - Set as an environment variable on the server, given to the AI client as a header
- If
MCP_AUTH_TOKENis unset (or empty), auth is disabled and a warning is logged — intended only for deployments already confined to a trusted network - Layered with
MCP_ALLOWED_HOSTS(Hostheader allowlist) for basic DNS-rebinding protection, in line with the spec's Origin-validation guidance
It's functionally an API key: one shared secret, compared by equality, for the one deployment. Trade-off, made deliberately: this is not spec-compliant with MCP's mandated OAuth 2.1 model for internet-facing servers — it's a simplification for a use case the full spec wasn't designed around, shared by a large share of self-hosted MCP servers in practice. It should not be used beyond a single trusted operator's personal deployment.
See docs/setup-server.md for the full deployment walkthrough.