Xiaobai

Xiaobai

Developer · Builder

Building AI engineering systems, developer tools and long-term digital assets at XBSTACK.

About Xiaobai & XBSTACK →
MCP OAuth Authentication in Practice: Why Remote MCP Servers Can't Go Unprotected

MCP 2026-07-28 OAuth: Protected Resource Metadata, CIMD, and Tool Authorization

MCP 2026-07-28 OAuth for Streamable HTTP: Protected Resource Metadata, Resource Indicators, issuer validation, CIMD, scopes, and Tool authorization.

Published · 2026-06-097 min readXBSTACK
#mcp#oauth#authorization#remote-mcp#mcp-server#tool-scope#ai-agent-security

What This Guide Covers

  • Why can’t remote MCP Servers be exposed directly to the public internet?
  • What is the difference between MCP Authorization and a standard API Key?
  • What is Protected Resource Metadata?
  • How does an MCP Server discover its Authorization Server?
  • How are Bearer Tokens, Scopes, and Resource Indicators used in MCP?
  • How to prevent different users from invoking the same set of high-risk tools?

Who This Guide Is For

  • Developers who have already migrated their MCP Server from stdio to Streamable HTTP.
  • Those looking to deploy an MCP Server on a VPS, via Cloudflare Tunnel, or within a corporate intranet.
  • Designers of permission models for remote tool invocation in Claude or Cursor.
  • Full-stack developers concerned with MCP OAuth, tokens, scopes, and tool permission boundaries.

1. Local vs. Remote MCP Security Boundaries Are Fundamentally Different

Where This Article Fits in the MCP Series

This article specifically addresses authentication and authorization for remote MCP servers. For deployment, see MCP Streamable HTTP in Practice; for protocol boundaries, see MCP 2026-07-28 Protocol Boundaries; and for security governance, see MCP Security Best Practices.

Direct answer: MCP 2026-07-28 does not require OAuth for every implementation, but a protected remote Streamable HTTP server should follow the current Authorization specification. The server publishes RFC 9728 Protected Resource Metadata; the client discovers the authorization server from that metadata, sends the RFC 8707 resource parameter in authorization and token requests, validates iss under RFC 9207, and prefers CIMD or pre-registration over new DCR dependencies. A valid token still does not authorize every Tool: resource, tenant, Tool, and argument permissions remain server-side checks.

Practical Review Checklist

Before adding OAuth to your MCP Server, ensure you have clarified the following:

  • Which tools are read-only, and which have side effects such as writing, deleting, sending, transferring funds, or deploying code.
  • Whether scopes can precisely limit access to specific tools or resources, rather than granting a single token access to all capabilities.
  • Whether the server defaults to denying execution when tokens expire, are revoked, or fail to refresh.
  • Whether tools/list is filtered by permissions when different users connect to the same remote MCP Server.
  • Whether audit logs record the authorized subject, invoked tools, resource scope, and reasons for denial.

The default trust for a local MCP Server stems from the local environment, whereas the default assumption for a remote MCP Server must be “do not trust any request.”

In local stdio mode, Claude or Cursor launches the MCP Server directly as a child process. The security boundary is protected by the OS kernel. Unless your machine itself is compromised, no one can bypass the client to invoke your tools.

However, when you migrate the MCP Server to remote Streamable HTTP, the situation changes fundamentally: Claude / Cursor → Network → Gateway / Proxy → MCP Server → Files / Database / APIs

Once connected to the public internet or a team intranet, your MCP Server faces the following core risks:

  • Unauthenticated Access: Anyone who knows your URL can invoke your tools.
  • Token Leakage: If you rely solely on simple API keys, leaked credentials make it difficult to revoke permissions granularly.
  • Privilege Escalation: User A might induce the AI to invoke resource tools belonging to User B.
  • Injection Attacks: LLMs may be induced by prompt injection to execute high-risk tools without authorization.

2. What Exactly Does MCP Authorization Solve?

MCP Authorization does not solve “whether the model can call tools”; rather, it solves “which Client can represent which user to invoke which restricted tools.”

Under the current MCP 2026-07-28 specification, Authorization is optional for MCP implementations and applies to HTTP-based transports. Once a server is a protected resource, it should follow the specified OAuth discovery, resource/audience, and issuer-validation flow. Because the core protocol is stateless, authorization is not a one-time connection check; protected requests must continue to be validated independently.

