Skip to content

Expose a public message_handler seam for MCP ClientSession (consume server notifications e.g. tools/list_changed) #6385

Closed

Description

@JesusCaseroDiazCano

Is your feature request related to a problem?

There is no supported way to have McpToolset / MCPSessionManager react to server-initiated MCP notifications — in particular notifications/tools/list_changed.

The underlying mcp SDK ClientSession accepts a message_handler constructor parameter, and invokes it for every incoming message (_handle_incoming → await self._message_handler(req)). But in ADK the ClientSession is constructed internally inside SessionContext._run (google/adk/tools/mcp_tool/session_context.py) with only sampling_callback / sampling_capabilities forwarded — no message_handler. So the SDK falls back to _default_message_handler, which silently discards all server notifications, including ToolListChangedNotification.

Neither MCPSessionManager.__init__, SessionContext.__init__, nor McpToolset.__init__ exposes a message_handler, so there is no public hook.

Observed on google-adk==2.3.0 (with mcp==1.27.2).

Describe the solution you'd like

Forward an optional message_handler: MessageHandlerFnT | None through the same path as sampling_callback:

  • McpToolset(..., message_handler=...) →
  • MCPSessionManager(..., message_handler=...) →
  • SessionContext(..., message_handler=...) →
  • passed into the ClientSession(...) constructor.

This would let toolsets consume tools/list_changed (e.g. to invalidate a cached tool list) and other server notifications through a supported API.

Describe alternatives you've considered

Today the only working hook is to assign the private attribute after create_session():

session = await super().create_session(headers=headers)
target = getattr(session, "_session", session)
if hasattr(target, "_message_handler"):
    target._message_handler = my_handler

This works (the SDK reads _message_handler dynamically per message, so post-construction assignment takes effect on the running receive loop), but it depends on a private attribute that any ADK/SDK change could rename or remove. A public parameter would remove the need for this workaround.

Additional context

Use case: a gateway that implements the MCP tools/list_changed capability emits the notification on the standalone GET SSE stream; the client wants to invalidate its cached tools/list result on receipt. The GET stream itself opens fine once the server returns an mcp-session-id; the only missing piece on the ADK side is delivery of the notification to a caller-supplied handler.

Activity

  1. Aho-Bakaa commented on Jul 14, 2026

    @Aho-Bakaa

    Hi, I'd like to work on this issue.

  2. added
    mcp[Component] This issues is related to MCP support
    on Jul 15, 2026
  3. sanketpatil06 commented on Jul 15, 2026

    @sanketpatil06

    Hi @JesusCaseroDiazCano , Thanks for the update. The request is currently being reviewed by our team, and we will let you know if anything further is needed. Thank you for your understanding.

  4. added
    needs review[Status] The PR/issue is awaiting review from the maintainer
    on Jul 15, 2026
  5. added
    spam[Status] Issues suspected of having comments which are spam
    on Jul 21, 2026
  6. adk-bot commented on Jul 21, 2026

    @adk-bot
    Collaborator

    🚨 Automated Spam Detection Alert 🚨
    @maintainers, a suspected spam comment was detected in this thread.

    Reason:

    @impeachmentright posted a link to an external site (https://a2a.elonsusk.com/.well-known/agent-card.json) promoting a 3rd party "A2A contractor card", which is promotional/spam content.
    
  7. removed
    spam[Status] Issues suspected of having comments which are spam
    on Oct 14, 2026
  8. Samecho commented on Oct 23, 2026

    @Samecho
    Contributor

    Is anyone still working on the generic message_handler hook? I would like to pass the optional SDK callback through McpToolset, MCPSessionManager and SessionContext, keeping the default behavior unchanged. I plan to test notification delivery against both supported MCP SDK majors. The scope would be the callback itself; automatic tool-cache invalidation can stay separate.

  9. added a commit that references this issue on Nov 1, 2026
    9a5117b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

mcp[Component] This issues is related to MCP supportneeds review[Status] The PR/issue is awaiting review from the maintainer

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions