ida-mcp

repository·main·Indexed 20 days ago

https://github.com/blacktop/ida-mcp-rs

A headless Model Context Protocol (MCP) server that provides AI agents with tools to interact with IDA Pro for automated binary analysis, disassembly, and decompilation. It supports serialized IDA access, streamable HTTP for multiple clients, and specialized capabilities for Apple dyld_shared_cache (DSC) and Lumina metadata lookup. The server allows for tool filtering via categories (e.g., core, functions, decompile) to optimize token usage in AI agent context windows.

Tokens
30.9K
Snippets
88
Records
144
Agent score
70%

What's inside ida-mcp

  1. Overview of ida-mcp design principles

    main

    ida-mcp is a headless IDA Pro MCP (Model Context Protocol) server designed with a discovery-first tool model. Key architectural features include:

    • Full tool list by default: Ensures compatibility with MCP clients that only register tools at the moment of connection.
    • Tool discovery: Provides dedicated tools (tool_catalog and tool_help) to allow AI agents to find and understand available capabilities.
    • Streamable HTTP: Supports multiple clients simultaneously using streaming notifications.
    • Serialized IDA access: Maintains stability by routing all IDA Pro operations through a single dedicated worker thread.
  2. Input format conventions for ida-mcp tools

    main

    When calling tools, follow these formatting rules for parameters:

    • Multiple Values: Many tools accept either a single value or an array (e.g., "0x1000" or ["0x1000", "0x2000"]).
    • Comma-Separated Strings: String inputs may be provided as comma-separated values (e.g., "0x1000, 0x2000").
    • Address Formats: Addresses are accepted in both hexadecimal (0x1000) and decimal (4096) formats.
  3. Discover available tools in ida-mcp

    main

    You can discover the capabilities of the server using three primary methods:

    1. List all tools: Use tools/list to retrieve the complete set of available tools (currently 73).
    2. Search by intent: Use tool_catalog(query=...) to find tools based on a natural language query or category.
    3. Get tool documentation: Use tool_help(name=...) to retrieve the full documentation and JSON schema for a specific tool.

    This workflow allows an AI agent or developer to understand the available surface area before attempting specific analysis tasks.

  4. Run ida-mcp as an HTTP/SSE worker pool

    main

    By default, serve-http uses a single in-process IDA worker. For stateful multi-client usage, use --max-workers to route sessions through child ida-mcp worker processes.

    ida-mcp serve-http --bind 127.0.0.1:8765 --max-workers 4 --min-workers 1

    Key Concepts

    • Worker Leasing: Each HTTP session leases one child worker until close_idb, an HTTP DELETE is sent, a session timeout occurs, or the server shuts down.
    • Pool Exhaustion: If all workers are leased, open_idb/open_dsc calls will fail with Worker pool exhausted.
    • Reclamation:
      • SSE-capable clients: Reclaimed after the stream disconnects and --worker-disconnect-grace-secs elapses.
      • POST-only clients: Reclaimed by --session-keep-alive-secs (default 1800s).
    • Constraints: Pooled mode requires stateful HTTP sessions; using --stateless with --max-workers > 1 is rejected.
    ida-mcp serve-http --bind 127.0.0.1:8765 --max-workers 4 --min-workers 1
  5. Enable Lumina metadata lookup

    main

    By default, ida-mcp disables automatic Lumina lookups to prevent unexpected network activity. To use Lumina, you must explicitly opt-in.

    Opt-in Methods

    • CLI Flag: ida-mcp --allow-lumina
    • Environment Variable: IDA_MCP_ALLOW_LUMINA=true

    Available Tools (after opt-in)

    • lumina_lookup: Queries a function and reports available metadata without modifying the database.
    • lumina_apply: Pulls and applies metadata using IDA's upgrade policy. Use force: true to replace existing names, types, or comments.

    Note: lumina_apply is disabled when running with the --read-only flag.

    ida-mcp --allow-lumina
  6. How the concurrency model works with HTTP workers

    main

    Because IDA requires main-thread access and one IDA process can only own one active database at a time, the server uses different strategies based on the --max-workers setting:

    • --max-workers 1: All HTTP sessions are serialized through a single worker loop.
    • --max-workers N (where N > 1): The server uses a child-process worker pool. Each opened HTTP session leases a child ida-mcp worker process. This allows different sessions to own different IDBs concurrently.

    Session Lifecycle & Reclaiming:

    • Manual Release: A lease is released immediately when close_idb is called or an HTTP DELETE is sent.
    • SSE Clients: If an SSE client disconnects without a manual release, the session is closed after the --worker-disconnect-grace-secs elapses.
    • POST-only Clients: Since they lack a persistent stream, orphaned sessions are reclaimed via the --session-keep-alive-secs timeout.
  7. Understand what is covered by integration tests

    main

    Integration tests verify the interaction between the MCP server and IDA Pro across several transport and functional layers:

    Stdio Integration (just test)

    Verifies the MCP protocol handshake, tool discovery (tool_catalog, tool_help), and a wide range of IDA operations including:

    • Database: open_idb, close_idb, idb_meta, analysis_status.
    • Analysis: list_functions, resolve_function, disasm_by_name, find_insns, find_insn_operands.
    • Editing: set_comments, rename, patch, patch_asm.
    • Types/Stack: declare_type, apply_types, infer_types, stack_frame, declare_stack, delete_stack.
    • Metadata: segments, strings, imports, exports, structs, xrefs_to_field, search_structs.

    HTTP/SSE Integration (just test-http)

    Verifies streamable HTTP transport using Server-Sent Events (SSE). It ensures tools/list returns the full toolset and that database operations (like open_idb and list_functions) function correctly over the HTTP transport.

    Scripting Integration (just test-script)

    Verifies the run_script tool, which allows running inline Python or executing .py files. It checks for correct stdout/stderr capture and Python error reporting.

    Elicitation and Background Analysis (just test-elicitation)

    Tests how the server handles clients with different capabilities:

    • Non-elicitation clients: Verifies that open_idb(auto_analyse=true) silently routes analysis to a background task.
    • Elicitation-capable clients: Verifies the client receives elicitation/create, accepts it, and receives analysis_background=true along with a pollable analysis_task_id.
  8. Build ida-mcp on Linux

    main

    On Linux (x86_64), you must install build essentials and LLVM dependencies. You must also specify the IDADIR where your IDA installation resides.

    Common IDA paths:

    • /opt/idapro-9.4
    • /home/<user>/idapro-9.4
    • /usr/local/idapro-9.4
    sudo apt-get update
    sudo apt-get install -y build-essential llvm clang libclang-dev
    
    git clone https://github.com/blacktop/ida-mcp-rs.git
    cd ida-mcp-rs
    env IDADIR=/opt/idapro-9.4 just release
  9. Use ida-mcp for binary analysis

    main

    Once configured, you can interact with binaries using the following toolset via your AI agent:

    Basic Operations

    • open_idb(path: "..."): Opens a binary. Returns quickly; analysis runs in the background.
    • list_functions(limit: int): Lists functions.
    • disasm_by_name(name: "...", count: int): Disassembles by function name.
    • strings(limit: int): Lists strings.

    Advanced Analysis

    • analyze_funcs(background: true): Runs analysis in the background. Returns a task_id.
    • task_status(task_id: "..."): Polls the progress of a background task.
    • decompile(address: "..."): Decompiles a specific address (requires Hex-Rays and completed analysis).
    • tool_catalog(query: "..."): Discovers available tools.

    IDAPython Scripting

    Execute arbitrary Python code via IDA's engine:

    • run_script(code: "..."): Runs inline code.
    • run_script(file: "..."): Runs a .py file from disk.
    • run_script(..., timeout_secs: int): Sets a timeout (default 120s, max 600s).
    open_idb(path: "~/samples/malware")
    
    # Background analysis example
    analyze_funcs(background: true)   # returns task_id
    task_status(task_id: "analyze-1") # poll progress
    
    # Scripting example
    run_script(code: "import idautils\nfor f in idautils.Functions():\n    print(hex(f))")
  10. Open an IDA database or raw binary

    main

    Use open_idb to load a database or a binary file for analysis.

    Supported Formats

    • IDA Databases: .i64 or .idb files.
    • Raw Binaries: Mach-O, ELF, or PE files.

    Behavior for Raw Binaries

    • Raw binaries are automatically analyzed and saved as a .i64 file in the same directory as the input.
    • If a .i64 file already exists for that binary, it is opened directly to save time.
    • If a sibling .dSYM file exists and no .i64 is present, DWARF debug information is loaded automatically.

    Rebuilding Analysis

    If you have modified the input binary or want to overwrite a stale analysis, set rebuild=true.

    Closing Databases

    Always call close_idb when finished to release file locks. In multi-client environments (like HTTP/SSE), ensure you use the close_token provided by open_idb to coordinate closing.

    # Example conceptual usage
    open_idb(path="/path/to/binary", rebuild=true)
  11. Run ida-mcp tests

    main

    The project uses just commands to run various integration tests. Note that all integration tests (except unit tests) require IDA Pro with a valid license to be installed and running. You must run cargo build before executing integration tests.

    Available test commands:

    • just test: Runs Stdio JSONL integration tests.
    • just test-http: Runs HTTP/SSE integration tests.
    • just test-script: Runs IDAPython script execution tests.
    • just test-elicitation: Runs the open_idb auto-background elicitation test.
    • just test-dsc <path>: Runs the DSC (dyld shared cache) loading test using a specific path.
    • just cargo-test: Runs standard Rust unit tests (does not require IDA).
    just test         # Stdio JSONL integration test
    just test-http    # HTTP/SSE integration test
    just test-script  # IDAPython script execution test
    just test-elicitation # open_idb auto-background elicitation test
    just test-dsc /path/to/dyld_shared_cache_arm64e  # DSC loading test
    just cargo-test   # Unit tests (no IDA required)
  12. Client-specific recommendations for tool filtering

    main

    Depending on your AI agent/client, you may or may not need to filter tools:

    • Claude Code, Cursor: No action needed. Both clients defer MCP tool schemas and discover them on demand.
    • Codex CLI: If using models without tool-search support, or to constrain capabilities, use --toolsets: ida-mcp --toolsets=core,functions,disassembly,decompile,xrefs
    • Clients without lazy tool loading: These clients receive the full ~11k-token schema every session. You must pick a focused subset using --toolsets to save context.
    • Gemini CLI: Filtering is optional but recommended to reduce tool-selection noise when multiple MCP servers are active: ida-mcp --toolsets=core,functions,disassembly,decompile --read-only
    • Small / local models: Use the smallest workable surface for triage: ida-mcp --toolsets=core,functions --tools=decompile,callees,callers --read-only