Skip to content

Prototype support for outputSchema/structuredContent #454

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

bhosmer-ant
Copy link
Contributor

@bhosmer-ant bhosmer-ant commented May 6, 2025

Prototype support for schema validation additions proposed in modelcontextprotocol/modelcontextprotocol#371

Motivation and Context

How Has This Been Tested?

Breaking Changes

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

bhosmer-ant and others added 2 commits May 5, 2025 16:17
- Add outputSchema field to Tool type and RegisteredTool interface
- Make content field optional in CallToolResult
- Update ListToolsRequestSchema handler to include outputSchema in tool list responses
- Add support for structuredContent in tool results
- Update examples to handle optional content field
- Add tests for new outputSchema and structuredContent functionality
- Update ToolCallback documentation to clarify when to use structuredContent vs content

This change enables tools to define structured output schemas and return
structured JSON content, providing better type safety and validation for
tool outputs.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Cache tool output schemas when listing tools
- Validate structuredContent against outputSchema during callTool
- Enforce that tools with outputSchema must return structuredContent
- Add json-schema-to-zod dependency for schema conversion
- Add comprehensive tests for validation scenarios

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…tured tool output

- Add outputSchema support to Tool interface with proper documentation
- Split CallToolResult into structured and unstructured variants
- Change structuredContent from string to object type
- Add validation that tools without outputSchema cannot return structuredContent
- Add validation that tools with outputSchema must return structuredContent
- Update client to validate structured content as object (no JSON parsing)
- Update tests to use object format for structuredContent
- Add tests for new validation constraints
- Update LATEST_PROTOCOL_VERSION to DRAFT-2025-v2

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@bhosmer-ant bhosmer-ant force-pushed the basil/output_schema branch from ae82638 to 2ab965e Compare May 8, 2025 03:03
…patibility

- 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>
@bhosmer-ant bhosmer-ant force-pushed the basil/output_schema branch from 2ab965e to 3a83e40 Compare May 8, 2025 03:11
@bhosmer-ant bhosmer-ant marked this pull request as ready for review May 8, 2025 03:13
Copy link
Contributor

@ihrpr ihrpr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some concerns around protocol version bump and questions

@@ -39,7 +39,7 @@ describe("OAuth Authorization", () => {
const [url, options] = calls[0];
expect(url.toString()).toBe("https://auth.example.com/.well-known/oauth-authorization-server");
expect(options.headers).toEqual({
"MCP-Protocol-Version": "2025-03-26"
"MCP-Protocol-Version": "DRAFT-2025-v2"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is an official version that SDK support, I think it's better to keep it as is until:

  • draft is release
  • SDK implements most of the features in the new spec

@@ -0,0 +1,171 @@
# OutputSchema Support Implementation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this file? Should this be just release notes and updated README?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yesss

{ method: "tools/list", params },
ListToolsResultSchema,
options,
);

// Cache the tools and their output schemas for future validation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit worried about this part related to caching tools

there are some efforts to refresh tool list on client like this one. Which will work fine as listTools is used there

I think my question here is, do we need to have cached output types - how expensive it is to convert it on the fly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think _cachedTools is not used, right?

Copy link
Contributor Author

@bhosmer-ant bhosmer-ant May 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[edited] the problem is that the client isn't actually storing tool definitions anywhere - so unless we grab and stash on an organic listTools call, we'd need to do one prior to the tool call itself (with no filter, and maybe multiple pages of results).

So yeah, this would be the first real connective state between tool definitions and tool calls in the client, I think. (And thus the first state that could go out of sync.)

But I'm not sure it's different in kind from, say, calling a tool based on a stale param schema... though ofc in that case the error would be on the server rather than the client.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants