C# MCP SDK: decouple StructuredContent from Content in McpServerTool results?
In the modelcontextprotocol/csharp-sdk (issue opened 2025-10-31), when a tool is registered with
[McpServerTool(UseStructuredContent = true)], how do you decouple theContenttext from theStructuredContentpayload? The output schema is generated fromCallToolResultinstead of the actual model type, which breaks targets like the OpenAI Apps SDK MCP server.Originally asked on GitHub: https://github.com/modelcontextprotocol/csharp-sdk/issues/930
2 answers
This was fixed: the issue is closed as completed, and the solution landed in the SDK via PR #1425 (the thread doesn't name a release version). A maintainer noted that decoupling
ContentfromStructuredContentis the right approach, but until the MCP protocol SEP that explicitly allows it is accepted, some clients will warn about — or reject — a response where the two aren't in sync.Before the fix, the workaround was to return an explicit
CallToolResultwithContentset to aTextContentBlockandStructuredContentset toJsonSerializer.SerializeToNode(model). That separates the two payloads in the response (which is what the OpenAI Apps SDK sample in the issue needs), but the tool's output schema is still generated fromCallToolResult, not from the model type, so the declared schema doesn't describe the actual structured content.To get the full fix, check PR #1425 in modelcontextprotocol/csharp-sdk — the thread doesn't show the final API shape. The reporter proposed either a generic
CallToolResult<TStructuredContent>or aStructuredContentTypeparameter on theMcpServerToolattribute; the PR may have implemented something else, so read it before writing code. In the meantime, keep the human-readableContenttext aligned with the structured payload (for example, a short summary in text and the trimmed data instructuredContent) to reduce the chance of client warnings.Did this work for you?What a GitHub user tried on GitHub (Partly worked)
The reporter used
[McpServerTool(UseStructuredContent = true)]and returned an explicitCallToolResultwithContentset to aTextContentBlockandStructuredContentset viaJsonSerializer.SerializeToNode(model). This separatedContentfromStructuredContentin the response, but the generated output schema describedCallToolResultinstead of the model type, so schema generation was still wrong.Source: https://github.com/modelcontextprotocol/csharp-sdk/issues/930 (opens external site)
Did this work for you?
Related questions
- Does the C# MCP SDK implement the Streamable HTTP transport (2025-03-26 spec)?
- How to use HTTP Streamable transport for MCP server and client in .NET csharp-sdk?
- How to pass HttpContext/bearer token from /message endpoint to MCP tool handler in csharp-sdk?
- Why is there no MCP Streamable HTTP server support on .NET Framework?
- Can I build MCP Apps with the C# SDK?