We need to distinguish between three layers of security:

  • Authentication: Verifying “who you are” (typically the MCP Client or the user behind it).
  • Authorization: Verifying “what you can call” (i.e., the Scope carried by the Token).
  • Tool Scope: Within the MCP Server, determining which specific list of Tools to expose based on identity.

3. What is Protected Resource Metadata?

Protected Resource Metadata can be understood as: The MCP Server telling the Client, “If you want to access me, this is where you should get authorization.”

MCP Servers should not leave Clients guessing about authorization methods blindly. The specification requires MCP Servers to implement the OAuth 2.0 Protected Resource Metadata mechanism to declare information about protected resources, particularly the list of trusted Authorization Servers.

This ensures interoperability within the MCP ecosystem: When a standard MCP Client (such as the Claude desktop app or a custom Agent) discovers a remote Server, it can automatically guide the user through the OAuth flow by reading the metadata.


4. How does Authorization Server Discovery work?

Remote MCP Servers should inform Clients of the authorization entry point through standard discovery mechanisms, rather than hardcoding the token endpoint in documentation.

The current specification requires clients to support both Protected Resource Metadata discovery paths:

  1. 401 Unauthorized challenge: the server may include a resource_metadata URI in WWW-Authenticate, optionally with the scopes required for the current operation.
  2. RFC 9728 well-known discovery: when a usable challenge metadata URL is absent, the client must try the MCP-endpoint path and site-root well-known URIs in the specified order.

After retrieving Protected Resource Metadata, the client reads authorization_servers and performs RFC 8414 / OpenID Connect discovery for the chosen authorization server. Client IDs, tokens, and registration state are issuer-specific and must not be reused across authorization servers.


5. Two 2026-07-28 Hardening Boundaries: Issuer Validation and CIMD

RFC 9207 issuer validation

Before redirecting the user agent, the client records the issuer from validated authorization-server metadata. If the authorization response contains iss, it must be compared against that recorded issuer under RFC 9207; when metadata declares authorization_response_iss_parameter_supported=true, a missing iss is a rejection condition. This reduces authorization-server mix-up risk.

Prefer Client ID Metadata Documents over new DCR dependencies

The current MCP registration priority favors Client ID Metadata Documents (CIMD) or pre-registration. Dynamic Client Registration remains for backward compatibility but is deprecated. New clients should not assume that every authorization server must expose open DCR for MCP interoperability.


6. Minimal Remote MCP Authentication Architecture

To enable secure remote calls, a typical architecture looks like this:

Claude / Cursor (Client) ↓ Initiates HTTP request with Access Token ↓ Remote MCP Server (Resource Server) ↓

  1. Validate Token validity
  2. Validate Scope (check if it includes tool:call permission)
  3. Validate Resource Indicator (ensure the Token was issued for this server) ↓ Tool-layer logic validation (isolate environments based on User ID) ↓ Execute specific tools and return results

6. Why are API Keys insufficient?

API Keys are suitable for personal experimentation but not for multi-user, remote, revocable, or auditable MCP services.

In production environments, API Keys have significant drawbacks:

  • They cannot express user identity: Keys are typically static, making it difficult to distinguish which end-user is making the call.
  • Fine-grained Tool Scopes are hard to manage: It is difficult to set dynamic permissions for an API Key, such as “only allowed to call read-only tools.”
  • Leakage risks: Once an API Key is leaked, it cannot be revoked for a specific session unless the entire Key is replaced.
  • Audit granularity: OAuth Tokens can bind richer metadata, facilitating the tracking of specific execution paths in logs.

7. How to Design Tool Scope?

A remote MCP Server shouldn’t just verify “whether the user is logged in”; it must also validate “whether the user is authorized to call this specific Tool.”

You should implement tool exposure logic based on scopes in your code. For example:

  • read:files: Only allows calling list_directory and read_file.
  • write:files: Allows calling write_file and delete_file.
  • admin:db: Allows executing high-risk operations like drop_table.

In the listTools handler of your MCP Server, you should dynamically return only the subset of tools the current user has permission to use based on the identity information in the request context, rather than exposing everything indiscriminately.


8. Resource Indicators: Tokens Shouldn’t Be Reused Everywhere

Tokens for a remote MCP Server should not be freely reused across multiple services.

According to the MCP specification’s reference to OAuth 2.1, when a client requests authorization and obtains a Token, it should include the resource parameter (Resource Indicators). This means that tokens issued by the authorization server are tagged with an “audience” marker.

