← All articles

OAuth PKCE for MCP: Complete Guide

July 20, 2026·18 min read·MCPForge

OAuth PKCE for MCP: Complete Guide

As Model Context Protocol (MCP) servers increasingly connect AI applications to cloud services, internal APIs, and enterprise systems, authentication has become one of the most important aspects of MCP security.

Modern remote MCP deployments rely on OAuth 2.1 for delegated authorization.

However, OAuth alone is not sufficient.

To protect the Authorization Code flow against interception attacks, the MCP authorization specification requires clients to implement Proof Key for Code Exchange (PKCE). PKCE binds the authorization request to the client that initiated it, ensuring that a stolen authorization code cannot be exchanged for access tokens by an attacker. :contentReference[oaicite:2]{index=2}

In this guide, you'll learn how PKCE works, why it is mandatory for modern MCP clients, and how it secures OAuth-based authentication for Cursor, Claude Code, and other MCP-compatible applications.

Quick Answer

PKCE (Proof Key for Code Exchange) is a security extension for OAuth 2.1 that protects the Authorization Code flow. The MCP authorization specification requires clients to implement PKCE and, whenever technically possible, use the S256 code challenge method to prevent authorization code interception attacks. :contentReference[oaicite:3]{index=3}


What Is PKCE?

PKCE (pronounced "pixy") stands for Proof Key for Code Exchange.

It is an extension to the OAuth Authorization Code flow that prevents attackers from using a stolen authorization code.

Instead of relying solely on the authorization code, the client proves ownership by generating a secret value before authentication begins.

A simplified flow looks like this:

text
Client
   │
Generate Code Verifier
   │
Generate Code Challenge
   │
   ▼
Authorization Server

Later, when exchanging the authorization code for tokens, the client must present the original verifier.

Only the client that generated the verifier can successfully complete the exchange.


Why MCP Uses PKCE

Remote MCP servers often provide access to:

  • source code repositories
  • company documentation
  • cloud infrastructure
  • databases
  • productivity platforms
  • business APIs

A stolen access token could expose sensitive information.

PKCE significantly reduces this risk by preventing attackers from redeeming intercepted authorization codes. The MCP authorization specification therefore requires OAuth clients to implement PKCE for Authorization Code flows. :contentReference[oaicite:4]{index=4}


OAuth Authorization Code Flow Without PKCE

Without PKCE, the flow is relatively simple.

text
Client
   │
Authorization Request
   │
   ▼
Authorization Server
   │
Authorization Code
   │
   ▼
Client
   │
Exchange Code
   │
   ▼
Access Token

The problem is that if an attacker somehow obtains the authorization code before it is exchanged, they may also be able to obtain the access token.

PKCE was specifically designed to eliminate this attack vector. :contentReference[oaicite:5]{index=5}

How PKCE Works

PKCE introduces two additional values into the OAuth Authorization Code flow:

  • Code Verifier
  • Code Challenge

The client generates both before the user is redirected to authenticate.

text
Random Secret
(Code Verifier)
        │
        ▼
SHA-256 Hash
        │
        ▼
Base64URL Encode
        │
        ▼
Code Challenge

The Code Challenge is sent with the initial authorization request.

The Code Verifier never leaves the client until the authorization code is exchanged for tokens.

When the authorization server receives the verifier, it performs the same transformation.

If both values match, the request is accepted.

If they do not match, the request is rejected.

This ensures that only the client that initiated the login process can complete it.


Code Verifier

The Code Verifier is a high-entropy cryptographically random string generated by the OAuth client before authentication begins.

It acts as proof that the same client completing the authorization flow is the one that initiated it.

The verifier should:

  • be cryptographically random
  • remain secret
  • exist only for the duration of a single authorization flow
  • never be reused

Every new OAuth authorization should generate a completely new verifier.

Reusing verifiers weakens security and violates the intent of the PKCE specification.


Code Challenge

The Code Challenge is derived from the Code Verifier.

