feat: add runtime proxy configuration support to browser_configure
Some checks failed
CI / lint (push) Has been cancelled
CI / test (macos-latest) (push) Has been cancelled
CI / test (ubuntu-latest) (push) Has been cancelled
CI / test (windows-latest) (push) Has been cancelled
CI / test_docker (push) Has been cancelled

Enables on-the-fly proxy switching without restarting MCP server, allowing
users to dynamically set or clear proxy settings during browser sessions.

Changes:
- Add proxyServer and proxyBypass parameters to updateBrowserConfig method
- Implement proxy set/clear logic with proper validation for empty strings
- Expose proxy configuration through browser_configure tool interface
- Update auto-generated documentation with proxy parameter descriptions

Tested with SOCKS5 proxy, verified IP changes when proxy is enabled/disabled.
This commit is contained in:
Ryan Malloy 2025-11-14 21:34:40 -07:00
parent 1c55b771a8
commit 3e92fc031f
3 changed files with 72 additions and 0 deletions

View File

@ -592,6 +592,8 @@ mcpInspector.start('click element', callback) for user collaboration.
- `colorScheme` (string, optional): Preferred color scheme - `colorScheme` (string, optional): Preferred color scheme
- `permissions` (array, optional): Permissions to grant (e.g., ["geolocation", "notifications", "camera", "microphone"]) - `permissions` (array, optional): Permissions to grant (e.g., ["geolocation", "notifications", "camera", "microphone"])
- `offline` (boolean, optional): Whether to emulate offline network conditions (equivalent to DevTools offline mode) - `offline` (boolean, optional): Whether to emulate offline network conditions (equivalent to DevTools offline mode)
- `proxyServer` (string, optional): Proxy server to use for network requests. Examples: "http://myproxy:3128", "socks5://127.0.0.1:1080". Set to null (empty) to clear proxy.
- `proxyBypass` (string, optional): Comma-separated domains to bypass proxy (e.g., ".com,chromium.org,.domain.com")
- `chromiumSandbox` (boolean, optional): Enable/disable Chromium sandbox (affects browser appearance) - `chromiumSandbox` (boolean, optional): Enable/disable Chromium sandbox (affects browser appearance)
- `slowMo` (number, optional): Slow down operations by specified milliseconds (helps with visual tracking) - `slowMo` (number, optional): Slow down operations by specified milliseconds (helps with visual tracking)
- `devtools` (boolean, optional): Open browser with DevTools panel open (Chromium only) - `devtools` (boolean, optional): Open browser with DevTools panel open (Chromium only)
@ -628,6 +630,38 @@ mcpInspector.start('click element', callback) for user collaboration.
- `contextLines` (number, optional): Number of context lines around matches - `contextLines` (number, optional): Number of context lines around matches
- `invertMatch` (boolean, optional): Invert match to show non-matches (default: false) - `invertMatch` (boolean, optional): Invert match to show non-matches (default: false)
- `maxMatches` (number, optional): Maximum number of matches to return - `maxMatches` (number, optional): Maximum number of matches to return
- `jqExpression` (string, optional): jq expression for structural JSON querying and transformation.
Common patterns:
• Buttons: .elements[] | select(.role == "button")
• Errors: .console[] | select(.level == "error")
• Forms: .elements[] | select(.role == "textbox" or .role == "combobox")
• Links: .elements[] | select(.role == "link")
• Transform: [.elements[] | {role, text, id}]
Tip: Use filterPreset instead for common cases - no jq knowledge required!
- `filterPreset` (string, optional): Filter preset for common scenarios (no jq knowledge needed).
• buttons_only: Show only buttons
• links_only: Show only links
• forms_only: Show form inputs (textbox, combobox, checkbox, etc.)
• errors_only: Show console errors
• warnings_only: Show console warnings
• interactive_only: Show all clickable elements (buttons + links)
• validation_errors: Show validation alerts
• navigation_items: Show navigation menus
• headings_only: Show headings (h1-h6)
• images_only: Show images
• changed_text_only: Show elements with text changes
Note: filterPreset and jqExpression are mutually exclusive. Preset takes precedence.
- `jqRawOutput` (boolean, optional): Output raw strings instead of JSON (jq -r flag). Useful for extracting plain text values.
- `jqCompact` (boolean, optional): Compact JSON output without whitespace (jq -c flag). Reduces output size.
- `jqSortKeys` (boolean, optional): Sort object keys in output (jq -S flag). Ensures consistent ordering.
- `jqSlurp` (boolean, optional): Read entire input into array and process once (jq -s flag). Enables cross-element operations.
- `jqExitStatus` (boolean, optional): Set exit code based on output (jq -e flag). Useful for validation.
- `jqNullInput` (boolean, optional): Use null as input instead of reading data (jq -n flag). For generating new structures.
- `filterOrder` (string, optional): Order of filter application. "jq_first" (default): structural filter then pattern match - recommended for maximum precision. "ripgrep_first": pattern match then structural filter - useful when you want to narrow down first. "jq_only": pure jq transformation without ripgrep. "ripgrep_only": pure pattern matching without jq (existing behavior).
- Read-only: **false** - Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js --> <!-- NOTE: This has been generated via update-readme.js -->

View File

@ -501,6 +501,10 @@ export class Context {
permissions?: string[]; permissions?: string[];
offline?: boolean; offline?: boolean;
// Proxy Configuration
proxyServer?: string;
proxyBypass?: string;
// Browser UI Customization // Browser UI Customization
chromiumSandbox?: boolean; chromiumSandbox?: boolean;
slowMo?: number; slowMo?: number;
@ -564,6 +568,21 @@ export class Context {
if (changes.offline !== undefined) if (changes.offline !== undefined)
(currentConfig.browser as any).offline = changes.offline; (currentConfig.browser as any).offline = changes.offline;
// Apply proxy configuration
if (changes.proxyServer !== undefined) {
if (changes.proxyServer === '' || changes.proxyServer === null) {
// Clear proxy when empty string or null
delete currentConfig.browser.launchOptions.proxy;
} else {
// Set proxy server
currentConfig.browser.launchOptions.proxy = {
server: changes.proxyServer
};
if (changes.proxyBypass)
currentConfig.browser.launchOptions.proxy.bypass = changes.proxyBypass;
}
}
// Apply browser launch options for UI customization // Apply browser launch options for UI customization
if (changes.chromiumSandbox !== undefined) if (changes.chromiumSandbox !== undefined)
currentConfig.browser.launchOptions.chromiumSandbox = changes.chromiumSandbox; currentConfig.browser.launchOptions.chromiumSandbox = changes.chromiumSandbox;

View File

@ -40,6 +40,10 @@ const configureSchema = z.object({
permissions: z.array(z.string()).optional().describe('Permissions to grant (e.g., ["geolocation", "notifications", "camera", "microphone"])'), permissions: z.array(z.string()).optional().describe('Permissions to grant (e.g., ["geolocation", "notifications", "camera", "microphone"])'),
offline: z.boolean().optional().describe('Whether to emulate offline network conditions (equivalent to DevTools offline mode)'), offline: z.boolean().optional().describe('Whether to emulate offline network conditions (equivalent to DevTools offline mode)'),
// Proxy Configuration
proxyServer: z.string().optional().describe('Proxy server to use for network requests. Examples: "http://myproxy:3128", "socks5://127.0.0.1:1080". Set to null (empty) to clear proxy.'),
proxyBypass: z.string().optional().describe('Comma-separated domains to bypass proxy (e.g., ".com,chromium.org,.domain.com")'),
// 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.number().min(0).optional().describe('Slow down operations by specified milliseconds (helps with visual tracking)'),
@ -316,6 +320,19 @@ export default [
} }
// Track proxy changes
if (params.proxyServer !== undefined) {
const currentProxy = currentConfig.browser.launchOptions.proxy?.server;
if (params.proxyServer !== currentProxy) {
const fromProxy = currentProxy || 'none';
const toProxy = params.proxyServer || 'none';
changes.push(`proxy: ${fromProxy}${toProxy}`);
if (params.proxyBypass)
changes.push(`proxy bypass: ${params.proxyBypass}`);
}
}
if (changes.length === 0) { if (changes.length === 0) {
response.addResult('No configuration changes detected. Current settings remain the same.'); response.addResult('No configuration changes detected. Current settings remain the same.');
@ -334,6 +351,8 @@ export default [
colorScheme: params.colorScheme, colorScheme: params.colorScheme,
permissions: params.permissions, permissions: params.permissions,
offline: params.offline, offline: params.offline,
proxyServer: params.proxyServer,
proxyBypass: params.proxyBypass,
}); });
response.addResult(`Browser configuration updated successfully:\n${changes.map(c => `${c}`).join('\n')}\n\nThe browser has been restarted with the new settings.`); response.addResult(`Browser configuration updated successfully:\n${changes.map(c => `${c}`).join('\n')}\n\nThe browser has been restarted with the new settings.`);