IDA Pro MCP with REA: Connect Claude Code and Codex to IDA
On this page
REA, the open-source project by morluto, can use IDA Pro as its native analysis engine. It does this through mrexodia/ida-pro-mcp: REA connects to the ida-pro-mcp server you already run, calls a fixed set of read-only tools, and returns results as Evidence, in the same format its Ghidra and Hopper providers use.
Read this first, because it decides which version you install: in REA 6.4.0, the attached (GUI) mode only understands the legacy tools of ida-pro-mcp 1.4.0. The redesigned tools in ida-pro-mcp 2.0.0 are not compatible with that mode. This is tracked in REA issue #2301, which was still open when this article was written (checked through the GitHub API on 2026-10-13). Headless mode follows a different contract; details are below.
Who this is for: people who own an IDA Pro license and want Claude Code or Codex to read IDA’s analysis through REA.
What you will learn:
- What you need: IDA Pro 8.3+, Python 3.11+, ida-pro-mcp 1.4.0, REA 6.4.0
- How to write the registration file REA reads, for attached and headless modes
- Where to put
REA_IDA_MCP_CONFIGandREA_ANALYSIS_PROVIDERin Claude Code and Codex - Which REA operations work with IDA, and which fail and why
Example target: a small C program you compile yourself (source below).
Requirements and licensing
- IDA Pro 8.3 or newer, licensed. ida-pro-mcp’s README lists “IDA Pro (8.3 or higher, 9 recommended)” and states “IDA Free is not supported”. REA does not install, activate or license IDA. Use a copy you obtained from Hex-Rays under its license terms.
- IDA Free does not work with REA 6.4.0 either. REA’s repository
maindocuments an optional separate native bridge that can work with IDA Free, but its"protocol": "native"registration is not in the 6.4.0 package: the 6.4.0 registration schema rejects unknown keys. Wait for a release that includes it. - Python 3.11+ for ida-pro-mcp.
- REA 6.4.0, registered with your agent through
npx rea-agents setup(getting started). - For headless mode: IDA Pro with idalib (IDA 9.x), activated as described in the ida-pro-mcp README.
Only analyze binaries you are allowed to analyze. REA’s DISCLAIMER.md explains the boundaries.
Version compatibility in REA 6.4.0
REA 6.4.0 checks the tool list the upstream server returns before it runs anything. Each mode expects one profile:
| REA mode | Upstream tools REA requires | Works with | Status |
|---|---|---|---|
attached (default) |
1.4 legacy: get_metadata, list_functions, list_strings, get_function_by_name, get_function_by_address, decompile_function, disassemble_function, get_callers, get_callees, get_xrefs_to |
ida-pro-mcp 1.4.0 GUI plugin | Supported |
attached |
(2.0.0 GUI plugin exposes lookup_funcs, decompile, disasm and others instead) |
ida-pro-mcp 2.0.0 | Not compatible (#2301) |
headless |
Database supervisor: idb_open, idb_list, idb_close, server_health, list_funcs, lookup_funcs, find_regex, decompile, disasm, callees, xrefs_to |
idalib-mcp with the supervisor API |
Narrow: see below |
About headless mode: the 1.4.0 idalib-mcp does not have the supervisor API at all. The supervisor exists only on the upstream development branch, whose pyproject.toml says 2.0.0. The #2301 thread shows that 2.0.0 builds made before upstream PR #495 lack idb_close and fail. REA’s IDA provider docs record headless verification against one upstream commit, c133c3853faa111a9b00ee615c013b720d0c4acd, on Windows x64 (IDA 9.3) and macOS arm64 (IDA Pro 9.1). Linux headless operation is listed as not yet verified. Treat headless as experimental and pinned to that commit. For the path REA 6.4.0 documents as supported, use attached mode with 1.4.0.
Why this matters in practice: upstream’s README tells you to pip install from the GitHub main archive, and today that gives you 2.0.0. Follow those instructions as written and attached mode will fail.
Step 1: Build a test target
Use something small that you compiled, so you know the right answer:
// check.c
#include <stdio.h>
#include <string.h>
static int check_key(const char *s) {
if (strlen(s) != 8) return 0;
int sum = 0;
for (int i = 0; i < 8; i++) sum += s[i] ^ 0x5A;
return sum == 0x2F0;
}
int main(int argc, char **argv) {
if (argc < 2) { puts("usage: check KEY"); return 1; }
puts(check_key(argv[1]) ? "ok" : "bad key");
return 0;
}
cc -O0 -g -o check check.c
shasum -a 256 check
Why: REA binds every result to the input file’s SHA-256. In attached mode it compares that hash with the input hash IDA recorded, so you need to know exactly which file you opened. On macOS, C symbols carry a leading underscore, so the function names become _main and _check_key.
Step 2: Install ida-pro-mcp 1.4.0 (attached mode)
Install the tagged 1.4.0 release from PyPI, not the GitHub main archive:
python3 -m pip install "ida-pro-mcp==1.4.0" "mcp<2"
ida-pro-mcp --install
Why pin mcp<2: ida-pro-mcp 1.4.0 declares mcp>=1.16.0, which allows version 2 of the Python MCP SDK. The workaround in #2301 reports that the 1.4 proxy’s server.py fails to import under the 2.x SDK, so the pin keeps it on 1.x.
--install copies the IDA plugin and registers ida-pro-mcp with the MCP clients it knows. Restart IDA afterwards.
Then open the original binary (check) in IDA Pro, let auto-analysis finish, and start the plugin with Edit → Plugins → MCP (hotkey Ctrl-Alt-M in 1.4.0). The plugin listens on 127.0.0.1:13337.
If you already have 2.0.0 installed, the #2301 reporter notes that the 1.4.0 plugin file is self-contained and can sit next to a 2.0.0 install; the 1.4 plugin hard-codes its address and port, so a second instance needs those edited.
Step 3: Write the registration file REA reads
REA does not talk to IDA’s port directly. It launches ida-pro-mcp’s stdio proxy (server.py), which forwards to the plugin. Get the exact interpreter and script path from:
ida-pro-mcp --config
That prints an mcpServers → ida-pro-mcp entry with command, args, timeout and disabled. Copy only command, args (and env, if present) into a new file, for example ~/ida/ida-mcp.json:
{
"mode": "attached",
"command": "/absolute/path/to/python3",
"args": [
"/absolute/path/to/site-packages/ida_pro_mcp/server.py",
"--ida-rpc",
"http://127.0.0.1:13337"
]
}
Why not paste the output as is: REA 6.4.0 validates this file strictly. A stdio registration accepts command, args, env, type, mode, timeoutMs and workspaceRoot. A local HTTP registration replaces command/args/env with a loopback url and optional headers, and accepts the same type, mode, timeoutMs and workspaceRoot. Any other key, including timeout and disabled from --config, makes the file invalid. A wrapping {"mcpServers": {"ida-pro-mcp": {...}}} object is accepted, but the inner entry is checked just as strictly.
Optional keys:
"timeoutMs": per-request deadline for upstream calls, default300000."mode":"attached"is the default; it is written out here for clarity.
The file must be at most 64 KiB (65,536 bytes), and REA_IDA_MCP_CONFIG must be an absolute path.
Step 4: Run it from the CLI
export REA_IDA_MCP_CONFIG="$HOME/ida/ida-mcp.json"
export REA_ANALYSIS_PROVIDER=ida
rea doctor --provider ida --json
rea search /absolute/path/check "bad key" --json
rea function /absolute/path/check check_key --json
rea decompile /absolute/path/check check_key --json
Use --provider ida on a single command instead of REA_ANALYSIS_PROVIDER if you also use Ghidra.
What each step proves:
doctor --provider idaonly validates the registration file. It does not launch IDA or check upstream compatibility (#2301 points out that it reports healthy even against 2.0.0).- The first real command connects, compares the tool list with the attached profile, and checks that IDA’s recorded input SHA-256 matches
check. REA repeats the identity and image-base check around every request. functionreturns a complete function dossier;decompilereturns pseudocode only.
xrefs with IDA needs an explicit hexadecimal address (rea xrefs /absolute/path/check 0x...), not a symbol name.
Step 5: Connect Claude Code and Codex
Add the two variables to the REA server entry, not to the ida-pro-mcp entry. If REA_IDA_MCP_CONFIG is set in your shell and points to a valid registration file when you run npx rea-agents setup --client claude_code, setup carries it into the registration; REA_ANALYSIS_PROVIDER you add by hand. Setup keeps existing env values when you rerun it.
Claude Code (~/.claude.json, inside the existing rea entry):
"env": {
"REA_IDA_MCP_CONFIG": "/Users/you/ida/ida-mcp.json",
"REA_ANALYSIS_PROVIDER": "ida"
}
Codex (~/.codex/config.toml):
[mcp_servers.rea.env]
REA_IDA_MCP_CONFIG = "/home/you/ida/ida-mcp.json"
REA_ANALYSIS_PROVIDER = "ida"
Restart the client completely. Opening a target waits on IDA, and in headless mode on auto-analysis, so give the client a generous tool deadline. In Codex that is tool_timeout_sec under [mcp_servers.rea]; in Claude Code the MCP_TOOL_TIMEOUT environment variable (milliseconds). Both are client settings, so check your client’s documentation for current defaults.
If ida-pro-mcp’s own --install also registered it in Claude Code, you now have two IDA-related servers. That works, but tell the agent which one to use, because both expose decompile-style tools.
Prompts that work
If you leave REA_ANALYSIS_PROVIDER unset, ask the agent to open the target with provider_id: "ida":
Use REA. Open /absolute/path/check with open_binary and provider_id "ida".
Find the function that decides whether a key is valid, decompile it, and
explain the condition in plain terms. Quote addresses for every claim and
list anything the IDA adapter reported as unknown. Close the binary when done.
With REA's IDA provider, search strings in /absolute/path/check for "key",
find which function references that string (use xrefs with the string's
address), and show that function's callees.
Why open and close explicitly: open_binary starts the provider session and close_binary releases it. In attached mode, closing only drops REA’s MCP connection; it never saves or closes your IDA database.
For a general prompt structure, see Claude Code Reverse Engineering Skill.
Headless mode in 6.4.0
Headless mode lets REA open its own IDA database without the GUI. The registration looks like this:
{
"mode": "headless",
"command": "idalib-mcp",
"args": ["--stdio", "--max-workers", "1"]
}
Add "env": {"IDADIR": "/absolute/path/to/ida"} if your idalib setup needs it, and optionally "workspaceRoot": "/absolute/existing/tmp/dir". A local Streamable HTTP supervisor can use "url": "http://127.0.0.1:8745/mcp" instead of command. REA only accepts localhost, 127.0.0.1 or [::1] URLs without credentials.
What REA does in this mode:
- Copies the binary into a private temporary directory and re-checks its SHA-256.
- Calls
idb_openwithforce_headlessand its own session ID, then confirms throughidb_listthat it owns an active worker for that copy. - Refuses to run analysis until
server_healthreports auto-analysis is ready. - On close, calls
idb_closewithsave: false, confirms the worker is gone, and deletes the copy.
Your original file is never modified. Requirements and limits:
- The supervisor must provide
idb_close(see the compatibility table). This is the part that 2.0.0 builds made before upstream PR #495 lack. - REA and the supervisor must share the same filesystem and path syntax: run both on Windows, or both on the same Unix host.
procedure_callers(direct callers) is unavailable in headless mode, because the modern tools do not prove direct call edges. Usexrefson the function address instead.
What works with IDA, and what does not
REA’s IDA adapter declares these read-only operations: list and search procedures and strings, resolve a procedure address, pseudocode, assembly, raw function instructions, callers (attached only), callees, xrefs, and the analyze_function dossier.
It does not cover:
rea analyze/rea inspect/ MCPbinary_overview. These need segment and document listings that the IDA adapter doesn’t declare, so they fail withcapability_unavailable(#2460, open). Start fromsearch,functionordecompileinstead..idb/.i64files. REA admits executables only. Open the original input.- MIPS targets. REA’s IDA adapter has no verified MIPS lane; use a Ghidra profile.
- Renaming, patching, types, debugging or arbitrary IDAPython. The adapter is read-only by design.
Results are live: they describe the current IDA database. REA records the database state before and after a request, but cannot prove the database is unpatched.
Troubleshooting
unreadable_output / “Analysis returned an unreadable result” right after connecting. The most likely cause is a profile mismatch, such as a 2.0.0 GUI plugin behind attached mode. #2301 reports that the CLI shows only this generic error while the internal message names the missing tools. Check pip show ida-pro-mcp and install 1.4.0.
“REA_IDA_MCP_CONFIG must contain an IDA MCP command/args or local url registration”. The JSON has extra keys (often timeout or disabled from --config), or the URL isn’t loopback. Strip it down to the keys listed in Step 3.
“The attached IDA input SHA-256 does not match the selected target”. IDA has a different file open, or you passed a copy whose bytes differ. Open the exact file in IDA, or pass the path IDA loaded.
“IDA MCP integration admits executable inputs, not analysis databases”. You passed an .i64 or .idb. Pass the original binary.
“IDA auto-analysis is incomplete or readiness is unknown”. Headless worker still analyzing. Retry once analysis finishes; raise timeoutMs for large binaries.
ImportError for FastMCP when the proxy starts. The 1.4 proxy is running under the 2.x Python MCP SDK. Reinstall with "mcp<2".
Port 13337 already in use. Another IDA instance is running the plugin. Close it, or follow the #2301 note about editing the 1.4 plugin’s port for a second instance.
rea doctor is healthy but nothing works. Expected: doctor checks the file only. The first analysis call is the real compatibility test.
Next steps
- How REA’s approach differs from running ida-pro-mcp directly: /en/rea-vs-ghidramcp-ida-pro-mcp/
- The free alternative engine, and comparing its Evidence with IDA’s on the same function: /en/rea-ghidra-native-binary/
- Prompt templates for agents: /en/claude-code-reverse-engineering-skill/
- Practice on CTF binaries: /en/ctf-reverse-engineering-ai-agent/
- Reference: ida-provider.md (repository
main, which can be ahead of 6.4.0), issue #2301