Headless IDA Pro MCP server using idalib
Project description
IDA MCP Server
A headless IDA Pro MCP server built on idalib. Exposes IDA Pro's binary analysis capabilities over the Model Context Protocol (MCP), letting LLMs drive IDA Pro for reverse engineering tasks. Supports multiple simultaneous databases through a supervisor/worker architecture.
This is a standalone server, not an IDA plugin. It uses idalib (IDA as a library) to run IDA's analysis engine without a GUI — no IDA GUI needs to be running. IDA Pro 9+ must be installed on the same machine.
Requirements
- IDA Pro 9+ with a valid license (including Hex-Rays decompiler for decompilation tools)
- Python 3.12+
- uv package manager (recommended) or pip
- macOS, Windows, or Linux
Installation
uv tool install ida-mcp
Or with pip:
pip install ida-mcp
The idapro package is loaded at runtime directly from your local IDA Pro installation — no extra setup steps or environment variables are needed if IDA is installed in a standard location.
From source
git clone https://github.com/jtsylve/ida-mcp && cd ida-mcp
uv sync
Or with pip:
git clone https://github.com/jtsylve/ida-mcp && cd ida-mcp
pip install -e .
Finding IDA Pro
At startup, the server looks for your IDA Pro installation in the following order:
IDADIRenvironment variable — checked first; set this if IDA is in a non-standard location.- IDA's own config file —
Paths.ida-install-dirin~/.idapro/ida-config.json(macOS/Linux) or%APPDATA%\Hex-Rays\IDA Pro\ida-config.json(Windows). If theIDAUSRenvironment variable is set, it is used as the config directory instead. This is the same config file IDA itself uses. - Platform-specific default paths:
| Platform | Default search paths |
|---|---|
| macOS | /Applications/IDA Professional *.app/Contents/MacOS |
| Windows | C:\Program Files\IDA Professional 9.3, C:\Program Files\IDA Pro 9.3, and their Program Files (x86) equivalents |
| Linux | /opt/ida-pro-9.3, /opt/idapro-9.3, /opt/ida-9.3, ~/ida-pro-9.3, ~/idapro-9.3 |
If the server can't find IDA, you'll get a clear error message telling you to set IDADIR.
Usage
Running the server
uvx ida-mcp
Or if installed with pip:
ida-mcp
The server uses a persistent HTTP daemon behind the scenes. The default mode runs a stdio proxy that auto-spawns this daemon, handling port allocation and authentication transparently. Workers and database state persist across client reconnections. The daemon shuts down automatically after 5 minutes of inactivity (configurable via IDA_MCP_IDLE_TIMEOUT).
| Command | Description |
|---|---|
ida-mcp (or ida-mcp proxy) |
Stdio proxy that auto-spawns a persistent HTTP daemon (default) |
ida-mcp serve |
Start the HTTP daemon directly (for manual daemon management) |
ida-mcp stop |
Gracefully shut down a running daemon |
ida-mcp stdio |
Direct stdio mode — single-session, workers die on disconnect |
Running without installing
You can run the server without installing it first:
# uv
IDADIR=/path/to/ida uvx ida-mcp
# pipx (set IDADIR if IDA isn't in a standard location)
IDADIR=/path/to/ida pipx run ida-mcp
# uv
$env:IDADIR = "C:\Program Files\IDA Professional 9.3"
uvx ida-mcp
# pipx (set IDADIR if IDA isn't in a standard location)
$env:IDADIR = "C:\Program Files\IDA Professional 9.3"
pipx run ida-mcp
MCP client configuration
Add to your MCP client config (e.g. Claude Desktop claude_desktop_config.json):
{
"mcpServers": {
"ida": {
"command": "uvx",
"args": ["ida-mcp"]
}
}
}
This runs the stdio proxy, which auto-spawns the persistent HTTP daemon in the background. The proxy handles port allocation and authentication automatically — no manual daemon management required.
If you don't use uv, use ida-mcp directly (assuming it's installed and on your PATH):
{
"mcpServers": {
"ida": {
"command": "ida-mcp"
}
}
}
If ida-mcp isn't on your PATH (e.g. installed into a pyenv or virtualenv), use the full path to the executable:
{
"mcpServers": {
"ida": {
"command": "/home/user/.pyenv/versions/<version>/bin/ida-mcp"
}
}
}
On macOS, the path would typically be /Users/<you>/.pyenv/versions/<version>/bin/ida-mcp.
If IDA is not in a default location, add IDADIR via the env key:
{
"mcpServers": {
"ida": {
"command": "uvx",
"args": ["ida-mcp"],
"env": {
"IDADIR": "/path/to/ida"
}
}
}
}
Connecting to a running daemon directly:
If you started the daemon manually with ida-mcp serve, the connection details (host, port, bearer token) are in the state file (~/Library/Application Support/ida-mcp/daemon.json on macOS). Clients that support streamable HTTP can connect directly:
{
"mcpServers": {
"ida": {
"type": "streamable-http",
"url": "http://127.0.0.1:<port>/mcp",
"headers": {
"Authorization": "Bearer <token>"
}
}
}
}
Basic workflow
- Open a binary — call
open_databasewith the path to a binary or an existing.i64/.idbdatabase, thenwait_for_analysisto block until it is ready - Analyze — use the available tools (list functions, decompile, search strings, read bytes, etc.)
- Close — call
close_databasewhen done (auto-saves by default)
Raw binaries must be in a writable directory since IDA creates a .i64 database file alongside them. When opening an existing database, the original binary does not need to be present.
Multi-database mode
Multiple databases can be open at the same time. By default, open_database keeps previously opened databases open. Pass keep_open=False to save and close databases owned by the current session before opening the new one. All tools except management tools (open_database, close_database, save_database, list_databases, wait_for_analysis, list_targets) require the database parameter (the stem ID returned by open_database or list_databases).
open_database("first.bin") # spawns worker (returns immediately)
wait_for_analysis(database="first") # blocks until ready
open_database("second.bin") # spawns second worker
wait_for_analysis(database="second") # blocks until ready
decompile_function(address="main", database="first") # targets first
close_database(database="second") # closes second
Environment variables
| Variable | Default | Description |
|---|---|---|
IDADIR |
(auto-detected) | Path to IDA Pro installation directory |
IDA_MCP_MAX_WORKERS |
(unlimited) | Maximum simultaneous databases (clamped to 1-8 when set) |
IDA_MCP_ALLOW_SCRIPTS |
(unset) | Set to 1, true, or yes to enable the run_script tool for arbitrary IDAPython execution |
IDA_MCP_LOG_LEVEL |
WARNING |
Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL) — output goes to stderr |
IDA_MCP_LOG_DIR |
(unset) | Directory for per-run log files. Supervisor Python logs go to <dir>/<run_id>-supervisor.log, each worker's Python logs to <dir>/<run_id>-worker-<db>.log, and each worker's raw stderr (catching pre-logging output and C-level crashes) to <dir>/<run_id>-worker-<db>.stderr. When unset, logs go only to stderr. |
IDA_MCP_IDLE_TIMEOUT |
300 |
Idle auto-shutdown timeout in seconds for auto-spawned daemons. Set to 0 to disable. ida-mcp serve defaults to 0 (use --idle-timeout=N to override). |
IDA_MCP_DISABLE_EXECUTE |
(unset) | Set to 1, true, yes, or on to hide the execute meta-tool (sandboxed Python code mode) |
IDA_MCP_DISABLE_BATCH |
(unset) | Set to 1, true, yes, or on to hide the batch meta-tool |
IDA_MCP_DISABLE_TOOL_SEARCH |
(unset) | Set to 1, true, yes, or on to disable server-side progressive tool disclosure — all tools become directly visible and callable, and the search_tools and get_schema meta-tools are removed. Useful with clients that provide their own tool deferral (e.g. Claude Code). |
Tools
To keep token usage manageable, only common analysis tools and management tools are directly visible to clients. The rest are discoverable and callable through meta-tools:
search_tools— regex search over non-pinned tool names, descriptions, and tags (pinned tools are already visible).get_schema— parameter schemas and return shapes for tools by name.call— lightweight proxy for calling any tool by name, including hidden tools not in the client tool list.execute— sandboxed Python that chains multipleawait invoke(name, params)calls in a single round trip. Supportsasyncio.gatherfor parallel queries, loops, and conditional logic between calls.batch— sequential multi-tool execution with per-item error collection and progress reporting (up to 50 operations per call).
Management tools (open_database, close_database, save_database, list_databases, wait_for_analysis, list_targets) are always visible. Most must be called directly — save_database and list_databases are the exceptions, allowed through execute and batch for use in multi-step workflows.
The full tool catalog spans these areas:
- Database — open/close/save/list databases, file region mapping, metadata
- Functions — list, query, decompile, disassemble, rename, prototypes, chunks, stack frames
- Decompiler — pseudocode variable renaming/retyping, decompiler comments, microcode
- Ctree — Hex-Rays AST exploration and pattern matching
- Cross-References — xref queries, call graphs, xref creation/deletion
- Imports & Exports — imported functions, exported symbols, entry point listing and manipulation
- Search — string extraction, byte patterns, text in disassembly, immediate values, string-to-code references, string list rebuilding
- Types & Structures — local types, structs, enums, type parsing and application, source declarations
- Instructions & Operands — decode instructions, resolve operand values, change operand display format
- Control Flow — basic blocks, CFG edges, switch/jump tables
- Data — raw byte reading, hex dumps, segment listing, pointer tables
- Patching — byte patching, instruction assembly, function/code creation, data loading
- Data Definition — define bytes, words, dwords, qwords, floats, doubles, strings, and arrays
- Segments — create, modify, and rebase segments
- Names & Comments — rename addresses, manage comments (get, set, and append)
- Demangling — C++ symbol name demangling
- Analysis — auto-analysis, fixups, exception handlers, segment registers
- Address Metadata — source line numbers, analysis flags, library item marking
- Register Tracking — register and stack pointer value tracking
- Register Variables — register-to-name mappings within functions
- Signatures — FLIRT signatures, type libraries, IDS modules
- Export — batch decompilation/disassembly, output file generation, executable rebuilding
- Snapshots — take, list, and restore database snapshots
- Processor — architecture info, register names, instruction classification
- Bookmarks — marked-position management
- Colors — address/function coloring
- Undo — undo/redo operations
- Directory Tree — IDA folder organization
- Utility — number conversion, IDC evaluation, scripting
All tools include MCP annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) so clients can distinguish safe reads from mutations and prompt for confirmation on destructive operations. Mutation tools return old values alongside new values for change tracking.
See docs/tools.md for the complete tools reference.
Resources
The server exposes MCP resources — read-only, cacheable endpoints for structured database context:
- Static binary data — imports, exports, entry points (with regex search variants)
- Aggregate snapshot — statistics (function/segment/entry point/string/name counts, code coverage)
- Supervisor —
ida://databaseslists all open databases with worker state
Prompts
The server provides MCP prompts — guided workflow templates that instruct the LLM to use tools in a structured sequence:
survey_binary— binary triage producing an executive summaryanalyze_function— full single-function analysis with decompilation, data flow, and behavior summarydiff_before_after— preview the effect of renaming/retyping on decompiler outputclassify_functions— categorize functions by behavioral patternfind_crypto_constants— scan for known cryptographic constantsauto_rename_strings— suggest function renames based on string referencesapply_abi— apply known ABI type information to identified functionsexport_idc_script— generate an IDAPython script that reproduces user annotations
Architecture
See docs/architecture.md for detailed architecture documentation.
Development
# With uv (recommended)
uv sync # Install dependencies
uv run ruff check src/ # Lint
uv run ruff format src/ # Format
uv run ruff check --fix src/ # Lint with auto-fix
# With pip
pip install -e . # Install in editable mode
pip install pre-commit pytest pytest-asyncio ruff jsonschema # dev tools; see [dependency-groups] in pyproject.toml for pinned versions
ruff check src/ # Lint
ruff format src/ # Format
ruff check --fix src/ # Lint with auto-fix
Pre-commit hooks run REUSE compliance checks, ruff lint (with --fix --exit-non-zero-on-fix), ruff formatting, idalib threading lint, and pytest on every commit.
License
This project is licensed under the MIT License.
© 2026 Joe T. Sylve, Ph.D.
This project is REUSE compliant.
IDA Pro and Hex-Rays are trademarks of Hex-Rays SA. ida-mcp is an independent project and is not affiliated with or endorsed by Hex-Rays.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ida_mcp-2.2.1rc1.tar.gz.
File metadata
- Download URL: ida_mcp-2.2.1rc1.tar.gz
- Upload date:
- Size: 304.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6390d509a6dd5ed939978754606939a5758a5336e671c0ea595e90ce0136220f
|
|
| MD5 |
49688af049b232582fb26cc904103dfc
|
|
| BLAKE2b-256 |
9fcebb5fada7491edb9f50bc8c93b1b708063777f23ed59a479ef7e7a51b7370
|
Provenance
The following attestation bundles were made for ida_mcp-2.2.1rc1.tar.gz:
Publisher:
publish.yml on jtsylve/ida-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ida_mcp-2.2.1rc1.tar.gz -
Subject digest:
6390d509a6dd5ed939978754606939a5758a5336e671c0ea595e90ce0136220f - Sigstore transparency entry: 1398121038
- Sigstore integration time:
-
Permalink:
jtsylve/ida-mcp@cdacb0898e0c5f737b776771fb24eb676c129a2a -
Branch / Tag:
refs/tags/v2.2.1rc1 - Owner: https://github.com/jtsylve
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cdacb0898e0c5f737b776771fb24eb676c129a2a -
Trigger Event:
release
-
Statement type:
File details
Details for the file ida_mcp-2.2.1rc1-py3-none-any.whl.
File metadata
- Download URL: ida_mcp-2.2.1rc1-py3-none-any.whl
- Upload date:
- Size: 211.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
018d6674ca3be2596ab94614f18eb8f8fd02d9734beaa3efcd2b9ab002111113
|
|
| MD5 |
429e28b47d8ce3134b8a2370d60ff4ba
|
|
| BLAKE2b-256 |
ef42371d858fd3ac8e1d66eb661671b9841272341e380189e6cbf64c9ea041f6
|
Provenance
The following attestation bundles were made for ida_mcp-2.2.1rc1-py3-none-any.whl:
Publisher:
publish.yml on jtsylve/ida-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ida_mcp-2.2.1rc1-py3-none-any.whl -
Subject digest:
018d6674ca3be2596ab94614f18eb8f8fd02d9734beaa3efcd2b9ab002111113 - Sigstore transparency entry: 1398121062
- Sigstore integration time:
-
Permalink:
jtsylve/ida-mcp@cdacb0898e0c5f737b776771fb24eb676c129a2a -
Branch / Tag:
refs/tags/v2.2.1rc1 - Owner: https://github.com/jtsylve
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cdacb0898e0c5f737b776771fb24eb676c129a2a -
Trigger Event:
release
-
Statement type: