Ghidra MCP Server

Ghidra MCP Server

Exposes Ghidra headless binary analysis capabilities via the Model Context Protocol, enabling AI assistants to decompile, analyze, and emulate binaries with 32 tools and multi-binary support.

Category
Visit Server

README

Ghidra MCP Server

A Ghidra headless server exposed via the Model Context Protocol (MCP), designed for binary analysis and malware reverse engineering with AI assistants. Runs locally or in Docker.

Features

  • 32 MCP tools for binary analysis: decompilation, function listing, string search, cross-references, byte pattern search, malware-focused analysis, advanced RE tools (CFG, call graphs, instruction search), and emulation
  • 3 emulation tools — emulate functions with automatic calling convention handling, single-step through code, read registers and memory
  • 5 MCP resources for browsing binary metadata, functions, strings, and imports
  • Multi-binary support — analyze multiple binaries simultaneously in a single Ghidra project
  • Malware analysis tools — entropy analysis (packing detection), suspicious API categorization, section anomaly detection
  • Code Mode — token-saving operating mode that exposes only 2 tools (search + execute) instead of all 32, for LLM-efficient usage
  • Ghidra Server — connect to a shared Ghidra server for collaborative reverse engineering with checkout/checkin workflow
  • SSE transport — run as an HTTP server with --transport sse for network-accessible deployments
  • Docker or local — runs in an isolated container or directly on your machine via stdio transport
  • PyGhidra 3.0 — direct Ghidra Java API access via in-process JVM (no Ghidra scripts needed)

Quick Start

Docker (recommended)

# Build the image
docker compose build

# Run in full mode (all 32 tools)
docker compose run --rm -i ghidra-mcp

# Run in code mode (2 tools: search + execute, saves tokens)
docker compose run --rm -i ghidra-mcp --mode code

See Client Configuration for setup with Claude Desktop, Claude Code, OpenCode, and Continue.dev.

Apple Silicon

The Docker image builds natively on arm64. Since Ghidra releases don't include pre-built linux_arm_64 decompiler binaries, the Dockerfile automatically builds the decompiler from source during docker compose build (adds ~2 min to build time, requires no extra configuration). If you encounter issues, you can force x86_64 emulation by uncommenting platform: linux/amd64 in docker-compose.yml (slower due to Rosetta/QEMU).

Local (no Docker)

Prerequisites

  • Python 3.11+python.org/downloads. On Windows, check "Add Python to PATH" during installation.
  • Java 21+ (e.g., OpenJDK 21) — JAVA_HOME must be set and java must be on your PATH.
    • Linux/macOS: export JAVA_HOME=/path/to/jdk-21 (add to ~/.bashrc or ~/.zshrc)
    • Windows: Set JAVA_HOME via System Properties > Environment Variables (e.g., C:\Program Files\Eclipse Adoptium\jdk-21)
  • Ghidra 12.0.4 — download and extract (no installer needed).
  • GHIDRA_INSTALL_DIR environment variable pointing to your Ghidra installation.
    • Linux/macOS: export GHIDRA_INSTALL_DIR=/path/to/ghidra_12.0.4_PUBLIC (add to ~/.bashrc or ~/.zshrc)
    • Windows: Set via System Properties > Environment Variables, or set GHIDRA_INSTALL_DIR=C:\ghidra\ghidra_12.0.4_PUBLIC in Command Prompt

Installation

Quick install (checks prerequisites, creates venv, installs):

# Linux/macOS
./scripts/install.sh

# Windows (PowerShell)
.\scripts\install.ps1

Manual install:

python -m venv venv

# Linux/macOS:
source venv/bin/activate

# Windows (Command Prompt):
venv\Scripts\activate

# Windows (PowerShell):
venv\Scripts\Activate.ps1

pip install -e .

Usage

# Activate the virtual environment first (see Installation for Windows commands)
source venv/bin/activate

# Full mode (default) — all 32 tools
ghidra-mcp

# Code mode — 2 meta-tools (search + execute)
ghidra-mcp --mode code

# Custom project directory and name
ghidra-mcp --project-dir ~/my-projects --project-name my_project
# Windows: ghidra-mcp --project-dir C:\Users\you\my-projects --project-name my_project

