Title: MCP Python SDK Protocol Compliance Gap-1:Response Sent After Receiving Cancellation Notifications · Issue #1419 · modelcontextprotocol/python-sdk · GitHub
Open Graph Title: MCP Python SDK Protocol Compliance Gap-1:Response Sent After Receiving Cancellation Notifications · Issue #1419 · modelcontextprotocol/python-sdk
X Title: MCP Python SDK Protocol Compliance Gap-1:Response Sent After Receiving Cancellation Notifications · Issue #1419 · modelcontextprotocol/python-sdk
Description: Initial Checks I confirm that I'm using the latest version of MCP Python SDK I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this issue Description MCP Python SDK Protoco...
Open Graph Description: Initial Checks I confirm that I'm using the latest version of MCP Python SDK I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this ...
X Description: Initial Checks I confirm that I'm using the latest version of MCP Python SDK I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening t...
Opengraph URL: https://github.com/modelcontextprotocol/python-sdk/issues/1419
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"MCP Python SDK Protocol Compliance Gap-1:Response Sent After Receiving Cancellation Notifications","articleBody":"### Initial Checks\n\n- [x] I confirm that I'm using the latest version of MCP Python SDK\n- [x] I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this issue\n\n### Description\n\n### MCP Python SDK Protocol Compliance Gap: Response Sent After Receiving Cancellation Notifications\n\n- Assessment: This is a protocol “SHOULD not” compliance gap. When acting as the receiver of a cancellation notification, the SDK still sends a JSON-RPC error response for the cancelled request, contrary to the spec’s guidance.\n\n### Description\nThe MCP specification states: “Receivers of cancellation notifications SHOULD not send a response for the cancelled request.” \nIn the current implementation, after processing a `CancelledNotification`, the SDK sends an error response for the cancelled in-flight request.\n\n### Detailed Analysis\n- Dedicated handling branch for cancellation notifications(https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/shared/session.py#L382):\n```383:387:src/mcp/shared/session.py\n # Handle cancellation notifications\n if isinstance(notification.root, CancelledNotification):\n cancelled_id = notification.root.params.requestId\n if cancelled_id in self._in_flight:\n await self._in_flight[cancelled_id].cancel()\n```\n- `cancel()` sends an error response instead of silently terminating( (https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/shared/session.py#L135)):\n```135:148:src/mcp/shared/session.py\n async def cancel(self) -\u003e None:\n \"\"\"Cancel this request and mark it as completed.\"\"\"\n ...\n self._cancel_scope.cancel()\n self._completed = True # Mark as completed so it's removed from in_flight\n # Send an error response to indicate cancellation\n await self._session._send_response(\n request_id=self.request_id,\n response=ErrorData(code=0, message=\"Request cancelled\", data=None),\n )\n```\n- Result: Even when the cancellation is triggered by a `CancelledNotification`, the SDK responds with a JSON-RPC error for the cancelled request, diverging from the spec’s “SHOULD not” recommendation.\n\n### Potential Impact\n- Protocol consistency: Behavior deviates from the spec’s guidance, potentially surprising peers that expect silent termination.\n- Interoperability: Differences may surface when integrating with implementations that strictly follow the “SHOULD not” behavior.\n\n### Remediation\n- Implement silent cancellation for notification-triggered cancellations:\n - Add a non-responding cancellation path on `RequestResponder` (e.g., `mark_cancelled_without_response()`), which cancels and marks complete without calling `_send_response`.\n - In the cancellation notification handling branch, call the silent path instead of `cancel()`.\n\n### Suggested Implementation\n- Location: `src/mcp/shared/session.py` in `BaseSession._receive_loop()` cancellation branch and in `RequestResponder`.\n\nChange call site to silent cancellation:\n- From:\n - `await self._in_flight[cancelled_id].cancel()`\n- To:\n - `await self._in_flight[cancelled_id].mark_cancelled_without_response()`\n\n\n### Impact\n- Aligns behavior with the MCP spec’s “SHOULD not” guidance.\n- Reduces unnecessary response traffic and improves predictability and interoperability in cancellation flows.\n\n### Example Code\n\n```Python\n\n```\n\n### Python \u0026 MCP Python SDK\n\n```Text\nLatest\n```","author":{"url":"https://github.com/younaman","@type":"Person","name":"younaman"},"datePublished":"2025-10-02T15:20:09.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/1419/python-sdk/issues/1419"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:ba35ffe4-33d2-f230-4a0f-fd6c0e86957e |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | ADE4:27FA02:5AA564:8131C7:6A59E59F |
| html-safe-nonce | 3df06e79c9ab96d78024d714882f1f79414eada94431a0ecef51af0012e07d19 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBREU0OjI3RkEwMjo1QUE1NjQ6ODEzMUM3OjZBNTlFNTlGIiwidmlzaXRvcl9pZCI6Ijc5OTkyODY3NjU2MzgyNDc4MzkiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | b3cf89b89e34dc89f4d3f9d73f319c2eaeefca951504133ac1c651e5be202cf0 |
| hovercard-subject-tag | issue:3477935958 |
| github-keyboard-shortcuts | repository,issues,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/_view_fragments/issues/show/modelcontextprotocol/python-sdk/1419/issue_layout |
| twitter:image | https://opengraph.githubassets.com/c7cf5cb451033ac08260c2507ccc5c4ee49427ee85c18e6552598d41a50ab28e/modelcontextprotocol/python-sdk/issues/1419 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/c7cf5cb451033ac08260c2507ccc5c4ee49427ee85c18e6552598d41a50ab28e/modelcontextprotocol/python-sdk/issues/1419 |
| og:image:alt | Initial Checks I confirm that I'm using the latest version of MCP Python SDK I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this ... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | younaman |
| hostname | github.com |
| expected-hostname | github.com |
| None | ba3976babb66479b1c943a8edc0777d96157da48fadc0161f9ddb219deee8353 |
| turbo-cache-control | no-preview |
| 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 |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 32bf0b7849e1b6561059cca2cb03568251960859 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width