Instead of transmitting the verifier itself during the authorization request, the client sends only its transformed version.

text
Code Verifier
      │
 SHA-256 Hash
      │
Base64URL Encode
      │
      ▼
Code Challenge

Because the verifier is not exposed during the initial request, an attacker cannot reconstruct it from the challenge alone.

Later, when exchanging the authorization code for tokens, the original verifier is supplied.

The authorization server independently generates the challenge again and compares the results.


PKCE defines multiple challenge methods.

Modern OAuth deployments overwhelmingly use S256, which hashes the verifier using SHA-256 before encoding it.

Compared to sending the verifier directly, S256 provides significantly stronger protection against interception and implementation mistakes.

The MCP authorization specification states that clients must implement PKCE and should use S256 whenever supported, making it the expected choice for modern MCP deployments.

A simplified comparison looks like this:

MethodSecurityRecommended
PlainLowNo
S256HighYes

Unless you have a very specific compatibility requirement, S256 should always be used.


OAuth Authorization Flow with PKCE

Once PKCE is added, the Authorization Code flow gains an additional verification step.

text
                 Generate
              Code Verifier
                     │
                     ▼
             Create Challenge
                     │
                     ▼
Client ------------------------------► Authorization Server
         Authorization Request
         + Code Challenge
                     │
                     ▼
            User Authentication
                     │
                     ▼
            Authorization Code
                     │
                     ▼
Client ------------------------------► Authorization Server
         Authorization Code
         + Code Verifier
                     │
                     ▼
          Verify Challenge Match
                     │
         ┌───────────┴───────────┐
         ▼                       ▼
      Success                 Reject

Without the original verifier, the authorization code cannot be exchanged for tokens.

Even if an attacker somehow intercepts the authorization code, it is effectively useless without the verifier.

This additional verification is what makes PKCE such an effective defense against authorization code interception attacks.


PKCE in the MCP Authorization Specification

The MCP authorization specification builds on OAuth 2.1 and requires clients to support PKCE when using the Authorization Code flow.

This is no longer treated as an optional security enhancement.

Instead, it is considered a core part of secure authentication for remote MCP servers.

Before starting the OAuth flow, an MCP client should:

  1. Discover the Authorization Server.
  2. Retrieve its metadata.
  3. Verify that PKCE is supported.
  4. Generate a Code Verifier.
  5. Generate an S256 Code Challenge.
  6. Begin the authorization flow.

A simplified sequence looks like this:

text
Client
   │
Discover Authorization Server
   │
   ▼
Read Metadata
   │
   ▼
Supports PKCE?
   │
   ├── Yes → Continue OAuth
   └── No  → Reject Connection

This prevents clients from accidentally authenticating against servers that do not meet modern OAuth security expectations.


Authorization Server Metadata

Before authentication begins, an MCP client discovers information about the Authorization Server.

Among other capabilities, the metadata indicates which PKCE methods are supported.

A simplified discovery process looks like this:

text
Client
   │
Metadata Request
   │
   ▼
Authorization Server
   │
Returns Metadata
   │
   ▼
Supported PKCE Methods

If the server advertises support for S256, the client should use that method.

Modern OAuth deployments almost universally support S256, making it the preferred choice for interoperability and security.


Why PKCE Matters for Remote MCP Servers

Local stdio servers generally run on the user's own machine.

Remote MCP servers are different.

They communicate across networks and often provide access to cloud resources, enterprise systems, and sensitive company data.

Examples include:

  • GitHub repositories
  • cloud infrastructure
  • documentation platforms
  • issue trackers
  • customer databases
  • internal APIs

Because authentication occurs over the internet, protecting authorization codes becomes significantly more important.

PKCE provides this additional layer of protection without changing how users sign in.


PKCE in Cursor

Cursor supports OAuth-enabled remote MCP servers.

When connecting to a secured server, authentication follows the MCP authorization model.

