@mcp-use/inspector 0.6.1 → 0.7.0

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 (61) hide show
  1. package/dist/cli.js +295 -19
  2. package/dist/client/assets/__vite-browser-external-CHS79mP1.js +8 -0
  3. package/dist/client/assets/browser-BdCJ_qyB.js +38211 -0
  4. package/dist/client/assets/chunk-VL2OQCWN-CxD8xDNw.js +6475 -0
  5. package/dist/client/assets/display-YIYC6WJE-B6ZSv77R.js +44742 -0
  6. package/dist/client/assets/embeddings-DlCMB9po.js +21 -0
  7. package/dist/client/assets/index-B0NYybvW.js +5371 -0
  8. package/dist/client/assets/index-CKXUnlZB.js +94617 -0
  9. package/dist/client/assets/index-Cb09SlUY.js +17535 -0
  10. package/dist/client/assets/index-CsP5AdwX.js +10699 -0
  11. package/dist/client/assets/index-DX0TIfSM.js +102 -0
  12. package/dist/client/assets/index-Q_pqNaNk.js +1780 -0
  13. package/dist/client/assets/index-kVFYovMy.css +5752 -0
  14. package/dist/client/assets/path-QsnVvLoj.js +62 -0
  15. package/dist/client/assets/transport-wrapper-browser-ChPHVnHg.js +165 -0
  16. package/dist/client/assets/winston-qgF6niUt.js +12326 -0
  17. package/dist/client/index.html +3 -3
  18. package/dist/server/{chunk-37X7HLUV.js → chunk-3T2VCYG6.js} +87 -13
  19. package/dist/server/chunk-CVECQ7BJ.js +78 -0
  20. package/dist/server/{chunk-555LGZ3I.js → chunk-FS77NTZN.js} +133 -10
  21. package/dist/server/chunk-PKBMQBKP.js +7 -0
  22. package/dist/server/{chunk-WYBXXYSP.js → chunk-RRPLH7DL.js} +1 -1
  23. package/dist/server/{chunk-PYGYQT2G.js → chunk-S7NOZBMG.js} +3 -3
  24. package/dist/server/{chunk-DGUMOD7P.js → chunk-ZONLXYBO.js} +92 -10
  25. package/dist/server/cli.js +6 -4
  26. package/dist/server/index.js +7 -5
  27. package/dist/server/middleware.js +7 -5
  28. package/dist/server/rpc-log-bus.d.ts +17 -0
  29. package/dist/server/rpc-log-bus.d.ts.map +1 -0
  30. package/dist/server/rpc-log-bus.js +7 -0
  31. package/dist/server/server.js +6 -4
  32. package/dist/server/shared-routes.d.ts.map +1 -1
  33. package/dist/server/shared-routes.js +4 -2
  34. package/dist/server/shared-static.js +3 -2
  35. package/dist/server/shared-utils-browser.d.ts +2 -1
  36. package/dist/server/shared-utils-browser.d.ts.map +1 -1
  37. package/dist/server/shared-utils-browser.js +2 -1
  38. package/dist/server/shared-utils.d.ts +4 -1
  39. package/dist/server/shared-utils.d.ts.map +1 -1
  40. package/dist/server/shared-utils.js +2 -1
  41. package/dist/server/transport-wrapper.d.ts +6 -0
  42. package/dist/server/transport-wrapper.d.ts.map +1 -0
  43. package/dist/server/transport-wrapper.js +68 -0
  44. package/dist/server/utils.js +1 -0
  45. package/package.json +12 -3
  46. package/dist/client/assets/__vite-browser-external-DFygW7-s.js +0 -1
  47. package/dist/client/assets/chunk-VL2OQCWN-iRVOQjqe.js +0 -8
  48. package/dist/client/assets/display-LIYVTGEU-D2dm8q2H.js +0 -30
  49. package/dist/client/assets/embeddings-Dcyp0Vlp.js +0 -1
  50. package/dist/client/assets/index-6zrNEwtM.js +0 -4
  51. package/dist/client/assets/index-CAnbiFOL.css +0 -1
  52. package/dist/client/assets/index-CB1s6Wr6.js +0 -146
  53. package/dist/client/assets/index-CoMldIFv.js +0 -2
  54. package/dist/client/assets/index-DRz5BQNA.js +0 -1
  55. package/dist/client/assets/index-DUf1336L.js +0 -1559
  56. package/dist/client/assets/index-DmIKR5St.js +0 -1
  57. package/dist/client/assets/index-DpUpZFq2.js +0 -25
  58. package/dist/client/assets/index-DzegZXPW.js +0 -40
  59. package/dist/client/assets/langfuse-C4HKZ3NL-vCtAvQQV.js +0 -564
  60. package/dist/client/assets/path-C9FudP8b.js +0 -1
  61. package/dist/client/assets/winston-BVJ8PyEn.js +0 -37
