Skip to content

invoke_mcp_tool behavior clarification for use_structured_content #1236

@jtanningbed

Description

@jtanningbed

Please read this first

  • Have you read the docs?Agents SDK docs
    Yes

  • Have you searched for related issues? Others may have had similar requests
    Yes

Question

the mcp/util.py defines invoke_mcp_tool, which parses the tool result output based on the server transport's use_structured_content attribute. It seems the idea was to support backwards compatibility by defaulting use_structured_content to False and continuing to return the [res for res in result.content] or result.content[0] since many servers may not return result.structuredContent yet. However, when use_structured_content is True, it will return both ie. tool_result={tool_output}\n{json.dumps(result.structuredContent)}.

        if len(result.content) == 1:
            tool_output = result.content[0].model_dump_json()
            # Append structured content if it exists and we're using it.
            if server.use_structured_content and result.structuredContent:
                tool_output = f"{tool_output}\n{json.dumps(result.structuredContent)}"
        elif len(result.content) > 1:
            tool_results = [item.model_dump(mode="json") for item in result.content]
            if server.use_structured_content and result.structuredContent:
                tool_results.append(result.structuredContent)
            tool_output = json.dumps(tool_results)
        elif server.use_structured_content and result.structuredContent:
            tool_output = json.dumps(result.structuredContent)
        else:
            # Empty content is a valid result (e.g., "no results found")
            tool_output = "[]"

There is a conditional for dumping just the result.structuredContent :

        elif server.use_structured_content and result.structuredContent:
            tool_output = json.dumps(result.structuredContent)

but this essentially will never get hit because len(result.content) if not 1 or >1 will only be 0, and len 0 would probably result in not result.structuredContent. How I thought this should be working was that use_structured_content would be set based on whether the server was known to produce result.structuredContent or not, and so the tool_output could contain ONLY the result.structuredContent, not both. As it stands, the current logic does not allow any way to return only the structured content. it only supports either the text content ONLY , or the text content + structured content. Is there any reason the control flow can't be something like:

        if server.use_structured_content and result.structuredContent:
            # dump structured content 
            tool_output = f"{json.dumps(result.structuredContent)}"
        else: 
            # dump text content 
            if len(result.content) == 1:
                tool_output = result.content[0].model_dump_json()
            elif len(result.content) > 1:
                tool_output = [item.model_dump(mode="json") for item in result.content]
            else:
                # Empty content is a valid result (e.g., "no results found")
                tool_output = "[]"

Basically I'm asking if there is any reason why if use_structured_content is being set to False by default already to support backwards compatibility, why does the use_structured_content=True case have to support only the addition of the structured content, not replacement of text content with structured content? Currently, if I want to use structured content, the tool calls will output double length ({text}\n{structured}), and if i want to output single length, it only supports {text}, but not just {structured}.

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