For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
MCP authentication
Verified Code examples on this page have been automatically tested and verified.Configure OAuth 2.0 protection for MCP servers with JWT validation.
Attaches to:
llm or mcp modes, the examples on this page show each option in tabs. For more information, see Routing-based configuration.MCP authentication enables OAuth 2.0 protection for MCP servers, helping to implement the MCP Authorization specification. Agentgateway can act as a resource server, validating JWT tokens and exposing protected resource metadata.
MCP authentication is configured at the route level under policies.mcpAuthentication. Because the policy runs at the route level, you can use JWT claims from MCP auth in other route-level policies, such as authorization, rate limiting, and transformations.
MCP authentication uses a connect-time model: the OAuth flow happens once when the client first connects, not on each tool call. After the initial authentication, the access token is reused for all subsequent requests within the session.
Note
There are three deployment scenarios.
Authorization Server Proxy
Agentgateway can adapt traffic for authorization servers that don’t fully comply with OAuth standards. For example, Keycloak exposes certificates at a non-standard endpoint.
Set the provider field to adapt agentgateway’s behavior to a specific authorization server. Supported values include keycloak, auth0, okta, descope, authentik, and entra. Microsoft Entra ID requires extra handling; see Microsoft Entra ID.
In this mode, agentgateway:
- Exposes protected resource metadata on behalf of the MCP server
- Proxies authorization server metadata and client registration
- Validates tokens using the authorization server’s JWKS
- Returns
401 Unauthorizedwith appropriateWWW-Authenticateheaders for unauthenticated requests
# yaml-language-server: $schema=https://agentgateway.dev/schema/config
mcp:
port: 3000
policies:
mcpAuthentication:
issuer: http://localhost:7080/realms/mcp
audiences: ["http://localhost:3000/mcp"]
jwks:
url: http://localhost:7080/realms/mcp/protocol/openid-connect/certs
provider:
keycloak: {}
resourceMetadata:
resource: http://localhost:3000/mcp
scopesSupported:
- read:all
bearerMethodsSupported:
- header
- body
- query
resourceDocumentation: http://localhost:3000/stdio/docs
resourcePolicyUri: http://localhost:3000/stdio/policies
targets:
- name: tools
stdio:
cmd: npx
args: ["@modelcontextprotocol/server-everything"]Microsoft Entra ID
Microsoft Entra ID (Azure AD) does not fully implement the OAuth behaviors that the MCP authorization specification assumes. It rejects the RFC 8707 resource parameter that MCP clients send (AADSTS9010010), has no Dynamic Client Registration (RFC 7591), and serves only OIDC discovery instead of RFC 8414 authorization server metadata. Set provider.entra to have agentgateway bridge these gaps so that you can use Entra as the authorization server without an external adapter proxy.
With the entra provider, agentgateway uses two extra mcpAuthentication fields as follows.
| Field | Description |
|---|---|
clientId | The Application (client) ID of a pre-registered Entra app registration. Because Entra has no Dynamic Client Registration, agentgateway answers registration requests with this value. |
clientSecret | The client secret of the app registration. Required only for confidential clients (apps registered under the Entra Web platform), which Entra requires to authenticate at the token endpoint. Omit it for public (PKCE-only) app registrations. Agentgateway injects it server-side into proxied token requests. |
The route must also match the /.well-known/oauth-authorization-server/<path> path prefix so that agentgateway can serve the bridged metadata and proxy the authorize and token endpoints. The jwks field is optional; when omitted, it defaults to https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys.
# yaml-language-server: $schema=https://agentgateway.dev/schema/config
mcp:
port: 3000
policies:
mcpAuthentication:
issuer: https://login.microsoftonline.com/<tenant-id>/v2.0
audiences:
- api://<client-id>
- <client-id>
provider:
entra: {}
clientId: <client-id>
clientSecret: <client-secret>
resourceMetadata:
resource: http://localhost:3000/mcp
scopesSupported:
- api://<client-id>/mcp_access
bearerMethodsSupported:
- header
targets:
- name: tools
stdio:
cmd: npx
args: ["@modelcontextprotocol/server-everything"]For end-to-end setup, including registering the Entra app and connecting an MCP client, see the Microsoft Entra ID integration guide.
Resource Server Only
Agentgateway acts solely as a resource server, validating tokens issued by an external authorization server.
# yaml-language-server: $schema=https://agentgateway.dev/schema/config
mcp:
port: 3000
policies:
mcpAuthentication:
issuer: http://localhost:9000
audiences: ["http://localhost:3000/mcp"]
jwks:
url: http://localhost:9000/.well-known/jwks.json
resourceMetadata:
resource: http://localhost:3000/mcp
scopesSupported:
- read:all
bearerMethodsSupported:
- header
- body
- query
targets:
- name: tools
stdio:
cmd: npx
args: ["@modelcontextprotocol/server-everything"]Authentication mode
You can control how agentgateway handles requests that lack valid credentials by setting the mode field. The following modes are supported:
| Mode | Behavior |
|---|---|
strict (default) | A valid token issued by a configured issuer must be present. Requests without a valid token are rejected with 401 Unauthorized. |
optional | If a token is present, it is validated. Requests without a token are permitted. |
permissive | Requests are never rejected based on authentication. |
The following example sets the mode to permissive:
policies:
mcpAuthentication:
mode: permissive
issuer: http://localhost:9000
audiences: ["http://localhost:3000/mcp"]
jwks:
url: http://localhost:9000/.well-known/jwks.json
resourceMetadata:
resource: http://localhost:3000/mcp
scopesSupported:
- read:allPassthrough
When the MCP server already implements OAuth authentication, no additional configuration is needed. Agentgateway passes requests through without modification.