MI

merozemory/ida-multi-mcp

Developer tools
466 stars 69 forks Quality 67 Trend 29

Multi-instance IDA Pro MCP server — analyze multiple binaries simultaneously through a single MCP endpoint.

Overview

Multi-instance IDA Pro MCP server for simultaneous reverse engineering of multiple binaries through a single MCP endpoint. Supports both GUI instances and headless analysis via idalib (IDA Pro only). - — locate the same or similar function within a binary or across instances (patch diffing, library-function ID, variant hunting). Name-independent signals that survive stripping — instruction-shingle MinHash + imported-API / string / constant anchors + CFG structure/shape — with an optional on-demand recall (jTrans embeddings) for cross-compiler twins. All local, no cloud. → details Analyze multiple binaries in parallel — dropper, payload, C2 — through a single MCP connection. Each IDA Pro instance auto-registers on startup; your LLM client sees every instance without touching its config. Copy-paste one of these prompts — it handles the Python version matching, IDA plugin placement, and MCP client registration for you.

README

ida-multi-mcp

Reverse-engineer several binaries at once — dropper, payload, C2 — through a single MCP endpoint. Each plugin-equipped IDA Pro database auto-registers when opened · headless idalib sessions · local, stripping-resistant function similarity across binaries.

Install · In action · Why · Upstream · Architecture · Tools · Docs


Install in one prompt

Ask your AI agent to install it. Copy-paste one of these — it matches IDA’s Python version, drops the plugin in place, and registers the MCP server with your client.

Claude Code / Codex:

Install and configure ida-multi-mcp by following the instructions here: https://raw.githubusercontent.com/MeroZemory/ida-multi-mcp/main/docs/installation.md

Cursor:

@Web fetch https://raw.githubusercontent.com/MeroZemory/ida-multi-mcp/main/docs/installation.md and follow the installation steps.

Then open your binaries in IDA Pro — instances register themselves — and talk to your agent. Prefer doing it by hand? See Manual installation. Removing it again is in Troubleshooting.


See it in action

Two binaries open in two IDA windows. One MCP endpoint. No client config per binary.

“Which function in dropper.dll is the same as sub_140001000 in malware.exe?”

→ list_instances()
  k7m2  malware.exe   x86_64  port 49152
  px3a  dropper.dll   x86_64  port 49153

→ analysis_wait(instance_id="px3a", timeout_sec=200)
  { "finished": true, "functions_added": 12884 }   # 12,884 functions that did not exist a minute ago

→ index_functions(instance_id="k7m2")   ·   index_functions(instance_id="px3a")
  { "indexed": 61044 }                      { "indexed": 73929 }

→ similar_functions(instance_id="k7m2", func="sub_140001000", scope="instances")
  0.94  px3a  sub_18000C120   high     minhash 0.91 · anchors 0.97 · cfg 0.88
  0.71  px3a  sub_18000E440   medium   minhash 0.68 · anchors 0.80 · cfg 0.64

→ decompile(instance_id="px3a", addr="sub_18000C120")
  ...

Core instruction, anchor and CFG signals do not use function names, so stripping does not remove them. When both functions have meaningful symbols, pseudocode identifier tokens can also contribute. Scoring and inference run locally; no binary or IDB is uploaded.


Why ida-multi-mcp


Built on ida-pro-mcp

The IDA tool implementations here come from ida-pro-mcp by Duncan Ogilvie (mrexodia), bundled as a package, periodically compared and selectively synchronized. That project is the foundation this one stands on, and fixes flow both ways.

What ida-multi-mcp adds on top:

  • a router that fronts N IDA processes behind one stdio endpoint, with instance_id routing and a worker pool
  • discovery through a shared file registry — the IDA plugin registers each GUI instance into ~/.ida-mcp/instances.json when a database opens, so the client needs no per-binary configuration
  • function similarity (BCSD) and compare_binaries for cross-binary work
  • auto-analysis gating (analysis_status / analysis_wait) so an agent can tell a partial answer from a complete one

Both projects now support working on several databases at once — upstream through its idalib-mcp supervisor, this one through registry-based discovery. Pick whichever fits your workflow. A running log of what has been adopted from upstream and what has been contributed back: docs/ida-pro-mcp/comparison.md.


Architecture at a glance

One stdio MCP server in front of N IDA processes. The router owns discovery, instance_id routing, health and the idalib lifecycle; the IDA tools themselves run inside each instance.

flowchart TD
    C["MCP clientClaude Code · Cursor · Codex …"]
    R["ida-multi-mcp routerdynamic tool discovery · instance_id routingworker pool · health · idalib lifecycle"]
    Reg[("~/.ida-mcp/instances.jsonshared registry")]
    G1["IDA #1 (GUI)malware.exe · k7m2"]
    G2["IDA #2 (GUI)dropper.dll · px3a"]
    H1["idalib #1 (headless)payload.bin · 9bf1"]

    C -- "stdio / MCP" --> R
    R -- "HTTP JSON-RPC" --> G1
    R -- "HTTP JSON-RPC" --> G2
    R -- "HTTP JSON-RPC" --> H1
    G1 -. "register after database opens" .-> Reg
    G2 -. "register after database opens" .-> Reg
    Reg -. "discovery" .-> R

