Skip to content

Supported specifications

The fastgeoapi MCP server plays two roles in an identity-secured MCP deployment: it is an MCP Server (the protected resource AI agents talk to) and it embeds its own OAuth Authorization Server (the OIDC proxy that faces MCP clients, independent of the upstream Identity Provider). The matrix below describes what each role supports, following the structure used by the OpenID AIIM interoperability program.

Support matrix

Legend: βœ… supported and verifiable on a live deployment Β· πŸ§ͺ supported upstream, end-to-end verification in progress Β· πŸ—ΊοΈ on the roadmap Β· ❌ not supported (by design where noted).

As MCP Server (protected resource)

Specification Status Notes
MCP Streamable HTTP transport (stateless) βœ… Every request is self-contained: restarts, redeploys and autosuspend are transparent to clients
OAuth 2.0 Protected Resource Metadata (RFC 9728) βœ… /.well-known/oauth-protected-resource/mcp/, advertised in the WWW-Authenticate challenge
Bearer token usage and error semantics (RFC 6750) βœ… Distinguishes missing vs invalid token in challenges
scope parameter in WWW-Authenticate πŸ§ͺ Under verification
OAuth token based access with own Resource AS βœ… The embedded OAuth proxy issues the tokens this server accepts

As OAuth Authorization Server (embedded OIDC proxy)

Specification Status Notes
OAuth 2.1-style authorization code + PKCE (RFC 7636) βœ… S256; the proxy fronts any OIDC-compliant upstream IdP
Authorization Server Metadata (RFC 8414) βœ… Path-aware, with the openid-configuration alias and no-trailing-slash variants
Dynamic Client Registration (RFC 7591) βœ… With redirect-URI validation (unsafe schemes and unregistered URIs rejected)
Refresh token rotation βœ… One-time-use refresh tokens; offline_access supported
Client-facing token TTL decoupled from IdP expires_in βœ… FASTGEOAPI_MCP_ACCESS_TOKEN_EXPIRY_SECONDS
CIMD β€” Client ID Metadata Document (draft-ietf-oauth-client-id-metadata-document) βœ… Advertised (client_id_metadata_document_supported: true) and covered end to end; see the CIMD detail below
Mixed-key JWKS validation (RSA / EC / Ed25519) βœ… Unsupported key types in an IdP's JWKS are skipped instead of failing the whole set β€” pairs with Keycloak, Ory Hydra, Rauthy out of the box
EMA β€” Enterprise Managed Authorization (ID-JAG) πŸ—ΊοΈ Accepting the Identity Assertion JWT Authorization Grant at the embedded AS is on the roadmap (tracking FastMCP 4 / SEP-990)
MTLS client authentication (RFC 8705) ❌ Not supported

CIMD feature detail

CIMD feature Status Notes
Client ID as URL, metadata document fetch βœ… SSRF-hardened fetcher (loopback and private ranges rejected, including IPv6 transition addresses)
redirect_uris from the metadata document βœ… Enforced: a redirect the document does not list is refused
Authorization code + PKCE, none client auth βœ… Public URL-identified client completes the flow with no prior registration
Authorization code + PKCE, private_key_jwt βœ… Assertion verified against the inline jwks published in the document
jwks_uri (remote key set) in the document βœ… Keys fetched from the URL the document publishes, SSRF-guarded on that hop too
Shared-secret client authentication for CIMD clients ❌ by design A URL-identified client cannot hold a usable secret: such documents are refused and yield no token
Key enforcement βœ… An assertion signed with a key the document does not publish is rejected, even with a matching kid

Supported OAuth flows

Flow Use Case Configuration
Authorization Code + PKCE Interactive clients (Claude Desktop, mcp-remote) JWKS_ENABLED=true with OIDC config
Client Credentials Machine-to-machine, service accounts JWKS_ENABLED=true with OIDC config
Dynamic Client Registration (DCR) Auto-registration for MCP clients Enabled automatically with OIDC

OAuth Proxy Architecture

When OAuth is enabled, the MCP server acts as an OAuth Proxy. This architecture allows the MCP server to handle OAuth flows on behalf of MCP clients, simplifying authentication for AI assistants.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   MCP Client    │────▢│   MCP Server    │────▢│   Identity      β”‚
β”‚  (mcp-remote)   β”‚     β”‚  (OAuth Proxy)  β”‚     β”‚   Provider      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                       β”‚                       β”‚
        β”‚  1. Discovery         β”‚                       β”‚
        │──────────────────────▢│                       β”‚
        β”‚  /.well-known/...     β”‚                       β”‚
        β”‚                       β”‚                       β”‚
        β”‚  2. DCR (register)    β”‚                       β”‚
        │──────────────────────▢│                       β”‚
        β”‚                       β”‚                       β”‚
        β”‚  3. Authorization     β”‚  4. Redirect to IdP   β”‚
        │──────────────────────▢│──────────────────────▢│
        β”‚                       β”‚                       β”‚
        β”‚                       β”‚  5. Auth Code         β”‚
        β”‚                       │◀──────────────────────│
        β”‚  6. Token Exchange    β”‚                       β”‚
        │◀──────────────────────│                       β”‚
        β”‚                       β”‚                       β”‚
        β”‚  7. MCP Requests      β”‚  8. In-process ASGI   β”‚
        β”‚  (with Bearer token)  β”‚     call to pygeoapi  β”‚
        │──────────────────────▢│──────────────────────▢│

OAuth Flow Steps:

  1. Discovery: The MCP client fetches OAuth metadata from /.well-known/oauth-protected-resource/mcp/
  2. Dynamic Client Registration: The client registers itself with the MCP server's OAuth proxy
  3. Authorization Request: The client initiates the OAuth flow
  4. IdP Redirect: The OAuth proxy redirects to the upstream Identity Provider
  5. Auth Code Return: The IdP returns an authorization code
  6. Token Exchange: The OAuth proxy exchanges the code for tokens and issues its own JWT
  7. MCP Requests: The client makes authenticated MCP requests with the Bearer token
  8. Internal API Calls: The MCP server reaches pygeoapi in-process through httpx.ASGITransport against a raw sub-app β€” no network hop and no shared secret; the OAuth middleware chain is simply not mounted on this internal path

Security Features

Feature Description
Fail-closed startup guard With MCP enabled and no authentication configured, the server refuses to start unless passthrough mode is explicitly opted in
JWT Validation Tokens are validated using JWKS from the IdP
Opaque Token Support Supports IdPs that return opaque tokens (e.g., Logto without API Resources)
RFC 6750 Compliance Proper error handling distinguishing "no token" vs "invalid token"
In-Process Internal Calls MCP-to-pygeoapi calls run in-process via httpx.ASGITransport on a non-routable virtual host β€” no bypass key or header exists
Scope Validation Configurable required scopes for access control
PKCE Support Prevents authorization code interception in public clients

Supported Identity Providers

The MCP server is provider-agnostic and works with any OIDC-compliant Identity Provider:

Provider Status Notes
Logto Tested OAuth proxy with DCR, opaque token support
Auth0 Supported Full OIDC support
Keycloak Supported Full OIDC and OPA integration
Okta Supported Standard OIDC flows
Azure AD Supported Microsoft identity platform
Google Supported Google OAuth 2.0
Back to top