
OAuth Is Not Enough for MCP—Five Checks Before Exposing a Server

Five preflight checks for a remote MCP server cover the MCP authorization security requirements and the deployment controls around them: bind tokens to the intended server, verify PKCE, constrain redirects, authorize each tool call, and retain an audit trail without logging secrets. A successful OAuth sign-in proves that a client obtained a token; it does not prove that this server should accept the token or that the caller may run a particular tool.
A 2026 measurement study identified 7,973 live remote MCP servers, found that 40.55% exposed tools without authentication, and found at least one flaw in each of 119 testable OAuth-enabled servers. The OAuth result describes that testable group, not every deployment. It gives operators a reason to test the complete authorization path before making a server reachable.
1. Bind the token to this server
Begin with a request that has no token. Microsoft’s Entra MCP guidance treats the server as a protected API: return an HTTP 401 challenge pointing to protected-resource metadata, require an access token on every request, and validate it before running a tool. The metadata identifies the protected resource and its authorization server so a client can request a token for the endpoint it intends to call.
Pass: the metadata identifies the server URL the client uses in the OAuth resource parameter, and a token issued for that resource reaches tool execution only after validation. Send requests with no token, an expired token, and a valid token issued for another API; all must stop before a tool runs. Check signature, issuer, expiry, and intended audience with established validation middleware. The audience value must match the server identity configured with the authorization provider; do not assume its claim must literally contain the server URL.
Test the outbound boundary as well. If a tool calls an upstream API, the MCP server needs a separate credential issued for that API. Fail this check if the bearer token received from the MCP client is forwarded unchanged: accepting a token for one recipient does not grant permission to present it to another.
2. Make an intercepted authorization code unusable
PKCE is a check on the client and authorization server involved in the code flow. Inspect authorization-server discovery metadata for code_challenge_methods_supported before login. A capable MCP client should use S256 and refuse to proceed when the metadata does not establish PKCE support.
Pass: obtain a code using one PKCE challenge, then try to redeem it with a different verifier. The token endpoint must reject the exchange. In the deployment’s supported client flow, also try an authorization request without the required challenge and confirm it cannot quietly fall back to an unprotected exchange. These negative tests matter because a normal login demonstrates only the successful path.
PKCE ties redemption of a code to the client that started the request. It does not bind the resulting access token to the right MCP server, restrict a tool’s scope, or approve a consequential action. Those decisions belong to the other checks.
3. Pin redirects and keep consent tied to the client
Register the redirect URIs that clients will actually use. Pass: the authorization server accepts an exact registered destination and rejects one with a changed host, path, or other unregistered value. Redirect URIs must use HTTPS except for permitted localhost callbacks. The client should send a state value and discard a response whose state is absent or differs from the original request.
There is a separate consent boundary when an MCP proxy uses one static client ID to connect dynamically registered clients to a third-party authorization server. Test a newly registered client after another client has already been approved. The new client must receive its own user-consent decision before the proxy forwards it; an approval remembered for the proxy cannot silently authorize every client behind it.
Run both tests through the real authorization route, including any gateway or proxy that rewrites callback URLs. A valid token at the end of the flow cannot undo a code sent to an unregistered destination or consent applied to the wrong client.
4. Decide what each caller may run
Token validation identifies an acceptable credential. Authorization still has to decide whether its actor may invoke the requested tool against the requested resource. Define scopes around operations and check them at invocation: a read permission should allow its intended read operation but fail on a write or execute operation. Where agent identities use application roles, check the role claim against the tool’s policy as well.
Pass: use identities with different permissions to invoke the same tool. Missing scopes or roles must deny the call, and access to another user’s underlying resource must fail even when the token has a broadly valid scope. Listing or discovering a tool is not permission to execute it. Make the authorization decision again when the call is made, using the actor, operation, and target resource.
For a tool that can make a consequential change, specify whether human approval is required and test that a client instruction cannot bypass it. This is a deployment policy rather than a property PKCE or a valid signature can supply. Consent to an OAuth scope need not serve as standing approval for every action that scope could enable.
5. Trace decisions without retaining credentials
An audit record should explain a tool call without making its credentials reusable. Record the authenticated actor and client, the tool and target resource, the authorization outcome, and a request or trace identifier. Include denied calls as well as successful ones so an investigation can distinguish rejected attempts from actions that proceeded.
Pass: send one permitted call and one denied call through the gateway, application, error handler, and any upstream connector. The records should show where each call stopped or proceeded. They must not contain bearer or refresh tokens, authorization codes, client secrets, or full Authorization headers, including when token validation fails with an exception.
Keep request bodies out of routine security logs unless a specific investigation requires them and access is controlled; tool arguments can contain user data. A usable audit trail preserves the decision and its context while avoiding a second route by which someone could obtain a credential and repeat the action.
Also read:
Related articles


Microsoft Makes Hyderabad an AI Hub—but Service Availability Still Varies

What an MCP Server Actually Exposes—and What It Never Decides Alone

NASA Picks PRIMA for the Hidden Universe—but 2033 Is Not Guaranteed

ESA and Mistral Want Sovereign Space AI—the Agreement Sets No Delivery Date

A £5.3M Laser Project Wants to Keep Aircraft Aloft With Ground Power
Subscribe to our newsletter
Get the latest Web3, AI, and crypto news delivered straight to your inbox.