MCP Apps: Cursor strips `_meta` from `ui/notifications/tool-result` before forwarding to the widget

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

Cursor strips _meta from ui/notifications/tool-result before forwarding MCP Apps tool results to the widget iframe. Widgets receive content and structuredContent only. Claude Desktop and VS Code forward _meta correctly on the same server payload.

The MCP Apps spec (2026-01-26) types the notification’s params as CallToolResult, which includes _meta, and describes _meta as widget-only metadata “not intended for model context.”

Steps to Reproduce

  1. Point Cursor at an MCP server that returns a tool result of this shape:
    {
      "content": [{"type": "text", "text": "Done."}],
      "structuredContent": {"summary": "..."},
      "_meta": {"example.com/widget-data": {"foo": "bar"}}
    }
    
  2. Invoke the tool from a widget-capable context.
  3. Log params in the widget’s ontoolresult handler.

Expected Behavior

params._meta contains the server’s payload, per the MCP Apps spec and matching Claude Desktop / VS Code behaviour.

Observed: _meta is absent.

Operating System

MacOS

Version Information

Version: 3.1.17
VSCode Version: 1.105.1
Commit: fce1e9ab7844f9ea35793da01e634aa7e50bce90
Date: 2026-04-19T19:33:58.189Z
Layout: glass
Build Type: Stable
Release Track: Default
Electron: 39.8.1
Chromium: 142.0.7444.265
Node.js: 22.22.1
V8: 14.2.231.22-electron.0
OS: Darwin arm64 25.4.0

Additional Information

_meta is the only spec-designated channel for widget-only payloads. Ecosystem behaviour on content vs structuredContent is inconsistent — see SEP-2200 on the MCP core spec. Stripping _meta forces servers to leak widget state into model-visible fields.

Does this stop you from using Cursor

No - Cursor works, but with this issue

Hi James,

Thanks for the detailed report, I was able to reproduce this! You’re right that _meta is being dropped from tool results before they reach the widget iframe.

This is the first report we’ve had for this specific issue, so it’s fairly niche territory. Is this affecting something custom you’re building, or is this coming up with a known/public MCP server? Understanding the use case would help us prioritize the fix!

Thanks Colin!

Surprised this isn’t more widely reported. Feels pretty fundamental to building an MCP app. It’s blocking our upcoming public Sanity MCP App for Cursor users.

We need a way to pass UI-specific payloads to the widget without the model seeing them. The MCP Apps spec originally pointed at structuredContent for this, but several harnesses forward structuredContent to the model. Our widget payload has UI-specific keys that confused those models and caused regressions when it leaked in. The spec is ambiguous about how structuredContent should behave outside MCP Apps, so current community guidance (see ext-apps#380 and SEP-2200) is to use _meta for UI-only concerns, which Cursor strips.

My theory for why this hasn’t surfaced more widely: either existing MCP Apps have structuredContent close enough to content that the model doesn’t regress, or they’re only testing on harnesses that treat structuredContent as UI-only and the problem stays invisible.

Once you need a widget-only payload that also won’t regress in text-only harnesses, there’s nowhere safe to put it.