claude-code - 💡(How to fix) Fix [FEATURE] Be Able to Add a OAuth-Compliant Credential Manager for Claude Connectors

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

  1. For each connector, Claude Code calls the team's helper script with the user token and connector context. The helper script calls the IdP's API: "give me the credential this user has authorized for connector X." The IdP looks up the vault entry, applies policy (is this user allowed to fetch a token with these scopes?), and returns either the credential or an error.

Code Example

{
  "mcpServers": {
    "salesforce": {
      "type": "http",
      "url": "https://mcp.salesforce.com/sse",
      "userAuth": {
        "issuer": "https://idp.example.com",
        "clientId": "${IDP_CLIENT_ID}",
        "scopes": "openid profile"
      },
      "headersHelper": "/path/to/get-salesforce-headers.sh"
    }
  }
}

---

CLAUDE_CODE_MCP_USER_TOKEN — the user's OAuth access token from the IdP
CLAUDE_CODE_MCP_USER_TOKEN_ISSUER — the issuer URL
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing requests and this feature hasn't been requested yet
  • This is a single feature request (not multiple features)

Problem Statement

headersHelper runs without user context. Claude Code's existing OAuth handles user authentication only against the MCP server's own AS. There's no way to combine them to say: "authenticate the user against my IdP, then let my script use that token to fetch the right credential for this connector."

The case that needs this: third-party SaaS connectors (Salesforce, Notion, GitHub) where I want my IdP in the loop. The IdP holds OAuth tokens it has obtained on the user's behalf, looks them up by user identity, and returns the right one for each connector. Without user context, headersHelper can't ask the IdP whose tokens to look up.

The standard fix is to run a proxy in front of every connector. That works but puts infrastructure in the request path. A user-OAuth-plus-helper pattern fixes this without sitting in the request path.

Proposed Solution

Extend headersHelper so it can be paired with user OAuth against an identity provider. Claude Code runs the OAuth flow, manages the user token, and passes it to headersHelper as an additional input. The helper uses that token to produce the headers Claude Code sends to the MCP server.

{
  "mcpServers": {
    "salesforce": {
      "type": "http",
      "url": "https://mcp.salesforce.com/sse",
      "userAuth": {
        "issuer": "https://idp.example.com",
        "clientId": "${IDP_CLIENT_ID}",
        "scopes": "openid profile"
      },
      "headersHelper": "/path/to/get-salesforce-headers.sh"
    }
  }
}

When userAuth is present, Claude Code does standard OAuth 2.1 with PKCE against the IdP (the same code path that already exists for MCP-server OAuth, just pointed at the IdP). The resulting user token is passed to headersHelper via a new environment variable, alongside the existing CLAUDE_CODE_MCP_SERVER_NAME and CLAUDE_CODE_MCP_SERVER_URL:

CLAUDE_CODE_MCP_USER_TOKEN — the user's OAuth access token from the IdP
CLAUDE_CODE_MCP_USER_TOKEN_ISSUER — the issuer URL

The helper does whatever IdP-specific exchange it needs and returns headers on stdout, exactly as headersHelper does today.

  • userAuth reuses the OAuth code path Claude Code already has for MCP-server OAuth. The only change is allowing it to point at an IdP independent of the MCP server.
  • headersHelper already runs a local script and returns connection headers. The only change is adding the user token as input.

The following standards would be used for this:

  • RFC 6749 / OAuth 2.1 for the user authentication flow
  • RFC 7636 (PKCE) for public client auth
  • RFC 8414 for IdP metadata discovery

Security

  • The user token lives in the same secure storage Claude Code already uses for OAuth tokens.
  • The helper has the same trust model as today's headersHelper: workspace trust dialog at project or local scope, restrictable via managed policy.
  • Helper failures fail closed.

What this is not

  • Not a new protocol. It's two existing config fields that compose.
  • Not a replacement for headersHelper's current uses. Workload-identity cases that don't need user OAuth keep working as today.
  • Not vendor-specific. Any OAuth 2.1 IdP works for userAuth. Any IdP-specific logic works in the helper.
  • Not the default. No userAuth field, no change in behavior.

Scope

I would like to start with Claude Code first. The pattern can extend to claude.ai connectors in the future since claude.ai already does user OAuth. However the gap there is the helper hook, not the user authentication.

Alternative Solutions

Run a proxy in front of every connector. A FastMCP gateway or custom service that terminates Claude Code's OAuth, calls our IdP for the right credential, and forwards to the upstream. Works, but adds infrastructure in the request path that has to be operated, monitored, and scaled. Doesn't help when the connector is hosted outside our network — reverse-proxying a third-party SaaS service is awkward and breaks anytime the upstream changes its endpoints.

Use headersHelper standalone. Skip OAuth entirely and have a local script return whatever credential the upstream needs. Works fine for workload identity (client_credentials JWTs against internal MCP servers). Falls apart for connectors that need user-interactive auth — headersHelper runs without user context, so there's no way to identify which user's vault entry to look up at the IdP. Without user identity, the IdP can't enforce per-user policy or audit, which defeats the point of having an IdP in the loop.

authServerMetadataUrl pointing at the IdP. Works when the MCP server is configured to trust our IdP as its issuer. Useless for third-party SaaS connectors (Salesforce, Notion, GitHub) that have their own AS and won't accept tokens from arbitrary IdPs.

Pre-configured OAuth credentials per connector (--client-id, --client-secret). Skips DCR for one connector. Doesn't centralize anything. Every connector still runs its own OAuth flow, stores its own token, has its own revocation surface. Just shifts the registration step earlier.