Registry layout, request routing, health monitoring and the design trade-offs behind them: docs/architecture.md.


The one rule: wait for auto-analysis

On a freshly opened binary IDA analyses in the background, and function lists, xrefs and decompilation are incomplete until it settles. On an 8.5 MB DLL the function count went from 9,580 to 13,252 — 28% of the functions did not exist yet. On a 23 MB DLL it was 12,885.

analysis_status()               -> {"queue_empty": false, "function_count": 61044}
analysis_wait(timeout_sec=200)  -> {"finished": true, "functions_added": 12884}
  • analysis_status() — non-blocking snapshot: queue state, current phase, function count so far.
  • analysis_wait(timeout_sec=120) — drives analysis to completion and returns. finished: false means the wait timed out, not that it failed; call it again.

If you only do one thing, call analysis_wait once after opening a binary. The router also attaches a warning to results from analysis-dependent tools while an instance is still analysing, so a partial answer is not silently mistaken for a complete one.


Tool surface

Up to 76 tools through one router. The router combines a 61-tool static fallback with live schema refresh, plus 11 local tools and 4 more when idalib is available.

Area Tools
Triage survey_binary · binary_fingerprint · classify_functions · func_profile · analyze_function · analyze_component · analyze_batch
Navigation & listing list_funcs · lookup_funcs · func_query · list_globals · imports · imports_query · export_funcs
Decompile & disassemble decompile · decompile_to_file · disasm · basic_blocks
Cross-references xrefs_to · xrefs_from · xrefs_to_field · xref_query · callgraph · callees · trace_data_flow
Search find · find_bytes · find_regex · insn_query · search_structs
Types & stack declare_type · set_type · infer_types · enum_upsert · read_struct · stack_frame · declare_stack · delete_stack
Modify rename · set_comments · append_comments · define_func · define_code · undefine · patch · patch_asm · idb_save
Memory get_bytes · get_int · put_int · get_string · get_global_value · int_convert
Similarity (BCSD) index_functions · index_status · similar_functions · compare_functions
Multi-instance list_instances · server_health · server_warmup · refresh_tools · refresh_caches · compare_binaries · diff_before_after
Analysis gating analysis_status · analysis_wait · analysis_step
Headless (idalib) idalib_open · idalib_close · idalib_list · idalib_status
Escape hatch py_eval — arbitrary IDAPython, in-process

Renames, retypes and comments live in memory until idb_save(). Full signatures and parameters: docs/tools.md.

The bundled IDA-side server also defines 16 debugger tools behind its direct-endpoint ?ext=dbg gate; the central router does not advertise them.


Function similarity (BCSD)

Find the same or a similar function within a binary or across instances — patch diffing, library-function ID, variant hunting. The core signals are name-independent, so they survive stripping. When both functions have meaningful symbols, a conditional pseudocode identifier-token signal can also contribute:

  • instruction-shingle MinHash
  • IDF-weighted imported-API / string / constant anchors
  • CFG structure and shape
  • symbol-gated pseudocode tokens
  • optional local neural recall — on-demand jTrans embeddings for anchor-less cross-compiler twins

Scoring, indexes and neural inference stay local; no binary or IDB is uploaded. Neural mode downloads its model checkpoint on demand as described below.

index_functions(instance_id, rebuild=False)   # content-hash keyed, persisted to ~/.ida-mcp/index/, incremental
index_status(instance_id)                     # readiness, function count, staleness, background progress
similar_functions(instance_id, func, top_k=20, scope="binary"|"instances"|"all")
compare_functions(a, b)                       # direct pairwise, optionally across instances

Neural recall is opt-in: pip install ida-multi-mcp[neural] and IDA_MCP_SIM_NEURAL=1 (the model auto-downloads to ~/.ida-mcp/models/). Worked examples against stripped binaries: docs/function-similarity-usage.md.


Requirements

  • Python 3.11 or later
  • IDA Pro 8.5+ (9.1 or later recommended)

IDA 9.0 SP0 (build 240925) is not supported. That build shipped without func_t.get_name, func_t.get_prototype and tinfo_t.get_udm, which several tools call directly. Use IDA 9.0 SP1 (build 241217) or later.


Manual installation

Already used the prompt in Install in one prompt? Skip this section.

The canonical guide an AI agent should follow is docs/installation.md — platform packages, IDA Python matching, plugin setup, verification.

Supported MCP clients

