@mcp-use/inspector 0.6.1 → 0.7.0-canary.4
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/dist/cli.js +297 -20
- package/dist/client/assets/__vite-browser-external-CHS79mP1.js +8 -0
- package/dist/client/assets/browser-DMU1DNWH.js +38211 -0
- package/dist/client/assets/chunk-VL2OQCWN-BSt8dT5C.js +6475 -0
- package/dist/client/assets/display-YIYC6WJE-BffT78jn.js +44742 -0
- package/dist/client/assets/embeddings-DTFNzTmk.js +21 -0
- package/dist/client/assets/index-B1pgTXiT.js +94617 -0
- package/dist/client/assets/index-BANvZe0e.js +17535 -0
- package/dist/client/assets/index-BqRMxNFR.js +10699 -0
- package/dist/client/assets/index-DSsmOzZI.js +5371 -0
- package/dist/client/assets/index-DX0TIfSM.js +102 -0
- package/dist/client/assets/index-Dz-Y_VJx.js +1780 -0
- package/dist/client/assets/index-kVFYovMy.css +5752 -0
- package/dist/client/assets/path-QsnVvLoj.js +62 -0
- package/dist/client/assets/transport-wrapper-browser-ChPHVnHg.js +165 -0
- package/dist/client/assets/winston-BAYefLfc.js +12326 -0
- package/dist/client/index.html +3 -3
- package/dist/server/{chunk-WYBXXYSP.js → chunk-26WTIZ4S.js} +1 -1
- package/dist/server/{chunk-PYGYQT2G.js → chunk-6ZFXPXO4.js} +6 -6
- package/dist/server/chunk-CVECQ7BJ.js +78 -0
- package/dist/server/{chunk-DGUMOD7P.js → chunk-KW44WB52.js} +94 -11
- package/dist/server/chunk-PKBMQBKP.js +7 -0
- package/dist/server/{chunk-37X7HLUV.js → chunk-V5FEV5SU.js} +89 -14
- package/dist/server/{chunk-555LGZ3I.js → chunk-XU7SXB3C.js} +133 -10
- package/dist/server/cli.js +6 -4
- package/dist/server/index.js +7 -5
- package/dist/server/middleware.d.ts +5 -1
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/middleware.js +7 -5
- package/dist/server/rpc-log-bus.d.ts +17 -0
- package/dist/server/rpc-log-bus.d.ts.map +1 -0
- package/dist/server/rpc-log-bus.js +7 -0
- package/dist/server/server.js +6 -4
- package/dist/server/shared-routes.d.ts.map +1 -1
- package/dist/server/shared-routes.js +4 -2
- package/dist/server/shared-static.js +3 -2
- package/dist/server/shared-utils-browser.d.ts +2 -1
- package/dist/server/shared-utils-browser.d.ts.map +1 -1
- package/dist/server/shared-utils-browser.js +2 -1
- package/dist/server/shared-utils.d.ts +4 -1
- package/dist/server/shared-utils.d.ts.map +1 -1
- package/dist/server/shared-utils.js +2 -1
- package/dist/server/transport-wrapper.d.ts +6 -0
- package/dist/server/transport-wrapper.d.ts.map +1 -0
- package/dist/server/transport-wrapper.js +68 -0
- package/dist/server/utils.js +1 -0
- package/package.json +12 -3
- package/dist/client/assets/__vite-browser-external-DFygW7-s.js +0 -1
- package/dist/client/assets/chunk-VL2OQCWN-iRVOQjqe.js +0 -8
- package/dist/client/assets/display-LIYVTGEU-D2dm8q2H.js +0 -30
- package/dist/client/assets/embeddings-Dcyp0Vlp.js +0 -1
- package/dist/client/assets/index-6zrNEwtM.js +0 -4
- package/dist/client/assets/index-CAnbiFOL.css +0 -1
- package/dist/client/assets/index-CB1s6Wr6.js +0 -146
- package/dist/client/assets/index-CoMldIFv.js +0 -2
- package/dist/client/assets/index-DRz5BQNA.js +0 -1
- package/dist/client/assets/index-DUf1336L.js +0 -1559
- package/dist/client/assets/index-DmIKR5St.js +0 -1
- package/dist/client/assets/index-DpUpZFq2.js +0 -25
- package/dist/client/assets/index-DzegZXPW.js +0 -40
- package/dist/client/assets/langfuse-C4HKZ3NL-vCtAvQQV.js +0 -564
- package/dist/client/assets/path-C9FudP8b.js +0 -1
- package/dist/client/assets/winston-BVJ8PyEn.js +0 -37
package/dist/client/index.html
CHANGED
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
rel="stylesheet"
|
|
28
28
|
/>
|
|
29
29
|
<title>Inspector | mcp-use</title>
|
|
30
|
-
<script type="module" crossorigin src="/inspector/assets/index-
|
|
31
|
-
<link rel="stylesheet" crossorigin href="/inspector/assets/index-
|
|
32
|
-
<script>window.__INSPECTOR_VERSION__ = "0.
|
|
30
|
+
<script type="module" crossorigin src="/inspector/assets/index-B1pgTXiT.js"></script>
|
|
31
|
+
<link rel="stylesheet" crossorigin href="/inspector/assets/index-kVFYovMy.css">
|
|
32
|
+
<script>window.__INSPECTOR_VERSION__ = "0.7.0-canary.4";</script>
|
|
33
33
|
</head>
|
|
34
34
|
<body>
|
|
35
35
|
<script>
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
registerInspectorRoutes
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XU7SXB3C.js";
|
|
4
4
|
import {
|
|
5
5
|
registerStaticRoutes
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-26WTIZ4S.js";
|
|
7
7
|
import {
|
|
8
8
|
checkClientFiles,
|
|
9
9
|
getClientDistPath
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-V5FEV5SU.js";
|
|
11
11
|
|
|
12
12
|
// src/server/middleware.ts
|
|
13
13
|
import { Hono } from "hono";
|
|
14
|
-
function mountInspector(app) {
|
|
14
|
+
function mountInspector(app, config) {
|
|
15
15
|
const clientDistPath = getClientDistPath();
|
|
16
16
|
if (!checkClientFiles(clientDistPath)) {
|
|
17
17
|
console.warn(
|
|
@@ -22,12 +22,12 @@ function mountInspector(app) {
|
|
|
22
22
|
);
|
|
23
23
|
}
|
|
24
24
|
if (app instanceof Hono) {
|
|
25
|
-
registerInspectorRoutes(app);
|
|
25
|
+
registerInspectorRoutes(app, config);
|
|
26
26
|
registerStaticRoutes(app, clientDistPath);
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
const honoApp = new Hono();
|
|
30
|
-
registerInspectorRoutes(honoApp);
|
|
30
|
+
registerInspectorRoutes(honoApp, config);
|
|
31
31
|
registerStaticRoutes(honoApp, clientDistPath);
|
|
32
32
|
app.use((req, res, next) => {
|
|
33
33
|
const url = new URL(req.url || "", `http://${req.headers.host}`);
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__publicField
|
|
3
|
+
} from "./chunk-PKBMQBKP.js";
|
|
4
|
+
|
|
5
|
+
// src/server/rpc-log-bus.ts
|
|
6
|
+
var SimpleEventEmitter = class {
|
|
7
|
+
constructor() {
|
|
8
|
+
__publicField(this, "listeners", /* @__PURE__ */ new Map());
|
|
9
|
+
}
|
|
10
|
+
on(event, listener) {
|
|
11
|
+
if (!this.listeners.has(event)) {
|
|
12
|
+
this.listeners.set(event, /* @__PURE__ */ new Set());
|
|
13
|
+
}
|
|
14
|
+
this.listeners.get(event).add(listener);
|
|
15
|
+
}
|
|
16
|
+
off(event, listener) {
|
|
17
|
+
this.listeners.get(event)?.delete(listener);
|
|
18
|
+
}
|
|
19
|
+
emit(event, ...args) {
|
|
20
|
+
this.listeners.get(event)?.forEach((listener) => {
|
|
21
|
+
try {
|
|
22
|
+
listener(...args);
|
|
23
|
+
} catch (e) {
|
|
24
|
+
console.error("Error in event listener:", e);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var RpcLogBus = class {
|
|
30
|
+
constructor() {
|
|
31
|
+
__publicField(this, "emitter", new SimpleEventEmitter());
|
|
32
|
+
__publicField(this, "bufferByServer", /* @__PURE__ */ new Map());
|
|
33
|
+
}
|
|
34
|
+
publish(event) {
|
|
35
|
+
const buffer = this.bufferByServer.get(event.serverId) ?? [];
|
|
36
|
+
buffer.push(event);
|
|
37
|
+
if (buffer.length > 1e3) {
|
|
38
|
+
buffer.shift();
|
|
39
|
+
}
|
|
40
|
+
this.bufferByServer.set(event.serverId, buffer);
|
|
41
|
+
this.emitter.emit("event", event);
|
|
42
|
+
}
|
|
43
|
+
subscribe(serverIds, listener) {
|
|
44
|
+
const filter = new Set(serverIds);
|
|
45
|
+
const handler = (event) => {
|
|
46
|
+
if (filter.size === 0 || filter.has(event.serverId)) listener(event);
|
|
47
|
+
};
|
|
48
|
+
this.emitter.on("event", handler);
|
|
49
|
+
return () => this.emitter.off("event", handler);
|
|
50
|
+
}
|
|
51
|
+
getBuffer(serverIds, limit) {
|
|
52
|
+
const filter = new Set(serverIds);
|
|
53
|
+
const all = [];
|
|
54
|
+
for (const [serverId, buf] of this.bufferByServer.entries()) {
|
|
55
|
+
if (filter.size > 0 && !filter.has(serverId)) continue;
|
|
56
|
+
all.push(...buf);
|
|
57
|
+
}
|
|
58
|
+
all.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
59
|
+
if (limit === 0) return [];
|
|
60
|
+
if (!Number.isFinite(limit) || limit < 0) return all;
|
|
61
|
+
return all.slice(0, limit);
|
|
62
|
+
}
|
|
63
|
+
clear(serverIds) {
|
|
64
|
+
if (serverIds && serverIds.length > 0) {
|
|
65
|
+
const filter = new Set(serverIds);
|
|
66
|
+
for (const serverId of filter) {
|
|
67
|
+
this.bufferByServer.delete(serverId);
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
this.bufferByServer.clear();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
var rpcLogBus = new RpcLogBus();
|
|
75
|
+
|
|
76
|
+
export {
|
|
77
|
+
rpcLogBus
|
|
78
|
+
};
|
|
@@ -312,7 +312,16 @@ function generateWidgetContainerHtml(basePath, toolId) {
|
|
|
312
312
|
`;
|
|
313
313
|
}
|
|
314
314
|
function generateWidgetContentHtml(widgetData) {
|
|
315
|
-
const {
|
|
315
|
+
const {
|
|
316
|
+
serverId,
|
|
317
|
+
uri,
|
|
318
|
+
toolInput,
|
|
319
|
+
toolOutput,
|
|
320
|
+
resourceData,
|
|
321
|
+
toolId,
|
|
322
|
+
devServerBaseUrl,
|
|
323
|
+
theme
|
|
324
|
+
} = widgetData;
|
|
316
325
|
console.log("[Widget Content] Using pre-fetched resource for:", {
|
|
317
326
|
serverId,
|
|
318
327
|
uri
|
|
@@ -343,23 +352,31 @@ function generateWidgetContentHtml(widgetData) {
|
|
|
343
352
|
const safeToolOutput = JSON.stringify(toolOutput ?? null).replace(/</g, "\\u003c").replace(/>/g, "\\u003e");
|
|
344
353
|
const safeToolId = JSON.stringify(toolId);
|
|
345
354
|
const safeWidgetStateKey = JSON.stringify(widgetStateKey);
|
|
355
|
+
const safeTheme = JSON.stringify(theme === "dark" ? "dark" : "light");
|
|
346
356
|
const apiScript = `
|
|
347
357
|
<script>
|
|
348
358
|
(function() {
|
|
349
359
|
'use strict';
|
|
350
360
|
|
|
351
361
|
// Change URL to "/" for React Router compatibility
|
|
352
|
-
if
|
|
362
|
+
// Skip if running in Inspector dev-widget proxy to prevent redirecting iframe to Inspector home
|
|
363
|
+
if (window.location.pathname !== '/' && !window.location.pathname.includes('/dev-widget/')) {
|
|
353
364
|
history.replaceState(null, '', '/');
|
|
354
365
|
}
|
|
355
366
|
|
|
367
|
+
// Inject MCP widget utilities for Image component and file access
|
|
368
|
+
window.__mcpPublicUrl = ${devServerBaseUrl ? `"${devServerBaseUrl}/mcp-use/public"` : '""'};
|
|
369
|
+
window.__getFile = function(filename) {
|
|
370
|
+
return ${devServerBaseUrl ? `"${devServerBaseUrl}/mcp-use/widgets/"` : '""'} + filename;
|
|
371
|
+
};
|
|
372
|
+
|
|
356
373
|
const openaiAPI = {
|
|
357
374
|
toolInput: ${safeToolInput},
|
|
358
375
|
toolOutput: ${safeToolOutput},
|
|
359
376
|
toolResponseMetadata: null,
|
|
360
377
|
displayMode: 'inline',
|
|
361
378
|
maxHeight: 600,
|
|
362
|
-
theme:
|
|
379
|
+
theme: ${safeTheme},
|
|
363
380
|
locale: 'en-US',
|
|
364
381
|
safeArea: { insets: { top: 0, bottom: 0, left: 0, right: 0 } },
|
|
365
382
|
userAgent: {},
|
|
@@ -432,6 +449,20 @@ function generateWidgetContentHtml(widgetData) {
|
|
|
432
449
|
return this.sendFollowupTurn(prompt);
|
|
433
450
|
},
|
|
434
451
|
|
|
452
|
+
async notifyIntrinsicHeight(height) {
|
|
453
|
+
console.log('[OpenAI Widget] notifyIntrinsicHeight called with:', height);
|
|
454
|
+
if (typeof height !== 'number' || height < 0) {
|
|
455
|
+
console.error('[OpenAI Widget] Invalid height value:', height);
|
|
456
|
+
throw new Error('Height must be a non-negative number');
|
|
457
|
+
}
|
|
458
|
+
const message = {
|
|
459
|
+
type: 'openai:notifyIntrinsicHeight',
|
|
460
|
+
height
|
|
461
|
+
};
|
|
462
|
+
console.log('[OpenAI Widget] Sending postMessage to parent:', message);
|
|
463
|
+
window.parent.postMessage(message, '*');
|
|
464
|
+
},
|
|
465
|
+
|
|
435
466
|
openExternal(payload) {
|
|
436
467
|
const href = typeof payload === 'string' ? payload : payload?.href;
|
|
437
468
|
if (href) {
|
|
@@ -476,6 +507,18 @@ function generateWidgetContentHtml(widgetData) {
|
|
|
476
507
|
} catch (err) {}
|
|
477
508
|
}, 0);
|
|
478
509
|
|
|
510
|
+
// Listen for widget state requests from inspector
|
|
511
|
+
window.addEventListener('message', (event) => {
|
|
512
|
+
if (event.data?.type === 'mcp-inspector:getWidgetState') {
|
|
513
|
+
window.parent.postMessage({
|
|
514
|
+
type: 'mcp-inspector:widgetStateResponse',
|
|
515
|
+
toolId: event.data.toolId,
|
|
516
|
+
state: openaiAPI.widgetState
|
|
517
|
+
}, '*');
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
|
|
479
522
|
// Listen for globals changes from parent (for displayMode, theme, etc.)
|
|
480
523
|
window.addEventListener('message', (event) => {
|
|
481
524
|
// Handle new general globalsChanged message
|
|
@@ -602,34 +645,58 @@ function generateWidgetContentHtml(widgetData) {
|
|
|
602
645
|
console.log("[Widget Content] Generated HTML length:", modifiedHtml.length);
|
|
603
646
|
return { html: modifiedHtml };
|
|
604
647
|
}
|
|
605
|
-
function getWidgetSecurityHeaders(widgetCSP) {
|
|
648
|
+
function getWidgetSecurityHeaders(widgetCSP, devServerBaseUrl) {
|
|
606
649
|
const trustedCdns = [
|
|
607
650
|
"https://persistent.oaistatic.com",
|
|
608
651
|
"https://*.oaistatic.com",
|
|
609
652
|
"https://unpkg.com",
|
|
610
653
|
"https://cdn.jsdelivr.net",
|
|
611
654
|
"https://cdnjs.cloudflare.com",
|
|
612
|
-
"https://cdn.skypack.dev"
|
|
655
|
+
"https://cdn.skypack.dev",
|
|
656
|
+
"https://*.openai.com"
|
|
613
657
|
];
|
|
614
|
-
const
|
|
658
|
+
const prodResourceDomains = [...trustedCdns];
|
|
615
659
|
if (widgetCSP?.resource_domains) {
|
|
616
|
-
|
|
660
|
+
prodResourceDomains.push(...widgetCSP.resource_domains);
|
|
661
|
+
}
|
|
662
|
+
const prodResourceDomainsStr = prodResourceDomains.join(" ");
|
|
663
|
+
let devServerOrigin = null;
|
|
664
|
+
const allResourceDomains = [...prodResourceDomains];
|
|
665
|
+
if (devServerBaseUrl) {
|
|
666
|
+
try {
|
|
667
|
+
devServerOrigin = new URL(devServerBaseUrl).origin;
|
|
668
|
+
allResourceDomains.push(devServerOrigin);
|
|
669
|
+
} catch (e) {
|
|
670
|
+
console.warn(`[CSP] Invalid devServerBaseUrl: ${devServerBaseUrl}`);
|
|
671
|
+
}
|
|
617
672
|
}
|
|
618
673
|
const resourceDomainsStr = allResourceDomains.join(" ");
|
|
674
|
+
let imgSrc = "'self' data: https: blob:";
|
|
675
|
+
if (devServerOrigin) {
|
|
676
|
+
imgSrc = `'self' data: https: blob: ${devServerOrigin}`;
|
|
677
|
+
}
|
|
678
|
+
let mediaSrc = "'self' data: https: blob:";
|
|
679
|
+
if (devServerOrigin) {
|
|
680
|
+
mediaSrc = `'self' data: https: blob: ${devServerOrigin}`;
|
|
681
|
+
}
|
|
682
|
+
let fontSrc = `'self' data: ${resourceDomainsStr}`;
|
|
683
|
+
if (devServerOrigin) {
|
|
684
|
+
fontSrc = `'self' data: https: http: ${resourceDomainsStr}`;
|
|
685
|
+
}
|
|
619
686
|
let connectSrc = "'self' https: wss: ws:";
|
|
620
687
|
if (widgetCSP?.connect_domains && widgetCSP.connect_domains.length > 0) {
|
|
621
688
|
connectSrc = `'self' ${widgetCSP.connect_domains.join(" ")} https: wss: ws:`;
|
|
622
689
|
}
|
|
623
|
-
|
|
690
|
+
const headers = {
|
|
624
691
|
"Content-Security-Policy": [
|
|
625
692
|
"default-src 'self'",
|
|
626
693
|
`script-src 'self' 'unsafe-inline' 'unsafe-eval' ${resourceDomainsStr}`,
|
|
627
694
|
"worker-src 'self' blob:",
|
|
628
695
|
"child-src 'self' blob:",
|
|
629
696
|
`style-src 'self' 'unsafe-inline' ${resourceDomainsStr}`,
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
`font-src
|
|
697
|
+
`img-src ${imgSrc}`,
|
|
698
|
+
`media-src ${mediaSrc}`,
|
|
699
|
+
`font-src ${fontSrc}`,
|
|
633
700
|
`connect-src ${connectSrc}`,
|
|
634
701
|
"frame-ancestors 'self'"
|
|
635
702
|
].join("; "),
|
|
@@ -639,6 +706,22 @@ function getWidgetSecurityHeaders(widgetCSP) {
|
|
|
639
706
|
Pragma: "no-cache",
|
|
640
707
|
Expires: "0"
|
|
641
708
|
};
|
|
709
|
+
if (devServerOrigin) {
|
|
710
|
+
const prodConnectSrc = "'self' https: wss: ws:";
|
|
711
|
+
headers["Content-Security-Policy-Report-Only"] = [
|
|
712
|
+
"default-src 'self'",
|
|
713
|
+
`script-src 'self' 'unsafe-inline' 'unsafe-eval' ${prodResourceDomainsStr}`,
|
|
714
|
+
"worker-src 'self' blob:",
|
|
715
|
+
"child-src 'self' blob:",
|
|
716
|
+
`style-src 'self' 'unsafe-inline' ${prodResourceDomainsStr}`,
|
|
717
|
+
"img-src 'self' data: https: blob:",
|
|
718
|
+
"media-src 'self' data: https: blob:",
|
|
719
|
+
`font-src 'self' data: ${prodResourceDomainsStr}`,
|
|
720
|
+
`connect-src ${prodConnectSrc}`,
|
|
721
|
+
"frame-ancestors 'self'"
|
|
722
|
+
].join("; ");
|
|
723
|
+
}
|
|
724
|
+
return headers;
|
|
642
725
|
}
|
|
643
726
|
|
|
644
727
|
export {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
__publicField
|
|
7
|
+
};
|
|
@@ -267,7 +267,9 @@ function storeWidgetData(data) {
|
|
|
267
267
|
toolOutput,
|
|
268
268
|
resourceData,
|
|
269
269
|
toolId,
|
|
270
|
-
widgetCSP
|
|
270
|
+
widgetCSP: _widgetCSP,
|
|
271
|
+
devWidgetUrl,
|
|
272
|
+
devServerBaseUrl
|
|
271
273
|
} = data;
|
|
272
274
|
console.log("[Widget Store] Received request for toolId:", toolId);
|
|
273
275
|
console.log("[Widget Store] Fields:", {
|
|
@@ -276,7 +278,9 @@ function storeWidgetData(data) {
|
|
|
276
278
|
hasResourceData: !!resourceData,
|
|
277
279
|
hasToolInput: !!toolInput,
|
|
278
280
|
hasToolOutput: !!toolOutput,
|
|
279
|
-
hasWidgetCSP: !!
|
|
281
|
+
hasWidgetCSP: !!_widgetCSP,
|
|
282
|
+
devWidgetUrl,
|
|
283
|
+
devServerBaseUrl
|
|
280
284
|
});
|
|
281
285
|
if (!serverId || !uri || !toolId || !resourceData) {
|
|
282
286
|
const missingFields = [];
|
|
@@ -298,7 +302,9 @@ function storeWidgetData(data) {
|
|
|
298
302
|
resourceData,
|
|
299
303
|
toolId,
|
|
300
304
|
timestamp: Date.now(),
|
|
301
|
-
widgetCSP
|
|
305
|
+
widgetCSP: _widgetCSP,
|
|
306
|
+
devWidgetUrl,
|
|
307
|
+
devServerBaseUrl
|
|
302
308
|
});
|
|
303
309
|
console.log("[Widget Store] Data stored successfully for toolId:", toolId);
|
|
304
310
|
return { success: true };
|
|
@@ -341,7 +347,17 @@ function generateWidgetContainerHtml(basePath, toolId) {
|
|
|
341
347
|
`;
|
|
342
348
|
}
|
|
343
349
|
function generateWidgetContentHtml(widgetData) {
|
|
344
|
-
const {
|
|
350
|
+
const {
|
|
351
|
+
serverId,
|
|
352
|
+
uri,
|
|
353
|
+
toolInput,
|
|
354
|
+
toolOutput,
|
|
355
|
+
resourceData,
|
|
356
|
+
toolId,
|
|
357
|
+
widgetCSP: _widgetCSP,
|
|
358
|
+
devServerBaseUrl,
|
|
359
|
+
theme
|
|
360
|
+
} = widgetData;
|
|
345
361
|
console.log("[Widget Content] Using pre-fetched resource for:", {
|
|
346
362
|
serverId,
|
|
347
363
|
uri
|
|
@@ -372,23 +388,31 @@ function generateWidgetContentHtml(widgetData) {
|
|
|
372
388
|
const safeToolOutput = JSON.stringify(toolOutput ?? null).replace(/</g, "\\u003c").replace(/>/g, "\\u003e");
|
|
373
389
|
const safeToolId = JSON.stringify(toolId);
|
|
374
390
|
const safeWidgetStateKey = JSON.stringify(widgetStateKey);
|
|
391
|
+
const safeTheme = JSON.stringify(theme === "dark" ? "dark" : "light");
|
|
375
392
|
const apiScript = `
|
|
376
393
|
<script>
|
|
377
394
|
(function() {
|
|
378
395
|
'use strict';
|
|
379
396
|
|
|
380
397
|
// Change URL to "/" for React Router compatibility
|
|
381
|
-
if
|
|
398
|
+
// Skip if running in Inspector dev-widget proxy to prevent redirecting iframe to Inspector home
|
|
399
|
+
if (window.location.pathname !== '/' && !window.location.pathname.includes('/dev-widget/')) {
|
|
382
400
|
history.replaceState(null, '', '/');
|
|
383
401
|
}
|
|
384
402
|
|
|
403
|
+
// Inject MCP widget utilities for Image component and file access
|
|
404
|
+
window.__mcpPublicUrl = ${devServerBaseUrl ? `"${devServerBaseUrl}/mcp-use/public"` : '""'};
|
|
405
|
+
window.__getFile = function(filename) {
|
|
406
|
+
return ${devServerBaseUrl ? `"${devServerBaseUrl}/mcp-use/widgets/"` : '""'} + filename;
|
|
407
|
+
};
|
|
408
|
+
|
|
385
409
|
const openaiAPI = {
|
|
386
410
|
toolInput: ${safeToolInput},
|
|
387
411
|
toolOutput: ${safeToolOutput},
|
|
388
412
|
toolResponseMetadata: null,
|
|
389
413
|
displayMode: 'inline',
|
|
390
414
|
maxHeight: 600,
|
|
391
|
-
theme:
|
|
415
|
+
theme: ${safeTheme},
|
|
392
416
|
locale: 'en-US',
|
|
393
417
|
safeArea: { insets: { top: 0, bottom: 0, left: 0, right: 0 } },
|
|
394
418
|
userAgent: {},
|
|
@@ -483,6 +507,17 @@ function generateWidgetContentHtml(widgetData) {
|
|
|
483
507
|
enumerable: true
|
|
484
508
|
});
|
|
485
509
|
|
|
510
|
+
// Listen for widget state requests from inspector
|
|
511
|
+
window.addEventListener('message', (event) => {
|
|
512
|
+
if (event.data?.type === 'mcp-inspector:getWidgetState') {
|
|
513
|
+
window.parent.postMessage({
|
|
514
|
+
type: 'mcp-inspector:widgetStateResponse',
|
|
515
|
+
toolId: event.data.toolId,
|
|
516
|
+
state: openaiAPI.widgetState
|
|
517
|
+
}, '*');
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
|
|
486
521
|
setTimeout(() => {
|
|
487
522
|
try {
|
|
488
523
|
const globalsEvent = new CustomEvent('openai:set_globals', {
|
|
@@ -536,34 +571,58 @@ function generateWidgetContentHtml(widgetData) {
|
|
|
536
571
|
console.log("[Widget Content] Generated HTML length:", modifiedHtml.length);
|
|
537
572
|
return { html: modifiedHtml };
|
|
538
573
|
}
|
|
539
|
-
function getWidgetSecurityHeaders(widgetCSP) {
|
|
574
|
+
function getWidgetSecurityHeaders(widgetCSP, devServerBaseUrl) {
|
|
540
575
|
const trustedCdns = [
|
|
541
576
|
"https://persistent.oaistatic.com",
|
|
542
577
|
"https://*.oaistatic.com",
|
|
543
578
|
"https://unpkg.com",
|
|
544
579
|
"https://cdn.jsdelivr.net",
|
|
545
580
|
"https://cdnjs.cloudflare.com",
|
|
546
|
-
"https://cdn.skypack.dev"
|
|
581
|
+
"https://cdn.skypack.dev",
|
|
582
|
+
"https://*.openai.com"
|
|
547
583
|
];
|
|
548
|
-
const
|
|
584
|
+
const prodResourceDomains = [...trustedCdns];
|
|
549
585
|
if (widgetCSP?.resource_domains) {
|
|
550
|
-
|
|
586
|
+
prodResourceDomains.push(...widgetCSP.resource_domains);
|
|
587
|
+
}
|
|
588
|
+
const prodResourceDomainsStr = prodResourceDomains.join(" ");
|
|
589
|
+
let devServerOrigin = null;
|
|
590
|
+
const allResourceDomains = [...prodResourceDomains];
|
|
591
|
+
if (devServerBaseUrl) {
|
|
592
|
+
try {
|
|
593
|
+
devServerOrigin = new URL(devServerBaseUrl).origin;
|
|
594
|
+
allResourceDomains.push(devServerOrigin);
|
|
595
|
+
} catch (e) {
|
|
596
|
+
console.warn(`[CSP] Invalid devServerBaseUrl: ${devServerBaseUrl}`);
|
|
597
|
+
}
|
|
551
598
|
}
|
|
552
599
|
const resourceDomainsStr = allResourceDomains.join(" ");
|
|
600
|
+
let imgSrc = "'self' data: https: blob:";
|
|
601
|
+
if (devServerOrigin) {
|
|
602
|
+
imgSrc = `'self' data: https: blob: ${devServerOrigin}`;
|
|
603
|
+
}
|
|
604
|
+
let mediaSrc = "'self' data: https: blob:";
|
|
605
|
+
if (devServerOrigin) {
|
|
606
|
+
mediaSrc = `'self' data: https: blob: ${devServerOrigin}`;
|
|
607
|
+
}
|
|
608
|
+
let fontSrc = `'self' data: ${resourceDomainsStr}`;
|
|
609
|
+
if (devServerOrigin) {
|
|
610
|
+
fontSrc = `'self' data: https: http: ${resourceDomainsStr}`;
|
|
611
|
+
}
|
|
553
612
|
let connectSrc = "'self' https: wss: ws:";
|
|
554
613
|
if (widgetCSP?.connect_domains && widgetCSP.connect_domains.length > 0) {
|
|
555
614
|
connectSrc = `'self' ${widgetCSP.connect_domains.join(" ")} https: wss: ws:`;
|
|
556
615
|
}
|
|
557
|
-
|
|
616
|
+
const headers = {
|
|
558
617
|
"Content-Security-Policy": [
|
|
559
618
|
"default-src 'self'",
|
|
560
619
|
`script-src 'self' 'unsafe-inline' 'unsafe-eval' ${resourceDomainsStr}`,
|
|
561
620
|
"worker-src 'self' blob:",
|
|
562
621
|
"child-src 'self' blob:",
|
|
563
622
|
`style-src 'self' 'unsafe-inline' ${resourceDomainsStr}`,
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
`font-src
|
|
623
|
+
`img-src ${imgSrc}`,
|
|
624
|
+
`media-src ${mediaSrc}`,
|
|
625
|
+
`font-src ${fontSrc}`,
|
|
567
626
|
`connect-src ${connectSrc}`,
|
|
568
627
|
"frame-ancestors 'self'"
|
|
569
628
|
].join("; "),
|
|
@@ -573,6 +632,22 @@ function getWidgetSecurityHeaders(widgetCSP) {
|
|
|
573
632
|
Pragma: "no-cache",
|
|
574
633
|
Expires: "0"
|
|
575
634
|
};
|
|
635
|
+
if (devServerOrigin) {
|
|
636
|
+
const prodConnectSrc = "'self' https: wss: ws:";
|
|
637
|
+
headers["Content-Security-Policy-Report-Only"] = [
|
|
638
|
+
"default-src 'self'",
|
|
639
|
+
`script-src 'self' 'unsafe-inline' 'unsafe-eval' ${prodResourceDomainsStr}`,
|
|
640
|
+
"worker-src 'self' blob:",
|
|
641
|
+
"child-src 'self' blob:",
|
|
642
|
+
`style-src 'self' 'unsafe-inline' ${prodResourceDomainsStr}`,
|
|
643
|
+
"img-src 'self' data: https: blob:",
|
|
644
|
+
"media-src 'self' data: https: blob:",
|
|
645
|
+
`font-src 'self' data: ${prodResourceDomainsStr}`,
|
|
646
|
+
`connect-src ${prodConnectSrc}`,
|
|
647
|
+
"frame-ancestors 'self'"
|
|
648
|
+
].join("; ");
|
|
649
|
+
}
|
|
650
|
+
return headers;
|
|
576
651
|
}
|
|
577
652
|
|
|
578
653
|
export {
|