Skip to content

docs: fill migration-guide gaps found by automated v1-to-v2 migration runs - #3187

Merged
maxisbey merged 2 commits into
mainfrom
docs/migration-guide-unchanged-surfaces
Jul 27, 2026
Merged

docs: fill migration-guide gaps found by automated v1-to-v2 migration runs#3187
maxisbey merged 2 commits into
mainfrom
docs/migration-guide-unchanged-surfaces

Conversation

@maxisbey

Copy link
Copy Markdown
Contributor

Fills gaps in docs/migration.md surfaced 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 with docs/migration.md and 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:

  • "What did not change" was the single biggest gap — the guide catalogues changes but never confirms survivals, so migrating code repeatedly went to SDK source to check that @mcp.tool(), Server.run(...), stdio_server(), create_initialization_options(), TokenVerifier/AccessToken, etc. still exist unchanged. Added compact "unchanged surface" inventories for MCPServer, the lowlevel Server serving scaffolding, and auth.
  • NoBackChannelError on 2026-07-28 connections (including the default in-process Client(server)) is now documented in one place with cross-links from the mode, testing, tasks, and SEP-2577 sections, plus the two migration routes (mode="legacy" vs resolver dependencies / InputRequiredResult).
  • Transport details: the real streamable_http_client signature (terminate_on_close included), a per-parameter porting map for the removed streamablehttp_client kwargs, sse_client's retained parameters, mcp no longer installing httpx, and auth providers now subclassing httpx2.Auth.
  • Mounted-app example now includes the required lifespan (without it every request fails with "Task group is not initialized"), plus which transport parameters live on run() vs the app factories.
  • Silent behavior/wire changes now called out: client_secret_post token requests including client_id, JSONRPCError.id widened to RequestId | None, and MCPDeprecationWarning under warnings-as-errors suites.
  • Porting guidance for the removed experimental Tasks API, ProgressContext's delta-vs-absolute semantics, RootModel-union consequences for isinstance/.root, the Client vs ClientSession pagination shapes, per-request ServerSession identity, and the current tool-only scope of the parametrized Context[X] annotation.

How Has This Been Tested?

Docs-only. markdownlint passes; internal anchor links were checked against the rendered heading slugs.

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

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 that Connection isn't reachable from ctx, and the "provisional" caveat on Server.middleware.

AI Disclaimer

… 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
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

📚 Documentation preview

Preview https://pr-3187.mcp-python-docs.pages.dev
Deployment https://bbc8d435.mcp-python-docs.pages.dev
Commit 5e479ca
Triggered by @maxisbey
Updated 2026-07-27 17:01:25 UTC

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
@maxisbey
maxisbey marked this pull request as ready for review July 27, 2026 17:14

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Re-trigger cubic

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 in mcp.shared.exceptions), streamable_http_client's signature, JSONRPCError.id: RequestId | None, the reduced Settings field set, client_secret_post sending client_id + client_secret, ServerSession.report_progress no-op semantics, {?var} optional query templates, and session-manager attributes.
  • The candidate concern that the guide falsely claims Connection is not reachable from ctx was 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.

@maxisbey
maxisbey merged commit e8ef138 into main Jul 27, 2026
39 checks passed
@maxisbey
maxisbey deleted the docs/migration-guide-unchanged-surfaces branch July 27, 2026 22:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant