proxy_start_transparent
Start a transparent proxy listener to intercept iptables-redirected HTTP/HTTPS traffic. Requires the explicit proxy to be running first.
Instructions
Start the transparent proxy listener. Receives iptables-redirected traffic (no CONNECT tunnels). Shares the same CA cert, rules, and traffic buffer as the explicit proxy. The explicit proxy must be started first.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Port for the transparent listener (default: 8443) |
Implementation Reference
- src/tools/transparent.ts:10-38 (registration)Registration of the 'proxy_start_transparent' tool via server.tool(), with a handler that calls proxyManager.startTransparent(port) and returns the result.
export function registerTransparentTools(server: McpServer): void { server.tool( "proxy_start_transparent", "Start the transparent proxy listener. Receives iptables-redirected traffic (no CONNECT tunnels). Shares the same CA cert, rules, and traffic buffer as the explicit proxy. The explicit proxy must be started first.", { port: z.number().optional().default(8443).describe("Port for the transparent listener (default: 8443)"), }, async ({ port }) => { try { const result = await proxyManager.startTransparent(port); const localIP = getLocalIP(); return { content: [{ type: "text", text: JSON.stringify({ status: "success", port: result.port, instructions: [ `Transparent listener active on ${localIP}:${result.port}`, "Traffic will be captured in the same buffer as the explicit proxy (tagged as 'transparent')", ], }), }], }; } catch (e) { return { content: [{ type: "text", text: JSON.stringify({ status: "error", error: String(e) }) }] }; } }, ); - src/tools/transparent.ts:15-15 (schema)Input schema for the proxy_start_transparent tool: optional port number with default 8443.
port: z.number().optional().default(8443).describe("Port for the transparent listener (default: 8443)"), - src/state.ts:443-458 (handler)Core handler logic: ProxyManager.startTransparent() validates state, delegates to buildAndStartTransparent(), and returns the port.
async startTransparent(port: number = 8443): Promise<{ port: number }> { if (this._transparentRunning) { throw new Error("Transparent proxy is already running. Stop it first."); } if (!this.cert) { throw new Error("No certificate. Start the explicit proxy first to generate the CA."); } this.transparentPort = port; await this.buildAndStartTransparent(); this._transparentRunning = true; this.transparentPort = this.transparentServer!.port; this.transparentTrafficCount = 0; return { port: this.transparentServer!.port }; } - src/state.ts:1283-1318 (helper)Helper that builds and starts a mockttp transparent proxy server with the same CA cert, rules, and event listeners as the explicit proxy.
private async buildAndStartTransparent(): Promise<void> { if (!this.cert) throw new Error("No certificate"); const mockttp = await getMockttp(); const server = mockttp.getLocal({ https: { key: this.cert.key, cert: this.cert.cert }, }); // Wire event listeners to the SAME ring buffer, tagged as "transparent" this.setupEventListeners(server, "transparent"); // Apply the same rules as the explicit proxy const proxyConfig = this.resolveProxyConfig(); const enabledRules = [...this.rules.values()] .filter((r) => r.enabled) .sort((a, b) => a.priority - b.priority); for (const rule of enabledRules) { const builder = this.buildMatcher(server, rule.matcher).always(); await this.buildHandler(builder, rule, proxyConfig); } // Default passthrough — same logic as explicit proxy but no JA3 spoofing // (transparent traffic is from mobile devices, not browsers needing spoof) await server.forAnyRequest().always() .thenPassThrough({ ignoreHostHttpsErrors: true, proxyConfig, }); await server.start(this.transparentPort || 0); this.transparentServer = server; // TLS capture on the transparent server too this.setupTlsCapture(server); } - src/index.ts:32-75 (registration)Import and registration call: registerTransparentTools is imported from './tools/transparent.js' and invoked during server setup.
import { registerTransparentTools } from "./tools/transparent.js"; import { registerMobileTools } from "./tools/mobile.js"; import { registerCamoufoxTools } from "./tools/camoufox.js"; import { registerResources } from "./resources.js"; import { initInterceptors } from "./interceptors/init.js"; /* ------------------------------------------------------------------ */ /* CLI helpers */ /* ------------------------------------------------------------------ */ function arg(name: string, fallback: string): string { const prefix = `--${name}=`; const found = process.argv.find((a) => a.startsWith(prefix)); if (found) return found.slice(prefix.length); const idx = process.argv.indexOf(`--${name}`); if (idx !== -1 && idx + 1 < process.argv.length) return process.argv[idx + 1]; return process.env[name.toUpperCase().replace(/-/g, "_")] ?? fallback; } /* ------------------------------------------------------------------ */ /* Server factory */ /* ------------------------------------------------------------------ */ function createMcpServer(): McpServer { const server = new McpServer({ name: "proxy", version: "3.3.2" }); initInterceptors(); registerLifecycleTools(server); registerUpstreamTools(server); registerRuleTools(server); registerTrafficTools(server); registerModificationTools(server); registerTlsTools(server); registerInterceptorTools(server); registerDevToolsTools(server); registerSessionTools(server); registerHumanizerTools(server); registerTransparentTools(server); registerMobileTools(server); registerCamoufoxTools(server); registerResources(server);