@mario.andreschak/mcp-browser 3.45.0 → 3.45.2

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 ADDED
@@ -0,0 +1,52 @@
1
+ # Browser MCP
2
+
3
+ The browser MCP provides interactive Patchright sessions, deterministic PNG capture, and WebM recording.
4
+
5
+ ## Evidence artifacts
6
+
7
+ `browser_screenshot` creates an immutable PNG by default under
8
+ `screenshots/browser/<sessionId>/<artifactId>-viewport.png` (or
9
+ `-full-page.png`). An optional `outputPath` is accepted only inside the
10
+ FLUJO data directory or configured screenshot root. Existing destinations,
11
+ root escapes, drive-relative/device/UNC paths, and symlink or junction escapes
12
+ are rejected.
13
+
14
+ Screenshot results include the artifact ID, SHA-256, capture timestamp, CSS
15
+ viewport, DPR, encoded PNG dimensions, and page/session metadata. When the
16
+ target is an active recording, the result also links the PNG to its
17
+ `recordingId` and configured recording geometry. PNGs are lossless evidence;
18
+ callers must still freeze application animation, timestamps, cursors, and
19
+ changing overlays before exact comparisons.
20
+
21
+ ## Recording geometry
22
+
23
+ Recording contexts use an explicit CSS viewport and device scale factor 1.
24
+ The configured video surface matches that viewport. Recording sessions have a
25
+ fixed viewport policy: resizing the MCP App or dock scales/letterboxes the live
26
+ stream and never mutates the page used to produce evidence.
27
+
28
+ Start, status, and stop results distinguish:
29
+
30
+ - `requestedViewport`
31
+ - `actualViewport`
32
+ - `deviceScaleFactor`
33
+ - `configuredVideoResolution`
34
+ - `actualEncodedVideoResolution` (after finalization, or `null` with a warning)
35
+ - content bounds, letterbox insets, and `geometryMismatch`
36
+
37
+ WebM remains review/playback evidence; use recording-linked PNG screenshots for
38
+ exact pixel evidence.
39
+
40
+ ## Session lifecycle and ownership
41
+
42
+ The backend-provided `_meta.flujo.ownerScope` is authoritative. Calls without
43
+ metadata use the process-local `legacy:anonymous` compatibility scope.
44
+ Session IDs cannot be listed, used, attached, stopped, or closed across owner
45
+ scopes. The live-view gateway additionally requires a private per-session
46
+ capability delivered to the MCP App through result metadata.
47
+
48
+ Capacity is reserved synchronously before browser creation, so concurrent opens
49
+ cannot race above `FLUJO_BROWSER_MAX_SESSIONS`. Dead and expired entries are
50
+ reclaimed before enforcing the cap. `browser_list_sessions` returns
51
+ owner-filtered lifecycle/capacity diagnostics, and `browser_release_owner`
52
+ idempotently finalizes recordings and releases sessions for the caller scope.
package/dist/capture.d.ts CHANGED
@@ -1,8 +1,31 @@
1
1
  import type { Page } from 'patchright';
2
+ export type Resolution = {
3
+ width: number;
4
+ height: number;
5
+ };
6
+ export type ResolutionOptions = {
7
+ defaultValue: Resolution;
8
+ minWidth: number;
9
+ minHeight: number;
10
+ maxWidth: number;
11
+ maxHeight: number;
12
+ even?: boolean;
13
+ };
14
+ export type NormalizedResolution = {
15
+ requested: Resolution;
16
+ effective: Resolution;
17
+ explicit: boolean;
18
+ warnings: string[];
19
+ };
20
+ /** Normalize presets, WIDTHxHEIGHT strings, objects, and legacy width/height values. */
21
+ export declare function normalizeResolution(resolution: unknown, legacyWidth: unknown, legacyHeight: unknown, options: ResolutionOptions): NormalizedResolution;
22
+ /** Try the requested size first, then progressively safer standard resolutions. */
23
+ export declare function resolutionFallbacks(primary: Resolution): Resolution[];
24
+ export declare function finiteParameter(value: unknown, fallback: number): number;
2
25
  /**
3
26
  * Local `getDataDir()`/`isInside()` — deliberately not imported from
4
27
  * `mcp-servers/shared`: the browser package resolves `FLUJO_DATA_DIR` inline
5
- * everywhere else (see `runtime.ts`'s `screenshotRoot()`), and does not carry
28
+ * and does not carry
6
29
  * the `@flujo-ai/mcp-shared` workspace dependency the other packages use.
7
30
  */
