Add client callbacks for list_changed notifications by omar-y-abdi · Pull Request #2281 · modelcontextprotocol/python-sdk · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion src/mcp/client/client.py
20 changes: 20 additions & 0 deletions src/mcp/client/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ async def __call__(
) -> types.ListRootsResult | types.ErrorData: ... # pragma: no branch


class ListChangedFnT(Protocol):
async def __call__(self) -> None: ... # pragma: no branch


class LoggingFnT(Protocol):
async def __call__(self, params: types.LoggingMessageNotificationParams) -> None: ... # pragma: no branch

Expand Down Expand Up @@ -95,6 +99,10 @@ async def _default_logging_callback(
pass


async def _default_list_changed_callback() -> None:
pass


ClientResponse: TypeAdapter[types.ClientResult | types.ErrorData] = TypeAdapter(types.ClientResult | types.ErrorData)


Expand All @@ -118,6 +126,9 @@ def __init__(
logging_callback: LoggingFnT | None = None,
message_handler: MessageHandlerFnT | None = None,
client_info: types.Implementation | None = None,
tools_list_changed_callback: ListChangedFnT | None = None,
resources_list_changed_callback: ListChangedFnT | None = None,
prompts_list_changed_callback: ListChangedFnT | None = None,
*,
sampling_capabilities: types.SamplingCapability | None = None,
experimental_task_handlers: ExperimentalTaskHandlers | None = None,
Expand All @@ -130,6 +141,9 @@ def __init__(
self._list_roots_callback = list_roots_callback or _default_list_roots_callback
self._logging_callback = logging_callback or _default_logging_callback
self._message_handler = message_handler or _default_message_handler
self._tools_list_changed_callback = tools_list_changed_callback or _default_list_changed_callback
self._resources_list_changed_callback = resources_list_changed_callback or _default_list_changed_callback
self._prompts_list_changed_callback = prompts_list_changed_callback or _default_list_changed_callback
self._tool_output_schemas: dict[str, dict[str, Any] | None] = {}
self._server_capabilities: types.ServerCapabilities | None = None
self._experimental_features: ExperimentalClientFeatures | None = None
Expand Down Expand Up @@ -470,6 +484,12 @@ async def _received_notification(self, notification: types.ServerNotification) -
match notification:
case types.LoggingMessageNotification(params=params):
await self._logging_callback(params)
case types.ToolListChangedNotification():
await self._tools_list_changed_callback()
case types.ResourceListChangedNotification():
await self._resources_list_changed_callback()
case types.PromptListChangedNotification():
await self._prompts_list_changed_callback()
case types.ElicitCompleteNotification(params=params):
# Handle elicitation completion notification
# Clients MAY use this to retry requests or update UI
Expand Down
6 changes: 3 additions & 3 deletions src/mcp/server/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,15 +474,15 @@ async def send_progress_notification(
related_request_id,
)

async def send_resource_list_changed(self) -> None: # pragma: no cover
async def send_resource_list_changed(self) -> None:
"""Send a resource list changed notification."""
await self.send_notification(types.ResourceListChangedNotification())

async def send_tool_list_changed(self) -> None: # pragma: no cover
async def send_tool_list_changed(self) -> None:
"""Send a tool list changed notification."""
await self.send_notification(types.ToolListChangedNotification())

async def send_prompt_list_changed(self) -> None: # pragma: no cover
async def send_prompt_list_changed(self) -> None:
"""Send a prompt list changed notification."""
await self.send_notification(types.PromptListChangedNotification())

Expand Down
135 changes: 135 additions & 0 deletions tests/client/test_list_changed_callback.py
Loading