mcp-oauth2-proxy

release test codecov SLSA 3 FIPS 140-3 compliant

The search is over. Easy OAuth 2.0 proxy for MCP servers.

Architecture

flowchart TB
    User[๐Ÿ‘ค User Browser<br/>Claude Web Page]
    AI[๐Ÿค– AI Client<br/>Claude Web Server]
    RP[๐Ÿ”€ Reverse Proxy<br/>e.g. nginx]
    Proxy[๐Ÿ›ก๏ธ mcp-oauth2-proxy<br/>Authorization Server]
    IdP[๐Ÿ”‘ Identity Provider<br/>Google/GitHub/Microsoft]
    MCP1[๐Ÿ“ฆ MCP Server 1<br/>host: server1.example.com]
    MCP2[๐Ÿ“ฆ MCP Server 2<br/>host: server2.example.com]
    
    %% User interactions
    User -.-> AI
    User -.-> IdP
    User -.-> RP
    
    %% AI Client to services via Reverse Proxy
    AI --> RP
    RP --> Proxy
    RP --> MCP1
    RP --> MCP2
    
    %% Authentication flow
    Proxy -.-> IdP
    
    %% Styling
    classDef userStyle fill:#e1f5fe,stroke:#01579b,stroke-width:2px,color:#000
    classDef aiStyle fill:#f3e5f5,stroke:#4a148c,stroke-width:2px,color:#000
    classDef proxyStyle fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px,color:#000
    classDef idpStyle fill:#fff3e0,stroke:#e65100,stroke-width:2px,color:#000
    classDef mcpStyle fill:#fce4ec,stroke:#880e4f,stroke-width:2px,color:#000
    classDef rpStyle fill:#f1f8e9,stroke:#33691e,stroke-width:2px,color:#000
    
    class User userStyle
    class AI aiStyle
    class Proxy proxyStyle
    class IdP idpStyle
    class MCP1,MCP2 mcpStyle
    class RP rpStyle

How it Works

  1. The user prompts the AI client to initiate the OAuth2 flow with mcp-oauth2-proxy
  2. If the MCP server advertises scopes, mcp-oauth2-proxy presents the consent screen
  3. The mcp-oauth2-proxy redirects the user to the backing Identity Provider (IdP)
  4. The user authenticates with the IdP
  5. The IdP redirects back to mcp-oauth2-proxy with an authorization code
  6. The mcp-oauth2-proxy exchanges the authorization code for the user info and performs validations
  7. If validations pass, mcp-oauth2-proxy issues a JWT and redirects back to the AI client with another authorization code
  8. The AI client exchanges the authorization code for the issued JWT
  9. The AI client uses the JWT to access the MCP server

API Endpoints

The mcp-oauth2-proxy exposes the following HTTP endpoints:

Authentication Endpoint

OAuth 2.0 Discovery Endpoints

OAuth 2.0 Flow Endpoints

OpenID Connect (OIDC) Endpoints

Key Features

Note: The signing keys live only in memory and are rotated hourly. To force an immediate key rotation, simply restart the proxy. This will invalidate all existing tokens.

MCP servers can advertise scopes through the tools/list MCP request. If the response contains a _meta.scopes field with a list of scopes, the user will be presented with a consent screen during the OAuth2 authorization flow to choose which scopes should be granted to the issued token.

For example, if the MCP server responds with:

[
  {
    "name": "toolbox:read_only",
    "description": "Allow all read-only toolbox operations.",
    "tools": [
      "get_resource",
      "list_resources"
    ]
  },
  {
    "name": "toolbox:read_write",
    "description": "Allow all toolbox operations.",
    "tools": [
      "get_resource",
      "list_resources",
      "create_resource",
      "update_resource",
      "delete_resource"
    ]
  },
  {
    "name": "toolbox:get_resource",
    "description": "Allow getting a resource.",
    "tools": [
      "get_resource"
    ]
  },
  {
    "name": "toolbox:list_resources",
    "description": "Allow listing resources.",
    "tools": [
      "list_resources"
    ]
  },
  {
    "name": "toolbox:create_resource",
    "description": "Allow creating resources.",
    "tools": [
      "create_resource"
    ]
  },
  {
    "name": "toolbox:update_resource",
    "description": "Allow updating resources.",
    "tools": [
      "update_resource"
    ]
  },
  {
    "name": "toolbox:delete_resource",
    "description": "Allow deleting resources.",
    "tools": [
      "delete_resource"
    ]
  }
]

Users will see a consent screen like this:

Consent Screen

Installation

Container Image

A container image is distributed via GitHub Container Registry and signed with keyless Cosign:

ghcr.io/matheuscscp/mcp-oauth2-proxy

Helm Chart

An OCI Helm chart is distributed via GitHub Container Registry and signed with keyless Cosign:

helm install mcp-oauth2-proxy oci://ghcr.io/matheuscscp/mcp-oauth2-proxy/charts/mcp-oauth2-proxy \
  --set provider.name=google \
  --set provider.clientID=your-client-id \
  --set provider.clientSecret=your-client-secret

The main configuration options are:

For all the available options, see values.yaml.

Integration with ingress-nginx

To integrate with ingress-nginx, configure the mcp-oauth2-proxy Helm chart to enable ingress by specifying a host configuration in the value proxy.hosts, then create Ingress resources for each MCP server that requires authentication.

Example of Ingress resource for an MCP server:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-mcp-server
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod

    # Only the auth-url annotation is needed for mcp-oauth2-proxy
    nginx.ingress.kubernetes.io/auth-url: https://$host/authenticate
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - my-mcp.example.com
      secretName: my-mcp-server-tls
  rules:
    - host: my-mcp.example.com
      http:
        paths:
          - path: /mcp
            pathType: ImplementationSpecific
            backend:
              service:
                name: my-mcp-server
                port:
                  name: http

The key difference from traditional oauth2-proxy integration is that mcp-oauth2-proxy only requires the auth-url annotation. The /authenticate endpoint handles token validation. If the token is not present or is invalid, it returns 401 with the WWW-Authenticate header pointing to the authorization server metadata endpoints, according to the MCP specification.

Providers

Donโ€™t see the provider you need? Just open an issue to let me know!