Hydra Engine

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

ToolsFor
fingerprint, importsIdentity, packing triage, sections and exports.
inspect, disasm, function, bytes, strings, xrefs, callers, calleesCheap evidence straight from the PE, no JVM.
sigscan, prologueFinding candidate sites, and checking bytes or whole hook tables against a build.
backend, prepare, jobEngine setup, one explicit analysis per build, progress and cancellation.
ghidra_query, ghidra_runQuestions to the saved analysis: decompile, types, variables, p-code, traces, exports.
evidence_add, evidence_listClaims, each with a mandatory source.
runtimeControlled 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:

bash
1uv venv .venv2.venv/Scripts/python.exe -m pip install -e .3.venv/Scripts/hydralysis.exe tools

Hydralysis needs Python 3.11 or later. Point HYDRALYSIS_ROOT at a directory for its engine, prepared projects, evidence and logs, then install the engine:

bash
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:

json
{  "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:

bash
1hydralysis prepare --adopt /re/MyProject --exe ./sample.exe --target sample

A fresh executable is analysed once:

bash
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
  • --plan imports, downloads and creates nothing.
  • prepare runs the import and analysis once, as a durable job. An identical build reuses its result, whatever alias an agent picked.
  • Wrapped executables (.bind sections, UPX) are refused with needs_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:

python
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. busy means retry or raise wait. not_owner comes with a ready overlay or working-copy request. conflict with reason: "changed" means re-read first.
  • Check the build. info.sha256 tells you which executable you're answering about.