skybridge 0.0.0-dev.bef3c23 → 0.0.0-dev.bf1cdbd
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.
- package/README.md +17 -8
- package/dist/cli/detect-port.d.ts +18 -0
- package/dist/cli/detect-port.js +61 -0
- package/dist/cli/detect-port.js.map +1 -0
- package/dist/cli/types.d.ts +5 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/use-nodemon.d.ts +1 -5
- package/dist/cli/use-nodemon.js +28 -9
- package/dist/cli/use-nodemon.js.map +1 -1
- package/dist/cli/use-tunnel.d.ts +8 -0
- package/dist/cli/use-tunnel.js +101 -0
- package/dist/cli/use-tunnel.js.map +1 -0
- package/dist/commands/build.js +1 -1
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/dev.d.ts +2 -1
- package/dist/commands/dev.js +20 -7
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/start.d.ts +3 -1
- package/dist/commands/start.js +32 -8
- package/dist/commands/start.js.map +1 -1
- package/dist/server/express.d.ts +15 -0
- package/dist/server/express.js +77 -0
- package/dist/server/express.js.map +1 -0
- package/dist/server/express.test.d.ts +1 -0
- package/dist/server/express.test.js +252 -0
- package/dist/server/express.test.js.map +1 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/middleware.d.ts +124 -0
- package/dist/server/middleware.js +93 -0
- package/dist/server/middleware.js.map +1 -0
- package/dist/server/middleware.test-d.d.ts +1 -0
- package/dist/server/middleware.test-d.js +75 -0
- package/dist/server/middleware.test-d.js.map +1 -0
- package/dist/server/middleware.test.d.ts +1 -0
- package/dist/server/middleware.test.js +490 -0
- package/dist/server/middleware.test.js.map +1 -0
- package/dist/server/server.d.ts +52 -1
- package/dist/server/server.js +158 -23
- package/dist/server/server.js.map +1 -1
- package/dist/server/templateHelper.d.ts +0 -1
- package/dist/server/templateHelper.js.map +1 -1
- package/dist/server/templates/development.hbs +0 -55
- package/dist/server/widgetsDevServer.d.ts +2 -1
- package/dist/server/widgetsDevServer.js +5 -5
- package/dist/server/widgetsDevServer.js.map +1 -1
- package/dist/test/widget.test.js +27 -19
- package/dist/test/widget.test.js.map +1 -1
- package/dist/web/bridges/apps-sdk/adaptor.d.ts +4 -4
- package/dist/web/bridges/apps-sdk/adaptor.js +26 -15
- package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -1
- package/dist/web/bridges/apps-sdk/bridge.d.ts +1 -1
- package/dist/web/bridges/apps-sdk/index.d.ts +1 -1
- package/dist/web/bridges/apps-sdk/index.js.map +1 -1
- package/dist/web/bridges/apps-sdk/types.d.ts +14 -8
- package/dist/web/bridges/apps-sdk/types.js.map +1 -1
- package/dist/web/bridges/mcp-app/adaptor.d.ts +6 -4
- package/dist/web/bridges/mcp-app/adaptor.js +37 -41
- package/dist/web/bridges/mcp-app/adaptor.js.map +1 -1
- package/dist/web/bridges/mcp-app/bridge.d.ts +13 -30
- package/dist/web/bridges/mcp-app/bridge.js +43 -196
- package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +5 -3
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js +2 -2
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +1 -41
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
- package/dist/web/bridges/types.d.ts +8 -3
- package/dist/web/components/modal-provider.js +1 -3
- package/dist/web/components/modal-provider.js.map +1 -1
- package/dist/web/create-store.test.js +9 -4
- package/dist/web/create-store.test.js.map +1 -1
- package/dist/web/data-llm.test.js +11 -8
- package/dist/web/data-llm.test.js.map +1 -1
- package/dist/web/hooks/index.d.ts +1 -1
- package/dist/web/hooks/index.js.map +1 -1
- package/dist/web/hooks/test/utils.js +4 -0
- package/dist/web/hooks/test/utils.js.map +1 -1
- package/dist/web/hooks/use-display-mode.d.ts +3 -3
- package/dist/web/hooks/use-display-mode.js.map +1 -1
- package/dist/web/hooks/use-display-mode.test-d.d.ts +1 -0
- package/dist/web/hooks/use-display-mode.test-d.js +8 -0
- package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
- package/dist/web/hooks/use-files.test.js +5 -1
- package/dist/web/hooks/use-files.test.js.map +1 -1
- package/dist/web/hooks/use-layout.test.js +3 -3
- package/dist/web/hooks/use-layout.test.js.map +1 -1
- package/dist/web/hooks/use-open-external.d.ts +3 -1
- package/dist/web/hooks/use-open-external.js +1 -1
- package/dist/web/hooks/use-open-external.js.map +1 -1
- package/dist/web/hooks/use-open-external.test.js +26 -11
- package/dist/web/hooks/use-open-external.test.js.map +1 -1
- package/dist/web/hooks/use-request-modal.test.js +5 -1
- package/dist/web/hooks/use-request-modal.test.js.map +1 -1
- package/dist/web/hooks/use-set-open-in-app-url.test.js +5 -11
- package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
- package/dist/web/hooks/use-tool-info.test.js +1 -1
- package/dist/web/hooks/use-tool-info.test.js.map +1 -1
- package/dist/web/hooks/use-user.js +18 -2
- package/dist/web/hooks/use-user.js.map +1 -1
- package/dist/web/hooks/use-user.test.js +29 -1
- package/dist/web/hooks/use-user.test.js.map +1 -1
- package/dist/web/hooks/use-widget-state.test.js +9 -6
- package/dist/web/hooks/use-widget-state.test.js.map +1 -1
- package/dist/web/plugin/plugin.js +8 -0
- package/dist/web/plugin/plugin.js.map +1 -1
- package/dist/web/plugin/validate-widget.d.ts +5 -0
- package/dist/web/plugin/validate-widget.js +27 -0
- package/dist/web/plugin/validate-widget.js.map +1 -0
- package/dist/web/plugin/validate-widget.test.d.ts +1 -0
- package/dist/web/plugin/validate-widget.test.js +42 -0
- package/dist/web/plugin/validate-widget.test.js.map +1 -0
- package/package.json +28 -24
- package/tsconfig.base.json +31 -0
package/dist/server/server.d.ts
CHANGED
|
@@ -2,7 +2,9 @@ import type { McpUiResourceMeta } from "@modelcontextprotocol/ext-apps";
|
|
|
2
2
|
import { McpServer as McpServerBase, type RegisteredTool } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
import type { AnySchema, SchemaOutput, ZodRawShapeCompat } from "@modelcontextprotocol/sdk/server/zod-compat.js";
|
|
4
4
|
import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
5
|
-
import type { CallToolResult, Resource, ServerNotification, ServerRequest, ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import type { CallToolResult, Resource, ServerNotification, ServerRequest, ServerResult, ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
|
|
6
|
+
import type { ErrorRequestHandler, RequestHandler } from "express";
|
|
7
|
+
import type { McpExtra, McpExtraFor, McpMethodString, McpMiddlewareFilter, McpMiddlewareFn, McpResultFor, McpTypedMiddlewareFn, McpWildcard } from "./middleware.js";
|
|
6
8
|
export type ToolDef<TInput = unknown, TOutput = unknown, TResponseMetadata = unknown> = {
|
|
7
9
|
input: TInput;
|
|
8
10
|
output: TOutput;
|
|
@@ -81,6 +83,55 @@ type ToolHandler<TInput extends ZodRawShapeCompat, TReturn extends {
|
|
|
81
83
|
} = CallToolResult> = (args: ShapeOutput<TInput>, extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => TReturn | Promise<TReturn>;
|
|
82
84
|
export declare class McpServer<TTools extends Record<string, ToolDef> = Record<never, ToolDef>> extends McpServerBase {
|
|
83
85
|
readonly $types: McpServerTypes<TTools>;
|
|
86
|
+
private express?;
|
|
87
|
+
private customMiddleware;
|
|
88
|
+
private customErrorMiddleware;
|
|
89
|
+
private mcpMiddlewareEntries;
|
|
90
|
+
private mcpMiddlewareApplied;
|
|
91
|
+
use(...handlers: RequestHandler[]): this;
|
|
92
|
+
use(path: string, ...handlers: RequestHandler[]): this;
|
|
93
|
+
useOnError(...handlers: ErrorRequestHandler[]): this;
|
|
94
|
+
useOnError(path: string, ...handlers: ErrorRequestHandler[]): this;
|
|
95
|
+
/**
|
|
96
|
+
* Register MCP protocol-level middleware (catch-all).
|
|
97
|
+
*/
|
|
98
|
+
mcpMiddleware(handler: McpMiddlewareFn): this;
|
|
99
|
+
/**
|
|
100
|
+
* Register MCP protocol-level middleware for all requests (`extra` is `McpExtra`).
|
|
101
|
+
*/
|
|
102
|
+
mcpMiddleware(filter: "request", handler: (request: {
|
|
103
|
+
method: string;
|
|
104
|
+
params: Record<string, unknown>;
|
|
105
|
+
}, extra: McpExtra, next: () => Promise<ServerResult>) => Promise<unknown> | unknown): this;
|
|
106
|
+
/**
|
|
107
|
+
* Register MCP protocol-level middleware for all notifications (`extra` is `undefined`).
|
|
108
|
+
*/
|
|
109
|
+
mcpMiddleware(filter: "notification", handler: (request: {
|
|
110
|
+
method: string;
|
|
111
|
+
params: Record<string, unknown>;
|
|
112
|
+
}, extra: undefined, next: () => Promise<undefined>) => Promise<unknown> | unknown): this;
|
|
113
|
+
/**
|
|
114
|
+
* Register MCP protocol-level middleware for an exact method.
|
|
115
|
+
* Narrows `params`, `extra`, and `next()` result based on the method string.
|
|
116
|
+
*/
|
|
117
|
+
mcpMiddleware<M extends McpMethodString>(filter: M, handler: McpTypedMiddlewareFn<M>): this;
|
|
118
|
+
/**
|
|
119
|
+
* Register MCP protocol-level middleware for a wildcard pattern (e.g. `"tools/*"`).
|
|
120
|
+
* `next()` returns the union of result types for matching methods.
|
|
121
|
+
*/
|
|
122
|
+
mcpMiddleware<W extends McpWildcard>(filter: W, handler: (request: {
|
|
123
|
+
method: string;
|
|
124
|
+
params: Record<string, unknown>;
|
|
125
|
+
}, extra: McpExtraFor<W>, next: () => Promise<McpResultFor<W>>) => Promise<unknown> | unknown): this;
|
|
126
|
+
/**
|
|
127
|
+
* Register MCP protocol-level middleware with a method filter.
|
|
128
|
+
* Filter can be an exact method (`"tools/call"`), wildcard (`"tools/*"`),
|
|
129
|
+
* category (`"request"` | `"notification"`), or an array of those.
|
|
130
|
+
*/
|
|
131
|
+
mcpMiddleware(filter: McpMiddlewareFilter, handler: McpMiddlewareFn): this;
|
|
132
|
+
private applyMcpMiddleware;
|
|
133
|
+
connect(transport: Parameters<typeof McpServerBase.prototype.connect>[0]): Promise<void>;
|
|
134
|
+
run(): Promise<void>;
|
|
84
135
|
registerWidget<TName extends string, TInput extends ZodRawShapeCompat, TReturn extends {
|
|
85
136
|
content: CallToolResult["content"];
|
|
86
137
|
}>(name: TName, resourceConfig: McpServerOriginalResourceConfig, toolConfig: McpServerOriginalToolConfig & {
|
package/dist/server/server.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
|
+
import http from "node:http";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { McpServer as McpServerBase, } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
6
|
import { mergeWith, union } from "es-toolkit";
|
|
7
|
+
import { createApp } from "./express.js";
|
|
8
|
+
import { buildMiddlewareChain, getHandlerMaps } from "./middleware.js";
|
|
6
9
|
import { templateHelper } from "./templateHelper.js";
|
|
7
10
|
const mergeWithUnion = (target, source) => {
|
|
8
11
|
return mergeWith(target, source, (targetVal, sourceVal) => {
|
|
@@ -12,6 +15,108 @@ const mergeWithUnion = (target, source) => {
|
|
|
12
15
|
});
|
|
13
16
|
};
|
|
14
17
|
export class McpServer extends McpServerBase {
|
|
18
|
+
express;
|
|
19
|
+
customMiddleware = [];
|
|
20
|
+
customErrorMiddleware = [];
|
|
21
|
+
mcpMiddlewareEntries = [];
|
|
22
|
+
mcpMiddlewareApplied = false;
|
|
23
|
+
use(pathOrHandler, ...handlers) {
|
|
24
|
+
if (typeof pathOrHandler === "string") {
|
|
25
|
+
this.customMiddleware.push({
|
|
26
|
+
path: pathOrHandler,
|
|
27
|
+
handlers,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
this.customMiddleware.push({
|
|
32
|
+
handlers: [pathOrHandler, ...handlers],
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
useOnError(pathOrHandler, ...handlers) {
|
|
38
|
+
if (typeof pathOrHandler === "string") {
|
|
39
|
+
this.customErrorMiddleware.push({ path: pathOrHandler, handlers });
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
this.customErrorMiddleware.push({
|
|
43
|
+
handlers: [pathOrHandler, ...handlers],
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
mcpMiddleware(filterOrHandler,
|
|
49
|
+
// biome-ignore lint/suspicious/noExplicitAny: overloads narrow the handler type at call sites; implementation must accept all variants
|
|
50
|
+
maybeHandler) {
|
|
51
|
+
if (this.mcpMiddlewareApplied) {
|
|
52
|
+
throw new Error("Cannot register MCP middleware after run() or connect() has been called");
|
|
53
|
+
}
|
|
54
|
+
const handler = maybeHandler;
|
|
55
|
+
if (typeof filterOrHandler === "function") {
|
|
56
|
+
this.mcpMiddlewareEntries.push({
|
|
57
|
+
filter: null,
|
|
58
|
+
handler: filterOrHandler,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
else if (handler) {
|
|
62
|
+
this.mcpMiddlewareEntries.push({
|
|
63
|
+
filter: filterOrHandler,
|
|
64
|
+
handler,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
throw new Error("mcpMiddleware requires a handler function when a filter is provided");
|
|
69
|
+
}
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
applyMcpMiddleware() {
|
|
73
|
+
if (this.mcpMiddlewareApplied) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
this.mcpMiddlewareApplied = true;
|
|
77
|
+
if (this.mcpMiddlewareEntries.length === 0) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const { requestHandlers, notificationHandlers } = getHandlerMaps(this.server);
|
|
81
|
+
const entries = this.mcpMiddlewareEntries;
|
|
82
|
+
// Wrap existing handlers and proxy future .set() for lazy SDK registration
|
|
83
|
+
const instrumentMap = (map, isNotification) => {
|
|
84
|
+
for (const [method, handler] of map) {
|
|
85
|
+
map.set(method, buildMiddlewareChain(method, isNotification, handler, entries));
|
|
86
|
+
}
|
|
87
|
+
const originalSet = map.set.bind(map);
|
|
88
|
+
map.set = (method, handler) => originalSet(method, buildMiddlewareChain(method, isNotification, handler, entries));
|
|
89
|
+
};
|
|
90
|
+
instrumentMap(requestHandlers, false);
|
|
91
|
+
instrumentMap(notificationHandlers, true);
|
|
92
|
+
}
|
|
93
|
+
async connect(transport) {
|
|
94
|
+
this.applyMcpMiddleware();
|
|
95
|
+
return super.connect(transport);
|
|
96
|
+
}
|
|
97
|
+
async run() {
|
|
98
|
+
this.applyMcpMiddleware();
|
|
99
|
+
const httpServer = http.createServer();
|
|
100
|
+
if (!this.express) {
|
|
101
|
+
this.express = await createApp({
|
|
102
|
+
mcpServer: this,
|
|
103
|
+
httpServer,
|
|
104
|
+
customMiddleware: this.customMiddleware,
|
|
105
|
+
errorMiddleware: this.customErrorMiddleware,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
httpServer.on("request", this.express);
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
httpServer.on("error", (error) => {
|
|
111
|
+
console.error("Failed to start server:", error);
|
|
112
|
+
reject(error);
|
|
113
|
+
});
|
|
114
|
+
const port = parseInt(process.env.__PORT ?? "3000", 10);
|
|
115
|
+
httpServer.listen(port, () => {
|
|
116
|
+
resolve();
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
}
|
|
15
120
|
registerWidget(name, resourceConfig, toolConfig, toolCallback) {
|
|
16
121
|
const userMeta = resourceConfig._meta;
|
|
17
122
|
const toolMeta = {
|
|
@@ -22,7 +127,7 @@ export class McpServer extends McpServerBase {
|
|
|
22
127
|
hostType: "apps-sdk",
|
|
23
128
|
uri: `ui://widgets/apps-sdk/${name}.html`,
|
|
24
129
|
mimeType: "text/html+skybridge",
|
|
25
|
-
buildContentMeta: ({ resourceDomains, connectDomains, domain }) => {
|
|
130
|
+
buildContentMeta: ({ resourceDomains, connectDomains, domain }, overrides) => {
|
|
26
131
|
const userUi = userMeta?.ui;
|
|
27
132
|
const userCsp = userUi?.csp;
|
|
28
133
|
const defaults = {
|
|
@@ -31,7 +136,7 @@ export class McpServer extends McpServerBase {
|
|
|
31
136
|
connect_domains: connectDomains,
|
|
32
137
|
},
|
|
33
138
|
"openai/widgetDomain": domain,
|
|
34
|
-
"openai/widgetDescription":
|
|
139
|
+
"openai/widgetDescription": resourceConfig.description,
|
|
35
140
|
};
|
|
36
141
|
const fromUi = {
|
|
37
142
|
"openai/widgetCSP": {
|
|
@@ -44,7 +149,7 @@ export class McpServer extends McpServerBase {
|
|
|
44
149
|
"openai/widgetPrefersBorder": userUi?.prefersBorder,
|
|
45
150
|
};
|
|
46
151
|
const directOpenaiKeys = Object.fromEntries(Object.entries(userMeta ?? {}).filter(([key]) => key.startsWith("openai/")));
|
|
47
|
-
return mergeWithUnion(mergeWithUnion(defaults, fromUi), directOpenaiKeys);
|
|
152
|
+
return mergeWithUnion(mergeWithUnion(mergeWithUnion(defaults, fromUi), directOpenaiKeys), { "openai/widgetDomain": overrides.domain });
|
|
48
153
|
},
|
|
49
154
|
};
|
|
50
155
|
this.registerWidgetResource({
|
|
@@ -59,7 +164,7 @@ export class McpServer extends McpServerBase {
|
|
|
59
164
|
hostType: "mcp-app",
|
|
60
165
|
uri: `ui://widgets/ext-apps/${name}.html`,
|
|
61
166
|
mimeType: "text/html;profile=mcp-app",
|
|
62
|
-
buildContentMeta: ({ resourceDomains, connectDomains, domain }) => {
|
|
167
|
+
buildContentMeta: ({ resourceDomains, connectDomains, domain }, overrides) => {
|
|
63
168
|
const defaults = {
|
|
64
169
|
ui: {
|
|
65
170
|
csp: {
|
|
@@ -69,7 +174,9 @@ export class McpServer extends McpServerBase {
|
|
|
69
174
|
domain,
|
|
70
175
|
},
|
|
71
176
|
};
|
|
72
|
-
return mergeWithUnion(defaults, {
|
|
177
|
+
return mergeWithUnion(defaults, {
|
|
178
|
+
ui: { ...userMeta?.ui, ...overrides },
|
|
179
|
+
});
|
|
73
180
|
},
|
|
74
181
|
};
|
|
75
182
|
this.registerWidgetResource({
|
|
@@ -95,14 +202,33 @@ export class McpServer extends McpServerBase {
|
|
|
95
202
|
const { hostType, uri: widgetUri, mimeType, buildContentMeta, } = widgetConfig;
|
|
96
203
|
this.registerResource(name, widgetUri, { ...resourceConfig, _meta: resourceConfig._meta }, async (uri, extra) => {
|
|
97
204
|
const isProduction = process.env.NODE_ENV === "production";
|
|
98
|
-
const useForwardedHost = process.env.SKYBRIDGE_USE_FORWARDED_HOST === "true";
|
|
99
205
|
const isClaude = extra?.requestInfo?.headers?.["user-agent"] === "Claude-User";
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
206
|
+
const headers = extra?.requestInfo?.headers || {};
|
|
207
|
+
const header = (key) => {
|
|
208
|
+
const val = headers[key];
|
|
209
|
+
return Array.isArray(val) ? val[0] : val;
|
|
210
|
+
};
|
|
211
|
+
let serverUrl;
|
|
212
|
+
const forwardedHost = header("x-forwarded-host");
|
|
213
|
+
const origin = header("origin");
|
|
214
|
+
const host = header("host");
|
|
215
|
+
if (forwardedHost) {
|
|
216
|
+
const proto = header("x-forwarded-proto") || "https";
|
|
217
|
+
serverUrl = `${proto}://${forwardedHost}`;
|
|
218
|
+
}
|
|
219
|
+
else if (origin) {
|
|
220
|
+
serverUrl = origin;
|
|
221
|
+
}
|
|
222
|
+
else if (host) {
|
|
223
|
+
const proto = ["127.0.0.1:", "localhost:"].some((p) => host.startsWith(p))
|
|
224
|
+
? "http"
|
|
225
|
+
: "https";
|
|
226
|
+
serverUrl = `${proto}://${host}`;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
const devPort = process.env.__PORT || "3000";
|
|
230
|
+
serverUrl = `http://localhost:${devPort}`;
|
|
231
|
+
}
|
|
106
232
|
const html = isProduction
|
|
107
233
|
? templateHelper.renderProduction({
|
|
108
234
|
hostType,
|
|
@@ -113,22 +239,31 @@ export class McpServer extends McpServerBase {
|
|
|
113
239
|
: templateHelper.renderDevelopment({
|
|
114
240
|
hostType,
|
|
115
241
|
serverUrl,
|
|
116
|
-
useLocalNetworkAccess: !useExternalHost,
|
|
117
242
|
widgetName: name,
|
|
118
243
|
});
|
|
119
|
-
const
|
|
244
|
+
const connectDomains = [serverUrl];
|
|
245
|
+
if (!isProduction) {
|
|
246
|
+
const wsUrl = new URL(serverUrl);
|
|
247
|
+
wsUrl.protocol = wsUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
248
|
+
connectDomains.push(wsUrl.origin);
|
|
249
|
+
}
|
|
250
|
+
let contentMetaOverrides = {};
|
|
251
|
+
if (isClaude) {
|
|
252
|
+
const pathname = extra?.requestInfo?.url?.pathname ?? "";
|
|
253
|
+
const url = `${serverUrl}${pathname}`;
|
|
254
|
+
const hash = crypto
|
|
255
|
+
.createHash("sha256")
|
|
256
|
+
.update(url)
|
|
257
|
+
.digest("hex")
|
|
258
|
+
.slice(0, 32);
|
|
259
|
+
contentMetaOverrides = { domain: `${hash}.claudemcpcontent.com` };
|
|
260
|
+
}
|
|
120
261
|
const contentMeta = buildContentMeta({
|
|
121
262
|
resourceDomains: [serverUrl],
|
|
122
|
-
connectDomains
|
|
123
|
-
domain:
|
|
124
|
-
? `${crypto
|
|
125
|
-
.createHash("sha256")
|
|
126
|
-
.update(`https://${hostFromHeaders}/mcp`)
|
|
127
|
-
.digest("hex")
|
|
128
|
-
.slice(0, 32)}.claudemcpcontent.com`
|
|
129
|
-
: serverUrl,
|
|
263
|
+
connectDomains,
|
|
264
|
+
domain: serverUrl,
|
|
130
265
|
baseUriDomains: [serverUrl],
|
|
131
|
-
});
|
|
266
|
+
}, contentMetaOverrides);
|
|
132
267
|
return {
|
|
133
268
|
contents: [
|
|
134
269
|
{ uri: uri.href, mimeType, text: html, _meta: contentMeta },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,OAAO,EACL,SAAS,IAAI,aAAa,GAG3B,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
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;AAGpC,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,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACpD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,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,IAKhB;QACC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACjD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,iBAAiB,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;AAGpC,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,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACpD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,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,IAKhB;QACC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACjD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,iBAAiB,CAAC,IAIjB;QACC,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"}
|
|
@@ -6,61 +6,6 @@
|
|
|
6
6
|
window.__vite_plugin_react_preamble_installed__ = true;
|
|
7
7
|
</script>
|
|
8
8
|
<script type="module" src="{{serverUrl}}/@vite/client"></script>
|
|
9
|
-
{{#if useLocalNetworkAccess}}
|
|
10
|
-
<script type="module">
|
|
11
|
-
// Checks for browser support and shows error if local network access is denied
|
|
12
|
-
(async () => {
|
|
13
|
-
if (!navigator.permissions?.query) {
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Skip for non-http(s) protocols (file://, custom protocols in Electron, etc.)
|
|
18
|
-
const protocol = window.location.protocol;
|
|
19
|
-
const isNonHttpProtocol = protocol !== 'http:' && protocol !== 'https:'
|
|
20
|
-
if (isNonHttpProtocol) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const host = window.location.hostname;
|
|
25
|
-
const isLoopback = host === 'localhost'
|
|
26
|
-
|| /^127\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.test(host)
|
|
27
|
-
|| host === '::1';
|
|
28
|
-
if (isLoopback) {
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
const status = await navigator.permissions.query({ name: "local-network-access" });
|
|
34
|
-
if (status.state === "denied") {
|
|
35
|
-
const errorDiv = document.createElement("div");
|
|
36
|
-
errorDiv.style.cssText = "background: #fef2f2; border: 2px solid #ef4444; border-radius: 8px; padding: 16px; text-align: center; z-index: 10000; font-family: system-ui, sans-serif;";
|
|
37
|
-
|
|
38
|
-
const errorTitle = document.createElement("div");
|
|
39
|
-
errorTitle.style.cssText = "color: #ef4444; font-size: 18px; font-weight: 600; margin-bottom: 8px;";
|
|
40
|
-
errorTitle.textContent = "Error: Local network access permission is denied.";
|
|
41
|
-
|
|
42
|
-
const errorMessage = document.createElement("div");
|
|
43
|
-
errorMessage.style.cssText = "color: #ef4444; font-size: 14px;";
|
|
44
|
-
errorMessage.textContent = "Local network access is required for your widget to connect to the local dev server. Please enable it in your browser settings. ";
|
|
45
|
-
|
|
46
|
-
const link = document.createElement("a");
|
|
47
|
-
link.href = "https://developer.chrome.com/blog/local-network-access";
|
|
48
|
-
link.target = "_blank";
|
|
49
|
-
link.rel = "noopener noreferrer";
|
|
50
|
-
link.style.cssText = "color: #ef4444; text-decoration: underline;";
|
|
51
|
-
link.textContent = "Learn more";
|
|
52
|
-
errorMessage.appendChild(link);
|
|
53
|
-
|
|
54
|
-
errorDiv.appendChild(errorTitle);
|
|
55
|
-
errorDiv.appendChild(errorMessage);
|
|
56
|
-
document.body.appendChild(errorDiv);
|
|
57
|
-
}
|
|
58
|
-
} catch (e) {
|
|
59
|
-
// Permission API doesn't support local-network-access, ignore silently
|
|
60
|
-
}
|
|
61
|
-
})();
|
|
62
|
-
</script>
|
|
63
|
-
{{/if}}
|
|
64
9
|
<div id="root"></div>
|
|
65
10
|
<script type="module" id="dev-widget-entry">
|
|
66
11
|
import('{{serverUrl}}/src/widgets/{{widgetName}}');
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type http from "node:http";
|
|
1
2
|
import { type Router } from "express";
|
|
2
3
|
/**
|
|
3
4
|
* Install Vite dev server
|
|
@@ -9,4 +10,4 @@ import { type Router } from "express";
|
|
|
9
10
|
* app.use(await widgetsRouter());
|
|
10
11
|
* }
|
|
11
12
|
*/
|
|
12
|
-
export declare const widgetsDevServer: () => Promise<Router>;
|
|
13
|
+
export declare const widgetsDevServer: (httpServer: http.Server) => Promise<Router>;
|
|
@@ -13,7 +13,7 @@ import { assetBaseUrlTransformPlugin } from "./asset-base-url-transform-plugin.j
|
|
|
13
13
|
* app.use(await widgetsRouter());
|
|
14
14
|
* }
|
|
15
15
|
*/
|
|
16
|
-
export const widgetsDevServer = async () => {
|
|
16
|
+
export const widgetsDevServer = async (httpServer) => {
|
|
17
17
|
const router = express.Router();
|
|
18
18
|
const { createServer, searchForWorkspaceRoot, loadConfigFromFile } = await import("vite");
|
|
19
19
|
// Since 0.16.0, the template is a single package that does not rely on workspace.
|
|
@@ -36,9 +36,7 @@ export const widgetsDevServer = async () => {
|
|
|
36
36
|
allowedHosts: true,
|
|
37
37
|
middlewareMode: true,
|
|
38
38
|
hmr: {
|
|
39
|
-
|
|
40
|
-
host: "localhost",
|
|
41
|
-
port: 24678,
|
|
39
|
+
server: httpServer,
|
|
42
40
|
},
|
|
43
41
|
},
|
|
44
42
|
root: webAppRoot,
|
|
@@ -47,7 +45,9 @@ export const widgetsDevServer = async () => {
|
|
|
47
45
|
},
|
|
48
46
|
plugins: [
|
|
49
47
|
...userPlugins,
|
|
50
|
-
assetBaseUrlTransformPlugin({
|
|
48
|
+
assetBaseUrlTransformPlugin({
|
|
49
|
+
devServerOrigin: `http://localhost:${process.env.__PORT ?? "3000"}`,
|
|
50
|
+
}),
|
|
51
51
|
],
|
|
52
52
|
});
|
|
53
53
|
router.use(cors());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widgetsDevServer.js","sourceRoot":"","sources":["../../src/server/widgetsDevServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"widgetsDevServer.js","sourceRoot":"","sources":["../../src/server/widgetsDevServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,OAAO,EAAE,EAAe,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AAEnF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,UAAuB,EACN,EAAE;IACnB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAEhC,MAAM,EAAE,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,GAChE,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAEvB,kFAAkF;IAClF,gFAAgF;IAChF,+FAA+F;IAC/F,IAAI,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;IAEjD,0DAA0D;IAC1D,MAAM,aAAa,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,aAAa,GAAG,sBAAsB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5D,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC;IAED,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,MAAM,EACJ,KAAK,EACL,OAAO,EACP,OAAO,EAAE,WAAW,GAAG,EAAE,EACzB,GAAG,SAAS,EACb,GAAG,YAAY,EAAE,MAAM,IAAI,EAAE,CAAC;IAE/B,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;YACpB,GAAG,EAAE;gBACH,MAAM,EAAE,UAAU;aACnB;SACF;QACD,IAAI,EAAE,UAAU;QAChB,YAAY,EAAE;YACZ,OAAO,EAAE,CAAC,OAAO,EAAE,kBAAkB,CAAC;SACvC;QACD,OAAO,EAAE;YACP,GAAG,WAAW;YACd,2BAA2B,CAAC;gBAC1B,eAAe,EAAE,oBAAoB,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM,EAAE;aACpE,CAAC;SACH;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"}
|
package/dist/test/widget.test.js
CHANGED
|
@@ -43,8 +43,10 @@ describe("McpServer.registerWidget", () => {
|
|
|
43
43
|
const appsSdkResourceCallback = mockRegisterResource.mock
|
|
44
44
|
.calls[0]?.[3];
|
|
45
45
|
expect(appsSdkResourceCallback).toBeDefined();
|
|
46
|
-
const
|
|
47
|
-
const
|
|
46
|
+
const host = "localhost:3000";
|
|
47
|
+
const serverUrl = `http://${host}`;
|
|
48
|
+
const hmrUrl = `ws://${host}`;
|
|
49
|
+
const mockExtra = createMockExtra(host);
|
|
48
50
|
const result = await appsSdkResourceCallback(new URL("ui://widgets/apps-sdk/my-widget.html"), mockExtra);
|
|
49
51
|
expect(mockRegisterTool).toHaveBeenCalled();
|
|
50
52
|
expect(result).toEqual({
|
|
@@ -56,10 +58,10 @@ describe("McpServer.registerWidget", () => {
|
|
|
56
58
|
_meta: {
|
|
57
59
|
"openai/widgetCSP": {
|
|
58
60
|
resource_domains: [serverUrl],
|
|
59
|
-
connect_domains: [
|
|
61
|
+
connect_domains: [serverUrl, hmrUrl],
|
|
60
62
|
},
|
|
61
63
|
"openai/widgetDomain": serverUrl,
|
|
62
|
-
"openai/widgetDescription": "Test
|
|
64
|
+
"openai/widgetDescription": "Test widget",
|
|
63
65
|
},
|
|
64
66
|
},
|
|
65
67
|
],
|
|
@@ -93,10 +95,10 @@ describe("McpServer.registerWidget", () => {
|
|
|
93
95
|
_meta: {
|
|
94
96
|
"openai/widgetCSP": {
|
|
95
97
|
resource_domains: [serverUrl],
|
|
96
|
-
connect_domains: [],
|
|
98
|
+
connect_domains: [serverUrl],
|
|
97
99
|
},
|
|
98
100
|
"openai/widgetDomain": serverUrl,
|
|
99
|
-
"openai/widgetDescription": "Test
|
|
101
|
+
"openai/widgetDescription": "Test widget",
|
|
100
102
|
},
|
|
101
103
|
},
|
|
102
104
|
],
|
|
@@ -134,7 +136,10 @@ describe("McpServer.registerWidget", () => {
|
|
|
134
136
|
expect(mockRegisterResource).toHaveBeenCalledTimes(2);
|
|
135
137
|
const appsSdkCallback = mockRegisterResource.mock
|
|
136
138
|
.calls[0]?.[3];
|
|
137
|
-
const appsSdkResult = await appsSdkCallback(new URL("ui://widgets/apps-sdk/my-widget.html"), createMockExtra("
|
|
139
|
+
const appsSdkResult = await appsSdkCallback(new URL("ui://widgets/apps-sdk/my-widget.html"), createMockExtra("localhost:3000"));
|
|
140
|
+
const host = "localhost:3000";
|
|
141
|
+
const serverUrl = `http://${host}`;
|
|
142
|
+
const hmrUrl = `ws://${host}`;
|
|
138
143
|
expect(appsSdkResult).toEqual({
|
|
139
144
|
contents: [
|
|
140
145
|
{
|
|
@@ -143,11 +148,11 @@ describe("McpServer.registerWidget", () => {
|
|
|
143
148
|
text: expect.stringContaining('<div id="root"></div>'),
|
|
144
149
|
_meta: {
|
|
145
150
|
"openai/widgetCSP": {
|
|
146
|
-
resource_domains: [
|
|
147
|
-
connect_domains: [
|
|
151
|
+
resource_domains: [serverUrl],
|
|
152
|
+
connect_domains: [serverUrl, hmrUrl],
|
|
148
153
|
},
|
|
149
|
-
"openai/widgetDomain":
|
|
150
|
-
"openai/widgetDescription": "Test
|
|
154
|
+
"openai/widgetDomain": serverUrl,
|
|
155
|
+
"openai/widgetDescription": "Test widget",
|
|
151
156
|
"openai/widgetPrefersBorder": true,
|
|
152
157
|
},
|
|
153
158
|
},
|
|
@@ -157,7 +162,7 @@ describe("McpServer.registerWidget", () => {
|
|
|
157
162
|
const extAppsResourceCallback = mockRegisterResource.mock
|
|
158
163
|
.calls[1]?.[3];
|
|
159
164
|
expect(extAppsResourceCallback).toBeDefined();
|
|
160
|
-
const extAppsResult = await extAppsResourceCallback(new URL("ui://widgets/ext-apps/my-widget.html"), createMockExtra(
|
|
165
|
+
const extAppsResult = await extAppsResourceCallback(new URL("ui://widgets/ext-apps/my-widget.html"), createMockExtra(host));
|
|
161
166
|
expect(extAppsResult).toEqual({
|
|
162
167
|
contents: [
|
|
163
168
|
{
|
|
@@ -167,10 +172,10 @@ describe("McpServer.registerWidget", () => {
|
|
|
167
172
|
_meta: {
|
|
168
173
|
ui: {
|
|
169
174
|
csp: {
|
|
170
|
-
resourceDomains: [
|
|
171
|
-
connectDomains: [
|
|
175
|
+
resourceDomains: [serverUrl],
|
|
176
|
+
connectDomains: [serverUrl, hmrUrl],
|
|
172
177
|
},
|
|
173
|
-
domain:
|
|
178
|
+
domain: serverUrl,
|
|
174
179
|
},
|
|
175
180
|
},
|
|
176
181
|
},
|
|
@@ -214,12 +219,15 @@ describe("McpServer.registerWidget", () => {
|
|
|
214
219
|
server.registerWidget("override-test", mockRegisterResourceConfig, mockToolConfig, mockToolCallback);
|
|
215
220
|
const appsSdkCallback = mockRegisterResource.mock
|
|
216
221
|
.calls[0]?.[3];
|
|
217
|
-
const
|
|
222
|
+
const host = `localhost:3000`;
|
|
223
|
+
const serverUrl = `http://${host}`;
|
|
224
|
+
const hmrUrl = `ws://${host}`;
|
|
225
|
+
const result = await appsSdkCallback(new URL("ui://widgets/apps-sdk/override-test.html"), createMockExtra(host));
|
|
218
226
|
const meta = result.contents[0]?._meta;
|
|
219
227
|
// CSP arrays are merged with union - all unique domains from defaults and user config are preserved
|
|
220
228
|
expect(meta["openai/widgetCSP"]).toEqual({
|
|
221
|
-
resource_domains: [
|
|
222
|
-
connect_domains: [
|
|
229
|
+
resource_domains: [serverUrl, "https://from-ui-csp.com"],
|
|
230
|
+
connect_domains: [serverUrl, hmrUrl, "https://from-ui-csp.com"],
|
|
223
231
|
frame_domains: undefined,
|
|
224
232
|
redirect_domains: undefined,
|
|
225
233
|
});
|
|
@@ -228,7 +236,7 @@ describe("McpServer.registerWidget", () => {
|
|
|
228
236
|
// PrefersBorder should be overridden by direct openai/* key (highest priority)
|
|
229
237
|
expect(meta["openai/widgetPrefersBorder"]).toBe(true);
|
|
230
238
|
// Description should be from defaults (toolConfig.description)
|
|
231
|
-
expect(meta["openai/widgetDescription"]).toBe("Test
|
|
239
|
+
expect(meta["openai/widgetDescription"]).toBe("Test widget");
|
|
232
240
|
});
|
|
233
241
|
it("should register tool with ui.resourceUri metadata only", async () => {
|
|
234
242
|
const mockToolCallback = vi.fn();
|