MCP doesn't mandate one auth method — it supports several depending on transport. For stdio servers, the parent process is implicitly trusted. For HTTP servers, you layer OAuth, API keys, or mTLS. Picking right depends on whether the server runs locally, in your network, or on the public internet.
Local (stdio) — no auth needed
MCP servers running as subprocesses of the client (stdio transport) inherit trust from the parent process. The client started them; they share the same user context. No auth layer required.
Network (HTTP) — bearer token
MCP-over-HTTP requests include Authorization: Bearer <token>. Server validates the token against its identity provider. Simple, works for internal services, fine for shared infrastructure.
OAuth 2.1 (production)
For multi-tenant public MCP servers, OAuth 2.1 with PKCE. Client redirects user to authorize, gets an access token, includes in MCP requests. Token has scopes that limit which tools/resources are accessible. This is what GitHub's MCP server uses.
Per-user scoping
Authenticated user_id should propagate into resource and tool calls. Reading file:///home/alice/notes should fail for user bob. The server enforces; the MCP protocol carries the identity via auth header.
Server identity (client trusts server)
Less commonly discussed: how does the client know it's talking to a real MCP server, not an impostor? mTLS for high-security setups. For HTTPS, TLS cert validation. For stdio, the parent process trusts itself.