DEV Community

Zhengxin
Zhengxin

Posted on

Claude Code MCP Deep Dive (6): From One Authorization to Multiple Servers

TL;DR: A remote MCP server that needs authentication has not necessarily failed to connect permanently. Claude Code can guide a user through browser-based OAuth, retain credentials securely, and refresh them later. In an enterprise deployment that supports Cross-App Access, one login to the organization's identity provider can also be reused to obtain server-specific access tokens without a separate browser prompt for every server.

Part 5 explored the permission decision after a tool becomes available. But Part 2 left another gate open: what happens when a remote server exists in configuration but cannot yet authenticate the client?

This is a different problem from deciding whether Claude may invoke a tool. OAuth determines whether the MCP client has a credential that the remote service accepts. Claude Code's tool permissions determine whether an individual call should proceed. Passing one gate does not automatically pass the other.

“Needs authentication” is an actionable state

Claude Code distinguishes a remote server that needs sign-in from an ordinary connection failure. Its current documentation says that an HTTP 401 Unauthorized or 403 Forbidden can mark a remote server as needing authentication. The /mcp panel shows which servers need sign-in; an interactive user can authenticate there, or run claude mcp login <name> from a shell.

The distinction matters because an authentication challenge has a clear next step. The server definition does not need to be deleted and recreated merely because credentials are missing. Finish the authorization flow and Claude Code can reconnect with valid credentials.

The code path examined for this series also includes a useful bridge back into the model's tool list. For an eligible server in the needs-auth state, it can expose a synthetic mcp__<server>__authenticate tool instead of leaving the model with no actionable capability. Calling that tool starts the OAuth flow and returns an authorization URL for the user. Once the callback succeeds, the client reconnects and replaces the temporary authentication entry with the server's real tools. This model-facing route complements the documented /mcp and CLI routes; it does not mean the model can sign in on the user's behalf.

There are boundaries to this behavior. The synthetic entry is for the HTTP/SSE OAuth path in the implementation examined here. A claude.ai connector uses its own authorization flow, and a noninteractive run cannot simply pop open an interactive /mcp sign-in dialog. In those cases the user needs the appropriate interactive route first.

The ordinary OAuth round trip

For a remote server that supports OAuth, the sequence is familiar:

  1. Claude Code discovers the authorization information associated with the remote MCP endpoint.
  2. It starts a temporary local callback listener and opens, or provides, the authorization URL.
  3. The user signs in and grants the requested access in a browser.
  4. The authorization server redirects to the callback address with an authorization result.
  5. Claude Code exchanges that result for credentials, stores them securely, and reconnects to the MCP server.

Claude Code's documentation notes that tokens are stored securely and refreshed automatically. That should not be paraphrased as “the token is always in the operating system keychain on every platform”: storage details vary by platform and credential type. The practical point is that the access token is not meant to be pasted into a shared .mcp.json server definition.

The browser step also has a headless-friendly path. If no local browser is available—for example, when claude mcp login <name> runs over SSH—the command prints the authorization URL. The user opens it on a machine with a browser and pastes the full redirect URL back into the interactive terminal. A failed browser redirect can be recovered in the same way. This is why the flow can still work when the terminal and browser are not on the same machine.

Once signed in, the ordinary case is quiet: Claude Code refreshes credentials when needed rather than requiring a browser login for every tool call. If an already-authorized remote server rejects a stored token with 401, current documentation says Claude Code refreshes it, reconnects, and retries the request once. Only if recovery fails does it surface the need to re-authenticate. A configured static Authorization header is different: if the server rejects that header, Claude Code reports a failed connection instead of silently switching to OAuth.

One enterprise identity, several server-specific tokens

A team may operate separate MCP servers for issues, documents, metrics, and internal APIs. Making every employee complete an unrelated browser consent flow for each server is cumbersome. Enterprise-Managed Authorization, also called Cross-App Access (SEP-990), addresses this with a shared enterprise identity provider (IdP).

The high-level sequence is:

One browser login to the enterprise IdP
  → reusable IdP identity token
  → token exchange for the target MCP authorization server
  → server-specific MCP access token
Enter fullscreen mode Exit fullscreen mode

The intermediate exchanges are not a claim that one bearer token should be sent indiscriminately to every server. The client uses the existing enterprise identity to request a credential scoped to the target authorization server. The MCP TypeScript SDK describes the two protocol steps: RFC 8693 token exchange produces an Identity Assertion Authorization Grant (ID-JAG), and RFC 7523's JWT bearer grant exchanges that assertion for an access token at the MCP authorization server.

In the Claude Code implementation examined for this series, the IdP login is cached and reused across servers configured for this flow. The IdP connection is configured once, while each participating MCP server opts in and supplies the details its authorization server needs. With a valid cached identity token, a subsequent server can complete the exchange without another browser interruption. It is not an unconditional “log in once and gain access to every server” promise: the enterprise IdP, each authorization server, the server configuration, and organizational policy must all support and permit the exchange.

This path is explicitly gated. The implementation uses a feature switch and enterprise IdP setup, and a server that opts into Cross-App Access does not silently fall back to ordinary per-server OAuth if the enterprise flow is misconfigured. A visible error is better than an ambiguous security posture where the configuration says one thing and the client does another.

Authentication can expire after a successful connection

A sign-in problem can arise at two points. The first is the initial connection, before the client can list tools. The second is later, after a working server rejects a call because a token expired, was revoked, or lacks the required scope.

The recovery path is not always “show the browser again.” Claude Code first uses its stored refresh credential where possible, reconnects, and retries once. If the refresh token itself is rejected, it points the user back to /mcp for re-authentication. If the server requests an additional OAuth scope, that is a different signal: the client may need a new consent flow with the appropriate scope, and an administrator's pinned scope policy may need review.

Treating these outcomes distinctly prevents two mistakes. A transient 401 need not make a working integration look permanently broken, while a genuinely missing permission must not be hidden behind endless retries. The server's authentication state and the next action should remain legible to the user.

What to remember

An MCP connection can be configured, discoverable, and still unusable until the client is authenticated. Claude Code's OAuth flow turns that state into an actionable sign-in path; secure credential storage and refresh make subsequent use less disruptive. Enterprise Cross-App Access can reduce repeated sign-ins further, but only for servers and organizations explicitly configured to support it.

The next article moves beyond tool calls. MCP servers can also offer resources for reading, and elicitation provides a way to request information from the user while a server-side workflow is in progress.

References

Top comments (0)