diff --git a/docs/specification/draft/changelog.mdx b/docs/specification/draft/changelog.mdx index 6c87cebec..245a00ce9 100644 --- a/docs/specification/draft/changelog.mdx +++ b/docs/specification/draft/changelog.mdx @@ -21,6 +21,8 @@ the previous revision, [2025-03-26](/specification/2025-03-26). 5. Added support for **[elicitation](client/elicitation)**, enabling servers to request additional information from users during interactions. (PR [#382](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/382)) +6. Added support for **[resource links](/specification/draft/server/tools#resource-links)** in + tool call results. (PR [#603](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/603)) ## Other schema changes diff --git a/docs/specification/draft/server/tools.mdx b/docs/specification/draft/server/tools.mdx index 32512901f..c8dcf28ab 100644 --- a/docs/specification/draft/server/tools.mdx +++ b/docs/specification/draft/server/tools.mdx @@ -230,18 +230,38 @@ Tool results may contain [**structured**](#structured-content) or **unstructured } ``` +#### Resource Links + +A tool **MAY** return links to [Resources](/specification/draft/server/resources), to provide additional context +or data. In this case, the tool will return a URI that can be subscribed to or fetched by the client: + +```json +{ + "type": "resource_link", + "uri": "file:///project/src/main.rs", + "name": "main.rs", + "description": "Primary application entry point", + "mimeType": "text/x-rust" +} +``` + + + Resource links returned by tools are not guaranteed to appear in the results + of a `resources/list` request. + + #### Embedded Resources -[Resources](/specification/draft/server/resources) **MAY** be embedded, to provide additional context -or data, behind a URI that can be subscribed to or fetched again by the client later: +A tool **MAY** return embedded [Resource contents](/specification/draft/server/resources), to provide additional context +or data, along with a URI that can be subscribed to or fetched again by the client later: ```json { "type": "resource", "resource": { - "uri": "resource://example", - "mimeType": "text/plain", - "text": "Resource content" + "uri": "file:///project/src/main.rs", + "mimeType": "text/x-rust", + "text": "fn main() {\n println!(\"Hello world!\");\n}" } } ``` diff --git a/schema/draft/schema.json b/schema/draft/schema.json index 5c860cf18..22ed285b1 100644 --- a/schema/draft/schema.json +++ b/schema/draft/schema.json @@ -132,20 +132,7 @@ "content": { "description": "A list of content objects that represent the unstructured result of the tool call.", "items": { - "anyOf": [ - { - "$ref": "#/definitions/TextContent" - }, - { - "$ref": "#/definitions/ImageContent" - }, - { - "$ref": "#/definitions/AudioContent" - }, - { - "$ref": "#/definitions/EmbeddedResource" - } - ] + "$ref": "#/definitions/ContentBlock" }, "type": "array" }, @@ -407,6 +394,25 @@ ], "type": "object" }, + "ContentBlock": { + "anyOf": [ + { + "$ref": "#/definitions/TextContent" + }, + { + "$ref": "#/definitions/ImageContent" + }, + { + "$ref": "#/definitions/AudioContent" + }, + { + "$ref": "#/definitions/ResourceLink" + }, + { + "$ref": "#/definitions/EmbeddedResource" + } + ] + }, "CreateMessageRequest": { "description": "A request from the server to sample an LLM via the client. The client has full discretion over which model to select. The client should also inform the user before beginning sampling, to allow them to inspect the request (human in the loop) and decide whether to approve it.", "properties": { @@ -1556,20 +1562,7 @@ "description": "Describes a message returned as part of a prompt.\n\nThis is similar to `SamplingMessage`, but also supports the embedding of\nresources from the MCP server.", "properties": { "content": { - "anyOf": [ - { - "$ref": "#/definitions/TextContent" - }, - { - "$ref": "#/definitions/ImageContent" - }, - { - "$ref": "#/definitions/AudioContent" - }, - { - "$ref": "#/definitions/EmbeddedResource" - } - ] + "$ref": "#/definitions/ContentBlock" }, "role": { "$ref": "#/definitions/Role" @@ -1739,6 +1732,46 @@ ], "type": "object" }, + "ResourceLink": { + "description": "A resource that the server is capable of reading, included in a prompt or tool call result.\n\nNote: resource links returned by tools are not guaranteed to appear in the results of `resources/list` requests.", + "properties": { + "annotations": { + "$ref": "#/definitions/Annotations", + "description": "Optional annotations for the client." + }, + "description": { + "description": "A description of what this resource represents.\n\nThis can be used by clients to improve the LLM's understanding of available resources. It can be thought of like a \"hint\" to the model.", + "type": "string" + }, + "mimeType": { + "description": "The MIME type of this resource, if known.", + "type": "string" + }, + "name": { + "description": "A human-readable name for this resource.\n\nThis can be used by clients to populate UI elements.", + "type": "string" + }, + "size": { + "description": "The size of the raw resource content, in bytes (i.e., before base64 encoding or any tokenization), if known.\n\nThis can be used by Hosts to display file sizes and estimate context window usage.", + "type": "integer" + }, + "type": { + "const": "resource_link", + "type": "string" + }, + "uri": { + "description": "The URI of this resource.", + "format": "uri", + "type": "string" + } + }, + "required": [ + "name", + "type", + "uri" + ], + "type": "object" + }, "ResourceListChangedNotification": { "description": "An optional notification from the server to the client, informing it that the list of resources it can read from has changed. This may be issued by servers without any previous subscription from the client.", "properties": { diff --git a/schema/draft/schema.ts b/schema/draft/schema.ts index cb53ec029..ec5340a99 100644 --- a/schema/draft/schema.ts +++ b/schema/draft/schema.ts @@ -634,7 +634,16 @@ export type Role = "user" | "assistant"; */ export interface PromptMessage { role: Role; - content: TextContent | ImageContent | AudioContent | EmbeddedResource; + content: ContentBlock; +} + +/** + * A resource that the server is capable of reading, included in a prompt or tool call result. + * + * Note: resource links returned by tools are not guaranteed to appear in the results of `resources/list` requests. + */ +export interface ResourceLink extends Resource { + type: "resource_link"; } /** @@ -652,7 +661,6 @@ export interface EmbeddedResource { */ annotations?: Annotations; } - /** * An optional notification from the server to the client, informing it that the list of prompts it offers has changed. This may be issued by servers without any previous subscription from the client. */ @@ -682,7 +690,7 @@ export interface CallToolResult extends Result { /** * A list of content objects that represent the unstructured result of the tool call. */ - content: (TextContent | ImageContent | AudioContent | EmbeddedResource)[]; + content: ContentBlock[]; /** * An optional JSON object that represents the structured result of the tool call. @@ -953,6 +961,14 @@ export interface Annotations { priority?: number; } +/** */ +export type ContentBlock = + | TextContent + | ImageContent + | AudioContent + | ResourceLink + | EmbeddedResource; + /** * Text provided to or from an LLM. */ @@ -1291,7 +1307,7 @@ export interface EnumSchema { title?: string; description?: string; enum: string[]; - enumNames?: string[]; // Display names for enum values + enumNames?: string[]; // Display names for enum values } /** @@ -1335,7 +1351,11 @@ export type ClientNotification = | InitializedNotification | RootsListChangedNotification; -export type ClientResult = EmptyResult | CreateMessageResult | ListRootsResult | ElicitResult; +export type ClientResult = + | EmptyResult + | CreateMessageResult + | ListRootsResult + | ElicitResult; /* Server messages */ export type ServerRequest =