Skip to main content
MCP Apps SDK MCP App data crosses three boundaries: the model reads the tool result, the View renders the UI, and the host manages the iframe and conversation state. Use the right field for each boundary so text-only MCP clients keep working and the View does not scrape text.

Field Guide

Result Flow

The first model-called tool should return enough content for a non-UI host to answer the user. The View should render structuredContent, not parse content.

Return Both Text and Structured Data

The text block keeps the result useful in normal MCP clients. structuredContent gives the View a stable object shape.

What Goes in content

Use content for facts the model may need immediately:
  • What the tool did.
  • Counts, totals, statuses, or identifiers that answer the user.
  • Error messages the model can recover from.
  • A compact summary when the full data is too large.
Avoid full tables, raw files, private UI state, and long logs in content. If the user later chooses a row or filter in the View, send that selection with updateModelContext.

What Goes in structuredContent

Use structuredContent for the UI payload:
  • Rows, chart series, map markers, cards, media metadata, or form defaults.
  • Pagination cursors and IDs the View needs for app-only tool calls.
  • Status objects that drive loading, success, and error UI.
Declare outputSchema for model-called UI tools and for app-only tools whose responses the View depends on. The schema documents the contract and helps clients validate the result.

What Goes in _meta

Use _meta only for metadata that should not be part of the model-readable answer:
  • Internal request IDs, cache keys, trace IDs, or view IDs.
  • Host-specific rendering hints.
  • Resource _meta.ui such as CSP, permissions, domain, and prefersBorder.
  • Data that the View can use but the model should not rely on.
Do not hide user-visible facts in _meta. Hosts and clients may treat _meta as implementation metadata, and the model should not need it to answer.

Keep the Model Current After UI Changes

Tool results describe the state at tool-call time. After the user interacts with the View, call updateModelContext with the small set of facts the model should know on later turns.
Each call overwrites the previous app context. Send the complete current state you want the model to retain, not just a patch.

App-only Tool Results

App-only tools still return normal MCP tool results. Keep content short for logs and debugging, and put the View payload in structuredContent.
The model never sees this tool in its tool list, but the result shape still matters because the View calls it through callServerTool.

Checklist

  • Return content on every model-visible tool result.
  • Render structuredContent in the View instead of parsing text.
  • Add outputSchema for structured UI payloads.
  • Use _meta for metadata only, not facts the model must know.
  • Use app-only tools for pagination, polling, submit buttons, and refresh actions.
  • Call updateModelContext after user selections that should affect future model replies.
  • Keep each model context update complete because the previous one is overwritten.

Tool and Resource Contract

Check the full server-side MCP App contract.

Tool _meta

Link tools to Views and control model vs app visibility.

updateModelContext

Push View state into future model turns.

useToolData

Read tool input and structured output in sunpeak React resources.