Skip to main content
MCP Apps SDK MCP Apps combine a model-called tool, a ui:// resource, and a View that can talk back to the host. The basic flow is covered in Lifecycle. This page covers common implementation patterns you will need once the first View is working.

Use App-only Tools for UI Interactions

Set _meta.ui.visibility to ["app"] when a tool should be callable by the View but hidden from the model. Use app-only tools for UI actions that do not help the model decide what to do next:
  • Refreshing dashboard data
  • Loading the next page of results
  • Saving form edits after the user clicks a button
  • Polling server state
  • Loading private or bulky data that should stay out of model context
Then call it from the View:
Keep a text content block even when the View mostly uses structuredContent. Text-only hosts, logs, and debugging tools still need a readable summary.

Poll Live Data Deliberately

For dashboards, job progress, or monitoring UIs, poll through an app-only tool. Stop polling during teardown and when the app is hidden or no longer needs updates.
Poll only while the View can use the result. If the server can return complete, failed, or cancelled, stop the interval as soon as that status arrives.

Load Large Data in Chunks

Large files and large result sets should not go through one model-visible tool response. Split them into app-only requests and render progress in the View.
In the View, loop until hasMore is false:
Use readServerResource() for data that naturally belongs in MCP resources, such as images, video, generated files, or cached artifacts.

Report Errors at the Right Layer

Use a tool-level error when the model can recover:
Throw an exception for broken app code, transport failures, or states where retrying the same request cannot work. When the View detects a degraded state that the model should know about, call updateModelContext():
Keep these messages short and factual. They become part of the model’s working context.

Adapt to Host Context

Hosts can differ in theme, display mode, size, safe area insets, locale, and available capabilities. Read host context after connect() and listen for changes.
For React apps, prefer the SDK hooks:
Check getHostCapabilities() before relying on host-mediated features such as server tool calls, resource reads, file downloads, link opening, sampling, or message sending.

Keep Model Context Small

Use content for the model-readable summary, structuredContent for the View, and app-only tools for data the model does not need. Good model context:
Avoid putting full tables, binary data, long logs, or private UI state into content. If the model needs a summary later, let the View call updateModelContext() with the specific facts the user selected.