Sandbox
@MCP-UI-Org/mcp-ui

MCP UI SDK for host-rendered tool interfaces

mcp-ui gives you SDKs for creating UI resources on top of MCP tools and rendering them in compatible hosts. It links tools to UI through `_meta.ui.resourceUri`, with client components like `AppRenderer` for MCP Apps hosts and `UIResourceRenderer` for legacy hosts.

5,144 starsโ€ข394 forksโ€ขTypeScriptโ€ขUpdated 2mo ago
Who it's for

Builders who want MCP tools to return interactive UI instead of plain text.

What it delivers

You can attach custom interfaces to tool calls and have supported hosts render them next to the tool result.

What it does

MCP Apps server SDK

`@mcp-ui/server` creates UI resources with `createUIResource` and works with `registerAppTool` and `registerAppResource`.

MCP Apps client renderer

`@mcp-ui/client` renders tool UIs with `AppRenderer` for hosts that support the MCP Apps standard.

Legacy host renderer

`UIResourceRenderer` renders embedded UI resources for older MCP-UI hosts.

Ruby and Python server SDKs

`mcp_ui_server` and `mcp-ui-server` let Ruby and Python servers create UI resources too.

Host adapters

Adapters translate MCP-UI messages to host APIs such as Apps SDK / `window.openai`.

Examples and walkthroughs

The repo includes demo servers and client examples, plus step-by-step docs for TypeScript, Ruby, and Python.

How to get it

  1. 1Run
    # using npm
    npm install @mcp-ui/server @mcp-ui/client
    
    # or pnpm
    pnpm add @mcp-ui/server @mcp-ui/client
    
    # or yarn
    yarn add @mcp-ui/server @mcp-ui/client
  2. 2Run
    gem install mcp_ui_server
  3. 3Run
    # using pip
    pip install mcp-ui-server
    
    # or uv
    uv add mcp-ui-server

README

๐Ÿ“ฆ Model Context Protocol UI SDK

image

Server Version Client Version Ruby Server SDK Version Python Server SDK Version Discord MCP Documentation

What's mcp-ui? โ€ข Core Concepts โ€ข Installation โ€ข Getting Started โ€ข Walkthrough โ€ข Examples โ€ข Supported Hosts โ€ข Security โ€ข Roadmap โ€ข Contributing โ€ข License


mcp-ui pioneered the concept of interactive UI over MCP, enabling rich web interfaces for AI tools. Alongside Apps SDK, the patterns developed here directly influenced the MCP Apps specification, which standardized UI delivery over the protocol.

