Skip to content

refactor: make tool registration object-based#2415

Open
mplemay wants to merge 3 commits intomodelcontextprotocol:mainfrom
mplemay:manager-consistency
Open

refactor: make tool registration object-based#2415
mplemay wants to merge 3 commits intomodelcontextprotocol:mainfrom
mplemay:manager-consistency

Conversation

@mplemay
Copy link
Copy Markdown

@mplemay mplemay commented Apr 9, 2026

Summary

Refactor tool registration to be object-first, matching resource registration, and fix structured-output inference for list[Any] so mixed media tool results continue to serialize correctly.

Motivation and Context

This makes MCPServer.add_tool() consistent with add_resource() and ToolManager.add_tool(). It also prevents list[Any] return annotations from advertising structured output when they can include Image / Audio helpers that only serialize correctly through the unstructured conversion path.

How Has This Been Tested?

  • UV_CACHE_DIR=/tmp/uv-cache uv run --frozen pytest tests/server/mcpserver/tools/test_base.py tests/server/mcpserver/test_tool_manager.py tests/server/mcpserver/test_server.py
  • UV_CACHE_DIR=/tmp/uv-cache uv run --frozen pytest tests/server/mcpserver/test_func_metadata.py tests/server/mcpserver/test_server.py -q
  • UV_CACHE_DIR=/tmp/uv-cache uv run --frozen ruff check src/mcp/server/mcpserver/tools/base.py src/mcp/server/mcpserver/tools/tool_manager.py src/mcp/server/mcpserver/server.py src/mcp/server/mcpserver/utilities/func_metadata.py tests/server/mcpserver/test_tool_manager.py tests/server/mcpserver/test_server.py tests/server/mcpserver/test_func_metadata.py
  • UV_CACHE_DIR=/tmp/uv-cache uv run --frozen pyright src/mcp/server/mcpserver/tools/base.py src/mcp/server/mcpserver/tools/tool_manager.py src/mcp/server/mcpserver/server.py src/mcp/server/mcpserver/utilities/func_metadata.py tests/server/mcpserver/test_tool_manager.py tests/server/mcpserver/test_server.py tests/server/mcpserver/test_func_metadata.py

Breaking Changes

Yes. MCPServer.add_tool() and ToolManager.add_tool() now expect prebuilt Tool instances instead of callables. Callers should use Tool.from_function(...) or @mcp.tool().

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

Tool registration now follows the same object-first pattern as resources. The list[Any] guard keeps mixed-content tool results unstructured so Image and Audio helpers stay on the legacy content conversion path and CI no longer fails on JSON serialization.

BREAKING CHANGE: MCPServer.add_tool() and ToolManager.add_tool() now require prebuilt Tool objects. Use Tool.from_function() or the @mcp.tool() decorator to construct tools before registration.
@mplemay mplemay changed the title refactor!: make tool registration object-based refactor: make tool registration object-based Apr 9, 2026
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