skybridge 0.0.0-dev.e0ede01 → 0.0.0-dev.e1b8fe1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +64 -361
  2. package/dist/src/server/index.d.ts +2 -2
  3. package/dist/src/server/index.js.map +1 -1
  4. package/dist/src/server/server.d.ts +22 -13
  5. package/dist/src/server/server.js +4 -4
  6. package/dist/src/server/server.js.map +1 -1
  7. package/dist/src/server/templateHelper.js +2 -2
  8. package/dist/src/server/templateHelper.js.map +1 -1
  9. package/dist/src/server/widgetsDevServer.js +3 -3
  10. package/dist/src/server/widgetsDevServer.js.map +1 -1
  11. package/dist/src/test/utils.d.ts +1 -1
  12. package/dist/src/test/utils.js +8 -8
  13. package/dist/src/test/utils.js.map +1 -1
  14. package/dist/src/test/widget.test.js +19 -20
  15. package/dist/src/test/widget.test.js.map +1 -1
  16. package/dist/src/web/create-store.js +3 -77
  17. package/dist/src/web/create-store.js.map +1 -1
  18. package/dist/src/web/create-store.test.d.ts +1 -0
  19. package/dist/src/web/create-store.test.js +70 -0
  20. package/dist/src/web/create-store.test.js.map +1 -0
  21. package/dist/src/web/data-llm.d.ts +1 -0
  22. package/dist/src/web/data-llm.js +4 -3
  23. package/dist/src/web/data-llm.js.map +1 -1
  24. package/dist/src/web/data-llm.test.js.map +1 -1
  25. package/dist/src/web/generate-helpers.d.ts +3 -3
  26. package/dist/src/web/generate-helpers.js.map +1 -1
  27. package/dist/src/web/generate-helpers.test-d.js +3 -2
  28. package/dist/src/web/generate-helpers.test-d.js.map +1 -1
  29. package/dist/src/web/generate-helpers.test.js +1 -1
  30. package/dist/src/web/generate-helpers.test.js.map +1 -1
  31. package/dist/src/web/helpers/state.d.ts +7 -0
  32. package/dist/src/web/helpers/state.js +40 -0
  33. package/dist/src/web/helpers/state.js.map +1 -0
  34. package/dist/src/web/helpers/state.test.d.ts +1 -0
  35. package/dist/src/web/helpers/state.test.js +53 -0
  36. package/dist/src/web/helpers/state.test.js.map +1 -0
  37. package/dist/src/web/hooks/index.d.ts +2 -2
  38. package/dist/src/web/hooks/index.js +1 -1
  39. package/dist/src/web/hooks/index.js.map +1 -1
  40. package/dist/src/web/hooks/use-call-tool.js.map +1 -1
  41. package/dist/src/web/hooks/use-call-tool.test-d.js +1 -1
  42. package/dist/src/web/hooks/use-call-tool.test-d.js.map +1 -1
  43. package/dist/src/web/hooks/use-call-tool.test.js +1 -1
  44. package/dist/src/web/hooks/use-call-tool.test.js.map +1 -1
  45. package/dist/src/web/hooks/use-display-mode.js.map +1 -1
  46. package/dist/src/web/hooks/use-display-mode.test.js +2 -2
  47. package/dist/src/web/hooks/use-display-mode.test.js.map +1 -1
  48. package/dist/src/web/hooks/use-files.test.js +1 -1
  49. package/dist/src/web/hooks/use-files.test.js.map +1 -1
  50. package/dist/src/web/hooks/use-locale.test.js +2 -2
  51. package/dist/src/web/hooks/use-locale.test.js.map +1 -1
  52. package/dist/src/web/hooks/use-open-external.test.js +2 -2
  53. package/dist/src/web/hooks/use-open-external.test.js.map +1 -1
  54. package/dist/src/web/hooks/use-openai-global.d.ts +2 -2
  55. package/dist/src/web/hooks/use-openai-global.js +1 -1
  56. package/dist/src/web/hooks/use-openai-global.js.map +1 -1
  57. package/dist/src/web/hooks/use-request-modal.test.js +2 -2
  58. package/dist/src/web/hooks/use-request-modal.test.js.map +1 -1
  59. package/dist/src/web/hooks/use-theme.test.js +2 -2
  60. package/dist/src/web/hooks/use-theme.test.js.map +1 -1
  61. package/dist/src/web/hooks/use-tool-info.js +1 -1
  62. package/dist/src/web/hooks/use-tool-info.js.map +1 -1
  63. package/dist/src/web/hooks/use-tool-info.test-d.js +0 -1
  64. package/dist/src/web/hooks/use-tool-info.test-d.js.map +1 -1
  65. package/dist/src/web/hooks/use-tool-info.test.js +2 -2
  66. package/dist/src/web/hooks/use-tool-info.test.js.map +1 -1
  67. package/dist/src/web/hooks/use-user-agent.test.js +2 -2
  68. package/dist/src/web/hooks/use-user-agent.test.js.map +1 -1
  69. package/dist/src/web/hooks/use-widget-state.js +3 -25
  70. package/dist/src/web/hooks/use-widget-state.js.map +1 -1
  71. package/dist/src/web/hooks/use-widget-state.test.js +2 -2
  72. package/dist/src/web/hooks/use-widget-state.test.js.map +1 -1
  73. package/dist/src/web/index.d.ts +4 -4
  74. package/dist/src/web/index.js +4 -4
  75. package/dist/src/web/index.js.map +1 -1
  76. package/dist/src/web/proxy.js +1 -1
  77. package/dist/src/web/proxy.js.map +1 -1
  78. package/dist/src/web/types.d.ts +5 -5
  79. package/package.json +10 -5
