feat: add support for custom client notifications (#556)

MCP servers, particularly ones that offer "experimental" capabilities,
may wish to handle custom client notifications that are not part of the
standard MCP specification. This change introduces a new
`CustomClientNotification` type that allows a server to process
such custom notifications.

- introduces `CustomClientNotification` to carry arbitrary methods/params while
  still preserving meta/extensions; wires it into the `ClientNotification` union
  and `serde` so `params` can be decoded with `params_as`
- allows server handlers to receive custom notifications via a new
  `on_custom_notification` hook
- adds integration coverage that sends a custom client notification end-to-end
  and asserts the server sees the method and payload

Test:

```shell
cargo test -p rmcp --features client test_custom_client_notification_reaches_server
```
This commit is contained in:
Michael Bolin 2025-12-01 12:58:18 -08:00 • committed by GitHub
commit 4ef1a163f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 263 additions and 7 deletions

View file

@ -396,6 +396,19 @@
"content"
]
},
"CustomClientNotification": {
"description": "A catch-all notification the client can use to send custom messages to a server.\n\nThis preserves the raw `method` name and `params` payload so handlers can\ndeserialize them into domain-specific types.",
"type": "object",
"properties": {
"method": {
"type": "string"
},
"params": true
},
"required": [
"method"
]
},
"ElicitationAction": {
"description": "Represents the possible actions a user can take in response to an elicitation request.\n\nWhen a server requests user input through elicitation, the user can:\n- Accept: Provide the requested information and continue\n- Decline: Refuse to provide the information but continue the operation\n- Cancel: Stop the entire operation",
"oneOf": [
@ -636,6 +649,9 @@
},
{
"$ref": "#/definitions/NotificationNoParam2"
},
{
"$ref": "#/definitions/CustomClientNotification"
}
],
"required": [

View file

@ -396,6 +396,19 @@
"content"
]
},
"CustomClientNotification": {
"description": "A catch-all notification the client can use to send custom messages to a server.\n\nThis preserves the raw `method` name and `params` payload so handlers can\ndeserialize them into domain-specific types.",
"type": "object",
"properties": {
"method": {
"type": "string"
},
"params": true
},
"required": [
"method"
]
},
"ElicitationAction": {
"description": "Represents the possible actions a user can take in response to an elicitation request.\n\nWhen a server requests user input through elicitation, the user can:\n- Accept: Provide the requested information and continue\n- Decline: Refuse to provide the information but continue the operation\n- Cancel: Stop the entire operation",
"oneOf": [
@ -636,6 +649,9 @@
},
{
"$ref": "#/definitions/NotificationNoParam2"
},
{
"$ref": "#/definitions/CustomClientNotification"
}
],
"required": [