Configure each connector individually with the IdP as the AS, then build identity translation into each MCP server. Theoretically workable for MCP servers we own. Doesn't help for the third-party SaaS case at all, since we don't control what those servers accept. Also forces every internal MCP server to implement IdP federation logic that should live at the IdP layer.

None of these handle the case I actually care about: third-party SaaS MCP servers where the user signs in once with my IdP, and the IdP brokers credentials for every connector based on that user identity. The user-OAuth-plus-helper pattern is the only one that gets there without putting infrastructure in the request path.

Priority

High - Significant impact on productivity

Feature Category

MCP server integration

Use Case Example

Scenario: Enterprise developer onboarding with 8 connectors:

  1. Acme Corp standardizes on a single identity provider for SSO, MFA, and audit. Security team has configured per-user policies: which engineers can access which SaaS apps, which production tenants require step-up auth, which connectors are restricted to specific times of day.

  2. New engineer joins. They install Claude Code and pull the team's .mcp.json, which references 8 connectors: Salesforce, GitHub, Linear, Notion, Slack, Sentry, PagerDuty, and an internal platform MCP server. Each connector has userAuth pointing at the corporate IdP, and a headersHelper script that the team maintains in a shared repo.

  3. Engineer runs claude mcp list. Claude Code sees userAuth configured, runs OAuth against the IdP, opens a browser. Engineer signs in once with SSO + MFA. Claude Code stores the user token.

  4. For each connector, Claude Code calls the team's helper script with the user token and connector context. The helper script calls the IdP's API: "give me the credential this user has authorized for connector X." The IdP looks up the vault entry, applies policy (is this user allowed to fetch a token with these scopes?), and returns either the credential or an error.

  5. For connectors the user hasn't yet authorized, the IdP returns a "needs authorization" response. The helper surfaces a URL the user opens to complete OAuth against that specific upstream, mediated by the IdP. Once done, the IdP stores the resulting token in its vault and the helper returns it on the next call. Future engineers joining the team skip this step for connectors others have already authorized organization-wide.

Mid-session step-up scenario: Engineer asks Claude to "create a $50k opportunity in Salesforce." The Salesforce MCP server returns the engineer's request. Claude Code's helper checks IdP policy on the next request and finds that opportunities over $25k require fresh MFA. Helper returns a 403 with a step-up URL. Engineer approves via push notification. Helper retries. Audit log in the IdP shows the full chain: who, what, when, what policy fired, what credential was issued.

Offboarding scenario: Engineer leaves the team. Security team revokes them in the IdP. Within seconds, every connector, including the SaaS ones where the underlying OAuth tokens would otherwise live for days, stops working in Claude Code.

None of this is possible today without putting a proxy in the request path of every individual MCP server.

Additional Context

Disclosure: I work on agentic identity at Descope.

The proposal is intentionally vendor-neutral. Any OAuth 2.1 IdP can implement the helper-side logic, and Descope's own implementation would be one example among others.

Auth0 Token Vault, WorkOS Pipes, and similar products from other IdPs already do most of the underlying credential management; the helper hook is the missing client-side piece for tools like Claude Code to consume them.

Evidence for feature investment and enterprise adoption of this model:

  • HashiCorp Vault's secrets engines store credentials for upstream services and issue them to clients on demand, with central renewal and revocation. The user-OAuth-plus-helper pattern is the analogous shape for MCP connector auth.
  • AWS STS (especially AssumeRoleWithWebIdentity) and RFC 8693 token exchange let a client request a scoped credential from a central authority by presenting an identity. The helper is where that exchange happens.
  • Auth0 Token Vault and Descope Connections already store third-party OAuth tokens minted on a user's behalf. The user-OAuth-plus-helper pattern is the missing client-side glue for AI dev tools to consume those vaults.

Why this matters now:

  • The Connectors Directory has crossed 200 entries. The per-user, per-connector OAuth model that worked for 1-3 connectors doesn't scale to 10-50.
  • Enterprise customers evaluating agentic IdPs consistently raise centralized auth as a blocker. SOC 2, PCI DSS 4.0, HIPAA, and FedRAMP all require centralized policy and audit for agent actions, and there's no story for that today beyond running a proxy.
  • MCP itself is auth-agnostic at the transport layer. This proposal doesn't require any MCP spec changes, it's purely about how Claude Code obtains the credential it puts in the Authorization header.

The riskiest part is probably making sure the OAuth code path generalizes cleanly to "OAuth against an IdP that isn't the MCP server itself." Most of the rest is small plumbing changes.

Some open discussion items:

  • Whether userAuth should be its own config field or whether the existing OAuth config should grow an "issuer is separate from the MCP server" flag. Either works.
  • Whether the user token should be passed via environment variable (matches how headersHelper currently exposes context) or via stdin (matches how Claude Code hooks pass JSON). Environment variable is simpler; stdin is more extensible if more fields get added later.
  • Whether to expose the refresh token to the helper or only the access token. Most cases only need the access token. Some specialized cases (long-running background helpers) might need refresh.
  • Field names. userAuth is a placeholder.

I'm happy to set up a working session with the Claude Code team to walk through the design and a prototype and to publish reference helpers for a few common IdP patterns (vault lookup, token exchange, API key retrieval) so users have working examples to fork.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [FEATURE] Be Able to Add a OAuth-Compliant Credential Manager for Claude Connectors