package/README.md CHANGED
@@ -1,417 +1,120 @@
1
1
  <div align="center">
2
2
 
3
- # Skybridge
3
+ <img alt="Skybridge" src="docs/static/img/logo.png" width="280">
4
4
 
5
- **Skybridge is the TypeScript framework for building ChatGPT apps**
5
+ <br />
6
6
 
7
- [![By Alpic](https://img.shields.io/badge/Made%20by%20Alpic-f6ffed?logo=alpic)](https://alpic.ai)
7
+ ### Build ChatGPT Apps. The Modern TypeScript Way.
8
8
 
9
- ![NPM Downloads](https://img.shields.io/npm/dm/skybridge?color=e90060)
10
- ![NPM Version](https://img.shields.io/npm/v/skybridge?color=e90060)
11
- ![GitHub License](https://img.shields.io/github/license/alpic-ai/skybridge?color=e90060)
9
+ Interactive widgets that live inside ChatGPT conversations.<br />
10
+ **Type-safe. React-powered. Zero config.**
12
11
 
13
- </div>
14
-
15
- Skybridge comes with 2 packages:
16
-
17
- - `skybridge/server`: A drop-in replacement of the `@modelcontextprotocol/sdk` official `McpServer` class with extra features for widget development.
18
- - `skybridge/web`: A react library with hooks and components to build widgets on the underlying _OpenAI iFrame skybridge_ runtime.
19
-
20
- ## Quick start
12
+ <br />
21
13
 
22
- To get started in less than a minute, you can [create a new repository](https://github.com/new?template_name=apps-sdk-template&template_owner=alpic-ai) using our [ChatGPT SDK template](https://github.com/alpic-ai/apps-sdk-template). This template includes a basic setup for both the server and the widgets.
14
+ [![NPM Version](https://img.shields.io/npm/v/skybridge?color=e90060&style=for-the-badge)](https://www.npmjs.com/package/skybridge)
15
+ [![NPM Downloads](https://img.shields.io/npm/dm/skybridge?color=e90060&style=for-the-badge)](https://www.npmjs.com/package/skybridge)
16
+ [![GitHub License](https://img.shields.io/github/license/alpic-ai/skybridge?color=e90060&style=for-the-badge)](https://github.com/alpic-ai/skybridge/blob/main/LICENSE)
23
17
 
24
- ## Installation
25
-
26
- ```bash
27
- pnpm add skybridge
28
- ```
18
+ <br />
29
19
 
30
- ## Concepts
20
+ [Documentation](https://skybridge.tech) · [Quick Start](https://github.com/new?template_name=apps-sdk-template&template_owner=alpic-ai) · [Examples](https://github.com/alpic-ai/apps-sdk-template)
31
21
 
32
- ### Widgets
22
+ </div>
33
23
 
34
- > A widget is a UI component that turns structured tool results into a human-friendly UI. Those are built using React components. They are rendered inside an iframe inline with the conversation on ChatGPT.
24
+ <br />
35
25
 
36
- Each widget in your app must have a unique name. The name is used to bridge the tool invocation result with the widget React component.
26
+ ## Why Skybridge?
37
27
 
38
- For example, in order to register a new widget named `pokemon` on your ChatGPT app. You should have the following file structure and file contents:
28
+ ChatGPT Apps let you embed **rich, interactive UIs** directly in conversations. But the raw SDK is low-level—no hooks, no type safety, no dev tools, and no HMR.
39
29
 
40
- _Project structure_
30
+ **Skybridge fixes that.**
41
31
 
42
- ```
43
- server/
44
- └── src/
45
- └── index.ts // Register the widget with McpServer.widget()
46
- web/
47
- └── src/
48
- └── widgets/
49
- └── pokemon.tsx // Use the same widget name as the file name
50
- ```
32
+ | | |
33
+ |:--|:--|
34
+ | 👨‍💻 **Full Dev Environment** — HMR, debug traces, and local emulator. No more refresh loops. | ✅ **End-to-End Type Safety** — tRPC-style inference from server to widget. Autocomplete everywhere. |
35
+ | 🔄 **Widget-to-Model Sync** — Keep the model aware of UI state with `data-llm`. Dual surfaces, one source of truth. | ⚒️ **React Query-style Hooks** — `isPending`, `isError`, callbacks. State management you already know. |
51
36
 
52
- _server/src/index.ts_
37
+ <br />
53
38
 
54
- ```ts
55
- import { McpServer } from "skybridge/server";
39
+ ## 🚀 Get Started
56
40
 
57
- const server = new McpServer();
41
+ **Create a new ChatGPT app:**
58
42
 
59
- server.widget(
60
- "pokemon"
61
- // Remaining arguments...
62
- );
63
- ```
64
-
65
- _web/src/widgets/pokemon.tsx_
66
-
67
- ```ts
68
- import { mountWidget } from "skybridge/web";
69
-
70
- const Pokemon: React.FunctionComponent = () => {
71
- // Your React component code goes here...
72
- };
73
-
74
- mountWidget(<Pokemon />);
43
+ ```bash
44
+ gh repo create my-app --template alpic-ai/apps-sdk-template --clone
45
+ cd my-app && pnpm install
75
46
  ```
76
47
 
77
- ## Packages
78
-
79
- ### skybridge/server
80
-
81
- The `skybridge/server` package is a drop-in replacement of the `@modelcontextprotocol/sdk` official `McpServer` class with extra features for widget development. If you're already using the `@modelcontextprotocol/sdk`, you can simply replace your `McpServer` import with `skybridge/server` and you're good to go.
82
-
83
- ### skybridge/web
84
-
85
- The `skybridge/web` package is a react library with hooks and components to build widgets on the underlying _OpenAI iFrame skybridge_ runtime.
86
-
87
- **Vite plugin**
88
-
89
- The `skybridge/web` package comes with a Vite plugin that allows you to build your widgets as regular Vite apps.
90
-
91
- ```ts
92
- import { defineConfig } from "vite";
93
- import { skybridge } from "skybridge/web";
48
+ **Or add to an existing project:**
94
49
 
95
- export default defineConfig({
96
- plugins: [skybridge()],
97
- });
50
+ ```bash
51
+ pnpm add skybridge
98
52
  ```
99
53
 
100
- **Typed Hooks**
101
-
102
- Skybridge provides fully typed hooks that give you autocomplete for tool names and type inference for inputs/outputs - similar to tRPC. This is opt-in and requires exporting your server type.
54
+ <div align="center">
103
55
 
104
- > **Tip:** For the best TypeScript experience, use typed hooks throughout your application. They provide autocomplete, type safety, and better IDE support.
56
+ ### 👉 [Read the Docs](https://skybridge.tech) 👈
105
57
 
106
- > **Important:** For `generateHelpers` to work correctly, your MCP server must be defined using method chaining (e.g., `server.widget(...).widget(...).registerTool(...)`). This ensures TypeScript can properly infer the tool registry type from the chained calls.
58
+ </div>
107
59
 
108
- **Examples:**
60
+ <br />
109
61
 
110
- **Works** - Using method chaining:
62
+ ## 📦 The Stack
111
63
 
112
- ```ts
113
- import { McpServer } from "skybridge/server";
114
- import { z } from "zod";
115
-
116
- const server = new McpServer({ name: "my-app", version: "1.0" }, {})
117
- .widget("search-voyage", {}, {
118
- inputSchema: { destination: z.string() },
119
- }, async ({ destination }) => {
120
- return { content: [{ type: "text", text: `Found trips to ${destination}` }] };
121
- })
122
- .registerTool("calculate-price", {
123
- inputSchema: { tripId: z.string() },
124
- }, async ({ tripId }) => {
125
- return { content: [{ type: "text", text: `Price for ${tripId}` }] };
126
- });
127
-
128
- export type AppType = typeof server; // ✅ Type inference works correctly
129
- ```
64
+ - **`skybridge/server`** — Drop-in MCP SDK replacement with widget registration and type inference.
65
+ - **`skybridge/web`** React hooks and components for ChatGPT's iframe environment.
66
+ - **Vite Plugin** HMR and optimized builds for local and production.
130
67
 
131
- **Doesn't work** - Without method chaining:
68
+ ### Server
132
69
 
133
70
  ```ts
134
71
  import { McpServer } from "skybridge/server";
135
- import { z } from "zod";
136
-
137
- const server = new McpServer({ name: "my-app", version: "1.0" }, {});
138
72
 
139
- server.widget("search-voyage", {}, {
73
+ server.registerWidget("flights", {}, {
140
74
  inputSchema: { destination: z.string() },
141
75
  }, async ({ destination }) => {
142
- return { content: [{ type: "text", text: `Found trips to ${destination}` }] };
76
+ const flights = await searchFlights(destination);
77
+ return { structuredContent: { flights } };
143
78
  });
144
-
145
- server.registerTool("calculate-price", {
146
- inputSchema: { tripId: z.string() },
147
- }, async ({ tripId }) => {
148
- return { content: [{ type: "text", text: `Price for ${tripId}` }] };
149
- });
150
-
151
- export type AppType = typeof server; // ❌ Type inference fails - tool registry is empty
152
79
  ```
153
80
 
154
- _Server setup (server/src/index.ts)_
155
-
156
- ```ts
157
- import { McpServer } from "skybridge/server";
158
- import { z } from "zod";
159
-
160
- const server = new McpServer({ name: "my-app", version: "1.0" }, {})
161
- .widget("search-voyage", {}, {
162
- description: "Search for trips",
163
- inputSchema: {
164
- destination: z.string(),
165
- departureDate: z.string().optional(),
166
- },
167
- outputSchema: {
168
- results: z.array(z.object({ id: z.string(), name: z.string() })),
169
- totalCount: z.number(),
170
- },
171
- }, async ({ destination }) => {
172
- // Your tool logic here...
173
- return { content: [{ type: "text", text: `Found trips to ${destination}` }] };
174
- })
175
- .widget("get-details", {}, {
176
- inputSchema: { tripId: z.string() },
177
- }, async ({ tripId }) => {
178
- return { content: [{ type: "text", text: `Details for ${tripId}` }] };
179
- });
180
-
181
- // Export the server type for the client
182
- export type AppType = typeof server;
183
- ```
184
-
185
- _One-time setup (web/src/skybridge.ts)_
186
-
187
- Create typed hooks once and export them for use across your app. This file acts as a bridge between your server types and your widgets:
188
-
189
- ```ts
190
- import type { AppType } from "../server"; // type-only import
191
- import { generateHelpers } from "skybridge/web";
192
-
193
- export const { useCallTool, useToolInfo } = generateHelpers<AppType>();
194
- ```
195
-
196
- _Usage in widgets (web/src/widgets/search.tsx)_
81
+ ### Widget
197
82
 
198
83
  ```tsx
199
- import { useCallTool, useToolInfo } from "../skybridge"; // import typed hooks
200
-
201
- export function SearchWidget() {
202
- const { callTool, data, isPending } = useCallTool("search-voyage");
203
- // ^ autocomplete for tool names
204
- const toolInfo = useToolInfo<"search-voyage">();
205
- // ^ autocomplete for widget names
206
-
207
- const handleSearch = () => {
208
- callTool({ destination: "Spain" });
209
- // ^ autocomplete for input fields
210
- };
211
-
212
- return (
213
- <div>
214
- <button onClick={handleSearch} disabled={isPending}>
215
- Search
216
- </button>
217
- {toolInfo.isSuccess && (
218
- <div>Found {toolInfo.output.structuredContent.totalCount} results</div>
219
- // ^ typed output
220
- )}
221
- </div>
222
- );
223
- }
224
- ```
225
-
226
- **Hooks**
227
-
228
- The `skybridge/web` package comes with a set of hooks to help you build your widgets :
229
-
230
- - `useOpenAiGlobal`: A generic hook to get any global data from the OpenAI iFrame skybridge runtime (in `window.openai`).
231
- - `useToolOutput`: A hook to get the initial tool `structuredContent` returned when rendering the widget for the first time. The data inside this hook is not updated when the tool is called again.
232
- - `useToolResponseMetadata`: A hook to get the initial tool `meta` returned when rendering the widget for the first time. The data inside this hook is not updated when the tool is called again.
233
- - `useToolInfo`: A hook to get the tool input, output, and response metadata with type inference. Provides a discriminated union based on status (pending/success).
234
- - `useCallTool`: A @tanstack/react-query inspired hook to send make additional tool calls inside a widget.
235
- - `generateHelpers`: A factory that creates typed versions of `useCallTool` and `useToolInfo` with full type inference from your server type.
236
-
237
- _useOpenAiGlobal_
238
-
239
- ```ts
240
- import { useOpenAiGlobal } from "skybridge/web";
241
-
242
- const theme = useOpenAiGlobal("theme");
243
- ```
244
-
245
- _useToolOutput_
246
-
247
- ```ts
248
- import { useToolOutput } from "skybridge/web";
249
-
250
- const toolOutput = useToolOutput();
251
- ```
252
-
253
- _useToolResponseMetadata_
254
-
255
- ```ts
256
- import { useToolResponseMetadata } from "skybridge/web";
257
-
258
- const toolResponseMetadata = useToolResponseMetadata();
259
- ```
260
-
261
- _useToolInfo_
262
-
263
- ```ts
264
84
  import { useToolInfo } from "skybridge/web";
265
85
 
266
- const toolInfo = useToolInfo<{
267
- input: { query: string };
268
- output: { results: string[] };
269
- responseMetadata: { id: number };
270
- }>();
271
-
272
- // toolInfo.input is typed based on the input type
273
- // toolInfo.output.structuredContent is typed based on the output type (undefined when pending)
274
- // toolInfo.status narrows correctly: "pending" | "success"
275
-
276
- if (toolInfo.isPending) {
277
- // toolInfo.output is undefined here (pending state)
278
- console.log(toolInfo.input.query);
279
- }
280
-
281
- if (toolInfo.isSuccess) {
282
- // toolInfo.output.structuredContent is typed here
283
- console.log(toolInfo.output.structuredContent.results);
284
- }
285
- ```
286
-
287
- _useToolInfo_ with typed hooks (recommended)
288
-
289
- ```tsx
290
- import { useToolInfo } from "../skybridge"; // import typed hooks
291
-
292
- export function SearchWidget() {
293
- const toolInfo = useToolInfo<"search-voyage">();
294
- // ^ autocomplete for widget names
295
- // toolInfo.input is typed as { destination: string; departureDate?: string; ... }
296
- // toolInfo.output.structuredContent is typed as { results: Array<...>; totalCount: number; }
297
-
298
- if (toolInfo.isSuccess) {
299
- return <div>Found {toolInfo.output.structuredContent.totalCount} results</div>;
300
- }
301
-
302
- return <div>Searching for {toolInfo.input.destination}...</div>;
303
- }
304
- ```
86
+ function FlightsWidget() {
87
+ const { output } = useToolInfo();
305
88
 
306
- _useCallTool_ in synchronous mode
307
-
308
- ```ts
309
- import { useCallTool } from "skybridge/web";
310
-
311
- export const TestTool: React.FunctionComponent = () => {
312
- const { callTool, isPending } = useCallTool("myToolName");
313
-
314
- return (
315
- <div>
316
- <button
317
- disabled={isPending}
318
- onClick={() => {
319
- callTool({ input: "test input" }, {
320
- onSuccess: (data) => {
321
- alert("Tool returned: " + data);
322
- },
323
- });
324
- >
325
- Call Tool inside a widget
326
- </button>
327
- </div>
89
+ return output.structuredContent.flights.map(f =>
90
+ <FlightCard key={f.id} flight={f} />
328
91
  );
329
- };
330
- ```
331
-
332
- _useCallTool_ in asynchronous mode
333
-
334
- ```ts
335
- import { useCallTool } from "skybridge/web";
336
-
337
- export const TestTool: React.FunctionComponent = () => {
338
- const { callToolAsync, isPending } = useCallTool("myToolName");
339
-
340
- return (
341
- <div>
342
- <button
343
- disabled={isPending}
344
- onClick={async () => {
345
- const data = await callToolAsync({ input: "test input" });
346
- alert("Tool returned: " + data);
347
- }}
348
- >
349
- Call Tool inside a widget
350
- </button>
351
- </div>
352
- );
353
- };
92
+ }
354
93
  ```
355
94
 
356
- **State Management**
95
+ <br />
357
96
 
358
- The `skybridge/web` package provides `createStore` for creating Zustand stores with automatic persistence to `window.openai.widgetState`. This is useful when you need more advanced state management than what `useWidgetState` provides.
97
+ ## 🎯 Features at a Glance
359
98
 
360
- _createStore_
99
+ - **Live Reload** — Vite HMR. See changes instantly without reinstalling.
100
+ - **Typed Hooks** — Full autocomplete for tools, inputs, outputs.
101
+ - **Widget → Tool Calls** — Trigger server actions from UI.
102
+ - **Dual Surface Sync** — Keep model aware of what users see with `data-llm`.
103
+ - **React Query-style API** — `isPending`, `isError`, callbacks.
104
+ - **MCP Compatible** — Extends the official SDK. Works with any MCP client.
361
105
 
362
- ```ts
363
- import { createStore } from "skybridge/web";
364
-
365
- type CounterState = {
366
- count: number;
367
- increment: () => void;
368
- decrement: () => void;
369
- };
370
-
371
- const useCounterStore = createStore<CounterState>(
372
- (set) => ({
373
- count: 0,
374
- increment: () => set((state) => ({ count: state.count + 1 })),
375
- decrement: () => set((state) => ({ count: state.count - 1 })),
376
- }),
377
- { count: 0 } // Optional default state
378
- );
379
-
380
- // Use in your component
381
- function CounterWidget() {
382
- const { count, increment, decrement } = useCounterStore();
383
-
384
- return (
385
- <div>
386
- <p>Count: {count}</p>
387
- <button onClick={increment}>Increment</button>
388
- <button onClick={decrement}>Decrement</button>
389
- </div>
390
- );
391
- }
392
- ```
106
+ <br />
393
107
 
394
- The `createStore` function:
395
-
396
- - Automatically persists state to `window.openai.widgetState`
397
- - Syncs with external state changes from the host
398
- - Filters out widget context keys from persisted state
399
- - Supports optional default state (value or function)
400
- - Only serializes state data, not methods
108
+ <div align="center">
401
109
 
402
- ## Migrate your existing MCP server to a ChatGPT app
110
+ [![GitHub Discussions](https://img.shields.io/badge/Discussions-Ask%20Questions-blue?style=flat-square&logo=github)](https://github.com/alpic-ai/skybridge/discussions)
111
+ [![GitHub Issues](https://img.shields.io/badge/Issues-Report%20Bugs-red?style=flat-square&logo=github)](https://github.com/alpic-ai/skybridge/issues)
112
+ [![Discord](https://img.shields.io/badge/Discord-Chat-5865F2?style=flat-square&logo=discord&logoColor=white)](https://discord.com/invite/gNAazGueab)
403
113
 
404
- If you're already using the `@modelcontextprotocol/sdk` to build a MCP server, you can migrate to a ChatGPT app by following these steps:
114
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for setup instructions
405
115
 
406
- 1. Replace your `McpServer` import from `@modelcontextprotocol/sdk` with the same import from `skybridge/server`
407
- 2. Create a new vite project in a folder named `web` and install the `skybridge` package
408
- 3. Replace the `vite.config.ts` file with the following:
116
+ <br />
409
117
 
410
- ```ts
411
- import { defineConfig } from "vite";
412
- import { skybridge } from "skybridge/web";
118
+ **[GPL-3.0 License](LICENSE)** · Made with ❤️ by **[Alpic](https://alpic.ai)**
413
119
 
414
- export default defineConfig({
415
- plugins: [skybridge()],
416
- });
417
- ```
120
+ </div>
@@ -1,4 +1,4 @@
1
+ export type { AnyToolRegistry, InferTools, ToolInput, ToolNames, ToolOutput, } from "./inferUtilityTypes.js";
2
+ export type { McpServerTypes, ToolDef } from "./server.js";
1
3
  export { McpServer } from "./server.js";
2
4
  export { widgetsDevServer } from "./widgetsDevServer.js";
3
- export type { ToolDef, McpServerTypes } from "./server.js";
4
- export type { InferTools, AnyToolRegistry, ToolNames, ToolInput, ToolOutput, } from "./inferUtilityTypes.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -1,13 +1,14 @@
1
- import { McpServer as McpServerBase, type RegisteredTool } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import type { Resource, ToolAnnotations, CallToolResult, ServerRequest, ServerNotification } from "@modelcontextprotocol/sdk/types.js";
1
+ import type { RegisteredTool } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { McpServer as McpServerBase } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import type { AnySchema, SchemaOutput, ZodRawShapeCompat } from "@modelcontextprotocol/sdk/server/zod-compat.js";
3
4
  import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
4
- import type { ZodRawShape, ZodObject, infer as Infer } from "zod";
5
+ import type { CallToolResult, Resource, ServerNotification, ServerRequest, ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
5
6
  export type ToolDef<TInput = unknown, TOutput = unknown> = {
6
7
  input: TInput;
7
8
  output: TOutput;
8
9
  };
9
10
  type McpServerOriginalResourceConfig = Omit<Resource, "uri" | "name" | "mimeType">;
10
- type McpServerOriginalToolConfig = Omit<Parameters<McpServerBase["registerTool"]>[1], "inputSchema" | "outputSchema">;
11
+ type McpServerOriginalToolConfig = Omit<Parameters<typeof McpServerBase.prototype.registerTool<ZodRawShapeCompat, ZodRawShapeCompat>>[1], "inputSchema" | "outputSchema">;
11
12
  type ExtractStructuredContent<T> = T extends {
12
13
  structuredContent: infer SC;
13
14
  } ? SC : never;
@@ -23,26 +24,34 @@ type ExtractStructuredContent<T> = T extends {
23
24
  export interface McpServerTypes<TTools extends Record<string, ToolDef> = {}> {
24
25
  readonly tools: TTools;
25
26
  }
26
- type AddTool<TTools, TName extends string, TInput extends ZodRawShape, TOutput> = McpServer<TTools & {
27
- [K in TName]: ToolDef<Infer<ZodObject<TInput>>, TOutput>;
27
+ type Simplify<T> = {
28
+ [K in keyof T]: T[K];
29
+ };
30
+ type ShapeOutput<Shape extends ZodRawShapeCompat> = Simplify<{
31
+ [K in keyof Shape as undefined extends SchemaOutput<Shape[K]> ? never : K]: SchemaOutput<Shape[K]>;
32
+ } & {
33
+ [K in keyof Shape as undefined extends SchemaOutput<Shape[K]> ? K : never]?: SchemaOutput<Shape[K]>;
34
+ }>;
35
+ type AddTool<TTools, TName extends string, TInput extends ZodRawShapeCompat, TOutput> = McpServer<TTools & {
36
+ [K in TName]: ToolDef<ShapeOutput<TInput>, TOutput>;
28
37
  }>;
29
- type ToolConfig<TInput extends ZodRawShape> = {
38
+ type ToolConfig<TInput extends ZodRawShapeCompat | AnySchema> = {
30
39
  title?: string;
31
40
  description?: string;
32
41
  inputSchema?: TInput;
33
- outputSchema?: ZodRawShape;
42
+ outputSchema?: ZodRawShapeCompat | AnySchema;
34
43
  annotations?: ToolAnnotations;
35
44
  _meta?: Record<string, unknown>;
36
45
  };
37
- type ToolHandler<TInput extends ZodRawShape, TReturn extends CallToolResult = CallToolResult> = (args: Infer<ZodObject<TInput>>, extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => TReturn | Promise<TReturn>;
46
+ type ToolHandler<TInput extends ZodRawShapeCompat, TReturn extends CallToolResult = CallToolResult> = (args: ShapeOutput<TInput>, extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => TReturn | Promise<TReturn>;
38
47
  export declare class McpServer<TTools extends Record<string, ToolDef> = {}> extends McpServerBase {
39
48
  readonly $types: McpServerTypes<TTools>;
40
- widget<TName extends string, TInput extends ZodRawShape, TReturn extends CallToolResult>(name: TName, resourceConfig: McpServerOriginalResourceConfig, toolConfig: McpServerOriginalToolConfig & {
49
+ registerWidget<TName extends string, TInput extends ZodRawShapeCompat, TReturn extends CallToolResult>(name: TName, resourceConfig: McpServerOriginalResourceConfig, toolConfig: McpServerOriginalToolConfig & {
41
50
  inputSchema?: TInput;
42
- outputSchema?: ZodRawShape;
51
+ outputSchema?: ZodRawShapeCompat | AnySchema;
43
52
  }, toolCallback: ToolHandler<TInput, TReturn>): AddTool<TTools, TName, TInput, ExtractStructuredContent<TReturn>>;
44
- registerTool<TName extends string, InputArgs extends ZodRawShape, TReturn extends CallToolResult>(name: TName, config: ToolConfig<InputArgs>, cb: ToolHandler<InputArgs, TReturn>): AddTool<TTools, TName, InputArgs, ExtractStructuredContent<TReturn>>;
45
- registerTool<InputArgs extends ZodRawShape>(name: string, config: ToolConfig<InputArgs>, cb: ToolHandler<InputArgs>): RegisteredTool;
53
+ registerTool<TName extends string, InputArgs extends ZodRawShapeCompat, TReturn extends CallToolResult>(name: TName, config: ToolConfig<InputArgs>, cb: ToolHandler<InputArgs, TReturn>): AddTool<TTools, TName, InputArgs, ExtractStructuredContent<TReturn>>;
54
+ registerTool<InputArgs extends ZodRawShapeCompat>(name: string, config: ToolConfig<InputArgs>, cb: ToolHandler<InputArgs>): RegisteredTool;
46
55
  private lookupDistFile;
47
56
  }
48
57
  export {};
@@ -1,9 +1,9 @@
1
- import { McpServer as McpServerBase, } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { templateHelper } from "./templateHelper.js";
3
1
  import { readFileSync } from "node:fs";
4
2
  import path from "node:path";
3
+ import { McpServer as McpServerBase } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { templateHelper } from "./templateHelper.js";
5
5
  export class McpServer extends McpServerBase {
6
- widget(name, resourceConfig, toolConfig, toolCallback) {
6
+ registerWidget(name, resourceConfig, toolConfig, toolCallback) {
7
7
  const uri = `ui://widgets/${name}.html`;
8
8
  const resourceMetadata = {
9
9
  ...(resourceConfig._meta ?? {}),
@@ -11,7 +11,7 @@ export class McpServer extends McpServerBase {
11
11
  if (toolConfig.description !== undefined) {
12
12
  resourceMetadata["openai/widgetDescription"] = toolConfig.description;
13
13
  }
14
- this.resource(name, uri, {
14
+ this.registerResource(name, uri, {
15
15
  ...resourceConfig,
16
16
  _meta: resourceMetadata,
17
17
  }, async (_uri, extra) => {
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/server/server.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,IAAI,aAAa,GAG3B,MAAM,yCAAyC,CAAC;AAUjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAkG7B,MAAM,OAAO,SAEX,SAAQ,aAAa;IAGrB,MAAM,CAKJ,IAAW,EACX,cAA+C,EAC/C,UAGC,EACD,YAA0C;QAE1C,MAAM,GAAG,GAAG,gBAAgB,IAAI,OAAO,CAAC;QACxC,MAAM,gBAAgB,GAAiB;YACrC,GAAG,CAAC,cAAc,CAAC,KAAK,IAAI,EAAE,CAAC;SAChC,CAAC;QACF,IAAI,UAAU,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACzC,gBAAgB,CAAC,0BAA0B,CAAC,GAAG,UAAU,CAAC,WAAW,CAAC;QACxE,CAAC;QAED,IAAI,CAAC,QAAQ,CACX,IAAI,EACJ,GAAG,EACH;YACE,GAAG,cAAc;YACjB,KAAK,EAAE,gBAAgB;SACxB,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;YACpB,MAAM,SAAS,GACb,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;gBACnC,CAAC,CAAC,WACE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,kBAAkB,CAAC;oBACjD,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,IAC/B,EAAE;gBACJ,CAAC,CAAC,uBAAuB,CAAC;YAE9B,MAAM,IAAI,GACR,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;gBACnC,CAAC,CAAC,cAAc,CAAC,gBAAgB,CAAC;oBAC9B,SAAS;oBACT,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,eAAe,IAAI,MAAM,CAAC;oBAC1D,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC;iBAC5C,CAAC;gBACJ,CAAC,CAAC,cAAc,CAAC,iBAAiB,CAAC;oBAC/B,SAAS;oBACT,UAAU,EAAE,IAAI;iBACjB,CAAC,CAAC;YAET,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG;wBACH,QAAQ,EAAE,qBAAqB;wBAC/B,IAAI,EAAE,IAAI;qBACX;iBACF;aACF,CAAC;QACJ,CAAC,CACF,CAAC;QAEF,MAAM,QAAQ,GAAa;YACzB,GAAG,UAAU,CAAC,KAAK;YACnB,uBAAuB,EAAE,GAAG;YAC5B,gBAAgB,EAAE,GAAG;SACtB,CAAC;QAEF,IAAI,CAAC,YAAY,CACf,IAAI,EACJ;YACE,GAAG,UAAU;YACb,KAAK,EAAE,QAAQ;SAChB,EACD,YAAY,CACb,CAAC;QAEF,OAAO,IAAyE,CAAC;IACnF,CAAC;IAkBQ,YAAY,CACnB,IAAY,EACZ,MAA6B,EAC7B,EAA2B;QAE3B,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,cAAc,CAAC,GAAW;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,YAAY,CACV,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,eAAe,CAAC,EACpE,OAAO,CACR,CACF,CAAC;QAEF,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IAC7B,CAAC;CACF"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/server/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAcrF,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAkHrD,MAAM,OAAO,SAEX,SAAQ,aAAa;IAGrB,cAAc,CAKZ,IAAW,EACX,cAA+C,EAC/C,UAGC,EACD,YAA0C;QAE1C,MAAM,GAAG,GAAG,gBAAgB,IAAI,OAAO,CAAC;QACxC,MAAM,gBAAgB,GAAiB;YACrC,GAAG,CAAC,cAAc,CAAC,KAAK,IAAI,EAAE,CAAC;SAChC,CAAC;QACF,IAAI,UAAU,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACzC,gBAAgB,CAAC,0BAA0B,CAAC,GAAG,UAAU,CAAC,WAAW,CAAC;QACxE,CAAC;QAED,IAAI,CAAC,gBAAgB,CACnB,IAAI,EACJ,GAAG,EACH;YACE,GAAG,cAAc;YACjB,KAAK,EAAE,gBAAgB;SACxB,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;YACpB,MAAM,SAAS,GACb,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;gBACnC,CAAC,CAAC,WACE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,kBAAkB,CAAC;oBACjD,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,IAC/B,EAAE;gBACJ,CAAC,CAAC,uBAAuB,CAAC;YAE9B,MAAM,IAAI,GACR,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;gBACnC,CAAC,CAAC,cAAc,CAAC,gBAAgB,CAAC;oBAC9B,SAAS;oBACT,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,eAAe,IAAI,MAAM,CAAC;oBAC1D,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC;iBAC5C,CAAC;gBACJ,CAAC,CAAC,cAAc,CAAC,iBAAiB,CAAC;oBAC/B,SAAS;oBACT,UAAU,EAAE,IAAI;iBACjB,CAAC,CAAC;YAET,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG;wBACH,QAAQ,EAAE,qBAAqB;wBAC/B,IAAI,EAAE,IAAI;qBACX;iBACF;aACF,CAAC;QACJ,CAAC,CACF,CAAC;QAEF,MAAM,QAAQ,GAAa;YACzB,GAAG,UAAU,CAAC,KAAK;YACnB,uBAAuB,EAAE,GAAG;YAC5B,gBAAgB,EAAE,GAAG;SACtB,CAAC;QAEF,IAAI,CAAC,YAAY,CACf,IAAI,EACJ;YACE,GAAG,UAAU;YACb,KAAK,EAAE,QAAQ;SAChB,EACD,YAAY,CACb,CAAC;QAEF,OAAO,IAKN,CAAC;IACJ,CAAC;IAkBQ,YAAY,CACnB,IAAY,EACZ,MAA6B,EAC7B,EAA2B;QAE3B,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,cAAc,CAAC,GAAW;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,YAAY,CACV,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,eAAe,CAAC,EACpE,OAAO,CACR,CACF,CAAC;QAEF,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IAC7B,CAAC;CACF"}
@@ -1,7 +1,7 @@
1
- import Handlebars from "handlebars";
2
1
  import { readFileSync } from "node:fs";
3
- import { join, dirname } from "node:path";
2
+ import { dirname, join } from "node:path";
4
3
  import { fileURLToPath } from "node:url";
4
+ import Handlebars from "handlebars";
5
5
  const __filename = fileURLToPath(import.meta.url);
6
6
  const __dirname = dirname(__filename);
7
7
  class TemplateHelper {
@@ -1 +1 @@
1
- {"version":3,"file":"templateHelper.js","sourceRoot":"","sources":["../../../src/server/templateHelper.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAOtC,MAAM,cAAc;IACV,aAAa,GAAG,IAAI,GAAG,EAAsC,CAAC;IAE9D,YAAY,CAAC,YAAoB;QACvC,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAE,CAAC;QAC/C,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,YAAY,MAAM,CAAC,CAAC;QACzE,MAAM,cAAc,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAEpD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAC/C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,gBAAgB,CAAC,IAIhB;QACC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACjD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,iBAAiB,CAAC,IAA+C;QAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QAClD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"templateHelper.js","sourceRoot":"","sources":["../../../src/server/templateHelper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,MAAM,cAAc;IACV,aAAa,GAAG,IAAI,GAAG,EAAsC,CAAC;IAE9D,YAAY,CAAC,YAAoB;QACvC,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAE,CAAC;QAC/C,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,YAAY,MAAM,CAAC,CAAC;QACzE,MAAM,cAAc,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAEpD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAC/C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,gBAAgB,CAAC,IAIhB;QACC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACjD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,iBAAiB,CAAC,IAA+C;QAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QAClD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC"}
@@ -1,6 +1,6 @@
1
- import express, {} from "express";
2
- import cors from "cors";
3
1
  import path from "node:path";
2
+ import cors from "cors";
3
+ import express, {} from "express";
4
4
  /**
5
5
  * Install Vite dev server
6
6
  * This router MUST be installed at the application root, like so:
@@ -17,7 +17,7 @@ export const widgetsDevServer = async () => {
17
17
  const workspaceRoot = searchForWorkspaceRoot(process.cwd());
18
18
  const webAppRoot = path.join(workspaceRoot, "web");
19
19
  const configResult = await loadConfigFromFile({ command: "serve", mode: "development" }, path.join(webAppRoot, "vite.config.ts"), webAppRoot);
20
- // Remove build-specific options that don't apply to dev server
20
+ // biome-ignore lint/correctness/noUnusedVariables: Remove build-specific options that don't apply to dev server
21
21
  const { build, preview, ...devConfig } = configResult?.config || {};
22
22
  const vite = await createServer({
23
23
  ...devConfig,
@@ -1 +1 @@
1
- {"version":3,"file":"widgetsDevServer.js","sourceRoot":"","sources":["../../../src/server/widgetsDevServer.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,EAAE,EAAuB,MAAM,SAAS,CAAC;AACvD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,IAA6B,EAAE;IAClE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAEhC,MAAM,EAAE,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,GAChE,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IACvB,MAAM,aAAa,GAAG,sBAAsB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAEnD,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAC3C,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,EACzC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,EACvC,UAAU,CACX,CAAC;IAEF,+DAA+D;IAC/D,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,GAAG,YAAY,EAAE,MAAM,IAAI,EAAE,CAAC;IAEpE,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC;QAC9B,GAAG,SAAS;QACZ,UAAU,EAAE,KAAK,EAAE,kFAAkF;QACrG,OAAO,EAAE,QAAQ;QACjB,MAAM,EAAE;YACN,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;SACrB;QACD,IAAI,EAAE,UAAU;QAChB,YAAY,EAAE;YACZ,OAAO,EAAE,CAAC,OAAO,EAAE,kBAAkB,CAAC;SACvC;KACF,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACnB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
1
+ {"version":3,"file":"widgetsDevServer.js","sourceRoot":"","sources":["../../../src/server/widgetsDevServer.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,OAAO,EAAE,EAAuB,MAAM,SAAS,CAAC;AAEvD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,IAA6B,EAAE;IAClE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAEhC,MAAM,EAAE,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,GAChE,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IACvB,MAAM,aAAa,GAAG,sBAAsB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAEnD,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAC3C,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,EACzC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,EACvC,UAAU,CACX,CAAC;IAEF,gHAAgH;IAChH,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,GAAG,YAAY,EAAE,MAAM,IAAI,EAAE,CAAC;IAEpE,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC;QAC9B,GAAG,SAAS;QACZ,UAAU,EAAE,KAAK,EAAE,kFAAkF;QACrG,OAAO,EAAE,QAAQ;QACjB,MAAM,EAAE;YACN,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;SACrB;QACD,IAAI,EAAE,UAAU;QAChB,YAAY,EAAE;YACZ,OAAO,EAAE,CAAC,OAAO,EAAE,kBAAkB,CAAC;SACvC;KACF,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACnB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
@@ -5,7 +5,7 @@ import { McpServer } from "../server/server.js";
5
5
  */
6
6
  export declare function createMockMcpServer(): {
7
7
  server: McpServer;
8
- mockResource: MockInstance<McpServer["resource"]>;
8
+ mockRegisterResource: MockInstance<McpServer["registerResource"]>;
9
9
  mockRegisterTool: MockInstance<McpServer["registerTool"]>;
10
10
  };
11
11
  export declare function createTestServer(): McpServer<{