@mcp-use/cli 3.2.1-canary.9 → 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.
package/dist/index.js CHANGED
@@ -2775,6 +2775,10 @@ async function captureScreenshot(opts) {
2775
2775
  }
2776
2776
  }
2777
2777
  };
2778
+ const DEFAULT_VIEWPORT_WIDTH = 1280;
2779
+ const DEFAULT_VIEWPORT_HEIGHT = 2e3;
2780
+ const viewportWidth = Math.max(opts.width ?? 0, DEFAULT_VIEWPORT_WIDTH);
2781
+ const viewportHeight = Math.max(opts.height ?? 0, DEFAULT_VIEWPORT_HEIGHT);
2778
2782
  try {
2779
2783
  let wsUrl;
2780
2784
  if (opts.cdpUrl) {
@@ -2796,7 +2800,7 @@ async function captureScreenshot(opts) {
2796
2800
  "--disable-gpu",
2797
2801
  "--hide-scrollbars",
2798
2802
  "--mute-audio",
2799
- `--window-size=${opts.width},${opts.height}`,
2803
+ `--window-size=${viewportWidth},${viewportHeight}`,
2800
2804
  "about:blank"
2801
2805
  ];
2802
2806
  child = spawn(opts.chromePath, chromeArgs, {
@@ -2864,8 +2868,8 @@ async function captureScreenshot(opts) {
2864
2868
  await cdp.send(
2865
2869
  "Emulation.setDeviceMetricsOverride",
2866
2870
  {
2867
- width: opts.width,
2868
- height: opts.height,
2871
+ width: viewportWidth,
2872
+ height: viewportHeight,
2869
2873
  deviceScaleFactor: opts.deviceScaleFactor ?? 1,
2870
2874
  mobile: false
2871
2875
  },
@@ -2915,21 +2919,36 @@ async function captureScreenshot(opts) {
2915
2919
  if (opts.delayMs && opts.delayMs > 0) {
2916
2920
  await new Promise((res) => setTimeout(res, opts.delayMs));
2917
2921
  }
2922
+ const rectResult = await cdp.send(
2923
+ "Runtime.evaluate",
2924
+ {
2925
+ expression: `(() => {
2926
+ const d = document.body.dataset;
2927
+ const n = (s) => { const v = parseFloat(s ?? ""); return Number.isFinite(v) ? v : undefined; };
2928
+ return { x: n(d.viewX), y: n(d.viewY), width: n(d.viewWidth), height: n(d.viewHeight) };
2929
+ })()`,
2930
+ returnByValue: true
2931
+ },
2932
+ sessionId
2933
+ );
2934
+ const rect = rectResult.result?.value ?? {};
2935
+ const clip = {
2936
+ x: rect.x ?? 0,
2937
+ y: rect.y ?? 0,
2938
+ width: opts.width ?? (rect.width && rect.width > 0 ? rect.width : viewportWidth),
2939
+ height: opts.height ?? (rect.height && rect.height > 0 ? rect.height : viewportHeight),
2940
+ scale: 1
2941
+ };
2918
2942
  const shot = await cdp.send(
2919
2943
  "Page.captureScreenshot",
2920
2944
  {
2921
2945
  format: "png",
2922
- clip: {
2923
- x: 0,
2924
- y: 0,
2925
- width: opts.width,
2926
- height: opts.height,
2927
- scale: 1
2928
- }
2946
+ clip
2929
2947
  },
2930
2948
  sessionId
2931
2949
  );
2932
2950
  writeFileSync(opts.outputPath, Buffer.from(shot.data, "base64"));
2951
+ return { width: clip.width, height: clip.height };
2933
2952
  } finally {
2934
2953
  cleanup();
2935
2954
  }
@@ -3058,16 +3077,13 @@ function detectToolResourceUri(tool) {
3058
3077
  return uiMeta?.resourceUri ?? meta["openai/outputTemplate"] ?? null;
3059
3078
  }
3060
3079
  async function captureToolScreenshot(inputs, options = {}) {
3061
- const width = options.width ?? 800;
3062
- const height = options.height ?? 600;
3080
+ const { width, height } = options;
3063
3081
  const theme = options.theme ?? "light";
3064
3082
  const timeoutMs = options.timeoutMs ?? 3e4;
3065
3083
  const delayMs = options.delayMs ?? 0;
3066
3084
  const chromePath = options.cdpUrl ? void 0 : resolveChromePath();
3067
3085
  const view = extractViewName(inputs.resourceUri);
3068
3086
  const devOptions = {
3069
- width: String(width),
3070
- height: String(height),
3071
3087
  theme,
3072
3088
  timeout: String(timeoutMs),
3073
3089
  inspector: options.inspector,
@@ -3087,10 +3103,13 @@ async function captureToolScreenshot(inputs, options = {}) {
3087
3103
  };
3088
3104
  const previewUrl = new URL(`/inspector/preview/${view}`, devHandle.url);
3089
3105
  previewUrl.searchParams.set("theme", theme);
3106
+ if (width !== void 0) {
3107
+ previewUrl.searchParams.set("width", String(width));
3108
+ }
3090
3109
  const ts = timestampSuffix();
3091
3110
  const outputPath = path6.resolve(options.output ?? `./${view}-${ts}.png`);
3092
3111
  await mkdir2(path6.dirname(outputPath), { recursive: true });
3093
- await captureScreenshot({
3112
+ const captured = await captureScreenshot({
3094
3113
  url: previewUrl.toString(),
3095
3114
  width,
3096
3115
  height,
@@ -3104,7 +3123,12 @@ async function captureToolScreenshot(inputs, options = {}) {
3104
3123
  bundle,
3105
3124
  deviceScaleFactor: options.deviceScaleFactor
3106
3125
  });
3107
- return { outputPath, width, height, view };
3126
+ return {
3127
+ outputPath,
3128
+ width: captured.width,
3129
+ height: captured.height,
3130
+ view
3131
+ };
3108
3132
  } finally {
3109
3133
  killChild(devHandle?.child);
3110
3134
  }
@@ -3234,9 +3258,10 @@ function timestampSuffix(date = /* @__PURE__ */ new Date()) {
3234
3258
  return `${datePart}_${timePart}`;
3235
3259
  }
3236
3260
  function extractViewName(resourceUri) {
3237
- const m = resourceUri.match(/^ui:\/\/widget\/(.+)$/);
3238
- if (!m) return resourceUri;
3239
- return m[1].replace(/\.html$/, "").replace(/\.[0-9a-f]+$/i, "");
3261
+ const m = resourceUri.match(/^ui:\/\/([^/]+)\/(.+)$/);
3262
+ if (!m) return encodeURIComponent(resourceUri);
3263
+ const name = m[2].replace(/\.html$/, "").replace(/\.[0-9a-f]+$/i, "");
3264
+ return m[1] === "widget" ? name : `${m[1]}-${name}`;
3240
3265
  }
3241
3266
  function parseDimension(raw, name) {
3242
3267
  const n = parseInt(raw, 10);
@@ -3336,8 +3361,8 @@ async function screenshotCommand(options, argsList, context) {
3336
3361
  exitCode = 1;
3337
3362
  return;
3338
3363
  }
3339
- const width = parseDimension(options.width, "width");
3340
- const height = parseDimension(options.height, "height");
3364
+ const width = options.width !== void 0 ? parseDimension(options.width, "width") : void 0;
3365
+ const height = options.height !== void 0 ? parseDimension(options.height, "height") : void 0;
3341
3366
  const navTimeout = parseInt(options.timeout, 10) || 3e4;
3342
3367
  const delayMs = options.delay ? parseInt(options.delay, 10) : 0;
3343
3368
  const deviceScaleFactor = options.deviceScaleFactor ? parseDeviceScaleFactor(options.deviceScaleFactor) : void 0;
@@ -3446,7 +3471,13 @@ function withCommonScreenshotOptions(cmd) {
3446
3471
  ).option(
3447
3472
  "--tool <name>",
3448
3473
  "Tool to call. Its UI resource is rendered with the result."
3449
- ).option("--width <px>", "Browser viewport width in pixels.", "800").option("--height <px>", "Browser viewport height in pixels.", "600").option(
3474
+ ).option(
3475
+ "--width <px>",
3476
+ "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)."
3477
+ ).option(
3478
+ "--height <px>",
3479
+ "Output image height in pixels. When omitted, fits the widget's natural height."
3480
+ ).option(
3450
3481
  "--device-scale-factor <n>",
3451
3482
  "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."
3452
3483
  ).option(
@@ -7137,6 +7168,16 @@ A new release of ${source_default.bold(PACKAGE_NAME)} is available: ${source_def
7137
7168
  }
7138
7169
  }
7139
7170
 
7171
+ // src/utils/widget-paths.ts
7172
+ function getWidgetAssetBase(mcpUrl, widgetName) {
7173
+ const widgetPath = `/mcp-use/widgets/${widgetName}/`;
7174
+ if (!mcpUrl) {
7175
+ return widgetPath;
7176
+ }
7177
+ const origin = mcpUrl.replace(/\/+$/, "");
7178
+ return `${origin}${widgetPath}`;
7179
+ }
7180
+
7140
7181
  // src/index.ts
7141
7182
  var program = new Command7();
7142
7183
  var packageContent = readFileSync2(
@@ -7627,7 +7668,7 @@ if (container && Component) {
7627
7668
  "widgets",
7628
7669
  widgetName
7629
7670
  );
7630
- const baseUrl = mcpUrl ? `${mcpUrl}/${widgetName}/` : `/mcp-use/widgets/${widgetName}/`;
7671
+ const baseUrl = getWidgetAssetBase(mcpUrl, widgetName);
7631
7672
  let widgetMetadata = {};
7632
7673
  try {
7633
7674
  const metadataTempDir = path11.join(
@@ -7943,7 +7984,9 @@ export default {
7943
7984
  try {
7944
7985
  const htmlPath = path11.join(outDir, "index.html");
7945
7986
  let html = await fs11.readFile(htmlPath, "utf8");
7946
- const injectionScript = `<script>window.__getFile = (filename) => { return "${mcpUrl}/${widgetName}/"+filename }; window.__mcpPublicUrl = "${mcpServerUrl}/mcp-use/public"; window.__mcpPublicAssetsUrl = "${mcpUrl}/public";</script>`;
7987
+ const widgetAssetBase = getWidgetAssetBase(mcpUrl, widgetName);
7988
+ const mcpOrigin = mcpUrl ? mcpUrl.replace(/\/+$/, "") : mcpServerUrl;
7989
+ const injectionScript = `<script>window.__getFile = (filename) => { return "${widgetAssetBase}"+filename }; window.__mcpPublicUrl = "${mcpServerUrl}/mcp-use/public"; window.__mcpPublicAssetsUrl = "${mcpOrigin}/mcp-use/public";</script>`;
7947
7990
  if (!html.includes("window.__mcpPublicUrl")) {
7948
7991
  html = html.replace(
7949
7992
  /<head[^>]*>/i,