Title: [v2] Server registry + per-connection state; ServerRunner consumes Server[L] directly by maxisbey · Pull Request #2562 · modelcontextprotocol/python-sdk · GitHub
Open Graph Title: [v2] Server registry + per-connection state; ServerRunner consumes Server[L] directly by maxisbey · Pull Request #2562 · modelcontextprotocol/python-sdk
X Title: [v2] Server registry + per-connection state; ServerRunner consumes Server[L] directly by maxisbey · Pull Request #2562 · modelcontextprotocol/python-sdk
Description: PR5 of the V2 server-side refactor (Transport → Dispatcher → ServerRunner → Server registry). Stacked on #PR4 (maxisbey/v2-server-runner). Status: WIP — chunks A+B landed, chunk C (additive new-path entry points) in progress. Opening as draft so the registry/typing changes are reviewable while the rest lands. Motivation and Context ServerRunner (PR4) needs to consume the lowlevel Server as a typed handler registry rather than via the old _handle_request callback path. This PR reshapes Server so the runner can read (params_type, handler) entries directly, and adds the per-connection scaffolding (state, exit_stack, session_id, headers) that the new Context exposes. The Server generics were settled at Server[LifespanResultT] only — no transport generic, no connection-state generic. A transport generic makes Server invariant in a way that breaks bare def deploy(server: Server) plumbing helpers; the connection-state generic doesn't earn its place when stateless is the default deployment. Both remain additive later via PEP 696 trailing defaults if demand appears. The transport-layer types (Dispatcher[TT_co], DispatchContext[TT], BaseContext[TT]) keep their generic; the server layer consumes base TransportContext. What's in here so far HandlerEntry[L] frozen dataclass replaces bare callables in the registry; public add_request_handler / add_notification_handler; zero-arg capabilities() (notification_options/experimental_capabilities are now ctor kwargs) ServerRunner reads Server[L] directly — the PR4 ServerRegistry Protocol scaffold is gone Connection.session_id, Connection.state: dict[str, Any], Connection.exit_stack: AsyncExitStack (unwound shielded by ServerRunner.run() after the dispatcher closes — handlers/middleware register per-connection teardown with stdlib enter_async_context/push_async_callback) TransportContext.headers: Mapping[str, str] | None on the base; ctx.session_id / ctx.headers convenience properties on Context JSONRPCDispatcher coerces string response/progress IDs to int for correlation (matches BaseSession and the TS SDK) Still to come in this PR Additive only — nothing in the existing Server.run() / _handle_* / ServerSession path is touched. OutboundMiddleware on JSONRPCDispatcher + otel_outbound_middleware (span + W3C _meta inject on send_raw_request, mirroring BaseSession.send_request) stdio.serve(server) + StdioTransportContext — new-path stdio entry for lowlevel users Compat properties on lowlevel Context (.lifespan_context/.session proxy) so the high-level mcpserver.Context works on either backend — temporary parity scaffolding MCPServerNext sibling class routing through ServerRunner for the parametrized e2e parity suite (next PR) How Has This Been Tested? tests/server/test_runner.py end-to-end over DirectDispatcher; new tests for state persistence, exit_stack unwound on close/error, session_id/headers round-trip. tests/shared/test_jsonrpc_dispatcher.py for the ID coercion. 100% coverage on touched files. Breaking Changes None yet. This PR is additive; the old runtime path is untouched. The eventual breaking changes (delete _handle_*/ServerSession/BaseSession) are deferred until the parity suite proves equivalence. 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 AI Disclaimer
Open Graph Description: PR5 of the V2 server-side refactor (Transport → Dispatcher → ServerRunner → Server registry). Stacked on #PR4 (maxisbey/v2-server-runner). Status: WIP — chunks A+B landed, chunk C (additive new-pat...
X Description: PR5 of the V2 server-side refactor (Transport → Dispatcher → ServerRunner → Server registry). Stacked on #PR4 (maxisbey/v2-server-runner). Status: WIP — chunks A+B landed, chunk C (additive new-pat...
Opengraph URL: https://github.com/modelcontextprotocol/python-sdk/pull/2562
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:4028d5ef-cbbd-2e57-de37-93d8e66bb01a |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | AB36:19CD0D:805487:AB7673:6A5B5383 |
| html-safe-nonce | a857dc20779fc0f8905ca156721aa0fe33361f0fb032c06e3ffbe7b3a1e447b5 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBQjM2OjE5Q0QwRDo4MDU0ODc6QUI3NjczOjZBNUI1MzgzIiwidmlzaXRvcl9pZCI6IjYxNzM3MzUyNzMyMzMwNzcxMjMiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 3eb036187ba41dfc753275656f150754edd9897c346b5a950207741b3d684afb |
| hovercard-subject-tag | pull_request:3650252660 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/modelcontextprotocol/python-sdk/pull/2562/files |
| twitter:image | https://avatars.githubusercontent.com/u/224885523?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/224885523?s=400&v=4 |
| og:image:alt | PR5 of the V2 server-side refactor (Transport → Dispatcher → ServerRunner → Server registry). Stacked on #PR4 (maxisbey/v2-server-runner). Status: WIP — chunks A+B landed, chunk C (additive new-pat... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 5290d7e14309ad1e76106a9c4237bd1041517e83ea182c8ab756752cb0c6940b |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/modelcontextprotocol/python-sdk git https://github.com/modelcontextprotocol/python-sdk.git |
| octolytics-dimension-user_id | 182288589 |
| octolytics-dimension-user_login | modelcontextprotocol |
| octolytics-dimension-repository_id | 862584018 |
| octolytics-dimension-repository_nwo | modelcontextprotocol/python-sdk |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 862584018 |
| octolytics-dimension-repository_network_root_nwo | modelcontextprotocol/python-sdk |
| turbo-body-classes | logged-out env-production page-responsive full-width |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 9c975978430e9ad293956f2bbdaf153b1bd84a99 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width