interceptor_chrome_devtools_navigate
Navigate Chrome browser sessions while automatically verifying that matching network traffic is captured by the proxy server for analysis and modification.
Instructions
Navigate the bound Chrome session via chrome-devtools-mcp and verify matching host traffic was captured by proxy-mcp.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| devtools_session_id | Yes | Session ID from interceptor_chrome_devtools_attach | |
| url | Yes | Destination URL | |
| wait_for_proxy_capture | No | Wait for matching proxy traffic after navigate (default: true) | |
| timeout_ms | No | Max wait for navigate response and optional proxy verification | |
| poll_interval_ms | No | Polling interval while waiting for proxy capture |
Implementation Reference
- src/tools/devtools.ts:542-628 (handler)Handler implementation for interceptor_chrome_devtools_navigate.
"interceptor_chrome_devtools_navigate", "Navigate the bound Chrome session via chrome-devtools-mcp and verify matching host traffic was captured by proxy-mcp.", { devtools_session_id: z.string().describe("Session ID from interceptor_chrome_devtools_attach"), url: z.string().describe("Destination URL"), wait_for_proxy_capture: z.boolean().optional().default(true) .describe("Wait for matching proxy traffic after navigate (default: true)"), timeout_ms: z.number().optional().default(5000).describe("Max wait for navigate response and optional proxy verification"), poll_interval_ms: z.number().optional().default(200).describe("Polling interval while waiting for proxy capture"), }, async ({ devtools_session_id, url, wait_for_proxy_capture, timeout_ms, poll_interval_ms }) => { try { const { targetId } = await ensureSessionTargetIsAlive(devtools_session_id); const beforeCount = proxyManager.getTraffic().length; const devtoolsResult = await devToolsBridge.callAction( devtools_session_id, "navigate", { type: "url", url }, ); const destinationHost = normalizeHostname(url); let matchedExchangeIds: string[] = []; let sawAnyNewTraffic = false; let waitedMs = 0; if (wait_for_proxy_capture) { const startedAt = Date.now(); while (Date.now() - startedAt <= timeout_ms) { const delta = proxyManager.getTraffic().slice(beforeCount); if (delta.length > 0) sawAnyNewTraffic = true; if (destinationHost) { const matches = delta .filter((x) => { const host = x.request.hostname.toLowerCase(); return host === destinationHost || host.endsWith(`.${destinationHost}`); }) .map((x) => x.id); if (matches.length > 0) { matchedExchangeIds = matches; break; } } else if (delta.length > 0) { matchedExchangeIds = delta.map((x) => x.id); break; } await sleep(Math.max(50, poll_interval_ms)); waitedMs = Date.now() - startedAt; } } const delta = proxyManager.getTraffic().slice(beforeCount); const response: Record<string, unknown> = { status: "success", devtools_session_id, target_id: targetId, url, devtoolsResult: sanitizeDevToolsPayload(devtoolsResult), traffic: { beforeCount, afterCount: beforeCount + delta.length, deltaCount: delta.length, destinationHost, matchedHostExchangeCount: matchedExchangeIds.length, matchedHostExchangeIds: matchedExchangeIds, waitedMs, }, }; if (wait_for_proxy_capture && destinationHost && matchedExchangeIds.length === 0) { response.warning = sawAnyNewTraffic ? `Navigation succeeded but no '${destinationHost}' traffic was captured within ${timeout_ms}ms.` : `No new proxy traffic observed within ${timeout_ms}ms after navigation.`; } return { content: [{ type: "text", text: truncateResult(response), }], }; } catch (e) { return { content: [{ type: "text", text: JSON.stringify({ status: "error", error: errorToString(e) }) }] }; } }, );