# Ida Headless Mcp

> Rust-native, multi-session headless IDA Pro MCP server with isolated workers and stdio or Streamable HTTP transports.

- **Type:** MCP server
- **Install:** `agentstack add mcp-vibrev-ida-headless-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [VibRev](https://agentstack.voostack.com/s/vibrev)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [VibRev](https://github.com/VibRev)
- **Source:** https://github.com/VibRev/ida-headless-mcp

## Install

```sh
agentstack add mcp-vibrev-ida-headless-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# ida-headless-mcp

English | [简体中文](README.zh-CN.md)

Rust-native, multi-session headless [IDA Pro](https://hex-rays.com/ida-pro) MCP server.

This project is a derivative of [blacktop/ida-mcp-rs](https://github.com/blacktop/ida-mcp-rs), rewritten around an explicit supervisor/worker split and pinned to the [mrexodia/ida-pro-mcp](https://github.com/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.

[](LICENSE)

## 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 a `database` session 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](docs/ARCHITECTURE.md) and [docs/MIGRATION.md](docs/MIGRATION.md).

## Prerequisites

- IDA Pro 9.2, 9.3, or 9.4 with a valid license
- Rust (source builds only) — `rust-toolchain.toml` pins the exact version and
  rustup installs it for you. `Cargo.toml` declares 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:

1. **Prebuilt archive.** Download from [Releases](https://github.com/fuqiuluo/ida-headless-mcp/releases), verify against `checksums.txt`, and put the executable on your `PATH`.
2. **Build from source** (below) — the only option for any other platform or architecture.

Archives are named `ida-headless-mcp__ida-__`, with `.tar.gz` on Unix and `.zip` on Windows. `` 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](docs/BUILDING.md). Each IDA minor has its own manifest; pick exactly one:

```bash
# 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-local
`sdk/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](docs/BUILDING.md).

`just --list` shows the repo's build and test recipes; [docs/TESTING.md](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` |

```bash
# Linux / macOS
export IDADIR=/path/to/ida
./target/release/ida-headless-mcp
```

```powershell
# 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](#streamable-http).) After the binary is on `PATH` (or use the absolute path):

### Claude Code

```bash
claude mcp add ida -- ida-headless-mcp serve --mode stdio
```

### Codex CLI

```bash
codex mcp add ida -- ida-headless-mcp serve --mode stdio
```

### Cursor

Add to `.cursor/mcp.json`:

```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: "", offset: 0, limit: 20)
find_string(database: "", query: "libc")
disasm(database: "", address: "0x100000f00")
xrefs_to(database: "", address: "0x100000f00")
decompile(database: "", address: "0x100000f00")
idb_close(database: "")
```

Notes that save a round trip:

- `input_path` may 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.
- A leading `~/` is expanded from `$HOME` (and `%USERPROFILE%` on Windows, where `~\` also works). Everything else is resolved against the server's working directory, which is the client's, not yours, when the client spawns it — absolute paths are the safe habit.
- Sessions are reaped after `idle_ttl_sec` seconds idle (default 600); pass `0` to disable.
- `idb_open` takes a `mode`: `prefer_headless` (default), `force_headless`, and `prefer_gui` all yield a headless worker; `force_gui` returns 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_WORKERS` is the env spelling.
- `server_health` reports 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](docs/MIGRATION.md).

### Streamable HTTP

```bash
./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:

```jsonc
"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](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:

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

- `--toolsets` keeps only the named categories: `core`, `functions`, `disassembly`, `decompile`, `xrefs`, `control_flow`, `memory`, `search`, `metadata`, `types`, `editing`, `scripting`.
- `--tools` adds individual tools back on top of `--toolsets`.
- `--exclude-tools` removes tools; exclusion always wins.
- `--read-only` keeps only tools that declare `readOnlyHint`, 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:

```bash
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_after` and the pseudocode part of `analyze_function` cannot 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 `IDADIR` at 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_gui` is an error, not a fallback.
- **HTTP is authenticated, always.** There is no anonymous mode, so a client that cannot send an `Authorization` header cannot use this transport.

## Docs

- [docs/TOOLS.md](docs/TOOLS.md) — worker tool catalog
- [docs/TRANSPORTS.md](docs/TRANSPORTS.md) — stdio vs Streamable HTTP
- [docs/BUILDING.md](docs/BUILDING.md) — build from source
- [docs/TESTING.md](docs/TESTING.md) — running tests
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — supervisor/worker design
- [docs/MIGRATION.md](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](https://github.com/blacktop/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](https://github.com/mrexodia/ida-pro-mcp) by **Duncan Ogilvie** and contributors, MIT License. This project no longer implements that project's tool contract; see [docs/MIGRATION.md](docs/MIGRATION.md).

IDA bindings come from [idalib](https://github.com/blacktop/idalib) (`MIT OR Apache-2.0`).

Full notices are in [NOTICE](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](NOTICE) as MIT requires.

See [LICENSE](LICENSE) and [NOTICE](NOTICE).

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [VibRev](https://github.com/VibRev)
- **Source:** [VibRev/ida-headless-mcp](https://github.com/VibRev/ida-headless-mcp)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-vibrev-ida-headless-mcp
- Seller: https://agentstack.voostack.com/s/vibrev
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
