Skip to content

feat: Add structured output support for tool functions #993

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 7 commits into
base: main
Choose a base branch
from

Conversation

bhosmer-ant
Copy link
Contributor

@bhosmer-ant bhosmer-ant commented Jun 20, 2025

Adds support for structured output in FastMCP tools, allowing tool functions to return well-typed, validated data that clients can easily process.

Key Changes

  • FastMCP server: adds structured_output parameter to @mcp.tool decorator. structured_output=True triggers structured output support:
    • function return type annotation is converted into Pydantic model (see "Supported return types" below)
    • tool's outputSchema is generated from model
    • structuredContent results are validated on the server before sending
  • lowlevel server: adds simple (nonvalidating) structured output support to the @server.call_tool() decorator:
    • tool function results of type dict[str, ...] are used as structuredContent and automatically replicated in content block for BC (note: FastMCP delegates to lowlevel server, so includes this support)
  • Client: adds validation of structuredContent results against tool outputSchema
  • Tests: lots
  • Docs: added to README.md
  • Examples: added examples/fastmcp/weather_structured.py showing various return type options

Supported return types

@mcp.tool(structured_output=True) supports the following function return types:

  • Pydantic models: Used directly to validate function results and generate outputSchema
  • dict[str, *], TypedDict, NamedTuple, classes with typed fields: Converted to Pydantic models
  • Primitives, lists, generics: Wrapped in {\"result\": value}

Motivation and Context

Support structured output as defined in spec rev 2025-06-18

How Has This Been Tested?

New tests added

Breaking Changes

  • Protocol defines structured output in a backwards-compatible way
  • SDK API changes should be backwards compatible

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

Many thanks to @davemssavage, who prototyped an initial version of this functionality.

- Add support for tool functions to return structured data with validation
- Functions can now use structured_output=True to enable output validation
- Add outputSchema field to Tool type in MCP protocol
- Implement client-side validation of structured content
- Add comprehensive tests for all supported types
- Add documentation and examples
@bhosmer-ant bhosmer-ant requested review from ihrpr and dsp-ant June 20, 2025 15:25
- Improve readability in func_metadata.py by using helper functions and clear if-statements
- Restore complex_inputs.py example to original state from main branch
- Fix test_88_random_error.py by adding list_tools handler
- Refactor test_lowlevel_tool_output.py to test server behavior directly without clients
- Fix README formatting for structured output examples
- Add type assertions to fix pyright errors in tests

This completes the code improvements requested in the PR review.
Required for client-side validation of structured tool output.
- Add jsonschema==4.20.0 and its transitive dependencies
- Includes jsonschema-specifications, referencing, and rpds-py
- Fixes pre-commit import resolution errors
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.

1 participant