
MCP Server Authentication: OAuth Tokens and Permissions Guide
How to authenticate clients on a corporate MCP server with OAuth: limit scopes, validate tokens, avoid passthrough and revoke access, per the MCP spec.
Want to apply this in your company?
Book a call with Juan →MCP Server Authentication: OAuth Tokens and Permissions Guide
To authenticate clients on a corporate MCP server, treat the server as an OAuth resource server. It does not issue tokens. It only validates tokens issued for it by your company's authorization server (usually your identity provider). The client discovers where to sign in, obtains a token with minimal scopes, and the server checks issuer, audience, expiry and scope on every call. Revocation works when tokens are short-lived and access can be cut at the identity provider.
Key takeaways
- The MCP specification treats authorization as optional for HTTP transports and builds on OAuth 2.1. If the server is remote and reaches company data, treat it as mandatory.
- The MCP server validates tokens and the identity provider issues them. Mixing the two roles creates a second login system to maintain and audit.
- A scope is not a permission. The scope limits what the client can ask for, but the server still has to check what that specific user is allowed to do in the source system.
- Never forward the token the client sent to your internal system. Use the server's own credentials for the downstream call.
- Revocation is a procedure, not a button that happens to exist. Decide in advance who cuts access, where, and how quickly it stops working.
What does the MCP specification say about authentication?
The protocol documentation is published on the official Model Context Protocol site, and the authorization section of the specification is the reference for this topic. It helps to separate official text from interpretation, and this article does that section by section.
From the official documentation, these are the points that matter most to a company:
- Authorization is optional. HTTP-transport servers that implement it should follow the specification. Local servers running over standard input and output (stdio) usually take credentials from the environment instead of running an OAuth flow.
- The MCP server acts as an OAuth resource server. The MCP client acts as an OAuth client. The authorization server can be separate from the MCP server, and in a company setting it should be.
- The server publishes protected resource metadata that says which authorization server it accepts. When it receives a call without a valid token, it answers 401 with a header pointing to that metadata.
- The client uses the authorization code flow with PKCE and states in the request which resource (which MCP server) the token is for. This ties the token to its audience.
- The server must accept only tokens issued for it and must not pass the received token on to third-party APIs. The specification calls this mistake token passthrough.
- The token travels in the Authorization header of every request, never in the URL.
The MCP authorization text has changed between versions of the specification. Before you design anything, confirm which version your client and your server implement and reread the matching section. For the general concepts of the flow, Google's OAuth 2.0 documentation is a neutral and clear reference.
How do you design the authentication flow step by step?
The plan below combines what the specification describes with implementation recommendations. The recommendations are labeled as such.
- Step 1: choose the authorization server. Use the identity provider your company already runs (corporate login with two-factor authentication). Implementation recommendation: do not build token issuance inside the MCP server.
- Step 2: register the client. The specification allows dynamic client registration as well as pre-registered clients. Recommendation: in a corporate environment, pre-register each approved client with exact redirect URIs, so an unknown client cannot start a flow.
- Step 3: publish the protected resource metadata and make the server answer 401 with the right pointer when a token is missing. This lets compatible clients discover the login on their own.
- Step 4: require PKCE and the resource parameter in the token request. That way the token is born with your MCP server as its audience.
- Step 5: validate issuer, audience, expiry and scopes on every call. Reject anything that does not match, without error messages that reveal internal details.
- Step 6: set short lifetimes for the access token and rotation for the refresh token. The exact duration depends on your risk, and it should be a recorded decision, not an inherited default.
- Step 7: log every authorization decision (who, which client, which tool, allowed or denied), without storing the token itself or unnecessary personal data.
If the server is still being planned, How to Build an MCP Server for Internal Systems: Read-Only First helps you decide which tools exist before you decide who may call them.
How do you limit scopes and permissions in practice?
The most common mistake is a single broad scope, something like full access, adopted as a stopgap that becomes permanent. The least-privilege principle described in the OWASP authorization guidance applies directly: deny by default and grant the minimum needed for the task.
A design that tends to work has three layers:
- Scopes by domain and by type of action. Separate read from write, for example orders:read and refunds:request, instead of one generic scope per system.
- Per-tool authorization on the server. Each tool declares the scope it requires. If the token does not carry it, the call fails before touching the internal system.
- Per-record authorization. Even with the right scope, the server checks whether that user may see that record. A salesperson with a customer-read scope should not see another salesperson's accounts just because the scope allows reading customers.
The specification lets the server indicate the scopes it needs and lets the client ask for more scope when an action requires it, so you can start with read access and step up only when necessary. Implementation recommendation: actions that change money, stock, records or customer communication should require, in addition to the scope, a recorded human approval. This ties in with what we cover in Guardrails for AI Agents: Input, Output and Action Controls.
Another rule: the language model is not a security boundary. Malicious text inside a document can push the agent to request an improper action (OWASP describes this risk in its list of risks for LLM applications). That is why the barrier must live in the server, through token and scope, and not in the prompt instructions.
Why shouldn't you forward the user's token to the internal system?
The temptation is simple: the client sent a token, so the MCP server hands it to the ERP or CRM and moves on. The specification forbids this pattern for good reasons. The token was issued for the MCP server, not for the ERP. If the ERP accepts it, any compromised client gains an indirect path, and the audit trail loses its meaning, because the final system cannot tell who actually originated the call.
The correct design has two steps. The server validates the token it received and identifies the user and the scopes. Then, to talk to the internal system, it uses its own credential, with minimal permissions and stored as a secret, or it performs a token exchange at the identity provider when that provider supports it. Implementation recommendation: log the original user alongside the call to the internal system, so traceability is not lost.
The server's own credential also needs a lifecycle: where it is stored, who can read it, when it is replaced. Managing API Keys and Secrets for AI Agents: Storage and Rotation covers that side.
How do you revoke access when someone leaves or something goes wrong?
Revoking access has four layers, and it pays to have all four ready before the first incident:
- Disable the user at the identity provider. When a person leaves the company, no new tokens should be issued and refresh tokens should be invalidated.
- Revoke the refresh tokens and sessions of one specific client. Useful when a laptop is lost or an MCP client is compromised, without affecting the others.
- Let the access token expire quickly. Because the server validates the token locally, it only learns about a revocation when the token expires, unless it queries the provider. That is why a short lifetime is part of the revocation design, not just general security.
- A master switch on the server. A block list by user or by client, and a single setting that turns off write tools, for the case where the problem is the agent's behavior and not the credential.
Also define who has authority to trigger each layer and within what time. In an incident involving personal data, your legal team and data protection officer will need the logs. Check the guidance from Brazil's data protection authority (ANPD) and align what you record with the law, keeping what is necessary and nothing more. LGPD and Artificial Intelligence for Companies: What to Do is a good starting point.
Illustrative scenario: an orders MCP server for a support agent
Imagine a distributor that wants an agent answering customers about their orders, including over WhatsApp. The MCP server exposes three tools: look up an order, look up a customer, and request a refund. This is an illustrative scenario, unrelated to any real company.
The design applied would be this:
- The distributor's corporate login is the authorization server. The agent's MCP client is pre-registered, with a fixed redirect URI.
- The scopes are orders:read, customers:read and refunds:request. The support agent receives only the first two by default.
- The refund tool only creates a pending request. A person in operations approves it in another system, and the approval is recorded.
- The server uses its own read-only credential to query the ERP, and a separate, more restricted credential to create the request.
- Every call produces a log entry with user, client, tool and result. If the agent starts behaving strangely, the team turns off the refund tool without taking down the lookups.
The point of the scenario is not the technology but the separation: who gets in, what they can ask for, what the server decides on its own and what depends on a person. For the channel side, How to Integrate AI into Your Company's WhatsApp (2026 Guide) covers the operating decisions that sit outside the MCP server.
How do you apply this in a pilot: map, limit, pilot, transfer
The method we use for agents and integrations follows four moves, and they fit MCP server authentication well.
- Map: list which tools the server will expose, which data each one touches, and who today has permission to do that task manually. The matrix of human permissions is the starting point for your scopes.
- Limit: start with read tools, narrow scopes, short tokens and separate credentials per system. Write actions come later, with human approval.
- Pilot: release one real workflow to a few users, with authorization logs on and an agreed success criterion that includes legitimate denials and blocked improper attempts.
- Transfer: hand the internal team the revocation procedure, the secret rotation and the periodic scope review, and decide whether the server expands, adjusts or stops.
If the server is not yours but a third party's, the order changes: audit first. The walkthrough in How to Audit an MCP Server Before Installing It at Your Company applies before any login configuration.
Checklist before going to production
- The server runs over HTTPS only and accepts the token only in the Authorization header.
- There is a single identity provider, with two-factor authentication for whoever approves clients.
- Each approved client is registered with exact redirect URIs.
- The server validates issuer, audience, expiry and scope on every call.
- There is no token passthrough to internal or third-party APIs.
- Each tool declares the scope it requires, and write actions have human approval.
- The server checks permission per record, not only per scope.
- A written revocation procedure exists, with an owner and a time limit.
- Logs record authorization decisions without storing tokens or personal data beyond what is needed.
- Someone has been assigned to review scopes and registered clients at defined intervals.
Frequently asked questions
Does MCP require OAuth? No. The specification treats authorization as optional, and local stdio servers usually use credentials from the environment. For HTTP servers that access company data, the practical recommendation is to implement the flow described in the specification, because it brings standard discovery, a token bound to the server, and revocation through the identity provider.
Can I use a fixed API key instead of OAuth? You can, in small internal cases, but you lose per-user identity, fine-grained scopes and individual revocation. If you take that route, treat the key as a secret with an owner, minimal scope and rotation, and log which client used it. Once more than one person or agent uses the server, moving to OAuth usually pays off.
Who should issue the tokens, the MCP server or the identity provider? The identity provider. The specification separates the authorization server role from the MCP server role, and in a company this avoids maintaining a second login system. The MCP server is responsible for validating tokens and applying each tool's permissions.
How do I configure the client once the server is authenticated? Each client has its own way of registering the server and storing credentials. In Claude Code, for example, the scope you choose for the configuration (local, project or user) affects who inherits the access, and Configure MCP in Claude Code: Local, Project and User Scopes walks through that decision.