@mcp-use/cli 3.2.1-canary.8 → 3.3.0-canary.19

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.
@@ -22,7 +22,16 @@ interface CaptureToolScreenshotInputs {
22
22
  resourceUri: string;
23
23
  }
24
24
  interface CaptureToolScreenshotOptions {
25
+ /**
26
+ * Desired output width in CSS pixels. When omitted, the screenshot fits the
27
+ * widget's natural rendered width. When set, also overrides the inline-mode
28
+ * 768px max-width cap so the widget renders at the requested width.
29
+ */
25
30
  width?: number;
31
+ /**
32
+ * Desired output height in CSS pixels. When omitted, the screenshot fits the
33
+ * widget's natural rendered height.
34
+ */
26
35
  height?: number;
27
36
  theme?: "light" | "dark";
28
37
  output?: string;
@@ -46,7 +55,9 @@ interface CaptureToolScreenshotOptions {
46
55
  }
47
56
  interface CaptureToolScreenshotResult {
48
57
  outputPath: string;
58
+ /** Final clip width in CSS pixels (what the PNG visually represents). */
49
59
  width: number;
60
+ /** Final clip height in CSS pixels. */
50
61
  height: number;
51
62
  view: string;
52
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/commands/screenshot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAwCjD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAa5D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOtE;AAaD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,SAAS,GAAG,IAAI,GAC3D,MAAM,GAAG,IAAI,CAUf;AAED,UAAU,2BAA2B;IACnC,OAAO,EAAE,UAAU,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,4BAA4B;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,UAAU,2BAA2B;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,2BAA2B,EACnC,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,2BAA2B,CAAC,CA2DtC;AAqLD;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,OAAa,GAAG,MAAM,CAKzD;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK3D;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAa1D;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAI/D;AAuQD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAwBvD;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAetE"}
1
+ {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/commands/screenshot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAwCjD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAa5D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOtE;AAaD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,SAAS,GAAG,IAAI,GAC3D,MAAM,GAAG,IAAI,CAUf;AAED,UAAU,2BAA2B;IACnC,OAAO,EAAE,UAAU,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,4BAA4B;IACpC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,UAAU,2BAA2B;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,2BAA2B,EACnC,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,2BAA2B,CAAC,CAmEtC;AAqLD;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,OAAa,GAAG,MAAM,CAKzD;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAa1D;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAI/D;AAmRD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAwBvD;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAetE"}
package/dist/index.cjs CHANGED
@@ -2790,6 +2790,10 @@ async function captureScreenshot(opts) {
2790
2790
  }
2791
2791
  }
2792
2792
  };
2793
+ const DEFAULT_VIEWPORT_WIDTH = 1280;
2794
+ const DEFAULT_VIEWPORT_HEIGHT = 2e3;
2795
+ const viewportWidth = Math.max(opts.width ?? 0, DEFAULT_VIEWPORT_WIDTH);
2796
+ const viewportHeight = Math.max(opts.height ?? 0, DEFAULT_VIEWPORT_HEIGHT);
2793
2797
  try {
2794
2798
  let wsUrl;
2795
2799
  if (opts.cdpUrl) {
@@ -2811,7 +2815,7 @@ async function captureScreenshot(opts) {
2811
2815
  "--disable-gpu",
2812
2816
  "--hide-scrollbars",
2813
2817
  "--mute-audio",
2814
- `--window-size=${opts.width},${opts.height}`,
2818
+ `--window-size=${viewportWidth},${viewportHeight}`,
2815
2819
  "about:blank"
2816
2820
  ];
2817
2821
  child = (0, import_node_child_process8.spawn)(opts.chromePath, chromeArgs, {
@@ -2879,8 +2883,8 @@ async function captureScreenshot(opts) {
2879
2883
  await cdp.send(
2880
2884
  "Emulation.setDeviceMetricsOverride",
2881
2885
  {
2882
- width: opts.width,
2883
- height: opts.height,
2886
+ width: viewportWidth,
2887
+ height: viewportHeight,
2884
2888
  deviceScaleFactor: opts.deviceScaleFactor ?? 1,
2885
2889
  mobile: false
2886
2890
  },
@@ -2930,21 +2934,36 @@ async function captureScreenshot(opts) {
2930
2934
  if (opts.delayMs && opts.delayMs > 0) {
2931
2935
  await new Promise((res) => setTimeout(res, opts.delayMs));
2932
2936
  }
2937
+ const rectResult = await cdp.send(
2938
+ "Runtime.evaluate",
2939
+ {
2940
+ expression: `(() => {
2941
+ const d = document.body.dataset;
2942
+ const n = (s) => { const v = parseFloat(s ?? ""); return Number.isFinite(v) ? v : undefined; };
2943
+ return { x: n(d.viewX), y: n(d.viewY), width: n(d.viewWidth), height: n(d.viewHeight) };
2944
+ })()`,
2945
+ returnByValue: true
2946
+ },
2947
+ sessionId
2948
+ );
2949
+ const rect = rectResult.result?.value ?? {};
2950
+ const clip = {
2951
+ x: rect.x ?? 0,
2952
+ y: rect.y ?? 0,
2953
+ width: opts.width ?? (rect.width && rect.width > 0 ? rect.width : viewportWidth),
2954
+ height: opts.height ?? (rect.height && rect.height > 0 ? rect.height : viewportHeight),
2955
+ scale: 1
2956
+ };
2933
2957
  const shot = await cdp.send(
2934
2958
  "Page.captureScreenshot",
2935
2959
  {
2936
2960
  format: "png",
2937
- clip: {
2938
- x: 0,
2939
- y: 0,
2940
- width: opts.width,
2941
- height: opts.height,
2942
- scale: 1
2943
- }
2961
+ clip
2944
2962
  },
2945
2963
  sessionId
2946
2964
  );
2947
2965
  (0, import_node_fs6.writeFileSync)(opts.outputPath, Buffer.from(shot.data, "base64"));
2966
+ return { width: clip.width, height: clip.height };
2948
2967
  } finally {
2949
2968
  cleanup();
2950
2969
  }
@@ -3073,16 +3092,13 @@ function detectToolResourceUri(tool) {
3073
3092
  return uiMeta?.resourceUri ?? meta["openai/outputTemplate"] ?? null;
3074
3093
  }
3075
3094
  async function captureToolScreenshot(inputs, options = {}) {
3076
- const width = options.width ?? 800;
3077
- const height = options.height ?? 600;
3095
+ const { width, height } = options;
3078
3096
  const theme = options.theme ?? "light";
3079
3097
  const timeoutMs = options.timeoutMs ?? 3e4;
3080
3098
  const delayMs = options.delayMs ?? 0;
3081
3099
  const chromePath = options.cdpUrl ? void 0 : resolveChromePath();
3082
3100
  const view = extractViewName(inputs.resourceUri);
3083
3101
  const devOptions = {
3084
- width: String(width),
3085
- height: String(height),
3086
3102
  theme,
3087
3103
  timeout: String(timeoutMs),
3088
3104
  inspector: options.inspector,
@@ -3102,10 +3118,13 @@ async function captureToolScreenshot(inputs, options = {}) {
3102
3118
  };
3103
3119
  const previewUrl = new URL(`/inspector/preview/${view}`, devHandle.url);
3104
3120
  previewUrl.searchParams.set("theme", theme);
3121
+ if (width !== void 0) {
3122
+ previewUrl.searchParams.set("width", String(width));
3123
+ }
3105
3124
  const ts = timestampSuffix();
3106
3125
  const outputPath = import_node_path6.default.resolve(options.output ?? `./${view}-${ts}.png`);
3107
3126
  await (0, import_promises5.mkdir)(import_node_path6.default.dirname(outputPath), { recursive: true });
3108
- await captureScreenshot({
3127
+ const captured = await captureScreenshot({
3109
3128
  url: previewUrl.toString(),
3110
3129
  width,
3111
3130
  height,
@@ -3119,7 +3138,12 @@ async function captureToolScreenshot(inputs, options = {}) {
3119
3138
  bundle,
3120
3139
  deviceScaleFactor: options.deviceScaleFactor
3121
3140
  });
3122
- return { outputPath, width, height, view };
3141
+ return {
3142
+ outputPath,
3143
+ width: captured.width,
3144
+ height: captured.height,
3145
+ view
3146
+ };
3123
3147
  } finally {
3124
3148
  killChild(devHandle?.child);
3125
3149
  }
@@ -3249,9 +3273,10 @@ function timestampSuffix(date = /* @__PURE__ */ new Date()) {
3249
3273
  return `${datePart}_${timePart}`;
3250
3274
  }
3251
3275
  function extractViewName(resourceUri) {
3252
- const m = resourceUri.match(/^ui:\/\/widget\/(.+)$/);
3253
- if (!m) return resourceUri;
3254
- return m[1].replace(/\.html$/, "").replace(/\.[0-9a-f]+$/i, "");
3276
+ const m = resourceUri.match(/^ui:\/\/([^/]+)\/(.+)$/);
3277
+ if (!m) return encodeURIComponent(resourceUri);
3278
+ const name = m[2].replace(/\.html$/, "").replace(/\.[0-9a-f]+$/i, "");
3279
+ return m[1] === "widget" ? name : `${m[1]}-${name}`;
3255
3280
  }
3256
3281
  function parseDimension(raw, name) {
3257
3282
  const n = parseInt(raw, 10);
@@ -3351,8 +3376,8 @@ async function screenshotCommand(options, argsList, context) {
3351
3376
  exitCode = 1;
3352
3377
  return;
3353
3378
  }
3354
- const width = parseDimension(options.width, "width");
3355
- const height = parseDimension(options.height, "height");
3379
+ const width = options.width !== void 0 ? parseDimension(options.width, "width") : void 0;
3380
+ const height = options.height !== void 0 ? parseDimension(options.height, "height") : void 0;
3356
3381
  const navTimeout = parseInt(options.timeout, 10) || 3e4;
3357
3382
  const delayMs = options.delay ? parseInt(options.delay, 10) : 0;
3358
3383
  const deviceScaleFactor = options.deviceScaleFactor ? parseDeviceScaleFactor(options.deviceScaleFactor) : void 0;
@@ -3461,7 +3486,13 @@ function withCommonScreenshotOptions(cmd) {
3461
3486
  ).option(
3462
3487
  "--tool <name>",
3463
3488
  "Tool to call. Its UI resource is rendered with the result."
3464
- ).option("--width <px>", "Browser viewport width in pixels.", "800").option("--height <px>", "Browser viewport height in pixels.", "600").option(
3489
+ ).option(
3490
+ "--width <px>",
3491
+ "Output image width in pixels. When omitted, fits the widget's natural width. When set, the widget renders at this width (overrides the inline-mode 768px cap)."
3492
+ ).option(
3493
+ "--height <px>",
3494
+ "Output image height in pixels. When omitted, fits the widget's natural height."
3495
+ ).option(
3465
3496
  "--device-scale-factor <n>",
3466
3497
  "Device pixel ratio for rendering (e.g. 2 for Retina). Output PNG is (width \xD7 dsf) \xD7 (height \xD7 dsf). Must be > 0 and <= 4."
3467
3498
  ).option(
@@ -7152,6 +7183,16 @@ A new release of ${source_default.bold(PACKAGE_NAME)} is available: ${source_def
7152
7183
  }
7153
7184
  }
7154
7185
 
7186
+ // src/utils/widget-paths.ts
7187
+ function getWidgetAssetBase(mcpUrl, widgetName) {
7188
+ const widgetPath = `/mcp-use/widgets/${widgetName}/`;
7189
+ if (!mcpUrl) {
7190
+ return widgetPath;
7191
+ }
7192
+ const origin = mcpUrl.replace(/\/+$/, "");
7193
+ return `${origin}${widgetPath}`;
7194
+ }
7195
+
7155
7196
  // src/index.ts
7156
7197
  var program = new import_commander7.Command();
7157
7198
  var packageContent = (0, import_node_fs14.readFileSync)(
@@ -7642,7 +7683,7 @@ if (container && Component) {
7642
7683
  "widgets",
7643
7684
  widgetName
7644
7685
  );
7645
- const baseUrl = mcpUrl ? `${mcpUrl}/${widgetName}/` : `/mcp-use/widgets/${widgetName}/`;
7686
+ const baseUrl = getWidgetAssetBase(mcpUrl, widgetName);
7646
7687
  let widgetMetadata = {};
7647
7688
  try {
7648
7689
  const metadataTempDir = import_node_path12.default.join(
@@ -7958,7 +7999,9 @@ export default {
7958
7999
  try {
7959
8000
  const htmlPath = import_node_path12.default.join(outDir, "index.html");
7960
8001
  let html = await fs11.readFile(htmlPath, "utf8");
7961
- const injectionScript = `<script>window.__getFile = (filename) => { return "${mcpUrl}/${widgetName}/"+filename }; window.__mcpPublicUrl = "${mcpServerUrl}/mcp-use/public"; window.__mcpPublicAssetsUrl = "${mcpUrl}/public";</script>`;
8002
+ const widgetAssetBase = getWidgetAssetBase(mcpUrl, widgetName);
8003
+ const mcpOrigin = mcpUrl ? mcpUrl.replace(/\/+$/, "") : mcpServerUrl;
8004
+ const injectionScript = `<script>window.__getFile = (filename) => { return "${widgetAssetBase}"+filename }; window.__mcpPublicUrl = "${mcpServerUrl}/mcp-use/public"; window.__mcpPublicAssetsUrl = "${mcpOrigin}/mcp-use/public";</script>`;
7962
8005
  if (!html.includes("window.__mcpPublicUrl")) {
7963
8006
  html = html.replace(
7964
8007
  /<head[^>]*>/i,