Install
$ agentstack add mcp-aurafriday-ghidra-mcp Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Dangerous shell/eval execution.
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ● Dynamic code execution Used
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
MCP-Link for Ghidra
AI-Powered Reverse Engineering with 100% Ghidra API Access
A Ghidra extension that connects to the Aura Friday MCP-Link server, making Ghidra available as a remote tool that AI agents can fully control via Java reflection. Unlike hardcoded MCP tools with limited operations, this gives AI unlimited access to every Ghidra API.
🚀 What Makes This Different
Traditional MCP Tools (Limited)
AI → get_functions() → hardcoded list
AI → decompile_function(name) → hardcoded call
... maybe 10-40 hardcoded endpoints ...
MCP-Link for Ghidra (Unlimited)
AI → eval("currentProgram.getFunctionManager().getFunctions(true)") → Full API
AI → eval("new DecompInterface().decompileFunction(func, 60, null)") → Any operation
AI → eval("memory.getByte(addr)") → Read raw bytes
AI → list_methods("currentProgram") → Discover 150+ methods
... 100% of Ghidra's Java API via reflection ...
The AI can call ANY method, access ANY field, instantiate ANY class. No limits, no waiting for us to add features.
✨ Features
🔬 Full Java Reflection Execution
- Execute any expression via
evaloperation - Method chaining:
obj.method1().method2().field - Object instantiation:
new ghidra.app.decompiler.DecompInterface() - Static method calls:
@ghidra.util.Msg.info(plugin, "Hello!") - Array/List access:
list[0],map[key]
🔍 API Introspection
list_methods- Discover all methods on any objectlist_fields- Discover all fields on any objectdescribe- Get full object description with type hierarchy
📜 Multi-Line Script Execution
- Variable assignments that persist across calls
- Session management for stateful analysis
- Print statements for output capture
🔗 MCP Tool Integration
- Call other MCP tools (SQLite, browser, user popups, AI models)
- Store analysis results in databases
- Show interactive HTML popups
- Automate cross-tool workflows
🎯 What AI Can Do
Binary Analysis
// Get all functions
functionManager.getFunctions(true)
// Find functions by name pattern
symbolTable.getGlobalSymbols("crypt")
// Read memory bytes
memory.getByte(addr)
memory.getInt(addr)
Decompilation
// Create decompiler and get C code
decomp = new ghidra.app.decompiler.DecompInterface()
decomp.openProgram(currentProgram)
result = decomp.decompileFunction(func, 60, null)
print(result.getDecompiledFunction().getC())
Symbol Analysis
// Find all symbols
symbolTable.getAllSymbols(true)
// Get imports/exports
symbolTable.getExternalSymbols()
// Find cross-references
referenceManager.getReferencesTo(addr)
Data Types
// Access data type manager
dtm = currentProgram.getDataTypeManager()
// Find structures
dtm.getDataType("/MyStruct")
// Create new types
dtm.addDataType(newStruct, null)
📦 Installation
Prerequisites
- Ghidra 12.0+ - Download from https://ghidra-sre.org/
- MCP-Link Server - Download from https://github.com/AuraFriday/mcp-link-server/releases
- Java 21+ - Required for building
Build & Install
# Clone the repository
git clone https://github.com/AuraFriday/ghidra_mcp.git
cd ghidra_mcp
# Set Ghidra installation path
# Windows PowerShell:
$env:GHIDRA_INSTALL_DIR = "C:\path\to\ghidra_12.0_PUBLIC"
# Linux/Mac:
export GHIDRA_INSTALL_DIR="/path/to/ghidra_12.0_PUBLIC"
# Build the extension
make build
# Or manually:
cd mcp_link_ghidra && ./gradlew buildExtension
# The extension ZIP is created in mcp_link_ghidra/dist/
Install the Extension
- Open Ghidra
- Go to File → Install Extensions
- Click the + button
- Select the ZIP file from
mcp_link_ghidra/dist/ - Restart Ghidra
- Open a binary in the CodeBrowser - the plugin auto-connects!
🎬 Quick Start Examples
Example 1: Get Program Info
{
"operation": "eval",
"expression": "currentProgram.getName()"
}
Result: "hello.exe"
Example 2: Count Functions
{
"operation": "eval",
"expression": "functionManager.getFunctionCount()"
}
Result: 42
Example 3: Decompile Entry Function
{
"operation": "script",
"script": "syms = symbolTable.getGlobalSymbols(\"entry\")\naddr = syms[0].getAddress()\nfunc = listing.getFunctionAt(addr)\ndecomp = new ghidra.app.decompiler.DecompInterface()\ndecomp.openProgram(currentProgram)\nresult = decomp.decompileFunction(func, 60, null)\nprint(result.getDecompiledFunction().getC())",
"session_id": "default"
}
Result:
void entry(void)
{
longlong lVar1;
undefined4 auStackX_8 [8];
auStackX_8[0] = 0;
lVar1 = GetStdHandle(0xfffffff5);
if (lVar1 != -1) {
WriteFile(lVar1,&DAT_140002020,0xf,auStackX_8,0);
}
ExitProcess(0);
...
}
Example 4: Discover Available Methods
{
"operation": "list_methods",
"target": "currentProgram"
}
Result: 150+ methods including getName(), getFunctionManager(), getMemory(), getSymbolTable(), etc.
Example 5: Read Memory Bytes
{
"operation": "script",
"script": "addr = currentAddress\nb0 = memory.getByte(addr)\nb1 = memory.getByte(addr.add(1))\nb2 = memory.getByte(addr.add(2))\nprint(b0)\nprint(b1)\nprint(b2)",
"session_id": "hex"
}
🔧 Available Operations
| Operation | Description | Example | |-----------|-------------|---------| | eval / execute_java | Execute single expression | {"operation": "eval", "expression": "currentProgram.getName()"} | | script / execute_script | Multi-line script with assignments | {"operation": "script", "script": "x = 1\ny = x + 1\nprint(y)"} | | list_methods | List all methods on object | {"operation": "list_methods", "target": "functionManager"} | | list_fields | List all fields on object | {"operation": "list_fields", "target": "currentProgram"} | | describe | Full object description | {"operation": "describe", "target": "memory"} | | call_tool | Call other MCP tools | {"operation": "call_tool", "tool_name": "sqlite", ...} |
📋 Built-in Variables
These are automatically available in every expression/script:
| Variable | Type | Description | |----------|------|-------------| | currentProgram | Program | The currently open program | | currentAddress | Address | Current cursor location | | tool | PluginTool | The Ghidra tool instance | | plugin | MCPLinkGhidraPlugin | This plugin instance | | flatApi | FlatProgramAPI | Simplified API for common operations | | functionManager | FunctionManager | Access to functions | | symbolTable | SymbolTable | Access to symbols and labels | | memory | Memory | Raw memory access | | listing | Listing | Instructions and data | | addressFactory | AddressFactory | Create address objects |
🛠️ Expression Syntax
Method Chaining
currentProgram.getFunctionManager().getFunctionCount()
symbolTable.getGlobalSymbols("main")[0].getAddress()
Object Instantiation
new ghidra.app.decompiler.DecompInterface()
new ghidra.program.model.address.GenericAddress(...)
Static Method Calls (@ prefix)
@ghidra.util.Msg.info(plugin, "Hello from AI!")
@java.lang.System.currentTimeMillis()
Class References ($ prefix)
$ghidra.app.decompiler.DecompInterface
$java.util.ArrayList
Literals
"string" // String
123 // Integer
45.67 // Double
0x1400 // Hex number
true / false // Boolean
null // Null
Array/List Access
list[0] // First element
map["key"] // Map lookup
iterator[5] // 6th element (converts to list)
🏗️ Architecture
┌─────────────────┐ ┌─────────────────────────┐
│ AI Agent │ │ MCP-Link Server │
│ (Cursor/Claude) │◄───────►│ (Running on user's PC) │
└─────────────────┘ MCP └─────────────────────────┘
│
▼
┌──────────────────┐
│ Ghidra Extension │
│ (Remote Tool) │
└──────────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Reflection │ │ Introspection│ │ MCP Bridge │
│ Executor │ │ (list_*) │ │ (call_tool) │
└──────────────┘ └──────────────┘ └──────────────┘
Components
- MCPLinkGhidraPlugin.java - Main plugin, lifecycle management
- MCPLinkConnection.java - SSE connection to MCP-Link server
- MCPLinkExecutor.java - Routes operations to handlers
- ReflectionExecutor.java - Pure Java reflection engine (the magic!)
- MCPLinkProvider.java - UI panel for connection status
How It Works
- Extension loads when you open a program in CodeBrowser
- Connects to MCP-Link via native messaging discovery
- Registers as "ghidra" tool with reflection capabilities
- AI sends expressions → Parsed and executed via reflection
- Results returned with type information and string representation
🔗 Built-in MCP Tools
When running with MCP-Link server, these tools are available:
| Tool | Description | |------|-------------| | 🖥️ System | Windows desktop automation - screenshots, UI scanning, clicking, typing, window management | | 🔌 Terminal | Universal transport - Serial, TCP, SSH, Telnet, WebSocket, Bluetooth, BLE, RFC2217, named pipes | | 🌐 Chrome Browser | Unique: Execute JS with pristine pre-page-load environment - essential for web malware analysis | | 🧠 SQLite | Store analysis results, semantic search with embeddings | | 💬 User | Show HTML popups, forms, get user input | | 🐍 Python | Local Python execution with MCP tool access | | 🤖 OpenRouter | Access 500+ AI models | | 📚 Context7 | Live library documentation lookup |
🌐 Chrome Browser: Web Malware Analysis Superpower
Unlike any other browser automation tool, our Chrome Browser MCP provides something unique: a pristine pre-page-load JavaScript environment.
When you analyze web-based malware, obfuscated JavaScript, or hostile web pages, those scripts often:
- Override
console.logto hide their activity - Hook
fetchandXMLHttpRequestto intercept/modify network traffic - Modify DOM methods to evade detection
- Pollute the global namespace to break analysis tools
Our solution: Before ANY page scripts execute, we inject originalWindow - a frozen copy of the pristine browser environment:
// In your analysis script (via run_script_in_page):
// Safe logging - works even if page redirected console.log to /dev/null
originalWindow.console.log('Malware did X, Y, Z');
// Bypass fetch hooks - make requests the malware can't intercept
const realData = await originalWindow.fetch('/api/secret');
// Access unmodified DOM - createElement that wasn't tampered with
const cleanDiv = originalWindow.document.createElement('div');
// See what the malware DID while having tools it COULDN'T break
const malwareState = document.body.innerHTML; // See malware's mess
originalWindow.console.log('Captured state:', malwareState); // Log safely
Why this matters for RE:
You can simultaneously:
- See what malicious scripts have done - access the polluted DOM, hooked functions, modified state
- Use unbroken tools to analyze it - pristine console, fetch, timers, event handlers
Plus: Execute JavaScript in any debug target - service workers, web workers, extension backgrounds, iframes. Perfect for analyzing complex web apps and browser extensions.
🔧 System + Terminal: Essential for Real RE Work
These two tools are game-changers for reverse engineering workflows:
System Tool - See and interact with the desktop:
- Take screenshots of running applications
- Scan UI elements with 100% accurate text extraction (no OCR needed)
- Click buttons, type text, automate any Windows application
- Perfect for: capturing debugger state, automating IDA/x64dbg, interacting with target programs
Terminal Tool - Connect to anything:
- Serial ports for embedded device debugging (ESP32, ARM, microcontrollers)
- TCP/Telnet for network device analysis
- SSH for remote system access
- Bluetooth/BLE for wireless device RE
- WebSocket for browser debugging protocols (Chrome DevTools)
- Named pipes for IPC analysis
Why this matters for RE:
When analyzing malware or firmware, you often need to:
- Run the target in a controlled environment
- Observe behavior - watch windows, network traffic, serial output
- Interact - click dialogs, respond to prompts, inject input
- Capture state - screenshots, memory dumps, communication logs
With System + Terminal, the AI can do ALL of this autonomously. It can run a sample, watch what windows appear, take screenshots, capture network traffic, and correlate everything with the static analysis from Ghidra.
Example: Store analysis in database
{
"operation": "call_tool",
"tool_name": "sqlite",
"arguments": {
"input": {
"sql": "INSERT INTO functions (name, addr) VALUES (?, ?)",
"params": ["main", "0x140001000"]
}
}
}
Example: Take screenshot of debugger
{
"operation": "call_tool",
"tool_name": "system",
"arguments": {
"input": {
"operation": "take_screenshot",
"hwnd": "0x001234",
"tool_unlock_token": "..."
}
}
}
Example: Monitor embedded device serial output
{
"operation": "call_tool",
"tool_name": "terminal",
"arguments": {
"input": {
"operation": "open_session",
"endpoint": "COM3",
"baud_rate": 115200,
"tool_unlock_token": "..."
}
}
}
💡 Use Cases
🔍 Malware Analysis
- Automatically find suspicious functions
- Extract strings and IOCs
- Decompile and analyze crypto routines
- Store findings in database
🛡️ Vulnerability Research
- Find dangerous API calls
- Trace data flow through functions
- Identify buffer overflow patterns
- Document findings automatically
📚 Documentation Generation
- Extract function signatures
- Generate API documentation
- Create call graphs
- Build symbol databases
🤖 Automated RE Workflows
- Batch analyze binaries
- Compare function similarities
- Track changes between versions
- Generate reports
🔧 Technical Details
Thread Safety
- All Ghidra API calls execute on Swing EDT when needed
- Background SSE thread handles network communication
- Concurrent session management for parallel analysis
Expression Parser
- Hand-written recursive descent parser
- Handles method chains, nested calls, string escaping
- Type-aware argument conversion
- Full Java primitive support
Session Persistence
- Variables persist within sessions
- Multiple sessions for parallel work
- Clear sessions programmatically
⚠️ Limitations
- No loop constructs - Use scripts with variable assignments
- No conditionals - Ternary expressions work, but no if/else blocks
- Iterator consumption - Iterators get consumed when displayed
- Swing EDT - Some operations must run on main thread
🤝 Contributing
Want to contribute? PRs welcome!
Ideas for Contributors
- Add more expression language features (loops, conditionals)
- Create example scripts for common RE tasks
- Improve error messages and debugging
- Build integrations with other tools
- Write tutorials and documentation
📄 License
Apache 2.0 - See LICENSE file for details
👤 Author
Created by [AuraFriday](https://github.com/AuraFriday
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: AuraFriday
- Source: AuraFriday/ghidra_mcp
- License: Apache-2.0
- Homepage: https://aurafriday.com/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.