Skip to content

Commit 9fc396b

Browse files
committed
Add multi-version protocol types: per-version fact tables
One superset type set in mcp.types plus declarative per-version wire-fact tables interpreted by a single engine at the wire boundary.
1 parent 7267818 commit 9fc396b

34 files changed

Lines changed: 22559 additions & 171 deletions

docs/migration.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,9 +1168,9 @@ In practice, replace direct `ServerSession` use with `Server.run(read_stream, wr
11681168

11691169
### Experimental Tasks support removed
11701170

1171-
Tasks (SEP-1686) have been removed from the MCP specification and are no longer part of this SDK. The `mcp.client.experimental`, `mcp.server.experimental`, `mcp.shared.experimental`, and `mcp.server.lowlevel.experimental` modules have been removed, along with all `Task*` types, the `tasks` capability fields, `Tool.execution`, and the `experimental` properties on `ClientSession`, `ServerSession`, `Server`, and `ServerRequestContext`.
1171+
The experimental task execution machinery (SEP-1686) is no longer part of this SDK. The `mcp.client.experimental`, `mcp.server.experimental`, `mcp.shared.experimental`, and `mcp.server.lowlevel.experimental` modules have been removed, along with the `experimental` properties on `ClientSession`, `ServerSession`, `Server`, and `ServerRequestContext`. Task execution is expected to return as a separate MCP extension in a future release.
11721172

1173-
Tasks are expected to return as a separate MCP extension in a future release.
1173+
The 2025-11-25 protocol's task **types** remain available from `mcp.types` (`Task`, `TaskMetadata`, `TaskStatus`, the `tasks/*` request and result types, the `tasks` capability fields, and `Tool.execution`), so task payloads from 2025-11-25 peers can be constructed and parsed. Compared with the v1 experimental module these are plain protocol types: attributes are snake_case (`task_id`, `created_at` — wire names are unchanged), timestamps are plain `str` fields, extra fields are ignored rather than preserved, and the `tasks/*` methods are not members of the request/notification unions — serving them requires registering a handler for the method explicitly.
11741174

11751175
## Deprecations
11761176

@@ -1238,6 +1238,12 @@ app = server.streamable_http_app(
12381238

12391239
The lowlevel `Server` also now exposes a `session_manager` property to access the `StreamableHTTPSessionManager` after calling `streamable_http_app()`.
12401240

1241+
### Newer protocol fields are modeled and round-trip
1242+
1243+
Fields introduced by the 2026-07-28 protocol revision are now typed on the existing payload models: `result_type` on results, `ttl_ms`/`cache_scope` on cacheable list/read results, `input_responses`/`request_state` on interactive request params, and `extensions` on the capability objects. Inbound payloads carrying these fields now retain them, and user-level `model_dump()` output includes them, where they were previously dropped as unknown fields. This is a strictly-more-lenient change: nothing that parsed before fails now.
1244+
1245+
Wire output to peers on protocol versions that predate a field is unaffected — the version-aware boundary (`mcp.types.wire.serialize_for`) drops these fields when emitting for 2025-11-25 and earlier, so existing peers see byte-identical frames.
1246+
12411247
## Need Help?
12421248

12431249
If you encounter issues during migration:

pyproject.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,12 @@ venv = ".venv"
143143
# those private functions instead of testing the private functions directly. It makes it easier to maintain the code source
144144
# and refactor code that is not public.
145145
executionEnvironments = [
146+
# Generated spec-oracle modules are committed verbatim from the generator;
147+
# a handful of generated patterns (recursive JSONValue alias, error `data`
148+
# overrides without defaults) are not strict-clean and must not be hand-edited.
149+
{ root = "tests/spec_oracles", extraPaths = [
150+
".",
151+
], reportUnusedFunction = false, reportPrivateUsage = false, reportGeneralTypeIssues = false, reportUnknownVariableType = false, reportInvalidTypeForm = false },
146152
{ root = "tests", extraPaths = [
147153
".",
148154
], reportUnusedFunction = false, reportPrivateUsage = false },
@@ -177,6 +183,10 @@ max-complexity = 24 # Default is 10
177183

178184
[tool.ruff.lint.per-file-ignores]
179185
"__init__.py" = ["F401"]
186+
# Generated spec-oracle modules: docstrings come verbatim from the spec schema
187+
# and ruff format does not wrap long docstring lines.
188+
"tests/spec_oracles/v*.py" = ["E501"]
189+
"tests/spec_oracles/ext_tasks.py" = ["E501"]
180190
"tests/server/mcpserver/test_func_metadata.py" = ["E501"]
181191
"tests/shared/test_progress_notifications.py" = ["PLW0603"]
182192

@@ -234,6 +244,11 @@ omit = [
234244
"src/mcp/server/__main__.py",
235245
"src/mcp/os/posix/utilities.py",
236246
"src/mcp/os/win32/utilities.py",
247+
# Generated spec-oracle modules and their comparison harness, vendored
248+
# unchanged from the oracle generator's output. The harness carries
249+
# defensive comparison branches and assertion-failure formatters that a
250+
# green suite never executes, and the files are not hand-edited here.
251+
"tests/spec_oracles/*",
237252
]
238253

239254
# https://coverage.readthedocs.io/en/latest/config.html#report

0 commit comments

Comments
 (0)