Skip to main content

odda

odda is a toolkit for agent-driven web security research, composable from a single MCP server. It gives an AI agent a real Chrome it can drive and observe, a transparent mitmproxy that writes every flow to disk, and a raw-HTTP send path for smuggling and race conditions.

  • Drive Chrome — open, navigate, run JS, screenshot, and interact with the page by accessibility-tree refs.
  • Capture every flow — a transparent proxy writes every request/response to disk, including media bodies browser capture drops.
  • Observe JS in progress — wrap functions/properties, plant source logpoints, record block coverage.
  • Craft raw HTTP — byte-faithful sends for smuggling, parser-differentials, and races.

Requirements

  • Python 3.14+
  • Chrome or Chromium installed and on PATH

Installation

uv tool install odda

This installs the odda command (an MCP server plus one helper subcommand, with --version for the version probe). Then register the server with your harness — one MCP config entry, and every odda capability becomes typed tools your agent can call.

Harness configuration

All configs spawn the same stdio server: odda mcp. One MCP process = one odda session with its own Chrome, proxy, and .odda/ data dir (created lazily under the process's working directory on first use).

Claude Code — project .mcp.json (or ~/.claude.json under mcpServers):

{
  "mcpServers": {
    "odda": {
      "command": "odda",
      "args": ["mcp"]
    }
  }
}

OpenCode~/.config/opencode/opencode.json:

{
  "mcp": {
    "odda": {
      "type": "local",
      "command": ["odda", "mcp"]
    }
  }
}

pi — install the MCP adapter once (pi install npm:pi-mcp-adapter), then add to project .mcp.json (same mcpServers shape as Claude Code):

{
  "mcpServers": {
    "odda": {
      "command": "odda",
      "args": ["mcp"]
    }
  }
}

Chrome profile (one-time)

To give odda's isolated browser sessions a base profile (cookies, extensions, preferences):

odda init-chrome-profile

This opens a visible Chrome window pointed at odda's base profile directory. Log in, install extensions, and set preferences as you want them; close the window when done. odda copies this profile into each isolated browser session opened by browser_open. Skip this step to start from a clean profile each time.

Usage

Agents drive odda through the MCP tools (browser_open, navigate, page_snapshot, request_send, ...). IDs are integers, monotonic within a session, and never reused; every browser/tab tool takes explicit browser_id / tab_id parameters.

A typical session:

browser_open          → {browser_id, tab_id}
navigate              → tab loads https://target.example/
read .odda/flows/flows.jsonl     → every request/response captured on disk
request_clone + request_send           → the Burp Repeater loop, as tools

All captured traffic is stored under .odda/flows/<id>/ — request bytes, response body, headers, timing — plus the append-only flows.jsonl index. Grep the index to find flows; read .odda/flows/<id>/response_body.* for the body (including image/video/audio/font Content-Types that browser capture drops).

Features

Drive Chrome

A real Chrome (via patchright/Playwright), headless by default:

  • Open / navigate / eval / wait-for / screenshot — drive the browser and run JS in the page.
  • Ref-driven page interactionpage_snapshot returns the accessibility tree with [ref=eN] tags; pass the ref to page_click / page_fill / page_hover / page_upload. page_click and page_hover also accept viewport coordinates as a raw trusted event for targets the a11y tree can't name. Cross-iframe is transparent.
  • Per-browser userscripts — JS that auto-runs at document_start on every navigation, before the page's own scripts.
  • Dialog blockingalert / confirm / prompt / beforeunload stay open until handled: the action that opens one returns its details, other tools on that tab wait, and every same-browser result lists open dialogs. Resolve with dialog_handle (accept/dismiss, prompt text); a human closing it in a headed window works too.

Capture every flow

A transparent mitmproxy sits between Chrome and the network; driving the browser is traffic capture. Every request/response is saved under .odda/flows/<id>/; the index is .odda/flows/flows.jsonl. See the odda://docs/flows resource for the file layout and schema.

Observe JS in progress

Three lenses, chosen by what you know:

  • Wrap — wrap a named function or property; record each call/access with this, args, ret, and stack. Takes effect on the next navigation.
  • Logpoint — plant a non-pausing observation at a source url + line + col; the expression is evaluated in the paused frame's scope, so it reads locals by name.
  • Coverage — record which code blocks execute across one or more navigations; start, trigger behavior, snapshot or stop.

Wrap and Logpoint records wipe on navigation — dump before navigating again. The odda://docs/dynamic-analysis resource documents the full surface; odda://docs/recipes has a worked example tracing untrusted DOM data to a sink.

Craft raw HTTP

Byte-faithful raw HTTP sends, bypassing the browser — the Burp Repeater model, as tools:

  • Wire-verbatim HTTP/1.1 — the request file is the wire; nothing is re-framed.
  • HTTP/2 frame-source — the request file is parsed into H2 frames; a custom line terminator lets a literal CRLF live inside an H2 pseudo-header for downgrade smuggling.
  • Clone or craftrequest_clone copies a captured flow's exact bytes; request_new starts an empty file.
  • Multi-name pipeline — pass several names to send several requests on one connection (H1 keep-alive, or H2 concurrent stream-multiplex) for same-connection attacks.
  • Concurrent sendrepeat fires N copies of one request concurrently for race conditions and limit-overrun attacks.
  • fix_content_length — recompute Content-Length after body edits.

See the odda://docs/request-crafting resource for framing details.

How it works

  • odda mcp is the only odda process: a stdio MCP server whose lifespan owns the proxy, the browser manager, and the flow storage. Your harness spawns it per agent session; closing the session tears everything down.
  • The remaining CLI surface is helpers, not the automation surface: odda init-chrome-profile (interactive, human-run) and odda --version/-V.
  • Project state lives in .odda/ under the MCP process's working directory: flows/, requests/, browsers/. It's created lazily on the first state-producing call, not when the server boots.
  • Errors from tools are odda's messages verbatim (as tool errors); unanticipated crashes log their traceback to the server's stderr, which the harness captures.

Release files for odda 0.44.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for odda 0.44.1
File Size Uploaded
odda-0.44.1.tar.gz 102.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for odda 0.44.1
File Interpreter ABI Platform
odda-0.44.1-py3-none-any.whl Python 3 none any Details

Total release size: 215.0 kB

Release files / odda-0.44.1.tar.gz

Download URL odda-0.44.1.tar.gz
Size 102.1 kB
Tags Source
SHA-256 checksum
How to use checksums
88cc090273d4043d7db1769186f82c65b04770a92abe8463fc5d59fbde4a5a53
BLAKE2b-256 checksum
How to use checksums
6e15c5675ba2601ad6db63f69ca4860206b06efd6aea4a98ff0e0220798120fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.2

Release files / odda-0.44.1-py3-none-any.whl

Download URL odda-0.44.1-py3-none-any.whl
Size 112.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e769bb92c7aa2ad43df89f70ade5bff6b12eb29307a8c66d34437dbfeb1ac3f5
BLAKE2b-256 checksum
How to use checksums
240a120d9cc44af31fc848d721c2caf70bc68162e0869f7f00bfd031c35eb3ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.2

Release history Release notifications | RSS feed

0.54.2

2 release files

0.54.1

2 release files

0.54.0

2 release files

0.53.1

2 release files

0.53.0

2 release files

0.52.1

2 release files

0.52.0

2 release files

0.51.0

2 release files

0.50.0

2 release files

0.49.0

2 release files

0.48.0

2 release files

0.47.0

2 release files

0.46.1

2 release files

0.46.0

2 release files

0.45.0

2 release files

This release

0.44.1 This release

2 release files

0.44.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page