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-builder

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mcp-apps-kit/ui-react-builder

Build tool for React-based MCP application UIs

latest
Source
npmnpm
Version
0.5.0
Version published
Maintainers
1
Created
Source

@mcp-apps-kit/ui-react-builder

npm node license

Build tool for React-based MCP application UIs.

@mcp-apps-kit/ui-react-builder allows you to define UI resources using React components instead of pre-built HTML files. The framework handles bundling React, ReactDOM, and @mcp-apps-kit/ui-react into self-contained HTML that works with both MCP Apps and ChatGPT.

Table of Contents

Background

Building interactive UI widgets for MCP applications traditionally requires manually bundling React components into self-contained HTML files. This package automates that process, letting you define UIs with React components directly in your tool definitions.

Features

  • defineReactUI() helper for type-safe React component definitions
  • Vite plugin for automatic discovery and building of React UIs
  • AST-based parsing using @typescript-eslint/typescript-estree for reliable detection
  • esbuild-powered bundling to self-contained HTML
  • Auto-generated HTML paths from component names (kebab-case)
  • Global CSS injection support
  • Configurable logging for plugin output
  • Full compatibility with defineTool() from @mcp-apps-kit/core

Compatibility

  • Node.js: >= 18
  • Peer dependencies:
    • @mcp-apps-kit/core ^0.2.0
    • @mcp-apps-kit/ui-react ^0.2.0
    • react and react-dom ^18 || ^19
    • vite ^5 || ^6 || ^7 (optional, for Vite plugin)

Install

npm install @mcp-apps-kit/ui-react-builder

Usage

Quick start

Define your React component:

// src/ui/GreetingWidget.tsx
import { useToolResult, useHostContext } from "@mcp-apps-kit/ui-react";

export function GreetingWidget() {
  const result = useToolResult();
  const { theme } = useHostContext();

  return (
    <div data-theme={theme}>
      <h1>{result?.greet?.message}</h1>
    </div>
  );
}

Use defineReactUI in your tool definition:

// src/index.ts
import { createApp, defineTool } from "@mcp-apps-kit/core";
import { defineReactUI } from "@mcp-apps-kit/ui-react-builder";
import { GreetingWidget } from "./ui/GreetingWidget";
import { z } from "zod";

const app = createApp({
  name: "my-app",
  version: "1.0.0",
  tools: {
    greet: defineTool({
      description: "Greet someone",
      input: z.object({ name: z.string() }),
      output: z.object({ message: z.string() }),
      ui: defineReactUI({
        component: GreetingWidget,
        name: "Greeting Widget",
        prefersBorder: true,
        // Optional: Disable automatic size notifications (default: true)
        // autoResize: false,
      }),
      handler: async ({ name }) => ({
        message: `Hello, ${name}!`,
      }),
    }),
  },
});

Vite Plugin

The Vite plugin automatically discovers defineReactUI calls and builds them into self-contained HTML files.

Configuration

// vite.config.ts
import { defineConfig } from "vite";
import { mcpReactUI } from "@mcp-apps-kit/ui-react-builder/vite";

export default defineConfig({
  plugins: [
    mcpReactUI({
      // Server entry point to scan for defineReactUI calls
      serverEntry: "./src/index.ts",
      // Output directory for built HTML files
      outDir: "./src/ui/dist",
      // Optional: Global CSS to include in all UIs
      globalCss: "./src/ui/styles.css",

      // Optional: Standalone mode takes over the Vite build and outputs only UI HTML.
      // Use this if this Vite config exists solely to build MCP UI widgets.
      // standalone: true,
    }),
  ],
});

How it works

  • The plugin scans your serverEntry file for defineReactUI calls using AST parsing
  • It resolves component imports to their source files
  • Each component is bundled with React, ReactDOM, and @mcp-apps-kit/ui-react
  • Self-contained HTML files are written to outDir

