ByHeartAI
Advanced8 min read

MCP Authentication & Authorization

Remote MCP uses OAuth 2.1: the user signs in, a token is minted for that server, and the server rejects anything else — local stdio servers skip OAuth and read credentials from the environment.

Explain like I'm new to AI

Two different situations, two different keys:

  • Local server on your laptop (stdio): the host started it. Secrets live in environment variables. OAuth would be theater.
  • Remote server on the internet (HTTP): many users, many hosts. That's OAuth 2.1. You sign in, a token is issued only for that MCP server, and the server checks it on every call.
Remote MCP uses OAuth 2.1. Tokens are bound to one server; local stdio servers use env credentials instead.

The sentence to remember: a token for server A must not work on server B. That's the audience check.

Mental model

A hotel key card encoded for room 412. The lock on 412 opens; the lock on 415 does not, even though both cards came from the same front desk. OAuth audience (aud / resource indicator) is that room number. Token passthrough is lending your 412 card to a courier who then tries every door.

How it works

For Streamable HTTP:

  1. The host starts an OAuth 2.1 authorization code flow with PKCE.
  2. The client sends the MCP server's URI as the resource (RFC 8707) so the token is bound to that server.
  3. The server validates issuer, audience, expiry — and does not forward that token to GitHub/Stripe/your DB. It uses a separate upstream credential.
  4. Client identity is moving from Dynamic Client Registration (DCR) to Client ID Metadata Documents (CIMD). DCR still works for now; new work should use CIMD. Clients must validate the iss parameter (RFC 9207) before redeeming a code.

Enterprise Managed Authorization (EMA) is an official extension for companies that want a gateway to broker identity, not every server talking to every identity provider.

Real-world example

You connect Sentry's remote MCP from Cursor. A browser opens, you sign in to Sentry, Cursor stores a token whose audience is Sentry's MCP. That token is useless against your internal finance MCP even if both use the same company identity provider — each server checks aud.

Technical explanation

MCP servers on HTTP are OAuth 2.0 resource servers. Important rules from the spec and security best practices:

  • Reject tokens not issued for you. Audience mismatch = 401, not "close enough."
  • No token passthrough. Upstream APIs get a token minted for them, issued to the MCP server as client.
  • PKCE is mandatory; redirect URIs match exactly.
  • Credentials are bound to the issuer that minted them — no reuse across authorization servers.
  • application_type exists so desktop/CLI apps with localhost redirects aren't rejected.
  • Request all scopes an operation needs in one challenge (don't drip-feed).
  • stdio transports SHOULD NOT use OAuth; env vars are the right pattern.

Authorization is where implementers spend the most time. Get audience and passthrough right before adding fancy scopes.

Common mistakes

Common mistake

Forwarding the client's bearer token to an upstream API. The spec forbids it. It breaks audience checks, muddies audit logs, and turns your server into a proxy for stolen tokens.

  • Accepting any JWT from "our company IdP" without checking aud.
  • Putting OAuth on a local stdio server, or an API key in a remote URL query string.

When to use it

  • OAuth for every remote multi-user server. Env credentials for local stdio. EMA / a gateway when an enterprise needs one policy plane.

When NOT to use it

  • Don't skip auth on a public HTTP MCP "because it's only listing docs" — listings still leak, and tools get added later.

Alternatives

  • Mutual TLS or network isolation in addition to OAuth, not instead of audience-bound tokens for internet-facing servers.

Quick quiz

Question 1 of 3

How should a remote (HTTP) MCP server authenticate callers?

Question 2 of 3

What is token passthrough, and is it allowed?

Question 3 of 3

True or false: local stdio MCP servers should use OAuth 2.1.

Related concepts

  • MCP Security Risks & Best PracticesMCP's real risks are poisoned tool descriptions, confused-deputy OAuth, token passthrough, and untrusted servers — treat catalogs as untrusted.
  • Consuming an MCP ServerA host consumes MCP by connecting a client per server, mapping the catalog into function calling, and enforcing allow-lists and approvals.
  • Agent Permission BoundariesLeast privilege for agents is a stack — caller identity, tiny tool kits, schema-checked args, human approval, sandbox — so a swayed model cannot exceed the job.

Further reading

NextBuilding an MCP Server

Last reviewed: 2026-09-04 · Written by ByHeart AI · Reviewed by ByHeart AI