Skip to content

[MCP Tool] Implement support for structured content #1825

@liliankasem

Description

@liliankasem

Implement support for MCP structured content in tool functions. This feature allows tools to return structured data that clients can programmatically consume, while maintaining backwards compatibility by also including text content.

Background

The MCP specification supports structured content that can be returned alongside unstructured (text) content from tool invocations. When a tool returns structured content, it should ALSO include a text representation for backwards compatibility with clients that don't support structured content.

MCP Specification: https://modelcontextprotocol.io/specification/2025-06-18/server/tools#structured-content

Reference Implementation: Azure/azure-functions-mcp-extension#172

Host Extension Contract

The host extension has a feature that allows the worker to be responsible for result content by setting UseResultSchema to true in the tool trigger binding. This was originally added to allow workers to support rich binding types such as TextContentBlock, ImageContentBlock, or CallToolResult. This same feature can be leveraged to enable structured content support.

    /// <summary>
    /// Gets or sets whether the result schema should be provided by the worker instead of being generated by the host extension.
    /// When set to true, the <see cref="ResultSchema"/> property must be provided.
    /// When set to false (default), the extension generates the schema from the function return type.
    /// </summary>
    public bool UseResultSchema { get; set; } = false;

When UseResultSchema is set to true, the host extension expects tool results to be wrapped in an McpToolResult object. This is a wrapper that the worker sends back to the host containing the serialized tool result along with metadata about the result type.

Note: If UseResultSchema is false (the default), the host extension handles result processing and this wrapper is not needed. The McpToolResult wrapper is only required when the worker wants to control the result schema.

McpToolResult schema:

public class McpToolResult
{
    // The type of content (e.g., "text", "image", "audio", "multi_content_result", "call_tool_result")
    public required string Type { get; set; }
    
    // The serialized content block(s)
    public string? Content { get; set; }
    
    // NEW: Optional structured content as a JSON object
    public string? StructuredContent { get; set; }
}

When using `McpToolResult`, the worker can use this to populate the `structuredContent` field when the user wants to return structured data.

**Standard result with structured content:**
```json
{
  "type": "text",
  "content": "<serialized-TextContentBlock>",
  "structuredContent": "<serialized-structured-data>"
}

CallToolResult with structured content:

{
  "type": "call_tool_result",
  "content": "<serialized-CallToolResult>",
  "structuredContent": "<serialized-structured-data>"
}

Key Considerations

  1. Backwards compatibility: When structuredContent is populated, there must also be a TextContentBlock in the content for clients that don't support structured content.

  2. The structuredContent field should contain the JSON-serialized structured data that clients can programmatically consume.

  3. The content field contains the serialized content block(s) as before - this is unchanged from existing behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions