ida-codemode
⚠️ Experimental prerelease ⚠️
IDA Code Mode gives agents a compact Python execution surface over the
ida-domain API. It will
discover and share databases already open in the IDA GUI, and starts
managed idalib workers only when no suitable instance exists.
The MCP adapter explicitly runs execute_python as a lease-scoped REPL: imports,
variables, and function definitions persist between its calls through the same
database handle. The low-level API remains stateless by default and opts in with
persist_globals=True; a stateless call discards any namespace previously
retained by that handle. Separate handles receive isolated namespaces, and
closing a handle releases its namespace and retained IDA objects.
Installation
Requirements
- Installed in your PATH
- IDA 9.4 or higher with idalib and Python 3.11+
- Other IDA MCP servers must be disabled to reduce agent confusion
Claude Code
claude plugin marketplace add HexRaysSA/claude-marketplace
claude plugin install ida-mcp@HexRaysSA
Codex CLI
codex plugin marketplace add HexRaysSA/codex-marketplace
codex plugin add ida-mcp@HexRaysSA
Pi
pi install git:github.com/HexRaysSA/ida-codemode
oh-my-pi
omp plugin install github:HexRaysSA/ida-codemode
IDA GUI Support
To support IDA GUI instances when using ida-codemode, install the plugin:
uvx ida-hcli plugin install ida-codemode
# or if you have hcli installed:
hcli plugin install ida-codemode
Other agents
Configure a regular stdio MCP server in your MCP JSON configuration:
{
"mcpServers": {
"ida": {
"command": "uvx",
"args": [
"--with=ida-hcli",
"ida-codemode",
"mcp",
"--agent=my-agent"
]
}
}
}
uvx resolves the latest stable ida-codemode release from PyPI, so this
configuration does not need to be updated for each release. Pre-release
dependency resolution is currently required because ida-domain is published
as a development release.
--agent=my-agent is a human-chosen label (like claude-code, cursor,
my-custom-agent, etc.) used to differentiate sessions in a metrics dashboard.
We tested the following clients, but any MCP client should work similarly:
Usage
Start your agent harness and ask it something like:
Reverse /path/to/sample.elf for me
To test the GUI integration, open something in IDA and ask your harness:
What do I have open in the IDA GUI?
Command line
The package installs one ida-codemode command with subcommands:
# MCP server (stdio/http)
ida-codemode mcp --agent=my-agent
# Inspect MCP session logs
ida-codemode dashboard --open
# Export MCP session logs to ZIP
ida-codemode logs
# IDA Domain API reference
ida-codemode reference "decompile function"
# Execute Python against an IDB (command, script, repl)
ida-codemode exec tests/crackme03/elf -c 'db.functions.get_all()'
Run ida-codemode COMMAND --help for command-specific options.
Python Package (Developers)
You can build on ida-codemode as a library and reuse the database management
functionality. Doing so will transparently allow other ida-codemode users
to use IDBs concurrently and work together.
Example scenarios
Below are a few scenarios enabled by the ida-codemode library:
- You have an executable open in the IDA GUI and would like to use the MCP without closing IDA.
- Your main agent spawns 5 subagents to work on different parts of the IDB concurrently.
- A headless database is created by the MCP, you want to access it with a CLI tool.
- You develop a web application to look at all the open IDA databases at once.
API
DatabaseHandle is the primary API. One handle owns one lease on an exact GUI
or idalib database; closing it releases only that lease.
from ida_codemode import DatabaseHandle, DatabaseOpenOptions
options = DatabaseOpenOptions(
startup_timeout=300,
processor="arm",
image_base=0x08000000,
)
with DatabaseHandle.open("firmware.bin", options=options) as handle:
handle.wait_autoanalysis()
execution = handle.execute_python(
"len(list(db.functions.get_all()))",
timeout=60,
)
print(execution["result"])
IDA import settings in DatabaseOpenOptions apply only when Code Mode imports a
new source file. They do not reconfigure a reused GUI, worker, or existing IDB.
execute_python() is stateless by default; pass persist_globals=True to keep
a lease-scoped Python namespace between calls.
Discovery returns public instance descriptors that support exact attachment:
from ida_codemode import DatabaseHandle, InstanceState, discover_databases
ready = [
item.instance for item in discover_databases() if item.state is InstanceState.READY
]
with DatabaseHandle.attach(ready[0]) as handle:
print(handle.instance.record_id, handle.instance.idb_path)
find_database_owner() and wait_database_released() support clients that must
safely replace an executable or IDB. DatabaseManager is the secondary API for
MCP-style adapters that manage several handles and a current target. All
supported Python names are exported directly from ida_codemode; underscore
modules and non-exported implementation modules are private.
See ARCHITECTURE.md for more details.
Metadata
Release files for ida-codemode 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ida_codemode-0.6.1.tar.gz | 188.1 kB | Without provenance | Details for ida_codemode-0.6.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ida_codemode-0.6.1-py3-none-any.whl | Python 3 | none | any | Details for ida_codemode-0.6.1-py3-none-any.whl |
Total release size: 292.8 kB
Release files / ida_codemode-0.6.1.tar.gz
| Download URL | ida_codemode-0.6.1.tar.gz |
|---|---|
| Size | 188.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
44df2a986d24a7e35e64b92c910a21eb485dc4c47d1e9db1e572e8fc1aa08a44
|
|
BLAKE2b-256 checksum How to use checksums |
5d55b9b72626e371bb36b712659b567ad1d890947c237bfbcaeccfb30f12fe80
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / ida_codemode-0.6.1-py3-none-any.whl
| Download URL | ida_codemode-0.6.1-py3-none-any.whl |
|---|---|
| Size | 104.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
69a39e25f7441aab794f6737133f8c6155fd794c77924e46e83cb938acf8944f
|
|
BLAKE2b-256 checksum How to use checksums |
05202397e9b34cefe7ce01945cc2299a01459b9371c48027f61bfdbd4bfcf677
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for ida-codemode 0.6.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.