> ## Documentation Index
> Fetch the complete documentation index at: https://sunpeak.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Apps useApp - React Connection Hook

> Connect to an MCP App host with useApp. Creates App, PostMessageTransport, handles initialization handshake, and returns connection state.

<Badge color="green">MCP Apps SDK</Badge>

```ts theme={null}
import { useApp } from "@modelcontextprotocol/ext-apps/react";
```

## Overview

`useApp` creates an [`App`](/mcp-apps/app/app-class) 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

```ts theme={null}
function useApp(options: UseAppOptions): AppState
```

## UseAppOptions

<ResponseField name="appInfo" type="{ name: string; version: string }" required>
  App identification sent to the host during `ui/initialize`.
</ResponseField>

<ResponseField name="capabilities" type="McpUiAppCapabilities" default="{}">
  Features this app provides (e.g., `{ tools: { listChanged: true } }`).
</ResponseField>

<ResponseField name="onAppCreated" type="(app: App) => void">
  Called after `App` is created but before `connect()`. Use this to register [event handlers](/mcp-apps/app/event-handlers) that must be in place before the initialization handshake.
</ResponseField>

## AppState

<ResponseField name="app" type="App | null">
  The connected `App` instance, or `null` during initialization.
</ResponseField>

<ResponseField name="isConnected" type="boolean">
  Whether initialization completed successfully.
</ResponseField>

<ResponseField name="error" type="Error | null">
  Connection error if initialization failed, `null` otherwise.
</ResponseField>

## Usage

```tsx theme={null}
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?.getHostVersion()?.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`](/mcp-apps/react/use-auto-resize).
* **Options stability** — Options are only read on initial mount. Changing `appInfo`, `capabilities`, or `onAppCreated` after mount has no effect.

<Tip>
  The [sunpeak framework](/quickstart) provides its own [`useApp`](/app-framework/hooks/use-app) that returns just `App | null` via React context, with additional framework integration.
</Tip>
