A hexagonal, adapter-headed reverse-engineering platform.
Scylla wraps a proven reverse-engineering engine behind a durable, transport-agnostic reverse-engineering domain model — the body — and exposes it through thin, disposable protocol adapters — the heads.
Named for the six-headed sea monster of Homer's Odyssey: many heads, one immortal body. Lop a head off and grow a new one. Today there are nine heads — an MCP server (so AI agents reverse-engineer binaries directly), a browser/WASM head, a native serving binary, a terminal CLI, a remote Cap'n Proto RPC head, an HTTP/JSON gateway, a GraphQL gateway, a TUI navigator, and an LSP server — all projecting the same body. When MCP is the CORBA of 2040, you grow a new head and the body never notices.
Reverse-engineering tools fossilize around the universal adapter of their era (Ghidra is Java-shaped because the JVM was the cross-platform answer circa 2000). You can't pick a technology that survives 20 years — so don't. Pick the right seam and bet on the slowest-moving layer.
In reverse engineering, the slowest-moving layer is the domain model itself — functions, basic blocks, cross-references, types, the call graph, symbols, decompiled output, annotations. That vocabulary barely moved from IDA in the '90s to Ghidra in the 2000s to today, and it won't move much in the next 20 years, because it isn't a technology — it's the shape of the problem.
Scylla's architecture (ports-and-adapters / hexagonal):
- The body — a clean, minimal, transport-agnostic contract for the RE domain model, sitting on top of a proven engine (the engine is sacred; it is never rewritten).
- The heads — thin, sheddable protocol adapters (MCP first; REST/gRPC/whatever next) that project the body to whatever consumer the era demands. Each head is ~a few hundred lines and disposable; the body is the only bet you can't take back.
You cannot shim your way out of a bad core, so the design effort goes into the body. The heads are cheap on purpose.
Before — the current GayHydra / Ghidra implementation Scylla refactors away from: a Java monolith with the UI welded to the framework, the proven C++ decompiler reached across a brittle serialized IPC seam (warts in red, the proven engine in green):
After — the hexagonal target Scylla builds toward: a durable Rust core holding the RE domain model as the system's narrow waist, GayHydra demoted to a droppable proven engine behind the engine-port, and disposable polyglot heads (MCP first) below the client-port. The two ⟡ bands are the narrow waists; the model-artifact is the one bet you can't take back:
The reasoning behind every box is recorded in DesignDecisions.md (all 44 decisions); the build path — prototype-first — is in SprintPlanning.md; what shipped when is in CHANGELOG.md.
One body — the durable RE domain model (scylla-model) and the client port over it
(scylla-port) — and nine heads today, each a thin adapter projecting the same verbs
(navigate / annotate / diff / merge / export):
- Browser (WASM) —
crates/scylla-wasm: the client port compiled towasm32, so a browser navigates / annotates / diffs a.scyllamodel-artifact entirely client-side — no server, no engine. Renders the call graph as an actual graph, paints a structural diff onto it, searches. - Native single binary —
crates/scylla-serve: a zero-dependency binary that bakes in the browser head and serves it + an artifact over HTTP.scylla-serve old.scylla new.scyllaopens straight onto what the rebuild changed. - Terminal —
crates/scylla-cli(scylla):materializea binary via the engine, thendiff/info/functions/search/view/callersan artifact offline.scylla diffcarriesgit diff --exit-codesemantics for CI. - AI agents (MCP) —
crates/scylla-mcp: an MCP server exposing the port 1:1 as tools (list_functions / search / get_function / callers / rename / retype / comment / diff / merge / export), so an agent reverse-engineers a binary directly. Binary-derived text is wrapped untrusted (DD-035). - Remote (Cap'n Proto RPC) —
crates/scylla-rpc:scylla-rpc-serveserves the model over TCP andscylla-rpc-connectdrives it from off-box, navigating by promise-pipelining (function(id).callers().view()is one round-trip — the transport the artifact format was chosen for, DD-002), annotating (rename/retype/comment) and pulling the result back down (export). Auth-gated, connection-capped, slow-loris-bounded, TLS-capable. - HTTP/JSON gateway —
crates/scylla-http:scylla-httpserves the model as a plain HTTP/JSON API (GET /api/info//api/functions//api/search?q=//api/functions/<id>/…/callers,POST /api/diff) and lets any client annotate it (POST …/rename/…/retype/…/comment) then pull the annotated model back as a.scylla(GET /api/export), so any language, dashboard, orcurldrives the full verb set — including persistence — with no special client. Token-gated and TLS-capable, like the RPC head. - GraphQL —
crates/scylla-graphql:scylla-graphqlserves the model as one typed GraphQL graph —query { info, functions, search, function, callers, diff, export }andmutation { rename, retype, comment }— so a client fetches exactly the function / caller / diff shape it wants in a single round-trip (no over- or under-fetching), with schema introspection and a GraphiQL console atGET /graphql. Token-gated and TLS-capable, like the HTTP and RPC heads. - TUI —
crates/scylla-tui:scylla-tuiis an interactive terminal navigator over the model — browse the function list, a detail pane (address, basic blocks, size, callees, callers) that follows the selection, a live/search filter, and a structural-diff pane (pass a second artifact, toggle withd) listing renamed / modified / added / removed with per-pair confidence — all over the client port. TheApp(model + UI state) is a pure projection of the port, conformance-tested verb-for-verb; theratatuishell is thin on top. - LSP —
crates/scylla-lsp:scylla-lspis a Language Server so an editor (nvim, VS Code) navigates the model like source — the program is one virtual document (functions in address order), with go-to-symbol (documentSymbol), hover (the port'sview, wrapped untrusted per DD-035), find-references (= thecallersverb), rename (the annotate verb, as aWorkspaceEdit), and workspace-symbol (=search). Hand-rolledContent-LengthJSON-RPC; thedispatchrouter is a headless, conformance-tested port projection.
The diff is a real binary-differ: it pairs functions across two builds by structural identity (address-independent), then climbs the BinDiff-style ladder — call-graph propagation, unique strings/imports, BSim feature vectors, mnemonic + ordered-trigram cosine — to report functions matched / renamed / modified / added / removed. Fail-closed throughout: a near-tie is never guessed.
Feature-complete core, nine working heads. The durable Rust body (model + client port + Cap'n Proto model-artifact) is built, with a structural binary-diff engine at parity with the identity-anchored merge. The heads above all run today over that one body — including a remote RPC head over the Cap'n Proto promise-pipelining surface (DD-002), the transport the format was chosen for; the heavy JVM engine is reached over gRPC as a droppable producer (DD-009/040). Sibling project to GayHydra (a hardened fork of NSA Ghidra, which provides the proven engine Scylla wraps).
Scylla stands on work it has no intention of replacing:
- Ghidra (NSA) — the proven reverse-engineering engine Scylla wraps, by way of the GayHydra hardened fork. The engine is sacred: Scylla demotes it to a droppable producer behind the engine-port, never rewrites it.
- Cap'n Proto — the serialization behind the durable model-artifact (DD-002). The artifact is the one bet Scylla can't take back, so it rests on a format built for schema evolution and bounded, memory-safe reads — and chosen, too, for the promise-pipelining RPC the client port will project if a remote head ever needs it.
- Protocol Buffers over tonic / Prost, on Tokio — the gRPC engine-port seam to the sandboxed JVM engine-as-service (DD-009/040).
- The Rust project and its crate ecosystem — the language of the durable core.
Two serialization IDLs in one tree — Cap'n Proto on the model/client waist, Protocol Buffers on the engine seam — is a deliberate, documented choice (see DD-002), not an accident.
Apache License 2.0 © Aaron K. Clark — matching Ghidra (Apache 2.0), the engine Scylla builds on.
Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/

