Skip to main content
MCP Apps SDK
import { useApp } from "@modelcontextprotocol/ext-apps/react";

Overview

useApp creates an App instance, connects it to the host via PostMessageTransport, and returns the connection state. Options are only used on the initial mount — the hook does not reconnect when options change.

Signature

function useApp(options: UseAppOptions): AppState

UseAppOptions

appInfo
{ name: string; version: string }
required
App identification sent to the host during ui/initialize.
capabilities
McpUiAppCapabilities
default:"{}"
Features this app provides (e.g., { tools: { listChanged: true } }).
onAppCreated
(app: App) => void
Called after App is created but before connect(). Use this to register event handlers that must be in place before the initialization handshake.

AppState

app
App | null
The connected App instance, or null during initialization.
isConnected
boolean
Whether initialization completed successfully.
error
Error | null
Connection error if initialization failed, null otherwise.

Usage

import { useApp } from "@modelcontextprotocol/ext-apps/react";

function MyApp() {
  const { app, isConnected, error } = useApp({
    appInfo: { name: "MyApp", version: "1.0.0" },
    capabilities: {},
    onAppCreated: (app) => {
      app.ontoolinput = (input) => {
        console.log("Tool input:", input);
      };
      app.ontoolresult = (result) => {
        console.log("Tool result:", result);
      };
      app.onhostcontextchanged = (ctx) => {
        console.log("Host context changed:", ctx);
      };
    },
  });

  if (error) return <div>Error: {error.message}</div>;
  if (!isConnected) return <div>Connecting...</div>;

  return <div>Connected to {app?.getHostContext()?.hostInfo?.name}</div>;
}

Behavior

  • HMR persistence — The App instance persists across React Fast Refresh, so code changes don’t trigger reconnection. A full page reload establishes a fresh connection.
  • Strict Mode — The App is intentionally not closed on unmount to avoid cleanup issues during React Strict Mode’s double-mount cycle. Call app.close() manually if needed.
  • Auto-resize — The App is created with autoResize: true by default. For custom options, create the App manually and use useAutoResize.
  • Options stability — Options are only read on initial mount. Changing appInfo, capabilities, or onAppCreated after mount has no effect.
The sunpeak framework provides its own useApp that returns just App | null via React context, with additional framework integration.