Skip to content

Python: Agent Framework Bug Report: MCP CallToolResult._meta Field Not Respected #2284

@bostdiek

Description

@bostdiek

Agent Framework Bug Report: MCP CallToolResult._meta Field Not Respected

Summary

The Agent Framework library violates the official Model Context Protocol (MCP) specification by completely dropping the _meta field from CallToolResult responses. This prevents applications from accessing critical metadata such as token usage, cost information, and performance metrics that MCP servers can provide.

Bug Details

Location: agent_framework/_mcp.py in function _mcp_call_tool_result_to_ai_contents()

Issue: The function only processes the content field of CallToolResult objects and completely ignores the _meta field, which is part of the official MCP specification.

Impact:

  • Loss of critical tool execution metadata (token usage, costs, performance metrics)
  • Protocol compliance violation
  • Prevents proper monitoring and cost tracking of MCP tool usage
  • Breaks integration with compliant MCP servers that return metadata

Evidence from Official MCP Specification

1. Official Type Definition

From the official MCP Python SDK repository in src/mcp/types.py:

class CallToolResult(Result):
    """The server's response to a tool call."""
    content: list[ContentBlock]
    structuredContent: dict[str, Any] | None = None
    isError: bool = False
    # _meta field is inherited from Result base class

class Result(BaseModel):
    """Base class for JSON-RPC results."""
    meta: dict[str, Any] | None = Field(alias="_meta", default=None)
    """
    See [MCP specification](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/47339c03c143bb4ec01a26e721a1b8fe66634ebe/docs/specification/draft/basic/index.mdx#general-fields)
    for notes on _meta usage.
    """
    model_config = ConfigDict(extra="allow")

2. Official Documentation

From the MCP Python SDK README.md (lines 387-417):

Advanced: Direct CallToolResult

For full control over tool responses including the _meta field (for passing data to client applications without exposing it to the model), you can return CallToolResult directly

3. Official Examples

From examples/snippets/servers/direct_call_tool_result.py:

@mcp.tool()
def advanced_tool() -> CallToolResult:
    """Return CallToolResult directly for full control including _meta field."""
    return CallToolResult(
        content=[TextContent(type="text", text="Response visible to the model")],
        _meta={"hidden": "data for client applications only"},
    )

@mcp.tool()
def validated_tool() -> Annotated[CallToolResult, ValidationModel]:
    """Return CallToolResult with structured output validation."""
    return CallToolResult(
        content=[TextContent(type="text", text="Validated response")],
        structuredContent={"status": "success", "data": {"result": 42}},
        _meta={"internal": "metadata"},
    )

4. Official Test Cases

From tests/server/test_lowlevel_output_validation.py:

async def call_tool_handler(name: str, arguments: dict[str, Any]) -> CallToolResult:
    if name == "get_info":
        return CallToolResult(
            content=[TextContent(type="text", text="Results calculated")],
            structuredContent={"status": "ok", "data": {"value": 42}},
            _meta={"some": "metadata"},
        )

# Test validates: assert result.meta == {"some": "metadata"}

The Bug in Agent Framework

Current implementation in agent_framework/_mcp.py:

def _mcp_call_tool_result_to_ai_contents(result: Any) -> list[types.Content]:
    """Convert CallToolResult to AI content."""
    if not hasattr(result, "content"):
        raise ValueError("Result must have content field")
    
    contents = []
    for item in result.content:
        # ... processes only content field
        contents.append(converted_content)
    
    return contents
    # BUG: _meta field is completely dropped and never processed!

Problem: The function:

  1. Only processes result.content
  2. Completely ignores result._meta
  3. Returns only converted content without metadata
  4. Violates the MCP specification

Expected Behavior

The Agent Framework should:

  1. Preserve the _meta field from CallToolResult responses
  2. Pass metadata through to the application layer
  3. Respect the MCP specification for protocol compliance
  4. Enable applications to access tool usage metrics, costs, and performance data

Proposed Solution

The _mcp_call_tool_result_to_ai_contents() function should be updated to:

  1. Extract and preserve the _meta field from CallToolResult
  2. Return both content and metadata to the calling application
  3. Maintain protocol compliance with the official MCP specification

Possible approaches:

  • Modify the return type to include metadata
  • Add metadata to the agent response structure
  • Provide a separate accessor for tool result metadata
  • Follow the same pattern used by the official MCP Python SDK

Impact Assessment

Critical: This bug affects:

  • Cost tracking: Token usage and API costs are lost
  • Performance monitoring: Tool execution metrics are unavailable
  • Protocol compliance: Violates official MCP specification
  • Integration: Breaks compatibility with compliant MCP servers
  • Debugging: Missing metadata prevents proper troubleshooting

Reproduction Steps

  1. Create an MCP server that returns CallToolResult with _meta field
  2. Use Agent Framework to call the tool
  3. Observe that metadata is completely dropped from the response
  4. Compare with direct MCP client usage (metadata is preserved)

Environment

  • Agent Framework Version: [Current installed version]
  • MCP Python SDK Version: v1.21.2 (latest)
  • Python Version: 3.12
  • Platform: macOS

Additional Evidence

The MCP specification is widely implemented across multiple languages and frameworks:

  • Official Go SDK includes _meta field support
  • TypeScript implementations respect metadata
  • Multiple third-party MCP implementations include metadata

References

  1. Official MCP Python SDK Repository
  2. MCP Specification Documentation
  3. MCP Protocol Introduction
  4. Official MCP Examples with _meta

Request: Please update Agent Framework to properly handle the _meta field in CallToolResult responses to ensure compliance with the official MCP specification and enable proper tool metadata access for applications.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions