Skip to content

Support specifying OutputSchema independently of return type for tools returning CallToolResult#1425

Open
Copilot wants to merge 5 commits intomainfrom
copilot/support-outputschema-type
Open

Support specifying OutputSchema independently of return type for tools returning CallToolResult#1425
Copilot wants to merge 5 commits intomainfrom
copilot/support-outputschema-type

Conversation

Copy link
Contributor

Copilot AI commented Mar 11, 2026

Tools returning CallToolResult directly (for control over Meta, IsError, StructuredContent) had no way to advertise a meaningful OutputSchema in tools/list. The inferred schema would reflect CallToolResult itself rather than the actual structured content shape.

Changes

  • McpServerToolCreateOptions: Add JsonElement? OutputSchema property (pre-computed schema, included in Clone())
  • McpServerToolAttribute: Add Type? OutputSchemaType property (converted to JSON schema via AIJsonUtilities.CreateJsonSchema during option derivation)
  • AIFunctionMcpServerTool.CreateOutputSchema: Explicit OutputSchema takes precedence over AIFunction.ReturnJsonSchema; existing wrapping/normalization logic applies to both paths
  • 13 new tests covering options-based, attribute-based, CallToolResult passthrough, non-object wrapping, nullable simplification, and options-over-attribute precedence

Usage

// Attribute-based: Type is converted to JSON schema at tool creation
[McpServerTool(UseStructuredContent = true, OutputSchemaType = typeof(WeatherResponse))]
public static CallToolResult GetWeather(string city)
{
    var response = new WeatherResponse { Temperature = 72, Condition = "sunny" };
    return new CallToolResult
    {
        Content = [new TextContentBlock { Text = "72°F, sunny" }],
        StructuredContent = JsonSerializer.SerializeToElement(response),
        IsError = false,
    };
}

// Options-based: pass a pre-computed JsonElement schema
McpServerTool.Create(myDelegate, new McpServerToolCreateOptions
{
    UseStructuredContent = true,
    OutputSchema = myJsonSchemaElement,
});

UseStructuredContent = true is still required for OutputSchema/OutputSchemaType to take effect.


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Copilot AI and others added 3 commits March 11, 2026 03:13
…ToolAttribute

Adds support for specifying the output schema type independently of the return
type for tools returning CallToolResult. This allows developers to advertise
a meaningful OutputSchema in tools/list while still having full control over
the CallToolResult response (Meta, IsError, StructuredContent).

- Add `JsonElement? OutputSchema` property to McpServerToolCreateOptions
- Add `Type? OutputSchema` property to McpServerToolAttribute
- DeriveOptions converts the attribute's Type to a JSON schema
- CreateOutputSchema uses explicit OutputSchema over AIFunction's return schema
- Add 13 comprehensive tests covering all variations

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
@stephentoub
Copy link
Contributor

@halter73 / @mikekistler, I explored creating a CallToolResult<T> and using that, but it leads to too many complications/oddities to be worthwhile in my opinion. I think the simple approach of just having OutputType on the attribute is the right answer.

@stephentoub stephentoub marked this pull request as ready for review March 11, 2026 03:16
Copilot AI changed the title [WIP] Support specifying OutputSchema type independently of return type Support specifying OutputSchema independently of return type for tools returning CallToolResult Mar 11, 2026
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
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.

Support specifying OutputSchema type independently of return type for tools returning CallToolResult

2 participants