# SSE transport (HTTP server on localhost:8080)
pip install -e ".[sse]"
ghidra-mcp --transport sse

# SSE with custom host and port
ghidra-mcp --transport sse --host 0.0.0.0 --port 3000

See Client Configuration for setup with Claude Desktop, Claude Code, OpenCode, and Continue.dev.

Client Configuration

All examples show full mode. For code mode, append --mode code (Docker: add "--mode", "code" to the args array; Local: add "--mode", "code" to args or the command).

Claude Desktop

Config file: claude_desktop_config.json

Docker:

{
  "mcpServers": {
    "ghidra": {
      "command": "docker",
      "args": ["compose", "-f", "/path/to/docker-compose.yml", "run", "--rm", "-i", "ghidra-mcp"]
    }
  }
}

Local:

{
  "mcpServers": {
    "ghidra": {
      "command": "/path/to/venv/bin/ghidra-mcp",
      "env": {
        "GHIDRA_INSTALL_DIR": "/path/to/ghidra_12.0.4_PUBLIC"
      }
    }
  }
}

Note: Use the full path to ghidra-mcp inside your virtual environment. If GHIDRA_INSTALL_DIR is already set in your shell profile, you can omit the env block. Windows: Use C:\path\to\venv\Scripts\ghidra-mcp.exe as the command and Windows-style paths for GHIDRA_INSTALL_DIR.

Claude Code

Docker — via CLI:

claude mcp add ghidra -- docker compose -f /path/to/docker-compose.yml run --rm -i ghidra-mcp

Docker — via project config (.mcp.json in project root):

{
  "mcpServers": {
    "ghidra": {
      "command": "docker",
      "args": ["compose", "-f", "/path/to/docker-compose.yml", "run", "--rm", "-i", "ghidra-mcp"]
    }
  }
}

Local — via CLI:

claude mcp add ghidra --env GHIDRA_INSTALL_DIR=/path/to/ghidra_12.0.4_PUBLIC -- /path/to/venv/bin/ghidra-mcp

Local — via project config (.mcp.json):

{
  "mcpServers": {
    "ghidra": {
      "command": "/path/to/venv/bin/ghidra-mcp",
      "env": {
        "GHIDRA_INSTALL_DIR": "/path/to/ghidra_12.0.4_PUBLIC"
      }
    }
  }
}

Note: Use the full path to ghidra-mcp inside your virtual environment. If GHIDRA_INSTALL_DIR is already set in your shell profile, you can omit the env block and --env flag. Windows: Use C:\path\to\venv\Scripts\ghidra-mcp.exe as the command and Windows-style paths for GHIDRA_INSTALL_DIR.

OpenCode

Config file: opencode.json (project root or ~/.config/opencode/opencode.json)

Docker:

{
  "mcp": {
    "ghidra": {
      "type": "local",
      "command": ["docker", "compose", "-f", "/path/to/docker-compose.yml", "run", "--rm", "-i", "ghidra-mcp"],
      "enabled": true
    }
  }
}

Local:

{
  "mcp": {
    "ghidra": {
      "type": "local",
      "command": ["/path/to/venv/bin/ghidra-mcp"],
      "environment": {
        "GHIDRA_INSTALL_DIR": "/path/to/ghidra_12.0.4_PUBLIC"
      },
      "enabled": true
    }
  }
}

Note: Use the full path to ghidra-mcp inside your virtual environment. If GHIDRA_INSTALL_DIR is already set in your shell profile, you can omit the "environment" block. Windows: Use C:\path\to\venv\Scripts\ghidra-mcp.exe in the command array and Windows-style paths for GHIDRA_INSTALL_DIR.

Continue.dev

Config file: .continue/mcpServers/ghidra.json

Note: MCP tools are only available in Continue's Agent mode, not Chat mode.

Docker:

{
  "mcpServers": [
    {
      "name": "Ghidra",
      "type": "stdio",
      "command": "docker",
      "args": ["compose", "-f", "/path/to/docker-compose.yml", "run", "--rm", "-i", "ghidra-mcp"]
    }
  ]
}

Local:

{
  "mcpServers": [
    {
      "name": "Ghidra",
      "type": "stdio",
      "command": "/path/to/venv/bin/ghidra-mcp",
      "env": {
        "GHIDRA_INSTALL_DIR": "/path/to/ghidra_12.0.4_PUBLIC"
      }
    }
  ]
}

