A Model Context Protocol (MCP) server for Binary Ninja that enables LLM-assisted reverse engineering through code execution.
This plugin implements Anthropic's Code Execution pattern. Instead of accessing the typical MCP "tools", the LLM writes Python code that executes directly against Binary Ninja's API. This approach (described by Cloudflare as "Code Mode") is more token-efficient and enables more complex multi-step analyses in a single execution.
- Write Python that runs directly against Binary Ninja's API
- Query and mutate the binary database
- Checkpoint/rollback, persistent workspace files, and reusable analysis patterns
- Basic security with API key authentication and some code validation
- In Binary Ninja, open the Plugin Manager (
Plugins > Manage Plugins) - Search for
Code Mode MCPorbinja_codemode_mcp - Click
Install - Restart Binary Ninja
After installation, the plugin will be located in the community plugins folder:
# Linux
~/.binaryninja/plugins/repositories/community/plugins/akrutsinger_binja_codemode_mcp/
# macOS
~/Library/Application Support/Binary Ninja/plugins/repositories/community/plugins/akrutsinger_binja_codemode_mcp/
# Windows
%APPDATA%\Binary Ninja\plugins\repositories\community\plugins\akrutsinger_binja_codemode_mcp\Clone or download this repository and copy to your Binary Ninja plugins folder:
# Linux
cp -r plugin/ ~/.binaryninja/plugins/binja_codemode_mcp/
# macOS
cp -r plugin/ ~/Library/Application\ Support/Binary\ Ninja/plugins/binja_codemode_mcp/
# Windows
copy plugin\ %APPDATA%\Binary Ninja\plugins\binja_codemode_mcp\Configure your MCP client to communicate with the plugin. The path to mcp_bridge.py depends on your installation method.
Zed (Agent Panel > ... > Add Custom Server...):
{
/// The name of your MCP server
"binja-codemode-mcp": {
/// The command which runs the MCP server
"command": "python3",
/// The arguments to pass to the MCP server
"args": ["~/.binaryninja/plugins/repositories/community/plugins/akrutsinger_binja_codemode_mcp/bridge/mcp_bridge.py"],
/// The environment variables to set
"env": {
"BINJA_MCP_URL": "http://127.0.0.1:42069",
"BINJA_MCP_KEY": "binja-codemode-local"
}
}
}Claude Desktop (Settings > Developer > Edit Config):
{
"mcpServers": {
"binja-codemode-mcp": {
"command": "python3",
"args": ["~/Library/Application Support/Binary Ninja/plugins/repositories/community/plugins/akrutsinger_binja_codemode_mcp/bridge/mcp_bridge.py"],
"env": {
"BINJA_MCP_URL": "http://127.0.0.1:42069",
"BINJA_MCP_KEY": "binja-codemode-local"
}
}
}
}Note: Use absolute paths. Replace ~ with your home directory path if needed, and adjust for your OS.
Use these paths instead:
- Linux:
~/.binaryninja/plugins/binja_codemode_mcp/bridge/mcp_bridge.py - macOS:
~/Library/Application Support/Binary Ninja/plugins/binja_codemode_mcp/bridge/mcp_bridge.py - Windows:
%APPDATA%\Binary Ninja\plugins\binja_codemode_mcp\bridge\mcp_bridge.py
To use a custom API key instead of the default API key, create ~/.binaryninja/codemode_mcp/config.json:
{
"api_key": "your-custom-key"
}Then update your MCP client config to use the same key in BINJA_MCP_KEY.
Set BINJA_MCP_LOG_LEVEL environment variable to control logging output (stderr):
# Options: DEBUG, INFO (default), WARNING, ERROR, CRITICAL
export BINJA_MCP_LOG_LEVEL=DEBUGOr add to your MCP client config:
"env": {
"BINJA_MCP_URL": "http://127.0.0.1:42069",
"BINJA_MCP_KEY": "binja-codemode-local",
"BINJA_MCP_LOG_LEVEL": "DEBUG"
}- Open Binary Ninja and load a binary
- Start the server:
Plugins > MCP Code Mode > Start Server - In your MCP client (Claude, Zed, etc.), start prompting!
"List all functions that reference memcpy and check if they validate buffer sizes"
"Decompile main() and identify potential security issues"
"Create a checkpoint, then rename all sub_* functions based on their behavior"
"Find and categhorize all string references by type (URL, file path, error message, etc.)"
"Analyze the binary's attack surface by examining input validation in network-facing functions"
The Python code written by the LLM has access to the binja object with these methods:
Binary Info
binja.get_binary_status()- Binary metadatabinja.list_functions()- All functionsbinja.analyze_function_batch()- Batched function alaysisbinja.list_imports()- Imported symbolsbinja.list_exports()- Exported symbolsbinja.list_segments()- Memory segmentsbinja.list_classes()- Classesbinja.list_namespaces()- Namespacesbinja.list_data_items()- Data items
Code Analysis
binja.decompile()- Get pseudocodebinja.get_assembly()- Get disassemblybinja.get_basic_blocks()- Basic function info
Cross References
binja.get_xrefs_to()- Find callersbinja.get_function_calls()- Find calleesbinja.get_data_xrefs_to()- Data references to addressbinja.get_data_xrefs_from()- Data references from address
Data Reading
binja.read_bytes()- Read raw bytesbinja.read_string()- Read stringbinja.get_string_at()- Get string infobinja.get_data_var_at()- Get data variable infobinja.list_strings()- List all strings
Search & Lookup
binja.find_bytes()- Search for byte patternbinja.function_at()- Get function by address or namebinja.get_comment()- Get commentbinja.get_function_comment()- Get function commentbinja.get_type()- Get User-defined struct/type info
Renaming
binja.rename_function(func, name)- Rename functionbinja.rename_data()- Rename databinja.rename_variable(func, old, new)- Rename variable
Typing
binja.retype_variable()- Retype variablebinja.define_type()- Define struct/typebinja.set_function_signature()- Set prototype
Comments
binja.set_comment()- Add commentbinja.set_function_comment()- Add function commentbinja.delete_comment()- Delete commentbinja.delete_function_comment()- Delete function comment
File Persistence
binja.write_file()- Save to workspacebinja.read_file()- Read from workspacebinja.list_files()- List workspace filesbinja.delete_file()- Delete workspace
Reusable Code
binja.save_skill(name, code, desc)- Save reusable codebinja.load_skill(name)- Load a skillbinja.list_skills()- List saved skillsbinja.delete_skill()- Delete a skill
binja.find_functions_calling_unsafe()- Find functions calling potentially unsafe functionsbinja.get_function_complexity()- Get cyclomatic complexity
A basic level of security in attempt to prevent some misuse:
- Localhost-only binding (127.0.0.1)
- API key authentication required
- Simple code validation blocks potentially dangerous operations
- 30-second execution timeout
Note: This plugin does execute arbitrary Python code. Only use with trusted MCP clients and LLMs.
MIT License - see LICENSE for details.