The official Python SDK for Model Context Protocol servers and clients
by modelcontextprotocolLast 12 weeks ยท 126 commits
5 of 6 standards met
Summary Fixes #2114 When a task in an anyio task group fails, sibling tasks are cancelled and the resulting exceptions are wrapped alongside the real error in a . This makes it extremely difficult for callers to classify the root cause of failures โ they must manually unwrap exception groups to find what actually went wrong. Solution Added a utility and a drop-in context manager in that automatically unwraps single-error exception groups: One real error + N cancelled โ raises the real error directly (chained to the original group via ) Multiple real errors โ preserves the as-is All cancelled** โ preserves the group as-is Applied Sites The unwrapping is applied to all client-facing code paths: Server-side task groups are left unchanged as they typically have internal error handling. Tests Added comprehensive tests in : : 5 unit tests covering all edge cases : 3 integration tests verifying unwrapping, clean exit, and cause chaining All 154 shared tests pass with 0 errors.
Problem When a JSON-RPC request uses , notifications sent during tool execution are not routed to the correct request stream. The client never receives them. Root cause:** In , the condition: evaluates to when is (integer zero is falsy in Python). This means the is not attached, so the message router in falls through to the instead of the request-specific stream. Fix This is consistent with the identity checks already used in : Line 984: Line 993: Line 997: Testing 64 tests pass across and (2 consecutive clean runs) The JSON-RPC spec explicitly allows as a valid request identifier Fixes #1218
Repository: modelcontextprotocol/python-sdk. Description: The official Python SDK for Model Context Protocol servers and clients Stars: 21886, Forks: 3121. Primary language: Python. Languages: Python (100%), Shell (0%). License: MIT. Homepage: https://modelcontextprotocol.github.io/python-sdk/ Latest release: v1.26.0 (1mo ago). Open PRs: 100, open issues: 295. Last activity: 13h ago. Community health: 87%. Top contributors: dsp-ant, Kludex, ihrpr, maxisbey, jspahrsummers, felixweinberger, nick-merrill, jerome3o-anthropic, calclavia, pja-ant and others.
Python
Summary When shutting down a (e.g. CTRL+C) while clients have active streaming connections, Uvicorn logs: The error occurs because the shutdown path cancels the task group without first gracefully terminating active SSE/streaming connections. Fix Before cancelling the task group in 's block, iterate through all active and call on each transport. This gives each transport a chance to close its SSE connections properly, so clients receive a proper HTTP response instead of an abrupt disconnect. Tests Added โ injects a mock transport and verifies is called during shutdown. Fixes #2150
Summary Fixes #2107 ClientSession currently silently drops , , and from the server because only handles and . This makes it impossible for clients to react when a server's tool, prompt, or resource lists change dynamically. Changes 3 callback protocol types: , , โ zero-argument async callables (matching the existing / pattern). Default no-op: โ silently accepts the notification (backward compatible). 3 keyword-only params in โ , , . 3 match cases in โ dispatch to the user callback, wrapped in so a misbehaving callback never crashes the session. 3 optional fields on the dataclass โ , , . Passthrough to in . 3 optional fields on . Passthrough in . (new) 5 tests: 1. โ fires on 2. โ fires on 3. โ fires on 4. โ no callback = silent (no crash) 5. โ bad callback logs exception but session survives Updated mock assertion to include the 3 new keyword args. Naming All names use singular** form to match the existing codebase conventions: โ โ โ Backward Compatibility Fully backward compatible โ the new parameters are keyword-only with defaults, falling back to a no-op. Test Results
Summary Fixes #1648 is raised by Starlette when a client disconnects mid-request (network timeouts, user cancellation, load balancer timeouts). This is a normal client-side event, not a server failure. Problem The broad handler in catches and: Logs it as ERROR with full traceback Returns HTTP 500 Internal Server Error Triggers false 5XX alerts in production monitoring Fix Catch before the generic handler: Log at INFO level (this is an expected operational event) Return early without sending a response (the client is already gone) Properly clean up by notifying the writer about the disconnection Test Results 475 server tests pass (2 consecutive clean runs).
Summary Fixes #1656 calls which previously called , configuring the root logger with handlers and level. This violates Python logging best practices: It is strongly advised that you do not add any handlers other than NullHandler to your library's loggers. This is because the configuration of handlers is the prerogative of the application developer.* โ Python Logging HOWTO Problem Any application using the MCP SDK that calls gets its logging configuration silently overridden: Custom log formats are replaced Log levels are changed Handlers (e.g., file handlers, structured JSON logging) are affected Unit test log capture can break Fix Replace with targeted configuration of the namespace logger only: is configured with handlers and level The root logger is left untouched Duplicate handler guards prevent stacking on repeated calls MCP SDK logs still work out of the box for quickstart scripts Test Results 475 server tests pass (2 consecutive clean runs).