@mcp-apps-kit/ui-react

React bindings for MCP applications.
@mcp-apps-kit/ui-react builds on @mcp-apps-kit/ui to provide React context and hooks for tool calls, tool results, and host context.
Table of Contents
Background
React widgets often need host-aware APIs for tool calls and UI state. This package provides a React-first wrapper around the vanilla UI SDK so you can use hooks instead of manual subscriptions.
Features
AppsProvider context wrapper
- Hooks for tools, host context, and widget state
- Typed tool calls with generics
- Optional debug logger hook
- Host capabilities - Query what the host supports (theming, display modes, file upload, etc.)
- Size notifications - Automatic resize observer integration
- Partial tool input - React to streaming tool inputs
Compatibility
- Hosts: MCP Apps and ChatGPT (OpenAI Apps SDK)
- Node.js:
>= 18 for tooling/builds (browser runtime)
- Peer dependencies:
react and react-dom ^18 || ^19
Install
npm install @mcp-apps-kit/ui-react
Usage
Quick start
import { AppsProvider, useAppsClient, useToolResult, useHostContext } from "@mcp-apps-kit/ui-react";
function Widget() {
const client = useAppsClient();
const result = useToolResult();
const host = useHostContext();
return (
<div data-theme={host.theme}>
<button onClick={() => client.callTool("greet", { name: "Alice" })}>Greet</button>
<pre>{JSON.stringify(result, null, 2)}</pre>
</div>
);
}
export function App() {
return (
<AppsProvider>
<Widget />
</AppsProvider>
);
}
Typed tools
import { AppsProvider, useAppsClient } from "@mcp-apps-kit/ui-react";
import type { AppClientTools } from "../server";
function Widget() {
const client = useAppsClient<AppClientTools>();
return null;
}
export function App() {
return (
<AppsProvider>
<Widget />
</AppsProvider>
);
}
Examples
API
Provider
AppsProvider - Context wrapper for all hooks
Core Hooks
useAppsClient | Client instance for tool calls |
useToolResult | Current tool result data |
useToolInput | Tool input parameters |
useHostContext | Host info (theme, viewport, locale, etc.) |
useWidgetState | Persisted state across reloads |
useDisplayMode | Fullscreen/panel mode control |
useDebugLogger | Debug logging configuration |
Host Capabilities & Version
import { useHostCapabilities, useHostVersion } from "@mcp-apps-kit/ui-react";
function Widget() {
const capabilities = useHostCapabilities();
const version = useHostVersion();
const themes = capabilities?.theming?.themes;
const modes = capabilities?.displayModes?.modes;
const hasPartialInput = !!capabilities?.partialToolInput;
const hasFileUpload = !!capabilities?.fileUpload;
return <div>Host: {version?.name}</div>;
}
Size Notifications (MCP Apps)
import { useSizeChangedNotifications } from "@mcp-apps-kit/ui-react";
function Widget() {
const containerRef = useSizeChangedNotifications();
return <div ref={containerRef}>Content that may resize</div>;
}
Partial Tool Input (MCP Apps)
import { useOnToolInputPartial } from "@mcp-apps-kit/ui-react";
function Widget() {
useOnToolInputPartial((input) => {
console.log("Partial input:", input);
});
return <div>Streaming input widget</div>;
}
Theme & Style Hooks
useHostStyleVariables | Apply host-provided CSS variables |
useDocumentTheme | Sync document theme with host |
useSafeAreaInsets | Safe area insets (ChatGPT) |
Lifecycle Hooks
useOnToolCancelled | Callback when tool is cancelled |
useOnTeardown | Cleanup callback before widget removal |
File Operations (ChatGPT)
useFileUpload | Upload files to host |
useFileDownload | Get file download URLs |
Layout (ChatGPT)
useIntrinsicHeight | Set widget intrinsic height |
useView | View management |
Modals (ChatGPT)
useModal | Modal dialog management |
Contributing
See ../../CONTRIBUTING.md for development setup and guidelines. Issues and pull requests are welcome.
License
MIT