diff --git a/docs/specification/draft/basic/index.mdx b/docs/specification/draft/basic/index.mdx index fc3cf00aa..3f8b3146c 100644 --- a/docs/specification/draft/basic/index.mdx +++ b/docs/specification/draft/basic/index.mdx @@ -38,6 +38,10 @@ Requests are sent from the client to the server or vice versa, to initiate an op method: string; params?: { [key: string]: unknown; + _meta?: { + [key: string]: unknown; + allowPartial?: boolean; + } }; } ``` @@ -46,6 +50,7 @@ Requests are sent from the client to the server or vice versa, to initiate an op - Unlike base JSON-RPC, the ID **MUST NOT** be `null`. - The request ID **MUST NOT** have been previously used by the requestor within the same session. +- Requests **MAY** allow partial results by setting the `allowPartial` flag. ### Responses @@ -57,6 +62,10 @@ Responses are sent in reply to requests, containing the result or error of the o id: string | number; result?: { [key: string]: unknown; + _meta?: { + [key: string]: unknown; + hasMore?: boolean; + } } error?: { code: number; @@ -70,6 +79,8 @@ Responses are sent in reply to requests, containing the result or error of the o - **Responses** are further sub-categorized as either **successful results** or **errors**. Either a `result` or an `error` **MUST** be set. A response **MUST NOT** set both. +- Results **MAY** set `hasMore` flag only if the corresponding request set the `allowPartial` flag. + The flag indicates that more responses with the same ID will follow. - Results **MAY** follow any JSON object structure, while errors **MUST** include an error code and message at minimum. - Error codes **MUST** be integers. diff --git a/docs/specification/draft/basic/transports.mdx b/docs/specification/draft/basic/transports.mdx index 3a79a9ec8..e7528753f 100644 --- a/docs/specification/draft/basic/transports.mdx +++ b/docs/specification/draft/basic/transports.mdx @@ -101,15 +101,15 @@ MCP endpoint. `Content-Type: application/json`, to return one JSON object. The client **MUST** support both these cases. 6. If the server initiates an SSE stream: - - The SSE stream **SHOULD** eventually include JSON-RPC _response_ for the + - The SSE stream **SHOULD** eventually include JSON-RPC _response(s)_ for the JSON-RPC _request_ sent in the POST body. - The server **MAY** send JSON-RPC _requests_ and _notifications_ before sending the - JSON-RPC _response_. These messages **SHOULD** relate to the originating client + final JSON-RPC _response_. These messages **SHOULD** relate to the originating client _request_. - - The server **SHOULD NOT** close the SSE stream before sending the JSON-RPC _response_ + - The server **SHOULD NOT** close the SSE stream before sending the JSON-RPC _response(s)_ for the received JSON-RPC _request_, unless the [session](#session-management) expires. - - After the JSON-RPC _response_ has been sent, the server **SHOULD** close the SSE + - After the final JSON-RPC _response_ has been sent, the server **SHOULD** close the SSE stream. - Disconnection **MAY** occur at any time (e.g., due to network conditions). Therefore: diff --git a/docs/specification/draft/server/tools.mdx b/docs/specification/draft/server/tools.mdx index adf1760a5..780041d19 100644 --- a/docs/specification/draft/server/tools.mdx +++ b/docs/specification/draft/server/tools.mdx @@ -347,6 +347,29 @@ Providing an output schema helps clients and LLMs understand and properly handle - Guiding clients and LLMs to properly parse and utilize the returned data - Supporting better documentation and developer experience +## Content streaming + +Tools might provide result as a stream of partial results: + +```mermaid +sequenceDiagram + participant User + participant Client + participant Server + + Note over Client,Server: Streaming + Client->>Server: tools/call + Server-->>Client: Tool partial result + Client-->>User: Content + Server-->>Client: Tool partial result + Client-->>User: Content + Server-->>Client: Tool partial result + Client-->>User: Content +``` + +_Unstructured_ content is incremental and the complete result can be acquired by concatenation. +_Structured_ content is not incremental unless the tool's output schema states otherwise. + ## Error Handling Tools use two error reporting mechanisms: diff --git a/schema/draft/schema.json b/schema/draft/schema.json index f1139948d..24dc7194f 100644 --- a/schema/draft/schema.json +++ b/schema/draft/schema.json @@ -131,6 +131,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" }, "content": { @@ -367,6 +373,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" }, "completion": { @@ -488,6 +500,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" }, "content": { @@ -585,6 +603,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" }, "action": { @@ -714,6 +738,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" }, "description": { @@ -816,6 +846,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" }, "capabilities": { @@ -965,6 +1001,10 @@ "properties": { "_meta": { "properties": { + "allowPartial": { + "description": "If specified, the caller is requesting partial results for this request. The receiver is not obligated to return partial results.", + "type": "boolean" + }, "progressToken": { "$ref": "#/definitions/ProgressToken", "description": "If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications." @@ -1032,6 +1072,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" }, "nextCursor": { @@ -1078,6 +1124,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" }, "nextCursor": { @@ -1124,6 +1176,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" }, "nextCursor": { @@ -1154,6 +1212,10 @@ "properties": { "_meta": { "properties": { + "allowPartial": { + "description": "If specified, the caller is requesting partial results for this request. The receiver is not obligated to return partial results.", + "type": "boolean" + }, "progressToken": { "$ref": "#/definitions/ProgressToken", "description": "If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications." @@ -1176,6 +1238,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" }, "roots": { @@ -1218,6 +1286,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" }, "nextCursor": { @@ -1399,6 +1473,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" }, "nextCursor": { @@ -1420,6 +1500,10 @@ "properties": { "_meta": { "properties": { + "allowPartial": { + "description": "If specified, the caller is requesting partial results for this request. The receiver is not obligated to return partial results.", + "type": "boolean" + }, "progressToken": { "$ref": "#/definitions/ProgressToken", "description": "If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications." @@ -1635,6 +1719,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" }, "contents": { @@ -1666,6 +1756,10 @@ "properties": { "_meta": { "properties": { + "allowPartial": { + "description": "If specified, the caller is requesting partial results for this request. The receiver is not obligated to return partial results.", + "type": "boolean" + }, "progressToken": { "$ref": "#/definitions/ProgressToken", "description": "If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications." @@ -1889,6 +1983,12 @@ "_meta": { "additionalProperties": {}, "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", + "properties": { + "hasMore": { + "description": "If true, more results will follow.", + "type": "boolean" + } + }, "type": "object" } }, diff --git a/schema/draft/schema.ts b/schema/draft/schema.ts index fdbb02894..58b0cdbc5 100644 --- a/schema/draft/schema.ts +++ b/schema/draft/schema.ts @@ -30,6 +30,10 @@ export interface Request { * If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications. */ progressToken?: ProgressToken; + /** + * If specified, the caller is requesting partial results for this request. The receiver is not obligated to return partial results. + */ + allowPartial?: boolean; }; [key: string]: unknown; }; @@ -50,7 +54,13 @@ export interface Result { /** * This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses. */ - _meta?: { [key: string]: unknown }; + _meta?: { + /** + * If true, more results will follow. + */ + hasMore?: boolean; + [key: string]: unknown; + }; [key: string]: unknown; }