If a token issued for https://api.xbstack.com/mcp does not contain authorization for https://internal.tools.local/mcp, the latter should reject the request. This effectively prevents tokens from being intercepted by man-in-the-middle attacks and used to compromise other sensitive MCP services.


9. Common Errors and Pitfalls (Error Logs)

1. Error: HTTP 401 Unauthorized

Symptom: The client cannot connect to the remote server. Cause: Usually due to a missing or expired token, or the WWW-Authenticate challenge format required by the server does not match the client’s expectations.

2. Error: Insufficient Scope

Symptom: Connection succeeds, but listTools returns an empty list, or errors occur when calling specific tools. Cause: Insufficient token permissions. Check whether the scopes requested during OAuth authorization cover the necessary tool permissions.

3. Risk: Multi-tenant Business-State Leakage

Trap: Even though the MCP 2026-07-28 core is stateless, a server can still put carts, approvals, cursors, uploads, or Tool caches into process-global memory and let User A’s state bleed into User B’s request. Mitigation: Keep protocol requests stateless. Persist cross-request business state behind explicit, unguessable handles bound to principal, tenant, resource, and expiry rules. Do not recreate an implicit session without an authorization boundary.


10. Practical Advice: The Security Baseline for Remote MCP Servers

Once a remote MCP server is reachable from the public internet or a team network, “only AI clients know this URL” is not a security control. If the server can reach files, databases, messaging, deployment systems, or other side-effecting tools, unauthorized access or token misuse can become a real system action.

I recommend that your remote MCP Server at least implements the following:

  • Enforce HTTPS transport; prohibit plaintext HTTP.
  • Use Bearer Token validation, even if it’s just static token verification initially (as a transitional measure).
  • Implement permission validation logic at the Tool level.
  • Enable detailed audit logs to record who called each tool and what input parameters were provided.

FAQ

Must an MCP Server use OAuth?

Local stdio servers don’t necessarily need it; however, remote MCP Servers that involve user resources, private data, enterprise tools, or production systems should use OAuth or an equivalent authentication and authorization mechanism.

Can API Keys replace OAuth?

For personal experimentation, yes. However, for multi-user, revocable, and auditable remote services, relying solely on API keys is not recommended.

Are MCP Authorization and Tool Scope the same thing?

No. Authorization answers “who can access the MCP Server,” while Tool Scope determines “which tools this user can invoke.”

Can a remote MCP Server rely solely on Cloudflare Access?

It can serve as the first layer of network and identity boundary, but the MCP Server itself must still perform Tool Scope and resource permission checks.

Why validate resource / audience?

To prevent a token from being used to access an MCP Server it shouldn’t be able to reach.


Continue Reading

Topic path / MCP

Continue from protocol details to production MCP governance

The MCP hub connects protocol fundamentals, transports, authentication, security, JSON-RPC debugging and production deployment without splitting the search intent across isolated guides.

More to Explore

Topic hub →
MCP Filesystem Server in Practice: Enabling Claude / Cursor to Securely Read Local FilesBuild a secure MCP Filesystem Server for Claude or Cursor with Roots, path allowlists, read-only tool scope, symlink/path checks, Prompt Injection defenses, and audit boundaries.MCP -32700 Parse Error: stdout Pollution, Tool List Failed, and Version ChecksFix MCP -32700 Parse Error by separating stdout/stderr, malformed JSON, startup failures, SDK v2 migration, and legacy 2025 versus stateless 2026-07-28 lifecycle issues.MCP StreamableHTTPClientTransport POST Stays Pending After SSE Disconnect: Issue #2739 ReproducedA v1 MCP StreamableHTTPClientTransport POST can remain pending until request timeout after request-scoped SSE error/EOF. XBSTACK reproduced Issue #2739 on SDK 1.29.0 and 1.30.0.How to Test an MCP Server Before Production: Read-Only Inspector PreflightTest an MCP Server before production with read-only server/discover and list checks for protocol version, catalogs, authorization, cache hints, and modern/legacy compatibility.

AI Engineering Weekly

Production changes, real failures, experiments and new XBSTACK assets.

Comments & evidence

DISCUSSION

Questions, verification and corrections

Sign in to comment. Every new comment is reviewed before publication; while pending, it is visible only to you and the administrator.

Sign-in required Reviewed before public
Loading the discussion…