The @mcp-ui/* packages implement the MCP Apps standard. @mcp-ui/client is the recommended SDK for MCP Apps Hosts.

The @mcp-ui/ packages are fully compliant with the MCP Apps specification and ready for production use.*

๐Ÿ’ก What's mcp-ui?

mcp-ui is an SDK implementing the MCP Apps standard for UI over MCP. It provides:

  • @mcp-ui/server (TypeScript): Create UI resources with createUIResource. Works with registerAppTool and registerAppResource from @modelcontextprotocol/ext-apps/server.
  • @mcp-ui/client (TypeScript): Render tool UIs with AppRenderer (MCP Apps) or UIResourceRenderer (legacy MCP-UI hosts).
  • mcp_ui_server (Ruby): Create UI resources in Ruby.
  • mcp-ui-server (Python): Create UI resources in Python.

The MCP Apps pattern links tools to their UIs via _meta.ui.resourceUri. Hosts fetch and render the UI alongside tool results.

โœจ Core Concepts

MCP Apps Pattern (Recommended)

The MCP Apps standard links tools to their UIs via _meta.ui.resourceUri:

import { registerAppTool, registerAppResource } from '@modelcontextprotocol/ext-apps/server';
import { createUIResource } from '@mcp-ui/server';

// 1. Create UI resource
const widgetUI = await createUIResource({
  uri: 'ui://my-server/widget',
  content: { type: 'rawHtml', htmlString: '<h1>Widget</h1>' },
  encoding: 'text',
});

// 2. Register resource handler
registerAppResource(server, 'widget_ui', widgetUI.resource.uri, {}, async () => ({
  contents: [widgetUI.resource]
}));

// 3. Register tool with _meta linking
registerAppTool(server, 'show_widget', {
  description: 'Show widget',
  inputSchema: { query: z.string() },
  _meta: { ui: { resourceUri: widgetUI.resource.uri } }  // Links tool โ†’ UI
}, async ({ query }) => {
  return { content: [{ type: 'text', text: `Query: ${query}` }] };
});

Hosts detect _meta.ui.resourceUri, fetch the UI via resources/read, and render it with AppRenderer.

UIResource (Wire Format)

The underlying payload for UI content:

interface UIResource {
  type: 'resource';
  resource: {
    uri: string;       // e.g., ui://component/id
    mimeType: 'text/html;profile=mcp-app';
    text?: string;      // HTML content
    blob?: string;      // Base64-encoded HTML content
  };
}
  • uri: Unique identifier using ui:// scheme
  • mimeType: text/html;profile=mcp-app โ€” the MCP Apps standard MIME type
  • text vs. blob: Plain text or Base64-encoded content

Client Components

AppRenderer (MCP Apps)

For MCP Apps hosts, use AppRenderer to render tool UIs:

import { AppRenderer } from '@mcp-ui/client';

function ToolUI({ client, toolName, toolInput, toolResult }) {
  return (
    <AppRenderer
      client={client}
      toolName={toolName}
      sandbox={{ url: sandboxUrl }}
      toolInput={toolInput}
      toolResult={toolResult}
      onOpenLink={async ({ url }) => window.open(url)}
      onMessage={async (params) => console.log('Message:', params)}
    />
  );
}

Key props:

  • client: Optional MCP client for automatic resource fetching
  • toolName: Tool name to render UI for
  • sandbox: Sandbox configuration with proxy URL
  • toolInput / toolResult: Tool arguments and results
  • onOpenLink / onMessage: Handlers for UI requests

UIResourceRenderer (Legacy MCP-UI)

For legacy hosts that embed resources in tool responses:

import { UIResourceRenderer } from '@mcp-ui/client';

<UIResourceRenderer
  resource={mcpResource.resource}
  onUIAction={(action) => console.log('Action:', action)}
/>

Props:

  • resource: Resource object with uri, mimeType, and content (text/blob)
  • onUIAction: Callback for handling tool, prompt, link, notify, and intent actions

Also available as a Web Component:

<ui-resource-renderer
  resource='{ "mimeType": "text/html", "text": "<h2>Hello!</h2>" }'
></ui-resource-renderer>

Supported Resource Types

HTML (text/html;profile=mcp-app)

Rendered using the internal <HTMLResourceRenderer /> component, which displays content inside an <iframe>. This is suitable for self-contained HTML.

  • mimeType: text/html;profile=mcp-app (MCP Apps standard)

UI Action

UI snippets must be able to interact with the agent. In mcp-ui, this is done by hooking into events sent from the UI snippet and reacting to them in the host (see onUIAction prop). For example, an HTML may trigger a tool call when a button is clicked by sending an event which will be caught handled by the client.

Platform Adapters

MCP-UI SDKs includes adapter support for host-specific implementations, enabling your open MCP-UI widgets to work seamlessly regardless of host. Adapters automatically translate between MCP-UI's postMessage protocol and host-specific APIs. Over time, as hosts become compatible with the open spec, these adapters wouldn't be needed.

Available Adapters

Apps SDK Adapter

For Apps SDK environments (e.g., ChatGPT), this adapter translates MCP-UI protocol to Apps SDK API calls (e.g., window.openai).

How it Works:

  • Intercepts MCP-UI postMessage calls from your widgets
  • Translates them to appropriate Apps SDK API calls
  • Handles bidirectional communication (tools, prompts, state management)
  • Works transparently - your existing MCP-UI code continues to work without changes

Usage:

import { createUIResource } from '@mcp-ui/server';

const htmlResource = await createUIResource({
  uri: 'ui://greeting/1',
  content: {
    type: 'rawHtml',
    htmlString: `
      <button onclick="window.parent.postMessage({ type: 'tool', payload: { toolName: 'myTool', params: {} } }, '*')">
        Call Tool
      </button>
    `
  },
  encoding: 'text',
});

๐Ÿ—๏ธ Installation

TypeScript

# using npm
npm install @mcp-ui/server @mcp-ui/client

# or pnpm
pnpm add @mcp-ui/server @mcp-ui/client

# or yarn
yarn add @mcp-ui/server @mcp-ui/client

Ruby

gem install mcp_ui_server

Python

# using pip
pip install mcp-ui-server

# or uv
uv add mcp-ui-server

๐Ÿš€ Getting Started

You can use GitMCP to give your IDE access to mcp-ui's latest documentation!

TypeScript (MCP Apps Pattern)

  1. Server-side: Create a tool with UI using _meta.ui.resourceUri

    import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
    import { registerAppTool, registerAppResource } from '@modelcontextprotocol/ext-apps/server';
    import { createUIResource } from '@mcp-ui/server';
    import { z } from 'zod';
    
    const server = new McpServer({ name: 'my-server', version: '1.0.0' });
    
    // Create UI resource
    const widgetUI = await createUIResource({
      uri: 'ui://my-server/widget',
      content: { type: 'rawHtml', htmlString: '<h1>Interactive Widget</h1>' },
      encoding: 'text',
    });
    
    // Register resource handler
    registerAppResource(server, 'widget_ui', widgetUI.resource.uri, {}, async () => ({
      contents: [widgetUI.resource]
    }));
    
    // Register tool with _meta linking
    registerAppTool(server, 'show_widget', {
      description: 'Show widget',
      inputSchema: { query: z.string() },
      _meta: { ui: { resourceUri: widgetUI.resource.uri } }
    }, async ({ query }) => {
      return { content: [{ type: 'text', text: `Query: ${query}` }] };
    });
    
  2. Client-side: Render tool UIs with AppRenderer

    import { AppRenderer } from '@mcp-ui/client';
    
    function ToolUI({ client, toolName, toolInput, toolResult }) {
      return (
        <AppRenderer
          client={client}
          toolName={toolName}
          sandbox={{ url: sandboxUrl }}
          toolInput={toolInput}
          toolResult={toolResult}
          onOpenLink={async ({ url }) => window.open(url)}
          onMessage={async (params) => console.log('Message:', params)}
        />
      );
    }
    

Legacy MCP-UI Pattern

For hosts that don't support MCP Apps yet:

import { UIResourceRenderer } from '@mcp-ui/client';

<UIResourceRenderer
  resource={mcpResource.resource}
  onUIAction={(action) => console.log('Action:', action)}
/>

Python

Server-side: Build your UI resources

from mcp_ui_server import create_ui_resource

# Inline HTML
html_resource = create_ui_resource({
  "uri": "ui://greeting/1",
  "content": { "type": "rawHtml", "htmlString": "<p>Hello, from Python!</p>" },
  "encoding": "text",
})

# External URL
external_url_resource = create_ui_resource({
  "uri": "ui://greeting/2",
  "content": { "type": "externalUrl", "iframeUrl": "https://example.com" },
  "encoding": "text",
})

Ruby

Server-side: Build your UI resources

require 'mcp_ui_server'

# Inline HTML
html_resource = McpUiServer.create_ui_resource(
  uri: 'ui://greeting/1',
  content: { type: :raw_html, htmlString: '<p>Hello, from Ruby!</p>' },
  encoding: :text
)

# External URL
external_url_resource = McpUiServer.create_ui_resource(
  uri: 'ui://greeting/2',
  content: { type: :external_url, iframeUrl: 'https://example.com' },
  encoding: :text
)

# remote-dom
remote_dom_resource = McpUiServer.create_ui_resource(
  uri: 'ui://remote-component/action-button',
  content: {
    type: :remote_dom,
    script: "
     const button = document.createElement('ui-button');
     button.setAttribute('label', 'Click me from Ruby!');
     button.addEventListener('press', () => {
       window.parent.postMessage({ type: 'tool', payload: { toolName: 'uiInteraction', params: { action: 'button-click', from: 'ruby-remote-dom' } } }, '*');
     });
     root.appendChild(button);
     ",
    framework: :react,
  },
  encoding: :text
)

๐Ÿšถ Walkthrough

For a detailed, simple, step-by-step guide on how to integrate mcp-ui into your own server, check out the full server walkthroughs on the mcp-ui documentation site:

These guides will show you how to add a mcp-ui endpoint to an existing server, create tools that return UI resources, and test your setup with the ui-inspector!

๐ŸŒ Examples

Client Examples

  • Goose - open source AI agent that supports mcp-ui.
  • LibreChat - enhanced ChatGPT clone that supports mcp-ui.
  • ui-inspector - inspect local mcp-ui-enabled servers.
  • MCP-UI Chat - interactive chat built with the mcp-ui client. Check out the hosted version!
  • MCP-UI RemoteDOM Playground (examples/remote-dom-demo) - local demo app to test RemoteDOM resources
  • MCP-UI Web Component Demo (examples/wc-demo) - local demo app to test the Web Component integration in hosts

Server Examples

  • TypeScript: A full-featured server that is deployed to a hosted environment for easy testing.
    • typescript-server-demo: A simple Typescript server that demonstrates how to generate UI resources.
    • server: A full-featured Typescript server that is deployed to a hosted Cloudflare environment for easy testing.
      • HTTP Streaming: https://remote-mcp-server-authless.idosalomon.workers.dev/mcp
      • SSE: https://remote-mcp-server-authless.idosalomon.workers.dev/sse
  • Ruby: A barebones demo server that shows how to use mcp_ui_server and mcp gems together.
  • Python: A simple demo server that shows how to use the mcp-ui-server Python package.
  • XMCP - Typescript MCP framework with mcp-ui starter example.

Drop those URLs into any MCP-compatible host to see mcp-ui in action. For a supported local inspector, see the ui-inspector.

๐Ÿ’ป Supported Hosts

The @mcp-ui/* packages work with both MCP Apps hosts and legacy MCP-UI hosts.

MCP Apps Hosts

These hosts implement the MCP Apps specification and support tools with _meta.ui.resourceUri:

HostNotes
Claudeโœ…
VSCode
Postman
Goose
MCPJam
LibreChat
mcp-use
Smithery

Legacy MCP-UI Hosts

These hosts expect UI resources embedded directly in tool responses:

HostRenderingUI ActionsNotes
Nanobotโœ…โœ…
MCPJamโœ…โœ…
Postmanโœ…โš ๏ธ
Gooseโœ…โš ๏ธ
LibreChatโœ…โš ๏ธ
Smitheryโœ…โŒ
fast-agentโœ…โŒ

Hosts Requiring Adapters

HostProtocolNotes
ChatGPTApps SDKGuide

Legend: โœ… Supported ยท โš ๏ธ Partial ยท โŒ Not yet supported

๐Ÿ”’ Security

Host and user security is one of mcp-ui's primary concerns. In all content types, the remote code is executed in a sandboxed iframe.

๐Ÿ›ฃ๏ธ Roadmap

  • Add online playground
  • Expand UI Action API (beyond tool calls)
  • Support Web Components
  • Support Remote-DOM
  • Add component libraries (in progress)
  • Add SDKs for additional programming languages (in progress; Ruby, Python available)
  • Support additional frontend frameworks
  • Explore providing a UI SDK (in addition to the client and server one)
  • Add declarative UI content type
  • Support generative UI?

Core Team

mcp-ui is a project by Ido Salomon, in collaboration with Liad Yosef.

๐Ÿค Contributing

Contributions, ideas, and bug reports are welcome! See the contribution guidelines to get started.

๐Ÿ“„ License

Apache License 2.0 ยฉ The MCP-UI Authors

Disclaimer

This project is provided "as is", without warranty of any kind. The mcp-ui authors and contributors shall not be held liable for any damages, losses, or issues arising from the use of this software. Use at your own risk.

Files in the repo

Repository payloadโ€ข23 top-level entries
  • .github
  • docs
  • examples
  • sdks
  • .gitignore
  • .prettierignore
  • .prettierrc.json
  • .releaserc.json
  • .ruby-version
  • CHANGELOG.md
  • CODE_OF_CONDUCT.md
  • eslint.config.mjs
  • lefthook.yml
  • LICENSE
  • package-lock.json
  • package.json
  • pnpm-lock.yaml
  • pnpm-workspace.yaml
  • README.md
  • SECURITY.md
  • tsconfig.base.json
  • vitest.config.ts
  • vitest.setup.ts

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More frameworks & sdks

HKUDS/nanobotFrameworks & SDKs

Ultra-lightweight, open-source, self-hosted personal AI agent framework in Python with WebUI, tools, memory, MCP, multi-agent workflows, automation, and chat apps

48k
microsoft/
SkillOpt
microsoft/SkillOptFrameworks & SDKs

SkillOpt is a text-space optimizer that trains reusable natural-language skills for frozen LLM agents through trajectory-driven edits, validation-gated updates, and deployable best_skill.md artifacts.

17k
omnigent-ai/omnigentFrameworks & SDKs

Omnigent is an open-source AI agent framework and meta-harness: orchestrate Claude Code, Codex, Cursor, Pi, and custom agents โ€” swap harnesses without rewriting, enforce policies and sandboxing, and collaborate in real time from any device.

9.8k
kyegomez/
OpenMythos
kyegomez/OpenMythosFrameworks & SDKs

A theoretical reconstruction of the Claude Mythos architecture, built from first principles using the available research literature.

15k
D4Vinci/ScraplingFrameworks & SDKs

๐Ÿ•ท๏ธ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!

80k