You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

@mcp-apps-kit/ui-react

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mcp-apps-kit/ui-react

React bindings for MCP applications

latest
Source
npmnpm
Version
0.5.0
Version published
Maintainers
1
Created
Source

@mcp-apps-kit/ui-react

npm node license

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 and results

Use ClientToolsFromCore from @mcp-apps-kit/core for end-to-end type safety:

import { AppsProvider, useAppsClient, useToolResult } from "@mcp-apps-kit/ui-react";
import type { AppClientTools } from "../server"; // Exported from your server

function Widget() {
  // Typed client - callTool arguments and return types are inferred
  const client = useAppsClient<AppClientTools>();

  // Typed results - result?.greet?.message is typed as string | undefined
  const result = useToolResult<AppClientTools>();

  const handleGreet = async () => {
    // Option 1: Using callTool with tool name string
    await client.callTool("greet", { name: "Alice" });

    // Option 2: Using the typed tools proxy (recommended)
    await client.tools.callGreet({ name: "Alice" });
  };

  if (result?.greet) {
    return (
      <div>
        <p>{result.greet.message}</p>
        <p>at {result.greet.timestamp}</p>
      </div>
    );
  }

  return <button onClick={handleGreet}>Greet</button>;
}

export function App() {
  return (
    <AppsProvider>
      <Widget />
    </AppsProvider>
  );
}

Automatic size notifications

By default, the MCP adapter automatically reports UI size changes to the host using a ResizeObserver. This feature is only supported in MCP Apps and is silently ignored in ChatGPT.

To disable automatic resizing:

export function App() {
  return (
    <AppsProvider autoResize={false}>
      <Widget />
    </AppsProvider>
  );
}

Note: The autoResize option is only applied during initial mount. Changing it at runtime has no effect.

The AppClientTools type is generated in your server code:

// server/index.ts
import { createApp, defineTool, type ClientToolsFromCore } from "@mcp-apps-kit/core";

const app = createApp({
  tools: {
    greet: defineTool({
      input: z.object({ name: z.string() }),
      output: z.object({ message: z.string(), timestamp: z.string() }),
      handler: async (input) => ({ ... }),
    }),
  },
});

// Export for UI code
export type AppClientTools = ClientToolsFromCore<typeof app.tools>;

Examples

API

Provider

  • AppsProvider - Context wrapper for all hooks
    • client? - Pre-initialized client instance (optional)
    • forceAdapter? - Force a specific adapter ("mcp" | "openai" | "mock")
    • autoResize? - Enable/disable automatic size change notifications (default: true). Only supported in MCP Apps; ignored in ChatGPT. Note: changing this prop after initial mount has no effect.
    • fallback? - Component to show while client initializes
    • errorFallback? - Component to show on initialization error

Core Hooks

HookDescription
useAppsClientClient instance for tool calls
useToolResultCurrent tool result data
useToolInputTool input parameters
useHostContextHost info (theme, viewport, locale, etc.)
useWidgetStatePersisted state across reloads
useDisplayModeFullscreen/panel mode control
useDebugLoggerDebug logging configuration

Typed Tools Proxy

The client returned by useAppsClient includes a tools property with typed method wrappers:

import { useAppsClient } from "@mcp-apps-kit/ui-react";
import type { AppClientTools } from "../server";

function Widget() {
  const client = useAppsClient<AppClientTools>();

  const handleClick = async () => {
    // Tool name "greet" becomes method "callGreet"
    const result = await client.tools.callGreet({ name: "Alice" });
    console.log(result.message);
  };

  return <button onClick={handleClick}>Greet</button>;
}

Method names are generated by prepending "call" and capitalizing the first letter of the tool name (e.g., greetcallGreet, searchRestaurantscallSearchRestaurants).

Host Capabilities & Version

import { useHostCapabilities, useHostVersion } from "@mcp-apps-kit/ui-react";

function Widget() {
  const capabilities = useHostCapabilities();
  const version = useHostVersion();

  // Common capabilities (both platforms)
  const themes = capabilities?.theming?.themes; // ["light", "dark"]
  const modes = capabilities?.displayModes?.modes; // ["inline", "fullscreen", "pip"]

  // MCP Apps specific
  const hasPartialInput = !!capabilities?.partialToolInput;

  // ChatGPT specific
  const hasFileUpload = !!capabilities?.fileUpload;

  // Host version (MCP Apps only)
  // { name: "MCP Host", version: "1.0.0" }
  return <div>Host: {version?.name}</div>;
}

Size Notifications (MCP Apps)

import { useSizeChangedNotifications } from "@mcp-apps-kit/ui-react";

function Widget() {
  // Attach to container to auto-report size changes
  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) => {
    // React to streaming partial input from the model
    console.log("Partial input:", input);
  });

  return <div>Streaming input widget</div>;
}

Theme & Style Hooks

HookDescription
useHostStyleVariablesApply host-provided CSS variables
useDocumentThemeSync document theme with host
useSafeAreaInsetsSafe area insets (ChatGPT)

Lifecycle Hooks

HookDescription
useOnToolCancelledCallback when tool is cancelled
useOnTeardownCleanup callback before widget removal

File Operations (ChatGPT)

HookDescription
useFileUploadUpload files to host
useFileDownloadGet file download URLs

Layout (ChatGPT)

HookDescription
useIntrinsicHeightSet widget intrinsic height
useViewView management

Modals (ChatGPT)

HookDescription
useModalModal dialog management

Contributing

See ../../CONTRIBUTING.md for development setup and guidelines. Issues and pull requests are welcome.

License

MIT

Keywords

mcp

FAQs

Package last updated on 14 Jan 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts