fix: use z.coerce.number() for all numeric tool parameters
MCP clients may send numbers as strings in JSON parameters. Using z.coerce.number() instead of z.number() across all 13 tool files ensures string-to-number coercion happens automatically, preventing "Expected number, received string" validation errors.
This commit is contained in:
parent
a65f00667a
commit
6cbc5f6bc1
@ -565,7 +565,7 @@ const enableDebugToolbarSchema = z.object({
|
|||||||
theme: z.enum(['light', 'dark', 'transparent']).optional().describe('Visual theme: light (white), dark (gray), transparent (glass effect)'),
|
theme: z.enum(['light', 'dark', 'transparent']).optional().describe('Visual theme: light (white), dark (gray), transparent (glass effect)'),
|
||||||
minimized: z.boolean().optional().describe('Start in compact pill mode (default: false)'),
|
minimized: z.boolean().optional().describe('Start in compact pill mode (default: false)'),
|
||||||
showDetails: z.boolean().optional().describe('Show session details when expanded (default: true)'),
|
showDetails: z.boolean().optional().describe('Show session details when expanded (default: true)'),
|
||||||
opacity: z.number().min(0.1).max(1.0).optional().describe('Toolbar opacity 0.1-1.0 (default: 0.95)')
|
opacity: z.coerce.number().min(0.1).max(1.0).optional().describe('Toolbar opacity 0.1-1.0 (default: 0.95)')
|
||||||
});
|
});
|
||||||
|
|
||||||
const injectCustomCodeSchema = z.object({
|
const injectCustomCodeSchema = z.object({
|
||||||
@ -580,13 +580,13 @@ const enableVoiceCollaborationSchema = z.object({
|
|||||||
enabled: z.boolean().optional().describe('Enable voice collaboration features (default: true)'),
|
enabled: z.boolean().optional().describe('Enable voice collaboration features (default: true)'),
|
||||||
autoInitialize: z.boolean().optional().describe('Automatically initialize voice on page load (default: true)'),
|
autoInitialize: z.boolean().optional().describe('Automatically initialize voice on page load (default: true)'),
|
||||||
voiceOptions: z.object({
|
voiceOptions: z.object({
|
||||||
rate: z.number().min(0.1).max(10).optional().describe('Speech rate (0.1-10, default: 1.0)'),
|
rate: z.coerce.number().min(0.1).max(10).optional().describe('Speech rate (0.1-10, default: 1.0)'),
|
||||||
pitch: z.number().min(0).max(2).optional().describe('Speech pitch (0-2, default: 1.0)'),
|
pitch: z.coerce.number().min(0).max(2).optional().describe('Speech pitch (0-2, default: 1.0)'),
|
||||||
volume: z.number().min(0).max(1).optional().describe('Speech volume (0-1, default: 1.0)'),
|
volume: z.coerce.number().min(0).max(1).optional().describe('Speech volume (0-1, default: 1.0)'),
|
||||||
lang: z.string().optional().describe('Language code (default: en-US)')
|
lang: z.string().optional().describe('Language code (default: en-US)')
|
||||||
}).optional().describe('Voice synthesis options'),
|
}).optional().describe('Voice synthesis options'),
|
||||||
listenOptions: z.object({
|
listenOptions: z.object({
|
||||||
timeout: z.number().min(1000).max(60000).optional().describe('Voice input timeout in milliseconds (default: 10000)'),
|
timeout: z.coerce.number().min(1000).max(60000).optional().describe('Voice input timeout in milliseconds (default: 10000)'),
|
||||||
lang: z.string().optional().describe('Speech recognition language (default: en-US)'),
|
lang: z.string().optional().describe('Speech recognition language (default: en-US)'),
|
||||||
continuous: z.boolean().optional().describe('Keep listening after first result (default: false)')
|
continuous: z.boolean().optional().describe('Keep listening after first result (default: false)')
|
||||||
}).optional().describe('Voice recognition options')
|
}).optional().describe('Voice recognition options')
|
||||||
|
|||||||
@ -40,10 +40,10 @@ const resize = defineTabTool({
|
|||||||
schema: {
|
schema: {
|
||||||
name: 'browser_resize',
|
name: 'browser_resize',
|
||||||
title: 'Resize browser window',
|
title: 'Resize browser window',
|
||||||
description: 'Resize the browser window',
|
description: 'Resize the browser viewport to the specified width and height in pixels. Common sizes: 1920x1080 (Full HD), 1440x900 (laptop), 1280x720 (HD), 390x844 (mobile).',
|
||||||
inputSchema: z.object({
|
inputSchema: z.object({
|
||||||
width: z.number().describe('Width of the browser window'),
|
width: z.coerce.number().describe('Viewport width in pixels'),
|
||||||
height: z.number().describe('Height of the browser window'),
|
height: z.coerce.number().describe('Viewport height in pixels'),
|
||||||
}),
|
}),
|
||||||
type: 'readOnly',
|
type: 'readOnly',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -24,15 +24,15 @@ import type { Response } from '../response.js';
|
|||||||
const configureSchema = z.object({
|
const configureSchema = z.object({
|
||||||
headless: z.boolean().optional().describe('Whether to run the browser in headless mode'),
|
headless: z.boolean().optional().describe('Whether to run the browser in headless mode'),
|
||||||
viewport: z.object({
|
viewport: z.object({
|
||||||
width: z.number(),
|
width: z.coerce.number(),
|
||||||
height: z.number(),
|
height: z.coerce.number(),
|
||||||
}).optional().describe('Browser viewport size'),
|
}).optional().describe('Browser viewport size'),
|
||||||
userAgent: z.string().optional().describe('User agent string for the browser'),
|
userAgent: z.string().optional().describe('User agent string for the browser'),
|
||||||
device: z.string().optional().describe('Device to emulate (e.g., "iPhone 13", "iPad", "Pixel 5"). Use browser_list_devices to see available devices.'),
|
device: z.string().optional().describe('Device to emulate (e.g., "iPhone 13", "iPad", "Pixel 5"). Use browser_list_devices to see available devices.'),
|
||||||
geolocation: z.object({
|
geolocation: z.object({
|
||||||
latitude: z.number().min(-90).max(90),
|
latitude: z.coerce.number().min(-90).max(90),
|
||||||
longitude: z.number().min(-180).max(180),
|
longitude: z.coerce.number().min(-180).max(180),
|
||||||
accuracy: z.number().min(0).optional().describe('Accuracy in meters (default: 100)')
|
accuracy: z.coerce.number().min(0).optional().describe('Accuracy in meters (default: 100)')
|
||||||
}).optional().describe('Set geolocation coordinates'),
|
}).optional().describe('Set geolocation coordinates'),
|
||||||
locale: z.string().optional().describe('Browser locale (e.g., "en-US", "fr-FR", "ja-JP")'),
|
locale: z.string().optional().describe('Browser locale (e.g., "en-US", "fr-FR", "ja-JP")'),
|
||||||
timezone: z.string().optional().describe('Timezone ID (e.g., "America/New_York", "Europe/London", "Asia/Tokyo")'),
|
timezone: z.string().optional().describe('Timezone ID (e.g., "America/New_York", "Europe/London", "Asia/Tokyo")'),
|
||||||
@ -46,7 +46,7 @@ const configureSchema = z.object({
|
|||||||
|
|
||||||
// Browser UI Customization Options
|
// Browser UI Customization Options
|
||||||
chromiumSandbox: z.boolean().optional().describe('Enable/disable Chromium sandbox (affects browser appearance)'),
|
chromiumSandbox: z.boolean().optional().describe('Enable/disable Chromium sandbox (affects browser appearance)'),
|
||||||
slowMo: z.number().min(0).optional().describe('Slow down operations by specified milliseconds (helps with visual tracking)'),
|
slowMo: z.coerce.number().min(0).optional().describe('Slow down operations by specified milliseconds (helps with visual tracking)'),
|
||||||
devtools: z.boolean().optional().describe('Open browser with DevTools panel open (Chromium only)'),
|
devtools: z.boolean().optional().describe('Open browser with DevTools panel open (Chromium only)'),
|
||||||
args: z.array(z.string()).optional().describe('Additional browser launch arguments for UI customization (e.g., ["--force-color-profile=srgb", "--disable-features=VizDisplayCompositor"])'),
|
args: z.array(z.string()).optional().describe('Additional browser launch arguments for UI customization (e.g., ["--force-color-profile=srgb", "--disable-features=VizDisplayCompositor"])'),
|
||||||
});
|
});
|
||||||
@ -93,7 +93,7 @@ const installPopularExtensionSchema = z.object({
|
|||||||
|
|
||||||
const configureSnapshotsSchema = z.object({
|
const configureSnapshotsSchema = z.object({
|
||||||
includeSnapshots: z.boolean().optional().describe('Enable/disable automatic snapshots after interactive operations. When false, use browser_snapshot for explicit snapshots.'),
|
includeSnapshots: z.boolean().optional().describe('Enable/disable automatic snapshots after interactive operations. When false, use browser_snapshot for explicit snapshots.'),
|
||||||
maxSnapshotTokens: z.number().min(0).optional().describe('Maximum tokens allowed in snapshots before truncation. Use 0 to disable truncation.'),
|
maxSnapshotTokens: z.coerce.number().min(0).optional().describe('Maximum tokens allowed in snapshots before truncation. Use 0 to disable truncation.'),
|
||||||
differentialSnapshots: z.boolean().optional().describe('Enable differential snapshots that show only changes since last snapshot instead of full page snapshots.'),
|
differentialSnapshots: z.boolean().optional().describe('Enable differential snapshots that show only changes since last snapshot instead of full page snapshots.'),
|
||||||
differentialMode: z.enum(['semantic', 'simple', 'both']).optional().describe('Type of differential analysis: "semantic" (React-style reconciliation), "simple" (text diff), or "both" (show comparison).'),
|
differentialMode: z.enum(['semantic', 'simple', 'both']).optional().describe('Type of differential analysis: "semantic" (React-style reconciliation), "simple" (text diff), or "both" (show comparison).'),
|
||||||
consoleOutputFile: z.string().optional().describe('File path to write browser console output to. Set to empty string to disable console file output.'),
|
consoleOutputFile: z.string().optional().describe('File path to write browser console output to. Set to empty string to disable console file output.'),
|
||||||
@ -104,9 +104,9 @@ const configureSnapshotsSchema = z.object({
|
|||||||
filterMode: z.enum(['content', 'count', 'files']).optional().describe('Type of filtering output: "content" (filtered data), "count" (match statistics), "files" (matching items only)'),
|
filterMode: z.enum(['content', 'count', 'files']).optional().describe('Type of filtering output: "content" (filtered data), "count" (match statistics), "files" (matching items only)'),
|
||||||
caseSensitive: z.boolean().optional().describe('Case sensitive pattern matching (default: true)'),
|
caseSensitive: z.boolean().optional().describe('Case sensitive pattern matching (default: true)'),
|
||||||
wholeWords: z.boolean().optional().describe('Match whole words only (default: false)'),
|
wholeWords: z.boolean().optional().describe('Match whole words only (default: false)'),
|
||||||
contextLines: z.number().min(0).optional().describe('Number of context lines around matches'),
|
contextLines: z.coerce.number().min(0).optional().describe('Number of context lines around matches'),
|
||||||
invertMatch: z.boolean().optional().describe('Invert match to show non-matches (default: false)'),
|
invertMatch: z.boolean().optional().describe('Invert match to show non-matches (default: false)'),
|
||||||
maxMatches: z.number().min(1).optional().describe('Maximum number of matches to return'),
|
maxMatches: z.coerce.number().min(1).optional().describe('Maximum number of matches to return'),
|
||||||
|
|
||||||
// jq Structural Filtering Parameters
|
// jq Structural Filtering Parameters
|
||||||
jqExpression: z.string().optional().describe(
|
jqExpression: z.string().optional().describe(
|
||||||
|
|||||||
@ -22,13 +22,13 @@ const elementSchema = z.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const coordinateSchema = z.object({
|
const coordinateSchema = z.object({
|
||||||
x: z.number().describe('X coordinate'),
|
x: z.coerce.number().describe('X coordinate'),
|
||||||
y: z.number().describe('Y coordinate'),
|
y: z.coerce.number().describe('Y coordinate'),
|
||||||
});
|
});
|
||||||
|
|
||||||
const advancedCoordinateSchema = coordinateSchema.extend({
|
const advancedCoordinateSchema = coordinateSchema.extend({
|
||||||
precision: z.enum(['pixel', 'subpixel']).optional().default('pixel').describe('Coordinate precision level'),
|
precision: z.enum(['pixel', 'subpixel']).optional().default('pixel').describe('Coordinate precision level'),
|
||||||
delay: z.number().min(0).max(5000).optional().describe('Delay in milliseconds before action'),
|
delay: z.coerce.number().min(0).max(5000).optional().describe('Delay in milliseconds before action'),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mouseMove = defineTabTool({
|
const mouseMove = defineTabTool({
|
||||||
@ -64,8 +64,8 @@ const mouseClick = defineTabTool({
|
|||||||
description: 'Click mouse button at a given position with advanced options',
|
description: 'Click mouse button at a given position with advanced options',
|
||||||
inputSchema: elementSchema.extend(advancedCoordinateSchema.shape).extend({
|
inputSchema: elementSchema.extend(advancedCoordinateSchema.shape).extend({
|
||||||
button: z.enum(['left', 'right', 'middle']).optional().default('left').describe('Mouse button to click'),
|
button: z.enum(['left', 'right', 'middle']).optional().default('left').describe('Mouse button to click'),
|
||||||
clickCount: z.number().min(1).max(3).optional().default(1).describe('Number of clicks (1=single, 2=double, 3=triple)'),
|
clickCount: z.coerce.number().min(1).max(3).optional().default(1).describe('Number of clicks (1=single, 2=double, 3=triple)'),
|
||||||
holdTime: z.number().min(0).max(2000).optional().default(0).describe('How long to hold button down in milliseconds'),
|
holdTime: z.coerce.number().min(0).max(2000).optional().default(0).describe('How long to hold button down in milliseconds'),
|
||||||
}),
|
}),
|
||||||
type: 'destructive',
|
type: 'destructive',
|
||||||
},
|
},
|
||||||
@ -111,16 +111,16 @@ const mouseDrag = defineTabTool({
|
|||||||
title: 'Drag mouse',
|
title: 'Drag mouse',
|
||||||
description: 'Drag mouse button from start to end position with advanced drag patterns',
|
description: 'Drag mouse button from start to end position with advanced drag patterns',
|
||||||
inputSchema: elementSchema.extend({
|
inputSchema: elementSchema.extend({
|
||||||
startX: z.number().describe('Start X coordinate'),
|
startX: z.coerce.number().describe('Start X coordinate'),
|
||||||
startY: z.number().describe('Start Y coordinate'),
|
startY: z.coerce.number().describe('Start Y coordinate'),
|
||||||
endX: z.number().describe('End X coordinate'),
|
endX: z.coerce.number().describe('End X coordinate'),
|
||||||
endY: z.number().describe('End Y coordinate'),
|
endY: z.coerce.number().describe('End Y coordinate'),
|
||||||
button: z.enum(['left', 'right', 'middle']).optional().default('left').describe('Mouse button to drag with'),
|
button: z.enum(['left', 'right', 'middle']).optional().default('left').describe('Mouse button to drag with'),
|
||||||
precision: z.enum(['pixel', 'subpixel']).optional().default('pixel').describe('Coordinate precision level'),
|
precision: z.enum(['pixel', 'subpixel']).optional().default('pixel').describe('Coordinate precision level'),
|
||||||
pattern: z.enum(['direct', 'smooth', 'bezier']).optional().default('direct').describe('Drag movement pattern'),
|
pattern: z.enum(['direct', 'smooth', 'bezier']).optional().default('direct').describe('Drag movement pattern'),
|
||||||
steps: z.number().min(1).max(50).optional().default(10).describe('Number of intermediate steps for smooth/bezier patterns'),
|
steps: z.coerce.number().min(1).max(50).optional().default(10).describe('Number of intermediate steps for smooth/bezier patterns'),
|
||||||
duration: z.number().min(100).max(10000).optional().describe('Total drag duration in milliseconds'),
|
duration: z.coerce.number().min(100).max(10000).optional().describe('Total drag duration in milliseconds'),
|
||||||
delay: z.number().min(0).max(5000).optional().describe('Delay before starting drag'),
|
delay: z.coerce.number().min(0).max(5000).optional().describe('Delay before starting drag'),
|
||||||
}),
|
}),
|
||||||
type: 'destructive',
|
type: 'destructive',
|
||||||
},
|
},
|
||||||
@ -209,8 +209,8 @@ const mouseScroll = defineTabTool({
|
|||||||
title: 'Scroll at coordinates',
|
title: 'Scroll at coordinates',
|
||||||
description: 'Perform scroll action at specific coordinates with precision control',
|
description: 'Perform scroll action at specific coordinates with precision control',
|
||||||
inputSchema: elementSchema.extend(advancedCoordinateSchema.shape).extend({
|
inputSchema: elementSchema.extend(advancedCoordinateSchema.shape).extend({
|
||||||
deltaX: z.number().optional().default(0).describe('Horizontal scroll amount (positive = right, negative = left)'),
|
deltaX: z.coerce.number().optional().default(0).describe('Horizontal scroll amount (positive = right, negative = left)'),
|
||||||
deltaY: z.number().describe('Vertical scroll amount (positive = down, negative = up)'),
|
deltaY: z.coerce.number().describe('Vertical scroll amount (positive = down, negative = up)'),
|
||||||
smooth: z.boolean().optional().default(false).describe('Use smooth scrolling animation'),
|
smooth: z.boolean().optional().default(false).describe('Use smooth scrolling animation'),
|
||||||
}),
|
}),
|
||||||
type: 'destructive',
|
type: 'destructive',
|
||||||
@ -256,9 +256,9 @@ const mouseGesture = defineTabTool({
|
|||||||
description: 'Perform complex mouse gestures with multiple waypoints',
|
description: 'Perform complex mouse gestures with multiple waypoints',
|
||||||
inputSchema: elementSchema.extend({
|
inputSchema: elementSchema.extend({
|
||||||
points: z.array(z.object({
|
points: z.array(z.object({
|
||||||
x: z.number().describe('X coordinate'),
|
x: z.coerce.number().describe('X coordinate'),
|
||||||
y: z.number().describe('Y coordinate'),
|
y: z.coerce.number().describe('Y coordinate'),
|
||||||
delay: z.number().min(0).max(5000).optional().describe('Delay at this point in milliseconds'),
|
delay: z.coerce.number().min(0).max(5000).optional().describe('Delay at this point in milliseconds'),
|
||||||
action: z.enum(['move', 'click', 'down', 'up']).optional().default('move').describe('Action at this point'),
|
action: z.enum(['move', 'click', 'down', 'up']).optional().default('move').describe('Action at this point'),
|
||||||
})).min(2).describe('Array of points defining the gesture path'),
|
})).min(2).describe('Array of points defining the gesture path'),
|
||||||
button: z.enum(['left', 'right', 'middle']).optional().default('left').describe('Mouse button for click actions'),
|
button: z.enum(['left', 'right', 'middle']).optional().default('left').describe('Mouse button for click actions'),
|
||||||
|
|||||||
@ -98,11 +98,11 @@ const currentNetworkConditions = new WeakMap<Context, {
|
|||||||
const setNetworkConditionsSchema = z.object({
|
const setNetworkConditionsSchema = z.object({
|
||||||
preset: z.enum(['offline', 'slow-3g', 'fast-3g', 'regular-4g', 'wifi', 'no-throttle']).optional()
|
preset: z.enum(['offline', 'slow-3g', 'fast-3g', 'regular-4g', 'wifi', 'no-throttle']).optional()
|
||||||
.describe('Network condition preset. Use "offline" to block all requests, "slow-3g" for poor mobile, "fast-3g" for typical mobile, "regular-4g" for LTE, "wifi" for home WiFi, or "no-throttle" to remove throttling.'),
|
.describe('Network condition preset. Use "offline" to block all requests, "slow-3g" for poor mobile, "fast-3g" for typical mobile, "regular-4g" for LTE, "wifi" for home WiFi, or "no-throttle" to remove throttling.'),
|
||||||
downloadThroughput: z.number().min(-1).optional()
|
downloadThroughput: z.coerce.number().min(-1).optional()
|
||||||
.describe('Custom download speed in bytes/second. Use -1 for no throttling. Overrides preset if specified.'),
|
.describe('Custom download speed in bytes/second. Use -1 for no throttling. Overrides preset if specified.'),
|
||||||
uploadThroughput: z.number().min(-1).optional()
|
uploadThroughput: z.coerce.number().min(-1).optional()
|
||||||
.describe('Custom upload speed in bytes/second. Use -1 for no throttling. Overrides preset if specified.'),
|
.describe('Custom upload speed in bytes/second. Use -1 for no throttling. Overrides preset if specified.'),
|
||||||
latency: z.number().min(0).optional()
|
latency: z.coerce.number().min(0).optional()
|
||||||
.describe('Custom latency in milliseconds to add to each request. Overrides preset if specified.'),
|
.describe('Custom latency in milliseconds to add to each request. Overrides preset if specified.'),
|
||||||
offline: z.boolean().optional()
|
offline: z.boolean().optional()
|
||||||
.describe('Set to true to simulate offline mode. Overrides preset if specified.')
|
.describe('Set to true to simulate offline mode. Overrides preset if specified.')
|
||||||
|
|||||||
@ -166,7 +166,7 @@ const waitForNotification = defineTabTool({
|
|||||||
title: z.string().optional().describe('Wait for notification with this exact title'),
|
title: z.string().optional().describe('Wait for notification with this exact title'),
|
||||||
titleContains: z.string().optional().describe('Wait for notification with title containing this text'),
|
titleContains: z.string().optional().describe('Wait for notification with title containing this text'),
|
||||||
origin: z.string().optional().describe('Wait for notification from this origin'),
|
origin: z.string().optional().describe('Wait for notification from this origin'),
|
||||||
timeout: z.number().optional().describe('Maximum time to wait in milliseconds (default: 30000)'),
|
timeout: z.coerce.number().optional().describe('Maximum time to wait in milliseconds (default: 30000)'),
|
||||||
}),
|
}),
|
||||||
type: 'readOnly',
|
type: 'readOnly',
|
||||||
},
|
},
|
||||||
@ -354,9 +354,9 @@ const setGeolocation = defineTool({
|
|||||||
title: 'Set geolocation at runtime',
|
title: 'Set geolocation at runtime',
|
||||||
description: 'Set the browser\'s geolocation at runtime without restarting. Automatically grants geolocation permission.',
|
description: 'Set the browser\'s geolocation at runtime without restarting. Automatically grants geolocation permission.',
|
||||||
inputSchema: z.object({
|
inputSchema: z.object({
|
||||||
latitude: z.number().min(-90).max(90).describe('Latitude coordinate (-90 to 90)'),
|
latitude: z.coerce.number().min(-90).max(90).describe('Latitude coordinate (-90 to 90)'),
|
||||||
longitude: z.number().min(-180).max(180).describe('Longitude coordinate (-180 to 180)'),
|
longitude: z.coerce.number().min(-180).max(180).describe('Longitude coordinate (-180 to 180)'),
|
||||||
accuracy: z.number().optional().describe('Accuracy in meters (default: 100)'),
|
accuracy: z.coerce.number().optional().describe('Accuracy in meters (default: 100)'),
|
||||||
}),
|
}),
|
||||||
type: 'destructive',
|
type: 'destructive',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -307,7 +307,7 @@ const pwaDownload = defineTabTool({
|
|||||||
includeIcons: z.boolean().optional().default(true).describe('Download all icon sizes from manifest (default: true)'),
|
includeIcons: z.boolean().optional().default(true).describe('Download all icon sizes from manifest (default: true)'),
|
||||||
includeCache: z.boolean().optional().default(true).describe('Download cached resources from CacheStorage (default: true)'),
|
includeCache: z.boolean().optional().default(true).describe('Download cached resources from CacheStorage (default: true)'),
|
||||||
createZip: z.boolean().optional().default(false).describe('Create zip archive of downloaded content (default: false)'),
|
createZip: z.boolean().optional().default(false).describe('Create zip archive of downloaded content (default: false)'),
|
||||||
maxCacheSize: z.number().optional().default(100).describe('Maximum total cache size to download in MB (default: 100)'),
|
maxCacheSize: z.coerce.number().optional().default(100).describe('Maximum total cache size to download in MB (default: 100)'),
|
||||||
}),
|
}),
|
||||||
type: 'destructive',
|
type: 'destructive',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -31,7 +31,7 @@ const startMonitoringSchema = z.object({
|
|||||||
|
|
||||||
captureBody: z.boolean().optional().default(true).describe('Whether to capture request and response bodies (default: true)'),
|
captureBody: z.boolean().optional().default(true).describe('Whether to capture request and response bodies (default: true)'),
|
||||||
|
|
||||||
maxBodySize: z.number().optional().default(10485760).describe('Maximum body size to capture in bytes (default: 10MB). Larger bodies will be truncated'),
|
maxBodySize: z.coerce.number().optional().default(10485760).describe('Maximum body size to capture in bytes (default: 10MB). Larger bodies will be truncated'),
|
||||||
|
|
||||||
autoSave: z.boolean().optional().default(false).describe('Automatically save captured requests after each response (default: false for performance)'),
|
autoSave: z.boolean().optional().default(false).describe('Automatically save captured requests after each response (default: false for performance)'),
|
||||||
|
|
||||||
@ -45,11 +45,11 @@ const getRequestsSchema = paginationParamsSchema.extend({
|
|||||||
|
|
||||||
method: z.string().optional().describe('Filter requests by HTTP method (GET, POST, etc.)'),
|
method: z.string().optional().describe('Filter requests by HTTP method (GET, POST, etc.)'),
|
||||||
|
|
||||||
status: z.number().optional().describe('Filter requests by HTTP status code'),
|
status: z.coerce.number().optional().describe('Filter requests by HTTP status code'),
|
||||||
|
|
||||||
format: z.enum(['summary', 'detailed', 'stats']).optional().default('summary').describe('Response format: summary (basic info), detailed (full data), stats (statistics only)'),
|
format: z.enum(['summary', 'detailed', 'stats']).optional().default('summary').describe('Response format: summary (basic info), detailed (full data), stats (statistics only)'),
|
||||||
|
|
||||||
slowThreshold: z.number().optional().default(1000).describe('Threshold in milliseconds for considering requests "slow" (default: 1000ms)')
|
slowThreshold: z.coerce.number().optional().default(1000).describe('Threshold in milliseconds for considering requests "slow" (default: 1000ms)')
|
||||||
});
|
});
|
||||||
|
|
||||||
const exportRequestsSchema = z.object({
|
const exportRequestsSchema = z.object({
|
||||||
|
|||||||
@ -42,9 +42,9 @@ const setDeviceOrientation = defineTabTool({
|
|||||||
|
|
||||||
**Note:** Requires Chromium-based browser. This overrides the DeviceOrientationEvent.`,
|
**Note:** Requires Chromium-based browser. This overrides the DeviceOrientationEvent.`,
|
||||||
inputSchema: z.object({
|
inputSchema: z.object({
|
||||||
alpha: z.number().min(0).max(360).describe('Compass heading (0-360 degrees). 0=North, 90=East, 180=South, 270=West'),
|
alpha: z.coerce.number().min(0).max(360).describe('Compass heading (0-360 degrees). 0=North, 90=East, 180=South, 270=West'),
|
||||||
beta: z.number().min(-180).max(180).describe('Front-to-back tilt (-180 to 180 degrees). Positive=tilted backward'),
|
beta: z.coerce.number().min(-180).max(180).describe('Front-to-back tilt (-180 to 180 degrees). Positive=tilted backward'),
|
||||||
gamma: z.number().min(-90).max(90).describe('Left-to-right tilt (-90 to 90 degrees). Positive=tilted right'),
|
gamma: z.coerce.number().min(-90).max(90).describe('Left-to-right tilt (-90 to 90 degrees). Positive=tilted right'),
|
||||||
}),
|
}),
|
||||||
type: 'destructive',
|
type: 'destructive',
|
||||||
},
|
},
|
||||||
@ -144,21 +144,21 @@ const setDeviceMotion = defineTabTool({
|
|||||||
**Note:** Requires Chromium-based browser.`,
|
**Note:** Requires Chromium-based browser.`,
|
||||||
inputSchema: z.object({
|
inputSchema: z.object({
|
||||||
acceleration: z.object({
|
acceleration: z.object({
|
||||||
x: z.number().describe('Acceleration on x-axis (m/s²)'),
|
x: z.coerce.number().describe('Acceleration on x-axis (m/s²)'),
|
||||||
y: z.number().describe('Acceleration on y-axis (m/s²)'),
|
y: z.coerce.number().describe('Acceleration on y-axis (m/s²)'),
|
||||||
z: z.number().describe('Acceleration on z-axis (m/s²)'),
|
z: z.coerce.number().describe('Acceleration on z-axis (m/s²)'),
|
||||||
}).optional().describe('Linear acceleration excluding gravity'),
|
}).optional().describe('Linear acceleration excluding gravity'),
|
||||||
accelerationIncludingGravity: z.object({
|
accelerationIncludingGravity: z.object({
|
||||||
x: z.number().describe('Acceleration on x-axis including gravity (m/s²)'),
|
x: z.coerce.number().describe('Acceleration on x-axis including gravity (m/s²)'),
|
||||||
y: z.number().describe('Acceleration on y-axis including gravity (m/s²)'),
|
y: z.coerce.number().describe('Acceleration on y-axis including gravity (m/s²)'),
|
||||||
z: z.number().describe('Acceleration on z-axis including gravity (m/s²)'),
|
z: z.coerce.number().describe('Acceleration on z-axis including gravity (m/s²)'),
|
||||||
}).optional().describe('Total acceleration including gravity'),
|
}).optional().describe('Total acceleration including gravity'),
|
||||||
rotationRate: z.object({
|
rotationRate: z.object({
|
||||||
alpha: z.number().describe('Rotation rate around z-axis (deg/s)'),
|
alpha: z.coerce.number().describe('Rotation rate around z-axis (deg/s)'),
|
||||||
beta: z.number().describe('Rotation rate around x-axis (deg/s)'),
|
beta: z.coerce.number().describe('Rotation rate around x-axis (deg/s)'),
|
||||||
gamma: z.number().describe('Rotation rate around y-axis (deg/s)'),
|
gamma: z.coerce.number().describe('Rotation rate around y-axis (deg/s)'),
|
||||||
}).optional().describe('Angular velocity around each axis'),
|
}).optional().describe('Angular velocity around each axis'),
|
||||||
interval: z.number().optional().describe('Interval between samples in milliseconds (default: 16)'),
|
interval: z.coerce.number().optional().describe('Interval between samples in milliseconds (default: 16)'),
|
||||||
}),
|
}),
|
||||||
type: 'destructive',
|
type: 'destructive',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -83,7 +83,7 @@ const setCookie = defineTool({
|
|||||||
url: z.string().optional().describe('URL to associate with the cookie. Either url or domain must be specified.'),
|
url: z.string().optional().describe('URL to associate with the cookie. Either url or domain must be specified.'),
|
||||||
domain: z.string().optional().describe('Cookie domain. Either url or domain must be specified.'),
|
domain: z.string().optional().describe('Cookie domain. Either url or domain must be specified.'),
|
||||||
path: z.string().optional().describe('Cookie path (default: "/")'),
|
path: z.string().optional().describe('Cookie path (default: "/")'),
|
||||||
expires: z.number().optional().describe('Unix timestamp in seconds for cookie expiration. -1 for session cookie.'),
|
expires: z.coerce.number().optional().describe('Unix timestamp in seconds for cookie expiration. -1 for session cookie.'),
|
||||||
httpOnly: z.boolean().optional().describe('Whether the cookie is HTTP only (default: false)'),
|
httpOnly: z.boolean().optional().describe('Whether the cookie is HTTP only (default: false)'),
|
||||||
secure: z.boolean().optional().describe('Whether the cookie is secure (default: false)'),
|
secure: z.boolean().optional().describe('Whether the cookie is secure (default: false)'),
|
||||||
sameSite: z.enum(['Strict', 'Lax', 'None']).optional().describe('SameSite attribute (default: "Lax")'),
|
sameSite: z.enum(['Strict', 'Lax', 'None']).optional().describe('SameSite attribute (default: "Lax")'),
|
||||||
|
|||||||
@ -42,7 +42,7 @@ const selectTab = defineTool({
|
|||||||
title: 'Select a tab',
|
title: 'Select a tab',
|
||||||
description: 'Select a tab by index. Returns page snapshot after selecting tab (configurable via browser_configure_snapshots).',
|
description: 'Select a tab by index. Returns page snapshot after selecting tab (configurable via browser_configure_snapshots).',
|
||||||
inputSchema: z.object({
|
inputSchema: z.object({
|
||||||
index: z.number().describe('The index of the tab to select'),
|
index: z.coerce.number().describe('The index of the tab to select'),
|
||||||
}),
|
}),
|
||||||
type: 'readOnly',
|
type: 'readOnly',
|
||||||
},
|
},
|
||||||
@ -82,7 +82,7 @@ const closeTab = defineTool({
|
|||||||
title: 'Close a tab',
|
title: 'Close a tab',
|
||||||
description: 'Close a tab. Returns page snapshot after closing tab (configurable via browser_configure_snapshots).',
|
description: 'Close a tab. Returns page snapshot after closing tab (configurable via browser_configure_snapshots).',
|
||||||
inputSchema: z.object({
|
inputSchema: z.object({
|
||||||
index: z.number().optional().describe('The index of the tab to close. Closes current tab if not provided.'),
|
index: z.coerce.number().optional().describe('The index of the tab to close. Closes current tab if not provided.'),
|
||||||
}),
|
}),
|
||||||
type: 'destructive',
|
type: 'destructive',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -28,8 +28,8 @@ const startRecording = defineTool({
|
|||||||
description: 'Start recording browser session video with intelligent viewport matching. For best results, the browser viewport size should match the video recording size to avoid gray space around content. Use browser_configure to set viewport size before recording.',
|
description: 'Start recording browser session video with intelligent viewport matching. For best results, the browser viewport size should match the video recording size to avoid gray space around content. Use browser_configure to set viewport size before recording.',
|
||||||
inputSchema: z.object({
|
inputSchema: z.object({
|
||||||
size: z.object({
|
size: z.object({
|
||||||
width: z.number().optional().describe('Video width in pixels (default: 1280). For full-frame content, set browser viewport to match this width.'),
|
width: z.coerce.number().optional().describe('Video width in pixels (default: 1280). For full-frame content, set browser viewport to match this width.'),
|
||||||
height: z.number().optional().describe('Video height in pixels (default: 720). For full-frame content, set browser viewport to match this height.'),
|
height: z.coerce.number().optional().describe('Video height in pixels (default: 720). For full-frame content, set browser viewport to match this height.'),
|
||||||
}).optional().describe('Video recording dimensions. IMPORTANT: Browser viewport should match these dimensions to avoid gray borders around content.'),
|
}).optional().describe('Video recording dimensions. IMPORTANT: Browser viewport should match these dimensions to avoid gray borders around content.'),
|
||||||
filename: z.string().optional().describe('Base filename for video files (default: session-{timestamp}.webm)'),
|
filename: z.string().optional().describe('Base filename for video files (default: session-{timestamp}.webm)'),
|
||||||
autoSetViewport: z.boolean().optional().default(true).describe('Automatically set browser viewport to match video recording size (recommended for full-frame content)'),
|
autoSetViewport: z.boolean().optional().default(true).describe('Automatically set browser viewport to match video recording size (recommended for full-frame content)'),
|
||||||
|
|||||||
@ -25,7 +25,7 @@ const wait = defineTool({
|
|||||||
title: 'Wait for',
|
title: 'Wait for',
|
||||||
description: 'Wait for text to appear or disappear or a specified time to pass. In smart recording mode, video recording is automatically paused during waits unless recordDuringWait is true.',
|
description: 'Wait for text to appear or disappear or a specified time to pass. In smart recording mode, video recording is automatically paused during waits unless recordDuringWait is true.',
|
||||||
inputSchema: z.object({
|
inputSchema: z.object({
|
||||||
time: z.number().optional().describe('The time to wait in seconds'),
|
time: z.coerce.number().optional().describe('The time to wait in seconds'),
|
||||||
text: z.string().optional().describe('The text to wait for'),
|
text: z.string().optional().describe('The text to wait for'),
|
||||||
textGone: z.string().optional().describe('The text to wait for to disappear'),
|
textGone: z.string().optional().describe('The text to wait for to disappear'),
|
||||||
recordDuringWait: z.boolean().optional().default(false).describe('Whether to keep video recording active during the wait (default: false in smart mode, true in continuous mode)'),
|
recordDuringWait: z.boolean().optional().default(false).describe('Whether to keep video recording active during the wait (default: false in smart mode, true in continuous mode)'),
|
||||||
|
|||||||
@ -28,7 +28,7 @@ const startWebRTCMonitoring = defineTabTool({
|
|||||||
title: 'Start WebRTC monitoring',
|
title: 'Start WebRTC monitoring',
|
||||||
description: 'Enable real-time WebRTC connection monitoring. Intercepts RTCPeerConnection API to track connection states and collect statistics. Required before using other WebRTC tools.',
|
description: 'Enable real-time WebRTC connection monitoring. Intercepts RTCPeerConnection API to track connection states and collect statistics. Required before using other WebRTC tools.',
|
||||||
inputSchema: z.object({
|
inputSchema: z.object({
|
||||||
statsPollingInterval: z.number().optional().describe('Stats collection interval in milliseconds (default: 1000ms). Lower values give more frequent updates but use more CPU.'),
|
statsPollingInterval: z.coerce.number().optional().describe('Stats collection interval in milliseconds (default: 1000ms). Lower values give more frequent updates but use more CPU.'),
|
||||||
}),
|
}),
|
||||||
type: 'destructive',
|
type: 'destructive',
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user