Skip to content

Stop returning structuredContent in MCP tool call results#214

Merged
rhennigan merged 1 commit into
mainfrom
bugfix/structured-content
Jul 9, 2026
Merged

Stop returning structuredContent in MCP tool call results#214
rhennigan merged 1 commit into
mainfrom
bugfix/structured-content

Conversation

@rhennigan

Copy link
Copy Markdown
Member

Summary

Some MCP clients discard a tool result's content (text and images) entirely when structuredContent is present, using it as a replacement for the model-visible content. That is not what we want. The MCP Apps viewers only need the notebookUrl, which already travels out-of-band via _meta (with the in-content <internal><url> marker as the fallback for hosts that drop _meta), so structuredContent is unnecessary here and actively harmful.

This PR stops emitting structuredContent from tool call results end-to-end, keeping _meta exactly as-is, and removes the resulting dead code.

Changes

Stop sending structuredContent

  • Kernel/StartMCPServer.wlevaluateTool no longer forwards structuredContent into the tool result. The _meta forwarding (e.g. notebookUrl for MCP Apps) is unchanged.
  • Kernel/UIResources.wl — dropped the now-orphaned StructuredContent key from makeNotebookUIResult; its only consumer was the forwarding above. It now carries notebookUrl in _meta only.

Remove the resulting dead code in the viewers

Since makeNotebookUIResult was the sole producer of the key and the server no longer emits it, params.structuredContent / result.structuredContent can never reach a viewer — the reads were unreachable.

  • Assets/Apps/evaluator-viewer.html, notebook-viewer.html, wolframalpha-viewer.html — removed the dead structured parameter and its unreachable check from findNotebookUrl/handleToolResult and all call sites. The live _meta → per-item _meta → <internal><url> marker recovery chain is unchanged.

Tests, comments, docs

  • Tests/MCPApps.wlt — the makeNotebookUIResult test now asserts StructuredContent is not produced.
  • Tests/EvaluatorSessions.wlt — removed the moot AppendSessionInfo-PreservesStructuredContent test (PreservesMeta already covers generic sibling-key preservation).
  • Updated tool comments and docs/mcp-apps.md to reflect _meta-only delivery.

Test plan

  • Tests/MCPApps.wlt94/94 pass
  • Tests/EvaluatorSessions.wlt34/34 pass
  • Tests/NotebookViewer.wlt24/24 pass
  • Tests/MCPAppsTest.wlt19/19 pass
  • Tests/StartMCPServer.wlt — 51/51 non-subprocess tests pass. The 34 failures are pre-existing/environmental: this sandbox can't spawn a wolframscript subprocess (StartProcess::pnfdMCPTestServerNotRunning), so the server never starts and evaluateTool is never reached. Should be re-run in an environment that can spawn subprocesses.
  • CodeInspector clean on all four changed .wl files (only pre-existing, unrelated FixMeComment warnings).
  • node --check on all three extracted viewer scripts — syntax valid.

Notes

Related upstream context (hosts dropping _meta/structuredContent): ext-apps#696. No internal tracking issue.

🤖 Generated with Claude Code

Some MCP clients discard a tool result's content (text and images)
entirely when structuredContent is present, treating it as a
replacement. The MCP Apps viewers only need the notebookUrl, which
already travels out-of-band via _meta (with the in-content
<internal><url> marker as the fallback for hosts that drop _meta), so
structuredContent is unnecessary here and actively harmful.

- StartMCPServer: stop forwarding structuredContent from tool results;
  the _meta forwarding is unchanged.
- UIResources: drop the now-orphaned StructuredContent key from
  makeNotebookUIResult -- its only consumer was the forwarding above.
- Remove the now-dead structuredContent reads from the evaluator,
  notebook, and wolframalpha viewers, since nothing can populate them
  anymore.
- Update tests, tool comments, and docs/mcp-apps.md accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ixcyVNPpuYCf9k9xnCoYP
Copilot AI review requested due to automatic review settings July 9, 2026 18:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates AgentTools’ MCP tool-call result pipeline and MCP Apps viewers to stop emitting structuredContent, because some MCP clients treat it as a replacement for content and therefore drop model-visible text/images. Notebook UI delivery is preserved via _meta.notebookUrl (plus the existing <internal><url>…</url></internal> marker fallback when _meta is dropped).

Changes:

  • Remove structuredContent forwarding from Kernel/StartMCPServer.wl tool results while preserving _meta forwarding.
  • Stop producing the StructuredContent key in makeNotebookUIResult and delete now-dead viewer logic that read params/result.structuredContent.
  • Update tests and documentation to assert/describe _meta-only delivery for notebook URLs.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
Tests/MCPApps.wlt Updates expectation to assert StructuredContent is not produced by makeNotebookUIResult.
Tests/EvaluatorSessions.wlt Removes now-moot structured-content preservation test.
Kernel/UIResources.wl Drops StructuredContent from makeNotebookUIResult; updates comments to _meta-only rationale.
Kernel/Tools/WolframLanguageEvaluator.wl Updates UI-result comment to reflect _meta-only delivery.
Kernel/Tools/WolframAlpha.wl Updates UI-result comment to reflect _meta-only delivery.
Kernel/StartMCPServer.wl Stops forwarding structuredContent into MCP tool call results; continues forwarding _meta.
docs/mcp-apps.md Documents _meta-only delivery and explains why structuredContent is intentionally not sent.
Assets/Apps/wolframalpha-viewer.html Removes dead structuredContent parameter plumbing; keeps _meta + marker recovery.
Assets/Apps/notebook-viewer.html Removes dead structuredContent reads; keeps _meta + marker recovery.
Assets/Apps/evaluator-viewer.html Removes dead structuredContent reads; keeps _meta + marker recovery.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@rhennigan rhennigan merged commit 64f4726 into main Jul 9, 2026
1 of 2 checks passed
@rhennigan rhennigan deleted the bugfix/structured-content branch July 9, 2026 19:03
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.

2 participants