docs: fill migration-guide gaps found by automated v1-to-v2 migration runs - #3187
Conversation
… runs A batch of automated v1-to-v2 migrations over the SDK's example directories plus several real-world consumers surfaced recurring gaps in docs/migration.md - places where migrating code had to fall back to reading SDK source. This addresses the highest-frequency ones: - Add "what is unchanged" inventories for MCPServer, the lowlevel Server serving scaffolding, and the auth surface (the single most common gap: the guide listed what changed but never confirmed what survived). - Document server-initiated requests raising NoBackChannelError on 2026-07-28 connections (including the default in-process Client(server)), with cross-links from the mode, testing, tasks, and deprecation sections. - State the real streamable_http_client signature, the per-parameter porting map for the removed streamablehttp_client kwargs, and sse_client's retained parameters; note that mcp no longer installs httpx and that the auth providers now subclass httpx2.Auth. - Fix the mounted-app example to include the required lifespan, and spell out which transport parameters live on run() vs the app factories. - Document the client_secret_post client_id fix, JSONRPCError.id becoming RequestId | None, and MCPDeprecationWarning behavior under warnings-as-errors. - Add porting guidance for the removed experimental Tasks API, the ProgressContext delta-vs-absolute semantics, and RootModel-union consequences for isinstance and .root access. - Note the Client vs ClientSession pagination shapes, the per-request ServerSession identity change, and the current tool-only scope of the parametrized Context[X] annotation. No-Verification-Needed: doc-only change
📚 Documentation preview
|
The "client request timeouts" heading contains a leading-hyphen number, which GitHub-style slugging (markdownlint MD051) and python-markdown (the site build) render as different anchors, so any fragment link to it fails one of the two strict checks. Refer to the section in prose instead. No-Verification-Needed: doc-only change
There was a problem hiding this comment.
LGTM — docs-only additions to the migration guide, and the factual claims I spot-checked all match the SDK source.
What was reviewed:
- Verified API claims against source:
NoBackChannelError(code/message inmcp.shared.exceptions),streamable_http_client's signature,JSONRPCError.id: RequestId | None, the reducedSettingsfield set,client_secret_postsendingclient_id+client_secret,ServerSession.report_progressno-op semantics,{?var}optional query templates, and session-manager attributes. - The candidate concern that the guide falsely claims
Connectionis not reachable fromctxwas investigated and ruled out. - No code, config, or dependency changes — markdown only.
Extended reasoning...
Overview
This PR touches a single file, docs/migration.md, adding roughly 400 lines of migration guidance: "what did not change" inventories for MCPServer, the lowlevel Server, and the auth surface; consolidated NoBackChannelError documentation with cross-links; transport parameter porting maps for the removed streamablehttp_client; a corrected mounted-app example including the required lifespan; and callouts for silent behavior changes (client_secret_post body, JSONRPCError.id widening, MCPDeprecationWarning under warnings-as-errors).
Security risks
None. This is a documentation-only change with no code, configuration, dependency, or CI modifications. The security-adjacent content (auth surfaces, DNS rebinding protection, token endpoint auth) is descriptive of existing behavior, and the descriptions I checked are accurate — notably the client_secret_post claim matches src/mcp/client/auth/oauth2.py exactly.
Level of scrutiny
The appropriate scrutiny for a docs PR is factual accuracy, since a wrong claim in a migration guide sends users down the wrong path. I spot-checked the highest-stakes claims against the source tree: NoBackChannelError subclasses MCPError with INVALID_REQUEST (-32600) and the quoted message text; streamable_http_client(url, *, http_client=None, terminate_on_close=True) is the real signature; JSONRPCError.id is RequestId | None (required but nullable, per the model docstring); Settings holds exactly the fields the guide lists (debug, log_level, warn_on_duplicate_*, dependencies, lifespan, auth); ServerSession.report_progress exists with the documented no-op-without-token semantics; the {?limit} optional-query template syntax and its default-value requirement exist in mcpserver/server.py; and StreamableHTTPSessionManager exposes stateless, json_response, event_store, and retry_interval as public attributes. All matched. The bug hunting system found no issues, and its one candidate concern (the Connection-not-reachable-from-ctx claim) was verified against the code and refuted as a bug — the guide's statement is accurate, and the PR description itself flags it as behavior that may change later.
Other factors
The PR follows the repo's own guideline that migration-affecting details belong in docs/migration.md, and it extends existing sections rather than restructuring the guide. The author reports markdownlint passing and anchor links checked against rendered slugs; a follow-up commit on main ("drop cross-link whose anchor slug differs between checkers") shows the anchors received real attention. The timeline contains only the docs-preview bot comment and no unresolved reviewer feedback. Worst case for an error here is a misleading sentence in documentation — easily fixed forward — so with the spot-checks passing, this is safe to approve without human review.
Fills gaps in
docs/migration.mdsurfaced by a batch of automated v1→v2 migration runs.Motivation and Context
We ran a set of automated v1→v2 migrations over the SDK's own example directories plus several real-world consumers (e.g.
langchain-mcp-adapters,openai-agents-python), each armed only withdocs/migration.mdand the installed package, and collected a note every time the guide wasn't enough. The migrations themselves went fine; the friction clustered around a few gaps, which this PR closes:@mcp.tool(),Server.run(...),stdio_server(),create_initialization_options(),TokenVerifier/AccessToken, etc. still exist unchanged. Added compact "unchanged surface" inventories forMCPServer, the lowlevelServerserving scaffolding, and auth.NoBackChannelErroron 2026-07-28 connections (including the default in-processClient(server)) is now documented in one place with cross-links from themode, testing, tasks, and SEP-2577 sections, plus the two migration routes (mode="legacy"vs resolver dependencies /InputRequiredResult).streamable_http_clientsignature (terminate_on_closeincluded), a per-parameter porting map for the removedstreamablehttp_clientkwargs,sse_client's retained parameters,mcpno longer installinghttpx, and auth providers now subclassinghttpx2.Auth.run()vs the app factories.client_secret_posttoken requests includingclient_id,JSONRPCError.idwidened toRequestId | None, andMCPDeprecationWarningunder warnings-as-errors suites.ProgressContext's delta-vs-absolute semantics,RootModel-union consequences forisinstance/.root, theClientvsClientSessionpagination shapes, per-requestServerSessionidentity, and the current tool-only scope of the parametrizedContext[X]annotation.How Has This Been Tested?
Docs-only.
markdownlintpasses; internal anchor links were checked against the rendered heading slugs.Breaking Changes
None — documentation only.
Types of changes
Checklist
Additional context
A few statements describe current behavior that we may still change, and should be revised if we do: the note that parametrized
Context[MyState]is currently tool-only on prompt/template handlers, the statement thatConnectionisn't reachable fromctx, and the "provisional" caveat onServer.middleware.AI Disclaimer