# Our MCP servers and clients are built on the official Python SDK (the mcp package on PyPI, FastMCP and the 2.x MCPServer). Several 2026 advisories now list fixes in mcp 1.30.0 and 2.2.0. Is upgrading enough, or do some fixes need settings we have to turn on?

**Short answer:** Upgrade to mcp 1.30.0 or later on 1.x, or 2.2.0 or later on 2.x (2.3.0 was the newest release on PyPI on November 11, 2026). That covers every advisory the Python SDK has published since mid-2026, and most of the fixes work as soon as you upgrade: request bodies over 4 MiB get 413, idle Streamable HTTP sessions are closed after 1800 seconds with at most 10000 open at once, client transports no longer follow redirects to another origin, client-side output-schema validation no longer fetches server-chosen $ref URLs, and the interactive OAuthClientProvider refuses authorization server metadata whose issuer doesn't match. Three fixes do nothing until you change code or settings. The token-audience check (GHSA-w4fh-qvv9-3v23) needs validate_token_resource=True plus AccessToken.resource returned from verify_token(); the unattended OAuth providers (GHSA-qx49-fqc8-xw99) keep following whatever authorization server the MCP server names until you pass issuer=; and OAuth client registrations stored before 1.30.0 stay unbound to an issuer until you clear them. If many users share one OAuth client, sessions are only isolated per user when your token verifier fills in AccessToken.subject.

## Checklist
1. Run pip show mcp (or uv pip show mcp) in every environment you deploy and write down the version, including copies pulled in by other packages; a server and a client in the same codebase can pin different versions.
2. Upgrade to mcp 1.30.0 or later (1.x) or 2.2.0 or later (2.x). There is no fixed 2.0.x release for the body-size limit, so anything still on 2.0.x has to move to 2.x latest.
3. Server with bearer auth: set validate_token_resource=True in AuthSettings, set resource_server_url to the audience your authorization server puts in tokens for your server, and return the token's aud from verify_token() as AccessToken.resource. With only the setting, every request gets 401. Until you upgrade, reject any token whose aud doesn't include your server inside verify_token().
4. Server shared by many users through one OAuth client (a hosted client or gateway): make verify_token() fill AccessToken.subject from the token's sub claim, so a session opened by one user can't be used by another holding a token for the same client.
5. Client using ClientCredentialsOAuthProvider or PrivateKeyJWTOAuthProvider: pass issuer= with the authorization server your credentials belong to. On 1.30.0 leaving it out only raises a DeprecationWarning, which Python hides by default, so search your code for both class names rather than waiting for a warning. Move off the deprecated 1.x RFC7523OAuthClientProvider, which has no issuer option.
6. Client with stored OAuth registrations: clear stored client information once after upgrading so the client registers again and the new record is bound to an issuer. If a client may already have connected to an untrusted MCP server, rotate its client secret and revoke its tokens at the authorization server.
7. Small hosts: lower session_idle_timeout, max_sessions and max_request_body_size to fit your memory, or run stateless_http=True where you don't need per-session state. Passing None disables a limit, so grep for it.
8. If you call server.experimental.enable_tasks() or still expose the deprecated WebSocket server transport on 1.x, check those two advisories separately (fixed in 1.27.2 and 1.28.1); the WebSocket fix also needs security_settings passed in, and the transport is gone in 2.x.