Works with stdio-capable MCP clients. ida-multi-mcp --install configures every supported client it finds on your machine:

  • CLI — Claude Code, Codex, Gemini CLI, Copilot CLI, Amazon Q Developer CLI, Qwen Coder, Opencode, Crush, Factory Droid
  • IDE — Cursor, VS Code (Copilot), Windsurf, Zed, Kiro, Trae, Antigravity, Augment Code
  • Desktop — Claude Desktop, LM Studio, BoltAI, Perplexity
  • Editor extension — Cline, Roo Code, Kilo Code, Qodo Gen
  • Terminal — Warp

For anything not auto-detected, ida-multi-mcp --config prints the raw configuration JSON to paste in yourself.


Usage

Opening several binaries (GUI)

Open each binary in its own IDA Pro window. The plugin auto-loads (PLUGIN_FIX) and registers a 4-character instance ID — k7m2, px3a, 9bf1. That is the whole setup.

Skipping the load dialog. A new binary normally pops IDA’s “Load a new file” dialog, which blocks before the plugin is running — nothing on the MCP side can dismiss it. Launch IDA in autonomous mode to accept the defaults:

ida -A path/to/binary.exe

Targeting an instance

instance_id is required whenever two or more instances are registered, so concurrent agents cannot collide. With exactly one registered it may be omitted and that instance is selected automatically.

Decompile the main function in malware.exe (k7m2)

Decompile main in malware.exe (k7m2) and compare it with the entry point in dropper.dll (px3a)

Index malware.exe (k7m2) and dropper.dll (px3a), then find the function in dropper.dll
most similar to sub_140001000 in malware.exe

Headless analysis (IDA Pro only)

Requires an IDA Pro license. IDA Home and IDA Free do not ship idalib.

Use idalib_open to analyze /path/to/malware.exe headlessly

idalib_open(input_path=...) spawns a headless idalib process, waits for auto-analysis and returns an instance_id. From there analysis tools use the same routed interface; GUI- and debugger-dependent operations remain subject to headless IDA limitations. To pin a specific Python that has idapro installed:

ida-multi-mcp --idalib-python /path/to/python3.11

Listing registered instances

$ ida-multi-mcp --list
Registered IDA instances (3):

  k7m2
    Binary: malware.exe
    Path: C:/samples/malware.exe
    Arch: x86_64
    Port: 49152
    PID: 12345

  px3a
    Binary: dropper.dll
    Path: C:/samples/dropper.dll
    Arch: x86_64
    Port: 49153
    PID: 12346

  9bf1
    Binary: payload.exe
    Path: C:/samples/payload.exe
    Arch: x86
    Port: 49154
    PID: 12347

Learn more

I want to… Read
Install it properly, on any platform docs/installation.md
Look up a tool’s parameters docs/tools.md
Use the CLI (--list, --install, --uninstall, --config) docs/cli.md
Understand routing, the registry and health monitoring docs/architecture.md
Know what it costs on a huge binary docs/performance.md · docs/benchmark-report.md
Fix a plugin that will not load, or a Python mismatch docs/troubleshooting.md
See similarity search used on stripped binaries docs/function-similarity-usage.md
Know how this relates to upstream ida-pro-mcp docs/ida-pro-mcp/comparison.md

Limitations

  • Localhost only. The router binds loopback and refuses non-loopback instances; remote IDA instances are not supported.
  • stdio transport only. There is no HTTP/SSE endpoint for remote or containerized clients.
  • Headless (idalib) requires IDA Pro. IDA Home and IDA Free do not ship idalib.
  • Concurrency is across instances, not within one. IDA executes on a single main thread, so two calls to the same instance still queue.
  • Cancellation is not forwarded to IDA. notifications/cancelled reaches the router, but the router→IDA hop is a blocking HTTP request; the per-tool deadline is what bounds a runaway call.
  • Resources (as opposed to tools) require manual routing.

Changelog highlights


Contributing

Contributions welcome. Please keep changes:

  • Python 3.11+ compatible
  • cross-platform (Windows, macOS, Linux)
  • covered by tests for new behaviour

CI runs lint (F821/F811 — IDA modules cannot be imported in CI, so undefined names are otherwise invisible to pytest) and the test suite on Ubuntu, Windows and macOS against Python 3.11 and 3.12.

License

MIT

Acknowledgments

This project exists because of ida-pro-mcp by Duncan Ogilvie (mrexodia) — the IDA tool implementations are its work, and the multi-instance layer here is built on that foundation. See Built on ida-pro-mcp for the details, and docs/ida-pro-mcp/comparison.md for what has been adopted from upstream and what has been contributed back.

  • ida-pro-mcp — the upstream IDA MCP plugin this project forked its tool implementations from; now also ships a multi-session idalib-mcp supervisor (MIT)
  • Model Context Protocol — the protocol every client listed above speaks

Support

Open an issue — but check docs/troubleshooting.md first; plugin-not-loading and Python-version mismatch are common failure modes.

View the full README on GitHub

Install

This server does not publish a one-line install command.

Open the repository installation guide New to MCP? Start with the mcpskill.org guide →