The plugin uses @typescript-eslint/typescript-estree for reliable AST-based detection of imports and defineReactUI calls. This is more robust than regex-based parsing and correctly handles:

  • Nested defineReactUI calls (e.g., inside defineTool)
  • Comments around definitions
  • Various import styles (named, default, aliased)
  • Complex code structures (conditionals, arrays, objects)

Supported patterns

The plugin discovers defineReactUI calls using static analysis. For reliable detection:

  • Import components directly from their source files:
    import { MyWidget } from "./ui/MyWidget"; // ✓ Works
    import { MyWidget } from "./ui"; // ✗ Barrel imports not supported
    
  • Use string literals for the name property:
    name: "My Widget"; // ✓ Works
    name: `My ${type}`; // ✗ Template literals not supported
    
  • Reference components by identifier:
    component: MyWidget; // ✓ Works
    component: widgets.MyWidget; // ✗ Property access not supported
    

If you need patterns not supported by auto-discovery, use defineUI({ html: "..." }) with manual Vite bundling.

Build commands

{
  "scripts": {
    "dev": "concurrently \"pnpm dev:server\" \"pnpm dev:ui\"",
    "dev:server": "tsx watch src/index.ts",
    "dev:ui": "vite build --watch",
    "build": "pnpm build:ui && tsc",
    "build:ui": "vite build"
  }
}

API

Definition Helpers

ExportDescription
defineReactUIDefine a UI using a React component
isReactUIDefType guard to check if a value is a ReactUIDef

defineReactUI Options

OptionTypeDefaultDescription
componentComponentType(required)React component to render
namestring(required)Display name for the UI
descriptionstring-Description of the UI widget
prefersBorderboolean-Hint to the host whether a border should be drawn
autoResizebooleantrueEnable automatic size change notifications. Only supported in MCP Apps; ignored in ChatGPT.
cspCSPConfig-Content Security Policy configuration (ChatGPT only)

Types

TypeDescription
ReactUIInputInput type for defineReactUI()
ReactUIDefOutput type (extends UIDef from core)
BuildOptionsOptions for the build process
BuildResultResult of building React UIs
PluginLoggerLogger interface for Vite plugin

Build Functions

ExportDescription
buildReactUIsBuild multiple React UIs to HTML
buildReactUIBuild a single React UI to HTML

Note: The programmatic build functions (buildReactUIs, buildReactUI) serialize components using .toString(), which has limitations:

  • No external imports (components cannot import other modules)
  • No closures (components that capture external variables won't work)
  • Simple components only (best for self-contained components)

For production use, prefer the Vite plugin which uses file paths for proper import resolution.

Transform Utilities

ExportDescription
transformToCoreDefsConvert ReactUIDefs to standard UIDefs
transformSingleToCoreDefConvert a single ReactUIDef to UIDef
extractReactUIsSeparate React UIs from standard UIs
buildAndTransformBuild and transform in one step

HTML Utilities

ExportDescription
generateHTMLGenerate HTML document from bundled JS
generateEntryPointGenerate React entry point code

Vite Plugin

import { mcpReactUI } from "@mcp-apps-kit/ui-react-builder/vite";
OptionTypeDefaultDescription
serverEntrystring(required)Server entry point to scan
outDirstring"./dist/ui"Output directory for HTML files
minifybooleantrue in prodMinify output JavaScript
globalCssstring-Path to global CSS file
loggerPluginLogger | falseconsoleCustom logger or false to disable logging
standalonebooleanfalseTake over Vite build (emit only UI HTML)

Custom logging

// Disable all logging
mcpReactUI({
  serverEntry: "./src/index.ts",
  logger: false,
});

// Custom logger
mcpReactUI({
  serverEntry: "./src/index.ts",
  logger: {
    info: (msg) => myLogger.info(msg),
    warn: (msg) => myLogger.warn(msg),
    error: (msg) => myLogger.error(msg),
  },
});

Examples

  • ../../examples/minimal - Simple hello world with React UI

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