## Which MCP Python SDK security fixes work as soon as you upgrade to mcp 1.30.0 or 2.2.0?
- GHSA-fmmv-w9g8-j3gc (CVE-2026-109527, high): HTTP server transports and the SDK's OAuth endpoints read whole request bodies into memory before checking size, so one large request could grow memory by two to three times its size, with no credentials needed against the OAuth routes. Fixed in 1.29.1 and 2.1.0: every SDK HTTP endpoint answers 413 above a shared 4 MiB limit before parsing. Code that drives StreamableHTTPServerTransport directly, without the session manager, doesn't get the limit and must bound bodies itself.
- GHSA-84m7-p3x7-pcfv (CVE-2026-59951, high): in stateful Streamable HTTP mode, which is the default for FastMCP and the 2.x MCPServer, sessions never expired, a client DELETE left the entry registered and the number of sessions was unlimited, so ordinary short requests could grow memory until a restart. Fixed in 1.30.0 and 2.2.0 with session_idle_timeout (default 1800 seconds) and max_sessions (default 10000, then 503). The advisory says this bounds retention rather than removing it, and that authentication limits who can open sessions, not how many a token holder can open.
- GHSA-5h93-6whr-6q8j (CVE-2026-116685, moderate): the Streamable HTTP and SSE client transports, and the OAuth providers' own requests, followed redirects to any host, re-sending custom headers such as an X-API-Key and, on 307 or 308, the request body. Fixed in 1.30.0 and 2.2.0 with no code change: only same-origin redirects (or http to https on the same host) are followed. A client that reached its server through a cross-origin redirect stops connecting until you put the final URL in its config.
- GHSA-rwrf-2pqf-9j8j (CVE-2026-116686, moderate): when a server declared an outputSchema, the client validated each tool result with a resolver that opened any $ref it couldn't resolve locally, including http, https and file URLs, synchronously and with no timeout. A server could make your client fetch internal URLs or read local files from its own network position, or freeze every session in the process. Fixed in 1.30.0 and 2.2.0: references resolve only inside the schema the server sent, and a schema pointing outside it fails the call with RuntimeError.
- Earlier in 2026, 1.27.2 fixed two 1.x issues: HTTP transports routed requests to a session by session ID alone without checking the authenticated principal (GHSA-jpw9-pfvf-9f58, CVE-2026-52869), and the experimental tasks handlers let any client list, read and cancel other clients' tasks (GHSA-hvrp-rf83-w775, CVE-2026-52870).

## Which MCP Python SDK fixes need validate_token_resource, issuer= or other settings turned on?
- Token audience (GHSA-w4fh-qvv9-3v23, CVE-2026-116684, moderate): before the fix the SDK's server-side bearer authentication had no way to check that a token was issued for your server, so where one authorization server issues tokens for several services, a valid token for another service was accepted. The advisory says upgrading alone changes nothing: validate_token_resource is off unless you set it, and it will default to True in 3.0. You're affected if you use auth=AuthSettings(...) with token_verifier=, your authorization server serves other services too, and your verifier doesn't check aud.
- Issuer binding on the client (GHSA-qx49-fqc8-xw99, CVE-2026-115563, high): before the fix the MCP server a client connected to could decide where its OAuth credentials went, by naming its own authorization server or by serving metadata that presents your real one as the issuer, and receive the client_secret, authorization code and PKCE code_verifier, or a signed client assertion. The fixed client works out the expected issuer before fetching metadata on every path and binds stored registrations to it. The interactive provider gets that automatically; ClientCredentialsOAuthProvider and PrivateKeyJWTOAuthProvider don't until you pass issuer=, which becomes required in 3.0.
- Per-user sessions behind a shared OAuth client: the 1.27.2 session fix records the OAuth client ID with the token's issuer and subject when the verifier supplies them, and answers a different principal with the same 404 as an unknown session. If your verifier leaves subject empty and many users share one client, sessions are isolated per client, not per user.

## How do you test that the MCP Python SDK audience check, session limits and issuer binding are working?
- A dependency scanner only proves the version. For the audience check, send your server a token your authorization server issued for a different service and expect 401. For sessions, open sessions in a loop from a test client and confirm the server answers 503 at your max_sessions and that an idle session's ID answers 404 after the timeout. For bodies, POST just over max_request_body_size and expect 413.
- On the client side, point a test client at a server that redirects to another origin and expect an error naming the target, not a connection; serve a tool whose outputSchema has a $ref to an outside URL and expect the call to fail without your client fetching it; and for unattended providers, serve protected resource metadata naming a different authorization server and expect the client to refuse. Keep these in CI so a later refactor that drops a setting fails the build.

