From bb5f71375e07d1c19c84844bb8c07f2bbdada7d1 Mon Sep 17 00:00:00 2001 From: Lukas Welinder Date: Wed, 16 Apr 2025 14:51:37 -0600 Subject: [PATCH 1/8] Add tool `outputSchema` and `JsonContent` content type --- schema/2025-03-26/schema.json | 77 +++++++++++++++++++++++++++++++++++ schema/2025-03-26/schema.ts | 37 +++++++++++++++-- 2 files changed, 111 insertions(+), 3 deletions(-) diff --git a/schema/2025-03-26/schema.json b/schema/2025-03-26/schema.json index e12106abc..100f95eaa 100644 --- a/schema/2025-03-26/schema.json +++ b/schema/2025-03-26/schema.json @@ -122,6 +122,9 @@ }, { "$ref": "#/definitions/EmbeddedResource" + }, + { + "$ref": "#/definitions/JsonContent" } ] }, @@ -438,6 +441,9 @@ }, { "$ref": "#/definitions/AudioContent" + }, + { + "$ref": "#/definitions/JsonContent" } ] }, @@ -880,6 +886,44 @@ ], "type": "object" }, + "JsonContent": { + "description": "Text provided to or from an LLM.", + "properties": { + "annotations": { + "$ref": "#/definitions/Annotations", + "description": "Optional annotations for the client." + }, + "data": { + "additionalProperties": true, + "description": "The text content of the message.", + "properties": {}, + "type": "object" + }, + "schema": { + "anyOf": [ + { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + { + "type": "string" + } + ], + "description": "The schema reference or definition of the JSON content." + }, + "type": { + "const": "json", + "type": "string" + } + }, + "required": [ + "data", + "schema", + "type" + ], + "type": "object" + }, "ListPromptsRequest": { "description": "Sent from the client to request a list of prompts and prompt templates the server has.", "properties": { @@ -1416,6 +1460,9 @@ }, { "$ref": "#/definitions/EmbeddedResource" + }, + { + "$ref": "#/definitions/JsonContent" } ] }, @@ -1762,6 +1809,9 @@ }, { "$ref": "#/definitions/AudioContent" + }, + { + "$ref": "#/definitions/JsonContent" } ] }, @@ -2043,6 +2093,33 @@ "name": { "description": "The name of the tool.", "type": "string" + }, + "outputSchema": { + "description": "A JSON Schema object defining the expected output for the tool's JSON content response.", + "properties": { + "properties": { + "additionalProperties": { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + "type": "object" + }, + "required": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "const": "object", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" } }, "required": [ diff --git a/schema/2025-03-26/schema.ts b/schema/2025-03-26/schema.ts index 555ea5eac..5c971bd2a 100644 --- a/schema/2025-03-26/schema.ts +++ b/schema/2025-03-26/schema.ts @@ -642,7 +642,7 @@ export type Role = "user" | "assistant"; */ export interface PromptMessage { role: Role; - content: TextContent | ImageContent | AudioContent | EmbeddedResource; + content: TextContent | ImageContent | AudioContent | EmbeddedResource | JsonContent; } /** @@ -696,7 +696,7 @@ export interface ListToolsResult extends PaginatedResult { * should be reported as an MCP error response. */ export interface CallToolResult extends Result { - content: (TextContent | ImageContent | AudioContent | EmbeddedResource)[]; + content: (TextContent | ImageContent | AudioContent | EmbeddedResource | JsonContent)[]; /** * Whether the tool call ended in an error. @@ -803,6 +803,15 @@ export interface Tool { required?: string[]; }; + /** + * A JSON Schema object defining the expected output for the tool's JSON content response. + */ + outputSchema?: { + type: "object"; + properties?: { [key: string]: object }; + required?: string[]; + }; + /** * Optional additional tool information. */ @@ -915,7 +924,7 @@ export interface CreateMessageResult extends Result, SamplingMessage { */ export interface SamplingMessage { role: Role; - content: TextContent | ImageContent | AudioContent; + content: TextContent | ImageContent | AudioContent | JsonContent; } /** @@ -1008,6 +1017,28 @@ export interface AudioContent { annotations?: Annotations; } +/** + * Text provided to or from an LLM. + */ +export interface JsonContent { + type: "json"; + + /** + * The text content of the message. + */ + data: object; + + /** + * The schema reference or definition of the JSON content. + */ + schema: string | object; + + /** + * Optional annotations for the client. + */ + annotations?: Annotations; +} + /** * The server's preferences for model selection, requested of the client during sampling. * From 88e025888f9c4b6945cc56a6363ba42b2f877a49 Mon Sep 17 00:00:00 2001 From: Lukas Welinder Date: Wed, 16 Apr 2025 14:52:13 -0600 Subject: [PATCH 2/8] Document tool `outputSchema` and `JsonContent` usage --- docs/docs.json | 1 + docs/docs/concepts/content-types.mdx | 264 ++++++++++++ docs/docs/concepts/tools.mdx | 392 ++++++++++++++++++ docs/specification/2025-03-26/changelog.mdx | 4 + .../specification/2025-03-26/server/tools.mdx | 32 ++ 5 files changed, 693 insertions(+) create mode 100644 docs/docs/concepts/content-types.mdx diff --git a/docs/docs.json b/docs/docs.json index 8d899ded2..359febab2 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -45,6 +45,7 @@ "docs/concepts/resources", "docs/concepts/prompts", "docs/concepts/tools", + "docs/concepts/content-types", "docs/concepts/sampling", "docs/concepts/roots", "docs/concepts/transports" diff --git a/docs/docs/concepts/content-types.mdx b/docs/docs/concepts/content-types.mdx new file mode 100644 index 000000000..78d9236d1 --- /dev/null +++ b/docs/docs/concepts/content-types.mdx @@ -0,0 +1,264 @@ +--- +title: "Content Types" +description: "Understanding data formats in the Model Context Protocol" +--- + +Content types define the format of data exchanged between clients and servers in the Model Context Protocol (MCP). These types enable rich multimodal interactions, allowing LLMs to process and generate various forms of content beyond just text. + +## Overview + +MCP supports several content types that can be used in different contexts: + +- **Text**: Plain text content +- **Image**: Visual content as base64-encoded data +- **Audio**: Sound content as base64-encoded data +- **JSON**: Structured data with optional schema information +- **Embedded Resources**: References to resources available on the server + +These content types allow for flexible interactions that combine different modalities, enabling a wide range of applications from simple text responses to complex multimodal interactions. + +## Text Content + +Text content is the most basic and commonly used content type, representing plain text data: + +```json +{ + "type": "text", + "text": "This is a text message." +} +``` + +The `text` field contains the actual text content, which can include any valid string data. + +## Image Content + +Image content allows including visual information: + +```json +{ + "type": "image", + "data": "base64-encoded-image-data", + "mimeType": "image/png", + "annotations": { + "audience": ["user", "assistant"], + "priority": 0.8 + } +} +``` + +Key fields: +- `data`: Base64-encoded image data +- `mimeType`: MIME type of the image (e.g., `image/png`, `image/jpeg`) +- `annotations`: Optional metadata about the image (e.g., intended audience, priority) + +## Audio Content + +Audio content enables the inclusion of sound information: + +```json +{ + "type": "audio", + "data": "base64-encoded-audio-data", + "mimeType": "audio/wav" +} +``` + +Key fields: +- `data`: Base64-encoded audio data +- `mimeType`: MIME type of the audio (e.g., `audio/wav`, `audio/mp3`) + +## JSON Content + +JSON content allows structured data to be exchanged: + +```json +{ + "type": "json", + "data": { + "temperature": 72, + "conditions": "Partly cloudy", + "forecast": [ + {"day": "Monday", "high": 75, "low": 58}, + {"day": "Tuesday", "high": 80, "low": 62} + ] + }, + "schema": "#/components/schemas/WeatherResponse" +} +``` + +Key fields: +- `data`: The JSON object containing structured data +- `schema`: Optional reference to a JSON schema that describes the structure of the data + +The `schema` field can be one of the following: +- Omitted (in which case the context might provide the schema, such as a tool's `outputSchema`) +- A string (interpreted as a URI reference to a schema, which could be a local reference or a full URL) +- An object (containing the complete schema definition) + +Example with inline schema: + +```json +{ + "type": "json", + "data": { + "count": 42 + }, + "schema": { + "type": "object", + "properties": { + "count": { + "type": "number", + "description": "The current count value" + } + } + } +} +``` + +## Embedded Resources + +Embedded resources allow referencing server-side resources directly in messages: + +```json +{ + "type": "resource", + "resource": { + "uri": "file:///example.txt", + "mimeType": "text/plain", + "text": "This is the content of the file." + } +} +``` + +For text resources, the `text` field contains the content. For binary resources, a `blob` field with base64-encoded data is used instead: + +```json +{ + "type": "resource", + "resource": { + "uri": "file:///example.png", + "mimeType": "image/png", + "blob": "base64-encoded-data" + } +} +``` + +Key fields: +- `resource`: An object containing resource metadata and content + - `uri`: The URI identifying the resource + - `mimeType`: The MIME type of the resource + - `text` or `blob`: The content of the resource + +## Usage in the Protocol + +Content types are used in multiple places in the MCP protocol: + +### Tool Results + +When a tool is called, it returns one or more content items: + +```json +{ + "content": [ + { + "type": "text", + "text": "Weather information:" + }, + { + "type": "json", + "data": { + "temperature": 72, + "conditions": "Partly cloudy" + } + } + ], + "isError": false +} +``` + +### Prompt Messages + +Prompts can include different content types to provide context: + +```json +{ + "messages": [ + { + "role": "user", + "content": { + "type": "text", + "text": "Can you describe this image?" + } + }, + { + "role": "user", + "content": { + "type": "image", + "data": "base64-encoded-image-data", + "mimeType": "image/jpeg" + } + } + ] +} +``` + +### Sampling Messages + +When sampling from an LLM, content types can be included in both the request and response: + +```json +{ + "messages": [ + { + "role": "user", + "content": { + "type": "text", + "text": "What's happening in this image?" + } + }, + { + "role": "user", + "content": { + "type": "image", + "data": "base64-encoded-image-data", + "mimeType": "image/jpeg" + } + } + ] +} +``` + +## Annotations + +All content types can include optional annotations that provide additional metadata: + +```json +"annotations": { + "audience": ["user", "assistant"], + "priority": 0.8 +} +``` + +Common annotations include: +- `audience`: Indicates who the content is intended for (`"user"`, `"assistant"`, or both) +- `priority`: A value between 0 and 1 indicating the importance of the content (1 being most important) + +## Best Practices + +When working with content types: + +1. **Choose the appropriate type**: Use the content type that best represents your data +2. **Validate content**: Ensure the content adheres to the expected format +3. **Handle multiple types**: Be prepared to process different content types in responses +4. **Consider bandwidth**: For large binary data, consider using resources instead of embedding directly +5. **Set proper annotations**: Use annotations to guide how content should be handled or displayed + +## Security Considerations + +When handling content types: + +1. **Validate all content**: Especially for binary data like images and audio +2. **Limit data sizes**: Set reasonable limits on content sizes to prevent resource exhaustion +3. **Sanitize text content**: Prevent injection attacks in text content +4. **Verify schemas**: For JSON content, validate against the provided schema +5. **Check MIME types**: Only allow expected MIME types for images and audio \ No newline at end of file diff --git a/docs/docs/concepts/tools.mdx b/docs/docs/concepts/tools.mdx index e697e3d33..fcb1e8f48 100644 --- a/docs/docs/concepts/tools.mdx +++ b/docs/docs/concepts/tools.mdx @@ -41,6 +41,19 @@ Each tool is defined with the following structure: } ``` +Additional optional properties include: + +```typescript +{ + outputSchema?: { // JSON Schema for the tool's JSON response (optional) + type: "object", + properties: { ... } // Expected JSON structure + } +} +``` + +The `outputSchema` property defines the expected structure for JSON content returned by the tool, which can be helpful for both clients and AI models to understand the tool's output format. + ## Implementing tools Here's an example of implementing a basic tool in an MCP server: @@ -128,6 +141,129 @@ Here's an example of implementing a basic tool in an MCP server: +### Example with outputSchema and JSON content + +Here's an example of a tool that uses `outputSchema` and returns JSON content: + + + + ```typescript + // Define available tools + server.setRequestHandler(ListToolsRequestSchema, async () => { + return { + tools: [{ + name: "get_weather", + description: "Get weather information for a location", + inputSchema: { + type: "object", + properties: { + location: { type: "string" } + }, + required: ["location"] + }, + outputSchema: { + type: "object", + properties: { + temperature: { type: "number" }, + conditions: { type: "string" }, + forecast: { + type: "array", + items: { + type: "object", + properties: { + day: { type: "string" }, + high: { type: "number" }, + low: { type: "number" } + } + } + } + } + } + }] + }; + }); + + // Handle tool execution + server.setRequestHandler(CallToolRequestSchema, async (request) => { + if (request.params.name === "get_weather") { + const { location } = request.params.arguments; + + // Fetch weather data + const weatherData = await fetchWeatherData(location); + + // Return as structured JSON + return { + content: [ + { + type: "json", + data: weatherData, + // schema field is optional - if omitted, outputSchema is used + } + ] + }; + } + throw new Error("Tool not found"); + }); + ``` + + + ```python + @app.list_tools() + async def list_tools() -> list[types.Tool]: + return [ + types.Tool( + name="get_weather", + description="Get weather information for a location", + inputSchema={ + "type": "object", + "properties": { + "location": {"type": "string"} + }, + "required": ["location"] + }, + outputSchema={ + "type": "object", + "properties": { + "temperature": {"type": "number"}, + "conditions": {"type": "string"}, + "forecast": { + "type": "array", + "items": { + "type": "object", + "properties": { + "day": {"type": "string"}, + "high": {"type": "number"}, + "low": {"type": "number"} + } + } + } + } + } + ) + ] + + @app.call_tool() + async def call_tool( + name: str, + arguments: dict + ) -> list[types.TextContent | types.ImageContent | types.JsonContent | types.EmbeddedResource]: + if name == "get_weather": + location = arguments["location"] + + # Fetch weather data + weather_data = await fetch_weather_data(location) + + # Return as structured JSON + return [types.JsonContent( + type="json", + data=weather_data + # schema field is optional - if omitted, outputSchema is used + )] + raise ValueError(f"Tool not found: {name}") + ``` + + + ## Example tool patterns Here are some examples of types of tools that a server could provide: @@ -192,6 +328,140 @@ Tools that transform or analyze data: } ``` +### Tool with structured output + +Here's an example of a tool designed to return structured data: + +```typescript +{ + name: "search_products", + description: "Search for products in the catalog", + inputSchema: { + type: "object", + properties: { + query: { type: "string" }, + category: { type: "string" }, + maxResults: { type: "number" } + }, + required: ["query"] + }, + outputSchema: { + type: "object", + properties: { + totalResults: { type: "number" }, + products: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + name: { type: "string" }, + price: { type: "number" }, + inStock: { type: "boolean" } + } + } + } + } + } +} +``` + +## Content types for tool results + +When a tool is called, it can return multiple content items of different types: + +### Text Content + +```json +{ + "type": "text", + "text": "Tool result text" +} +``` + +### Image Content + +```json +{ + "type": "image", + "data": "base64-encoded-data", + "mimeType": "image/png" +} +``` + +### Audio Content + +```json +{ + "type": "audio", + "data": "base64-encoded-audio-data", + "mimeType": "audio/wav" +} +``` + +### JSON Content + +```json +{ + "type": "json", + "data": { + "temperature": 72, + "conditions": "Partly cloudy" + }, + "schema": "#/components/schemas/WeatherResponse" +} +``` + +The JSON content type allows structured data to be returned from tools with several options: + +- If `schema` is omitted, the tool's `outputSchema` is implied +- If `schema` is a string, it is interpreted as a URI reference to a schema +- If `schema` is an object, it provides the full schema definition + +Example with an inline schema: + +```json +{ + "type": "json", + "data": { + "results": [ + {"id": "product-1", "name": "Widget", "price": 9.99} + ] + }, + "schema": { + "type": "object", + "properties": { + "results": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "name": { "type": "string" }, + "price": { "type": "number" } + } + } + } + } + } +} +``` + +### Embedded Resources + +Resources can be embedded directly in tool results: + +```json +{ + "type": "resource", + "resource": { + "uri": "resource://example", + "mimeType": "text/plain", + "text": "Resource content" + } +} +``` + ## Best practices When implementing tools: @@ -307,6 +577,88 @@ Here's an example of proper error handling for tools: +### Error handling with JSON content + +For tools that return JSON content, error handling can include structured error information: + + + + ```typescript + try { + // Tool operation + const data = await fetchData(); + return { + content: [ + { + type: "json", + data: data + } + ] + }; + } catch (error) { + return { + isError: true, + content: [ + { + type: "json", + data: { + errorCode: error.code || "UNKNOWN_ERROR", + message: error.message, + details: error.details || {} + }, + schema: { + type: "object", + properties: { + errorCode: { type: "string" }, + message: { type: "string" }, + details: { type: "object" } + } + } + } + ] + }; + } + ``` + + + ```python + try: + # Tool operation + data = await fetch_data() + return types.CallToolResult( + content=[ + types.JsonContent( + type="json", + data=data + ) + ] + ) + except Exception as error: + return types.CallToolResult( + isError=True, + content=[ + types.JsonContent( + type="json", + data={ + "errorCode": getattr(error, "code", "UNKNOWN_ERROR"), + "message": str(error), + "details": getattr(error, "details", {}) + }, + schema={ + "type": "object", + "properties": { + "errorCode": {"type": "string"}, + "message": {"type": "string"}, + "details": {"type": "object"} + } + } + ) + ] + ) + ``` + + + This approach allows the LLM to see that an error occurred and potentially take corrective action or request human intervention. ## Tool annotations @@ -399,6 +751,46 @@ Here's how to define tools with annotations for different scenarios: } ``` +### Tool with outputSchema and annotations + +Here's an example combining outputSchema with annotations: + +```typescript +{ + name: "fetch_stock_data", + description: "Fetch current stock price and market data", + inputSchema: { + type: "object", + properties: { + symbol: { type: "string" }, + metrics: { + type: "array", + items: { + enum: ["price", "volume", "marketCap", "peRatio"] + } + } + }, + required: ["symbol"] + }, + outputSchema: { + type: "object", + properties: { + symbol: { type: "string" }, + price: { type: "number" }, + volume: { type: "number" }, + marketCap: { type: "number" }, + peRatio: { type: "number" }, + lastUpdated: { type: "string", format: "date-time" } + } + }, + annotations: { + title: "Stock Data Lookup", + readOnlyHint: true, + openWorldHint: true + } +} +``` + ### Integrating annotations in server implementation diff --git a/docs/specification/2025-03-26/changelog.mdx b/docs/specification/2025-03-26/changelog.mdx index 1e4da5d38..66b9c0351 100644 --- a/docs/specification/2025-03-26/changelog.mdx +++ b/docs/specification/2025-03-26/changelog.mdx @@ -18,6 +18,10 @@ the previous revision, [2024-11-05](/specification/2024-11-05). 1. Added comprehensive **tool annotations** for better describing tool behavior, like whether it is read-only or destructive (PR [#185](https://github.com/modelcontextprotocol/specification/pull/185)) +1. Added **structured JSON content type** support for returning structured data from tools + (PR [#XXX](https://github.com/modelcontextprotocol/specification/pull/XXX)) +1. Added **outputSchema** property to tools to define the expected JSON schema for tool results + (PR [#XXX](https://github.com/modelcontextprotocol/specification/pull/XXX)) ## Other schema changes diff --git a/docs/specification/2025-03-26/server/tools.mdx b/docs/specification/2025-03-26/server/tools.mdx index fe97f2112..5ede19844 100644 --- a/docs/specification/2025-03-26/server/tools.mdx +++ b/docs/specification/2025-03-26/server/tools.mdx @@ -88,6 +88,19 @@ To discover available tools, clients send a `tools/list` request. This operation } }, "required": ["location"] + }, + "outputSchema": { + "type": "object", + "properties": { + "temperature": { + "type": "number", + "description": "Temperature in degrees Fahrenheit" + }, + "conditions": { + "type": "string", + "description": "Weather conditions description" + } + } } } ], @@ -181,6 +194,7 @@ A tool definition includes: - `name`: Unique identifier for the tool - `description`: Human-readable description of functionality - `inputSchema`: JSON Schema defining expected parameters +- `outputSchema`: Optional JSON Schema defining the structure of JSON responses - `annotations`: optional properties describing tool behavior For trust & safety and security, clients **MUST** consider @@ -219,6 +233,24 @@ Tool results can contain multiple content items of different types: } ``` +#### JSON Content + +```json +{ + "type": "json", + "data": { + "temperature": 72, + "conditions": "Partly cloudy" + }, + "schema": "#/components/schemas/WeatherResponse" +} +``` + +The JSON content type allows structured data to be returned from tools. The `schema` field can be: +- Omitted (in which case the tool's `outputSchema` is implied) +- A string (which is interpreted as a URI reference to a schema) +- An object (containing the full schema definition) + #### Embedded Resources [Resources](/specification/2025-03-26/server/resources) **MAY** be embedded, to provide additional context From 0f19c33433e045a89e98b51a095b08ea199f0077 Mon Sep 17 00:00:00 2001 From: lukaswelinder Date: Fri, 18 Apr 2025 18:06:37 -0600 Subject: [PATCH 3/8] Change name of `JsonContent` to `DataContent` --- docs/docs/concepts/content-types.mdx | 16 ++-- docs/docs/concepts/tools.mdx | 38 ++++----- .../specification/2025-03-26/server/tools.mdx | 2 +- schema/2025-03-26/schema.json | 84 +++++++++---------- schema/2025-03-26/schema.ts | 10 +-- 5 files changed, 75 insertions(+), 75 deletions(-) diff --git a/docs/docs/concepts/content-types.mdx b/docs/docs/concepts/content-types.mdx index 78d9236d1..d595ad98d 100644 --- a/docs/docs/concepts/content-types.mdx +++ b/docs/docs/concepts/content-types.mdx @@ -12,7 +12,7 @@ MCP supports several content types that can be used in different contexts: - **Text**: Plain text content - **Image**: Visual content as base64-encoded data - **Audio**: Sound content as base64-encoded data -- **JSON**: Structured data with optional schema information +- **Data**: Structured data with optional schema information - **Embedded Resources**: References to resources available on the server These content types allow for flexible interactions that combine different modalities, enabling a wide range of applications from simple text responses to complex multimodal interactions. @@ -67,13 +67,13 @@ Key fields: - `data`: Base64-encoded audio data - `mimeType`: MIME type of the audio (e.g., `audio/wav`, `audio/mp3`) -## JSON Content +## Data Content -JSON content allows structured data to be exchanged: +Data content allows structured data to be exchanged: ```json { - "type": "json", + "type": "data", "data": { "temperature": 72, "conditions": "Partly cloudy", @@ -87,7 +87,7 @@ JSON content allows structured data to be exchanged: ``` Key fields: -- `data`: The JSON object containing structured data +- `data`: The JSON serializable object containing structured data - `schema`: Optional reference to a JSON schema that describes the structure of the data The `schema` field can be one of the following: @@ -99,7 +99,7 @@ Example with inline schema: ```json { - "type": "json", + "type": "data", "data": { "count": 42 }, @@ -165,7 +165,7 @@ When a tool is called, it returns one or more content items: "text": "Weather information:" }, { - "type": "json", + "type": "data", "data": { "temperature": 72, "conditions": "Partly cloudy" @@ -260,5 +260,5 @@ When handling content types: 1. **Validate all content**: Especially for binary data like images and audio 2. **Limit data sizes**: Set reasonable limits on content sizes to prevent resource exhaustion 3. **Sanitize text content**: Prevent injection attacks in text content -4. **Verify schemas**: For JSON content, validate against the provided schema +4. **Verify schemas**: For data content, validate against the provided schema 5. **Check MIME types**: Only allow expected MIME types for images and audio \ No newline at end of file diff --git a/docs/docs/concepts/tools.mdx b/docs/docs/concepts/tools.mdx index fcb1e8f48..6f354a8eb 100644 --- a/docs/docs/concepts/tools.mdx +++ b/docs/docs/concepts/tools.mdx @@ -45,14 +45,14 @@ Additional optional properties include: ```typescript { - outputSchema?: { // JSON Schema for the tool's JSON response (optional) + outputSchema?: { // JSON Schema for the tool's response (optional) type: "object", - properties: { ... } // Expected JSON structure + properties: { ... } // Expected structure } } ``` -The `outputSchema` property defines the expected structure for JSON content returned by the tool, which can be helpful for both clients and AI models to understand the tool's output format. +The `outputSchema` property defines the expected structure for data content returned by the tool, which can be helpful for both clients and AI models to understand the tool's output format. ## Implementing tools @@ -195,9 +195,9 @@ Here's an example of a tool that uses `outputSchema` and returns JSON content: return { content: [ { - type: "json", + type: "data", data: weatherData, - // schema field is optional - if omitted, outputSchema is used + // schema field is optional - if omitted, the tool's outputSchema is implied } ] }; @@ -246,7 +246,7 @@ Here's an example of a tool that uses `outputSchema` and returns JSON content: async def call_tool( name: str, arguments: dict - ) -> list[types.TextContent | types.ImageContent | types.JsonContent | types.EmbeddedResource]: + ) -> list[types.TextContent | types.ImageContent | types.DataContent | types.EmbeddedResource]: if name == "get_weather": location = arguments["location"] @@ -254,10 +254,10 @@ Here's an example of a tool that uses `outputSchema` and returns JSON content: weather_data = await fetch_weather_data(location) # Return as structured JSON - return [types.JsonContent( - type="json", + return [types.DataContent( + type="data", data=weather_data - # schema field is optional - if omitted, outputSchema is used + # schema field is optional - if omitted, the tool's outputSchema is implied )] raise ValueError(f"Tool not found: {name}") ``` @@ -399,11 +399,11 @@ When a tool is called, it can return multiple content items of different types: } ``` -### JSON Content +### Data Content ```json { - "type": "json", + "type": "data", "data": { "temperature": 72, "conditions": "Partly cloudy" @@ -412,7 +412,7 @@ When a tool is called, it can return multiple content items of different types: } ``` -The JSON content type allows structured data to be returned from tools with several options: +The data content type allows structured data to be returned from tools with several options: - If `schema` is omitted, the tool's `outputSchema` is implied - If `schema` is a string, it is interpreted as a URI reference to a schema @@ -422,7 +422,7 @@ Example with an inline schema: ```json { - "type": "json", + "type": "data", "data": { "results": [ {"id": "product-1", "name": "Widget", "price": 9.99} @@ -590,7 +590,7 @@ For tools that return JSON content, error handling can include structured error return { content: [ { - type: "json", + type: "data", data: data } ] @@ -600,7 +600,7 @@ For tools that return JSON content, error handling can include structured error isError: true, content: [ { - type: "json", + type: "data", data: { errorCode: error.code || "UNKNOWN_ERROR", message: error.message, @@ -627,8 +627,8 @@ For tools that return JSON content, error handling can include structured error data = await fetch_data() return types.CallToolResult( content=[ - types.JsonContent( - type="json", + types.DataContent( + type="data", data=data ) ] @@ -637,8 +637,8 @@ For tools that return JSON content, error handling can include structured error return types.CallToolResult( isError=True, content=[ - types.JsonContent( - type="json", + types.DataContent( + type="data", data={ "errorCode": getattr(error, "code", "UNKNOWN_ERROR"), "message": str(error), diff --git a/docs/specification/2025-03-26/server/tools.mdx b/docs/specification/2025-03-26/server/tools.mdx index 5ede19844..bdb7e3d1b 100644 --- a/docs/specification/2025-03-26/server/tools.mdx +++ b/docs/specification/2025-03-26/server/tools.mdx @@ -237,7 +237,7 @@ Tool results can contain multiple content items of different types: ```json { - "type": "json", + "type": "data", "data": { "temperature": 72, "conditions": "Partly cloudy" diff --git a/schema/2025-03-26/schema.json b/schema/2025-03-26/schema.json index 100f95eaa..a20d9f5d6 100644 --- a/schema/2025-03-26/schema.json +++ b/schema/2025-03-26/schema.json @@ -124,7 +124,7 @@ "$ref": "#/definitions/EmbeddedResource" }, { - "$ref": "#/definitions/JsonContent" + "$ref": "#/definitions/DataContent" } ] }, @@ -443,7 +443,7 @@ "$ref": "#/definitions/AudioContent" }, { - "$ref": "#/definitions/JsonContent" + "$ref": "#/definitions/DataContent" } ] }, @@ -470,6 +470,44 @@ "description": "An opaque token used to represent a cursor for pagination.", "type": "string" }, + "DataContent": { + "description": "Text provided to or from an LLM.", + "properties": { + "annotations": { + "$ref": "#/definitions/Annotations", + "description": "Optional annotations for the client." + }, + "data": { + "additionalProperties": true, + "description": "The text content of the message.", + "properties": {}, + "type": "object" + }, + "schema": { + "anyOf": [ + { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + { + "type": "string" + } + ], + "description": "The schema reference or definition of the JSON content." + }, + "type": { + "const": "json", + "type": "string" + } + }, + "required": [ + "data", + "schema", + "type" + ], + "type": "object" + }, "EmbeddedResource": { "description": "The contents of a resource, embedded into a prompt or tool call result.\n\nIt is up to the client how best to render embedded resources for the benefit\nof the LLM and/or the user.", "properties": { @@ -886,44 +924,6 @@ ], "type": "object" }, - "JsonContent": { - "description": "Text provided to or from an LLM.", - "properties": { - "annotations": { - "$ref": "#/definitions/Annotations", - "description": "Optional annotations for the client." - }, - "data": { - "additionalProperties": true, - "description": "The text content of the message.", - "properties": {}, - "type": "object" - }, - "schema": { - "anyOf": [ - { - "additionalProperties": true, - "properties": {}, - "type": "object" - }, - { - "type": "string" - } - ], - "description": "The schema reference or definition of the JSON content." - }, - "type": { - "const": "json", - "type": "string" - } - }, - "required": [ - "data", - "schema", - "type" - ], - "type": "object" - }, "ListPromptsRequest": { "description": "Sent from the client to request a list of prompts and prompt templates the server has.", "properties": { @@ -1462,7 +1462,7 @@ "$ref": "#/definitions/EmbeddedResource" }, { - "$ref": "#/definitions/JsonContent" + "$ref": "#/definitions/DataContent" } ] }, @@ -1811,7 +1811,7 @@ "$ref": "#/definitions/AudioContent" }, { - "$ref": "#/definitions/JsonContent" + "$ref": "#/definitions/DataContent" } ] }, diff --git a/schema/2025-03-26/schema.ts b/schema/2025-03-26/schema.ts index 5c971bd2a..afca6648c 100644 --- a/schema/2025-03-26/schema.ts +++ b/schema/2025-03-26/schema.ts @@ -642,7 +642,7 @@ export type Role = "user" | "assistant"; */ export interface PromptMessage { role: Role; - content: TextContent | ImageContent | AudioContent | EmbeddedResource | JsonContent; + content: TextContent | ImageContent | AudioContent | EmbeddedResource | DataContent; } /** @@ -696,7 +696,7 @@ export interface ListToolsResult extends PaginatedResult { * should be reported as an MCP error response. */ export interface CallToolResult extends Result { - content: (TextContent | ImageContent | AudioContent | EmbeddedResource | JsonContent)[]; + content: (TextContent | ImageContent | AudioContent | EmbeddedResource | DataContent)[]; /** * Whether the tool call ended in an error. @@ -924,7 +924,7 @@ export interface CreateMessageResult extends Result, SamplingMessage { */ export interface SamplingMessage { role: Role; - content: TextContent | ImageContent | AudioContent | JsonContent; + content: TextContent | ImageContent | AudioContent | DataContent; } /** @@ -1020,8 +1020,8 @@ export interface AudioContent { /** * Text provided to or from an LLM. */ -export interface JsonContent { - type: "json"; +export interface DataContent { + type: "data"; /** * The text content of the message. From 1b9eda1b6c2a493aa8744e9b947e45e467771694 Mon Sep 17 00:00:00 2001 From: lukaswelinder Date: Thu, 24 Apr 2025 13:03:45 -0600 Subject: [PATCH 4/8] Change approach to defining tool output/schema --- schema/2025-03-26/schema.json | 151 +++++++++++++++++++++++++++++----- schema/2025-03-26/schema.ts | 97 ++++++++++++++++++++-- 2 files changed, 219 insertions(+), 29 deletions(-) diff --git a/schema/2025-03-26/schema.json b/schema/2025-03-26/schema.json index a20d9f5d6..ae8ada2bd 100644 --- a/schema/2025-03-26/schema.json +++ b/schema/2025-03-26/schema.json @@ -497,13 +497,12 @@ "description": "The schema reference or definition of the JSON content." }, "type": { - "const": "json", + "const": "data", "type": "string" } }, "required": [ "data", - "schema", "type" ], "type": "object" @@ -2094,31 +2093,141 @@ "description": "The name of the tool.", "type": "string" }, - "outputSchema": { - "description": "A JSON Schema object defining the expected output for the tool's JSON content response.", + "output": { "properties": { - "properties": { - "additionalProperties": { - "additionalProperties": true, - "properties": {}, - "type": "object" + "content": { + "properties": { + "audio": { + "properties": { + "count": { + "description": "The number of items the tool will return, if left empty, one or more is assumed.", + "enum": [ + "multiple", + "single" + ], + "type": "string" + }, + "description": { + "description": "A description of the data the tool will return.", + "type": "string" + }, + "mimeTypes": { + "description": "The MIME types of the audio.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "data": { + "properties": { + "count": { + "description": "The number of items the tool will return, if left empty, one or more is assumed.", + "enum": [ + "multiple", + "single" + ], + "type": "string" + }, + "description": { + "description": "A description of the data the tool will return.", + "type": "string" + }, + "schema": { + "anyOf": [ + { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + { + "type": "string" + } + ], + "description": "A JSON Schema object defining the expected output for the tool's JSON content response." + }, + "strict": { + "description": "If true, `DataContent.data` must always be valid against the whole schema.\nOtherwise `DataContent.schema` may reference `$defs` in the root schema or provide its own schema.\n\nDefault: false", + "type": "boolean" + } + }, + "type": "object" + }, + "image": { + "properties": { + "count": { + "description": "The number of items the tool will return, if left empty, one or more is assumed.", + "enum": [ + "multiple", + "single" + ], + "type": "string" + }, + "description": { + "description": "A description of the data the tool will return.", + "type": "string" + }, + "mimeTypes": { + "description": "The MIME types of the image.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "resource": { + "properties": { + "count": { + "description": "The number of items the tool will return, if left empty, one or more is assumed.", + "enum": [ + "multiple", + "single" + ], + "type": "string" + }, + "description": { + "description": "A description of the data the tool will return.", + "type": "string" + }, + "mimeTypes": { + "description": "The MIME types of the resource.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "text": { + "properties": { + "count": { + "description": "If true, the tool will return a single item.\n\nDefault: false", + "enum": [ + "multiple", + "single" + ], + "type": "string" + }, + "description": { + "description": "A description of the data the tool will return.", + "type": "string" + } + }, + "type": "object" + } }, "type": "object" }, - "required": { - "items": { - "type": "string" - }, - "type": "array" - }, - "type": { - "const": "object", - "type": "string" + "strict": { + "description": "If true, omitted content types in `Tool.output.content` will not appear in the response.\n\nDefault: false", + "type": "boolean" } }, - "required": [ - "type" - ], "type": "object" } }, diff --git a/schema/2025-03-26/schema.ts b/schema/2025-03-26/schema.ts index afca6648c..9038c1b12 100644 --- a/schema/2025-03-26/schema.ts +++ b/schema/2025-03-26/schema.ts @@ -803,13 +803,94 @@ export interface Tool { required?: string[]; }; - /** - * A JSON Schema object defining the expected output for the tool's JSON content response. - */ - outputSchema?: { - type: "object"; - properties?: { [key: string]: object }; - required?: string[]; + output?: { + /** + * If true, omitted content types in `Tool.output.content` will not appear in the response. + * + * Default: false + */ + strict?: boolean; + content?: { + text?: { + /** + * If true, the tool will return a single item. + * + * Default: false + */ + count?: 'single' | 'multiple'; + /** + * A description of the data the tool will return. + */ + description?: string; + }; + + image?: { + /** + * The number of items the tool will return, if left empty, one or more is assumed. + */ + count?: 'single' | 'multiple'; + /** + * A description of the data the tool will return. + */ + description?: string; + /** + * The MIME types of the image. + */ + mimeTypes?: string[]; + }; + + audio?: { + /** + * The number of items the tool will return, if left empty, one or more is assumed. + */ + count?: 'single' | 'multiple'; + /** + * A description of the data the tool will return. + */ + description?: string; + /** + * The MIME types of the audio. + */ + mimeTypes?: string[]; + }; + + resource?: { + /** + * The number of items the tool will return, if left empty, one or more is assumed. + */ + count?: 'single' | 'multiple'; + /** + * A description of the data the tool will return. + */ + description?: string; + /** + * The MIME types of the resource. + */ + mimeTypes?: string[]; + }; + + data?: { + /** + * The number of items the tool will return, if left empty, one or more is assumed. + */ + count?: 'single' | 'multiple'; + /** + * A description of the data the tool will return. + */ + description?: string; + /** + * A JSON Schema object defining the expected output for the tool's JSON content response. + */ + schema?: string | object; + /** + * If true, `DataContent.data` must always be valid against the whole schema. + * Otherwise `DataContent.schema` may reference `$defs` in the root schema or provide its own schema. + * + * Default: false + */ + strict?: boolean; + }; + }; }; /** @@ -1031,7 +1112,7 @@ export interface DataContent { /** * The schema reference or definition of the JSON content. */ - schema: string | object; + schema?: string | object; /** * Optional annotations for the client. From 2c0da9d56ded6e500f6493ce88ce1434910e1f20 Mon Sep 17 00:00:00 2001 From: lukaswelinder Date: Thu, 24 Apr 2025 13:05:32 -0600 Subject: [PATCH 5/8] Update docs to reflect tool output/schema changes --- .../2025-03-26/client/sampling.mdx | 36 ++++ .../2025-03-26/server/prompts.mdx | 47 ++++++ .../specification/2025-03-26/server/tools.mdx | 154 +++++++++++++++++- 3 files changed, 229 insertions(+), 8 deletions(-) diff --git a/docs/specification/2025-03-26/client/sampling.mdx b/docs/specification/2025-03-26/client/sampling.mdx index 4d246e193..72dd3cd3b 100644 --- a/docs/specification/2025-03-26/client/sampling.mdx +++ b/docs/specification/2025-03-26/client/sampling.mdx @@ -163,6 +163,42 @@ Sampling messages can contain: } ``` +#### JSON Content + +```json +{ + "type": "data", + "data": { + "name": "Weather Report", + "details": { + "temperature": 72, + "conditions": "Partly cloudy" + } + }, + "schema": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "details": { + "type": "object", + "properties": { + "temperature": { "type": "number" }, + "conditions": { "type": "string" } + } + } + } + } +} +``` + +The JSON content type (DataContent) allows structured data to be included in messages. This is especially useful when: + +- The server or client needs to exchange precisely structured information +- The information has a well-defined schema +- The data might be processed programmatically rather than just displayed + +The schema field is optional but recommended to help receivers understand and validate the structure. + ### Model Preferences Model selection in MCP requires careful abstraction since servers and clients may use diff --git a/docs/specification/2025-03-26/server/prompts.mdx b/docs/specification/2025-03-26/server/prompts.mdx index 4c32807fe..a9844bade 100644 --- a/docs/specification/2025-03-26/server/prompts.mdx +++ b/docs/specification/2025-03-26/server/prompts.mdx @@ -225,6 +225,53 @@ Audio content allows including audio information in messages: The audio data MUST be base64-encoded and include a valid MIME type. This enables multi-modal interactions where audio context is important. +#### JSON Content + +```json +{ + "type": "data", + "data": { + "query": { + "id": "12345", + "parameters": { + "limit": 10, + "orderBy": "relevance" + } + } + }, + "schema": { + "type": "object", + "properties": { + "query": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "parameters": { + "type": "object", + "properties": { + "limit": { "type": "number" }, + "orderBy": { "type": "string" } + } + } + } + } + } + } +} +``` + +The JSON content type (DataContent) allows structured data to be included in prompt messages. +This enables precise communication of complex information that would be unwieldy to represent +as plain text. Key benefits include: + +- Preserving exact data structures without formatting loss +- Enabling programmatic data processing by tools or models +- Maintaing type information for numeric, boolean, or structured values +- Supporting validation via schema definitions + +The schema field provides a JSON Schema definition to help the client understand +and potentially validate the structure before passing it to the LLM. + #### Embedded Resources Embedded resources allow referencing server-side resources directly in messages: diff --git a/docs/specification/2025-03-26/server/tools.mdx b/docs/specification/2025-03-26/server/tools.mdx index bdb7e3d1b..55bf37cf1 100644 --- a/docs/specification/2025-03-26/server/tools.mdx +++ b/docs/specification/2025-03-26/server/tools.mdx @@ -139,7 +139,18 @@ To invoke a tool, clients send a `tools/call` request: "content": [ { "type": "text", - "text": "Current weather in New York:\nTemperature: 72°F\nConditions: Partly cloudy" + "text": "Here's the current weather for New York:" + }, + { + "type": "data", + "data": { + "temperature": 72, + "conditions": "Partly cloudy", + "forecast": [ + {"day": "Monday", "high": 75, "low": 65}, + {"day": "Tuesday", "high": 80, "low": 68} + ] + } } ], "isError": false @@ -194,12 +205,81 @@ A tool definition includes: - `name`: Unique identifier for the tool - `description`: Human-readable description of functionality - `inputSchema`: JSON Schema defining expected parameters -- `outputSchema`: Optional JSON Schema defining the structure of JSON responses - `annotations`: optional properties describing tool behavior +- `output`: Optional configuration defining what content types the tool can return: + - `strict`: If true, only declared content types will appear in responses + - `content`: Configuration object for each supported content type: + - `text`: Text response configuration + - `image`: Image response configuration + - `audio`: Audio response configuration + - `resource`: Resource response configuration + - `data`: JSON data response configuration + +Each content type configuration can include: +- `count`: Whether the content type returns 'single' or 'multiple' items +- `description`: Human-readable description of the returned content +- For image/audio/resource: `mimeTypes`: Array of supported MIME types +- For data: `schema` and `strict` options for JSON schema validation For trust & safety and security, clients **MUST** consider tool annotations to be untrusted unless they come from trusted servers. +#### Example Tool Definition + +```json +{ + "name": "get_weather", + "description": "Get current weather information for a location", + "inputSchema": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "City name or zip code" + } + }, + "required": ["location"] + }, + "output": { + "strict": false, + "content": { + "text": { + "count": "single", + "description": "Human-readable weather description" + }, + "data": { + "count": "single", + "description": "Structured weather data", + "schema": { + "type": "object", + "properties": { + "temperature": { + "type": "number", + "description": "Temperature in degrees Fahrenheit" + }, + "conditions": { + "type": "string", + "description": "Weather conditions description" + }, + "forecast": { + "type": "array", + "items": { + "type": "object", + "properties": { + "day": {"type": "string"}, + "high": {"type": "number"}, + "low": {"type": "number"} + } + } + } + } + } + } + } + } +} +``` + ### Tool Result Tool results can contain multiple content items of different types: @@ -233,23 +313,81 @@ Tool results can contain multiple content items of different types: } ``` -#### JSON Content +#### JSON Content (DataContent) ```json { "type": "data", "data": { "temperature": 72, - "conditions": "Partly cloudy" + "conditions": "Partly cloudy", + "forecast": [ + {"day": "Monday", "high": 75, "low": 65}, + {"day": "Tuesday", "high": 80, "low": 68} + ] }, "schema": "#/components/schemas/WeatherResponse" } ``` -The JSON content type allows structured data to be returned from tools. The `schema` field can be: -- Omitted (in which case the tool's `outputSchema` is implied) -- A string (which is interpreted as a URI reference to a schema) -- An object (containing the full schema definition) +The JSON content type (DataContent) allows structured data to be returned from tools. This enables more precise communication of complex, structured information that can be programmatically processed by the client or presented to the LLM. + +The content includes: +- `type`: Must be "data" +- `data`: A JSON object containing the structured data +- `schema` (optional): Can be one of: + - Omitted (in which case the tool's `output.content.data.schema` is implied) + - A string URI reference to a schema + - An inline object containing the full schema definition + +Schema validation behavior: +- If `output.content.data.strict` is true, the data must validate against the entire schema +- Otherwise, partial schemas or schema fragments can be provided with the DataContent instance + +#### Sample Tool Call with Structured Data Response + +Request: +```json +{ + "jsonrpc": "2.0", + "id": 2, + "method": "tools/call", + "params": { + "name": "get_weather", + "arguments": { + "location": "New York" + } + } +} +``` + +Response with structured data: +```json +{ + "jsonrpc": "2.0", + "id": 2, + "result": { + "content": [ + { + "type": "text", + "text": "Here's the current weather for New York:" + }, + { + "type": "data", + "data": { + "temperature": 72, + "conditions": "Partly cloudy", + "forecast": [ + {"day": "Monday", "high": 75, "low": 65}, + {"day": "Tuesday", "high": 80, "low": 68} + ] + } + } + ], + "isError": false + } +} +``` #### Embedded Resources From 371cc70e86b81ea8ad1bc0f332e0a0de3f43741c Mon Sep 17 00:00:00 2001 From: lukaswelinder Date: Thu, 24 Apr 2025 13:21:09 -0600 Subject: [PATCH 6/8] Update property name for tool output --- schema/2025-03-26/schema.json | 57 ++++++++++++++++++++++++----------- schema/2025-03-26/schema.ts | 12 ++++---- 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/schema/2025-03-26/schema.json b/schema/2025-03-26/schema.json index ae8ada2bd..850046709 100644 --- a/schema/2025-03-26/schema.json +++ b/schema/2025-03-26/schema.json @@ -2111,12 +2111,19 @@ "description": "A description of the data the tool will return.", "type": "string" }, - "mimeTypes": { - "description": "The MIME types of the audio.", - "items": { - "type": "string" - }, - "type": "array" + "mimeType": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ], + "description": "The MIME type(s) of the audio." } }, "type": "object" @@ -2169,12 +2176,19 @@ "description": "A description of the data the tool will return.", "type": "string" }, - "mimeTypes": { - "description": "The MIME types of the image.", - "items": { - "type": "string" - }, - "type": "array" + "mimeType": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ], + "description": "The MIME type(s) of the image." } }, "type": "object" @@ -2193,12 +2207,19 @@ "description": "A description of the data the tool will return.", "type": "string" }, - "mimeTypes": { - "description": "The MIME types of the resource.", - "items": { - "type": "string" - }, - "type": "array" + "mimeType": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ], + "description": "The MIME type(s) of the resource." } }, "type": "object" diff --git a/schema/2025-03-26/schema.ts b/schema/2025-03-26/schema.ts index 9038c1b12..4ad7994c0 100644 --- a/schema/2025-03-26/schema.ts +++ b/schema/2025-03-26/schema.ts @@ -834,9 +834,9 @@ export interface Tool { */ description?: string; /** - * The MIME types of the image. + * The MIME type(s) of the image. */ - mimeTypes?: string[]; + mimeType?: string | string[]; }; audio?: { @@ -849,9 +849,9 @@ export interface Tool { */ description?: string; /** - * The MIME types of the audio. + * The MIME type(s) of the audio. */ - mimeTypes?: string[]; + mimeType?: string | string[]; }; resource?: { @@ -864,9 +864,9 @@ export interface Tool { */ description?: string; /** - * The MIME types of the resource. + * The MIME type(s) of the resource. */ - mimeTypes?: string[]; + mimeType?: string | string[]; }; data?: { From 41074f289d544887a7c2205171465747eabd3e96 Mon Sep 17 00:00:00 2001 From: lukaswelinder Date: Thu, 24 Apr 2025 13:24:52 -0600 Subject: [PATCH 7/8] Update docs to reflect tool output changes --- docs/specification/2025-03-26/server/tools.mdx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/specification/2025-03-26/server/tools.mdx b/docs/specification/2025-03-26/server/tools.mdx index 55bf37cf1..026e3ac4b 100644 --- a/docs/specification/2025-03-26/server/tools.mdx +++ b/docs/specification/2025-03-26/server/tools.mdx @@ -218,7 +218,7 @@ A tool definition includes: Each content type configuration can include: - `count`: Whether the content type returns 'single' or 'multiple' items - `description`: Human-readable description of the returned content -- For image/audio/resource: `mimeTypes`: Array of supported MIME types +- For image/audio/resource: `mimeType`: String or array of strings specifying supported MIME type(s) - For data: `schema` and `strict` options for JSON schema validation For trust & safety and security, clients **MUST** consider @@ -247,6 +247,21 @@ tool annotations to be untrusted unless they come from trusted servers. Date: Thu, 24 Apr 2025 15:40:49 -0600 Subject: [PATCH 8/8] Add escape hatch to `DataContent` --- schema/2025-03-26/schema.json | 6 +++++- schema/2025-03-26/schema.ts | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/schema/2025-03-26/schema.json b/schema/2025-03-26/schema.json index 850046709..5f688d98a 100644 --- a/schema/2025-03-26/schema.json +++ b/schema/2025-03-26/schema.json @@ -490,11 +490,15 @@ "properties": {}, "type": "object" }, + { + "const": false, + "type": "boolean" + }, { "type": "string" } ], - "description": "The schema reference or definition of the JSON content." + "description": "The schema reference or definition of the JSON content.\n- `string` is a reference path in the tool's `output.content.data.schema`\n- `object` is a JSON Schema object, helpful for dynamic schemas or usage in sampling/prompts\n- `false` is an escape hatch for tools with a data output schema" }, "type": { "const": "data", diff --git a/schema/2025-03-26/schema.ts b/schema/2025-03-26/schema.ts index 4ad7994c0..243d6f160 100644 --- a/schema/2025-03-26/schema.ts +++ b/schema/2025-03-26/schema.ts @@ -1111,8 +1111,11 @@ export interface DataContent { /** * The schema reference or definition of the JSON content. + * - `string` is a reference path in the tool's `output.content.data.schema` + * - `object` is a JSON Schema object, helpful for dynamic schemas or usage in sampling/prompts + * - `false` is an escape hatch for tools with a data output schema */ - schema?: string | object; + schema?: string | object | false; /** * Optional annotations for the client.