package/dist/cli.js CHANGED
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
2
5
 
3
6
  // src/server/cli.ts
4
7
  import { serve } from "@hono/node-server";
@@ -324,7 +327,16 @@ function generateWidgetContainerHtml(basePath, toolId) {
324
327
  `;
325
328
  }
326
329
  function generateWidgetContentHtml(widgetData) {
327
- const { serverId, uri, toolInput, toolOutput, resourceData, toolId } = widgetData;
330
+ const {
331
+ serverId,
332
+ uri,
333
+ toolInput,
334
+ toolOutput,
335
+ resourceData,
336
+ toolId,
337
+ devServerBaseUrl,
338
+ theme
339
+ } = widgetData;
328
340
  console.log("[Widget Content] Using pre-fetched resource for:", {
329
341
  serverId,
330
342
  uri
@@ -355,23 +367,31 @@ function generateWidgetContentHtml(widgetData) {
355
367
  const safeToolOutput = JSON.stringify(toolOutput ?? null).replace(/</g, "\\u003c").replace(/>/g, "\\u003e");
356
368
  const safeToolId = JSON.stringify(toolId);
357
369
  const safeWidgetStateKey = JSON.stringify(widgetStateKey);
370
+ const safeTheme = JSON.stringify(theme === "dark" ? "dark" : "light");
358
371
  const apiScript = `
359
372
  <script>
360
373
  (function() {
361
374
  'use strict';
362
375
 
363
376
  // Change URL to "/" for React Router compatibility
364
- if (window.location.pathname !== '/') {
377
+ // Skip if running in Inspector dev-widget proxy to prevent redirecting iframe to Inspector home
378
+ if (window.location.pathname !== '/' && !window.location.pathname.includes('/dev-widget/')) {
365
379
  history.replaceState(null, '', '/');
366
380
  }
367
381
 
382
+ // Inject MCP widget utilities for Image component and file access
383
+ window.__mcpPublicUrl = ${devServerBaseUrl ? `"${devServerBaseUrl}/mcp-use/public"` : '""'};
384
+ window.__getFile = function(filename) {
385
+ return ${devServerBaseUrl ? `"${devServerBaseUrl}/mcp-use/widgets/"` : '""'} + filename;
386
+ };
387
+
368
388
  const openaiAPI = {
369
389
  toolInput: ${safeToolInput},
370
390
  toolOutput: ${safeToolOutput},
371
391
  toolResponseMetadata: null,
372
392
  displayMode: 'inline',
373
393
  maxHeight: 600,
374
- theme: 'dark',
394
+ theme: ${safeTheme},
375
395
  locale: 'en-US',
376
396
  safeArea: { insets: { top: 0, bottom: 0, left: 0, right: 0 } },
377
397
  userAgent: {},
@@ -444,6 +464,20 @@ function generateWidgetContentHtml(widgetData) {
444
464
  return this.sendFollowupTurn(prompt);
445
465
  },
446
466
 
467
+ async notifyIntrinsicHeight(height) {
468
+ console.log('[OpenAI Widget] notifyIntrinsicHeight called with:', height);
469
+ if (typeof height !== 'number' || height < 0) {
470
+ console.error('[OpenAI Widget] Invalid height value:', height);
471
+ throw new Error('Height must be a non-negative number');
472
+ }
473
+ const message = {
474
+ type: 'openai:notifyIntrinsicHeight',
475
+ height
476
+ };
477
+ console.log('[OpenAI Widget] Sending postMessage to parent:', message);
478
+ window.parent.postMessage(message, '*');
479
+ },
480
+
447
481
  openExternal(payload) {
448
482
  const href = typeof payload === 'string' ? payload : payload?.href;
449
483
  if (href) {
@@ -488,6 +522,18 @@ function generateWidgetContentHtml(widgetData) {
488
522
  } catch (err) {}
489
523
  }, 0);
490
524
 
525
+ // Listen for widget state requests from inspector
526
+ window.addEventListener('message', (event) => {
527
+ if (event.data?.type === 'mcp-inspector:getWidgetState') {
528
+ window.parent.postMessage({
529
+ type: 'mcp-inspector:widgetStateResponse',
530
+ toolId: event.data.toolId,
531
+ state: openaiAPI.widgetState
532
+ }, '*');
533
+ return;
534
+ }
535
+ });
536
+
491
537
  // Listen for globals changes from parent (for displayMode, theme, etc.)
492
538
  window.addEventListener('message', (event) => {
493
539
  // Handle new general globalsChanged message
@@ -614,7 +660,7 @@ function generateWidgetContentHtml(widgetData) {
614
660
  console.log("[Widget Content] Generated HTML length:", modifiedHtml.length);
615
661
  return { html: modifiedHtml };
616
662
  }
617
- function getWidgetSecurityHeaders(widgetCSP) {
663
+ function getWidgetSecurityHeaders(widgetCSP, devServerBaseUrl) {
618
664
  const trustedCdns = [
619
665
  "https://persistent.oaistatic.com",
620
666
  "https://*.oaistatic.com",
@@ -623,25 +669,48 @@ function getWidgetSecurityHeaders(widgetCSP) {
623
669
  "https://cdnjs.cloudflare.com",
624
670
  "https://cdn.skypack.dev"
625
671
  ];
626
- const allResourceDomains = [...trustedCdns];
672
+ const prodResourceDomains = [...trustedCdns];
627
673
  if (widgetCSP?.resource_domains) {
628
- allResourceDomains.push(...widgetCSP.resource_domains);
674
+ prodResourceDomains.push(...widgetCSP.resource_domains);
675
+ }
676
+ const prodResourceDomainsStr = prodResourceDomains.join(" ");
677
+ let devServerOrigin = null;
678
+ const allResourceDomains = [...prodResourceDomains];
679
+ if (devServerBaseUrl) {
680
+ try {
681
+ devServerOrigin = new URL(devServerBaseUrl).origin;
682
+ allResourceDomains.push(devServerOrigin);
683
+ } catch (e) {
684
+ console.warn(`[CSP] Invalid devServerBaseUrl: ${devServerBaseUrl}`);
685
+ }
629
686
  }
630
687
  const resourceDomainsStr = allResourceDomains.join(" ");
688
+ let imgSrc = "'self' data: https: blob:";
689
+ if (devServerOrigin) {
690
+ imgSrc = `'self' data: https: blob: ${devServerOrigin}`;
691
+ }
692
+ let mediaSrc = "'self' data: https: blob:";
693
+ if (devServerOrigin) {
694
+ mediaSrc = `'self' data: https: blob: ${devServerOrigin}`;
695
+ }
696
+ let fontSrc = `'self' data: ${resourceDomainsStr}`;
697
+ if (devServerOrigin) {
698
+ fontSrc = `'self' data: https: http: ${resourceDomainsStr}`;
699
+ }
631
700
  let connectSrc = "'self' https: wss: ws:";
632
701
  if (widgetCSP?.connect_domains && widgetCSP.connect_domains.length > 0) {
633
702
  connectSrc = `'self' ${widgetCSP.connect_domains.join(" ")} https: wss: ws:`;
634
703
  }
635
- return {
704
+ const headers = {
636
705
  "Content-Security-Policy": [
637
706
  "default-src 'self'",
638
707
  `script-src 'self' 'unsafe-inline' 'unsafe-eval' ${resourceDomainsStr}`,
639
708
  "worker-src 'self' blob:",
640
709
  "child-src 'self' blob:",
641
710
  `style-src 'self' 'unsafe-inline' ${resourceDomainsStr}`,
642
- "img-src 'self' data: https: blob:",
643
- "media-src 'self' data: https: blob:",
644
- `font-src 'self' data: ${resourceDomainsStr}`,
711
+ `img-src ${imgSrc}`,
712
+ `media-src ${mediaSrc}`,
713
+ `font-src ${fontSrc}`,
645
714
  `connect-src ${connectSrc}`,
646
715
  "frame-ancestors 'self'"
647
716
  ].join("; "),
@@ -651,6 +720,22 @@ function getWidgetSecurityHeaders(widgetCSP) {
651
720
  Pragma: "no-cache",
652
721
  Expires: "0"
653
722
  };
723
+ if (devServerOrigin) {
724
+ const prodConnectSrc = "'self' https: wss: ws:";
725
+ headers["Content-Security-Policy-Report-Only"] = [
726
+ "default-src 'self'",
727
+ `script-src 'self' 'unsafe-inline' 'unsafe-eval' ${prodResourceDomainsStr}`,
728
+ "worker-src 'self' blob:",
729
+ "child-src 'self' blob:",
730
+ `style-src 'self' 'unsafe-inline' ${prodResourceDomainsStr}`,
731
+ "img-src 'self' data: https: blob:",
732
+ "media-src 'self' data: https: blob:",
733
+ `font-src 'self' data: ${prodResourceDomainsStr}`,
734
+ `connect-src ${prodConnectSrc}`,
735
+ "frame-ancestors 'self'"
736
+ ].join("; ");
737
+ }
738
+ return headers;
654
739
  }
655
740
 
656
741
  // src/server/utils.ts
@@ -699,6 +784,77 @@ function formatErrorResponse(error, context) {
699
784
  };
700
785
  }
701
786
 
787
+ // src/server/rpc-log-bus.ts
788
+ var SimpleEventEmitter = class {
789
+ constructor() {
790
+ __publicField(this, "listeners", /* @__PURE__ */ new Map());
791
+ }
792
+ on(event, listener) {
793
+ if (!this.listeners.has(event)) {
794
+ this.listeners.set(event, /* @__PURE__ */ new Set());
795
+ }
796
+ this.listeners.get(event).add(listener);
797
+ }
798
+ off(event, listener) {
799
+ this.listeners.get(event)?.delete(listener);
800
+ }
801
+ emit(event, ...args2) {
802
+ this.listeners.get(event)?.forEach((listener) => {
803
+ try {
804
+ listener(...args2);
805
+ } catch (e) {
806
+ console.error("Error in event listener:", e);
807
+ }
808
+ });
809
+ }
810
+ };
811
+ var RpcLogBus = class {
812
+ constructor() {
813
+ __publicField(this, "emitter", new SimpleEventEmitter());
814
+ __publicField(this, "bufferByServer", /* @__PURE__ */ new Map());
815
+ }
816
+ publish(event) {
817
+ const buffer = this.bufferByServer.get(event.serverId) ?? [];
818
+ buffer.push(event);
819
+ if (buffer.length > 1e3) {
820
+ buffer.shift();
821
+ }
822
+ this.bufferByServer.set(event.serverId, buffer);
823
+ this.emitter.emit("event", event);
824
+ }
825
+ subscribe(serverIds, listener) {
826
+ const filter = new Set(serverIds);
827
+ const handler = (event) => {
828
+ if (filter.size === 0 || filter.has(event.serverId)) listener(event);
829
+ };
830
+ this.emitter.on("event", handler);
831
+ return () => this.emitter.off("event", handler);
832
+ }
833
+ getBuffer(serverIds, limit) {
834
+ const filter = new Set(serverIds);
835
+ const all = [];
836
+ for (const [serverId, buf] of this.bufferByServer.entries()) {
837
+ if (filter.size > 0 && !filter.has(serverId)) continue;
838
+ all.push(...buf);
839
+ }
840
+ all.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
841
+ if (limit === 0) return [];
842
+ if (!Number.isFinite(limit) || limit < 0) return all;
843
+ return all.slice(0, limit);
844
+ }
845
+ clear(serverIds) {
846
+ if (serverIds && serverIds.length > 0) {
847
+ const filter = new Set(serverIds);
848
+ for (const serverId of filter) {
849
+ this.bufferByServer.delete(serverId);
850
+ }
851
+ } else {
852
+ this.bufferByServer.clear();
853
+ }
854
+ }
855
+ };
856
+ var rpcLogBus = new RpcLogBus();
857
+
702
858
  // src/server/shared-routes.ts
703
859
  function registerInspectorRoutes(app2, config) {
704
860
  app2.get("/inspector/health", (c) => {
@@ -904,8 +1060,10 @@ function registerInspectorRoutes(app2, config) {
904
1060
  }
905
1061
  );
906
1062
  html = html.replace(
907
- /(src|href)="\/mcp-use\/widgets\//g,
908
- `$1="${proxyBase}/mcp-use/widgets/`
1063
+ /(src|href)="(\/mcp-use\/widgets\/[^"]+)"/g,
1064
+ (_match, attr, path) => {
1065
+ return `${attr}="${widgetData.devServerBaseUrl}${path}"`;
1066
+ }
909
1067
  );
910
1068
  html = html.replace(/(src|href)="\.\/([^"]+)"/g, (match, attr, path) => {
911
1069
  if (path.match(/\.(js|css|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$/i)) {
@@ -913,14 +1071,45 @@ function registerInspectorRoutes(app2, config) {
913
1071
  }
914
1072
  return match;
915
1073
  });
916
- const host = c.req.header("host") || "localhost:3000";
917
- const protocol = c.req.header("x-forwarded-proto") || (c.req.url.startsWith("https") ? "https" : "http");
918
- const wsProtocol = protocol === "https" ? "wss" : "ws";
919
- html = html.replace(/__vite_ws__:\s*["']([^"']+)["']/g, () => {
920
- const proxyWsUrl = `${wsProtocol}://${host}/inspector/api/dev-widget/${toolId}/__vite_hmr`;
921
- return `__vite_ws__: "${proxyWsUrl}"`;
1074
+ if (widgetData.devServerBaseUrl) {
1075
+ const devServerUrl = new URL(widgetData.devServerBaseUrl);
1076
+ const wsProtocol = devServerUrl.protocol === "https:" ? "wss" : "ws";
1077
+ const wsHost = devServerUrl.host;
1078
+ const directWsUrl = `${wsProtocol}://${wsHost}/mcp-use/widgets/`;
1079
+ const baseTag = `<base href="${widgetData.devServerBaseUrl}/mcp-use/widgets/${widgetName}/">`;
1080
+ const cspWarningScript = `
1081
+ <script>
1082
+ // Listen for CSP violations (from Report-Only policy)
1083
+ document.addEventListener('securitypolicyviolation', (e) => {
1084
+ // Only warn about report-only violations (not enforced ones)
1085
+ if (e.disposition === 'report') {
1086
+ console.warn(
1087
+ '%c\u26A0\uFE0F CSP Warning: Resource would be blocked in production',
1088
+ 'color: orange; font-weight: bold',
1089
+ '\\n Blocked URL:', e.blockedURI,
1090
+ '\\n Directive:', e.violatedDirective,
1091
+ '\\n Policy:', e.originalPolicy,
1092
+ '\\n\\n\u2139\uFE0F To fix: Add this domain to your widget\\'s CSP configuration in appsSdkMetadata[\\'openai/widgetCSP\\']'
1093
+ );
1094
+ }
922
1095
  });
923
- const headers = getWidgetSecurityHeaders(widgetData.widgetCSP);
1096
+ </script>`;
1097
+ const viteConfigScript = `
1098
+ <script>
1099
+ // Configure Vite HMR to connect directly to dev server
1100
+ window.__vite_ws_url__ = "${directWsUrl}";
1101
+ </script>`;
1102
+ html = html.replace(/<head>/i, `<head>
1103
+ ${baseTag}`);
1104
+ html = html.replace(
1105
+ /<script/,
1106
+ cspWarningScript + viteConfigScript + "\n <script"
1107
+ );
1108
+ }
1109
+ const headers = getWidgetSecurityHeaders(
1110
+ widgetData.widgetCSP,
1111
+ widgetData.devServerBaseUrl
1112
+ );
924
1113
  Object.entries(headers).forEach(([key, value]) => {
925
1114
  c.header(key, value);
926
1115
  });
@@ -1027,6 +1216,93 @@ function registerInspectorRoutes(app2, config) {
1027
1216
  return c.json({ success: false });
1028
1217
  }
1029
1218
  });
1219
+ app2.post("/inspector/api/rpc/log", async (c) => {
1220
+ try {
1221
+ const event = await c.req.json();
1222
+ rpcLogBus.publish(event);
1223
+ return c.json({ success: true });
1224
+ } catch (error) {
1225
+ console.error("[RPC Log] Error receiving RPC event:", error);
1226
+ return c.json({ success: false });
1227
+ }
1228
+ });
1229
+ app2.delete("/inspector/api/rpc/log", async (c) => {
1230
+ try {
1231
+ const url = new URL(c.req.url);
1232
+ const serverIdsParam = url.searchParams.get("serverIds");
1233
+ const serverIds = serverIdsParam ? serverIdsParam.split(",").filter(Boolean) : void 0;
1234
+ rpcLogBus.clear(serverIds);
1235
+ return c.json({ success: true });
1236
+ } catch (error) {
1237
+ console.error("[RPC Log] Error clearing RPC log:", error);
1238
+ return c.json({ success: false });
1239
+ }
1240
+ });
1241
+ app2.get("/inspector/api/rpc/stream", async (c) => {
1242
+ const url = new URL(c.req.url);
1243
+ const replay = parseInt(url.searchParams.get("replay") || "3", 10);
1244
+ const serverIdsParam = url.searchParams.get("serverIds");
1245
+ const serverIds = serverIdsParam ? serverIdsParam.split(",").filter(Boolean) : [];
1246
+ const encoder = new TextEncoder();
1247
+ const stream = new ReadableStream({
1248
+ start(controller) {
1249
+ const send = (data) => {
1250
+ try {
1251
+ controller.enqueue(
1252
+ encoder.encode(`data: ${JSON.stringify(data)}
1253
+
1254
+ `)
1255
+ );
1256
+ } catch {
1257
+ }
1258
+ };
1259
+ try {
1260
+ const recent = rpcLogBus.getBuffer(
1261
+ serverIds,
1262
+ isNaN(replay) ? 3 : replay
1263
+ );
1264
+ for (const evt of recent) {
1265
+ send({ type: "rpc", ...evt });
1266
+ }
1267
+ } catch {
1268
+ }
1269
+ const unsubscribe = rpcLogBus.subscribe(
1270
+ serverIds,
1271
+ (evt) => {
1272
+ send({ type: "rpc", ...evt });
1273
+ }
1274
+ );
1275
+ const keepalive = setInterval(() => {
1276
+ try {
1277
+ controller.enqueue(encoder.encode(`: keepalive ${Date.now()}
1278
+
1279
+ `));
1280
+ } catch {
1281
+ }
1282
+ }, 15e3);
1283
+ c.req.raw.signal?.addEventListener("abort", () => {
1284
+ try {
1285
+ clearInterval(keepalive);
1286
+ unsubscribe();
1287
+ } catch {
1288
+ }
1289
+ try {
1290
+ controller.close();
1291
+ } catch {
1292
+ }
1293
+ });
1294
+ }
1295
+ });
1296
+ return new Response(stream, {
1297
+ headers: {
1298
+ "Content-Type": "text/event-stream",
1299
+ "Cache-Control": "no-cache",
1300
+ Connection: "keep-alive",
1301
+ "Access-Control-Allow-Origin": "*",
1302
+ "Access-Control-Expose-Headers": "*"
1303
+ }
1304
+ });
1305
+ });
1030
1306
  }
1031
1307
 
1032
1308
  // src/server/shared-static.ts
@@ -0,0 +1,8 @@
1
+ const __viteBrowserExternal = {};
2
+ const os = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3
+ __proto__: null,
4
+ default: __viteBrowserExternal
5
+ }, Symbol.toStringTag, { value: "Module" }));
6
+ export {
7
+ os as o
8
+ };