An open API service indexing awesome lists of open source software.

https://github.com/mcp-ui-org/mcp-ui

UI over MCP. Create next-gen UI experiences with the protocol and SDK!
https://github.com/mcp-ui-org/mcp-ui

ai frontend llm mcp ui web

Last synced: 2 days ago
JSON representation

UI over MCP. Create next-gen UI experiences with the protocol and SDK!

Awesome Lists containing this project

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](https://modelcontextprotocol.io/introduction), enabling rich web interfaces for AI tools. Alongside Apps SDK, the patterns developed here directly influenced the [MCP Apps](https://github.com/modelcontextprotocol/ext-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](https://github.com/modelcontextprotocol/ext-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`:

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

// 1. Create UI resource
const widgetUI = createUIResource({
uri: 'ui://my-server/widget',
content: { type: 'rawHtml', htmlString: '

Widget

' },
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:

```ts
interface UIResource {
type: 'resource';
resource: {
uri: string; // e.g., ui://component/id
mimeType: 'text/html' | 'text/uri-list' | 'application/vnd.mcp-ui.remote-dom';
text?: string; // Inline HTML, external URL, or remote-dom script
blob?: string; // Base64-encoded content
};
}
```

* **`uri`**: Unique identifier using `ui://` scheme
* **`mimeType`**: `text/html` for HTML, `text/uri-list` for URLs, `text/html;profile=mcp-app` for MCP Apps
* **`text` vs. `blob`**: Plain text or Base64-encoded content

### Client Components

#### AppRenderer (MCP Apps)

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

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

function ToolUI({ client, toolName, toolInput, toolResult }) {
return (
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:

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

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:
```html

```

### Supported Resource Types

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

Rendered using the internal `` component, which displays content inside an ``. 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:**

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

const htmlResource = createUIResource({
uri: 'ui://greeting/1',
content: {
type: 'rawHtml',
htmlString: `

Call Tool

`
},
encoding: 'text',
// Enable adapters
adapters: {
appsSdk: {
enabled: true,
config: ...
}
// Future adapters can be enabled here
}
});
```

The adapter scripts are automatically injected into your HTML content and handle all protocol translation.

**Supported Actions:**
- โœ… **Tool calls** - `{ type: 'tool', payload: { toolName, params } }`
- โœ… **Prompts** - `{ type: 'prompt', payload: { prompt } }`
- โœ… **Intents** - `{ type: 'intent', payload: { intent, params } }` (converted to prompts)
- โœ… **Notifications** - `{ type: 'notify', payload: { message } }`
- โœ… **Render data** - Access to `toolInput`, `toolOutput`, `widgetState`, `theme`, `locale`
- โš ๏ธ **Links** - `{ type: 'link', payload: { url } }` (may not be supported, returns error in some environments)

#### Advanced Usage

You can manually wrap HTML with adapters or access adapter scripts directly:

```ts
import { wrapHtmlWithAdapters, getAppsSdkAdapterScript } from '@mcp-ui/server';

// Manually wrap HTML with adapters
const wrappedHtml = wrapHtmlWithAdapters(
'Click me',
{
appsSdk: {
enabled: true,
config: { intentHandling: 'ignore' }
}
}
);

// Get a specific adapter script
const appsSdkScript = getAppsSdkAdapterScript({ timeout: 60000 });
```

## ๐Ÿ—๏ธ Installation

### TypeScript

```bash
# 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

```bash
gem install mcp_ui_server
```

### Python

```bash
# using pip
pip install mcp-ui-server

# or uv
uv add mcp-ui-server
```

## ๐Ÿš€ Getting Started

You can use [GitMCP](https://gitmcp.io/idosal/mcp-ui) 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`

```ts
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 = createUIResource({
uri: 'ui://my-server/widget',
content: { type: 'rawHtml', htmlString: '

Interactive Widget

' },
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`

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

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

### Legacy MCP-UI Pattern

For hosts that don't support MCP Apps yet:

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

console.log('Action:', action)}
/>
```

### Python

**Server-side**: Build your UI resources

```python
from mcp_ui_server import create_ui_resource

# Inline HTML
html_resource = create_ui_resource({
"uri": "ui://greeting/1",
"content": { "type": "rawHtml", "htmlString": "

Hello, from Python!

" },
"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

```ruby
require 'mcp_ui_server'

# Inline HTML
html_resource = McpUiServer.create_ui_resource(
uri: 'ui://greeting/1',
content: { type: :raw_html, htmlString: '

Hello, from Ruby!

' },
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](https://mcpui.dev):

- **[TypeScript Server Walkthrough](https://mcpui.dev/guide/server/typescript/walkthrough)**
- **[Ruby Server Walkthrough](https://mcpui.dev/guide/server/ruby/walkthrough)**
- **[Python Server Walkthrough](https://mcpui.dev/guide/server/python/walkthrough)**

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](https://github.com/block/goose) - open source AI agent that supports `mcp-ui`.
* [LibreChat](https://github.com/danny-avila/LibreChat) - enhanced ChatGPT clone that supports `mcp-ui`.
* [ui-inspector](https://github.com/idosal/ui-inspector) - inspect local `mcp-ui`-enabled servers.
* [MCP-UI Chat](https://github.com/idosal/scira-mcp-ui-chat) - interactive chat built with the `mcp-ui` client. Check out the [hosted version](https://scira-mcp-chat-git-main-idosals-projects.vercel.app/)!
* 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](examples/server) that is deployed to a hosted environment for easy testing.
* **[`typescript-server-demo`](./examples/typescript-server-demo)**: A simple Typescript server that demonstrates how to generate UI resources.
* **server**: A [full-featured Typescript server](examples/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](/examples/ruby-server-demo) that shows how to use `mcp_ui_server` and `mcp` gems together.
* **Python**: A simple [demo server](/examples/python-server-demo) that shows how to use the `mcp-ui-server` Python package.
* [XMCP](https://github.com/basementstudio/xmcp/tree/main/examples/mcp-ui) - 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](https://github.com/idosal/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](https://github.com/modelcontextprotocol/ext-apps) and support tools with `_meta.ui.resourceUri`:

| Host | Notes |
| :--- | :---- |
| [Claude](https://www.claude.ai/) | โœ… | โœ… |
| [VSCode](https://github.com/microsoft/vscode/issues/260218) | |
| [Postman](https://www.postman.com/) | |
| [Goose](https://block.github.io/goose/) | |
| [MCPJam](https://www.mcpjam.com/) | |
| [LibreChat](https://www.librechat.ai/) | |
| [mcp-use](https://mcp-use.com/) | |
| [Smithery](https://smithery.ai/playground) | |

### Legacy MCP-UI Hosts

These hosts expect UI resources embedded directly in tool responses:

| Host | Rendering | UI Actions | Notes |
| :--- | :-------: | :--------: | :---- |
| [Nanobot](https://www.nanobot.ai/) | โœ… | โœ… |
| [MCPJam](https://www.mcpjam.com/) | โœ… | โœ… |
| [Postman](https://www.postman.com/) | โœ… | โš ๏ธ | |
| [Goose](https://block.github.io/goose/) | โœ… | โš ๏ธ | |
| [LibreChat](https://www.librechat.ai/) | โœ… | โš ๏ธ | |
| [Smithery](https://smithery.ai/playground) | โœ… | โŒ | |
| [fast-agent](https://fast-agent.ai/mcp/mcp-ui/) | โœ… | โŒ | |

### Hosts Requiring Adapters

| Host | Protocol | Notes |
| :--- | :------: | :---- |
| [ChatGPT](https://chatgpt.com/) | Apps SDK | [Guide](https://mcpui.dev/guide/apps-sdk) |

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

- [X] Add online playground
- [X] Expand UI Action API (beyond tool calls)
- [X] Support Web Components
- [X] 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](https://x.com/idosal1), in collaboration with [Liad Yosef](https://x.com/liadyosef).

## ๐Ÿค Contributing

Contributions, ideas, and bug reports are welcome! See the [contribution guidelines](https://github.com/idosal/mcp-ui/blob/main/.github/CONTRIBUTING.md) to get started.

## ๐Ÿ“„ License

Apache License 2.0 ยฉ [The MCP-UI Authors](LICENSE)

## 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.