Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/mrexodia/ida-pro-mcp/llms.txt

Use this file to discover all available pages before exploring further.

IDA Pro MCP is built on a two-process architecture. An MCP server process receives requests from clients over a configurable transport, then proxies or routes those requests to a second process that has access to the IDA SDK — either a running GUI instance of IDA Pro with the plugin loaded, or a headless idalib worker. This separation keeps the MCP transport layer free of IDA dependencies and allows the same server code to front multiple open databases.

Top-level components

server.py

MCP server entrypoint for the GUI plugin mode. Runs as a standalone process, discovers running IDA GUI instances, and proxies JSON-RPC requests to them over HTTP.

idalib_supervisor.py

Headless idalib entry point (idalib-mcp). Manages a pool of idalib worker subprocesses — one per open database — and routes each tool call to the correct worker.

idalib_server.py

Per-database idalib worker. Imports idalib, loads one binary, and handles tool calls forwarded from the supervisor. Not invoked directly.

ida_mcp/

IDA plugin-side code shared by both the GUI plugin and the idalib workers. Contains all tool implementations, the RPC registry, sync utilities, and the zeromcp transport layer.

API modules

All tools are implemented in src/ida_pro_mcp/ida_mcp/api_*.py. Each file owns a coherent slice of IDA functionality:

api_core.py

IDB metadata, function listing, string search, imports, integer conversion

api_analysis.py

Decompilation, disassembly, cross-references, call graphs, pattern and instruction search, basic blocks

api_memory.py

Raw byte reads and writes, integer reads and writes, string reads, memory patching

api_types.py

Struct definitions, type inference, type application, type export

api_modify.py

Comments, renaming functions/globals/locals, assembly patching

api_stack.py

Stack frame inspection, stack variable declaration and deletion

api_resources.py

ida:// MCP resources — browsable, read-only IDB state exposed as URIs

api_debug.py

Debugger control, breakpoints, registers, memory. All tools are marked @unsafe and hidden by default.

api_python.py

py_eval — executes arbitrary Python in the IDA context

api_sigmaker.py

Signature creation, scanning, and xref-based signature generation

Transport modes

The MCP server supports three transports selectable at startup:
ModeCommandUse case
stdiouv run idalib-mcp --stdio path/to/binarySingle-binary clients such as Claude Code
SSEuv run ida-pro-mcp --transport http://127.0.0.1:8744/sseLong-lived connections from GUI clients
Streamable HTTPuv run idalib-mcp --host 127.0.0.1 --port 8745Multi-client headless setups
With --isolated-contexts, each transport connection gets its own database binding, preventing one agent from changing another’s active database. Strict Mcp-Session-Id semantics are enforced for Streamable HTTP under this mode.

Plugin mode vs. idalib mode

GUI plugin mode

The ida-pro-mcp command connects to an already-running IDA Pro instance with the plugin installed. The plugin registers an HTTP server on port 13337 inside IDA. server.py discovers running instances and proxies requests to them. Changes are visible immediately in the GUI.

Headless idalib mode

The idalib-mcp command spawns worker subprocesses that each import idalib directly. No GUI is required. Multiple databases can be open simultaneously, each in its own worker, managed by the supervisor’s session model.
The GUI plugin mode is no longer the recommended approach and will eventually be deprecated. Use idalib-mcp for all new integrations.

zeromcp

The ida_mcp/zeromcp/ directory contains a vendored, minimal MCP transport layer. It provides McpServer, McpRpcRegistry, McpHttpRequestHandler, and related JSON-RPC primitives. The supervisor imports it without loading the rest of ida_mcp/ — specifically to avoid importing IDAPython modules at supervisor startup.

IDA thread safety model

IDA’s SDK is not thread-safe. All calls to IDA APIs must happen on the IDA main thread. Every tool function is annotated with @idasync, which wraps the function body in idaapi.execute_sync(..., MFF_WRITE):
from .rpc import tool
from .sync import idasync

@tool
@idasync
def my_tool(...):
    # This body runs on the IDA main thread
    ...
idasync also enables batch mode (idc.batch(1)) for the duration of the call to suppress interactive dialogs, and installs a profile hook that enforces the per-tool timeout (default 60 seconds, overridable via IDA_MCP_TOOL_TIMEOUT_SEC). Reentrant @idasync calls from within a tool body are detected and raise an error immediately.

Build docs developers (and LLMs) love