camoufox-reverse-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| os | No | OS fingerprint (windows/macos/linux) | windows |
| geoip | No | Infer geolocation from proxy IP | false |
| proxy | No | Proxy server URL | |
| headless | No | Headless mode | false |
| humanize | No | Humanized mouse movement | false |
| block-images | No | Block image loading | false |
| block-webrtc | No | Block WebRTC | false |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| launch_browserA | Launch the Camoufox anti-detection browser, or attach to a running one. Args:
headless: Run in headless mode (default False).
os_type: OS fingerprint - "auto", "windows", "macos", or "linux".
locale: Browser locale (e.g. "zh-CN"). "auto" detects system locale.
proxy: Proxy server URL (e.g. "http://127.0.0.1:7890").
humanize: Enable humanized mouse movement.
geoip: Auto-infer geolocation from proxy IP.
block_images: Block image loading.
block_webrtc: Block WebRTC to prevent IP leaks.
enable_trace: Enable engine-level property access tracing.
Requires camoufox-reverse custom browser build.
When enabled, use trace_property_access() to capture DOM access.
trace_objects: Optional exact native object-name allowlist (for example
["navigator", "screen", "webgl"]). Empty traces all native sites
declared by the selected reverse build.
trace_max_events: Per Firefox process/session event cap (1..200000).
browser_version: Select one already-installed Camoufox 0.5+ browser
without changing its persistent active version. Use a repo-qualified
selector such as "official/beta.30" or
"whitenightshadow/152.0.4-beta.30-reverse.5". Omit it to preserve the
active/default behavior, including Camoufox 0.4.x installations.
The selected browser must match the active browser's exact
version/build because Camoufox reads shared resources from active.
ws_endpoint: Attach to an already-running Camoufox server instead of
launching a new browser. Start the server with
Returns: dict with status, config, and page list. |
| close_browserA | Close the browser after serializing any native trace transition. |
| navigateA | Navigate to a URL, with optional hook pre-injection and redirect tracing. Args: url: Target URL. wait_until: "load", "domcontentloaded", or "networkidle". pre_inject_hooks: Hook preset names to register before navigation. collect_response_chain: Record responses for final_status resolution. clear_network_capture: Clear stale network buffer before navigating. Returns: dict with url, title, initial_status, final_status, redirect_chain, hooks_injected, reloaded, warnings. |
| reloadA | Reload the current page, preserving any init scripts. |
| take_screenshotC | Take a screenshot of the current page or a specific element. Args: full_page: Capture the entire scrollable page. selector: CSS selector of a specific element to capture. |
| take_snapshotA | Get a bounded accessibility tree, or a labelled DOM fallback. Args: timeout_ms: Maximum wait for snapshot collection (1..30000). A hung error-page accessibility query returns an error without restarting the browser or replaying navigation. max_nodes: Maximum retained tree containers (1..5000). Depth is capped at 16 and individual strings at 2000 characters; truncation is explicit. |
| clickC | Click on a page element. |
| type_textC | Type text into an input field with realistic keystroke delays. |
| wait_forB | Wait for an element to appear or a network request matching a URL pattern. |
| get_page_infoB | Get page metadata plus a zero-based frame list for targeted tools. |
| reset_browser_stateC | Reset browser residual state after serializing trace transitions. |
| scriptsA | Script inspection (v0.9.0 unified). Replaces list_scripts / get_script_source / save_script. Args: action: "list" — list all loaded scripts (src, type, inline preview) "get" — get full source of one script (requires url; use "inline:" for inline scripts) "save" — save script source to local file (requires url + save_path) url: Script URL or "inline:" (required for "get" and "save"). save_path: Local file path (required for "save"). Returns: For "list": list of script info dicts. For "get": dict with source string. For "save": dict with status, path, size. |
| search_codeA | Search keyword in loaded scripts (v0.9.0 unified). Replaces search_code (all scripts) + search_code_in_script (single script). Args: keyword: The keyword to search for (case-sensitive substring match). script_url: If None, search across ALL loaded scripts. If given, search within that one script only (supports "inline:" for inline scripts). Single-script mode auto-detects minified files and uses character-based context. context_chars: Context window in char mode (default 200 = +/-200 chars). Used when searching single minified scripts. context_lines: Context window in line mode (default 3). max_results: Maximum matches to return (default 200). Returns: dict with matches, total_matches, mode ("line" | "char"), etc. |
| evaluate_jsA | Execute an arbitrary JavaScript expression in the page context and return the result. v1.0.1 fix: correctly handles undefined/null/void/Symbol return values without triggering JSON.parse crashes. Default auto mode preserves legacy cleaning and smart JSON parsing; it may strip BOM/whitespace and replace lone surrogates. value_raw is not a code-unit-preserving transport. json_ascii returns explicit JSON text before transport/cleaning, preserving JSON string code units. Evaluation is never replayed after a failure. Args:
expression: JavaScript expression. Must be a single expression, not
top-level var/let/const/function declarations (Playwright limitation).
Wrap in IIFE if needed: (() => { var x = 1; return x; })()
await_promise: If True, awaits Promise results (default True).
world: "isolated" preserves the existing Playwright execution context.
"main" prefers Camoufox's native Returns: dict with keys: value - cleaned value (parsed JSON if applicable) value_raw - raw string before cleaning (only when cleaning applied) type - "primitive" | "json" | "handle_fallback" | "error" world - selected execution world frame - selected frame's current snapshot metadata execution_backend - isolated, Camoufox native, or wrappedJSObject warnings - list of applied cleanups, if any hint - (error only) friendly fix suggestion or None |
| hook_functionA | Hook or trace a function (v0.9.0 unified). Replaces hook_function + trace_function. Args: function_path: Full path like "window.encrypt", "XMLHttpRequest.prototype.open", "JSON.stringify". mode: "intercept" — inject custom JS before/after/replace the function. Requires hook_code. (was: hook_function) "trace" — log synchronous returns/throws and optionally args and call stacks. (was: trace_function) hook_code: JS code for "intercept" mode. Context vars: - arguments: original args - __this: the 'this' context - __result: return value (only in position="after") position: For "intercept": "before", "after", or "replace". non_overridable: For "intercept": use Object.defineProperty to lock. persistent: If True, survives page navigation. log_args: For "trace": record arguments (default True). log_return: For "trace": record return values (default True). log_stack: For "trace": record call stacks (default False). max_captures: For "trace": max calls to record (default 50). world: "isolated" (compatible default) or Firefox page "main" world. wait_timeout_ms: How long to wait for a late-bound target. Defaults to 5000 for persistent hooks and 0 for non-persistent hooks. poll_interval_ms: Late-binding polling interval (10..1000ms). watch_assignments: Install a temporary setter on the first missing path segment so assignment-and-immediate-call in one JS task is captured. Defaults to True for persistent hooks and False otherwise. frame_url: Optional exact frame URL or shell-style wildcard. frame_name: Optional exact frame name or shell-style wildcard. frame_index: Optional zero-based index from get_page_info().frames. serialization: For "trace": "json" (default) retains JSON text fields, but executes getters/toJSON and may fall back to String conversion; this can have side effects. "preview" reads no properties of argument, return, or thrown objects and never coerces them: objects/functions are placeholders, symbols omit their description, and undefined, BigInt, NaN, infinities and -0 have string tags. Only the wrapper's own argument array is traversed. Text is truncated at 2000 characters in both modes and is not necessarily complete/parseable JSON. Trace semantics: Ordinary synchronous calls keep the original receiver, argument values, return/throw identity and one original invocation. Entries retain traceId, callIndex, timestamp, world, frame, args/returnValue and optional stack; outcome is "return" or "throw", with thrownValue for synchronous throws. completion="sync" always: a returned Promise/thenable is only a synchronous return, never an observed settlement (no await or attached handlers). Logging failures do not replace the original result/exception. Calls made by logging/JSON serialization are not recursively traced; real nested calls are. Clearing logs does not reset max_captures or callIndex. Intrinsics are saved at the first trace installation in each realm, so later hooks cannot redirect the logger. Already modified third-party intrinsics cannot be recovered. Preview limits value inspection, not timing/stack/identity visibility of wrappers or page-controlled sinks; optional stack capture may run custom stack formatting. Constructor/new semantics are outside this ordinary-call trace contract. Returns: dict with status, target, mode. |
| get_trace_dataC | Retrieve in-page traces and BrowserManager's cross-navigation cache. The Python-side cache is the authoritative source after reload/navigation.
Every new trace entry includes |
| inject_hook_presetA | Inject a pre-built hook template for common reverse engineering tasks. Available presets: - "xhr": Hook XMLHttpRequest to log all XHR requests. - "fetch": Hook window.fetch to log all fetch requests. - "crypto": Hook btoa/atob/JSON.stringify to capture encryption I/O. - "websocket": Hook WebSocket to log all WS messages. - "debugger_bypass": Bypass anti-debugging traps. - "cookie": Hook document.cookie writes. - "runtime_probe": Full runtime probe. Args: preset: One of the above preset names. persistent: If True (default), survives page navigation. Returns: dict with status and the preset name. |
| remove_hooksA | Remove installed hooks and restore original objects in-place. Args: keep_persistent: If True, keep persistent init_scripts registered. Returns: dict with status, restored_objects, cleared counts. |
| get_console_logsA | Get console output collected from the page. Args: level: Filter by log level - "log", "warn", "error", or "info". keyword: Filter logs containing this keyword in the text. clear: If True, clear the log buffer after retrieval. Returns: List of dicts with level, text, timestamp, and location. |
| network_captureA | Unified network capture control (v0.9.0). Replaces start_network_capture / stop_network_capture. Args: action: "start" — begin capturing network events "stop" — stop capturing (buffer retained) "clear" — clear the capture buffer "status" — return current capture state url_pattern: Glob pattern for "start" (default "**/*" captures all). capture_body: For "start" only; capture response bodies (more memory). max_body_size: For start; retained characters per response, 0..2000000. Playwright still reads the complete response before truncation. wait_timeout_ms: For stop; wait up to 30000ms for captured responses. New requests stop immediately; unfinished work is reported, not replayed. Clear cancels pending work; IDs remain monotonic until browser close. Returns: dict with action result + current status snapshot. |
| list_network_requestsA | List captured network requests with optional filters. Args: url_filter: Substring filter for request URLs. url_contains_domain: Host/subdomain boundary filter (e.g. "example.com"). method: HTTP method filter (e.g. "GET", "POST"). resource_type: Resource type filter (e.g. "xhr", "fetch", "script", "document"). status_code: HTTP status code filter. limit: Optional page size (1..2000); omitted preserves the full list. after_id: Return IDs greater than this cursor, in capture order. Check network_capture(status).dropped_requests for lost history. Returns: List of request summaries. Legacy size is retained body characters; size_unit is characters and body_bytes is the retained decoded entity byte count when encoding is known. Not compressed wire bytes. |
| get_network_requestA | Get full details of a specific captured network request. Args: request_id: The ID of the request (from list_network_requests). include_body: Include response body (default False). include_headers: Include request/response headers (default True). max_body_size: Max chars of body when include_body=True. Pass -1 for unlimited. Returns: dict with request and response details. |
| get_request_initiatorA | Get the JS call stack that initiated a network request. Returns a URL-matched hook stack as an investigation lead, not exact request attribution. Repeated/concurrent URLs can match a different invocation; corroborate with captured inputs. Requires inject_hook_preset("xhr"/"fetch") BEFORE navigating. KNOWN LIMITATIONS (v0.8.1+):
Args: request_id: The ID of the request. Returns: dict with url, initiator_stack, source, diagnostics and match_confidence. match_confidence is heuristic or unavailable; it never asserts exact identity. |
| intercept_requestB | Intercept network requests matching a pattern. Args: url_pattern: URL glob pattern (e.g. "**/api/login*"). action: "log", "block", "modify", "mock", or "stop" (unroute). modify_headers: Headers to add/override (action="modify"). modify_body: Request body replacement (action="modify"). mock_response: Dict with "status", "headers", "body" (action="mock"). |
| export_network_captureA | Export a versioned JSON snapshot of this manager's retained capture. Args: save_path: New local JSON path; existing files are never overwritten. include_body: Include captured request/response bodies only together with include_sensitive=True. Does not fetch or replay requests. include_sensitive: Opt in to original headers, query values and bodies. Default masks all header/query values, removes URL credentials and fragments, and omits bodies. URL paths are retained: this is not full anonymization. Keep original captures out of public repositories. url_filter: Optional URL substring filter. Returns: Path, count, redaction mode and capture status including pending/dropped work. For a settled snapshot call network_capture(stop, wait_timeout_ms). |
| compare_network_requestsA | Compare 2..10 captured requests without issuing requests or launching a browser. Args: request_ids: Distinct IDs from list_network_requests in this capture. include_headers: Compare available request headers; incompleteness warns. include_body: Compare exact request body text plus top-level JSON fields. max_value_chars: Preview characters per value (0..2000); digests always cover full values in canonical JSON. Each string also includes raw_utf8 byte length/SHA-256; use that for exact body byte checks. Results may contain credentials; keep them private. max_fields: Maximum changed rows and constant field names (1..200). Returns: Changed fields, constant names and completeness limits. Query duplicates, value order and raw URL encoding are preserved. Missing differs from null. A varying field is evidence, not proof that it participates in signing. |
| save_response_bodyA | Save captured response bytes (JS/WASM/JSON/binary) without refetch/replay. Args: request_id: A captured ID with a completed body (capture_body=True). save_path: New file path. Never overwrites existing files. allow_partial: Explicitly permit a truncated body; default rejects it. Returns: Path, saved byte length, SHA-256 and partial flag. Bytes are Playwright's decoded HTTP response body (not original compression/wire bytes). If the body was missing or truncated, increase the capture limit and collect a new sample intentionally; this tool never triggers a new request. |
| cookiesA | Cookie management (v0.9.0 unified). Replaces get_cookies / set_cookies / delete_cookies. Args: action: "get" — return cookies (optionally filtered by domain) "set" — set cookies (requires cookies_list: [{name, value, domain, ...}]) "delete" — delete cookies (filter by name and/or domain; no filter = clear all) domain: Host or parent domain for get/delete (boundary match, includes subdomains). With name, both filters must match. No filters deletes all cookies. cookies_list: List of cookie dicts for "set". name: Cookie name filter for "delete". Returns: For "get": list of cookie dicts. For "set"/"delete": dict with status and count. |
| get_storageA | Get the contents of localStorage or sessionStorage. Args: storage_type: "local" for localStorage, "session" for sessionStorage. Returns: dict with all key-value pairs in the storage. |
| export_stateA | Export the complete browser state (cookies + storage) to a JSON file. Args: save_path: Local file path to save the state JSON. Returns: dict with status and the save path. |
| import_stateA | Import browser state from a JSON file by creating a new context. Args: state_path: Path to the state JSON file (exported by export_state). Returns: dict with status and the new context name. |
| hook_jsvmp_interpreterA | Install a JSVMP runtime probe. Multi-path instrumentation for JSVMP interpreters. Wraps Reflect.get/apply, installs Proxies on globals (navigator, screen, etc.), intercepts timing APIs. LIMITATIONS: "proxy" mode is DETECTABLE by RS/AK-style signature-based anti-bot. For those, use instrumentation(action='install') (source-level rewrite) or mode='transparent' instead. IMPORTANT — timing for sync-loaded SDKs (e.g. webmssdk): JSVMP interpreters capture native references at startup via closures. If you install hooks AFTER the SDK has loaded, the SDK's closures already hold the original (un-hooked) references — your hooks will never fire. You MUST install hooks BEFORE navigate(): 1. launch_browser() 2. hook_jsvmp_interpreter(mode='transparent', persistent=True) 3. navigate("https://www.douyin.com/...") If already navigated, call instrumentation(action='reload') after installing hooks to force a page reload with hooks active. Args: script_url: Target script URL substring for stack filtering. persistent: Survive navigation (default True). mode: "proxy" (full coverage, detectable) or "transparent" (safe, lower coverage). track_calls, track_props, track_reflect: Only for mode="proxy". proxy_objects: Objects to proxy (default: navigator, screen, etc.). max_entries: Log buffer cap (default 10000). Returns: dict with status, mode, coverage summary. |
| compare_envA | Collect browser environment fingerprint data for comparison with Node.js/jsdom. Args: properties: Optional list of specific properties to check. If omitted, checks navigator, screen, canvas, WebGL, audio, timing. Returns: dict with categorized environment data and their values. |
| instrumentationA | JSVMP source-level instrumentation (v0.9.0 unified). Replaces instrument_jsvmp_source / get_instrumentation_log / stop_instrumentation / reload_with_hooks. Args: action: "install" — register route + AST/regex rewrite on matched scripts. Requires url_pattern. (was: instrument_jsvmp_source) "log" — fetch accumulated tap events from instrumented code. (was: get_instrumentation_log) "stop" — unregister instrumentation route. (was: stop_instrumentation) "reload" — reload page so persistent hooks fire before page JS. (was: reload_with_hooks) "status" — show active instrumentations and stats. (was: get_instrumentation_status) url_pattern: For "install"/"stop" — glob pattern matching VMP script URLs. mode: For "install" — "ast" (esprima then local bundled Acorn) or "regex" (conservative whole-program subset; unsupported input skipped). tag: For "install"/"log" — group identifier. rewrite_member_access: For "install" — tap obj[key] reads. rewrite_calls: For "install" — tap fn(args) calls. include_source_site: For "install" — attach a stable site_id and monotonic seq to tap events, plus an original-source range map in the log response. Default False. max_rewrites: For "install" — hard cap on rewrites per file. fallback_on_error: For "install" — try conservative regex on AST failure only without property/object filters; otherwise pass through unchanged. ignore_csp: For "install" — skip CSP pre-flight check. clear_log: For "reload" — clear JSVMP logs before reload. wait_until: For "reload" — "load" / "domcontentloaded" / "networkidle". tag_filter: For "log" — filter by tag. type_filter: For "log" — "tap_get", "tap_call", "tap_method", "tap_call_err". key_filter: For "log" — substring match on property/method name. limit: For "log" — max entries to return. clear: For "log" — clear log after retrieval in the selected main world. frame_url: For log; select a target frame by URL pattern. frame_name: For log; select a target frame by name. frame_index: For log; current frame snapshot index, not a persistent identity. Source scripts run in the main world; logs are always read there. filter_property_names: For AST "install" — only rewrite reads/methods of these property names (e.g. ['userAgent', 'platform', 'webdriver']). Dramatically reduces overhead for large files like webmssdk. filter_object_names: For AST "install" — only rewrite when the static base object path matches (e.g. ['navigator', 'this.bytecode']). Dynamic object identity is not inferred. Regex mode rejects nonempty filters. max_file_size: For "install" — files larger than this (bytes) trigger on_oversized behavior. Default 200KB. on_oversized: For "install" — "selective" (require filters), "skip", or "force" (full rewrite anyway). Default "selective". Returns: dict with action-specific results. IMPORTANT — timing for sync-loaded scripts (e.g. webmssdk): Route interception only catches requests made AFTER the route is registered. For scripts loaded via during page load, you MUST call instrumentation(action='install') BEFORE navigate(). Pattern: 1. launch_browser() 2. instrumentation(action='install', url_pattern='**/webmssdk*') 3. navigate("https://www.douyin.com/...") If called after navigate, use instrumentation(action='reload') to re-trigger page load with routes active. |
| check_environmentA | One-stop self-check of MCP environment, dependencies, and browser state. v1.0.0: session-related checks removed (session mechanism removed). Checks MCP version, critical dependencies (esprima, playwright), browser state (residuals, captures). Returns: dict with sections: mcp, deps, browser, overall_ok, recommendations. |
| verify_signer_offlineA | Verify a signer against explicit expected values without sending requests. Args: signer_code: JS expression evaluating to a function receiving sample.input and returning an object. Async functions are supported. Only run code you intend to execute locally; Node vm is not a security boundary. samples: Non-empty list (up to 1000) of {id?, input: object, expected: object}. Each expected object must contain at least one comparison key. compare_params: Optional non-empty list of expected keys. Missing keys are invalid input; missing computed keys fail even if expected is null. runtime: "browser" preserves the current-page default. "node" runs an independent process without launching a browser, supports require of crypto/node:crypto, and needs Node.js on PATH. No runtime fallback. timeout_ms: Node process deadline (1..120000); also the maximum wait for the browser evaluation. A browser timeout does not undo/stop effects. Returns: total_samples, passed, failed, pass_rate, first_divergence and details. Invalid input returns error before any signer code is executed. |
| trace_property_accessB | Control/query the current Gecko native PropertyTracer run. action supports capture, start, stop, query, clear, and status. Results can use summary, timeline, sequence, or search views and optional object, kind, site, and keyword filters. collect_values is a safe post-trace snapshot, not an event-time value capture. |
| list_trace_filesC | List all trace files on disk (for post-hoc analysis). Returns: dict with traces_dir, total file count, and file details. |
| query_trace_fileC | Query a specific historical trace file (post-hoc analysis). Args: file_path: Path to the .jsonl trace file. mode: Same as trace_property_access (summary/timeline/sequence/search). filter_object: Filter by object name. search_query: Filter by search string. limit: Max events for sequence mode. bucket_ms: Bucket size for timeline mode. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 39 tools
Most tools have clearly distinct purposes (e.g., click vs type_text, get_console_logs vs get_network_request). However, some overlap exists among hooking/tracing tools (inject_hook_preset, hook_function, hook_jsvmp_interpreter, instrumentation) and among network capture tools (network_capture, intercept_request, list_network_requests). Detailed descriptions mitigate confusion, but a few boundaries remain fuzzy.
The majority of tools follow a verb_noun snake_case pattern (e.g., take_snapshot, get_page_info, export_state). Exceptions include bare verbs like 'click' and 'reload', and noun-only names like 'cookies', 'scripts', and 'network_capture' which are unified command families. Overall consistent, with minor deviations.
With 39 tools, the surface is heavy but not excessive given the broad scope of browser automation and reverse engineering. Many tools are specialized and some have been unified to reduce count (e.g., instrumentation, network_capture). While each has a purpose, the number may strain an agent's context and selection accuracy.
The tool surface is remarkably complete for the domain: launching/attaching browser, navigation, interaction, snapshots, screenshots, JS evaluation, storage/cookies, network capture/interception/analysis, multiple hooking mechanisms, source instrumentation, tracing, script inspection, state persistence, environment fingerprinting, and signer verification. No significant dead ends or missing core operations.