From the user's perspective, the experience is straightforward:

  1. Connect to the remote MCP server.
  2. Sign in using the provider's login page.
  3. Grant access.
  4. Return to Cursor.
  5. Continue using MCP tools.

Behind the scenes, PKCE protects the Authorization Code exchange without requiring additional user interaction.

For developers, this means stronger security without increasing complexity for end users.


PKCE in Claude Code

Claude Code also supports OAuth authentication for remote MCP servers.

Its authentication flow follows the MCP authorization specification and includes support for PKCE, browser-based authentication, localhost callbacks, and automatic token management.

Although the user experience differs slightly from Cursor, the underlying security model remains the same.

Both clients rely on PKCE to ensure that intercepted authorization codes cannot be exchanged for access tokens.


Common PKCE Errors

Most PKCE-related issues stem from implementation mistakes rather than OAuth itself.

Invalid Code Verifier

If the verifier sent during token exchange does not match the original challenge, authentication fails.

Unsupported Challenge Method

Older OAuth implementations may not support S256.

Modern MCP clients should expect S256 support.

Reused Code Verifier

Each authorization request should generate a new verifier.

Reusing verifiers weakens security and may cause authentication failures.

Metadata Mismatch

If the Authorization Server advertises different capabilities than expected, the client may refuse to begin authentication.

Expired Authorization Code

Authorization codes are short-lived.

Attempting to exchange an expired code results in an authorization error.


Security Best Practices

When implementing OAuth for MCP servers, follow these recommendations:

  • Always implement PKCE.
  • Prefer the S256 challenge method.
  • Generate a new Code Verifier for every authorization request.
  • Never log Code Verifiers or access tokens.
  • Validate Authorization Server metadata before authentication.
  • Use HTTPS for every remote OAuth endpoint.
  • Store tokens securely.
  • Rotate refresh tokens according to your provider's recommendations.

Following these practices helps reduce the risk of token theft and improves compatibility with modern MCP clients.


Want to analyze your API security?

Import your OpenAPI spec and generate a Security Report automatically.

Conclusion

PKCE is one of the most important security improvements introduced to the OAuth Authorization Code flow.

Rather than relying solely on an authorization code, PKCE proves that the client exchanging the code is the same client that initiated the authentication request.

For MCP, this protection is particularly important because remote servers often expose sensitive business systems, cloud infrastructure, and proprietary data.

By implementing PKCE with the S256 challenge method and validating Authorization Server capabilities before authentication begins, MCP clients can establish secure OAuth connections while remaining fully compatible with the latest authorization specification.

Continue learning:

Frequently Asked Questions

What is PKCE in MCP?

PKCE (Proof Key for Code Exchange) protects the OAuth Authorization Code flow against authorization code interception attacks.

Is PKCE required for MCP?

Yes. The MCP authorization specification requires clients to implement PKCE for OAuth Authorization Code flows. :contentReference[oaicite:0]{index=0}

Which PKCE method should be used?

Clients should use the S256 code challenge method whenever technically possible, as required by OAuth and the MCP authorization specification. :contentReference[oaicite:1]{index=1}

Does Cursor use PKCE?

Cursor follows the MCP authorization model for OAuth-enabled remote MCP servers.

Does Claude Code use PKCE?

Claude Code supports OAuth-based authentication for remote MCP servers following the MCP authorization specification.

What is a code verifier?

It is a cryptographically random secret generated by the client before the OAuth flow begins.

What is a code challenge?

It is a transformed version of the code verifier that is sent during the authorization request.

Why is S256 preferred?

S256 hashes the verifier before transmission, making interception attacks significantly more difficult.

Does PKCE replace OAuth?

No. PKCE is an extension that strengthens the OAuth Authorization Code flow.

Is PKCE only for public clients?

PKCE originated for public clients but is now recommended broadly and required by the MCP authorization specification.

Check your MCP security posture

Generate a Security Score, detect risky tools, and review permissions before exposing APIs to AI agents.