iflow-mcp_iamgublin-ida-codex-mcp 0.2.1
IDA Pro MCP Server - Expose reverse engineering capabilities through MCP protocol
Requires Python: >=3.9

# ida-codex-mcp

Local MCP (Model Context Protocol) server plus an IDA 9.2 plugin to expose common reverse engineering capabilities to MCP clients.

- `ida_bridge.py`: an IDA plugin that exposes core analysis features (function list, call graph, Hex-Rays pseudocode, disassembly, imports/exports, xrefs, strings, memory reads, navigation, naming/typing helpers, etc.) over a local TCP JSON interface (default `127.0.0.1:31337`).
- `mcp_ida_server.py`: a local MCP server that talks to the IDA plugin, then re-exposes features as MCP tools and resources over STDIN/STDOUT so MCP clients (e.g., Codex CLI) can use them directly.


## Features

- Functions and calls
  - List functions: `ida_list_functions`
  - Call graph: `ida_call_graph(name, max_depth)`
  - Analyze and optionally rename: `ida_analyze_function(name, max_depth, rename, rename_locals)`
- Decompile/Disassemble
  - Pseudocode (Hex-Rays): `ida_get_pseudocode(name|ea, offset, limit)`
  - Disassembly: `ida_get_disassembly(name|ea, offset, limit)`
  - Add pseudocode comment: `ida_add_pseudocode_comment(name|ea, line, comment, repeatable)`
  - Rename function: `ida_rename_function(old_name, new_name)`
- Program info
  - Imports: `ida_get_imports`
  - Exports: `ida_get_exports`
  - Cross-references: `ida_get_xrefs(target)` (name or address)
  - Globals: `ida_list_globals(offset, count)`
  - Memory read: `ida_read_memory(address, size)`
  - Strings: `ida_get_strings(min_length, offset, count)`
- Navigation & typing
  - Jump to address: `ida_jump_to_address(address)`
  - Set data type: `ida_set_data_type(address, data_type)` (byte/word/dword/qword/float/double/ascii/unicode)
  - Set function pointer type: `ida_set_function_pointer_type(address, function_signature)` (supports simplified signatures like `NTSTATUS __fastcall`)
  - Smart name: `ida_set_name(address, name)` (auto-detects function pointers and applies QWORD + function type)
  - Create function pointer: `ida_create_function_pointer(address, name, function_signature)` (jump + QWORD + function type + name; supports simplified signatures)
- MCP resources
  - `resources/list`: export top functions as resources (first 500)
  - `resources/read`: fetch pseudocode (or fallback to disassembly) via `ida://function/{ea}/{name}`
  - `resources/templates/list`: provide `ida_function` template


## Repository Layout

```
ida-codex-mcp/
├─ ida_bridge.py        # IDA plugin: local TCP JSON bridge
├─ mcp_ida_server.py    # MCP local process server: bridge MCP <-> IDA
└─ __pycache__/         # cache generated at runtime
```


## Requirements

- IDA Pro 9.2 (Hex-Rays recommended for pseudocode features)
- Python 3.9+
- Windows/Linux/macOS


## Installation & Startup

1) IDA side (plugin)

- Copy `ida_bridge.py` into IDA's `plugins` directory and restart IDA.
- When a target is open, the plugin spawns a local listener at `127.0.0.1:31337` (auto-increments port if taken).

2) MCP side (local process)

- From this repo folder, run:

```bash
python mcp_ida_server.py
```

- To override the IDA bridge address/port, set environment variables:

```bash
# Default: 127.0.0.1:31337
set IDA_HOST=127.0.0.1
set IDA_PORT=31337
```

- The process communicates over STDIN/STDOUT. Register it in your MCP client (e.g., Codex CLI) to use tools and resources.

## Codex CLI Integration (config.toml)

Add this server to Codex CLI's `config.toml` so the tools appear in the client. The exact location of the config file depends on your setup, for example:

- Windows: `%AppData%\\Codex\\config.toml`
- macOS: `~/Library/Application Support/Codex/config.toml`
- Linux: `~/.config/codex/config.toml`

Example configuration using stdio transport:

```toml
# Register an MCP server named "ida"
[mcp.servers.ida]
type = "stdio"
command = "python"
# Use an absolute path to the server script; single quotes are safe for Windows paths
args = ['D:\\Code\\ida-codex-mcp\\mcp_ida_server.py']

# Optional environment overrides (match your IDA bridge address/port)
env = { IDA_HOST = "127.0.0.1", IDA_PORT = "31337" }

# Optional stability knobs
enabled = true
restart_on_exit = true
timeout_ms = 15000
```

Unix-like path variant:

```toml
[mcp.servers.ida]
type = "stdio"
command = "python3"
args = ["/path/to/ida-codex-mcp/mcp_ida_server.py"]
env = { IDA_HOST = "127.0.0.1", IDA_PORT = "31337" }
enabled = true
restart_on_exit = true
timeout_ms = 15000
```

Verification steps:

- Ensure IDA is running with `ida_bridge.py` loaded and a database open.
- Restart Codex CLI so it picks up the new server.
- In Codex CLI, list tools and confirm `ida_*` tools (e.g., `ida_list_functions`, `ida_get_pseudocode`) are available.


## Quick Check (two ways)

Option A: Direct TCP to the IDA plugin (simple self-test)

```python
# quick_test.py
import json, socket

HOST, PORT = "127.0.0.1", 31337
req = {"method": "list_functions", "params": {}}

s = socket.create_connection((HOST, PORT), timeout=5)
s.sendall((json.dumps(req) + "\n").encode("utf-8"))
data = s.recv(65536)
print("IDA reply:", data.decode("utf-8", "ignore"))
```

```bash
python quick_test.py
```

Option B: Through MCP (recommended via an MCP client)

- Initialize:

```json
{"jsonrpc":"2.0","id":"1","method":"initialize","params":{"protocolVersion":"2024-11-05"}}
```

- List tools:

```json
{"jsonrpc":"2.0","id":"2","method":"tools/list"}
```

- Call example (list functions):

```json
{"jsonrpc":"2.0","id":"3","method":"tools/call","params":{"name":"ida_list_functions","arguments":{}}}
```

Tip: Sending single JSON lines via a pipe is only for smoke tests—register this process in an MCP client for the best experience.


## FAQ

- If Hex-Rays is not installed, `ida_get_pseudocode` and `ida_add_pseudocode_comment` will error; use `ida_get_disassembly` instead.
- If port `31337` is occupied, the plugin increases the port number automatically; set `IDA_PORT` accordingly on the MCP side to match.
- Transport encoding is UTF-8; each request/response is a single JSON line ending with a newline.


## License

TBD. Contributions welcome—please mention license intentions in PRs.


## Demo

![IDA reverse engineering demo](img/demo.png)