Note: Use the full path to ghidra-mcp inside your virtual environment. If GHIDRA_INSTALL_DIR is already set in your shell profile, you can omit the env block. Windows: Use C:\path\to\venv\Scripts\ghidra-mcp.exe as the command and Windows-style paths for GHIDRA_INSTALL_DIR.

Server Modes

The server supports three operating modes, selectable via the --mode flag:

Mode Flag Tools Registered Use Case
Full --mode full (default) All 32 tools + 5 resources Direct tool access, best for exploration and interactive use
Code --mode code 2 tools (search + execute) Token-efficient, best for automated pipelines and cost-sensitive usage
Script --mode script 6 tools (search_api + get_class_info + execute_script + binary management) Direct Ghidra Java API access via live reflection and Python code execution

Full and Code modes provide identical analytical capabilities — Code Mode routes calls through a dynamic dispatcher instead of registering each tool individually. Script Mode goes further by exposing the raw Ghidra Java API for custom analysis not covered by the built-in tools.

MCP Tools (Full Mode)

Project Management

Tool Description
import_binary Import a binary file for analysis
upload_binary Upload a binary via base64-encoded data
list_binaries List all imported binaries
delete_binary Remove a binary from the project

Analysis

Tool Description
list_functions List functions with pagination and name filtering
decompile_function Decompile a function to C pseudocode
rename_function Rename a function
rename_variable Rename a variable (parameter or local) within a function
rename_label Rename a symbol/label in the program
list_strings List defined strings
search_strings Search strings by substring or regex
list_imports List imported symbols
list_exports List exported symbols
get_xrefs Get cross-references to/from an address
search_bytes Search for hex byte patterns with wildcards
get_memory_bytes Read raw bytes from an address
search_instructions Regex search over disassembly mnemonics/operands

Malware Analysis

Tool Description
get_entropy Per-section Shannon entropy, packing detection
detect_suspicious_apis Categorized suspicious imports (injection, persistence, crypto, network, anti-debug)
get_sections Sections with permissions, entropy, and anomaly flags (W+X, unusual names)

Advanced Analysis

Tool Description
get_function_summary Rich function metadata (params, callees, callers, strings, complexity) without decompilation
get_basic_blocks Control-flow graph basic blocks with instructions and edges
get_call_graph Function call graph with BFS depth control (callees/callers/both)

Emulation

Emulate functions using Ghidra's EmulatorHelper API. The emulator automatically handles calling conventions — arguments are placed in the correct registers or stack locations based on the function's parameter metadata, and return values are extracted from the appropriate return register.

Tool Description
emulate_function Emulate a function with optional integer arguments, get return value
emulate_step Single-step an existing emulator session, read registers and memory
emulate_session_destroy Destroy an emulator session and free its resources

Server Connectivity

Connect to a shared Ghidra server for collaborative reverse engineering. Programs opened from the server are available to all analysis tools. Supports checkout/checkin workflow with exclusive locking.

Tool Description
connect_server Connect to a Ghidra server (host, port, username, optional password)
disconnect_server Disconnect from server, release checkouts, clean up
list_repositories List available repositories on the connected server
list_server_files List files and subfolders in a server repository
open_from_server Open a program from the server for analysis (with optional checkout)
checkin_file Check in changes back to the Ghidra server

Server Workflow

# 1. Connect to the Ghidra server
connect_server(host="ghidra.example.com", port=13100, username="analyst")

# 2. Browse available repositories and files
list_repositories()
list_server_files(repository_name="malware-lab")

# 3. Open a program (checkout for editing)
open_from_server(repository_name="malware-lab", file_path="/samples/trojan.exe", checkout=True)

# 4. Analyze with any tool — decompile, rename functions, etc.
decompile_function(binary_name="trojan.exe", name_or_addr="main")
rename_function(binary_name="trojan.exe", old_name="FUN_00401000", new_name="decrypt_payload")

# 5. Save changes back to the server
checkin_file(binary_name="trojan.exe", comment="Identified decryption routine")

# 6. Disconnect when done
disconnect_server()

Emulation Workflow

