From e3e82bbb3d241de362b5a7457caae7bfcdc9f6c7 Mon Sep 17 00:00:00 2001 From: madevoge <50627071+madevoge@users.noreply.github.com> Date: Sun, 2 Mar 2025 14:40:06 -0800 Subject: [PATCH 1/2] Define Webhook based transport This transport proposal aims to optimize Server to Server communication (hosted clients), especially around long-running sessions and operations. To make MCP work for long running tasks like deep analysis, this proposal defines a transport that leverages http webhooks for bidirectionality. So whilst the SSE transport enables remote servers, a webhook based approach enables remoteness without the need of long-lived open socket connections. As an extension of this transport, we could introduce an (optional) SSE endpoint for message streaming for reduced latency. However, it is critical to not bind the lifetime of the session to the request lifetime. --- docs/specification/draft/basic/transports.md | 55 +++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/docs/specification/draft/basic/transports.md b/docs/specification/draft/basic/transports.md index 739b77a..41ec078 100644 --- a/docs/specification/draft/basic/transports.md +++ b/docs/specification/draft/basic/transports.md @@ -8,12 +8,13 @@ weight: 10 MCP uses JSON-RPC to encode messages. JSON-RPC messages **MUST** be UTF-8 encoded. -The protocol currently defines two standard transport mechanisms for client-server +The protocol currently defines three standard transport mechanisms for client-server communication: 1. [stdio](#stdio), communication over standard in and standard out 2. [HTTP with Server-Sent Events](#http-with-sse) (SSE) - +3. [HTTP with Webhooks](#http-with-webhooks), optimized for long-running and Server to Server communication + Clients **SHOULD** support stdio whenever possible. It is also possible for clients and servers to implement @@ -79,6 +80,56 @@ sequenceDiagram end Client->>Server: Close SSE connection ``` +## HTTP with Webhooks + +Contrary to **stdio** and **SSE**, the lifecycle of a session using **Webhooks** is *not* scoped to a process or request. + +The server **MUST** provide a single HTTP POST endpoint for clients to send messages to the server. + +Additionally, the client **MUST** provide a HTTP POST endpoint for servers to send messages back to the client. + +### Client behavior +A client connects by sending JRPC payloads to the server at a known endpoint. +In addition to the standard JRPC payload, the client **MUST** include an additional `callbackUri` property. +When resuming an existing session, the client **MUST** provide a `sessionId` query parameter. + +### Server behavior +- The server **MUST** follow the callback URI when replying. +- For successful requests, the server must respond with a `200 OK` status code. +- When receiving new payloads from the client, the server **SHOULD** use the latest callback URI from the client. +- The server **MUST** include a `X-MCP-Session-Id` header when sending messages to the client. The server **MAY** change the `X-MCP-Session-Id` in following responses. +- The Server **MAY** encode information in the session id, to enable it to act as a (time-scoped) _Secure Access Signature_ URI. + + ### Disconnect + Whereas we have a clear signal when disconnecting in **stdio** and **SSE**, we cannot depend on a specific connection. Instead, we leverage a combination of signals and HTTP Response codes. +1. If a session is unknown or closed, both client and server **MUST** respond with a `404 Not Found` status code on incoming requests. +2. Client and Server **MAY** send a "notifications/disconnect" JRPC notification payload to indicate +the end of the session. + +```mermaid +sequenceDiagram + participant Client + participant Server + + Client->>Server: HTTP POST messages (+ callbackUri) + Server-->>Client: 200 OK + + Server->>Client: HTTP POST messages on callback Uri (+sessionId) + Client-->>Server: 200 OK + loop Message Exchange + Client->>Server: HTTP POST messages (+ callbackUri + sessionId) + Server-->>Client: 200 OK + Server->>Client: HTTP POST messages on callback Uri (+sessionId) + Client-->>Server: 200 OK + end + + Client->>Server: HTTP POST disconnect message + Server-->>Client: 200 OK + opt Attempting communication on disconnected session + Server->>Client: HTTP POST messages on callback Uri (+sessionId) + Client-->>Server: 404 NOT FOUND + end +``` ## Custom Transports From ba77b30c54c00408503ca76501e9e85c562c5cfc Mon Sep 17 00:00:00 2001 From: Marius de Vogel <50627071+madevoge@users.noreply.github.com> Date: Wed, 5 Mar 2025 09:33:30 -0800 Subject: [PATCH 2/2] Update docs/specification/draft/basic/transports.md Co-authored-by: Darrel --- docs/specification/draft/basic/transports.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/specification/draft/basic/transports.md b/docs/specification/draft/basic/transports.md index 41ec078..5466eca 100644 --- a/docs/specification/draft/basic/transports.md +++ b/docs/specification/draft/basic/transports.md @@ -97,7 +97,7 @@ When resuming an existing session, the client **MUST** provide a `sessionId` que - The server **MUST** follow the callback URI when replying. - For successful requests, the server must respond with a `200 OK` status code. - When receiving new payloads from the client, the server **SHOULD** use the latest callback URI from the client. -- The server **MUST** include a `X-MCP-Session-Id` header when sending messages to the client. The server **MAY** change the `X-MCP-Session-Id` in following responses. +- The server **MUST** include a `MCP-Session-Id` header when sending messages to the client. The server **MAY** change the `MCP-Session-Id` in following responses. - The Server **MAY** encode information in the session id, to enable it to act as a (time-scoped) _Secure Access Signature_ URI. ### Disconnect