Skip to content

MCP Apps

Reference for MCP App capabilities: callTool, openLink, requestDisplayMode, readResource, sendMessage, updateModelContext, host context, and host capabilities.

For the complete documentation index, see llms.txt. Markdown variants of every page are available by appending .md to the URL.

What is an MCP App?

An MCP App is an iframe-based UI that communicates with its host through PostMessage and JSON-RPC. The host provides capabilities like tool calling, resource reads, display-mode switching, and conversation messaging. Your app discovers what the host supports at connection time and can adapt accordingly.

The MCP App runtime is exported from the main xmcp package at xmcp/host-bridge. The @xmcp-dev/ui package re-exports a React hook (useMcpApp()) that wraps one shared bridge for the iframe lifetime. React component cleanup unsubscribes only its observer, so Strict Mode remounts do not dispose the shared host connection.

useMcpApp() hook

The recommended way to use MCP App capabilities in React:

src/tools/my-app.tsx

Capabilities

callTool(name, args?)

Invoke an MCP tool through the host. The host routes the call to the connected MCP server and returns the result.

openLink(url)

Open a URL in the host's browser. Falls back to window.open when no host is connected.

requestDisplayMode(mode)

Ask the host to switch the app's display mode. Supported modes:

  • "inline": embedded in the conversation flow (default)
  • "fullscreen": takes over the full viewport
  • "pip": picture-in-picture floating window

The host may not grant the requested mode. The returned object tells you which mode was actually applied.

readResource(uri)

Read an MCP resource from the server through the host.

sendMessage(params)

Send a message to the host conversation. This lets the app communicate back to the user or model through the host's chat interface.

updateModelContext(params)

Inject context into the model's next turn. Use this to provide the model with information it should consider in its response.

logMessage(params)

Emit a log notification to the host. This is fire-and-forget and does not wait for a response.

notifySizeChanged(dimensions)

Tell the host that the app's rendered size has changed. The host can use this to resize the iframe container.

For automatic size reporting, use useAutoMcpAppSize() instead of calling this manually.

Reactive state

isConnected

Boolean indicating whether the bridge has an active connection to the host. The bridge starts connected if it detects a parent window, then marks disconnected if no host traffic arrives within the connection timeout (2 seconds by default).

hostContext

The host environment context, updated reactively when the host sends ui/notifications/host-context-changed. Contains:

FieldTypeDescription
themestringHost color theme ("light", "dark", etc.)
displayModestringCurrent display mode
localestringHost locale (e.g. "en-US")
timeZonestringHost timezone
platformstringHost platform identifier
availableDisplayModesMcpUiDisplayMode[]Which display modes the host supports
containerDimensions{ width, height }Current container size in pixels
safeAreaInsets{ top, right, bottom, left }Safe area insets for the app viewport
toolInfoRecord<string, unknown>Metadata about the tool that launched this app
deviceCapabilitiesRecord<string, unknown>Device-level capabilities
stylesMcpHostStyleContextTheme variables and CSS provided by the host

hostCapabilities

What the host advertises it supports. Use this to conditionally enable features:

FieldTypeDescription
serverTools{ call, listChanged }Whether the host can call tools and track changes
serverResources{ read, listChanged }Whether the host can read resources
openLinksbooleanWhether openLink is supported
updateModelContextboolean | string[]Whether model context updates are supported
messagebooleanWhether sendMessage is supported
loggingbooleanWhether logMessage is supported
downloadFilebooleanWhether file downloads are supported
sandboxRecordSandbox restrictions

Auto size reporting

useAutoMcpAppSize() uses ResizeObserver to automatically report size changes to the host:

src/tools/my-app.tsx

Framework-agnostic usage

If you are not using React or @xmcp-dev/ui, the host bridge is available directly from the main xmcp package:

The bridge exposes the same methods as useMcpApp() plus lifecycle controls:

  • getState(): current bridge state
  • getHostContext(): current host context
  • getHostCapabilities(): current host capabilities
  • isConnected(): connection status
  • subscribe(listener): listen for state changes (returns unsubscribe fn)
  • dispose(): clean up listeners and reject pending requests

References

On this page

One framework to rule them all