8
31
  export declare function getDataDir(): string;
@@ -10,21 +33,22 @@ export declare function isInside(root: string, candidate: string): boolean;
10
33
  export type CaptureSource = {
11
34
  kind: 'html';
12
35
  html: string;
36
+ warnings: string[];
13
37
  } | {
14
38
  kind: 'url';
15
39
  url: string;
40
+ warnings: string[];
16
41
  };
17
42
  /** Assert a single, stable PNG color type and return it. Never silently accepts a malformed image. */
18
43
  export declare function pngColorType(png: Buffer): number;
19
- /** Gates 1-3 of the local-capture ladder; gate 4 is `assertNavigationAllowed()` itself. */
20
- export declare function assertLocalCaptureAllowed(resolvedPath: string, allowLocal: boolean): Promise<void>;
44
+ export declare function pngDimensions(png: Buffer): Resolution;
21
45
  /**
22
- * Resolve exactly one of `url` / `html` / `filePath` into a `CaptureSource`,
23
- * applying local-source gating for `file://` and localhost/private-host
24
- * inputs and the ordinary `assertNavigationAllowed()` gate for everything
25
- * else.
46
+ * Resolve the compact `source` parameter while retaining the old url/html/
47
+ * filePath aliases. If a caller supplies several aliases, choose the clearest
48
+ * one and report the adjustment instead of failing the whole tool call.
26
49
  */