The typical emulation workflow is:

  1. Start emulation with emulate_function — sets up the emulator, places arguments, runs until the function returns or the step limit is reached, and returns the result including the return value.

  2. Inspect interactively (optional) with emulate_step — after emulate_function creates a session, you can single-step through the remaining execution, reading specific registers and memory regions at each step.

  3. Clean up with emulate_session_destroy — disposes the emulator and frees resources. Sessions are also cleaned up automatically when a binary is deleted or the server shuts down.

Emulation Example

# Step 1: Emulate a function with arguments
emulate_function(binary_name="malware.exe", name_or_addr="decrypt_string", args=[0x00402000, 16])
# Returns: {
#   "session_key": "malware.exe:decrypt_string",
#   "return_value": 4198400,
#   "steps_executed": 847,
#   "hit_breakpoint": true,
#   ...
# }

# Step 2: Inspect registers and memory after execution
emulate_step(binary_name="malware.exe", name_or_addr="decrypt_string",
             count=0, read_registers=["RAX", "RCX"],
             read_memory=[{"address": "0x00402000", "size": 32}])
# Returns: {
#   "registers": {"RAX": "0x401000", "RCX": "0x0"},
#   "memory": [{"address": "0x00402000", "hex": "48656c6c6f..."}],
#   ...
# }

# Step 3: Clean up
emulate_session_destroy(binary_name="malware.exe", name_or_addr="decrypt_string")

Emulation Limitations

  • External calls: If the emulated function calls imported/external functions (e.g., printf, malloc), emulation will stop or produce undefined behavior. Only self-contained functions emulate correctly without additional stubbing.
  • Architecture support: x86/x86-64 (push sentinel return address to stack) and ARM/AARCH64 (set LR register) are supported. Other architectures will raise an error.
  • Integer arguments only: The current implementation handles integer arguments via register/stack writes. Floating-point and struct arguments are not supported.
  • Step limit: A max_steps parameter (default: 10,000) prevents runaway emulation.

MCP Resources

URI Description
ghidra://binaries All binaries in the project
ghidra://binary/{name}/info Binary metadata (arch, format, hashes, entry point)
ghidra://binary/{name}/functions Full function list
ghidra://binary/{name}/strings All defined strings
ghidra://binary/{name}/imports All imported symbols

Code Mode

Code Mode is a token-efficient operating mode that replaces all 32 individual tool registrations with just 2 meta-tools: search and execute. This dramatically reduces the number of tool schemas sent to the LLM on every request, saving tokens and cost while preserving full analytical capability.

Activation

# Docker
docker compose run --rm -i ghidra-mcp --mode code

# Local
ghidra-mcp --mode code

Tools

search(query?)

Search the tool catalog. Returns tool names, descriptions, and full parameter signatures.

Parameter Type Required Description
query string No Substring to filter tool names and descriptions. Returns all 32 tools if omitted.

Example — find emulation tools:

search(query="emulate")
# Returns:
# [
#   {"tool": "emulate_function", "description": "Emulate a function with optional arguments...",
#    "parameters": [{"name": "binary_name", "type": "string", "required": true}, ...]},
#   {"tool": "emulate_step", ...},
#   {"tool": "emulate_session_destroy", ...}
# ]

Example — find tools related to entropy:

search(query="entropy")
# Returns tools whose name or description contains "entropy"

execute(method, params?)

Execute any Ghidra analysis tool by name with the given parameters.

Parameter Type Required Description
method string Yes Tool name from the catalog (use search to discover available tools).
params object No Keyword arguments as a dictionary. Omit for tools with no required params.

Example — list functions:

execute(method="list_functions", params={"binary_name": "test.elf", "filter": "main", "limit": 10})

Example — decompile a function:

execute(method="decompile_function", params={"binary_name": "test.elf", "name_or_addr": "main"})

Example — emulate a function:

execute(method="emulate_function", params={"binary_name": "test.elf", "name_or_addr": "decrypt", "args": [1, 2]})

Example — list all binaries (no params needed):

execute(method="list_binaries")

Error Handling

  • Unknown method: Raises ValueError with the list of all available method names.
  • Missing required parameter: Raises TypeError from the underlying Python method call.
  • Bridge errors: KeyError (binary not found), RuntimeError (decompilation failure), etc. propagate directly with descriptive messages.

