AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified Apache-2.0 Self-run

Mcp Auth Adapter

mcp-redhat-community-ai-tools-mcp-auth-adapter · by redhat-community-ai-tools

An authentication adapter for Model Context Protocol (MCP) world. It sits in front of any OAuth 2.0 / OIDC IdP and provides functionality required by the MCP Authorization specification for the most common MCP clients (Claude Code/Desktop, Cursor IDE, ChatGPT, Gemini CLI, VS Code, ...) and their known problematic behaviours.

— No reviews yet
0 installs
36 views
0.0% view→install

Install

$ agentstack add mcp-redhat-community-ai-tools-mcp-auth-adapter

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ● Network access Used
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ● Environment & secrets Used
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-redhat-community-ai-tools-mcp-auth-adapter)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
● 19d ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Mcp Auth Adapter? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

MCP Auth Adapter

[](https://github.com/redhat-community-ai-tools/mcp-auth-adapter/actions/workflows/ci.yml) [](https://github.com/redhat-community-ai-tools/mcp-auth-adapter/actions/workflows/ci.yml) [](https://securityscorecards.dev/viewer/?uri=github.com/redhat-community-ai-tools/mcp-auth-adapter)

An OAuth/OIDC authentication adapter for Model Context Protocol (MCP) clients. It sits in front of any OAuth 2.0 / OIDC upstream IdP - such as Keycloak, Auth0, Okta, Azure AD, Google Identity, or any provider serving standard OAuth 2.0 / OIDC discovery metadata - and provides functionality required by the MCP Authorization specification for the most common MCP clients (Claude Code/Desktop, Cursor IDE, ChatGPT, Gemini CLI, VS Code, ...) and [their known problematic behaviours](#known-mcp-client-behaviors).

MCP servers announce this adapter as their authorization server. MCP clients discover it via .well-known and interact with its endpoints. Authentication itself and token issuing are performed by the upstream IdP - this adapter is only a very thin, transparent, stateless facade.

MCP Spec Compatibility

Features

  • Well-known discovery - filtered, MCP-focused view of the upstream IdP metadata with injected adapter endpoints and tailored configurations. See [Upstream Well-Known Handling](#upstream-well-known-handling).
  • Open Dynamic Client Registration (DCR) (optional) - returns a pre-configured client_id for registering MCP clients per RFC 7591. Supports per-MCP-client IdP client mapping based on client_name with optional per-client redirect URI enforcement. See [Open DCR and its Security Limitations](#open-dcr-and-its-security-limitations) and [Per-MCP-Client IdP Client Mapping](#per-mcp-client-idp-client-mapping).
  • Scope filtering (optional) - intercepts /authorize and /par requests to modify scopes before forwarding to the upstream IdP.
  • RFC 9207 iss parameter validation - mandatory authorization response issuer verification preventing OAuth mix-up attacks per the MCP Auth Spec. See [RFC 9207 iss parameter validation](#rfc-9207-iss-parameter-validation).
  • Resource parameter validation (optional) - validates the RFC 8707 resource parameter required by the MCP specification, with configurable enforcement, format checking, and allowlist filtering. See [Resource Parameter Validation (RFC 8707)](#resource-parameter-validation-rfc-8707).
  • Client Credentials passthrough - transparently proxies client_credentials and JWT bearer grants to the upstream IdP per the MCP OAuth Client Credentials extension. See [Client Credentials Passthrough](#client-credentials-passthrough).
  • PAR proxy (optional) - proxies RFC 9126 Pushed Authorization Requests when the authorize proxy is active and the Upstream IdP advertises PAR. See [PAR (RFC 9126)](#par-rfc-9126).
  • DPoP header forwarding - always forwards DPoP / DPoP-Nonce on /token and /par; discovery advertisement is opt-in. See [DPoP (RFC 9449)](#dpop-rfc-9449).
  • CIMD adapter (EXPERIMENTAL, optional) - accepts Client ID Metadata Document style client_id URLs, validates metadata documents, and maps them to upstream IdP clientids. See [CIMD Adapter](#cimd-adapter-experimental).

See [Flow Diagrams](#flow-diagrams) to understand functionality better.

Container Image

Pre-built container images are published to GitHub Container Registry on every release. This is the recommended way to deploy in production - no Node.js installation required.

Image: ghcr.io/redhat-community-ai-tools/mcp-auth-adapter with tags X.Y.Z, X.Y, X, and latest.

Older tags were published under ghcr.io/velias/mcp-auth-adapter. GHCR does not redirect to the new org namespace, so update to ghcr.io/redhat-community-ai-tools/mcp-auth-adapter in pull/run commands.

Prerequisites: Docker or Podman

Pull and run

Podman is used in examples, but you can use docker command instead:

podman run -d --name mcp-auth-adapter \
  -p 3000:3000 \
  -e MCP_BASE_URL=https://mcp-auth.example.com \
  -e MCP_UPSTREAM_SSO_URL=https://sso.example.com/auth/realms/external \
  -e MCP_PROXY_DCR_CLIENT_ID=mcp-client \
  ghcr.io/redhat-community-ai-tools/mcp-auth-adapter:latest

Or use an env file for all configuration (see [Configuration](#configuration) below):

podman run -d -p 3000:3000 --env-file .env ghcr.io/redhat-community-ai-tools/mcp-auth-adapter:latest

Available tags

Each release vX.Y.Z produces the following image tags:

  • X.Y.Z - exact version (recommended for production)
  • X.Y - latest patch within a minor version
  • X - latest minor within a major version
  • latest - most recent release

To build the image locally from source, see [CONTRIBUTING.md](CONTRIBUTING.md#running-with-docker--podman).

npm Package

The adapter is published on npm and can be run directly with npx — no cloning or building required.

Prerequisites: Node.js >= 20.x, npx or npm

npx mcp-auth-adapter

Or install globally with npm install -g mcp-auth-adapter and run as mcp-auth-adapter.

Or install it into your Node.js project with npm install mcp-auth-adapter to use it.

Build from Source

Prerequisites: Node.js >= 20.x (uses native fetch), npm

npm install
npm run build

# Create .env from the template and edit it
cp .env.example .env

npm start

Configuration

Environment variables are used. All variables are prefixed with MCP_. A .env file in the project root is loaded automatically, explicit environment variables take precedence.

| Variable | Required | Default | Description | |---|---|---|---| | | | | Core | | MCP_BASE_URL | Yes | -- | Public base URL of this adapter. Used as issuer (RFC 8414 §3.3) and to construct endpoint URLs. Must be http or https; trailing slashes are stripped automatically. Must exactly match what MCP servers advertise in their Protected Resource Metadata authorization_servers array. | | MCP_UPSTREAM_SSO_URL | Yes | -- | Base URL (issuer) of the upstream IdP. Must be http or https; trailing slashes are stripped automatically. Works with any OAuth 2.0 / OIDC provider. Discovery is attempted via /.well-known/openid-configuration, then /.well-known/oauth-authorization-server (RFC 8414); on failure, fallback endpoints are derived using Keycloak URL conventions ([see below](#upstream-well-known-handling)). | | MCP_PORT | No | 3000 | Port this app listens on. | | MCP_SHUTDOWN_TIMEOUT_SECONDS | No | 30 | Maximum seconds to wait for in-flight requests to drain after SIGTERM/SIGINT before force-exiting. | | | | | Authorize proxy (RFC 9207 iss interception, scopes, resource; auto-enables /authorize + /token; /par when upstream advertises PAR — see [PAR](#par-rfc-9126)) | | MCP_PROXY_AUTH_STATE_SECRET | Conditional | -- | Hex-encoded HMAC secret for signing state blobs (min 32 bytes = 64 hex chars). Required when the /authorize proxy is active (scope filtering, CIMD, or standalone). Generate with openssl rand -hex 32. Must be identical across all pods. | | MCP_PROXY_AUTH_STATE_SECRET_PREVIOUS | No | -- | Previous HMAC secret for zero-downtime key rotation (same format). Set to the old key during rotation; remove after TTL has elapsed. | | MCP_PROXY_AUTH_STATE_TTL_MINUTES | No | 30 | How long (minutes) the signed state blob remains valid. Must cover full user interaction at the upstream IdP (login + registration + MFA + consent). | | MCP_PROXY_AUTH_ALLOWED_REDIRECT_URIS | Conditional | -- | Comma-separated allowed redirect URI patterns. Trailing * = host-aware wildcard (exact hostname; http://host* / http://host:* = any port and path; https://host/path* = path prefix); no * = exact match. Domain-extension attacks (host.evil.com) are rejected. Required when /authorize proxy is active (unless CIMD-only, or all MCP_PROXY_DCR_CLIENT_NAME_MAP entries have per-client allowed_redirect_uris with no fallback MCP_PROXY_DCR_CLIENT_ID). See [known MCP client patterns](#known-mcp-client-redirect-uri-patterns) for common values. | | MCP_PROXY_AUTH_SCOPES_REMOVED | No | -- | Comma-separated scopes to strip from /authorize and /par requests (e.g. offline_access). Ignored if MCP_PROXY_AUTH_SCOPES_PRESERVED is also set. Setting this (or scopes preserved / CIMD) auto-enables the authorize proxy. | | MCP_PROXY_AUTH_SCOPES_PRESERVED | No | -- | Comma-separated scopes to keep in /authorize and /par requests; all others are stripped. Takes precedence over MCP_PROXY_AUTH_SCOPES_REMOVED. | | MCP_PROXY_AUTH_REQUIRE_RESOURCE | No | false | Reject /authorize, /par, and /token requests missing the RFC 8707 resource parameter. Enable for strict MCP spec compliance; leave disabled if MCP clients don't yet include it. | | MCP_PROXY_AUTH_ALLOWED_RESOURCES | No | -- | Comma-separated allowed resource URI patterns. Trailing * = prefix match, *.domain.com = domain wildcard (matches domain and all subdomains), no * = exact match. When set, resource must match a pattern; unmatched values are rejected with 400. | | | | | Dynamic Client Registration | | MCP_PROXY_DCR_CLIENT_ID | No | -- | Default client_id returned by POST /register. Setting this enables the DCR proxy. Must be pre-registered at the upstream IdP as a public client. When MCP_PROXY_DCR_CLIENT_NAME_MAP is also set, this serves as the fallback for unmatched client names. | | MCP_PROXY_DCR_CLIENT_NAME_MAP | No | -- | JSON object mapping client_name patterns to upstream IdP clientids, with optional per-client redirect URI restrictions. Setting this enables the DCR proxy (even without MCP_PROXY_DCR_CLIENT_ID). See [Per-MCP-Client IdP Client Mapping](#per-mcp-client-idp-client-mapping). | | | | | CIMD adapter (EXPERIMENTAL, auto-enables authorize proxy) | | MCP_PROXY_CIMD_MAP | No | -- | JSON object mapping CIMD URLs to upstream IdP clientids. Format: {"":"", ...}. N:1 mapping supported. CIMD auto-enables when this is non-empty or MCP_PROXY_CIMD_DEFAULT_CLIENT_ID is set. | | MCP_PROXY_CIMD_DEFAULT_CLIENT_ID | No | -- | Fallback upstream client_id for CIMD URLs not in the map. If unset, unknown CIMD URLs are rejected with 403 (strict allowlist). | | MCP_PROXY_CIMD_CACHE_MINUTES | No | 30 | Cache TTL (in minutes) for validated CIMD metadata documents. | | | | | Well-known discovery | | MCP_WELL_KNOWN_SCOPES_SUPPORTED | No | -- | Comma-separated scopes to announce in scopes_supported. If empty, the field is omitted. Note: some MCP clients request all announced scopes -- this controls announced scopes, not forwarded scopes. | | MCP_WELL_KNOWN_REFRESH_MINUTES | No | 60 | How often (in minutes) to re-fetch the upstream well-known document. | | | | | Protocol opt-ins | | MCP_PROXY_DPOP_ENABLED | No | false | When true, advertise upstream dpop_signing_alg_values_supported in discovery only if the Upstream IdP announces it. Off by default — see [DPoP](#dpop-rfc-9449). Header forwarding on /token and /par is always on. PAR has no env flag (see authorize proxy note above). | | | | | Observability | | MCP_ACCESS_LOG | No | true | Emit per-request access logs at info level with client identification (User-Agent, method, path, IP, plus route-specific fields). Set to false to disable. | | MCP_METRICS_ENABLED | No | true | Enable Prometheus metrics endpoint (GET /metrics) and request instrumentation. Set to false to disable (zero overhead). | | MCP_DEBUG | No | false | Emit structured debug logs for every request. |

Open DCR and its Security Limitations

MCP Clients need a way to get client_id necessary to login through the upstream IdP. You can use Open DCR functionality of this adapter if your IdP does not provide it, or if you do not want to use it.

The Open DCR endpoint returns a fixed public client_id (token_endpoint_auth_method: none) to be used by MCP Clients. But as many MCP Clients are local apps, any local application can obtain this client_id and start an OAuth flow. IdP do not know who is asking for the client_id. Two emerging standards address this:

  • DCR with Software Statement Assertion (SSA) - cryptographically proves client identity via signed JWTs (RFC 7591 §2.3). No major MCP client currently includes Software Statements in DCR requests.
  • Client ID Metadata Documents (CIMD) - the client_id is an HTTPS URL pointing to a metadata document. Default mechanism in the MCP Auth Spec (2025-11-25), not yet universally adopted. This adapter includes experimental CIMD support - see [CIMD Adapter](#cimd-adapter-experimental).

Until "DCR with SSA" or CIMD is widely supported, user consent during login at the upstream IdP is the last line of defense. This is an accepted limitation of the MCP auth ecosystem.

Per-client IdP client mapping (see below) provides partial mitigation: operators can isolate IdP clients per MCP application.

Per-MCP-Client IdP Client Mapping

Operators often want different MCP clients (Cursor, Claude Code, VS Code, etc.) to use different upstream IdP clients — for per-client consent screens, scope policies, audit logging, and access revocation. DCR client name mapping (below) and [CIMD client mapping](#cimd-adapter-experimental) both support this, using different client identification methods. For how redirect URIs are validated across all client types, see [Redirect URIs at the upstream IdP](#redirect-uris-at-the-upstream-idp).

DCR Client Name Mapping

MCP_PROXY_DCR_CLIENT_NAME_MAP maps client_name values from DCR requests to upstream IdP client_ids. Pattern matching is case-insensitive; trailing * means prefix match, no * means exact match. Exact matches are checked first, then prefix matches in declaration order.

Simple format (all clients use global MCP_PROXY_AUTH_ALLOWED_REDIRECT_URIS):

MCP_PROXY_DCR_CLIENT_NAME_MAP={"Cursor":"cursor-sso-client","Claude Code*":"claude-sso-client","VS Code*":"vscode-sso-client"}

Extended format (per-client redirect URI enforcement — recommended):

MCP_PROXY_DCR_CLIENT_NAME_MAP={
  "Cursor": {
    "client_id": "cursor-sso-client",
    "allowed_redirect_uris": "cursor://anysphere.cursor-mcp/*"
  },
  "Claude Code*": {
    "client_id": "claude-sso-client",
    "allowed_redirect_uris": "http://localhost:*,http://127.0.0.1:*"
  },
  "VS Code*": "vscode-sso-client"
}

When allowed_redirect_uris is set, these patterns are

…

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.