Summary
The Agent Framework's MCP tool result parser (_parse_contents_from_mcp_tool_result) only processes the content field from CallToolResult objects, completely ignoring the structured_content field. This causes MCP servers that return JSON data via structured_content (like the Power BI MCP server) to appear as if they returned None.
Related Issue
This is related to but distinct from #2284 which addressed the _meta field. The structured_content field is a separate part of the MCP specification that remains unhandled.
Bug Details
Location: agent_framework/_mcp.py in function _parse_contents_from_mcp_tool_result()
Issue: The function only iterates over mcp_type.content and ignores mcp_type.structured_content:
def _parse_contents_from_mcp_tool_result(mcp_type: mcp_types.CallToolResult) -> list[types.Contents]:
"""Parse the contents from an MCP CallToolResult."""
contents: list[types.Contents] = []
for item in mcp_type.content: # <-- Only processes content field!
contents = _parse_content_from_mcp(item)
if contents:
all_contents.extend(contents)
return all_contents
# BUG: structured_content is completely ignored!
Impact:
- MCP servers returning data via
structured_content appear to return empty/None results
- Power BI MCP server integration fails silently
- Any MCP server using
structured_content for JSON responses won't work properly
Evidence from Official MCP Specification
From the official MCP Python SDK in src/mcp/types.py:
class ToolResultContent(MCPModel):
"""Content representing the result of a tool execution."""
type: Literal["tool_result"] = "tool_result"
tool_use_id: str
content: list[ContentBlock] = []
structured_content: dict[str, Any] | None = None # <-- This field is ignored!
The structured_content field is specifically designed for returning structured JSON data from tool calls, as documented in the MCP specification.
Reproduction Steps
- Connect to an MCP server that returns
structured_content (e.g., Power BI MCP at https://api.fabric.microsoft.com/v1/mcp/powerbi)
- Call a tool that returns JSON data via
structured_content
- Observe that the tool result is empty/None
Example with Power BI MCP:
from agent_framework import ChatAgent, MCPStreamableHTTPTool
from agent_framework.azure import AzureOpenAIResponsesClient
# Create MCP tool for Power BI
powerbi_tool = MCPStreamableHTTPTool(
name="powerbi",
url="https://api.fabric.microsoft.com/v1/mcp/powerbi",
# parse_tool_results=True # default
)
agent = ChatAgent(
chat_client=AzureOpenAIResponsesClient(...),
tools=[powerbi_tool],
)
# When calling GetSemanticModelSchema or ExecuteQuery:
# The MCP server returns:
# CallToolResult(content=[], structured_content={'Tables': [...], ...}, isError=False)
#
# But MAF only sees content=[] and returns None to the agent!
Debug output showing the issue:
DEBUG:agent_framework:Function powerbi-mcp_GetSemanticModelSchema succeeded.
DEBUG:agent_framework:Function result: None # <-- Should contain schema data!
# The actual MCP response was:
meta=None content=[] structured_content={'Tables': [...]} isError=False
Current Workaround
Setting parse_tool_results=False on MCPStreamableHTTPTool bypasses the parser and returns the raw CallToolResult, which includes structured_content:
powerbi_tool = MCPStreamableHTTPTool(
name="powerbi",
url="https://api.fabric.microsoft.com/v1/mcp/powerbi",
parse_tool_results=False, # Workaround - returns raw CallToolResult
)
However, this is not ideal as it changes the return type and requires the LLM to parse the raw result.
Expected Behavior
The _parse_contents_from_mcp_tool_result() function should:
- Check for
structured_content in addition to content
- Convert
structured_content to an appropriate content type (e.g., TextContent with JSON string, or a new structured content type)
- Preserve the structured data so the LLM can access it
Proposed Solution
Update _parse_contents_from_mcp_tool_result() to handle structured_content:
def _parse_contents_from_mcp_tool_result(mcp_type: mcp_types.CallToolResult) -> list[types.Contents]:
"""Parse the contents from an MCP CallToolResult."""
contents: list[types.Contents] = []
# Process content field (existing logic)
for item in mcp_type.content:
parsed = _parse_content_from_mcp(item)
if parsed:
contents.extend(parsed)
# NEW: Process structured_content field
if mcp_type.structured_content:
import json
structured_text = json.dumps(mcp_type.structured_content, indent=2)
contents.append(types.TextContent(text=structured_text))
return contents
Environment
- Agent Framework Version: 1.0.0b260116
- MCP Python SDK Version: Latest
- Python Version: 3.12/3.13
- Platform: Windows 11
Affected MCP Servers
- Power BI MCP (
https://api.fabric.microsoft.com/v1/mcp/powerbi) - Returns query results and schemas via structured_content
- Any MCP server that uses
structured_content for JSON responses
Summary
The Agent Framework's MCP tool result parser (
_parse_contents_from_mcp_tool_result) only processes thecontentfield fromCallToolResultobjects, completely ignoring thestructured_contentfield. This causes MCP servers that return JSON data viastructured_content(like the Power BI MCP server) to appear as if they returnedNone.Related Issue
This is related to but distinct from #2284 which addressed the
_metafield. Thestructured_contentfield is a separate part of the MCP specification that remains unhandled.Bug Details
Location:
agent_framework/_mcp.pyin function_parse_contents_from_mcp_tool_result()Issue: The function only iterates over
mcp_type.contentand ignoresmcp_type.structured_content:Impact:
structured_contentappear to return empty/None resultsstructured_contentfor JSON responses won't work properlyEvidence from Official MCP Specification
From the official MCP Python SDK in
src/mcp/types.py:The
structured_contentfield is specifically designed for returning structured JSON data from tool calls, as documented in the MCP specification.Reproduction Steps
structured_content(e.g., Power BI MCP athttps://api.fabric.microsoft.com/v1/mcp/powerbi)structured_contentExample with Power BI MCP:
Debug output showing the issue:
Current Workaround
Setting
parse_tool_results=FalseonMCPStreamableHTTPToolbypasses the parser and returns the rawCallToolResult, which includesstructured_content:However, this is not ideal as it changes the return type and requires the LLM to parse the raw result.
Expected Behavior
The
_parse_contents_from_mcp_tool_result()function should:structured_contentin addition tocontentstructured_contentto an appropriate content type (e.g.,TextContentwith JSON string, or a new structured content type)Proposed Solution
Update
_parse_contents_from_mcp_tool_result()to handlestructured_content:Environment
Affected MCP Servers
https://api.fabric.microsoft.com/v1/mcp/powerbi) - Returns query results and schemas viastructured_contentstructured_contentfor JSON responses