When to Use Code Mode

Scenario Recommended Mode
Interactive exploration with Claude Desktop Full
Automated analysis pipelines Code
Cost-sensitive / high-volume usage Code
First time using the server Full
LLM with small context window Code
Custom analysis beyond built-in tools Script
Exploring Ghidra API for scripting Script

Script Mode

Script Mode provides direct access to the Ghidra Java API via live reflection and Python code execution. Instead of using pre-built tools, the LLM can search API classes, inspect method signatures, and execute arbitrary Python code with full Ghidra API access — like a programmable Ghidra scripting environment.

Activation

# Docker
docker compose run --rm -i ghidra-mcp --mode script

# Local
ghidra-mcp --mode script

Tools

search_api(query, package?)

Search Ghidra Java API classes and methods by keyword using live Java reflection.

search_api(query="FunctionManager")
# Returns class info with all method signatures

search_api(query="getParameters", package="ghidra.program.model.listing")
# Returns classes in that package with matching methods

get_class_info(class_name)

Get full reflection info for a specific class — methods, parameter types, return types, interfaces.

get_class_info(class_name="ghidra.program.model.listing.Function")
# Returns: {"class": "...", "methods": [{"name": "getName", "params": [], "returns": "String"}, ...]}

get_class_info(class_name="Function")  # Short name also works

execute_script(code, binary_name?)

Execute a Python code snippet with full Ghidra Java API access.

execute_script(
    binary_name="malware.exe",
    code="""
fm = program.getFunctionManager()
funcs = list(fm.getFunctions(True))
result = []
for f in funcs[:5]:
    result.append({
        'name': f.getName(),
        'addr': str(f.getEntryPoint()),
        'cc': f.getCallingConventionName(),
    })
return result
"""
)

Pre-defined variables in script scope:

  • bridge — GhidraBridge instance
  • program / currentProgram — Program object (if binary_name provided)
  • monitor — ConsoleTaskMonitor
  • All ghidra.* packages importable via normal Python imports

Configuration

CLI Flags

Flag Default Description
--mode full Server mode: full, code, or script
--transport stdio Transport protocol: stdio or sse
--host localhost Host to bind for SSE transport
--port 8080 Port to bind for SSE transport
--project-dir ./ghidra-projects Directory for Ghidra projects
--project-name mcp_project Ghidra project name

Environment Variables

Variable Default Description
GHIDRA_INSTALL_DIR (auto-detect) Path to Ghidra installation directory (required if PyGhidra auto-detection fails)
GHIDRA_ANALYSIS_TIMEOUT_SECONDS 300 Analysis timeout per binary
GHIDRA_MAX_HEAP 2g JVM max heap size

Docker Volumes

Path Purpose
/home/ghidra/binaries Input binaries (mounted read-only)
/home/ghidra/projects Persistent Ghidra project data

Development

# Install dev dependencies
pip install -e ".[dev]"

# Run tests (uses mocked GhidraBridge, no Ghidra needed)
pytest tests/ -v

# 192 tests covering full mode, emulation, server, code mode, script mode, CLI, and validation

Architecture

MCP Client (Claude Desktop / Claude Code / OpenCode / Continue.dev / ...)
  ↕ stdio or SSE (HTTP)
FastMCP Server (server.py)
  ├── Full Mode: 32 @mcp.tool() + 5 @mcp.resource()
  ├── Code Mode: search + execute → _dispatch()
  └── Script Mode: search_api + get_class_info + execute_script
        ↕
GhidraBridge (ghidra_bridge.py)
  ├── Programs cache     (dict[str, Program])
  ├── Decompilers cache  (dict[str, DecompInterface])
  └── Emulators cache    (dict[str, EmulatorHelper])
        ↕
PyGhidra / JPype / JVM
        ↕
Ghidra Java API
  • FastMCP handles MCP protocol over stdio or SSE
  • GhidraBridge manages the JVM lifecycle, Ghidra project, cached program handles, decompiler instances, and emulator sessions
  • PyGhidra provides in-process access to Ghidra's Java API via JPype (no separate Ghidra process needed)
  • Code Mode dispatcher (_dispatch) translates execute(method, params) calls into the appropriate bridge method invocations, handling parameter renaming and response wrapping

License

MIT

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured