Guidance for working in this repository.
IDA Pro MCP Server: exposes IDA Pro / idalib functionality to MCP clients.
Main pieces:
src/ida_pro_mcp/server.py: MCP server entrypointsrc/ida_pro_mcp/idalib_server.py: headless idalib serversrc/ida_pro_mcp/ida_mcp/: IDA/plugin-side APIs
Important API modules:
api_core.py: IDB metadata, functions, strings, importsapi_analysis.py: decompilation, disassembly, xrefs, paths, pattern searchapi_memory.py: bytes/ints/strings, patchingapi_types.py: structs, type inference, type applicationapi_modify.py: comments, renaming, asm patchingapi_stack.py: stack frame operationsapi_debug.py: debugger control, unsafe / low priority for testsapi_python.py: execute Python in IDA contextapi_resources.py:ida://MCP resources
All IDA SDK calls must run on the main thread. Use:
from .rpc import tool
from .sync import idasync
@tool
@idasync
def my_tool(...):
...- Prefer batch-first APIs.
- Many functions accept either a comma-separated string or a list.
- Use full type hints and
Annotated[...]descriptions. - The function docstring becomes the MCP tool description.
Example:
def my_api(addrs: Annotated[str, "Addresses (0x401000, main) or list"]) -> list[dict]:
...- Parse addresses with
parse_address() - Normalize batch input with
normalize_list_input()/normalize_dict_list() - Use shared pagination / filtering helpers from
utils.py
Debugger or destructive operations should be marked unsafe:
from .rpc import tool, unsafe
@unsafe
@tool
@idasync
def dangerous_op(...):
...uv run ida-pro-mcp
uv run ida-pro-mcp --transport http://127.0.0.1:8744/sse
uv run idalib-mcp --host 127.0.0.1 --port 8745 path/to/binary
uv run idalib-mcp --isolated-contexts --host 127.0.0.1 --port 8745 path/to/binary
uv run ida-pro-mcp --unsafeuv run mcp dev src/ida_pro_mcp/server.pyuv run ida-pro-mcp --install
uv run ida-pro-mcp --uninstallUse the headless test runner:
uv run ida-mcp-test tests/crackme03.elf -q
uv run ida-mcp-test tests/typed_fixture.elf -q
uv run ida-mcp-test tests/crackme03.elf -c api_analysis
uv run ida-mcp-test tests/typed_fixture.elf -p "*stack*"Notes:
- Use
uv run ... - Non-interactive output should show failures only plus a summary
- Binary-specific tests should use
@test(binary="...")with the executable basename
Measure coverage across both maintained fixtures:
uv run coverage erase
uv run coverage run -m ida_pro_mcp.test tests/crackme03.elf -q
uv run coverage run --append -m ida_pro_mcp.test tests/typed_fixture.elf -q
uv run coverage report --show-missingCurrent fixture intent:
tests/crackme03.elf: compact general regression fixturetests/typed_fixture.elf: typed globals / structs / locals / stack coverage fixture
- Prefer semantic assertions, not weak "field exists" checks
- Prefer round-trip tests for mutating APIs
- If tests expose clearly wrong API behavior, fix the API instead of weakening the test
- Focus on IDA-facing modules, not server/config plumbing
- Expect some IDA / Hex-Rays variance; guarded assertions or runtime skips are acceptable when justified
When adding generic tests, also try a non-fixture binary to avoid ELF-specific assumptions:
uv run ida-mcp-test "C:\CodeBlocks\x64dbg\bin\x64\x64dbg.dll" -qHigh priority:
api_analysis.pyapi_types.pyapi_modify.pyapi_stack.pyapi_memory.pyapi_core.pyapi_resources.pyutils.pyframework.py
Lower priority:
api_debug.py- MCP transport / hosting details
- install / config mutation logic
- Server/plugin Python: 3.11+
- IDA Pro 8.3+; 9.0 recommended
- IDA Free is not supported
- If IDA uses the wrong Python, use
idapyswitch