With the MCP Python SDK vulnerability, a successful login could still end with credentials going to the wrong destination. An affected client could send a user to the real identity provider, then submit sensitive OAuth material to an endpoint chosen by a malicious MCP server, according to the maintainers’ advisory.
For teams handling AI agent security, the first task is to find affected HTTP clients and check their authorization settings. Install the patch, then follow through on configuration: some providers need an explicit issuer, and older stored registrations may still need repair.
Quick answer: The MCP Python SDK vulnerability can send a client’s OAuth credentials to an attacker-selected endpoint. Upgrade to mcp 1.30.0 or 2.2.0, or a later compatible release. Set issuer= for providers using pre-provisioned credentials, repair unbound registrations, and rotate secrets and revoke tokens if earlier exposure is possible.
What is the MCP Python SDK vulnerability?
The flaw sits in mcp.client.auth, the SDK’s OAuth client support. The Model Context Protocol, or MCP, connects applications to external tools and data. OAuth lets an application obtain authorization without collecting the user’s password.
The GitHub advisory identifies two connected weaknesses. The client did not consistently validate the authorization server’s identity, and credentials were not reliably tied to the server that issued them.
| Detail | Verified information |
|---|---|
| Advisory | GHSA-qx49-fqc8-xw99 |
| Package | mcp on PyPI |
| Disclosure | September 28, 2026 |
| Severity | High; CVSS v3.1 7.5 for unattended providers |
| Interactive flow | CVSS v3.1 6.5 because a person starts sign-in |
| CVE | No known CVE listed in the advisory at the research cutoff |
For MCP security, both checks matter: who signed in, and which service receives the credentials afterward.
Table of affected MCP Python SDK vulnerability versions: 1.x below 1.30.0 and 2.x below 2.2.0

Affected versions and who is at risk
The advisory defines these exact ranges for the MCP OAuth vulnerability:
| Release line | Affected range | First fixed release |
|---|---|---|
| 1.x | >=1.9.1,<1.30.0 |
1.30.0 |
| 2.x | >=2.0.0a1,<2.2.0 |
2.2.0 |
The range includes the prerelease 2.0.0a1. Check prerelease deployments too.
An affected client connects over HTTP using one of the SDK’s OAuth providers. It holds credentials for a legitimate authorization server and may connect to an MCP server the application cannot fully trust. Assess those conditions together.
Check for OAuthClientProvider, ClientCredentialsOAuthProvider, PrivateKeyJWTOAuthProvider, and the deprecated 1.x RFC7523OAuthClientProvider.
The maintainers exclude SDK-based MCP servers, stdio clients, and clients that attach their own tokens or headers from this advisory. That exclusion applies only to this flaw.
If an application mainly acts as a server but also makes outbound client connections, review those connections separately.
How OAuth discovery crossed the trust boundary
The MCP authorization specification defines distinct roles for clients, protected resource servers, and the authorization servers that issue access tokens.
Discovery tells the client where authorization happens. The resource server advertises authorization servers, and the client retrieves metadata containing their endpoints and an issuer identifier. Under RFC 8414, that identifier must match the issuer used to build the metadata request. A mismatch means the client must reject the metadata.
Existing credentials also need to stay tied to the server that issued them. The MCP discovery requirements call for separate registration state for each authorization server.
The SDK patch explanation describes the failure in the legacy fallback. Without protected resource metadata, the client could skip validation, then let attacker-controlled metadata influence whether existing credentials belonged to the selected server.
The fix establishes the expected issuer before using that metadata. It also covers discovery during a 403 insufficient_scope challenge.
The MCP OAuth vulnerability undermined both identity checks and credential binding. For Model Context Protocol security, those protections must work through fallback and reauthorization as well as the normal flow.

