Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
2e016cd
feat: add adapters infra (appssdk) (#125)
idosal Oct 10, 2025
d567725
ci: fix alpha release
idosal Oct 10, 2025
8fcc807
chore(release): 5.13.0-alpha.1 [skip ci]\n\n# [5.13.0-alpha.1](https:…
semantic-release-bot Oct 10, 2025
259c842
fix: adapter version
idosal Oct 10, 2025
9730d17
chore(release): 5.13.0-alpha.2 [skip ci]\n\n# [5.13.0-alpha.2](https:…
semantic-release-bot Oct 10, 2025
420efc0
fix: release
idosal Oct 10, 2025
48f9610
chore(release): 1.0.0-alpha.1 [skip ci]
semantic-release-bot Oct 10, 2025
2324371
fix: server versioning
idosal Oct 10, 2025
55a4d67
chore(release): 1.0.0-alpha.2 [skip ci]
semantic-release-bot Oct 10, 2025
368dc29
chore(release): 1.0.0-alpha.1 [skip ci]
semantic-release-bot Oct 10, 2025
7f35d3b
fix: server alpha versioning
idosal Oct 10, 2025
0e1f27e
chore(release): 5.13.0-alpha.1 [skip ci]
semantic-release-bot Oct 10, 2025
46e6589
chore(release): 5.12.0-alpha.1 [skip ci]
semantic-release-bot Oct 10, 2025
bc47423
fix: set the mime type as text/html+skybridge for apps SDK
liady Oct 10, 2025
ca07af1
chore(release): 5.13.0-alpha.2 [skip ci]
semantic-release-bot Oct 10, 2025
addd0ce
chore(release): 5.12.0-alpha.2 [skip ci]
semantic-release-bot Oct 10, 2025
fb3b8c3
ci: fix alpha releases
idosal Oct 10, 2025
4e96596
ci: remove cross-dependencies
idosal Oct 10, 2025
60b8f8c
ci: fix change detection in alpha
idosal Oct 10, 2025
9283cba
ci: fix ref
idosal Oct 11, 2025
207222f
docs: update description
idosal Oct 11, 2025
9299839
fkx: nodenext imports
idosal Oct 11, 2025
767a245
fix: version
idosal Oct 11, 2025
58a2232
chore(release): 5.12.0-alpha.3 [skip ci]\n\n# [5.12.0-alpha.3](https:…
semantic-release-bot Oct 11, 2025
0018c17
fix: exports
idosal Oct 11, 2025
dc67eb6
chore(release): 5.13.0-alpha.3 [skip ci]\n\n# [5.13.0-alpha.3](https:…
semantic-release-bot Oct 11, 2025
b48ec4b
chore(release): 5.12.0-alpha.4 [skip ci]\n\n# [5.12.0-alpha.4](https:…
semantic-release-bot Oct 11, 2025
4de2b0c
fix: exports vite
idosal Oct 12, 2025
c92de61
chore(release): 5.13.0-alpha.4 [skip ci]\n\n# [5.13.0-alpha.4](https:…
semantic-release-bot Oct 12, 2025
0aa2afe
chore(release): 5.12.0-alpha.5 [skip ci]\n\n# [5.12.0-alpha.5](https:…
semantic-release-bot Oct 12, 2025
bdab2df
Potential fix for code scanning alert no. 15: Bad HTML filtering regexp
idosal Oct 13, 2025
ade79d7
ignore generated file
idosal Oct 13, 2025
4b18bc6
ci: fix tests
idosal Oct 13, 2025
5905fd5
refac: simplify types
idosal Oct 13, 2025
36954bb
Update sdks/typescript/server/scripts/bundle-adapter.js
idosal Oct 13, 2025
9fb04b5
tests: fix adapter test setup
idosal Oct 13, 2025
24bb3e5
tests: fix imports
idosal Oct 13, 2025
0eebe72
docs: add apps sdk walkthrough
idosal Oct 13, 2025
325da73
docs: fix docs
idosal Oct 13, 2025
a636844
fix: separate adapter wrappers for flexibility (#128)
idosal Oct 13, 2025
71fc1c0
chore(release): 5.12.0-alpha.6 [skip ci]\n\n# [5.12.0-alpha.6](https:…
semantic-release-bot Oct 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ jobs:
example_files: ${{ steps.filter.outputs.example_files }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: dorny/paths-filter@v2
id: filter
with:
base: ${{ github.event_name == 'push' && github.event.before || github.base_ref }}
filters: |
ts_client_files:
- 'sdks/typescript/client/**'
Expand Down Expand Up @@ -152,6 +155,8 @@ jobs:
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- name: Fetch all tags
run: git fetch --tags --force
- name: Setup pnpm
uses: pnpm/action-setup@v2
with: { version: 10 }
Expand Down Expand Up @@ -184,6 +189,8 @@ jobs:
with: { fetch-depth: 0 }
- name: Pull latest changes
run: git pull --rebase origin ${{ github.ref_name }}
- name: Fetch all tags
run: git fetch --tags --force
- name: Setup pnpm
uses: pnpm/action-setup@v2
with: { version: 10 }
Expand All @@ -201,7 +208,7 @@ jobs:

release_ruby_sdk:
name: Release Ruby SDK
needs: [ruby_sdk_test, release_ts_server, filter_changed_paths]
needs: [ruby_sdk_test, filter_changed_paths, release_ts_server]
if: >
always() &&
(github.ref == 'refs/heads/main' || github.ref == 'refs/heads/alpha') &&
Expand Down Expand Up @@ -244,7 +251,7 @@ jobs:

release_python_sdk:
name: Release Python SDK
needs: [python_sdk_test, release_ruby_sdk, filter_changed_paths]
needs: [python_sdk_test, filter_changed_paths, release_ruby_sdk]
if: >
always() &&
(github.ref == 'refs/heads/main' || github.ref == 'refs/heads/alpha') &&
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,7 @@ __pycache__/

# Husky
.husky/_/
.husky/.gitignore
.husky/.gitignore

# Auto-generated files
adapter-runtime.bundled.ts
78 changes: 77 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

## 💡 What's `mcp-ui`?

`mcp-ui` is a collection of SDKs comprising:
`mcp-ui` is a playground for the open spec of UI over MCP. It offers a collection of community SDKs comprising:

* **`@mcp-ui/server` (TypeScript)**: Utilities to generate UI resources (`UIResource`) on your MCP server.
* **`@mcp-ui/client` (TypeScript)**: UI components (e.g., `<UIResourceRenderer />`) to render the UI resources and handle their events.
Expand Down Expand Up @@ -143,6 +143,82 @@ Rendered using the internal `<RemoteDOMResourceRenderer />` component, which uti

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: `
<button onclick="window.parent.postMessage({ type: 'tool', payload: { toolName: 'myTool', params: {} } }, '*')">
Call Tool
</button>
`
},
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(
'<button>Click me</button>',
{
appsSdk: {
enabled: true,
config: { intentHandling: 'ignore' }
}
}
);

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

## 🏗️ Installation

### TypeScript
Expand Down
85 changes: 85 additions & 0 deletions docs/src/guide/apps-sdk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# OpenAI Apps SDK Integration

The Apps SDK adapter in `@mcp-ui/server` ensures your MCP-UI HTML runs inside ChatGPT. However, for now, you still need to manually wire the resource according to the Apps SDK resource pattern. This guide walks through the manual flow the adapter expects today.

## Why two resources?

- **Static template for Apps SDK** – referenced from your tool descriptor via `_meta["openai/outputTemplate"]`. This version must enable the Apps SDK adapter so ChatGPT injects the bridge script and uses the `text/html+skybridge` MIME type.
- **Embedded resource in tool results** – returned each time your tool runs. This version should *not* enable the adapter so MCP-native hosts continue to receive standard MCP-UI HTML.

## Step-by-step workflow

### 1. Register the Apps SDK template

Use `createUIResource` with `adapters.appsSdk.enabled: true` and expose it through the MCP Resources API so both Apps SDK and traditional MCP hosts can fetch it.

```ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { createUIResource } from '@mcp-ui/server';

const server = new McpServer({ name: 'weather-bot', version: '1.0.0' });
const TEMPLATE_URI = 'ui://widgets/weather';

const appsSdkTemplate = createUIResource({
uri: TEMPLATE_URI,
encoding: 'text',
adapters: {
appsSdk: {
enabled: true,
config: { intentHandling: 'prompt' },
},
},
content: {
type: 'rawHtml',
htmlString: renderInitialShell(),
},
});

server.registerResource(TEMPLATE_URI, async () => appsSdkTemplate.resource);
```

> **Note:** The adapter switches the MIME type to `text/html+skybridge` and injects the Apps bridge script automatically. No extra HTML changes are required.

### 2. Reference the template in your tool descriptor

The Apps SDK looks for `_meta["openai/outputTemplate"]` to know which resource to render. Mirror the rest of the Apps-specific metadata you need (status text, accessibility hints, security schemes, etc.).

```ts
server.registerTool(
'forecast',
{
title: 'Get the forecast',
description: 'Returns a UI that displays the current weather.',
inputSchema: {
type: 'object',
properties: { city: { type: 'string' } },
required: ['city'],
},
_meta: {
'openai/outputTemplate': TEMPLATE_URI,
'openai/toolInvocation/invoking': 'Fetching forecast…',
'openai/toolInvocation/invoked': 'Forecast ready',
'openai/widgetAccessible': true,
},
},
async ({ city }) => {
const forecast = await fetchForecast(city);

// Step 3 happens inside the handler.
return {
content: [
{
type: 'text',
text: `Forecast prepared for ${city}.`,
},
],
structuredContent: {
forecast,
},
};
},
);
```

For the complete list of supported metadata fields, refer to the official documentation. [Apps SDK Reference](https://developers.openai.com/apps-sdk/reference)

1 change: 1 addition & 0 deletions docs/src/guide/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,5 @@ This project is an experimental playground for MCP-UI ideas, that aims to test o
- [Client SDK](./client/overview.md) - Learn to render UI resources
- [Typescript Server SDK](./server/typescript/overview.md) - Learn to create UI resources in Typescript
- [Ruby Server SDK](./server/ruby/overview.md) - Learn to create UI resources in Ruby
- [Apps SDK Integration](./apps-sdk.md) - Wire the existing adapter into ChatGPT's Apps SDK
- [Protocol Details](./protocol-details.md) - Understand the underlying protocol
2 changes: 2 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ hero:
link: /about

features:
- title: 🌐 Open Protocol
details: MCP-UI is an open spec to standardize UI over MCP. Write once, run everywhere!
- title: ⚛️ Client SDK
details: Provides a React component and Web Component for easy frontend integration. Render interactive UI resources and handle UI actions effortlessly.
- title: 🛠️ Server SDKs
Expand Down
Loading