docs: restructure the migration guide around topical groups with a navigation layer
Restructures docs/migration.md so a migrating user (or an agent driving a migration) can find what applies to them at a glance. Documentation only; the diff is one file.
Motivation and Context
The migration guide grew by accretion: one section per breaking PR, in merge order, under four coarse buckets (Breaking Changes / Deprecations / Bug Fixes / New Features). Finding "what hits me" meant reading 1700 lines, several entries described 2026-07-28 features rather than v1-to-v2 breaks, some real breaks were filed under Bug Fixes or New Features, and a number of breaks were missing entirely.
This PR reworks the page along one rule: a section belongs if migrated v1 code, talking to a 2025-11-25 peer, behaves observably differently. Adopting the 2026-07-28 revision is the whats-new page's territory, not this page's.
What changed:
- A navigation layer up front: a symptom-keyed table of the changes almost every project hits, an audience index, and a suggested migration order.
- Sections regrouped topically, ordered the way a migration proceeds: packaging, types and wire format, MCPServer, lowlevel Server, clients, transports, OAuth and server auth, validation and wire behavior, testing, deprecations.
- Removed sections that describe 2026-era features with no observable effect for migrated v1 code against 2025-11-25 peers (client Mcp-Param mirroring, caching hints, extensions API, identity assertion, modeled protocol fields, the additive lowlevel streamable_http_app, and a registration note whose "before" API only ever existed in v2 alphas). That content already lives on the whats-new page and the feature pages. The server-side Mcp-Param section stays, under a clearly scoped "Notes for 2026-era connections" heading, because whats-new.md deep-links it.
- Reclassified behavior changes misfiled under Bug Fixes / New Features (extra-fields handling, the OAuth trailing-slash change, SEP-2352/SEP-2350/SEP-837, the ElicitationResult isinstance change) and merged three satellite sections into their parents.
- Added missing breaks, each verified on both runtimes: timeouts take float seconds instead of timedelta; client request timeouts raise -32001 instead of 408; lowlevel tool-handler exceptions surface as JSON-RPC errors instead of isError results; streamable HTTP non-2xx responses become per-request errors; the _meta envelope and the new OpenTelemetry dependencies; OAuth offline_access plus prompt=consent and issuer validation; stricter /token client authentication; MCPServer constructor positional-slot changes; the default server name change; dependency floor bumps; and several smaller renames folded into existing sections.
- Fixed stale or wrong claims found while re-validating every section: model_dump() now needs by_alias=True to produce the wire shape, two "Before" examples never worked in v1 as shown, StatelessModeNotSupported never existed in any v1 release, and the mcp.shared.context removal claims were imprecise.
How Has This Been Tested?
Every section's claims were exercised against both runtimes (mcp 1.28.1 and this branch): removed-API claims by importing on both sides, behavior claims with small scripts (including wire captures behind the _meta and mode='legacy' statements), and code examples by running them. mkdocs build --strict passes (the strict build fails on dead anchors, so the eight heading anchors that whats-new.md deep-links are unchanged), and markdownlint passes.
Breaking Changes
None; documentation only.
Types of changes
- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- Breaking change (fix or feature that would cause existing functionality to change)
- Documentation update
Checklist
- I have read the MCP Documentation
- My code follows the repository's style guidelines
- New and existing tests pass locally
- I have added appropriate error handling
- I have added or updated documentation as needed
Additional context
- Two open PRs add sections to this file: the subscribe/unsubscribe deprecation entry slots into the Deprecations group, and the elicitation capability-gate section slots into the MCPServer group after the Context.elicit() section. Rebases should be mechanical.
- Reordering does not change heading anchors; the handful of retitles were grep-verified to have no inbound links anywhere in docs/.
- Follow-up, deliberately not in this PR: docs/client/caching.md carries the same ambiguous default_ttl_ms parenthetical the removed caching-hints section had.