- Update McpServer to support registering tools with outputSchema - Add automatic content generation from structuredContent for backward compatibility - Add validation to ensure proper usage of structuredContent vs content - Add comprehensive tests for outputSchema functionality - Add example servers demonstrating structured output usage - Update existing test to match new backward compatibility behavior 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
6.3 KiB
6.3 KiB
OutputSchema Support Implementation
This document summarizes the changes made to support tools with outputSchema in the MCP TypeScript SDK.
Changes Made
Server-Side Changes
1. Tool Registration (mcp.ts)
- Added support for parsing and storing
outputSchemawhen registering tools - Updated the
tool()method to handle outputSchema parameter in various overload combinations - Added new overloads to support tools with outputSchema:
tool<Args extends ZodRawShape>( name: string, paramsSchema: Args, outputSchema: Tool["outputSchema"], cb: ToolCallback<Args>, ): RegisteredTool;
2. Tool Listing
- Modified
ListToolsResulthandler to include outputSchema in tool definitions - Only includes outputSchema in the response if it's defined for the tool
3. Tool Execution
- Updated
CallToolRequesthandler to validate structured content based on outputSchema - Added automatic backward compatibility:
- If a tool has outputSchema and returns
structuredContentbut nocontent, the server automatically generates a text representation - This ensures compatibility with clients that don't support structured content
- If a tool has outputSchema and returns
- Added validation to ensure:
- Tools with outputSchema must return structuredContent (unless error)
- Tools without outputSchema must not return structuredContent
- Tools without outputSchema must return content
4. Backward Compatibility
The implementation maintains full backward compatibility:
- Tools without outputSchema continue to work as before
- Tools with outputSchema can optionally provide both
structuredContentandcontent - If only
structuredContentis provided,contentis auto-generated as JSON
Client-Side Changes
1. Schema Caching and Validation (index.ts)
- Added
_cachedToolsand_cachedToolOutputSchemasmaps to cache tool definitions and their parsed Zod schemas - The client converts JSON Schema to Zod schema using the
json-schema-to-zodlibrary for runtime validation - Added dependency:
json-schema-to-zodfor converting JSON schemas to Zod schemas
2. Tool Listing
- Modified
listToolsto parse and cache output schemas:- When a tool has an outputSchema, the client converts it to a Zod schema
- Schemas are cached for validation during tool calls
- Handles errors gracefully with warning logs if schema parsing fails
3. Tool Execution
- Enhanced
callToolmethod with comprehensive validation:- Tools with outputSchema must return
structuredContent(validates this requirement) - Tools without outputSchema must not return
structuredContent - Validates structured content against the cached Zod schema
- Provides detailed error messages when validation fails
- Tools with outputSchema must return
4. Error Handling
The client throws McpError with appropriate error codes:
ErrorCode.InvalidRequestwhen required structured content is missing or unexpectedErrorCode.InvalidParamswhen structured content doesn't match the schema
Testing
Server Tests
Added comprehensive test suite (mcp-outputschema.test.ts) covering:
- Tool registration with outputSchema
- ListToolsResult including outputSchema
- Tool execution with structured content
- Automatic backward compatibility behavior
- Error cases and validation
Client Tests
Added tests in index.test.ts covering:
- Validation of structured content against output schemas
- Error handling when structured content doesn't match schema
- Error handling when tools with outputSchema don't return structured content
- Error handling when tools without outputSchema return structured content
- Complex JSON schema validation including nested objects, arrays, and strict mode
- Validation of additional properties when
additionalProperties: false
Examples
Created two example servers:
outputSchema.ts- Using the low-level Server APImcpServerOutputSchema.ts- Using the high-level McpServer API
These examples demonstrate:
- Tools with structured output (weather data, CSV processing, BMI calculation)
- Tools that return both structured and readable content
- Traditional tools without outputSchema for comparison
API Usage
Registering a tool with outputSchema:
server.tool(
"calculate_bmi",
"Calculate BMI given height and weight",
{
height_cm: z.number(),
weight_kg: z.number()
},
{
type: "object",
properties: {
bmi: { type: "number" },
category: { type: "string" }
},
required: ["bmi", "category"]
},
async ({ height_cm, weight_kg }) => {
// Calculate BMI...
return {
structuredContent: {
bmi: calculatedBmi,
category: bmiCategory
}
};
}
);
Tool callback return values:
- For tools with outputSchema: Return
{ structuredContent: {...} } - For backward compatibility: Optionally include
{ structuredContent: {...}, content: [...] } - For tools without outputSchema: Return
{ content: [...] }as before
Implementation Summary
Key Design Decisions
- Backward Compatibility: The server automatically generates
contentfromstructuredContentfor clients that don't support structured output - Schema Validation: The client validates all structured content against the tool's output schema using Zod
- Caching: The client caches parsed schemas to avoid re-parsing on every tool call
- Error Handling: Both client and server validate the correct usage of
structuredContentvscontentbased on whether a tool has an outputSchema
Implementation Notes
-
Server Side:
- Automatically handles backward compatibility by serializing structuredContent to JSON
- Validates that tools properly use structuredContent vs content based on their outputSchema
- All existing tools continue to work without changes
-
Client Side:
- Converts JSON Schema to Zod schemas for runtime validation
- Caches schemas for performance
- Provides detailed validation errors when structured content doesn't match schemas
- Enforces proper usage of structuredContent based on outputSchema presence
-
Compatibility:
- The implementation follows the spec requirements
- Maintains full backward compatibility
- Provides a good developer experience with clear error messages
- Ensures both old and new clients can work with servers that support outputSchema