ida-headless-mcp

mcp
Security Audit
Pass
Health Pass
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 146 GitHub stars
Code Pass
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

Headless IDA Pro binary analysis via Model Context Protocol

README.md

IDA Headless MCP Server

Headless IDA Pro binary analysis via Model Context Protocol. Go orchestrates multi-session concurrency while Python workers handle IDA operations.

Architecture

┌─────────────────┐
│  MCP Client     │  Claude Desktop, Claude Code, CLI
│  (HTTP/SSE)     │
└────────┬────────┘
         │ http://localhost:17300/
         ▼
┌─────────────────┐
│   Go Server     │  Session registry, worker manager, watchdog
│   (MCP Tools)   │
└────────┬────────┘
         │ Connect RPC over Unix socket
         ▼
┌─────────────────┐
│ Python Worker   │  IDA + idalib (one per session)
│ (per session)   │
└─────────────────┘

Key features:

  • Multi-session concurrency via process isolation
  • 52 MCP tools for binary analysis
  • Automatic session timeouts (4 hours default, configurable)
  • Paginated results with configurable limit (default 1000)
  • Il2CppDumper metadata import for Unity games
  • unflutter metadata import for Flutter/Dart apps

Constants

These values are witnessed from internal/server/server.go by
wit; wit check README.md fails if the
README drifts from the source.

Constant Value
Default port 17300
Session timeout (minutes) 240
Default page limit 1000

Prerequisites

  1. IDA Pro 9.0+ or IDA Essential 9.2+, installed under /Applications. The
    build discovers the newest IDA automatically, or set IDA_INSTALL_DIR to its
    Contents/MacOS directory.
  2. Go 1.21+. The C++ worker links IDA headless via cgo; the required SDK
    headers are vendored in third_party/ida-include, so no separate SDK
    checkout is needed.

Optional: Il2CppDumper for Unity
games, and unflutter for Flutter/Dart
apps.

Build

Builds are driven by a magefile. Two ways to run it:

# With mage installed:
go install github.com/magefile/mage@latest
mage all              # build the server and the ida-worker

# Zero-install (no mage binary needed):
go run mage.go all

Targets: all, build, worker, run, restart, test, clean
(go run mage.go -l lists them).

Usage

Start Server

./bin/ida-mcp-server

Server starts running on port 17300 (configurable via config.json, env, or --port), exposing both transports:

  • Streamable HTTP (recommended): http://localhost:17300/
  • SSE compatibility endpoint: http://localhost:17300/sse

Configure Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "ida-headless": {
      "url": "http://127.0.0.1:17300/",
      "type": "http"
    }
  }
}

Restart Claude Desktop after editing.

Configure Claude Code

Copy .claude/settings.json to ~/.claude/settings.json to grant access to all IDA MCP tools.

Basic Workflow

1. open_binary(path="/path/to/binary.so")
   → {"session_id": "abc123"}

2. run_auto_analysis(session_id="abc123")
   → {"completed": true}

3. get_entry_point(session_id="abc123")
   → {"address": 4198400}

4. get_decompiled_func(session_id="abc123", address=4198400)
   → {pseudocode...}

5. get_functions(session_id="abc123")
   → {"functions": [...], "count": 1523}

6. close_binary(session_id="abc123")
   → {"success": true}

Flutter/Dart Import

1. Run unflutter on the target: unflutter meta libapp.so
2. open_binary(path="libapp.so")
3. import_flutter(session_id="...", meta_json_path="flutter_meta.json")
   → {"functions_created": 9926, "structs_created": 2090,
      "signatures_applied": 9926, "comments_set": 34172}
4. run_auto_analysis(session_id="...")

The import_flutter tool reads structured JSON metadata from unflutter. It creates Dart class structs, function definitions with typed signatures, and annotates THR/PP/string reference comments in a single pass.

Use tools/list via MCP to see all available tools.

Configuration

Command line flags:

./bin/ida-mcp-server \
  --port 17300 \
  --max-sessions 10 \
  --session-timeout 4h \
  --worker python/worker/server.py \
  --debug

Environment variables (overridden by CLI flags):

IDA_MCP_PORT=17300
IDA_MCP_SESSION_TIMEOUT_MIN=240
IDA_MCP_MAX_SESSIONS=10
IDA_MCP_WORKER=/custom/worker.py
IDA_MCP_DEBUG=1

Development

Build and test

mage build          # build the server (go run mage.go build without mage installed)
mage worker         # build the per-session ida-worker
mage all            # both
mage test           # go tests + wit check (README constants match the code)
mage restart        # kill, rebuild, restart server
mage clean          # remove binaries and the rpath symlink

mage test runs wit against this README,
so the witnessed values in Constants cannot drift from
internal/server/server.go.

Project Structure

ida-headless-mcp/
├── cmd/ida-mcp-server/   # Go MCP server entry point
├── internal/
│   ├── server/           # MCP tool handlers
│   ├── session/          # Session registry
│   └── worker/           # Worker process manager
├── proto/                # Protobuf definitions
├── python/worker/        # Python worker (idalib wrapper)
├── contrib/il2cpp/       # Il2CppDumper helpers (MIT)
└── tests/                # Test suites

Adding New Tools

  1. Add RPC to proto/ida/worker/v1/ida_service.proto
  2. Regenerate: make proto
  3. Implement in python/worker/ida_wrapper.py
  4. Add handler in python/worker/connect_server.py
  5. Register MCP tool in internal/server/server.go

Session Lifecycle

  1. Client calls open_binary(path)
  2. Go creates session in registry (UUID)
  3. Go spawns Python worker subprocess
  4. Worker creates Unix socket at /tmp/ida-worker-{id}.sock
  5. Worker opens IDA database with idalib
  6. Go creates Connect RPC clients over socket
  7. Subsequent tool calls proxy to worker via Connect
  8. Watchdog monitors idle time (default: 4 hours)
  9. On timeout or close_binary: save database, kill worker, cleanup
  10. Session metadata persists under <database_directory>/sessions for automatic restoration after server restart

Troubleshooting

Worker fails to start:

python3 -c "import idapro; print('OK')"

If this fails, run ./scripts/setup_idalib.sh

Socket timeout:
Check Python worker logs. Worker may have crashed during init.

Port already in use:

lsof -ti:17300 | xargs kill
# or use a different port
./bin/ida-mcp-server --port 17301

Session not found:
Session may have timed out. Use list_sessions to check active sessions.

License

MIT

Related Projects

MCP Servers:

Metadata Dumpers:

References

Reviews (0)

No results found