27
50
  export declare function resolveCaptureSource(args: {
51
+ source?: unknown;
28
52
  url?: string;
29
53
  html?: string;
30
54
  filePath?: string;
@@ -42,7 +66,7 @@ export type CapturePageOptions = {
42
66
  * boolean-coerced and discarded — never returned to the caller, per D4) →
43
67
  * screenshot with animations disabled.
44
68
  */
45
- export declare function captureDeterministicPng(page: Page, source: CaptureSource, options: CapturePageOptions): Promise<{
69
+ export declare function captureDeterministicPng(page: Page, source: CaptureSource | undefined, options: CapturePageOptions): Promise<{
46
70
  png: Buffer;
47
71
  colorType: number;
48
72
  }>;
@@ -55,7 +79,7 @@ export type CaptureRegion = {
55
79
  height: number;
56
80
  };
57
81
  /** Region capture is a clipped `page.screenshot()`, not a manual pixel crop, so DPR/scroll never drift the result. */
58
- export declare function captureRegionPng(page: Page, source: CaptureSource, region: CaptureRegion, timeoutMs: number): Promise<{
82
+ export declare function captureRegionPng(page: Page, source: CaptureSource | undefined, region: CaptureRegion, timeoutMs: number): Promise<{
59
83
  png: Buffer;
60
84
  colorType: number;
61
85
  }>;
@@ -88,7 +112,7 @@ export type ElementMetrics = {
88
112
  };
89
113
  export declare function evaluateElementMetrics(page: Page, selectors: string[]): Promise<ElementMetrics[]>;
90
114
  export declare function sha256Hex(data: Buffer): string;
91
- /** Default persistence root for still captures, mirroring `writeScreenshotArtifact()`'s layout. */
115
+ /** Default persistence root for immutable still-capture artifacts. */
92
116
  export declare function captureRoot(): string;
93
117
  /** Write a capture artifact, confining any caller-supplied `outputPath` to the data dir or the capture root. */
94
118
  export declare function writeCaptureArtifact(outputPath: string | undefined, defaultRelativePath: string[], data: Buffer): Promise<string>;
package/dist/capture.js CHANGED
@@ -6,26 +6,134 @@
6
6
  * an ephemeral capture context (`createCaptureContext()` in `runtime.ts`) or
7
7
  * an existing session's page — and never owns session lifecycle itself.
8
8
  *
9
- * Local-source gating (`assertLocalCaptureAllowed`) is the narrow, explicit
10
- * bypass mentioned in the plan: it does not touch `assertNavigationAllowed()`,
11
- * so ordinary `browser_open`/`browser_navigate` behaviour is unchanged. Four
12
- * independent gates must all hold before a `file://` / localhost / private
13
- * host is captured:
14
- * 1. `allowLocal === true` on the call;
15
- * 2. `FLUJO_BROWSER_ALLOW_LOCAL_CAPTURE` is truthy (default off);
16
- * 3. the resolved realpath satisfies `isInside()` against the FLUJO data
17
- * directory or an entry in `FLUJO_BROWSER_LOCAL_CAPTURE_ROOTS`;
18
- * 4. everything else still goes through the ordinary `assertNavigationAllowed()`.
9
+ * Sources intentionally use the same permissive target normalization as
10
+ * ordinary browser navigation. Models may pass a URL, localhost address,
11
+ * local path, file:// URL, or inline HTML without having to coordinate policy
12
+ * flags. Output paths remain confined to FLUJO's data roots.
19
13
  */
20
14
  import { promises as fs } from 'node:fs';
21
15
  import { createHash } from 'node:crypto';
22
16
  import path from 'node:path';
23
- import { fileURLToPath, pathToFileURL } from 'node:url';
24
- import { BrowserMcpError, assertNavigationAllowed, enabledEnv } from './runtime.js';
17
+ import { BrowserMcpError, assertNavigationAllowed } from './runtime.js';
18
+ const RESOLUTION_PRESETS = {
19
+ '360p': { width: 640, height: 360 },
20
+ '480p': { width: 854, height: 480 },
21
+ '720p': { width: 1280, height: 720 },
22
+ hd: { width: 1280, height: 720 },
23
+ '1080p': { width: 1920, height: 1080 },
24
+ fhd: { width: 1920, height: 1080 },
25
+ '1440p': { width: 2560, height: 1440 },
26
+ qhd: { width: 2560, height: 1440 },
27
+ '2160p': { width: 3840, height: 2160 },
28
+ '4k': { width: 3840, height: 2160 },
29
+ };
30
+ function finiteNumber(value) {
31
+ if (typeof value === 'number' && Number.isFinite(value))
32
+ return value;
33
+ if (typeof value === 'string' && value.trim()) {
34
+ const parsed = Number(value.trim());
35
+ if (Number.isFinite(parsed))
36
+ return parsed;
37
+ }
38
+ return undefined;
39
+ }
40
+ function parseResolution(value) {
41
+ if (typeof value === 'string') {
42
+ const normalized = value.trim().toLowerCase().replace(/\s+/g, '');
43
+ if (RESOLUTION_PRESETS[normalized])
44
+ return { ...RESOLUTION_PRESETS[normalized] };
45
+ const match = /^(\d{2,5})[x×](\d{2,5})$/.exec(normalized);
46
+ if (match)
47
+ return { width: Number(match[1]), height: Number(match[2]) };
48
+ }
49
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
50
+ const record = value;
51
+ const width = finiteNumber(record.width);
52
+ const height = finiteNumber(record.height);
53
+ if (width !== undefined && height !== undefined)
54
+ return { width, height };
55
+ }
56
+ return undefined;
57
+ }
58
+ function fitInside(value, maxWidth, maxHeight) {
59
+ const scale = Math.min(1, maxWidth / value.width, maxHeight / value.height);
60
+ return {
61
+ width: Math.round(value.width * scale),
62
+ height: Math.round(value.height * scale),
63
+ };
64
+ }
65
+ function clamp(value, min, max) {
66
+ return Math.min(max, Math.max(min, Math.round(value)));
67
+ }
68
+ function makeEven(value, min) {
69
+ const rounded = Math.max(min, value);
70
+ return rounded % 2 === 0 ? rounded : rounded - 1;
71
+ }
72
+ /** Normalize presets, WIDTHxHEIGHT strings, objects, and legacy width/height values. */
73
+ export function normalizeResolution(resolution, legacyWidth, legacyHeight, options) {
74
+ const warnings = [];
75
+ const parsed = parseResolution(resolution);
76
+ const legacyW = finiteNumber(legacyWidth);
77
+ const legacyH = finiteNumber(legacyHeight);
78
+ const explicit = parsed !== undefined || legacyW !== undefined || legacyH !== undefined;
79
+ let requested = parsed ?? {
80
+ width: legacyW ?? options.defaultValue.width,
81
+ height: legacyH ?? options.defaultValue.height,
82
+ };
83
+ if (resolution !== undefined && !parsed) {
84
+ warnings.push(`Unrecognized resolution ${JSON.stringify(resolution)}; using ${requested.width}x${requested.height}.`);
85
+ }
86
+ if (!parsed && (legacyW !== undefined || legacyH !== undefined)) {
87
+ requested = {
88
+ width: legacyW ?? Math.round((requested.height * options.defaultValue.width) / options.defaultValue.height),
89
+ height: legacyH ?? Math.round((requested.width * options.defaultValue.height) / options.defaultValue.width),
90
+ };
91
+ }
92
+ const fitted = fitInside({
93
+ width: Math.max(1, requested.width),
94
+ height: Math.max(1, requested.height),
95
+ }, options.maxWidth, options.maxHeight);
96
+ let effective = {
97
+ width: clamp(fitted.width, options.minWidth, options.maxWidth),
98
+ height: clamp(fitted.height, options.minHeight, options.maxHeight),
99
+ };
100
+ if (options.even) {
101
+ effective = {
102
+ width: makeEven(effective.width, options.minWidth),
103
+ height: makeEven(effective.height, options.minHeight),
104
+ };
105
+ }
106
+ requested = { width: Math.round(requested.width), height: Math.round(requested.height) };
107
+ if (effective.width !== requested.width || effective.height !== requested.height) {
108
+ warnings.push(`Requested ${requested.width}x${requested.height}; using the supported ${effective.width}x${effective.height} resolution.`);
109
+ }
110
+ return { requested, effective, explicit, warnings };
111
+ }
112
+ /** Try the requested size first, then progressively safer standard resolutions. */
113
+ export function resolutionFallbacks(primary) {
114
+ const candidates = [
115
+ primary,
116
+ { width: 1920, height: 1080 },
117
+ { width: 1280, height: 720 },
118
+ { width: 854, height: 480 },
119
+ { width: 640, height: 360 },
120
+ ];
121
+ const seen = new Set();
122
+ return candidates.filter(({ width, height }) => {
123
+ const key = `${width}x${height}`;
124
+ if (seen.has(key))
125
+ return false;
126
+ seen.add(key);
127
+ return true;
128
+ });
129
+ }
130
+ export function finiteParameter(value, fallback) {
131
+ return finiteNumber(value) ?? fallback;
132
+ }
25
133
  /**
26
134
  * Local `getDataDir()`/`isInside()` — deliberately not imported from
27
135
  * `mcp-servers/shared`: the browser package resolves `FLUJO_DATA_DIR` inline
28
- * everywhere else (see `runtime.ts`'s `screenshotRoot()`), and does not carry
136
+ * and does not carry
29
137
  * the `@flujo-ai/mcp-shared` workspace dependency the other packages use.
30
138
  */
31
139
  export function getDataDir() {
@@ -45,90 +153,37 @@ export function pngColorType(png) {
45
153
  }
46
154
  return png.readUInt8(PNG_COLOR_TYPE_OFFSET);
47
155
  }
48
- async function realpathIfExists(candidate) {
49
- try {
50
- return await fs.realpath(candidate);
51
- }
52
- catch {
53
- return path.resolve(candidate);
54
- }
55
- }
56
- function localCaptureRoots() {
57
- const roots = [getDataDir()];
58
- const raw = process.env.FLUJO_BROWSER_LOCAL_CAPTURE_ROOTS?.trim();
59
- if (raw) {
60
- for (const entry of raw.split(path.delimiter)) {
61
- const trimmed = entry.trim();
62
- if (trimmed)
63
- roots.push(path.resolve(trimmed));
64
- }
65
- }
66
- return roots;
67
- }
68
- function isLocalOrPrivateOrigin(url) {
69
- if (url.protocol === 'file:')
70
- return true;
71
- const hostname = url.hostname.toLowerCase().replace(/^\[|\]$/g, '');
72
- return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1'
73
- || hostname.endsWith('.localhost') || hostname.endsWith('.local');
74
- }
75
- /** Gates 1-3 of the local-capture ladder; gate 4 is `assertNavigationAllowed()` itself. */
76
- export async function assertLocalCaptureAllowed(resolvedPath, allowLocal) {
77
- if (!allowLocal) {
78
- throw new BrowserMcpError('NAVIGATION_BLOCKED', 'Local file/localhost capture requires allowLocal=true.');
79
- }
80
- if (!enabledEnv('FLUJO_BROWSER_ALLOW_LOCAL_CAPTURE')) {
81
- throw new BrowserMcpError('NAVIGATION_BLOCKED', 'Local capture is disabled by policy (set FLUJO_BROWSER_ALLOW_LOCAL_CAPTURE=1 to enable).');
82
- }
83
- const real = await realpathIfExists(resolvedPath);
84
- const roots = localCaptureRoots();
85
- if (!roots.some((root) => isInside(root, real))) {
86
- throw new BrowserMcpError('NAVIGATION_BLOCKED', 'The local path is outside the allowed capture roots.');
156
+ export function pngDimensions(png) {
157
+ if (png.length < 24 || png.subarray(0, 8).toString('hex') !== PNG_SIGNATURE) {
158
+ throw new BrowserMcpError('UNEXPECTED', 'The captured image is not a valid PNG.');
87
159
  }
160
+ return { width: png.readUInt32BE(16), height: png.readUInt32BE(20) };
88
161
  }
89
162
  /**
90
- * Resolve exactly one of `url` / `html` / `filePath` into a `CaptureSource`,
91
- * applying local-source gating for `file://` and localhost/private-host
92
- * inputs and the ordinary `assertNavigationAllowed()` gate for everything
93
- * else.
163
+ * Resolve the compact `source` parameter while retaining the old url/html/
164
+ * filePath aliases. If a caller supplies several aliases, choose the clearest
165
+ * one and report the adjustment instead of failing the whole tool call.
94
166
  */
95
167
  export async function resolveCaptureSource(args) {
96
- const provided = [args.url, args.html, args.filePath].filter((value) => typeof value === 'string' && value.length > 0);
97
- if (provided.length !== 1) {
98
- throw new BrowserMcpError('INVALID_ARGUMENT', 'Provide exactly one of url, html, or filePath.');
99
- }
100
- if (typeof args.html === 'string') {
101
- return { kind: 'html', html: args.html };
102
- }
103
- const allowLocal = args.allowLocal === true;
104
- if (typeof args.filePath === 'string') {
105
- const resolved = path.resolve(args.filePath);
106
- await assertLocalCaptureAllowed(resolved, allowLocal);
107
- return { kind: 'url', url: pathToFileURL(resolved).href };
108
- }
109
- const raw = args.url;
110
- let parsed;
111
- try {
112
- parsed = new URL(raw);
113
- }
114
- catch {
115
- throw new BrowserMcpError('NAVIGATION_BLOCKED', 'The URL is malformed.');
168
+ const warnings = [];
169
+ const compact = typeof args.source === 'string' && args.source.trim() ? args.source.trim() : undefined;
170
+ const html = typeof args.html === 'string' && args.html.length > 0 ? args.html : undefined;
171
+ const filePath = typeof args.filePath === 'string' && args.filePath.trim() ? args.filePath.trim() : undefined;
172
+ const url = typeof args.url === 'string' && args.url.trim() ? args.url.trim() : undefined;
173
+ const count = [compact, html, filePath, url].filter(Boolean).length;
174
+ if (count === 0) {
175
+ throw new BrowserMcpError('INVALID_ARGUMENT', 'Provide source, or omit it while supplying an active sessionId.');
116
176
  }
117
- if (parsed.protocol === 'file:') {
118
- await assertLocalCaptureAllowed(fileURLToPath(parsed), allowLocal);
119
- return { kind: 'url', url: parsed.href };
120
- }
121
- if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
122
- throw new BrowserMcpError('NAVIGATION_BLOCKED', 'Only HTTP, HTTPS, and file:// URLs are allowed.');
123
- }
124
- if (isLocalOrPrivateOrigin(parsed)) {
125
- await assertLocalCaptureAllowed(raw, allowLocal);
126
- return { kind: 'url', url: parsed.href };
127
- }
128
- // Gate 4: ordinary navigation policy, byte-for-byte unchanged, for anything
129
- // that is not a local/private destination.
130
- const allowedUrl = await assertNavigationAllowed(raw);
131
- return { kind: 'url', url: allowedUrl.href };
177
+ if (count > 1)
178
+ warnings.push('Several capture sources were supplied; source/html/filePath/url precedence was applied.');
179
+ const chosen = compact ?? html ?? filePath ?? url;
180
+ const isHtml = compact
181
+ ? /^\s*(?:<!doctype\s+html|<html|<body|<svg|<[A-Za-z][^>]*>)/i.test(compact)
182
+ : html !== undefined && chosen === html;
183
+ if (isHtml)
184
+ return { kind: 'html', html: chosen, warnings };
185
+ const target = await assertNavigationAllowed(chosen);
186
+ return { kind: 'url', url: target.href, warnings };
132
187
  }
133
188
  function looksLikeJsPredicate(expression) {
134
189
  return /[(){}=]/.test(expression) || /^\s*function\b/.test(expression) || expression.includes('=>');
@@ -141,10 +196,10 @@ function looksLikeJsPredicate(expression) {
141
196
  */
142
197
  export async function captureDeterministicPng(page, source, options) {
143
198
  const timeout = options.timeoutMs;
144
- if (source.kind === 'html') {
199
+ if (source?.kind === 'html') {
145
200
  await page.setContent(source.html, { waitUntil: 'load', timeout });
146
201
  }
147
- else {
202
+ else if (source) {
148
203
  await page.goto(source.url, { waitUntil: 'load', timeout });
149
204
  }
150
205
  await page.waitForLoadState('load', { timeout }).catch(() => undefined);
@@ -201,10 +256,10 @@ export async function navigateCaptureSource(page, source, timeoutMs) {
201
256
  }
202
257
  /** Region capture is a clipped `page.screenshot()`, not a manual pixel crop, so DPR/scroll never drift the result. */
203
258
  export async function captureRegionPng(page, source, region, timeoutMs) {
204
- if (source.kind === 'html') {
259
+ if (source?.kind === 'html') {
205
260
  await page.setContent(source.html, { waitUntil: 'load', timeout: timeoutMs });
206
261
  }
207
- else {
262
+ else if (source) {
208
263
  await page.goto(source.url, { waitUntil: 'load', timeout: timeoutMs });
209
264
  }
210
265
  await page.waitForLoadState('load', { timeout: timeoutMs }).catch(() => undefined);
@@ -272,7 +327,7 @@ export async function evaluateElementMetrics(page, selectors) {
272
327
  export function sha256Hex(data) {
273
328
  return createHash('sha256').update(data).digest('hex');
274
329
  }
275
- /** Default persistence root for still captures, mirroring `writeScreenshotArtifact()`'s layout. */
330
+ /** Default persistence root for immutable still-capture artifacts. */
276
331
  export function captureRoot() {
277
332
  const configured = process.env.FLUJO_BROWSER_SCREENSHOT_DIR?.trim();
278
333
  if (configured)
@@ -283,11 +338,13 @@ export function captureRoot() {
283
338
  /** Write a capture artifact, confining any caller-supplied `outputPath` to the data dir or the capture root. */
284
339
  export async function writeCaptureArtifact(outputPath, defaultRelativePath, data) {
285
340
  let filePath;
341
+ const roots = [getDataDir(), captureRoot()];
286
342
  if (outputPath) {
343
+ if (/^[A-Za-z]:[^\\/]/.test(outputPath) || /^\\\\/.test(outputPath)) {
344
+ throw new BrowserMcpError('INVALID_ARGUMENT', 'outputPath must not use drive-relative, UNC, or Windows device-path syntax.');
345
+ }
287
346
  const resolved = path.resolve(outputPath);
288
- const dataDir = getDataDir();
289
- const root = captureRoot();
290
- if (!isInside(dataDir, resolved) && !isInside(root, resolved)) {
347
+ if (!roots.some((root) => isInside(root, resolved))) {
291
348
  throw new BrowserMcpError('INVALID_ARGUMENT', 'outputPath must be inside the FLUJO data directory or the browser screenshot root.');
292
349
  }
293
350
  filePath = resolved;
@@ -295,8 +352,51 @@ export async function writeCaptureArtifact(outputPath, defaultRelativePath, data
295
352
  else {
296
353
  filePath = path.join(captureRoot(), ...defaultRelativePath);
297
354
  }
298
- await fs.mkdir(path.dirname(filePath), { recursive: true });
299
- await fs.writeFile(filePath, data);
300
- return filePath;
355
+ if (path.extname(filePath).toLowerCase() !== '.png') {
356
+ throw new BrowserMcpError('INVALID_ARGUMENT', 'Browser screenshot outputPath must end in .png.');
357
+ }
358
+ if (process.platform === 'win32') {
359
+ const reserved = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i;
360
+ if (path.resolve(filePath).split(/[\\/]/).some((part) => reserved.test(part))) {
361
+ throw new BrowserMcpError('INVALID_ARGUMENT', 'outputPath contains a Windows reserved device name.');
362
+ }
363
+ }
364
+ const parent = path.dirname(filePath);
365
+ await fs.mkdir(parent, { recursive: true });
366
+ const [realParent, realRoots] = await Promise.all([
367
+ fs.realpath(parent),
368
+ Promise.all(roots.map(async (root) => {
369
+ await fs.mkdir(root, { recursive: true });
370
+ return fs.realpath(root);
371
+ })),
372
+ ]);
373
+ if (!realRoots.some((root) => isInside(root, realParent))) {
374
+ throw new BrowserMcpError('INVALID_ARGUMENT', 'outputPath traverses a symlink or junction outside an approved artifact root.');
375
+ }
376
+ let handle;
377
+ try {
378
+ handle = await fs.open(filePath, 'wx', 0o600);
379
+ }
380
+ catch (error) {
381
+ if (error.code === 'EEXIST') {
382
+ throw new BrowserMcpError('INVALID_ARGUMENT', 'outputPath already exists; browser artifacts never overwrite existing evidence.');
383
+ }
384
+ throw error;
385
+ }
386
+ try {
387
+ const boundaryParent = await fs.realpath(parent);
388
+ if (boundaryParent !== realParent || !realRoots.some((root) => isInside(root, boundaryParent))) {
389
+ throw new BrowserMcpError('INVALID_ARGUMENT', 'outputPath parent changed during artifact creation.');
390
+ }
391
+ await handle.writeFile(data);
392
+ await handle.sync();
393
+ }
394
+ catch (error) {
395
+ await handle.close().catch(() => undefined);
396
+ await fs.unlink(filePath).catch(() => undefined);
397
+ throw error;
398
+ }
399
+ await handle.close();
400
+ return path.resolve(filePath);
301
401
  }
302
402
  //# sourceMappingURL=capture.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"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"}
package/dist/gateway.d.ts CHANGED
@@ -20,7 +20,7 @@ export declare function browserGatewayEndpoint(): BrowserGatewayEndpoint | undef
20
20
  * until a client opens /audio. Failure is intentionally non-fatal: browser
21
21
  * navigation and the screenshot stream must continue when audio is unavailable.
22
22
  */
23
- export declare function prepareBrowserAudioStream(sessionId: string): Promise<void>;
23
+ export declare function prepareBrowserAudioStream(sessionId: string, gatewayToken?: string): Promise<void>;
24
24
  export declare function shutdownBrowserGateway(): Promise<void>;
25
25
  /** Exported for tests: host speaker output stays muted unless opted in. */
26
26
  export declare function browserAudioEnabled(): boolean;