Skip to content

MCP Python SDK Protocol Compliance Gap: Missing Direction Validation for Cancellation Notifications #1415

@younaman

Description

@younaman

Initial Checks

Description

MCP Python SDK Protocol Compliance Gap: Missing Direction Validation for Cancellation Notifications

The current implementation of the MCP Python SDK does not validate the direction requirement for cancellation notifications, despite the MCP protocol explicitly mandating with a MUST requirement that "Cancellation notifications MUST only reference requests that were previously issued in the same direction." This creates a protocol compliance gap and potential security risk in scenarios where request ID collision is possible or where both client and server share session contexts.

Technical Analysis

The MCP Python SDK's low-level implementation processes cancellation notifications without performing the mandatory direction validation, creating a critical protocol compliance gap. More specifically:

  1. Missing Direction Validation in Core Definitions: The CancelledNotification and CancelledNotificationParams definitions in the SDK lack any mechanism to track or validate the direction of the original request being cancelled.

  2. Unsafe Cancellation Processing: In the cancellation handling logic, the code directly processes cancellation requests without direction validation:

    if isinstance(notification.root, CancelledNotification):
        cancelled_id = notification.root.params.requestId
        if cancelled_id in self._in_flight:
            await self._in_flight[cancelled_id].cancel()
  3. Protocol Compliance Gap: The MCP protocol specifies that cancellation notifications MUST only reference requests issued in the same direction, but the Python SDK completely ignores this requirement, creating a compliance gap.

In scenarios where request ID collision occurs between client and server, or where both sides share the same session context, this gap could potentially allow cancellation notifications to target requests from the opposite direction without proper validation.

Potential Security Impact

Protocol Compliance Violation

The MCP Python SDK's low-level implementation supports cancellation notifications but lacks the direction validation mechanism mandated by the MCP protocol, creating a compliance gap that could lead to:

  • Unauthorized termination of requests in collision scenarios
  • Resource management inconsistencies due to improper request lifecycle handling
  • Violation of the fundamental directional communication model of MCP-based systems

Potential Risk Scenarios

While the risk is limited by the typical separation of client and server _in_flight dictionaries, potential issues could arise in:

  • Scenarios where request ID collision occurs between client and server
  • Shared session contexts where both sides maintain the same _in_flight collection
  • Future architectural changes that might increase the likelihood of ID collision

Remediation

I recommend that the MCP Python SDK implement proper direction validation for cancellation notifications as mandated by the protocol's MUST requirement. This should include:

  1. Direction Metadata Enhancement: Modify CancelledNotificationParams and related structures to include directional information for validation
  2. Request Direction Tracking: Enhance the _in_flight request tracking to maintain direction metadata for each active request
  3. Validation Logic Implementation: Add direction validation checks in the cancellation processing logic before allowing cancellation to proceed

Suggested Implementation

Location: src/mcp/shared/session.py in BaseSession._receive_loop() around line 383

Current code:

# Handle cancellation notifications
if isinstance(notification.root, CancelledNotification):
    cancelled_id = notification.root.params.requestId
    if cancelled_id in self._in_flight:
        await self._in_flight[cancelled_id].cancel()

Suggested enhancement:

# Handle cancellation notifications
if isinstance(notification.root, CancelledNotification):
    cancelled_id = notification.root.params.requestId
    if cancelled_id in self._in_flight:
        responder = self._in_flight[cancelled_id]
        # Add direction validation
        if self._validate_cancellation_direction(responder, notification):
            await responder.cancel()
        else:
            logger.warning(f"Rejected cancellation notification for request {cancelled_id} - direction mismatch")

Additional changes needed:

  • Add direction tracking to RequestResponder class
  • Implement _validate_cancellation_direction() method
  • Update request creation logic to set direction metadata

Impact

This issue affects users and downstream projects that rely on the MCP Python SDK in scenarios where request ID collision is possible or where both client and server share session contexts. While the immediate risk is limited by typical architectural separation, this represents a protocol compliance gap that should be addressed to ensure full adherence to MCP specifications.

Supporting Material/References

Please refer to the MCP protocol specification regarding cancellation notification direction requirements and the code analysis of CancelledNotification, CancelledNotificationParams, and the _in_flight processing logic in src/mcp/shared/session.py lines 382-386.

Example Code

Python & MCP Python SDK

master

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Nice to haves, rare edge casesfeature requestRequest for a new feature that's not currently supportedimproves spec complianceWhen a change improves ability of SDK users to comply with spec definitionready for workEnough information for someone to start working on

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions