Skip to content

Commit 376707e

Browse files
authored
Merge pull request #91 from openai/update-readme
Clean up reference to old "openai.com/widget" and embeddedResource pattern
2 parents e24c445 + 5ef433e commit 376707e

File tree

3 files changed

+22
-28
lines changed

3 files changed

+22
-28
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,23 @@ pnpm run dev
6464

6565
## Serve the static assets
6666

67-
If you want to preview the generated bundles without the MCP servers, start the static file server after running a build:
67+
All of the MCP servers expect the bundled HTML, JS, and CSS to be served from the local static file server. After every build, start the server before launching any MCP processes:
6868

6969
```bash
7070
pnpm run serve
7171
```
7272

7373
The assets are exposed at [`http://localhost:4444`](http://localhost:4444) with CORS enabled so that local tooling (including MCP inspectors) can fetch them.
7474

75+
> **Note:** The Python Pizzaz server caches widget HTML with `functools.lru_cache`. If you rebuild or manually edit files in `assets/`, restart the MCP server so it picks up the updated markup.
76+
7577
## Run the MCP servers
7678

7779
The repository ships several demo MCP servers that highlight different widget bundles:
7880

7981
- **Pizzaz (Node & Python)** – pizza-inspired collection of tools and components
8082
- **Solar system (Python)** – 3D solar system viewer
8183

82-
Every tool response includes plain text content, structured JSON, and `_meta.openai/outputTemplate` metadata so the Apps SDK can hydrate the matching widget.
83-
8484
### Pizzaz Node server
8585

8686
```bash

pizzaz_server_node/src/server.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ function readWidgetHtml(componentName: string): string {
7474
return htmlContents;
7575
}
7676

77-
function widgetMeta(widget: PizzazWidget) {
77+
function widgetDescriptorMeta(widget: PizzazWidget) {
7878
return {
7979
"openai/outputTemplate": widget.templateUri,
8080
"openai/toolInvocation/invoking": widget.invoking,
@@ -84,6 +84,13 @@ function widgetMeta(widget: PizzazWidget) {
8484
} as const;
8585
}
8686

87+
function widgetInvocationMeta(widget: PizzazWidget) {
88+
return {
89+
"openai/toolInvocation/invoking": widget.invoking,
90+
"openai/toolInvocation/invoked": widget.invoked,
91+
} as const;
92+
}
93+
8794
const widgets: PizzazWidget[] = [
8895
{
8996
id: "pizza-map",
@@ -152,7 +159,7 @@ const tools: Tool[] = widgets.map((widget) => ({
152159
description: widget.title,
153160
inputSchema: toolInputSchema,
154161
title: widget.title,
155-
_meta: widgetMeta(widget),
162+
_meta: widgetDescriptorMeta(widget),
156163
// To disable the approval prompt for the widgets
157164
annotations: {
158165
destructiveHint: false,
@@ -166,15 +173,15 @@ const resources: Resource[] = widgets.map((widget) => ({
166173
name: widget.title,
167174
description: `${widget.title} widget markup`,
168175
mimeType: "text/html+skybridge",
169-
_meta: widgetMeta(widget),
176+
_meta: widgetDescriptorMeta(widget),
170177
}));
171178

172179
const resourceTemplates: ResourceTemplate[] = widgets.map((widget) => ({
173180
uriTemplate: widget.templateUri,
174181
name: widget.title,
175182
description: `${widget.title} widget markup`,
176183
mimeType: "text/html+skybridge",
177-
_meta: widgetMeta(widget),
184+
_meta: widgetDescriptorMeta(widget),
178185
}));
179186

180187
function createPizzazServer(): Server {
@@ -213,7 +220,7 @@ function createPizzazServer(): Server {
213220
uri: widget.templateUri,
214221
mimeType: "text/html+skybridge",
215222
text: widget.html,
216-
_meta: widgetMeta(widget),
223+
_meta: widgetDescriptorMeta(widget),
217224
},
218225
],
219226
};
@@ -255,7 +262,7 @@ function createPizzazServer(): Server {
255262
structuredContent: {
256263
pizzaTopping: args.pizzaTopping,
257264
},
258-
_meta: widgetMeta(widget),
265+
_meta: widgetInvocationMeta(widget),
259266
};
260267
}
261268
);

pizzaz_server_python/main.py

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -146,16 +146,11 @@ def _tool_meta(widget: PizzazWidget) -> Dict[str, Any]:
146146
}
147147

148148

149-
def _embedded_widget_resource(widget: PizzazWidget) -> types.EmbeddedResource:
150-
return types.EmbeddedResource(
151-
type="resource",
152-
resource=types.TextResourceContents(
153-
uri=widget.template_uri,
154-
mimeType=MIME_TYPE,
155-
text=widget.html,
156-
title=widget.title,
157-
),
158-
)
149+
def _tool_invocation_meta(widget: PizzazWidget) -> Dict[str, Any]:
150+
return {
151+
"openai/toolInvocation/invoking": widget.invoking,
152+
"openai/toolInvocation/invoked": widget.invoked,
153+
}
159154

160155

161156
@mcp._mcp_server.list_tools()
@@ -262,15 +257,7 @@ async def _call_tool_request(req: types.CallToolRequest) -> types.ServerResult:
262257
)
263258

264259
topping = payload.pizza_topping
265-
widget_resource = _embedded_widget_resource(widget)
266-
meta: Dict[str, Any] = {
267-
"openai.com/widget": widget_resource.model_dump(mode="json"),
268-
"openai/outputTemplate": widget.template_uri,
269-
"openai/toolInvocation/invoking": widget.invoking,
270-
"openai/toolInvocation/invoked": widget.invoked,
271-
"openai/widgetAccessible": True,
272-
"openai/resultCanProduceWidget": True,
273-
}
260+
meta = _tool_invocation_meta(widget)
274261

275262
return types.ServerResult(
276263
types.CallToolResult(

0 commit comments

Comments
 (0)