## Ask Rightshold (free, no key)
Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code (one-click setup: https://www.rightshold.com/start?ref=seo), then ask: "I just upgraded my Python MCP server to the patched SDK and turned on the audience check. Check what it serves now: has its tool list changed from what was recorded, and does any tool definition carry hidden text?"

```json
{
  "tool": "precall_check",
  "arguments": {
    "url": "<your server's https MCP URL>"
  }
}
```
- Free, no key. It probes the tool definitions your server serves now and compares them with any recorded fingerprint (unchanged, changed with a plain diff, or unreachable, never reported as unchanged), scans them for invisible text and reports standing security flags and tool-name collisions. An SDK upgrade shouldn't change your tools; if the diff shows it did, review that before your users' clients flag it. Checking a server doesn't register it.
- It doesn't read your installed mcp version, test the audience check, session limits, redirect handling or issuer binding, or inspect your stored OAuth registrations. Those are the tests above, and they belong in your own CI.

_Rightshold reports what an MCP endpoint serves and what it has on record about it. It doesn't scan your code, dependencies or configuration, and an unchanged answer isn't a finding that a server or client is patched. Advisory details are as published by the MCP Python SDK maintainers on GitHub and release dates as listed on PyPI, both read on November 11, 2026; advisories get updated, so confirm fixed versions on the linked pages before you upgrade._

## Sources
- [MCP Python SDK: GHSA-w4fh-qvv9-3v23, server bearer-token authentication accepts tokens issued for a different resource server (CVE-2026-116684)](https://github.com/modelcontextprotocol/python-sdk/security/advisories/GHSA-w4fh-qvv9-3v23)
- [MCP Python SDK: GHSA-qx49-fqc8-xw99, OAuth client could send credentials to an authorization server chosen by the MCP server (CVE-2026-115563)](https://github.com/modelcontextprotocol/python-sdk/security/advisories/GHSA-qx49-fqc8-xw99)
- [MCP Python SDK: GHSA-84m7-p3x7-pcfv, Streamable HTTP sessions were never reclaimed by default (CVE-2026-59951)](https://github.com/modelcontextprotocol/python-sdk/security/advisories/GHSA-84m7-p3x7-pcfv)
- [MCP Python SDK: GHSA-fmmv-w9g8-j3gc, HTTP server transports and OAuth endpoints read request bodies with no size limit (CVE-2026-109527)](https://github.com/modelcontextprotocol/python-sdk/security/advisories/GHSA-fmmv-w9g8-j3gc)
- [MCP Python SDK: GHSA-5h93-6whr-6q8j, HTTP client transports followed cross-origin redirects carrying custom headers and bodies (CVE-2026-116685)](https://github.com/modelcontextprotocol/python-sdk/security/advisories/GHSA-5h93-6whr-6q8j)
- [MCP Python SDK: GHSA-rwrf-2pqf-9j8j, client fetched server-chosen $ref URLs while validating tool results (CVE-2026-116686)](https://github.com/modelcontextprotocol/python-sdk/security/advisories/GHSA-rwrf-2pqf-9j8j)
- [MCP Python SDK: GHSA-jpw9-pfvf-9f58, HTTP transports served session requests without verifying the authenticated principal (CVE-2026-52869)](https://github.com/modelcontextprotocol/python-sdk/security/advisories/GHSA-jpw9-pfvf-9f58)
- [PyPI: mcp package release history](https://pypi.org/project/mcp/)

## Related
- [Which MCP TypeScript SDK version fixes the October 2026 server advisories, and why upgrading isn't enough](https://www.rightshold.com/answers/which-mcp-typescript-sdk-version-fixes-the-october-2026-server-advisories-and-why-upgrading-isnt-enough)
- [Can a malicious MCP server steal your OAuth refresh token or client secret?](https://www.rightshold.com/answers/can-a-malicious-mcp-server-steal-your-oauth-refresh-token-or-client-secret)
- [MCP OAuth wrong-audience tokens: what they are and how to defend](https://www.rightshold.com/answers/mcp-oauth-wrong-audience-tokens)
- [Can an MCP session ID or state handle be used to authenticate a user?](https://www.rightshold.com/answers/can-an-mcp-session-id-or-state-handle-be-used-to-authenticate-a-user)

_Not legal advice. Updated 2026-11-11. JSON: https://www.rightshold.com/answers/which-mcp-python-sdk-version-fixes-the-2026-advisories-and-what-you-still-have-to-turn-on.json_