The attack flow explained
Cycode’s researcher disclosure describes an interactive attack with this sequence:
- A client holding legitimate OAuth credentials connects to an attacker-controlled MCP server.
- The server directs discovery toward metadata it controls, including through the legacy fallback.
- The metadata points to a real authorization endpoint but a malicious token endpoint.
- The user signs in with the real provider, which returns an authorization code to the client.
- The vulnerable client submits the code, PKCE verifier, and applicable client secret to the malicious endpoint. The attacker can then try to redeem them with the legitimate provider.
The login page can be genuine throughout this OAuth credential theft attempt. What the attacker can access depends on the credentials, grant, and permissions involved. The flaw does not automatically open every account the user owns.
Machine-to-machine grants have no browser sequence. Check unattended jobs separately; human approval does not always stand between a connection and credential exposure.
Why PKCE did not prevent the leak
Proof Key for Code Exchange, or PKCE, binds an authorization code to a verifier generated by the client. As RFC 7636 specifies, the authorization server checks that verifier against the earlier challenge before issuing tokens.
An intercepted code is harder to misuse when the attacker lacks its verifier. But PKCE does not authenticate the token endpoint a vulnerable or misconfigured client selects.
In the demonstrated attack, the client handed over both values. The attacker did not have to break the cryptography because the client supplied the required proof.
The MCP security fix is to repair discovery and credential binding while keeping PKCE enabled. Keep TLS checks intact too.
Check your Python deployment
Use the same Python interpreter and environment that run the client:
python -m pip show mcp
python -c "from importlib.metadata import version; print(version('mcp'))"
The pip command shows installed package metadata, while Python’s importlib.metadata.version() returns the installed distribution version. These are inventory checks, not exploitability tests.
Assessing the MCP Python SDK vulnerability also means checking how the application uses that package:
- Check dependency declarations and lockfiles, including indirect dependencies.
- Find the OAuth provider attached to the HTTP client or transport.
- Trace the source of client secrets, signing configuration, and registrations.
- Identify the MCP destinations the application can contact.
- Repeat these checks for workers, containers, scheduled jobs, and production services.
Keep the runtime version, provider, trusted issuer, credential-store owner, and permitted destinations together in your MCP security inventory.
That gives your Model Context Protocol security review a useful starting point. The version identifies an affected dependency. Configuration and connection history tell you more about possible exposure.
How to fix the MCP Python SDK vulnerability
1. Upgrade within the intended release line
For an application remaining on 1.x:
python -m pip install --upgrade "mcp>=1.30.0,<2"
For an application already using 2.x:
python -m pip install --upgrade "mcp>=2.2.0,<3"
Update the dependency declaration and lockfile through the project’s usual workflow. Then rebuild the deployment artifacts and check the version running in the deployed environment. Retain any package extras the application uses.
Read the 1.30.0 release notes or 2.2.0 release notes before rollout. The commands set minimum fixes for this advisory. Check whether newer security updates also apply.

2. Set the trusted issuer for pre-provisioned credentials
Set issuer= on ClientCredentialsOAuthProvider and PrivateKeyJWTOAuthProvider. As the SDK’s OAuth guide explains, leaving it out still allows discovery to choose the authorization server. The new warning alone does not restrict where credentials go.
The helper below uses the constructor documented in the OAuth guide and 1.x source. Supply your existing TokenStorage implementation:
import os
from mcp.client.auth import TokenStorage
from mcp.client.auth.extensions.client_credentials import (
ClientCredentialsOAuthProvider,
)
def build_oauth(storage: TokenStorage) -> ClientCredentialsOAuthProvider:
return ClientCredentialsOAuthProvider(
server_url=os.environ["MCP_SERVER_URL"],
storage=storage,
client_id=os.environ["OAUTH_CLIENT_ID"],
client_secret=os.environ["OAUTH_CLIENT_SECRET"],
issuer=os.environ["OAUTH_ISSUER"],
)
Take OAUTH_ISSUER from trusted identity-provider configuration, including any tenant or realm path. This value identifies the authorization server, which may differ from the MCP endpoint. Do not copy it from metadata an untrusted MCP server supplies.
Attach the provider to the HTTP client’s auth setting through your release’s transport API. You still need deployment configuration and an existing token store to use this helper; it does not provide a complete connection script.
3. Repair stored registrations and deprecated providers
Older registration records need a separate check. The 1.x patch notes explain that saved records without an issuer remain unbound after the update.
Clear the affected stored OAuth client information once so the client can register again with issuer binding. For a manually provisioned registration record, set its issuer from trusted configuration instead.
Replace the deprecated RFC7523OAuthClientProvider, which has no issuer option. Before changing providers, confirm that the replacement grant works with your authorization server.
4. Validate the deployed behavior
Use test credentials in a controlled environment. Check that legitimate authorization succeeds and that mismatched issuer metadata stops the flow before credentials are sent. Include legacy discovery and scope escalation if your application supports them.
Investigate an OAuthFlowError instead of suppressing it to restore connectivity.

