skip to content

In MCP, what OAuth 2.1 role does a remote server play, and what does it do with a token?

level: juniorimportance: must knowfreq 55%

answer

  1. Two servers, only one issues tokens
  2. MCP holds data, not identity
  3. Bearer token verified, never minted
  4. Audience check, then scope check
  5. Resource server in OAuth 2.1 terms

basics

~20 s

A remote MCP server is an OAuth 2.1 resource server, never an authorization server. It issues no tokens and runs no login screen: it validates the bearer token presented on every HTTP request and rejects one not issued for itself.

solid answer

~40 s

In MCP revision 2026-07-28 the authorization profile applies to HTTP-based remote servers, and it puts the MCP server in exactly one OAuth 2.1 role: **resource server**. Some separate authorization server authenticates the user and mints an access token; the MCP client sends that token as `Authorization: Bearer <token>` on each POST to the MCP endpoint. The server's job is verification — signature or introspection, expiry, scopes, and crucially the audience, so a token minted for a different service is refused. A missing or invalid token gets `401`; a valid token that lacks the needed permission gets `403` with `error="insufficient_scope"`. Because 2026-07-28 removed protocol-level sessions and the `initialize` handshake, authorization is never "established once at connect time": every request carries its own credential and is authorized on its own.

go deeper

for a junior

Be able to say plainly that a remote MCP server is an OAuth 2.1 resource server: it checks bearer tokens, it does not create them, and the token rides on every HTTP request.

for a middle

Explain the four checks the server performs — signature, expiry, audience, scope — and why the audience check is the one people forget. Know that 401 means no usable credential and 403 with insufficient_scope means under-privileged.

for a senior

Show that you have operated this: validate tokens locally against cached signing keys so any node can serve any request, and be able to say why per-request authorization falls out of the 2026-07-28 removal of sessions and the initialize handshake.

for a principal

Own the argument for keeping identity out of MCP servers entirely — one organizational authorization server, uniform revocation and MFA, and MCP servers that hold data but never credentials, so a compromised server cannot mint access to anything.

## The three OAuth 2.1 roles, and which one MCP takes OAuth 2.1 separates three parties. The **client** is the application asking for access — here, the MCP client inside the host application. The **authorization server** (AS) authenticates the end user, obtains their consent, and mints access tokens. The **resource server** (RS) holds the protected functionality and does nothing but check the tokens presented to it. A remote MCP server, in revision 2026-07-28 of the specification, is a resource server and only a resource server. It does not render a login page, does not verify passwords or second factors, does not mint, refresh or revoke tokens, and never sees the user's credentials. It receives an access token that somebody else issued and decides — on this request, right now — whether that token authorizes this call. ## Why the specification draws the line there Putting identity in the MCP server would mean every server author reimplements login, consent, MFA, token lifetime and revocation. Delegating to an existing authorization server means an operator can put an MCP server in front of an internal API and reuse the identity provider the organization already runs. It also keeps the blast radius small: a compromised MCP server leaks whatever data it fronts, but cannot mint credentials for anything. ## What the server actually does with the token On each request the server must establish four things. 1. **Integrity and origin** — the token really was issued by an authorization server this resource server trusts (verify the signature against the AS's keys, or call an introspection endpoint). 2. **Freshness** — it has not expired and is not used before its validity window. 3. **Audience** — the token was issued *for this MCP server*. MCP's profile is explicit that a server must reject a token that was not issued for it; accepting somebody else's token is the token-passthrough antipattern. 4. **Authorization** — the scopes or claims in the token cover the operation being attempted. The HTTP answers follow ordinary bearer semantics: `401` when no usable credential was presented, `403` with `error="insufficient_scope"` when the caller is authenticated but under-privileged for that particular call. ## Authorization is per request, not per connection This is where MCP differs from the mental model most people carry over from older client-server protocols. Revision 2026-07-28 made MCP a stateless protocol: the `initialize` handshake and the protocol-level session (with its `Mcp-Session-Id` header) that existed through 2025-11-25 were both removed. There is nothing to "log into". Each POST to the MCP endpoint carries its own protocol version and capabilities in `params._meta` and its own `Authorization` header, and a server must not rely on a previous request over the same connection to establish who is calling. Two practical consequences follow. First, any node behind a load balancer can serve any request, so token validation must be cheap and independent — cache the authorization server's signing keys rather than round-tripping introspection per call. Second, while the tool, prompt and resource sets a server exposes must not vary per connection, they *may* vary by the authorization presented — a token with fewer scopes may legitimately see a smaller `tools/list`. ## Which servers this applies to The OAuth profile is transport-level and HTTP-only. A stdio server is a local subprocess the host launched; there is no HTTP request to attach a bearer token to, and it takes whatever credentials it needs from its own environment. When an interviewer asks "how does an MCP server authenticate callers", the first move is to ask whether the server is local or remote. ## What a remote MCP server is not It is not an authorization server, so it should not be growing its own user table. It is not a token issuer. It must not accept a token minted for a different audience just because the token verifies. And it must not take the caller's token and replay it to an upstream API — when the MCP server needs to call something downstream, it uses credentials of its own, obtained separately.

  • Does the same authorization profile apply to a stdio MCP server?
    No. MCP's authorization profile is transport-level and HTTP-only. A stdio server is a subprocess the host launches over stdin/stdout, with no HTTP request to carry an `Authorization` header; it takes any credentials it needs from its own environment or configuration. The OAuth 2.1 resource-server rules apply to remote servers reached over the HTTP transport.
  • If there is no session in MCP 2026-07-28, when does the client attach the token?
    On every request. Sessions and the `Mcp-Session-Id` header were removed in 2026-07-28, so there is no connect-time authorization step to inherit from. Each POST carries the `Authorization: Bearer` header alongside the per-request `_meta` version and capabilities, and the server authorizes that request in isolation without consulting earlier ones.
  • Can a server expose a different tool list to different callers?
    Yes, by authorization. The rule is that the tool set must not vary per *connection*, but it may vary by the authorization presented on the request. A token with narrower scopes may legitimately see fewer tools in `tools/list`. What is forbidden is making the set depend on connection-scoped state, which no longer exists.

saying these in an interview costs you the question

  • Says the MCP server issues its own access tokens
  • Thinks the client logs in once per connection
  • Treats any valid signature as sufficient, ignoring audience
  • Applies the OAuth profile to local stdio servers
  • Confuses 401 for a missing token with 403 for missing scope

context