Make the per-version wire packages private (`mcp_types._v*`)

Merged
MA
3mo ago
+133-127

Renames the two generated per-protocol-version wire packages, mcp_types.v2025_11_25 and mcp_types.v2026_07_28, to underscore-private mcp_types._v2025_11_25 / mcp_types._v2026_07_28.

Motivation and Context

These packages are datamodel-code-generator output: strict per-schema-era validators (~175 classes each) whose names are derived by the generator, including unstable ones for anonymous inline schema objects (Params1, Params2, Error1, Elicitation1, ...) that renumber whenever the upstream schema gains an anonymous object. The types users actually hold are the version-free models in mcp_types._types, re-exported at the mcp_types top level; every mcp_types.methods parse function returns those.

Their own module docstrings and the methods.py docstring already say "internal validators, not for direct import" — but with public-looking names, scripts/docs/gen_ref_pages.py (which documents every module without a _-prefixed path component) would publish all ~350 unstable-named classes as API reference. Rather than special-casing the docs generator, this makes the name match the intent: the existing underscore convention (_types, _wire_base) now covers these too, and the docs, IDE autocomplete, and prose all agree.

Nothing on the supported surface changes: mcp_types, mcp_types.jsonrpc, mcp_types.methods, mcp_types.version are untouched, and the public surface maps (CLIENT_REQUESTS et al.) still hold the same models — extending them per the docs never required importing these packages.

How Has This Been Tested?

  • Full suite green (./scripts/test, 100% coverage), gen_surface_types.py --check reports no drift under the new output path (the generated files are byte-identical after the move).
  • Built both wheels and drove the public API from a clean install: parse_client_request / serialize_server_result route through the renamed internals correctly, mcp.server.elicitation's schema gate still validates, and mcp_types.v2025_11_25 now raises ModuleNotFoundError as intended.
  • scripts/docs/gen_ref_pages.py now emits only index/jsonrpc/methods/version for mcp_types — the versioned pages are gone.

Breaking Changes

Yes, nominally: import mcp_types.v2025_11_25 / mcp_types.v2026_07_28 stop resolving. These modules only exist on the v2 pre-release line (added in #2849) and were documented as internal from the start. A GitHub-wide search finds no supported usage — FastMCP's fastmcp-slim and mcpscore (both on 2.0.0b2) import only the top-level surface — so this lands in the pre-stable window where the rename is cheap rather than after 2.0.0. Noted in docs/migration.md alongside the supported import surface.

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

src/mcp/server/elicitation.py keeps importing PrimitiveSchemaDefinition from the (now underscored) _v2025_11_25 package rather than promoting it to the public monolith: mcp exact-pins mcp-types to the same version, so this is a lockstep-safe internal import, and the monolith deliberately keeps ElicitRequestedSchema as a raw dict[str, Any].

AI Disclaimer