mcp-migration
Is your MCP server ready for the 2026-07-28 spec?
The 2026-07-28 revision
is the largest change to the Model Context Protocol since launch: the protocol
goes stateless. Mcp-Session-Id is gone, the initialize handshake is
gone, any request can land on any server instance, list responses must carry
cache metadata, and Roots/Sampling/Logging are deprecated. Nearly every
existing server was written against the stateful spec.
mcp-migration finds your hidden session dependencies before your clients do:
mcp-migration scan <path>— static scan of a server's source tree (Python, TypeScript, Go, C#, Java, ...). Flags removed protocol features, deprecated primitives, pre-2.0 SDK pins, and — for Python — the classic hazard: in-memory state mutated inside tool handlers, which silently breaks once requests stop sticking to one instance.mcp-migration probe <url>— points at a running Streamable HTTP server, speaks the old protocol to it, and reports a readiness checklist: does it mint sessions, does it refuse sessionless requests, does it emitttlMs/cacheScope/resultType, does it implementserver/discover, which error code does it use for missing resources.
Every finding cites the SEP that changed the behaviour and says what to do instead. Zero dependencies, Python ≥ 3.10.
Install
pip install mcp-migration
Scan a source tree
$ mcp-migration scan path/to/server
server.py:12 warning S004 handler 'add_to_basket' mutates module-level 'BASKETS' — this state is lost when requests land on another instance
transport.py:88 blocker S001 references the removed Mcp-Session-Id header
pyproject.toml:14 info C302 python `mcp` requirement '>=1.2.0' predates the 2026-07-28 line — test against mcp==2.0.0b1
3 file(s) checked against MCP 2026-07-28: 1 blocker(s), 1 warning(s), 1 info(s)
Exit code is 1 when blockers are found (--strict: on any finding), so it
drops straight into CI. --format json for machines, --format md for a
migration report you can paste into an issue:
mcp-migration scan . --format md > MIGRATION.md
Probe a live server
$ mcp-migration probe https://example.com/mcp
MCP 2026-07-28 readiness probe — https://example.com/mcp
[FAIL] No protocol-level session
server minted an Mcp-Session-Id on initialize; the header and the session are removed in 2026-07-28
[FAIL] Serves sessionless requests
tools/list without initialize was refused (HTTP 400: Bad Request: no valid session ID); in 2026-07-28 any request may be the first one an instance sees
[NOTE] Cache metadata on list results
tools/list result has no ttlMs/cacheScope (required by SEP-2549)
...
Authenticated servers: --header 'Authorization: Bearer ...' (repeatable).
What it checks
| Code | Severity | Change |
|---|---|---|
| S001 | blocker | Mcp-Session-Id / protocol sessions removed (SEP-2567) |
| S002 | blocker | initialize/initialized handshake removed (SEP-2575) |
| S003 | blocker | SSE resumability / Last-Event-ID / event stores removed (SEP-2575) |
| S004 | warning | In-memory state mutated across tool calls (Python AST) |
| S005 | warning | Handler depends on the session object (Python AST) |
| R101 | blocker | tasks/list / tasks/result removed — Tasks is now an extension (SEP-2663) |
| R102 | blocker | resources/subscribe |
| R103 | blocker | ping, logging/setLevel, notifications/roots/list_changed removed (SEP-2575) |
| R104 | warning | Server-initiated requests become Multi Round-Trip Requests (SEP-2322) |
| R105 | warning | notifications/elicitation/complete / elicitationId removed (SEP-2322) |
| D201–D205 | warning | Roots, Sampling, Logging, HTTP+SSE transport, includeContext deprecated (SEP-2577, SEP-2596) |
| C301 | warning | Resource-not-found error code -32002 → -32602 |
| C302 | info | SDK pinned below the 2026-07-28 beta line |
| C303–C307 | info | New-spec adoption: ttlMs/cacheScope, resultType, server/discover, deterministic tool order, legacy GET stream |
mcp-migration rules prints the full list with migration hints.
What it is not
- Not a conformance suite — the official one is
modelcontextprotocol/conformance,
which tests new implementations against the spec.
mcp-migrationlooks at existing servers for migration hazards. - Not a codemod — TypeScript users should also run
npx @modelcontextprotocol/codemod@beta v1-to-v2 .;mcp-migrationtells you about the behavioural hazards a codemod can't rewrite. - Static findings are heuristics. S004 in particular flags state that may be a deliberate per-process cache — review, don't blindly delete.
The spec is a release candidate (locked 2026-05-21, final on 2026-07-28); rules track the RC changelog.
Why this exists
I maintain okft, which ships an MCP server. Auditing it for the 2026-07-28 changes by hand meant re-reading the changelog with one finger on grep — so I turned the checklist into a tool.
License
Apache-2.0
Metadata
Release files for mcp-migration 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mcp_migration-0.1.0.tar.gz | 24.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcp_migration-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 50.4 kB
Release files / mcp_migration-0.1.0.tar.gz
| Download URL | mcp_migration-0.1.0.tar.gz |
|---|---|
| Size | 24.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7bb0148907ca4b73dfc054ba6584ae18edab8e7e1f3b255b728f7dad0588c1d4
|
|
BLAKE2b-256 checksum How to use checksums |
aa36ea771fd03aa05a168c0d5278e436dc6286459dd8b210a841e3bae35c615d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / mcp_migration-0.1.0-py3-none-any.whl
| Download URL | mcp_migration-0.1.0-py3-none-any.whl |
|---|---|
| Size | 25.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
31274b8b4be3a3e5a4a3b813ad5bf2c6cacd9a863b10003f0ff601277438c457
|
|
BLAKE2b-256 checksum How to use checksums |
d5d244e96915f2bb275735690e97491e377f982518be85dfe23323670a407119
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Security for mcp-migration 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.