-
Notifications
You must be signed in to change notification settings - Fork 762
Feat: Add Webhooks as a server capability #593
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Authenticating webhooks is at tricky proposition. Can I suggest that an initial impl for a WH callback would be to a publicly accessible client endpoint without guarantees of authorization? Edit: moving my comment into the discussion thread: #523 (comment) |
@AchintyaAshok Left a comment on the discussion. I think the suggestion makes sense but until we have a a better auth mechanism, my spec changes would allow support for webhooks while ensuring basic security from vulnerabilities. Without this, it would be hard to securely host webhooks that can receive communication from MCP servers. I am fine with simplifying it further and just allowing for custom headers. The client can directly specify the auth headers that they might want to add for secure communication with the webhook. I would also like to hear from others in the community and the sdk maintainers. Open to removing it completely as well if that is the consensus. |
I created a demo to demonstrate how webhooks can be used by an MCP client when dealing with long-running/asynchronous processes. This uses the python SDK implementation of webhooks that is present in my draft PR. The client can pass a webhook to the server during a tool call and send a generic response to the user when it receives an acknowledgement from the server. The server will asynchronously process the tool call and route the result to the webhook. Based on the client implementation, the call tool result will then either be pushed to the client by the webhook or be fetched from the webhook by the client. The client can use the call tool result to generate a relevant response for the original user query. MCP.Webhook.Demo.mp4 |
I am aligned with the goal of needing signals to enable long running processes. With Streamable enabling resumable SSE streams; why not have the callback have 0 content, and allow the client to use it as a signal to re-connect through the GET endpoint? This enforces (authenticated) HTTP requests for any data retrieval; whilst preventing clients from keeping open connections / polling the GET endpoint for very long running operations. wdyt? |
I am aligned with this. However, I do think this should be something that is configurable by the server owner. If a certain server does not have security concerns wrt their response, I think MCP should offer the capability to send back the response content. Otherwise resuming the stream could be the mechanism to ensure secure data retrieval. |
Webhooks are HTTP based. This leaks the transport layer into the data layer of the protocol and wouldn't work in a stdio case. I think there is use in a generalized concept around |
Acknowledged. Will draft a more generalizable SEP for |
Add support for transmitting call tool responses to webhooks. Routing the responses to the webhook will be the responsibility of the transport layer, however, this specification change will standardize how webhooks can be passed from the client to the server and how the server can expose support for webhooks as a capability.
Changes:
Motivation and Context
Discussed in #523
As MCP expands to support asynchronous communication (#491), there will arise scenarios wherein the async execution will take anywhere from a few hours to a few days. The current discussion revolves around modeling long-running executions as resources/streams that require client polling to allow the client to disconnect from the server.
In order to free up the client and reduce load when handling multiple async operations, the recommended approach is often to offer support for webhooks (similar discussion: #266). Webhooks offer a lightweight approach that allow the server to send results to the client when the async execution for a tool has been completed. Webhooks can be hosted by standalone servers (common in cloud services) or in some cases, they can be hosted by the client.
Even though the webhook routing implementation will exist in the transport layer, the server will have the ability to decide whether to offer support for routing responses to webhooks or not. This decision could be based on whether the server comprises of asynchronous tools, whether the server wants to establish connections to the webhooks uris provided by the client (security concerns), if the server wants to risk additional latency of transmitting results to webhook (reliability) etc-.
If a server supports webhook capability, webhooks will be supported for all tools in the server. The client will have the option to pass webhooks as part of the CallToolsRequest. Any request with webhooks will have the final results transmitted to webhooks instead of back to the client. The client will receive an acknowledgement response once the tool call with webhooks has been received by the server.
The tool call implementations should be able to vary their behaviour depending on whether the tool call from the client consists of a webhook or not. This can be achieved by adding information to the request context about whether a webhook was passed in the request or not.
Examples
How Has This Been Tested?
Breaking Changes
None
Types of changes
Checklist