Skip to content

Commit 4734bf7

Browse files
committed
Adds client support for unknown custom and known custom notifications
1 parent 5f4cee1 commit 4734bf7

File tree

6 files changed

+735
-1
lines changed

6 files changed

+735
-1
lines changed

README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2153,6 +2153,70 @@ if __name__ == "__main__":
21532153
_Full example: [examples/snippets/clients/streamable_basic.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/streamable_basic.py)_
21542154
<!-- /snippet-source -->
21552155

2156+
### Handling Server Notifications
2157+
2158+
Servers may send notifications, which derive from the `ServerNotification` class. To handle these, follow the following steps:
2159+
2160+
1. For each notification type you want to support, write a callback function that follows implements the matching protocol, such as `ToolListChangedFnT` for the tool list changed notification.
2161+
2. Pass that function to the appropriate parameter when instantiating your client, e.g. `tool_list_changed_callback` for the tool list changed notification. This will be called every time your client receives the matching notification.
2162+
2163+
You can also use this pattern with the `UnknownNotificationFnT` protocol to handle notification types that aren't anticipated in the SDK or by your code. This would handle custom notification types from the server.
2164+
2165+
<!-- snippet-source examples/snippets/clients/server_notification_client.py -->
2166+
```python
2167+
# Snippets demonstrating handling known and custom server notifications
2168+
2169+
import asyncio
2170+
2171+
from mcp import ClientSession, StdioServerParameters
2172+
from mcp.client.stdio import stdio_client
2173+
from mcp.types import ServerNotification
2174+
2175+
# Create dummy server parameters for stdio connection
2176+
server_params = StdioServerParameters(
2177+
command="uv",
2178+
args=["run"],
2179+
env={},
2180+
)
2181+
2182+
2183+
# Create a custom handler for the resource list changed notification
2184+
async def custom_resource_list_changed_handler() -> None:
2185+
"""Custom handler for resource list changed notifications."""
2186+
print("RESOURCE LIST CHANGED")
2187+
2188+
2189+
# Create a fallback handler for custom notifications we aren't aware of.
2190+
async def fallback_notification_handler(notification: ServerNotification) -> None:
2191+
"""Fallback handler for unknown notifications."""
2192+
print(f"UNKNOWN notification caught: {notification.root.method}")
2193+
2194+
2195+
async def run():
2196+
async with stdio_client(server_params) as (read, write):
2197+
async with ClientSession(
2198+
read,
2199+
write,
2200+
resource_list_changed_callback=custom_resource_list_changed_handler,
2201+
unknown_notification_callback=fallback_notification_handler,
2202+
) as session:
2203+
# Initialize the connection
2204+
await session.initialize()
2205+
2206+
# Do client stuff here
2207+
2208+
2209+
if __name__ == "__main__":
2210+
asyncio.run(run())
2211+
```
2212+
2213+
_Full example: [examples/snippets/clients/server_notification_client.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/server_notification_client.py)_
2214+
<!-- /snippet-source -->
2215+
2216+
If your client expects to connect to a server that sends custom notifications, you can create your handler or handlers, then pass them in a dictionary where the key is the notification literal and the value is a reference to the handler function. This dictionary is then passed in to the `custom_notification_handlers` parameter of the `ClientSession` constructor.
2217+
2218+
For a runnable example, see [examples/snippets/clients/custom_notifications_example.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/custom_notifications_example.py).
2219+
21562220
### Client Display Utilities
21572221

21582222
When building MCP clients, the SDK provides utilities to help display human-readable names for tools, resources, and prompts:

0 commit comments

Comments
 (0)