Skip to content

feat: forward MCP _meta field through ToolResultBlock#1130

Open
sridhar-3009 wants to merge 1 commit into
anthropics:mainfrom
sridhar-3009:feat/tool-result-meta-407
Open

feat: forward MCP _meta field through ToolResultBlock#1130
sridhar-3009 wants to merge 1 commit into
anthropics:mainfrom
sridhar-3009:feat/tool-result-meta-407

Conversation

@sridhar-3009

Copy link
Copy Markdown

Summary

Closes #407. MCP's _meta field is designed for handler-only data that should not enter model context (record IDs, pagination cursors, etc.), but it was being silently dropped on the tool-result path:

  • create_sdk_mcp_server's call_tool() only read content and is_error from a tool handler's return dict, discarding any _meta key.
  • The Query JSON-RPC bridge (_handle_sdk_mcp_request) built the tools/call response without forwarding CallToolResult.meta back to the CLI — even though the sibling tools/list path already forwards tool.meta the same way (see the existing _meta handling a few lines up in the same method).
  • message_parser.py's two ToolResultBlock construction sites parsed content and is_error off transcript tool_result blocks but ignored _meta.

This change:

  1. Adds meta: dict[str, Any] | None = None to ToolResultBlock (types.py).
  2. Forwards block.get("_meta") into both ToolResultBlock construction sites in message_parser.py.
  3. Forwards a handler's _meta return value into CallToolResult in create_sdk_mcp_server's call_tool().
  4. Forwards CallToolResult.meta into the tools/call JSON-RPC response in query.py, mirroring the existing tools/list pattern.

Test plan

  • Added test_parse_user_message_with_tool_result_meta / test_parse_user_message_with_tool_result_no_meta in tests/test_message_parser.py.
  • Added test_tool_result_meta_reaches_call_tool_result and test_tool_result_meta_flows_through_jsonrpc_bridge in tests/test_sdk_mcp_integration.py (the latter mirrors the existing test_max_result_size_chars_annotation_flows_to_cli bridge test, for the tools/call path instead of tools/list).
  • pytest (1237 passed, 5 pre-existing skips, no new failures)
  • mypy src/ (strict mode, clean)
  • ruff check / ruff format --check (clean)

🤖 Generated with Claude Code

SDK-defined MCP tools can already receive _meta in tools/list responses
(for maxResultSizeChars annotations), but tools/call results silently
dropped it: create_sdk_mcp_server's call_tool() only read content and
is_error from a handler's return dict, and the Query JSON-RPC bridge
never forwarded CallToolResult.meta back to the CLI. On the parsing
side, message_parser.py's ToolResultBlock construction discarded any
_meta key present on tool_result blocks in the transcript.

This wires _meta end-to-end so handlers can return data meant for
event handlers/UI without it entering model context, per the MCP
spec's intent for _meta.

Fixes anthropics#407
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.

Feature Request: Expose MCP _meta field in ToolResultBlock for handler-only data

1 participant