MCP Server
Hydralysis: twenty reverse-engineering tools. One CLI. One MCP server.
To an agent, an MCP server is a tool list. Hydralysis is RusticStack's: a small, fixed catalog that takes an agent from an analysed project or a fresh executable to bounded, cited answers. It runs on Hydra Engine, so every CLI call, MCP session and script shares one warm Ghidra. It's built for native PE files you own.
- MCP over stdio
- Python package
The twenty tools
| Tools | For |
|---|---|
fingerprint, imports | Identity, packing triage, sections and exports. |
inspect, disasm, function, bytes, strings, xrefs, callers, callees | Cheap evidence straight from the PE, no JVM. |
sigscan, prologue | Finding candidate sites, and checking bytes or whole hook tables against a build. |
backend, prepare, job | Engine setup, one explicit analysis per build, progress and cancellation. |
ghidra_query, ghidra_run | Questions to the saved analysis: decompile, types, variables, p-code, traces, exports. |
evidence_add, evidence_list | Claims, each with a mandatory source. |
runtime | Controlled local runtime sessions with byte-checked probes. |
The catalog is deliberately small: 20 tools in about 7.4 KB of schema, so it costs an agent little context. Detailed options are fetched on demand with backend help.
Install
From a checkout of Hydralysis, in a virtual environment:
1uv venv .venv2.venv/Scripts/python.exe -m pip install -e .3.venv/Scripts/hydralysis.exe toolsHydralysis needs Python 3.11 or later. Point HYDRALYSIS_ROOT at a directory for its engine, prepared projects, evidence and logs, then install the engine:
1hydralysis backend inspect2hydralysis backend install # a background job3hydralysis job <setup-id>backend install fetches the pinned Hydra Engine release (12.3-hydra.2: the engine and its client) and a JDK, checks each archive's SHA-256 and installs them under the root, with no administrator rights. That is Windows x64 only, the one released build; elsewhere, build Hydra Engine from source and name it with hydra_dir, hydra_client and java_home in hydralysis.local.json.
Rather have your agent do it? Paste the setup prompt from the home page into your agent harness.
Register it with a client
For any client that reads the common mcpServers shape:
{ "mcpServers": { "hydralysis": { "command": "/path/to/Hydralysis/.venv/Scripts/hydralysis.exe", "args": ["mcp"], "env": { "HYDRALYSIS_ROOT": "/path/to/hydralysis-data" } } }}Restart the client afterwards: a session that is already open keeps the tool list it started with. Hydralysis never edits client settings itself.
From a project or an executable to answers
A project Ghidra already analysed is adopted where it is, with no copy and no import:
1hydralysis prepare --adopt /re/MyProject --exe ./sample.exe --target sampleA fresh executable is analysed once:
1hydralysis fingerprint --exe ./sample.exe2hydralysis prepare --exe ./sample.exe --target sample --plan # shows the work, does none3hydralysis prepare --exe ./sample.exe --target sample # analyses once, as a job4hydralysis job <prepare-id>5hydralysis ghidra-query --target sample rva:0x10006hydralysis ghidra-query --target sample --action functions --contains Render --limit 20--planimports, downloads and creates nothing.prepareruns the import and analysis once, as a durable job. An identical build reuses its result, whatever alias an agent picked.- Wrapped executables (
.bindsections, UPX) are refused withneeds_unwrapped_artifact. Hydralysis doesn't unpack or launch anything for you. - Queries run contained on the warm engine, so one client's query can't change what another reads.
- Corrections (types, names, prototypes) are cited overlays in a working copy forked from the analysis; the analysed project is never written.
Answers stay bounded
An MCP reply that floods the context is worse than none. Listings are paged and say when they're truncated, with a cursor to continue. Decompiler output is capped at 32,000 characters. Bulk work goes to an export job instead: resumable JSONL with progress and hashes, which refuses to resume against a changed build.
Without MCP
Every tool is also a CLI command, so a client without an MCP connection can run the same operations from its terminal. Put skills/hydralysis/SKILL.md in that client's agent guidance so it knows the short commands exist.
Writing your own server
Hydra is a generic Ghidra front end; the tools belong to whoever wraps it. An MCP server keeps one daemon connection for the whole server and exposes the commands it wants as tools:
1import ghidra_session as gs2 3daemon = gs.connect(client="my-mcp", harness="mcp")4 5def decompile_tool(agent: str, harness: str, program: str, address: str) -> str:6 # One labelled view per agent: holders, status and cancel name the agent, not the server.7 view = daemon.labelled(client=agent, harness=harness)8 return view.call("decompile", program=program, address=address, maxChars=32000)["c"]- Parallel by default. A labelled view sends
parallel: true, so one agent's long request doesn't hold up another's. - Answer errors, don't retry blindly.
busymeans retry or raisewait.not_ownercomes with a ready overlay or working-copy request.conflictwithreason: "changed"means re-read first. - Check the build.
info.sha256tells you which executable you're answering about.