Skip to content

Commit 459c9a7

Browse files
Merge pull request #505 from basementstudio/canary
v0.6.5
2 parents 8474421 + 500caad commit 459c9a7

File tree

80 files changed

+515
-1686
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+515
-1686
lines changed

apps/website/app/api/og/[...path]/route.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,11 @@ function resolveOgContent(
162162
return {
163163
ok: true,
164164
content: {
165-
title: "Shaping the future of MCP tooling",
165+
title: "Examples & templates",
166166
description:
167-
"xmcp now supports building compatible UI resources and tools with the OpenAI Apps SDK, out of the box.",
167+
"Quickstart with xmcp using real-world examples and best practices.",
168168
summary: undefined,
169-
date: "2025-12-11",
169+
date: undefined,
170170
},
171171
};
172172
}

apps/website/content/blog/apps-sdk.mdx

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,19 @@ previewImage: "/blog/apps-sdk.png"
1010
xmcp now supports building and serving UI resources compatible with OpenAI's Apps SDK. Get started by running:
1111

1212
```bash
13-
npx create-xmcp-app --gpt
13+
npx create-xmcp-app@latest
1414
```
1515

1616
<Video
1717
src="https://j2fbnka41vq9pfap.public.blob.vercel-storage.com/videos/gpt-apps-2.mp4"
1818
controls
1919
/>
2020

21-
The `--gpt` flag scaffolds a project with the necessary files and dependencies to get you up and running quickly.
21+
<Callout variant="warning">
22+
OpenAI now supports MCP Apps. This post contains legacy context, so older
23+
syntax examples may be outdated. New projects should use the MCP App template
24+
and `_meta.ui` metadata.
25+
</Callout>
2226

2327
Once your project is set up, you'll find two main folders. The prompts folder is excluded from this template by default, but you can easily enable it by modifying the `xmcp.config.ts` file.
2428