Responding to possible OAuth credential theft
The advisory calls for rotating secrets and revoking tokens if an affected client may have contacted an untrusted server. Applying the fix does not invalidate credentials an attacker may already hold.
Work through the response in this order:
- Stop affected connections to untrusted destinations.
- Preserve the available connection history, deployment versions, and authorization logs.
- Rotate potentially exposed client secrets at the authorization server.
- Use the provider’s supported controls to revoke associated tokens or grants.
- Repair the configuration and registration state before reconnecting.
Look for unexpected destination hosts, registration changes, token issuance, and unusual client activity. Use anomalies to guide the investigation; they do not prove compromise on their own. Keep secrets, codes, and verifiers out of diagnostic logs.
For PrivateKeyJWTOAuthProvider, the documented exposure is a signed assertion. That does not establish that the signing key was extracted. Work with the identity team to assess assertion reuse and token activity, and rotate keys when the evidence or policy calls for it.
CyberInfos Analyst Insight: the operational lesson
CyberInfos assessment: AI agent security reviews should cover how an agent authenticates before it calls a tool. Allowing the tool does not settle every question about the credentials used to reach it.
Consider a hypothetical reporting worker with preconfigured credentials whose MCP destinations can change. Who approves a new destination? Which issuer may receive the worker’s credentials? Does its registration binding survive an upgrade?
For Model Context Protocol security, give client identities narrow permissions and a named credential owner. Review destination changes alongside dependency updates. The worker example is hypothetical; it does not describe another incident.
The primary sources reviewed describe the vulnerability and a researcher demonstration. They establish neither a confirmed exploitation campaign nor a victim count.

MCP security checklist
- Inventory deployed versions and OAuth providers.
- Upgrade affected runtimes and rebuild their deployment artifacts.
- Set the trusted issuer on both pre-provisioned provider types.
- Recreate or correctly bind older registration records.
- Replace deprecated authentication providers where applicable.
- Rotate exposed secrets and revoke associated tokens or grants.
- Validate issuer rejection with test credentials before rollout.
- Restrict and review newly added MCP destinations.
- Include provider configuration in AI agent security reviews.
- Keep secrets out of application logs and incident tickets.
Frequently asked questions
Does the MCP Python SDK vulnerability affect servers?
SDK-based servers acting only as servers are excluded from the advisory. If the application also makes outbound connections as an OAuth client, assess that behavior separately.
Is version 1.29.1 affected?
Yes. Version 1.29.1 falls within the MCP OAuth vulnerability range. Whether credentials were exposed also depends on the OAuth configuration and the destinations contacted.
Is installing the fixed version enough?
Not always. Pre-provisioned providers also need a trusted issuer setting. Older unbound registrations need cleanup or correction, depending on the provider and storage model.
Should I disable PKCE?
No. Keep PKCE enabled and fix destination validation. Its protection against intercepted codes depends on keeping the verifier secret.
Does an exposed client secret reveal the user’s password?
No. A client secret authenticates the application. Misusing it can still expose resources the application may access. Check issued tokens, scopes, and client capabilities without assuming the user’s password was disclosed.
Is exploitation in the wild confirmed?
The primary sources reviewed do not establish an active campaign. That leaves uncertainty about past exploitation. Assess your own connection history and identity telemetry.
Your next action
Start with one production client. Record its SDK version, OAuth provider, trusted issuer, and registration store, then apply the relevant fixes. Repeat that review across deployments. Closing the MCP Python SDK vulnerability requires an updated package, correct credential binding, and a separate response wherever earlier exposure is possible.
