ida-headless-mcp
Health Warn
- License — License: Apache-2.0
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Fail
- rm -rf — Recursive force deletion command in e2e/http_bootstrap.sh
- rm -rf — Recursive force deletion command in e2e/http_close_recovery.sh
- rm -rf — Recursive force deletion command in e2e/http_integration.sh
- rm -rf — Recursive force deletion command in e2e/http_observability.sh
- rm -rf — Recursive force deletion command in e2e/http_pool.sh
- rm -rf — Recursive force deletion command in e2e/http_script_integration.sh
- rm -rf — Recursive force deletion command in e2e/http_session_cancel.sh
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Rust-native, multi-session headless IDA Pro MCP server with isolated workers and stdio or Streamable HTTP transports.
ida-headless-mcp
English | 简体中文
Rust-native, multi-session headless IDA Pro MCP server.
This project is a derivative of blacktop/ida-mcp-rs, rewritten around an explicit supervisor/worker split and pinned to the mrexodia/ida-pro-mcp public contract. It is not a drop-in replacement for the upstream Homebrew/Scoop packages, and it is not an official Hex-Rays product.
What this project adds
- One supervisor process owns MCP stdio or Streamable HTTP.
- Each open database gets its own IDA worker process; a crash takes down one session, not the server.
- Session lifecycle is explicit:
idb_open,idb_list,idb_close,server_health, plus analysis tools that all require adatabasesession ID. - 90 tools by default, 91 with
--unsafe, in 12 categories. - Headless-only: debugger and GUI control stay out of the public surface.
See docs/ARCHITECTURE.md and docs/MIGRATION.md.
Prerequisites
- IDA Pro 9.2, 9.3, or 9.4 with a valid license
- Rust (source builds only) —
rust-toolchain.tomlpins the exact version and
rustup installs it for you.Cargo.tomldeclares a 1.95 floor, inherited from
vibrev-kit, but the pin is what every build and every CI run actually uses. - LLVM/Clang for the C++ bindings (source builds only)
Release builds never ship IDA, the SDK, or IDA runtime libraries. You must already have a licensed IDA install on the same platform and architecture.
Install
There is no package-manager distribution — no Homebrew tap, no Scoop bucket, no snap. Two paths:
- Prebuilt archive. Download from Releases, verify against
checksums.txt, and put the executable on yourPATH. - Build from source (below) — the only option for any other platform or architecture.
Archives are named ida-headless-mcp_<version>_ida-<minor>_<OS>_<arch>, with .tar.gz on Unix and .zip on Windows. <OS> is Linux, macOS, or Windows. Each release publishes three IDA minors (9.2, 9.3, 9.4) for three platform pairs — Linux_x86_64, macOS_arm64, Windows_x86_64 — so nine archives in total. Each one carries the executable plus README.md, LICENSE, and NOTICE.
Pick the archive whose IDA minor matches your installed IDA. The binary checks the loaded IDA version before it opens a database: once either side is 9.4 the minor has to match exactly, because idalib reconstructs IDA-internal layouts by hand and 9.4 moved one of them. Below 9.4 only the major is compared (IDA 9.3 reports its product version as 9.0), but matching the minor is still the right habit.
Build
See docs/BUILDING.md. Each IDA minor has its own manifest; pick exactly one:
# IDA 9.4 (default)
IDADIR=/path/to/ida-9.4 cargo build --release
# IDA 9.3
IDADIR=/path/to/ida-9.3 cargo build --release \
--manifest-path sdk/ida-93/Cargo.toml
# IDA 9.2
IDADIR=/path/to/ida-9.2 cargo build --release \
--manifest-path sdk/ida-92/Cargo.toml
The 9.4 binary is under target/release; 9.2 and 9.3 use their manifest-localsdk/ida-*/target/release directories. Windows adds the .exe suffix. The 9.2
and 9.3 builds need one extra linker flag — see docs/BUILDING.md.
just --list shows the repo's build and test recipes; docs/TESTING.md explains which ones need a licensed IDA.
Platform setup
The process links against IDA at runtime. Point it at your install if it is not in a default location:
| Platform | Typical path | Runtime hint |
|---|---|---|
| Linux | ~/ida-pro-9.4 or /opt/ida-pro-9.4 |
IDADIR or LD_LIBRARY_PATH |
| macOS | /Applications/IDA Professional 9.4.app/Contents/MacOS |
IDADIR or DYLD_LIBRARY_PATH |
| Windows | C:\Program Files\IDA Professional 9.4 |
Put the exe next to ida.dll, or set IDADIR and add that directory to PATH |
# Linux / macOS
export IDADIR=/path/to/ida
./target/release/ida-headless-mcp
# Windows
$env:IDADIR = "C:\Program Files\IDA Professional 9.4"
.\target\release\ida-headless-mcp.exe
That starts the default HTTP listener on 127.0.0.1:8765 and prints a security
banner — enough to confirm the binary found IDA. Ctrl-C to stop it.
IDADIR must name the same installation the binary was built for. The two
halves of IDA are resolved separately — the core library by the dynamic linker,
the plugins and processor modules by IDA out of IDADIR — so pointing IDADIR
at a different release on a machine that has both leaves you running one
version's core with another version's plugins. That used to start, and then fail
as "Hex-Rays decompiler is not available", a segfault inside a processor module,
or a dyld_shared_cache that would not open. It now refuses at startup and names
both directories. Pass --allow-ida-mismatch (or IDA_MCP_ALLOW_IDA_MISMATCH=1)
if you have a reason to run it anyway.
Configure an MCP client
MCP clients spawn the binary and talk over the pipe, so they need the stdio transport by name: serve --mode stdio. (A bare invocation serves HTTP — see Streamable HTTP.) After the binary is on PATH (or use the absolute path):
Claude Code
claude mcp add ida -- ida-headless-mcp serve --mode stdio
Codex CLI
codex mcp add ida -- ida-headless-mcp serve --mode stdio
Cursor
Add to .cursor/mcp.json:
{
"mcpServers": {
"ida": {
"command": "ida-headless-mcp",
"args": ["serve", "--mode", "stdio"],
"env": {
"IDADIR": "/path/to/ida"
}
}
}
}
Usage
The supervisor returns an opaque session ID from idb_open. Pass that ID as database to every analysis tool, then close the session when finished.
idb_open(input_path: "~/samples/malware")
idb_list()
list_funcs(database: "<session_id>", offset: 0, limit: 20)
find_string(database: "<session_id>", query: "libc")
disasm(database: "<session_id>", address: "0x100000f00")
xrefs_to(database: "<session_id>", address: "0x100000f00")
decompile(database: "<session_id>", address: "0x100000f00")
idb_close(database: "<session_id>")
Notes that save a round trip:
input_pathmay be a raw binary (Mach-O/ELF/PE) or an existing.i64/.idb. Opening the same canonical path twice returns the session that already exists instead of a second worker.- Sessions are reaped after
idle_ttl_secseconds idle (default 600); pass0to disable. idb_opentakes amode:prefer_headless(default),force_headless, andprefer_guiall yield a headless worker;force_guireturns a stable unsupported-mode error, because this build is headless-only.--max-workers(default 4) caps how many worker processes the supervisor keeps alive at once, on either transport — one per open database.IDA_MCP_MAX_WORKERSis the env spelling.server_healthreports on the supervisor without touching a database.
Coming from the previous ida-pro-mcp-compatible tool names? See the mapping table in docs/MIGRATION.md.
Streamable HTTP
./target/release/ida-headless-mcp serve --bind 127.0.0.1:8765
Unlike stdio, this opens a listener, so every request needs a bearer token — there is no flag that turns it off. The token lives in $VIBREV_HOME/token, or ~/.vibrev/token when that is unset (mode 0600, generated on first use and reused afterwards); --token-file moves it. On startup the server prints a security banner and a paste-able client-config snippet:
"ida-headless-mcp": {
"type": "http",
"url": "http://127.0.0.1:8765/mcp",
"headers": { "Authorization": "Bearer vbr_…" }
}
The token is elided from that snippet when stderr is not a terminal, so redirected logs and CI output do not leak it; read it back with head -n1 ~/.vibrev/token.
HTTP is what serve does unless you pass --mode stdio, so the command above needs no mode. See docs/TRANSPORTS.md for authentication, Origin/Host checks, session keep-alive, and the pool flags.
Bundled skills
The binary carries an IDAPython reference skill (105 files, compressed into the
executable) that teaches a model the ida_* API the tool surface sits on top of.
It is packed at build time from skills/ and written back out byte for byte:
ida-headless-mcp skills list
ida-headless-mcp skills export --dir ~/.claude/skills
Neither command opens a database or needs an IDA license — the answer is baked
into the binary. vibrev install ida calls them for you and puts the result
where Claude Code reads it; see vibrev skill --help. Only Claude Code has a
skill mechanism, so other clients get the MCP server without this part.
Tool filtering
The default catalog advertises every available tool except run_script, which executes arbitrary IDAPython inside the worker. --unsafe (or IDA_MCP_UNSAFE=true) enables it — that is the only tool the flag gates.
To narrow the surface instead:
--toolsetskeeps only the named categories:core,functions,disassembly,decompile,xrefs,control_flow,memory,search,metadata,types,editing,scripting.--toolsadds individual tools back on top of--toolsets.--exclude-toolsremoves tools; exclusion always wins.--read-onlykeeps only tools that declarereadOnlyHint, so it tracks the catalog rather than a hand-kept list.
Each has an environment mirror (IDA_MCP_TOOLSETS, IDA_MCP_TOOLS, IDA_MCP_EXCLUDE_TOOLS, IDA_MCP_READ_ONLY).
Lumina
Automatic Lumina lookup is disabled unless you opt in:
ida-headless-mcp --allow-lumina
The equivalent environment setting is IDA_MCP_ALLOW_LUMINA=true. The isolated IDA user profile used by this server does not change the normal IDA GUI profile.
Limitations
- You bring your own IDA. No archive here contains IDA, its SDK, or its runtime libraries, and none of them will run without a licensed install.
- The decompiler-backed tools need Hex-Rays. Without a decompiler the worker reports "Hex-Rays decompiler is not available" at warm-up — followed by what it observed: the processor, the module that processor needs, the modules actually installed, and whether the installation is internally consistent.
decompile,pseudocode_at,diff_before_afterand the pseudocode part ofanalyze_functioncannot answer. Everything built on disassembly still works. - Prebuilt binaries cover three platform pairs only — Linux x86_64, macOS arm64, Windows x86_64. Anything else means building from source.
- A binary is tied to one IDA installation. Mixing a 9.4 build with a non-9.4 runtime, or the reverse, is rejected before any database opens. Pointing
IDADIRat an installation other than the one the core library was loaded from is rejected at startup, before IDA is initialized at all. - Headless-only. There is no debugger surface and no GUI control;
force_guiis an error, not a fallback. - HTTP is authenticated, always. There is no anonymous mode, so a client that cannot send an
Authorizationheader cannot use this transport.
Docs
- docs/TOOLS.md — worker tool catalog
- docs/TRANSPORTS.md — stdio vs Streamable HTTP
- docs/BUILDING.md — build from source
- docs/TESTING.md — running tests
- docs/ARCHITECTURE.md — supervisor/worker design
- docs/MIGRATION.md — migrating from the old
ida-pro-mcp-compatible tool names
Attribution
Substantial portions of the IDA worker, MCP tool implementations, and build glue come from ida-mcp-rs by blacktop, MIT License.
The multi-database session model (idb_open / idb_list / idb_close plus a database argument on every analysis tool) follows ida-pro-mcp by Duncan Ogilvie and contributors, MIT License. This project no longer implements that project's tool contract; see docs/MIGRATION.md.
IDA bindings come from idalib (MIT OR Apache-2.0).
Full notices are in NOTICE.
License
Apache-2.0. Copyright (c) 2026 VibRev Developers.
The upstream portions listed above arrived under the MIT License and stay available under it; their notices are preserved in NOTICE as MIT requires.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found