ida-code 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ida_code-0.2.1/.gitignore +7 -0
- ida_code-0.2.1/CHANGELOG.md +84 -0
- ida_code-0.2.1/LICENSE +21 -0
- ida_code-0.2.1/PKG-INFO +167 -0
- ida_code-0.2.1/README.md +138 -0
- ida_code-0.2.1/pyproject.toml +60 -0
- ida_code-0.2.1/src/ida_code/__init__.py +2 -0
- ida_code-0.2.1/src/ida_code/_search_utils.py +33 -0
- ida_code-0.2.1/src/ida_code/comments.py +191 -0
- ida_code-0.2.1/src/ida_code/config.py +9 -0
- ida_code-0.2.1/src/ida_code/doc_search.py +255 -0
- ida_code-0.2.1/src/ida_code/example_search.py +570 -0
- ida_code-0.2.1/src/ida_code/executor.py +145 -0
- ida_code-0.2.1/src/ida_code/guidelines.py +370 -0
- ida_code-0.2.1/src/ida_code/macho.py +67 -0
- ida_code-0.2.1/src/ida_code/prompts.py +176 -0
- ida_code-0.2.1/src/ida_code/server.py +1011 -0
- ida_code-0.2.1/src/ida_code/session.py +293 -0
- ida_code-0.2.1/src/ida_code/snapshots.py +110 -0
- ida_code-0.2.1/src/ida_code/structures.py +227 -0
- ida_code-0.2.1/src/ida_code/undo.py +102 -0
- ida_code-0.2.1/src/ida_code/variables.py +206 -0
- ida_code-0.2.1/tests/__init__.py +0 -0
- ida_code-0.2.1/tests/test_comments.py +56 -0
- ida_code-0.2.1/tests/test_doc_search.py +173 -0
- ida_code-0.2.1/tests/test_example_search.py +304 -0
- ida_code-0.2.1/tests/test_executor.py +153 -0
- ida_code-0.2.1/tests/test_macho.py +213 -0
- ida_code-0.2.1/tests/test_search_utils.py +70 -0
- ida_code-0.2.1/tests/test_session.py +59 -0
- ida_code-0.2.1/tests/test_structures.py +85 -0
- ida_code-0.2.1/tests/test_undo.py +210 -0
- ida_code-0.2.1/tests/test_variables.py +42 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.2.1] - 2026-05-05
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **PyPI publish workflow** — `.github/workflows/publish-pypi.yml` builds with `uv build` and publishes to PyPI via Trusted Publishing on every push to `main` whose `pyproject.toml` version differs from the latest released version. No-op when versions match.
|
|
14
|
+
- **Credits section** in README thanking [@p41l](https://github.com/p41l) for ideas and cross-LLM testing.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **fastmcp v3** — Bumped dependency from `fastmcp>=2.0,<3` to `fastmcp>=3.0,<4`. No code changes required: the `FastMCP` constructor, `@mcp.tool` / `@mcp.resource` / `@mcp.prompt` decorators, `fastmcp.exceptions.ToolError`, `fastmcp.server.auth.DebugTokenVerifier`, and `mcp.run(transport="streamable-http"|"sse", host=..., port=...)` are all still supported in v3.
|
|
19
|
+
- **README polish** — Compressed install to a single primary path (`uv tool install ida-code`, with `pip` fallback), added a per-OS `IDA_INSTALL_DIR` table, moved the tool inventory above transport/env sections, and pushed source-install + fastmcp note to the bottom.
|
|
20
|
+
|
|
21
|
+
## [0.2.0] - 2026-04-30
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **PyPI release prep** — Full PEP 639 metadata in `pyproject.toml` (license expression, classifiers, urls, authors, keywords, readme). Hatchling sdist allowlist excludes dev-only files (`.claude/`, `.mcp.json`, `CLAUDE.md`, `TODO.md`, `uv.lock`). README rewritten as a slim user-facing reference (~130 lines, table-of-tools instead of 30 per-tool sections).
|
|
26
|
+
- **Friendlier `idapro` import error** — When `IDA_INSTALL_DIR` doesn't point at a valid IDA Pro install, the server now exits with a clear message naming the directory it tried instead of an opaque `ModuleNotFoundError`.
|
|
27
|
+
- **`.mcp.json.example`** — Committed configuration template with placeholder paths. The real `.mcp.json` is now gitignored to avoid leaking local paths.
|
|
28
|
+
- **Word-boundary matching** — `search_docs` and `search_examples` now use word-boundary-aware matching. Searching for "set" matches `set_name` and `ida_name.set_name` but not "reset", "offset", or "unset". Boundaries are start-of-string, underscore, dot, and whitespace.
|
|
29
|
+
- **Field-weighted scoring in `search_docs`** — Title matches now score 4x higher than body matches, and Python API name matches score 5x higher. Previously all matches scored equally. Includes all-terms-match bonus (1.5x multiplier).
|
|
30
|
+
- **Cross-linking docs → examples** — `search_docs` now includes a `related_examples` key with up to 2 matching example scripts. Controlled via `include_examples` parameter (default `True`).
|
|
31
|
+
- **Server instructions** — Added `instructions` parameter to FastMCP server with workflow guidance (open → list → decompile → annotate → iterate). Visible to LLMs in the MCP `initialize` response.
|
|
32
|
+
- **Literal types for enum parameters** — `comment_type`, `category`, and `level` parameters now use `Literal` types, exposing valid values in the JSON schema `enum` field instead of only in docstrings.
|
|
33
|
+
- **`rename_function` tool** — Rename a function by name or address. Returns old and new names.
|
|
34
|
+
- **`retype_function` tool** — Change a function's type signature with a C type string.
|
|
35
|
+
- **`get_xrefs_to` tool** — Get cross-references to an address (who calls/references this?). Returns typed xref list with human-readable type names.
|
|
36
|
+
- **`get_xrefs_from` tool** — Get cross-references from an address (what does this call/reference?).
|
|
37
|
+
- **`get_strings` tool** — List strings in the database with min-length and filter options.
|
|
38
|
+
- **`get_imports` tool** — List all imported functions grouped by module.
|
|
39
|
+
- **`get_exports` tool** — List all exported functions/symbols with ordinals.
|
|
40
|
+
- **Database file guard** — Before every IDA API call, `session.require_open()` now checks that the `.i64`/`.idb` database file still exists on disk. If the file has been moved or deleted, the server resets internal state and returns a clean `ToolError` instead of letting idalib segfault and crash the process. All tools that require an open database use this centralized check.
|
|
41
|
+
- **`open_database` `overwrite` flag** — Delete existing `.i64`/`.idb` database files before opening, forcing a fresh analysis from the original binary.
|
|
42
|
+
- **`close_database` tool** — Explicitly close the current database and free resources. Clears the executor namespace.
|
|
43
|
+
- **`execute_file` tool** — Run IDAPython script files directly by path. Optional `args` parameter for inline follow-up code in the same namespace.
|
|
44
|
+
- **Coding guidelines resources** — Three MCP Resources (`guidelines://standalone_script`, `guidelines://plugin`, `guidelines://idapython_script`) providing architecture templates and best practices for writing standalone idalib scripts, IDA plugins, and classic IDAPython scripts.
|
|
45
|
+
- **Execution timeout** — `execute` and `execute_file` now enforce a wall-clock timeout (default 30s, configurable via `timeout` parameter, 0 = unlimited). Prevents infinite loops from hanging the server.
|
|
46
|
+
- **Process-killing exception guard** — `SystemExit` and `KeyboardInterrupt` raised by user code are now intercepted and returned as error text instead of killing the server process.
|
|
47
|
+
- **`decompile` tool** — Decompile a function by name or address. Resolves names via `ida_name`, accepts hex/decimal addresses, returns pseudocode with a header comment. Requires Hex-Rays.
|
|
48
|
+
- **Structured logging** — All modules now use Python `logging`. Output goes to stderr (won't interfere with stdio MCP transport). Controlled via `LOG_LEVEL` env var (default `WARNING`).
|
|
49
|
+
- **Unit tests** — 35 tests covering executor (output capture, timeout, exception handling, namespace persistence, truncation) and doc_search (HTML stripping, scoring, excerpt extraction). Run with `uv run pytest`.
|
|
50
|
+
- **`open_database` timeout** — New `timeout` parameter (default 0 = unlimited) limits auto-analysis wait time. When the timeout expires, the database stays open with partial analysis and a warning is appended. Progress (function count) is logged during analysis.
|
|
51
|
+
- **`get_database_info` tool** — Read-only tool returning current database summary (processor, segments, entry points, function count) without opening or closing anything.
|
|
52
|
+
- **`list_functions` tool** — Paginated function listing with address, size, and name. Supports `offset`/`limit` pagination and case-insensitive name `filter`.
|
|
53
|
+
- **REPL-like expression output** — `execute` now returns the `repr()` of the last expression if it's a bare expression (not an assignment or statement), just like the interactive Python prompt. No need to wrap everything in `print()`.
|
|
54
|
+
- **Database snapshots** — Four new tools for checkpointing and rolling back database state: `list_snapshots`, `create_snapshot`, `restore_snapshot`, `remove_snapshot`. Built on `ida_loader.snapshot_t` and `ida_kernwin.take_database_snapshot` / `restore_database_snapshot`.
|
|
55
|
+
- **`search_examples` tool** — Search 125 official IDAPython example scripts. Indexes metadata from `index.md` (title, description, keywords, APIs used, level, category) and AST-parses each `.py` file for imports, definitions, and `ida_*` API call patterns. Weighted scoring ranks API matches highest. Supports `category` and `level` filters.
|
|
56
|
+
- **Structure management tools** — Five new tools for managing IDA structs and unions: `list_structures` (paginated listing with filter), `get_structure` (detailed info with C definition), `create_structure` (from C definition string via `idc.parse_decls`), `edit_structure` (replace existing definition), `delete_structure` (remove from type library).
|
|
57
|
+
- **Variable management tools** — Two new tools for inspecting and modifying variables: `get_variable` (read local or global variable info) and `set_variable` (rename and/or retype). Local variables use Hex-Rays decompiler APIs (`ida_hexrays`); globals use `ida_name` and `ida_typeinf`.
|
|
58
|
+
- **Comment management tools** — Three new tools for managing comments: `get_comment` (read one or all comment types at an address), `set_comment` (write a comment), `delete_comment` (remove a comment). Supports all five IDA comment types: regular, repeatable, function, anterior, and posterior.
|
|
59
|
+
- **Undo/redo tools** — Three new tools for undoing and redoing database changes: `get_undo_status` (check availability and next action labels), `perform_undo` (undo one or more steps), `perform_redo` (redo one or more steps). Built on `ida_undo`. Multi-step undo/redo in a single call with partial success support.
|
|
60
|
+
- **MCP prompts** — Two new MCP prompts for guided workflows: `reverse_engineer` (comprehensive five-phase binary analysis workflow covering reconnaissance, triage, deep analysis, annotation, and iteration) and `create_script` (coding guidelines for standalone scripts, plugins, or IDAPython scripts plus IDAPython best practices for error handling, performance, naming conventions, and common pitfalls).
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- **`remove_snapshot` → `delete_snapshot`** — Renamed for consistency with `delete_structure` and `delete_comment`.
|
|
65
|
+
- **`filter` → `name_filter`** — Renamed in `list_functions` and `list_structures` to avoid shadowing the Python builtin and clarify semantics.
|
|
66
|
+
- **`id` → `snapshot_id`** — Renamed in `restore_snapshot` and `delete_snapshot` to avoid shadowing the Python builtin and be self-documenting.
|
|
67
|
+
- **`function` → `scope`** — Renamed in `get_variable` and `set_variable` to clarify it's the containing scope, not the target variable.
|
|
68
|
+
- **Tool descriptions** — All 30 tools that require an open database now say "Requires an open database" in the first line. Added `Returns:` lines listing dict keys. Enriched `execute` description with exhaustive pre-imported module list. Improved `search_docs` and `search_examples` descriptions to clarify when and why to use them.
|
|
69
|
+
- **`reverse_engineer` prompt** — Updated to reference new dedicated tools (`get_strings`, `get_imports`, `get_exports`, `get_xrefs_to`, `get_xrefs_from`, `rename_function`, `retype_function`) instead of raw `execute` boilerplate. Recommends dedicated tools over `execute` where available.
|
|
70
|
+
- **`execute` behavior** — Last-expression values are now auto-printed. `None` results are suppressed. Explicit `print()` calls still work as before.
|
|
71
|
+
- **Auto-import idalib on startup** — `idapro` is now loaded automatically from `IDA_INSTALL_DIR/idalib/python/` and `IDADIR` is set via `os.environ.setdefault`. No manual `pip install` or `py-activate-idalib.py` needed.
|
|
72
|
+
|
|
73
|
+
## [0.1.0] - 2026-02-10
|
|
74
|
+
|
|
75
|
+
Initial release.
|
|
76
|
+
|
|
77
|
+
### Added
|
|
78
|
+
|
|
79
|
+
- **`open_database` tool** — Open binaries and IDA databases via idalib with auto-analysis support. Returns summary info: processor type, bitness, segments, entry points, function count.
|
|
80
|
+
- **`execute` tool** — Run arbitrary IDAPython code with persistent namespace across calls. Pre-imports common `ida_*` modules. Captures stdout/stderr with 50K character truncation.
|
|
81
|
+
- **`search_docs` tool** — Keyword search over IDA's HTML documentation (2628 indexed pages) and IDAPython API source files (`ida_*.py` signatures and docstrings).
|
|
82
|
+
- Implicit database lifecycle management (close-on-open, atexit cleanup).
|
|
83
|
+
- stdio MCP transport via fastmcp.
|
|
84
|
+
- Claude Code `.mcp.json` configuration template.
|
ida_code-0.2.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dil4rd
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
ida_code-0.2.1/PKG-INFO
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ida-code
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: MCP server for AI-assisted IDAPython scripting via idalib
|
|
5
|
+
Project-URL: Homepage, https://github.com/Dil4rd/ida-code
|
|
6
|
+
Project-URL: Repository, https://github.com/Dil4rd/ida-code
|
|
7
|
+
Project-URL: Issues, https://github.com/Dil4rd/ida-code/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/Dil4rd/ida-code/blob/main/CHANGELOG.md
|
|
9
|
+
Author: Dil4rd
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: ida,ida-pro,idalib,idapython,mcp,reverse-engineering
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Information Technology
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Security
|
|
21
|
+
Classifier: Topic :: Software Development :: Disassemblers
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Requires-Python: >=3.12
|
|
24
|
+
Requires-Dist: fastmcp<4,>=3.0
|
|
25
|
+
Requires-Dist: lief>=0.15
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# ida-code
|
|
31
|
+
|
|
32
|
+
MCP server that lets AI coding agents interact with IDA Pro. Open binaries, decompile, run IDAPython, search the API docs — all through tool calls.
|
|
33
|
+
|
|
34
|
+
Built on [idalib](https://docs.hex-rays.com/developer-guide/idalib) for headless in-process operation and [fastmcp](https://github.com/jlowin/fastmcp) for the MCP transport.
|
|
35
|
+
|
|
36
|
+
> **Requires** a licensed IDA Pro 9.2+ with idalib support. `ida-code` does not install or replace IDA Pro — it loads `idapro` from your existing install at startup.
|
|
37
|
+
|
|
38
|
+
## Install
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
uv tool install ida-code
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This puts the `ida-code` CLI on your `PATH` (via `uv`'s tool dir) so MCP clients can launch it directly. Don't have uv? `pip install ida-code` works too.
|
|
45
|
+
|
|
46
|
+
Then point `IDA_INSTALL_DIR` at your IDA Pro install (the directory that contains `idalib/python/`):
|
|
47
|
+
|
|
48
|
+
| OS | Typical path |
|
|
49
|
+
|---|---|
|
|
50
|
+
| Linux | `/opt/ida-pro-9.3` |
|
|
51
|
+
| macOS | `/Applications/IDA Professional 9.3.app/Contents/MacOS` |
|
|
52
|
+
| Windows | `C:\Program Files\IDA Professional 9.3` |
|
|
53
|
+
|
|
54
|
+
## Use with Claude Code
|
|
55
|
+
|
|
56
|
+
Add `ida-code` to your project's `.mcp.json`:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"mcpServers": {
|
|
61
|
+
"ida-code": {
|
|
62
|
+
"command": "ida-code",
|
|
63
|
+
"env": {
|
|
64
|
+
"IDA_INSTALL_DIR": "/opt/ida-pro-9.3"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Restart Claude Code; the server is picked up automatically. You can confirm it's wired up by asking Claude to open a binary — it should call `open_database` and report architecture, entry point, and load address.
|
|
72
|
+
|
|
73
|
+
For other MCP clients, run the server directly:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
IDA_INSTALL_DIR=/opt/ida-pro-9.3 ida-code # stdio transport
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Tools (35)
|
|
80
|
+
|
|
81
|
+
Full parameter docs live in each tool's docstring — surfaced automatically to MCP clients via `tools/list`.
|
|
82
|
+
|
|
83
|
+
| Domain | Tools |
|
|
84
|
+
|---|---|
|
|
85
|
+
| Database | `open_database`, `close_database`, `get_database_info`, `list_architectures` |
|
|
86
|
+
| Code execution | `execute`, `execute_file` |
|
|
87
|
+
| Navigation | `list_functions`, `decompile`, `get_disassembly`, `get_xrefs_to`, `get_xrefs_from` |
|
|
88
|
+
| Annotation | `rename_function`, `retype_function`, `get_comment`, `set_comment`, `delete_comment`, `get_variable`, `set_variable` |
|
|
89
|
+
| Structures | `list_structures`, `get_structure`, `create_structure`, `edit_structure`, `delete_structure` |
|
|
90
|
+
| Snapshots | `list_snapshots`, `create_snapshot`, `restore_snapshot`, `delete_snapshot` |
|
|
91
|
+
| Undo/redo | `get_undo_status`, `perform_undo`, `perform_redo` |
|
|
92
|
+
| Inventory | `get_strings`, `get_imports`, `get_exports` |
|
|
93
|
+
| Search | `search_docs`, `search_examples` |
|
|
94
|
+
|
|
95
|
+
## Resources & prompts
|
|
96
|
+
|
|
97
|
+
| Type | URI / name | Purpose |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| Resource | `guidelines://standalone_script` | Boilerplate for standalone idalib scripts |
|
|
100
|
+
| Resource | `guidelines://plugin` | Boilerplate for IDA plugins (`plugin_t`) |
|
|
101
|
+
| Resource | `guidelines://idapython_script` | Boilerplate for IDAPython scripts run inside IDA GUI |
|
|
102
|
+
| Prompt | `reverse_engineer` | Five-phase RE workflow (recon, triage, analysis, annotation, iteration) |
|
|
103
|
+
| Prompt | `create_script` | Coding guidelines for a chosen target script type |
|
|
104
|
+
|
|
105
|
+
## Transport modes
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
ida-code # stdio (default)
|
|
109
|
+
ida-code --http # streamable-http on 127.0.0.1:8080
|
|
110
|
+
ida-code --http 0.0.0.0:9090 # custom host:port
|
|
111
|
+
ida-code --sse # SSE on 127.0.0.1:8080
|
|
112
|
+
ida-code --sse :9090 # SSE on 127.0.0.1:9090
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
HTTP/SSE require bearer token auth. Set `MCP_AUTH_TOKEN` or let the server generate one (printed to stderr on startup).
|
|
116
|
+
|
|
117
|
+
## Environment variables
|
|
118
|
+
|
|
119
|
+
| Variable | Default | Description |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| `IDA_INSTALL_DIR` | `/opt/ida-pro-9.3` | IDA Pro installation directory (must contain `idalib/python/`) |
|
|
122
|
+
| `LOG_LEVEL` | `WARNING` | Logging verbosity (`DEBUG`, `INFO`, `WARNING`, `ERROR`) |
|
|
123
|
+
| `MCP_AUTH_TOKEN` | (auto-generated) | Bearer token for HTTP/SSE transports |
|
|
124
|
+
|
|
125
|
+
Doc and example paths are derived from `IDA_INSTALL_DIR` (`docs/`, `python/`, `python/examples/`).
|
|
126
|
+
|
|
127
|
+
## Install from source
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
git clone https://github.com/Dil4rd/ida-code
|
|
131
|
+
cd ida-code
|
|
132
|
+
uv sync
|
|
133
|
+
uv run ida-code
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
When wiring a source checkout into `.mcp.json`, use `uv` as the command:
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"mcpServers": {
|
|
141
|
+
"ida-code": {
|
|
142
|
+
"command": "uv",
|
|
143
|
+
"args": ["run", "--directory", "/path/to/ida-code", "ida-code"],
|
|
144
|
+
"env": { "IDA_INSTALL_DIR": "/opt/ida-pro-9.3" }
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
> **Note:** the `fastmcp` dependency is the [community fastmcp](https://github.com/jlowin/fastmcp) package, not the official `mcp` SDK. Don't install `mcp` by mistake.
|
|
151
|
+
|
|
152
|
+
## Development
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
uv sync --extra dev
|
|
156
|
+
uv run pytest
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The test suite covers the executor, doc/example search, comments, snapshots, structures, undo, variables, and Mach-O parsing. Tests that need idalib are skipped if it's not available.
|
|
160
|
+
|
|
161
|
+
## Credits
|
|
162
|
+
|
|
163
|
+
Thanks to [@p41l](https://github.com/p41l) for ideas and for testing the tool across different LLMs.
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
MIT — see `LICENSE`.
|
ida_code-0.2.1/README.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# ida-code
|
|
2
|
+
|
|
3
|
+
MCP server that lets AI coding agents interact with IDA Pro. Open binaries, decompile, run IDAPython, search the API docs — all through tool calls.
|
|
4
|
+
|
|
5
|
+
Built on [idalib](https://docs.hex-rays.com/developer-guide/idalib) for headless in-process operation and [fastmcp](https://github.com/jlowin/fastmcp) for the MCP transport.
|
|
6
|
+
|
|
7
|
+
> **Requires** a licensed IDA Pro 9.2+ with idalib support. `ida-code` does not install or replace IDA Pro — it loads `idapro` from your existing install at startup.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
uv tool install ida-code
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This puts the `ida-code` CLI on your `PATH` (via `uv`'s tool dir) so MCP clients can launch it directly. Don't have uv? `pip install ida-code` works too.
|
|
16
|
+
|
|
17
|
+
Then point `IDA_INSTALL_DIR` at your IDA Pro install (the directory that contains `idalib/python/`):
|
|
18
|
+
|
|
19
|
+
| OS | Typical path |
|
|
20
|
+
|---|---|
|
|
21
|
+
| Linux | `/opt/ida-pro-9.3` |
|
|
22
|
+
| macOS | `/Applications/IDA Professional 9.3.app/Contents/MacOS` |
|
|
23
|
+
| Windows | `C:\Program Files\IDA Professional 9.3` |
|
|
24
|
+
|
|
25
|
+
## Use with Claude Code
|
|
26
|
+
|
|
27
|
+
Add `ida-code` to your project's `.mcp.json`:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"mcpServers": {
|
|
32
|
+
"ida-code": {
|
|
33
|
+
"command": "ida-code",
|
|
34
|
+
"env": {
|
|
35
|
+
"IDA_INSTALL_DIR": "/opt/ida-pro-9.3"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Restart Claude Code; the server is picked up automatically. You can confirm it's wired up by asking Claude to open a binary — it should call `open_database` and report architecture, entry point, and load address.
|
|
43
|
+
|
|
44
|
+
For other MCP clients, run the server directly:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
IDA_INSTALL_DIR=/opt/ida-pro-9.3 ida-code # stdio transport
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Tools (35)
|
|
51
|
+
|
|
52
|
+
Full parameter docs live in each tool's docstring — surfaced automatically to MCP clients via `tools/list`.
|
|
53
|
+
|
|
54
|
+
| Domain | Tools |
|
|
55
|
+
|---|---|
|
|
56
|
+
| Database | `open_database`, `close_database`, `get_database_info`, `list_architectures` |
|
|
57
|
+
| Code execution | `execute`, `execute_file` |
|
|
58
|
+
| Navigation | `list_functions`, `decompile`, `get_disassembly`, `get_xrefs_to`, `get_xrefs_from` |
|
|
59
|
+
| Annotation | `rename_function`, `retype_function`, `get_comment`, `set_comment`, `delete_comment`, `get_variable`, `set_variable` |
|
|
60
|
+
| Structures | `list_structures`, `get_structure`, `create_structure`, `edit_structure`, `delete_structure` |
|
|
61
|
+
| Snapshots | `list_snapshots`, `create_snapshot`, `restore_snapshot`, `delete_snapshot` |
|
|
62
|
+
| Undo/redo | `get_undo_status`, `perform_undo`, `perform_redo` |
|
|
63
|
+
| Inventory | `get_strings`, `get_imports`, `get_exports` |
|
|
64
|
+
| Search | `search_docs`, `search_examples` |
|
|
65
|
+
|
|
66
|
+
## Resources & prompts
|
|
67
|
+
|
|
68
|
+
| Type | URI / name | Purpose |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| Resource | `guidelines://standalone_script` | Boilerplate for standalone idalib scripts |
|
|
71
|
+
| Resource | `guidelines://plugin` | Boilerplate for IDA plugins (`plugin_t`) |
|
|
72
|
+
| Resource | `guidelines://idapython_script` | Boilerplate for IDAPython scripts run inside IDA GUI |
|
|
73
|
+
| Prompt | `reverse_engineer` | Five-phase RE workflow (recon, triage, analysis, annotation, iteration) |
|
|
74
|
+
| Prompt | `create_script` | Coding guidelines for a chosen target script type |
|
|
75
|
+
|
|
76
|
+
## Transport modes
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
ida-code # stdio (default)
|
|
80
|
+
ida-code --http # streamable-http on 127.0.0.1:8080
|
|
81
|
+
ida-code --http 0.0.0.0:9090 # custom host:port
|
|
82
|
+
ida-code --sse # SSE on 127.0.0.1:8080
|
|
83
|
+
ida-code --sse :9090 # SSE on 127.0.0.1:9090
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
HTTP/SSE require bearer token auth. Set `MCP_AUTH_TOKEN` or let the server generate one (printed to stderr on startup).
|
|
87
|
+
|
|
88
|
+
## Environment variables
|
|
89
|
+
|
|
90
|
+
| Variable | Default | Description |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| `IDA_INSTALL_DIR` | `/opt/ida-pro-9.3` | IDA Pro installation directory (must contain `idalib/python/`) |
|
|
93
|
+
| `LOG_LEVEL` | `WARNING` | Logging verbosity (`DEBUG`, `INFO`, `WARNING`, `ERROR`) |
|
|
94
|
+
| `MCP_AUTH_TOKEN` | (auto-generated) | Bearer token for HTTP/SSE transports |
|
|
95
|
+
|
|
96
|
+
Doc and example paths are derived from `IDA_INSTALL_DIR` (`docs/`, `python/`, `python/examples/`).
|
|
97
|
+
|
|
98
|
+
## Install from source
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
git clone https://github.com/Dil4rd/ida-code
|
|
102
|
+
cd ida-code
|
|
103
|
+
uv sync
|
|
104
|
+
uv run ida-code
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
When wiring a source checkout into `.mcp.json`, use `uv` as the command:
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"mcpServers": {
|
|
112
|
+
"ida-code": {
|
|
113
|
+
"command": "uv",
|
|
114
|
+
"args": ["run", "--directory", "/path/to/ida-code", "ida-code"],
|
|
115
|
+
"env": { "IDA_INSTALL_DIR": "/opt/ida-pro-9.3" }
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
> **Note:** the `fastmcp` dependency is the [community fastmcp](https://github.com/jlowin/fastmcp) package, not the official `mcp` SDK. Don't install `mcp` by mistake.
|
|
122
|
+
|
|
123
|
+
## Development
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
uv sync --extra dev
|
|
127
|
+
uv run pytest
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The test suite covers the executor, doc/example search, comments, snapshots, structures, undo, variables, and Mach-O parsing. Tests that need idalib are skipped if it's not available.
|
|
131
|
+
|
|
132
|
+
## Credits
|
|
133
|
+
|
|
134
|
+
Thanks to [@p41l](https://github.com/p41l) for ideas and for testing the tool across different LLMs.
|
|
135
|
+
|
|
136
|
+
## License
|
|
137
|
+
|
|
138
|
+
MIT — see `LICENSE`.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ida-code"
|
|
3
|
+
version = "0.2.1"
|
|
4
|
+
description = "MCP server for AI-assisted IDAPython scripting via idalib"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.12"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
license-files = ["LICENSE"]
|
|
9
|
+
authors = [{name = "Dil4rd"}]
|
|
10
|
+
keywords = ["ida-pro", "ida", "idapython", "reverse-engineering", "mcp", "idalib"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 4 - Beta",
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"Intended Audience :: Information Technology",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.12",
|
|
18
|
+
"Programming Language :: Python :: 3.13",
|
|
19
|
+
"Topic :: Security",
|
|
20
|
+
"Topic :: Software Development :: Disassemblers",
|
|
21
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
22
|
+
]
|
|
23
|
+
dependencies = ["fastmcp>=3.0,<4", "lief>=0.15"]
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
Homepage = "https://github.com/Dil4rd/ida-code"
|
|
27
|
+
Repository = "https://github.com/Dil4rd/ida-code"
|
|
28
|
+
Issues = "https://github.com/Dil4rd/ida-code/issues"
|
|
29
|
+
Changelog = "https://github.com/Dil4rd/ida-code/blob/main/CHANGELOG.md"
|
|
30
|
+
|
|
31
|
+
[project.scripts]
|
|
32
|
+
ida-code = "ida_code.server:main"
|
|
33
|
+
|
|
34
|
+
[project.optional-dependencies]
|
|
35
|
+
dev = ["pytest>=8.0"]
|
|
36
|
+
|
|
37
|
+
[build-system]
|
|
38
|
+
requires = ["hatchling"]
|
|
39
|
+
build-backend = "hatchling.build"
|
|
40
|
+
|
|
41
|
+
[tool.pytest.ini_options]
|
|
42
|
+
testpaths = ["tests"]
|
|
43
|
+
filterwarnings = [
|
|
44
|
+
"ignore:builtin type SwigPyPacked has no __module__ attribute:DeprecationWarning",
|
|
45
|
+
"ignore:builtin type SwigPyObject has no __module__ attribute:DeprecationWarning",
|
|
46
|
+
"ignore:builtin type swigvarlink has no __module__ attribute:DeprecationWarning",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
[tool.hatch.build.targets.wheel]
|
|
50
|
+
packages = ["src/ida_code"]
|
|
51
|
+
|
|
52
|
+
[tool.hatch.build.targets.sdist]
|
|
53
|
+
include = [
|
|
54
|
+
"src/",
|
|
55
|
+
"tests/",
|
|
56
|
+
"README.md",
|
|
57
|
+
"LICENSE",
|
|
58
|
+
"CHANGELOG.md",
|
|
59
|
+
"pyproject.toml",
|
|
60
|
+
]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Shared search utilities for doc_search and example_search.
|
|
2
|
+
|
|
3
|
+
Provides word-boundary-aware matching: "set" matches "set_name" and
|
|
4
|
+
"ida_name.set_name" but not "reset" or "offset".
|
|
5
|
+
|
|
6
|
+
Boundaries are: start-of-string, underscore, dot, whitespace.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import re
|
|
10
|
+
from functools import lru_cache
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@lru_cache(maxsize=128)
|
|
14
|
+
def _boundary_pattern(term: str) -> re.Pattern:
|
|
15
|
+
"""Regex that matches term at an underscore/dot/whitespace boundary."""
|
|
16
|
+
escaped = re.escape(term)
|
|
17
|
+
return re.compile(rf"(?:^|[_.\s]){escaped}", re.IGNORECASE)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def term_matches(term: str, text: str) -> bool:
|
|
21
|
+
"""Check if term appears in text at a word boundary.
|
|
22
|
+
|
|
23
|
+
Boundaries are: start-of-string, underscore, dot, whitespace.
|
|
24
|
+
Fast path: rejects via substring check before running regex.
|
|
25
|
+
|
|
26
|
+
Dotted terms (e.g. "ida_funcs.get_func") use plain substring
|
|
27
|
+
matching since the dot is already specific enough.
|
|
28
|
+
"""
|
|
29
|
+
if term not in text.lower():
|
|
30
|
+
return False
|
|
31
|
+
if "." in term:
|
|
32
|
+
return True # dotted terms: substring match is sufficient
|
|
33
|
+
return _boundary_pattern(term).search(text) is not None
|