IDA Pro MCP Multi
Multi-instance IDA Pro MCP Server — simultaneous reverse engineering across multiple binaries with LLM-powered binary diffing, symbol porting, and patch discovery.
English | 中文
English
What is this?
IDA Pro MCP Multi is an enhanced fork of mrexodia/ida-pro-mcp that enables simultaneous analysis of multiple binaries through a single MCP (Model Context Protocol) connection. Connect Claude Code (or any MCP client) to two or more IDA Pro instances at once, and let the LLM cross-reference between them.
Why?
Reverse engineers frequently compare binary versions to:
- Port symbols & names from an older, symbolicated build to a newer, stripped one
- Discover patches between versions to understand what was fixed (or broken)
- Reproduce vulnerabilities by identifying the exact code changes in a security patch
- Diff malware variants to track evolution
Traditional Bindiff tools require manual inspection. With MCP Multi, Claude reads both binaries simultaneously and reasons about their differences in natural language.
Quick Start
# 1. Install
git clone https://github.com/Torebtr/ida-pro-mcp-multi.git
cd ida-pro-mcp-multi
pip install -e .
# 2. Install IDA plugin + configure Claude Code
python -m ida_pro_mcp --install claude-code
# 3. Open IDA #1 -> load binary v1 -> Ctrl+Alt+M
# 4. Open IDA #2 -> load binary v2 -> Ctrl+Alt+M
# 5. Restart Claude Code
In Claude Code:
# Enter multi-instance mode
multi_select(aliases=[
{"alias":"sym","host":"127.0.0.1","port":13337},
{"alias":"nosym","host":"127.0.0.1","port":13338}
])
# Use prefixed tools to target a specific instance
sym__decompile(addr="main")
nosym__decompile(addr="0x401000")
# Cross-instance analysis
multi_match_function(source_alias="sym", target_alias="nosym", addrs=["main"])
multi_port_names(source_alias="sym", target_alias="nosym", dry_run=False)
multi_diff_function(addr_a="main", addr_b="0x401000", alias_a="sym", alias_b="nosym")
multi_find_new_or_changed(reference_alias="sym", target_alias="nosym")
Multi-Instance Tools
| Tool | Description |
|---|
multi_select(aliases, primary?) | Register 2+ IDA instances and activate multi-instance mode |
multi_list_instances() | List registered aliases with reachability status |
multi_match_function(source_alias, target_alias, addrs) | Match functions across instances by byte-level signatures |
multi_port_names(source_alias, target_alias, addrs?, dry_run) | Copy function names from symbolicated to stripped binary |
multi_diff_function(addr_a, addr_b, alias_a, alias_b) | Side-by-side decompilation diff between two instances |
multi_find_new_or_changed(reference_alias, target_alias) | Find functions that are new or modified between versions |
After multi_select, all standard IDA tools are also available with <alias>__ prefix (e.g., sym__decompile, nosym__list_funcs), in addition to the unprefixed versions which route to the primary instance.
Architecture
Claude Code (stdio)
|
v
server.py (MCP proxy with multi-instance dispatch)
|
+-- tools/list -> fetches & prefixes tools from each instance (parallel)
+-- tools/call -> <alias>__<tool> routes to specific instance
|
+-- multi/manager.py -> per-session state (alias -> host:port)
+-- multi/router.py -> dispatch interception + parallel tool fetching
+-- multi/tools.py -> cross-instance analysis tools
|
+--> IDA #1 (127.0.0.1:13337) <- auto-discovered
+--> IDA #2 (127.0.0.1:13338) <- auto-discovered
Requirements
- Python 3.11+
- IDA Pro 8.3+ (9.0 recommended)
- IDA Free is not supported
Backward Compatibility
This fork is fully backward compatible with upstream ida-pro-mcp. If you never call multi_select, the server behaves exactly like the original -- single-instance mode with select_instance for switching.
Typical Workflows
Symbol Porting:
multi_select(aliases=[
{"alias":"old","host":"127.0.0.1","port":13337},
{"alias":"new","host":"127.0.0.1","port":13338}
])
# Preview first (no modifications)
multi_port_names(source_alias="old", target_alias="new", dry_run=True)
# Apply
multi_port_names(source_alias="old", target_alias="new", dry_run=False)
Patch Diffing:
# Find all changed functions
multi_find_new_or_changed(reference_alias="old", target_alias="new")
# Compare specific functions
multi_diff_function(addr_a="sub_1000", addr_b="0x401000", alias_a="old", alias_b="new")
Three-Way Diff:
multi_select(aliases=[
{"alias":"v1","host":"127.0.0.1","port":13337},
{"alias":"v2","host":"127.0.0.1","port":13338},
{"alias":"v3","host":"127.0.0.1","port":13339}
])
v1__decompile(addr="main")
v2__decompile(addr="0x401000")
v3__decompile(addr="0x402000")