@@ -52,42 +56,40 @@ For more information on constructing resource URIs, check out the [resources doc
5256

5357
This folder contains your tools, which interact with and retrieve your UI resources.
5458

55-
The `ToolMetadata` includes a `_meta` property for adding Apps SDK-specific metadata, enabling your resources to be displayed within widgets.
59+
The `ToolMetadata` includes a `_meta.ui` property for MCP Apps metadata, enabling your resources to be displayed within widgets.
5660

5761
Available metadata keys:
5862

59-
- `openai/outputTemplate`: Points to your resource URI template (required for discoverability)
60-
- `openai/widgetAccessible`: Boolean indicating if the resource is accessible within a widget
61-
- `openai/resultCanProduceWidget`: Boolean indicating if the tool result can produce a widget
62-
- `openai/widgetDescription`: Description displayed to the model when a client renders the component
63-
- `openai/widgetPrefersBorder`: Enables border rendering for widgets better suited to a "Card" layout
63+
- `ui.csp.connectDomains`: Origins allowed for fetch/XHR/WebSocket calls
64+
- `ui.csp.resourceDomains`: Origins for images, scripts, stylesheets, and media
65+
- `ui.domain`: Optional dedicated subdomain for your widget sandbox origin
66+
- `ui.prefersBorder`: Requests a bordered card layout for widgets
6467

6568
```typescript
6669
import { type ToolMetadata } from "xmcp";
6770

68-
const widgetMeta = {
69-
"openai/outputTemplate": "ui://widget/your-ui-resource.html",
70-
"openai/widgetAccessible": true,
71-
"openai/resultCanProduceWidget": true,
72-
};
73-
7471
export const metadata: ToolMetadata = {
7572
name: "get-your-ui-resource",
7673
description: "Show Your UI Resource",
7774
_meta: {
78-
...widgetMeta,
75+
ui: {
76+
csp: {
77+
connectDomains: ["https://api.example.com"],
78+
resourceDomains: ["https://cdn.example.com"],
79+
}
80+
},
7981
},
8082
};
8183

8284
export default async function handler() {
8385
return {
84-
_meta: widgetMeta, // Required: return metadata in the response
86+
content: [{ type: "text", text: "Widget ready" }],
8587
};
8688
}
8789
```
8890

89-
If you're not returning content in the response, you can omit the `content` array property and simply return the widget metadata.
91+
If you don't need CSP or rendering hints, you can omit `_meta.ui` entirely.
9092

9193
## References
9294

93-
For more details, see the [OpenAI Apps SDK documentation](https://developers.openai.com/apps-sdk). You can test your resources and tools using [MCPJam](https://mcpjam.com), an open source MCP inspector.
95+
For more details, see the [MCP Apps docs](https://modelcontextprotocol.github.io/ext-apps/api/) and [OpenAI Apps SDK docs](https://developers.openai.com/apps-sdk). You can test your resources and tools using [MCPJam](https://mcpjam.com), an open source MCP inspector.

apps/website/content/blog/build-and-submit-gpt-apps.mdx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ Learn how to submit your ChatGPT App to the OpenAI directory. We'll cover everyt
1717
build guide [here](/blog/doom-with-xmcp).
1818
</Callout>
1919

20+
<Callout variant="warning">
21+
OpenAI now supports MCP Apps. Some legacy syntax you may see in older guides
22+
can be outdated, so prefer the current MCP Apps metadata format (`_meta.ui`)
23+
in your implementation.
24+
</Callout>
25+
2026
## First steps
2127

2228
If you don't have your assets ready, this is the moment to prepare them. The checklist includes:
@@ -52,7 +58,7 @@ You will need to explain why each permission is needed or not. Be specific about
5258

5359
Next, you will need to verify your domain by serving the token provided by OpenAI at the path `/.well-known/openai-apps-challenge`.
5460

55-
If you're using xmcp standalone mode, this route is automatically generated for you after setting the `OPENAI-APPS-VERIFICATION-TOKEN` environment variable. If you're using adapter mode, you'll need to create it manually.
61+
If you're using xmcp standalone mode, this route is automatically generated for you after setting the `OPENAI_APPS_VERIFICATION_TOKEN` environment variable. If you're using adapter mode, you'll need to create it manually.
5662

5763
## Testing
5864

apps/website/content/docs/core-concepts/css.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: CSS
33
description: Style your xmcp tools with Tailwind CSS, CSS, or CSS Modules
44
---
55

6-
If you're using [ChatGPT widgets](/docs/core-concepts/tools#openai-metadata) or [MCP Apps](/docs/core-concepts/tools#mcp-apps-metadata), xmcp provides your application multiple ways to use CSS:
6+
If you're using [MCP Apps](/docs/core-concepts/tools#mcp-apps-metadata), xmcp provides your application multiple ways to use CSS:
77

88
- [Tailwind CSS](#tailwind-css)
99
- [CSS](#css)

apps/website/content/docs/core-concepts/tools.mdx

Lines changed: 9 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -177,55 +177,11 @@ annotations: {
177177
about when and how to call your tools, but they don't enforce any behavior.
178178
</Callout>
179179

180-
### OpenAI Metadata
181-
182-
For ChatGPT widget integration, add OpenAI-specific metadata under `_meta.openai`:
183-
184-
```typescript
185-
export const metadata: ToolMetadata = {
186-
name: "show-analytics",
187-
description: "Display analytics dashboard",
188-
_meta: {
189-
openai: {
190-
// Tool-specific
191-
widgetAccessible: true,
192-
toolInvocation: {
193-
invoking: "Loading analytics...",
194-
invoked: "Dashboard ready!",
195-
},
196-
197-
// Resource-specific (for auto-generated widgets)
198-
widgetDescription: "Real-time analytics dashboard",
199-
widgetPrefersBorder: true,
200-
widgetCSP: {
201-
connect_domains: ["https://api.analytics.com"],
202-
resource_domains: ["https://cdn.analytics.com"],
203-
},
204-
},
205-
},
206-
};
207-
```
208-
209-
**Tool-specific properties:**
210-
211-
- `widgetAccessible` - Enable widget-to-tool communication (required for widgets)
212-
- `toolInvocation.invoking` - Message shown while executing (≤64 chars)
213-
- `toolInvocation.invoked` - Message shown after completion (≤64 chars)
214-
- `outputTemplate` - Custom widget URI (auto-generated if not provided)
215-
216-
**Resource-specific properties:**
217-
218-
- `widgetDescription` - Human-readable widget summary
219-
- `widgetPrefersBorder` - UI rendering hint for borders
220-
- `widgetCSP` - Content Security Policy for external resources
221-
- `widgetDomain` - Optional dedicated subdomain
222-
- `widgetState` - Initial state object passed to widget
223-
224180
### MCP Apps metadata
225181

226182
<Callout variant="info">
227-
Unlike OpenAI widgets, MCP Apps do not require specific metadata
228-
configuration. Widgets work automatically without additional setup.
183+
MCP Apps widgets work automatically for React tools. Add `ui` metadata only
184+
when you need CSP or rendering hints.
229185
</Callout>
230186

231187
```typescript
@@ -300,9 +256,8 @@ export default async function calculate({
300256

301257
### 2. Template Literal Handlers
302258

303-
Return HTML directly to create interactive widgets in ChatGPT. When you return HTML and include OpenAI metadata, xmcp automatically generates a widget resource.
304-
305-
To enable widgets, you need to add the `_meta.openai` configuration in your metadata with `widgetAccessible: true`.
259+
Return HTML directly to create interactive widgets. xmcp automatically generates
260+
the widget resource.
306261

307262
```typescript title="src/tools/show-chart.ts"
308263
import { type ToolMetadata } from "xmcp";
@@ -311,11 +266,9 @@ export const metadata: ToolMetadata = {
311266
name: "show-chart",
312267
description: "Display an interactive chart",
313268
_meta: {
314-
openai: {
315-
widgetAccessible: true,
316-
toolInvocation: {
317-
invoking: "Loading chart...",
318-
invoked: "Chart loaded!",
269+
ui: {
270+
csp: {
271+
resourceDomains: ["https://cdn.jsdelivr.net"],
319272
},
320273
},
321274
},
@@ -339,8 +292,6 @@ export default async function showChart() {
339292

340293
Return React components for interactive, composable widgets. xmcp renders the component to HTML and generates a widget resource automatically.
341294

342-
To enable widgets, you need to add the `_meta.openai` configuration in your metadata with `widgetAccessible: true`.
343-
344295
```typescript title="src/tools/interactive-todo.tsx"
345296
import { type ToolMetadata } from "xmcp";
346297
import { useState } from "react";
@@ -349,12 +300,8 @@ export const metadata: ToolMetadata = {
349300
name: "interactive-todo",
350301
description: "Interactive todo list widget",
351302
_meta: {
352-
openai: {
353-
widgetAccessible: true,
354-
toolInvocation: {
355-
invoking: "Loading todo list...",
356-
invoked: "Todo list ready!",
357-
},
303+
ui: {
304+
prefersBorder: true,
358305
},
359306
},
360307
};

apps/website/content/docs/getting-started/installation.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ On installation, you'll see the following prompts:
2727

2828
<TerminalPrompt>
2929
{
30-
"? What is your project named? (my-xmcp-app)\n? Select a template: (Use arrow keys)\n❯ Default (Standard MCP server)\n GPT App (ChatGPT/OpenAI widgets)\n MCP App (React widgets for ext-apps)"
30+
"? What is your project named? (my-xmcp-app)\n? Select a template: (Use arrow keys)\n❯ Default (Standard MCP server)\n MCP App (React widgets for ext-apps)"
3131
}
3232
</TerminalPrompt>
3333

34-
You can also skip prompts using flags: `--gpt` (GPT App), `--ui` (MCP App), `--tailwind` or `--tw` (Tailwind CSS). Run `npx create-xmcp-app --help` for all options.
34+
You can use `--ui` to scaffold the MCP App template (non-tailwind), or use `--tailwind` / `--tw` when selecting the MCP App template interactively. Run `npx create-xmcp-app --help` for all options.
3535

3636
<TerminalPrompt>
3737
{

examples/ext-apps/src/tools/counter.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export const metadata: ToolMetadata = {
88
};
99

1010
export const schema = {
11-
initialCount: z.number().describe("The name of the user to greet"),
11+
initialCount: z.number().describe("The initial count value"),
1212
};
1313

1414
export default function handler({ initialCount }: InferSchema<typeof schema>) {
File renamed without changes.

examples/open-ai-react-css-modules/package.json renamed to examples/mcp-app-css-modules/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
"name": "ChatGPT React CSS Modules",
3-
"description": "Learn how to set up an xmcp server using ChatGPT widgets using React + CSS modules and single tool handlers",
2+
"name": "MCP App React CSS Modules",
3+
"description": "Learn how to set up an xmcp server using MCP app widgets with React + CSS modules and single tool handlers",
44
"keywords": [
5-
"chatgpt"
5+
"mcp-app"
66
],
77
"scripts": {
88
"build": "xmcp build",

examples/open-ai-react-css-modules/src/tools/counter.module.css renamed to examples/mcp-app-css-modules/src/tools/counter.module.css

File renamed without changes.

0 commit comments

Comments
 (0)