Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

908 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ghidra MCP Server

Tests Release License GitHub Sponsors

Python Java Ghidra MCP

Stars Last commit Discussions Issues OpenSSF Scorecard

If you find this useful, please ⭐ star the repo — it helps others discover it!

If Ghidra MCP saves you time, consider sponsoring the project. One-time and recurring support both help fund compatibility updates, production hardening, docs, and new tooling.

A production-ready Model Context Protocol (MCP) server that bridges Ghidra's powerful reverse engineering capabilities with modern AI tools and automation frameworks. 272 MCP tools, battle-tested AI workflows, and the most comprehensive Ghidra-MCP integration available — now including P-code emulation, live debugger integration, and PCode-graph data flow analysis.

Why Ghidra MCP?

Most Ghidra MCP implementations give you a handful of read-only tools and call it a day. This project is different — it was built by a reverse engineer who uses it daily on real binaries, not as a demo.

  • 272 MCP tools — 3x more than any competing implementation. Not just read operations — full write access for renaming, typing, commenting, structure creation, script execution, P-code emulation, and live debugging.
  • Battle-tested AI workflows — Proven documentation workflows (V5) refined across hundreds of functions. Includes step-by-step prompts, Hungarian notation reference, batch processing guides, and orphaned code discovery.
  • Production-grade reliability — Atomic transactions, batch operations (93% API call reduction), configurable timeouts, and graceful error handling. No silent failures.
  • Cross-binary documentation transfer — SHA-256 function hash matching propagates documentation across binary versions automatically. Document once, apply everywhere.
  • Full Ghidra Server integration — Connect to shared Ghidra servers, manage repositories, version control, checkout/checkin workflows, and multi-user collaboration.
  • Headless and GUI modes — Run with or without the Ghidra GUI. Docker-ready for CI/CD pipelines and automated analysis at scale.
  • Opinionated by design — v5.0 moves naming conventions, type safety, and documentation standards into the tool layer. AI agents and human engineers produce consistent output without style guides in every prompt.

Convention Enforcement

You've been there: six months into a project you find ProcessItem, process_items, handleItem, and ItemProc in the same codebase — four functions doing the same thing, named by four different sessions or engineers with no shared contract. Fixing it takes longer than it should, and the problem will happen again.

v5.0 moves conventions from "things to remember" into the tool layer, where they can actually be enforced.

Tier Behavior Example
Auto-fix Applied silently count field on a uint32 → auto-prefixed dwCount on save
Warn Change goes through, warning returned processData → "name should be PascalCase with a verb: ProcessData"
Reject Change blocked with explanation undefined → undefined type change → "no-op rejected, type unchanged"

For AI agents, this means consistent output across every session, every model, every run — without pasting a style guide into every prompt. The tool knows the rules; the model just needs to make the call.

For teams, it eliminates the entire class of review comment that says "that's not our naming convention." Convention arbitration stays in the tool, not in code review.

For solo work at scale, analyze_function_completeness gives you a 0–100% score that measures honestly: structural deductions (unfixable compiler artifacts) are forgiven in your effective score, log-scaling prevents one bad category from burying everything else, and tiered plate comment quality means you know exactly what's missing and why.

🌟 Features

Core MCP Integration

  • Full MCP Compatibility — Complete implementation of Model Context Protocol
  • 272 MCP tools — Comprehensive API surface covering every aspect of binary analysis
  • Production-Ready Reliability — Atomic transactions, batch operations, configurable timeouts
  • Real-time Analysis — Live integration with Ghidra's analysis engine

Compatibility note: MCP tool names are normalized for GitHub Copilot CLI and CAPI validation. Exposed tool names use lowercase letters, digits, underscores, and hyphens only; nested HTTP paths such as /debugger/status are advertised as names like debugger_status_2 when needed to avoid collisions with static bridge tools.

Binary Analysis Capabilities

  • Function Analysis — Decompilation, call graphs, cross-references, completeness scoring
  • Data Flow Analysis — PCode-graph value propagation (forward / backward) from any variable or register
  • Data Structure Discovery — Struct/union/enum creation with field analysis and naming suggestions
  • String Extraction — Regex search, quality filtering, and string-anchored function discovery
  • Import/Export Analysis — Symbol tables, external locations, ordinal import resolution
  • Memory & Data Inspection — Raw memory reads, byte pattern search, array boundary detection
  • Cross-Binary Documentation — Function hash matching and documentation propagation across versions

Dynamic Analysis (v5.4.0)

  • P-code Emulation — Run any function in isolation via Ghidra's EmulatorHelper; brute-force API hash resolution in milliseconds
  • Live Debugger Integration — 17 Java endpoints + 22 Python bridge tools over Ghidra's TraceRmi framework (dbgeng on Windows PE, gdb/lldb otherwise): attach, step, breakpoints, registers, memory reads, non-breaking function tracing, ASLR-aware static↔dynamic address translation

AI-Powered Reverse Engineering Workflows

  • Function Documentation Workflow V5 — 7-step process for complete function documentation with Hungarian notation, type auditing, and automated verification scoring
  • Batch Documentation — Parallel subagent dispatch for documenting multiple functions simultaneously
  • Orphaned Code Discovery — Automated scanner finds undiscovered functions in gaps between known code
  • Data Type Investigation — Systematic workflows for structure discovery and field analysis
  • Cross-Version Matching — Hash-based function matching across different binary versions

Development & Automation

  • Ghidra Script Management — Create, run, update, and delete Ghidra scripts entirely via MCP
  • Multi-Program Support — Switch between and compare multiple open programs
  • Batch Operations — Bulk renaming, commenting, typing, and label management (93% fewer API calls)
  • Headless Server — Full analysis without Ghidra GUI — Docker and CI/CD ready
  • Project & Version Control — Create projects, manage files, Ghidra Server integration
  • Analysis Control — List, configure, and trigger Ghidra analyzers programmatically

🚀 Quick Start

Prerequisites

  • Java 21 LTS (OpenJDK recommended)
  • Apache Maven 3.9+
  • Ghidra 12.1.2 (or compatible version)
  • Python 3.10+ with uv (recommended) or pip + venv

Shared Ghidra Server users: Ghidra 12.1.2 clients require a Ghidra Server at 12.1, 12.0.5, or a newer compatible version. Upgrade the server before using this plugin from a 12.1 client.

Ghidra 12.1.2 ships Jython as an optional extension. Java scripts work by default, but .py scripts in ghidra_scripts/ require installing the Jython extension from File > Install Extensions and restarting Ghidra.

Installation

Recommended for all platforms: use python -m tools.setup directly.

ensure-prereqs installs runtime Python requirements plus the Ghidra JARs needed in the local Maven repository. deploy copies the build output, installs the user-profile extension, and patches Ghidra user config.

  1. Clone the repository:

    git clone https://github.com/bethington/ghidra-mcp.git
    cd ghidra-mcp
  2. Recommended: run environment preflight first:

    python -m tools.setup preflight --ghidra-path "F:\ghidra_12.1.2_PUBLIC"
    
  3. Build and deploy to Ghidra:

    python -m tools.setup ensure-prereqs --ghidra-path "F:\ghidra_12.1.2_PUBLIC"
    python -m tools.setup build
    python -m tools.setup deploy --ghidra-path "F:\ghidra_12.1.2_PUBLIC"
    

    deploy saves/closes an already-running matching Ghidra instance when needed, installs the extension, starts Ghidra, waits for MCP health, and runs schema smoke checks.

  4. Optional strict/manual mode (advanced):

    # Skip automatic prerequisite setup
    python -m tools.setup build
    python -m tools.setup deploy --ghidra-path "F:\ghidra_12.1.2_PUBLIC"
    
  5. Show command help:

    python -m tools.setup --help
    
  6. Optional build-only mode (advanced/troubleshooting):

    python -m tools.setup build
    

    Supported build path: python -m tools.setup build uses Maven under the hood and is the canonical workflow used by the repo tasks and docs.

    # Manual Maven build (requires Ghidra deps already installed in local .m2)
    mvn clean package assembly:single -DskipTests
    # Secondary/manual Gradle build path only (not used by tools.setup or VS Code tasks)
    GHIDRA_INSTALL_DIR=/path/to/ghidra gradle buildExtension

Installation (Linux — Ubuntu/Debian)

  1. Clone the repository:

    git clone https://github.com/bethington/ghidra-mcp.git
    cd ghidra-mcp
  2. Install system prerequisites (if not already installed):

    sudo apt update && sudo apt install -y openjdk-21-jdk maven python3 python3-pip python3-venv curl jq unzip

    Debian/Kali/Ubuntu 23.04+ note (PEP 668): these distros mark the system Python as externally managed, so a bare pip install fails with error: externally-managed-environment. Don't work around it with --break-system-packages — it can corrupt apt-managed tooling. Instead use uv (recommended — it creates and manages a project-local .venv automatically, and is what this repo's commands use):

    curl -LsSf https://astral.sh/uv/install.sh | sh
    uv run bridge-mcp-ghidra    # resolves deps into .venv and starts the bridge

    or a classic virtual environment:

    python3 -m venv .venv && source .venv/bin/activate
    pip install -e .
    bridge-mcp-ghidra
  3. Run environment preflight:

    python -m tools.setup preflight --ghidra-path ~/ghidra_12.1.2_PUBLIC
  4. Build and deploy to Ghidra (single command):

    python -m tools.setup ensure-prereqs --ghidra-path ~/ghidra_12.1.2_PUBLIC
    python -m tools.setup build
    python -m tools.setup deploy --ghidra-path ~/ghidra_12.1.2_PUBLIC

    This will:

    • Install Ghidra JAR dependencies into your local ~/.m2/repository
    • Build GhidraMCP-<version>.zip with Maven
    • Extract the extension to ~/.config/ghidra/ghidra_<version>_PUBLIC/Extensions/
    • Update preferences with LastExtensionImportDirectory
    • Install Python requirements
  5. Optional: setup only Maven dependencies:

    python -m tools.setup install-ghidra-deps --ghidra-path ~/ghidra_12.1.2_PUBLIC
  6. Show command help:

    python -m tools.setup --help

Linux paths: The extension is installed to $HOME/.config/ghidra/ghidra_<version>_PUBLIC/Extensions/GhidraMCP/. Ghidra config files are in $HOME/.config/ghidra/ghidra_<version>_PUBLIC/.

Installation (macOS — Homebrew)

  1. Install prerequisites:

    brew install openjdk@21 maven python ghidra
  2. Clone the repository:

    git clone https://github.com/bethington/ghidra-mcp.git
    cd ghidra-mcp
  3. Install Ghidra JARs into local Maven:

     python -m tools.setup install-ghidra-deps \
        --ghidra-path /opt/homebrew/opt/ghidra/libexec
  4. Build and deploy:

     python -m tools.setup ensure-prereqs \
        --ghidra-path /opt/homebrew/opt/ghidra/libexec
     python -m tools.setup build
     python -m tools.setup deploy \
        --ghidra-path /opt/homebrew/opt/ghidra/libexec

    The extension is installed to ~/Library/ghidra/ghidra_12.1.2_PUBLIC/Extensions/GhidraMCP/.

    Note: --ghidra-version is required when using the Homebrew path because the path contains no version string.

  5. Start Ghidra and enable the plugin:

    /opt/homebrew/opt/ghidra/libexec/ghidraRun

    In the main project window: Tools > GhidraMCP > Start MCP Server

  6. Configure Cursor/Claude MCP (~/.cursor/mcp.json):

    {
      "mcpServers": {
        "ghidra": {
          "command": "uv",
          "args": ["run", "--directory", "/path/to/ghidra-mcp", "bridge-mcp-ghidra"]
        }
      }
    }

Installation (Arch Linux — AUR)

@Pandoriaantje maintains community AUR packages:

Install with your AUR helper of choice, e.g.:

yay -S ghidra-mcp        # or ghidra-mcp-git

Basic Usage

Option 1: Stdio Transport (Recommended for AI tools)

uv run bridge-mcp-ghidra          # or: python -m bridge_mcp_ghidra

To add the bridge to Autohand Code from a cloned checkout:

autohand mcp add ghidra uv run --directory /path/to/ghidra-mcp bridge-mcp-ghidra

Add --scope project before ghidra to save the server in the current project's .autohand configuration instead of your user configuration.

Option 2: Streamable HTTP Transport (Recommended for web/HTTP clients)

uv run bridge-mcp-ghidra --transport streamable-http --mcp-host 127.0.0.1 --mcp-port 8081

MCP client config for the HTTP transport (add to your client's MCP config file):

{
  "mcpServers": {
    "ghidra-mcp-http": {
      "url": "http://127.0.0.1:8081/mcp"
    }
  }
}

Browser-based clients (e.g. MCP Inspector) work out of the box: the HTTP transports answer CORS preflight (OPTIONS) requests and expose the mcp-session-id / mcp-protocol-version headers to scripts. Allowed origins mirror the Host-header policy — loopback on any port is always permitted, plus the bind host and any hosts listed in GHIDRA_MCP_ALLOWED_HOSTS.

Option 3: SSE Transport (Deprecated — use streamable-http instead)

uv run bridge-mcp-ghidra --transport sse --mcp-host 127.0.0.1 --mcp-port 8081

Bridge advanced flags

Flag Default Description
--transport stdio stdio (AI tools), streamable-http (web clients), sse (deprecated)
--mcp-host 127.0.0.1 Bind host for HTTP transports
--mcp-port Port for HTTP transports
--lazy off Load only the default tool groups on connect. Faster startup, but MCP clients that don't support tools/list_changed will see an incomplete tool list. Not recommended for Claude Code.
--no-lazy (default) Load all tool groups immediately on connect. Required for most AI clients.
--default-groups listing,function,program Comma-separated groups loaded on connect when --lazy is set.

Strict program routing (multi-program safety)

Set GHIDRA_MCP_REQUIRE_PROGRAM_SELECTORS=1 to make the bridge refuse any program-scoped call that omits a program selector, returning a clear error instead of letting the call ride the server's shared "current program" (the one switch_program and the active GUI tab move).

export GHIDRA_MCP_REQUIRE_PROGRAM_SELECTORS=1
uv run bridge-mcp-ghidra

Without this, a call that leaves program= out runs against whichever program is current, which is fine for a single-program workflow but a hazard once several programs are open: the call can read or edit the wrong binary with no error. The hazard is worse when more than one client shares a server, since each one moves that current-program global out from under the others.

With strict mode on, every program-scoped call must name its target. This covers every selector that picks an open program: plain program= and the cross-program tools' source_program/target_program or program_a/program_b (declared required, but the server still falls back to the current program when one arrives empty). A forgotten selector surfaces as a loud error on the first bad call instead of a silent write to the wrong binary. Tools with no program selector (open_program and close_program take path/name) are unaffected. Off by default: with the variable unset the bridge sends calls unchanged.

Reducing tool-context overhead

The bridge exposes a large catalog. To keep the model's tool surface small, run with --lazy (loads only listing,function,program on connect) and let the model discover the rest on demand instead of registering everything:

  • search_tools("rename function") — keyword-search the entire catalog, including tools whose group isn't loaded. Each result says whether it's callable now and, if not, the exact load_tool_group(...) call to enable it.
  • list_tool_groups() — list all categories and their load state.
  • load_tool_group("datatype") / unload_tool_group("datatype") — load or drop a category at runtime.
  • check_tools("rename_or_label,batch_set_comments") — confirm specific tools are callable right now.

search_tools works in both eager and --lazy modes, so agents that honor tools/list_changed get full discovery without the upfront context cost.

Optional: Start the standalone debugger server

uv sync --group debugger
uv run python -m debugger

The debugger server listens on http://127.0.0.1:8099/ by default and is required for the debugger_* proxy tools exposed by the MCP bridge.

Debugger server flags:

Flag Default Description
--port 8099 HTTP server port
--host 127.0.0.1 Bind address (0.0.0.0 to expose on LAN)
--exports-dir Path to a dll_exports/ directory for ordinal-to-name resolution
--log-level INFO DEBUG, INFO, WARNING, or ERROR

Set GHIDRA_DEBUGGER_URL in .env if you change the default port or host so the bridge can find it.

In Ghidra

  1. Start Ghidra and open a CodeBrowser window
  2. In CodeBrowser, enable the plugin via File > Configure > Configure All Plugins > GhidraMCP
  3. Optional: configure custom port via CodeBrowser > Edit > Tool Options > GhidraMCP HTTP Server
  4. Start the server via Tools > GhidraMCP > Start MCP Server
  5. The server runs on http://127.0.0.1:8089/ by default

Verify It's Working

# Quick health check
curl http://127.0.0.1:8089/check_connection
# Expected: "Connected: GhidraMCP plugin running with program '<name>'"

# Get version info
curl http://127.0.0.1:8089/get_version

Support This Project

If Ghidra MCP saves you engineering or reverse-engineering time, consider sponsoring the project.

  • One-time sponsorship helps fund fixes, compatibility updates, and release work.
  • Recurring sponsorship helps keep maintenance, docs, and production hardening moving.
  • Company support helps prioritize long-term reliability for the bridge, headless server, debugger integration, and workflow tooling.

🔒 Security

GhidraMCP is designed for localhost-only development. The default configuration — HTTP server bound to 127.0.0.1, no authentication — is safe on a trusted single-user workstation and matches pre-v5.4.1 behavior.

If you expose the server beyond loopback, configure these three environment variables first. The server refuses to start on a non-loopback bind without a token.

Env var Effect
GHIDRA_MCP_AUTH_TOKEN When set, every HTTP request must carry Authorization: Bearer <token>. Timing-safe comparison. /mcp/health, /health, /check_connection are exempt.
GHIDRA_MCP_ALLOW_SCRIPTS Set to 1, true, or yes to enable /run_script_inline and /run_ghidra_script. Off by default as of v5.4.1 — these endpoints execute arbitrary Java against the Ghidra process. In headless mode this also triggers OSGi BundleHost initialization at server startup (Felix framework, ~hundreds of ms); leave it off if you don't need script execution.
GHIDRA_MCP_FILE_ROOT When set to a directory path, filesystem-path endpoints (/load_program, /import_file, /open_project, /delete_file, etc.) canonicalize the input and require it to fall under this root. Prevents path-traversal.

Name-quality enforcement is separate from security. By default, rename_function_by_address and global write endpoints reject names that fail the built-in quality gates, and struct field writes apply the built-in field prefix convention. Disable the built-in convention layer with Edit > Tool Options > GhidraMCP HTTP Server > Strict Naming Enforcement. The same Tool Options checkbox covers rename_data, rename_global_variable, set_global, the apply_data_type prefix/type guard, and struct-field Hungarian prefix auto-fixes in create_struct, add_struct_field, and modify_struct_field. The setting is read when the MCP server starts or restarts. Function/global convention warnings are still returned when enforcement is disabled.

Example: exposing to a private LAN with auth

export GHIDRA_MCP_AUTH_TOKEN=$(openssl rand -hex 32)
export GHIDRA_MCP_ALLOW_SCRIPTS=1     # only if your workflow needs it
export GHIDRA_MCP_FILE_ROOT=/srv/ghidra/inputs

java -jar GhidraMCPHeadless.jar --bind 0.0.0.0 --port 8089

Ghidra Server authentication

When connecting to a shared Ghidra Server, GhidraMCP can suppress the password dialog automatically. It resolves credentials in this order (first non-empty value wins):

Compatibility note: Ghidra 12.1.2 clients require Ghidra Server 12.1.2, 12.0.5, or a newer compatible server. Older shared servers are not safe targets for a 12.1 client upgrade.

  1. GHIDRA_SERVER_PASSWORD environment variable (or .env file in the Ghidra install directory or ~)
  2. ~/.ghidra-cred — single-line password file in your home directory
  3. <ghidra-install-dir>/.ghidra-cred

Username resolves similarly: GHIDRA_SERVER_USER env var → user.name system property.

If no password is found, Ghidra shows its normal GUI prompt. Set these in .env (see .env.template for the full block) to enable silent auth.

Migration from v5.4.0 → v5.4.1

  • Script endpoints now default-off. If you relied on /run_script_inline or /run_ghidra_script, export GHIDRA_MCP_ALLOW_SCRIPTS=1. This is a deliberate breaking change; the prior default was unsafe.
  • Localhost-only deployments need no changes. Auth, bind refusal, and path-root checks are all opt-in.

❓ Troubleshooting

"GhidraMCP" menu not appearing in Tools

Cause: Plugin not enabled or installed incorrectly.

Solution:

  1. Verify extension is installed: File > Install Extensions — GhidraMCP should be listed
  2. Enable the plugin: File > Configure > Configure All Plugins > GhidraMCP (check the box)
  3. Restart Ghidra after installation/enabling

Server not responding / Connection refused

Cause: Server not started or wrong port.

Solution:

  1. Ensure you started the server: Tools > GhidraMCP > Start MCP Server
  2. Check configured port: Edit > Tool Options > GhidraMCP HTTP Server
  3. Check if port is in use:
    # Linux/macOS
    lsof -i :8089
    # Windows
    netstat -ano | findstr :8089
  4. Look for errors in Ghidra console: Window > Console

pip install fails with error: externally-managed-environment

Cause: PEP 668. Debian-family distros (Debian 12+, Kali, Ubuntu 23.04+) mark the system Python as externally managed, so global pip install is blocked to protect apt-managed packages.

Solution: Use a virtual environment — never --break-system-packages. The recommended path is uv, which manages a project-local .venv automatically:

curl -LsSf https://astral.sh/uv/install.sh | sh
cd ghidra-mcp
uv run bridge-mcp-ghidra

Or a classic venv:

python3 -m venv .venv && source .venv/bin/activate
pip install -e .
bridge-mcp-ghidra

python -m debugger fails with ModuleNotFoundError for pybag or comtypes

Cause: The standalone debugger server uses optional Windows-only Python dependencies that are not installed by default.

Solution:

uv sync --group debugger
uv run python -m debugger

If you have both a global Python and a project venv, make sure you install into and run from the same interpreter.

500 Internal Server Errors

Cause: Server-side exception, often due to missing program data.

Solution:

  1. Ensure a binary is loaded in CodeBrowser
  2. Run auto-analysis first: Analysis > Auto Analyze
  3. Check Ghidra console (Window > Console) for Java exceptions
  4. Some operations require fully analyzed binaries

404 Not Found Errors

Cause: Endpoint doesn't exist or wrong URL.

Solution:

  1. Verify endpoint exists: curl http://127.0.0.1:8089/get_version
  2. Check for typos in endpoint name
  3. Ensure you're using correct HTTP method (GET vs POST)

Python Ghidra scripts fail with "No script provider found"

Cause: In Ghidra 12.1.2, Jython support is no longer enabled by default. .py scripts need the bundled Jython extension; Python 3 scripts should use PyGhidra instead of the Ghidra Script Manager.

Solution:

  1. In the Ghidra Front End, open File > Install Extensions.
  2. Check Jython, restart Ghidra, then refresh Script Manager.
  3. For new automation, prefer Java Ghidra scripts or PyGhidra.

Extension not appearing in Install Extensions

Cause: JAR file in wrong location.

Solution:

  1. Manual install location: ~/.ghidra/ghidra_12.1.2_PUBLIC/Extensions/GhidraMCP/lib/GhidraMCP.jar
  2. Or use: File > Install Extensions > Add and select the ZIP file
  3. Ensure JAR/ZIP was built for your Ghidra version

Build fails with "Ghidra dependencies not found"

Cause: Ghidra JARs not installed in local Maven repository.

Solution:

# Windows (recommended)
python -m tools.setup install-ghidra-deps --ghidra-path "C:\ghidra_12.1.2_PUBLIC"

📊 Production Performance

  • MCP Tools: 272 tools fully implemented
  • Speed: Sub-second response for most operations
  • Efficiency: 93% reduction in API calls via batch operations
  • Reliability: Atomic transactions with all-or-nothing semantics
  • AI Workflows: Proven documentation prompts refined across hundreds of real functions
  • Deployment: Automated version-aware deployment script

🛠️ API Reference

272 MCP tools backed by HTTP endpoints, grouped by catalog category. Generated from tests/endpoints.json by python -m tools.gen_readme_api_reference --write; the live schema at /mcp/schema is authoritative at runtime. Usage patterns: docs/prompts/TOOL_USAGE_GUIDE.md.

Program & Session Management

  • analysis_status - Get auto-analysis status for open programs
  • close_program - Close an open program by project path or name
  • create_property_map - Create a user property map to store typed values keyed by address
  • delete_property_map - Delete a user property map and all values it holds
  • exit_ghidra - Save and exit Ghidra
  • get_address_spaces - List all physical and overlay address spaces in the program (overlays include is_overlay flag and overlayed_space name)
  • get_current_program_info - Get current program info
  • get_language_metadata - Dump the program's language description: address spaces, registers, default symbols, endianness, pointer size (issue #192)
  • get_program_options - Read all options in a program option group with types, current values, defaults, and descriptions
  • get_property - Read the value stored at an address in a property map
  • import_file - Import a binary file from disk into the current Ghidra project and open it
  • list_open_programs - List open programs
  • list_option_groups - List program option groups (e.g
  • list_project_files - List project files
  • list_properties - List (address, value) entries stored in a property map, with pagination
  • list_property_maps - List user-defined property maps — typed per-address key→value stores
  • open_program - Open program from project
  • reanalyze - Trigger full auto-analysis on a program
  • remove_program_option - Remove an option from a program option group
  • remove_property - Remove the value stored at a single address in a property map
  • save_all_programs - Save all open programs
  • save_program - Save current program
  • set_image_base - Set the base address of the program (rebases all addresses)
  • set_program_option - Set a typed program option
  • set_property - Set a value at an address in a property map
  • switch_program - Switch current program

Project Organization

  • create_folder - Create a folder in the project
  • delete_file - Delete a file from the project
  • delete_project - Delete a Ghidra project
  • list_projects - List available Ghidra projects
  • move_file - Move a file to another project folder
  • move_folder - Move a folder to another location
  • project_info - Get detailed project info including running tools and open programs

Headless Project & Program Lifecycle

Available on the standalone headless server (GhidraMCPHeadlessServer).

  • archive_project - Archive the currently open project to a Ghidra-native .gar file
  • checkin_program - Check an open program back in to the shared Ghidra Server as a new version
  • close_project - Close the currently open project
  • create_project - Create a new Ghidra project
  • export_program - Export an open or project-resident program to a Ghidra Zip File (.gzf)
  • get_project_info - Get info about the currently open project
  • import_program - Import a Ghidra Zip File (.gzf) into the currently open project as a new DomainFile under target_folder (default '/')
  • load_program - Load a binary file into the headless server for analysis
  • load_program_from_project - Load program from Ghidra project (headless)
  • open_project - Open an existing Ghidra project (.gpr file or directory)
  • restore_project - Restore a Ghidra .gar archive into a fresh on-disk project at parent_dir/project_name
  • server_status - Check headless server connection status

Listing & Enumeration

  • list_bookmarks - List bookmarks
  • list_calling_conventions - List available calling conventions
  • list_classes - List namespace/class names
  • list_data_items - List defined data
  • list_data_items_by_xrefs - List data sorted by xref count
  • list_exports - List exported symbols
  • list_external_locations - List external locations
  • list_functions - List functions with addresses
  • list_functions_enhanced - List functions with metadata
  • list_globals - List global variables
  • list_imports - List imported symbols
  • list_methods - List all function names with pagination
  • list_namespaces - List all namespaces
  • list_scripts - List available Ghidra scripts
  • list_segments - List memory segments
  • list_strings - List defined strings

Context & Lookups

  • get_current_address - Get cursor address (GUI only)
  • get_current_function - Get function at cursor (GUI only)
  • get_current_selection - Get highlighted address ranges in the CodeBrowser listing (GUI only)
  • get_entry_points - Get program entry points
  • get_enum_values - Get enumeration values
  • get_external_location - Get external location details
  • get_full_call_graph - Get full call graph
  • get_function_by_address - Get function at address
  • get_function_call_graph - Get call graph
  • get_function_callees - Get functions called
  • get_function_callers - Get calling functions
  • get_function_count - Return the number of functions in the loaded program
  • get_function_jump_targets - Get jump targets
  • get_function_labels - Get labels in function
  • get_function_variables - List all variables in a function
  • get_struct_layout - Get structure layout
  • get_valid_data_types - Get valid data type names

Search

  • find_similar_functions - Find similar functions
  • search_byte_patterns - Search for byte patterns
  • search_data_types - Search data types
  • search_functions - Search functions by name
  • search_functions_enhanced - Advanced function search
  • search_strings - Search defined strings by a regex/substring pattern

Decompilation & Disassembly

  • decompile_function - Decompile function
  • disassemble_bytes - Disassemble byte range
  • disassemble_function - Disassemble function
  • force_decompile - Force fresh decompilation

Function Tags, Variables & Attributes

  • add_function_tag - Attach one or more tags to a function
  • batch_add_function_tags - Attach tags to many functions in one transaction
  • batch_remove_function_tags - Detach tags from many functions in one transaction
  • clear_flow_and_repair - Run Ghidra's GUI 'Clear Flow and Repair' action on a seed range: clears instruction flow reachable from the seed, then repairs function bodies and re-disassembles retained flow (ClearFlowAndRepairCmd with clear_data=false, clear_labels=false, repair=true)
  • create_function_tag - Create a program-wide function tag definition with an optional comment
  • delete_function_tag - Delete a program-wide function tag definition
  • get_function_tags - List all tags assigned to a specific function
  • list_class_members - List the member functions of a C++ class
  • list_function_tags - List all program-wide function tag definitions with their use counts
  • remove_function_tag - Detach one or more tags from a function
  • search_functions_by_tag - List all functions that have a specified tag attached
  • set_decompiler_variable_type - Set a decompiler (high-level) variable or parameter type by name
  • set_function_no_return - Set no-return attribute
  • set_function_tag_comment - Update the comment/description on an existing program-wide function tag
  • set_function_this_type - Set the decompiler/database type of the implicit 'this' pointer (ECX on x86 __thiscall/__fastcall)
  • set_variables - Set types and names for multiple variables atomically

Cross-References

  • add_memory_reference - Create a user-defined cross-reference between two memory addresses that the auto-analyzer can't infer (runtime-populated pointer tables, vtables, late-bound function pointers, missed jump/switch tables)
  • get_bulk_xrefs - Get xrefs for multiple addresses
  • get_function_xrefs - Get function cross-references
  • get_xrefs_from - Get references from address
  • get_xrefs_to - Get references to address
  • remove_reference - Remove memory cross-reference(s) from one address to another — the inverse of add_memory_reference

Data Types & Structures

  • add_struct_field - Add struct field
  • analyze_global_completeness - Score a global variable's documentation completeness on a budgeted 0-100 scale — the data-address analog of analyze_function_completeness
  • apply_data_type - Apply data type
  • audit_global - Audit a global variable's documentation state
  • audit_globals_in_function - Audit every global variable referenced from within a function in one call
  • batch_set_variable_types - Set multiple variable types
  • clone_data_type - Clone data type
  • create_array_type - Create array type
  • create_data_type_category - Create data type category
  • create_enum - Create enumeration
  • create_function_signature - Create function signature type
  • create_pointer_type - Create pointer type
  • create_struct - Create structure
  • create_typedef - Create typedef
  • create_union - Create union
  • delete_data_type - Delete data type
  • embed_struct_field - Replace a structure field with an embedded struct type by value (e.g
  • get_data_type_size - Get data type size in bytes
  • get_type_size - Get data type size and info
  • import_data_types - Import data types from GDT
  • list_data_type_categories - List data type categories
  • list_data_types - List data types
  • modify_struct_field - Modify struct field
  • modify_struct_field_type - Set a structure field's type by name or offset (offset:N)
  • move_data_type_to_category - Move data type to category
  • recreate_struct - Replace a structure in one step: optionally remove an existing same-named type, then create with fields JSON (same shape as create_struct)
  • remove_struct_field - Remove struct field
  • rename_data_type - Rename a data type (struct, union, enum, typedef) in place, preserving existing applications of it
  • resize_struct - Grow or shrink an existing structure by total byte size
  • resolve_duplicate_type - Find duplicate data types by simple name; delete unused /Demangler size-1 stubs when a larger canonical type exists
  • set_function_prototype - Set function prototype (return type, param types, calling convention)
  • set_global - Atomically apply name + type + plate-comment + array length to a global variable
  • set_local_variable_type - Set variable type
  • set_parameter_type - Set parameter type
  • set_variable_storage - Set variable storage
  • validate_data_type - Validate data type syntax
  • validate_data_type_exists - Check if data type exists
  • validate_function_prototype - Validate function prototype

Renaming & Labels

  • batch_create_labels - Create multiple labels
  • batch_delete_labels - Delete multiple labels
  • batch_rename_function_components - Batch rename function components
  • create_label - Create label
  • delete_label - Delete label at address
  • rename_data - Rename data symbol
  • rename_external_location - Rename external location
  • rename_function - Rename function by name
  • rename_function_by_address - Rename function by address
  • rename_global_variable - Rename global variable
  • rename_label - Rename label
  • rename_or_label - Rename or create label
  • rename_variable - Rename a variable in a function
  • rename_variables - Batch rename variables

Comments & Bookmarks

  • batch_set_comments - Set multiple comments
  • clear_function_comments - Clear all comments for a function
  • delete_bookmark - Delete bookmark
  • get_comment - Get listing comments (plate/pre/eol/post/repeatable) at ANY address, including data addresses (unlike get_plate_comment which requires a function)
  • get_plate_comment - Get plate comment
  • set_bookmark - Set bookmark
  • set_comment - Set a listing comment of a given kind (plate/pre/eol/post/repeatable) at ANY address, including data addresses
  • set_decompiler_comment - Set PRE_COMMENT
  • set_disassembly_comment - Set EOL_COMMENT
  • set_plate_comment - Set plate comment

Analysis

  • analyze_api_call_chains - Analyze API call chains
  • analyze_call_graph - Analyze function call graph patterns
  • analyze_control_flow - Analyze control flow
  • analyze_data_region - Analyze data region
  • analyze_dataflow - Trace value propagation through a function (PCode graph, forward/backward)
  • analyze_for_documentation - Composite RE documentation analysis (decompile + classify + variables + completeness)
  • analyze_function_complete - Comprehensive single-call function analysis
  • analyze_function_completeness - Analyze documentation completeness
  • analyze_struct_field_usage - Analyze struct field usage
  • apply_data_classification - Apply data classification
  • batch_analyze_completeness - Batch analyze completeness for multiple functions
  • batch_apply_documentation - Apply all documentation to a function in one call
  • batch_decompile - Decompile multiple functions at once
  • can_rename_at_address - Check if address can be renamed
  • clear_instruction_flow_override - Clear flow override
  • configure_analyzer - Configure an analysis plugin
  • create_function - Create function at address
  • create_memory_block - Create memory block
  • delete_function - Delete function at address
  • detect_array_bounds - Detect array bounds
  • detect_crypto_constants - Detect crypto constants
  • detect_malware_behaviors - Detect malware behaviors
  • extract_iocs_with_context - Extract IOCs with context
  • find_anti_analysis_techniques - Find anti-analysis techniques
  • find_code_gaps - Find gaps of undefined bytes between functions in executable memory
  • find_dead_code - Find dead code
  • find_next_undefined_function - Find next undefined function
  • get_assembly_context - Get assembly context
  • get_field_access_context - Get field access context
  • get_function_pcode - Dump raw P-code for a function (issue #192)
  • inspect_memory_content - Inspect memory bytes
  • list_analyzers - List available analysis plugins
  • read_memory - Read raw memory
  • run_analysis - Run auto-analysis on the current program
  • search_instructions - Search for instructions by mnemonic and/or operand substring
  • suggest_field_names - Suggest field names

Cross-Binary Documentation & Archive

  • archive_ingest_function - Ingest a single function's documentation into the cross-version archive (re_kb.functions on bsim Postgres)
  • archive_ingest_program - Bulk-ingest every function in a program into the cross-version documentation archive
  • batch_string_anchor_report - Report of source file strings and their FUN_* functions
  • bulk_fuzzy_match - Bulk cross-binary function matching
  • find_similar_functions_fuzzy - Cross-binary fuzzy function matching
  • merge_program_documentation - Bulk merge: copy all RE documentation (function names, signatures, plate comments, instruction comments at EOL/PRE/POST, non-default labels & global symbols) from one program to another at matching addresses

Utility & Documentation Transfer

  • apply_function_documentation - Apply function documentation
  • check_connection - Health check endpoint
  • compare_programs_documentation - Compare documentation across programs
  • convert_number - Convert number between bases
  • diff_functions - Diff two functions
  • find_undocumented_by_string - Find undocumented functions referencing string
  • get_bulk_function_hashes - Get bulk function hashes
  • get_function_documentation - Export function documentation
  • get_function_hash - Get function hash
  • get_function_signature - Get function feature signature
  • get_metadata - Get program metadata
  • get_version - Get plugin version
  • health - Health check endpoint for headless server
  • mcp_health - HTTP server health: pool stats, uptime, memory, active request count
  • mcp_schema - Machine-readable API schema with endpoint metadata
  • tool_goto_address - Navigate CodeBrowser listing and decompiler to a specific address
  • tool_launch_codebrowser - Open a file in CodeBrowser, launching a new one if needed
  • tool_running_tools - List all running Ghidra tool windows

Emulation

  • emulate_function - Emulate a single function with controlled register/memory inputs
  • emulate_hash_batch - Brute-force API hash resolution

Scripting

  • run_ghidra_script - Run script with output capture
  • run_script_inline - Run inline script code

Ghidra Server & Version Control

  • server_admin_set_permissions - Set user permissions on a repository
  • server_admin_terminate_all_checkouts - Terminate all checkouts in a folder recursively
  • server_admin_terminate_checkout - Terminate all checkouts on a single file
  • server_admin_users - List all users on the server
  • server_authenticate - Register server credentials for programmatic authentication
  • server_checkouts - List all checked-out files in a folder, including server-side checkouts
  • server_connect - Connect to a Ghidra server
  • server_disconnect - Disconnect from the Ghidra server
  • server_repositories - List repositories on the connected server
  • server_repository_create - Create a new repository on the server
  • server_repository_file - Get file info from a server repository
  • server_repository_files - List files in a server repository folder
  • server_version_control_add - Add a file to version control
  • server_version_control_checkin - Check in a version-controlled file
  • server_version_control_checkout - Check out a version-controlled file
  • server_version_control_undo_checkout - Undo a file checkout
  • server_version_history - Get version history for a file

Debugger (Ghidra TraceRmi — GUI only)

On Windows hosts where the bridge's WinDbg debugger proxy is active (GHIDRA_DEBUGGER_URL), colliding names get a _2 suffix (e.g. debugger_status_2).

  • debugger_dynamic_to_static - Translate a runtime dynamic address from the current trace back to a static Ghidra program address
  • debugger_interrupt - Interrupt (break into) the running target
  • debugger_launch - Launch an executable through Ghidra's Trace RMI debugger launcher
  • debugger_launch_offers - List available debugger launch/attach options for the current program
  • debugger_list_breakpoints - List all breakpoints in the current trace
  • debugger_modules - List modules (DLLs/EXEs) loaded in the debugged process
  • debugger_read_memory - Read memory from the debugged process
  • debugger_registers - Read CPU registers from the current debug trace snapshot
  • debugger_remove_breakpoint - Remove a breakpoint at an address
  • debugger_resume - Resume execution of the debugged process
  • debugger_set_breakpoint - Set a software execution breakpoint at an address in the trace
  • debugger_stack_trace - Get the call stack backtrace for the current thread
  • debugger_static_to_dynamic - Translate a static Ghidra program address to a runtime dynamic address in the current trace
  • debugger_status - Get debugger status: active trace, thread, execution state, module count
  • debugger_step_into - Single-step into the next instruction (follows calls)
  • debugger_step_out - Step out of the current function (run to return)
  • debugger_step_over - Step over the next instruction (does not follow calls)
  • debugger_traces - List all open debug traces

System

  • prompt_policy - Temporarily enable, disable, or query scoped automation prompt handling

Bridge Static Tools

Defined in the Python bridge itself (instance discovery, tool-group management); always available even before a Ghidra connection. The bridge also proxies 22 debugger_* WinDbg tools when GHIDRA_DEBUGGER_URL points at the standalone debugger server.

  • check_tools - Report which tools are currently registered and callable
  • connect_instance - Connect the bridge to a specific Ghidra instance
  • import_file - Import a binary from disk into the current project and open it
  • list_instances - Discover running Ghidra MCP instances (UDS + TCP port scan)
  • list_tool_groups - List tool groups and their load state
  • load_tool_group - Register a tool group's dynamic tools with the MCP client
  • search_tools - Search the full tool catalog by keyword
  • unload_tool_group - Unregister a tool group's dynamic tools

See CHANGELOG.md for version history.

🏗️ Architecture

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   AI/Automation │◄──►│   MCP Bridge    │◄──►│  Ghidra Plugin  │
│     Tools       │    │ (bridge_mcp_    │    │ (GhidraMCP.jar) │
│  (Claude, etc.) │    │  ghidra/)       │    │                 │
└─────────────────┘    └─────────────────┘    └─────────────────┘
        │                       │                       │
   MCP Protocol            HTTP REST              Ghidra API
(stdio/streamable-http) (localhost:8089)      (Program, Listing)

Components

  • python/bridge_mcp_ghidra/ — Python MCP server package (ships as the ghidra-mcp-bridge wheel; bridge-mcp-ghidra console script) that translates MCP protocol to HTTP calls (225 catalog entries)
  • GhidraMCP.jar — Ghidra plugin that exposes analysis capabilities via HTTP (175 GUI endpoints)
  • GhidraMCPHeadlessServer — Standalone headless server — 183 endpoints, no GUI required
  • ghidra_scripts/ — Collection of automation scripts for common tasks

🔧 Development

Building from Source

# Recommended: direct Python-first workflow
python -m tools.setup ensure-prereqs --ghidra-path "C:\ghidra_12.1.2_PUBLIC"
python -m tools.setup build
python -m tools.setup deploy --ghidra-path "C:\ghidra_12.1.2_PUBLIC"

# Version bump (updates all maintained version references atomically)
python -m tools.setup bump-version --new X.Y.Z

The authoritative build system today is Maven. tools.setup, the VS Code tasks, and the documented deploy flow all build through pom.xml and write artifacts to target/. build.gradle remains in the repo as a manual fallback for direct Ghidra/Gradle users, but it is not the primary path.

Command Reference

Command What it does
ensure-prereqs Install Python deps + Ghidra Maven JARs in one shot. Start here on a new machine.
preflight Validate Python, build tool, Ghidra path, and JAR availability without making changes. Add --strict to also check network reachability.
build Build the plugin JAR and extension ZIP via Maven (or Gradle when TOOLS_SETUP_BACKEND=gradle).
deploy Copy the built extension into the Ghidra profile and patch FrontEndTool.xml for auto-activation.
start-ghidra Launch the configured Ghidra installation.
clean Remove Maven/Gradle build outputs (target/, build/).
clean-all Remove build outputs plus local cache artifacts (.m2 Ghidra JARs, etc.).
install-ghidra-deps Install only the Ghidra JARs into ~/.m2. Useful when the build environment changes.
install-python-deps Install the Python dependency groups via uv sync.
run-tests Run the Java offline test suite (no live Ghidra needed).
verify-version Check that version strings are consistent across pom.xml, CHANGELOG.md, and README.md.
bump-version --new X.Y.Z Atomically update all version references. Pass --tag to create a git tag.

Common flags accepted by most commands:

Flag Description
--ghidra-path PATH Ghidra installation directory. Defaults to GHIDRA_PATH from .env.
--dry-run Print actions without executing them.
--force Reinstall Ghidra JARs even if already present (install-ghidra-deps, ensure-prereqs).
--with-debugger Force-install debugger Python requirements (Windows only).
--use-debugger-toggle Read INSTALL_DEBUGGER_DEPS from .env to decide whether to install debugger deps.
--test TIER (deploy only) Opt into live deploy regression tiers such as release or debugger-live.
--strict (preflight only) Also check network reachability for Maven Central and PyPI.

Deploy test tiers are opt-in because benchmark tiers can import/reset Benchmark.dll and BenchmarkDebug.exe in the active Ghidra project. Use --test release before cutting releases, or set GHIDRA_MCP_DEPLOY_TESTS=release in a local .env when you want every deploy on your machine to run the live benchmark regression. See Testing and Release Regression.

# Standard first-time setup and deploy
python -m tools.setup ensure-prereqs --ghidra-path "C:\ghidra_12.1.2_PUBLIC"
python -m tools.setup build
python -m tools.setup deploy --ghidra-path "C:\ghidra_12.1.2_PUBLIC"

# Preflight check before deploying
python -m tools.setup preflight --strict --ghidra-path "C:\ghidra_12.1.2_PUBLIC"

# Version bump and tag
python -m tools.setup bump-version --new X.Y.Z --tag

# Run offline Java tests
python -m tools.setup run-tests

# Show full help
python -m tools.setup --help

Project Structure

ghidra-mcp/
├── pyproject.toml           # uv project (ghidra-mcp-bridge wheel + dependency groups)
├── python/bridge_mcp_ghidra/ # MCP server package (Python, 225 catalog entries)
├── src/main/java/           # Ghidra plugin + headless server (Java)
│   └── com/xebyte/
│       ├── GhidraMCPPlugin.java         # GUI plugin (196 endpoints)
│       ├── headless/                    # Headless server (183 endpoints)
│       └── core/                        # Shared service layer (12 services)
├── debugger/                # Optional standalone debugger server (port 8099)
├── ghidra_scripts/          # Automation scripts for batch workflows
├── tests/                   # Python unit tests + endpoint catalog
│   ├── unit/               # Catalog consistency, schema, tool function tests
│   └── endpoints.json      # Endpoint specification (225 entries)
├── docs/                    # Documentation
│   ├── prompts/            # AI workflow prompts (V5 documentation workflows)
│   ├── releases/           # Version release notes
│   └── project-management/ # Contributor planning docs (Gradle migration, etc.)
├── tools/setup/             # Build and deployment CLI (python -m tools.setup)
├── fun-doc/                 # Internal RE curation tool — not part of the MCP plugin
│                            #   Priority-queue worker, LLM scoring, web dashboard.
│                            #   See fun-doc/README.md for details.
└── .github/workflows/      # CI/CD pipelines

Library Dependencies

Ghidra JARs must be installed into your local Maven repository (~/.m2/repository) before compilation. This is a one-time setup per machine, and again when your Ghidra version changes. -Deploy now installs these automatically by default.

The tool enforces version consistency between:

  • pom.xml (ghidra.version)
  • --ghidra-path version segment (e.g., ghidra_12.1.2_PUBLIC)

If these do not match, deployment fails fast with a clear error.

Troubleshooting: Version Mismatch

If you see a version mismatch error, align both values:

  1. pom.xmlghidra.version
  2. --ghidra-path version segment (ghidra_X.Y.Z_PUBLIC)

Then rerun:

python -m tools.setup preflight --ghidra-path "C:\ghidra_12.1.2_PUBLIC"
# Windows
python -m tools.setup install-ghidra-deps --ghidra-path "C:\path\to\ghidra_12.1.2_PUBLIC"

Required Libraries (14 JARs, ~37MB):

Library Source Path Purpose
Base.jar Features/Base/lib/ Core Ghidra functionality
Decompiler.jar Features/Decompiler/lib/ Decompilation engine
PDB.jar Features/PDB/lib/ Microsoft PDB symbol support
FunctionID.jar Features/FunctionID/lib/ Function identification
SoftwareModeling.jar Framework/SoftwareModeling/lib/ Program model API
Project.jar Framework/Project/lib/ Project management
Docking.jar Framework/Docking/lib/ UI docking framework
Generic.jar Framework/Generic/lib/ Generic utilities
Utility.jar Framework/Utility/lib/ Core utilities
Gui.jar Framework/Gui/lib/ GUI components
FileSystem.jar Framework/FileSystem/lib/ File system support
Graph.jar Framework/Graph/lib/ Graph/call graph analysis
DB.jar Framework/DB/lib/ Database operations
Emulation.jar Framework/Emulation/lib/ P-code emulation

Note: Libraries are NOT included in the repository (see .gitignore). You must install them from your Ghidra installation before building.

Automation entry point:

  • python -m tools.setup is the supported setup/build/deploy/versioning interface
  • use ensure-prereqs, build, deploy, preflight, clean-all, and bump-version directly
  • these commands currently use Maven as the canonical Java build backend

Development Features

  • Automated Deployment: Version-aware deployment script
  • Batch Operations: Reduces API calls by 93%
  • Atomic Transactions: All-or-nothing semantics
  • Comprehensive Logging: Debug and trace capabilities

📚 Documentation

Core Documentation

AI Workflow Prompts

Release History

🐳 Headless Server (Docker)

GhidraMCP includes a headless server mode for automated analysis without the Ghidra GUI.

Quick Start with Docker

# Build and run
docker-compose up -d ghidra-mcp

# Test connection
curl http://localhost:8089/check_connection
# Connection OK - GhidraMCP Headless Server v6.0.0

Headless API Workflow

# 1. Load a binary
curl -X POST -d "file=/data/program.exe" http://localhost:8089/load_program

# 2. Run auto-analysis (identifies functions, strings, data types)
curl -X POST http://localhost:8089/run_analysis

# 3. List discovered functions
curl "http://localhost:8089/list_functions?limit=20"

# 4. Decompile a function
curl "http://localhost:8089/decompile_function?address=0x401000"

# 5. Get metadata
curl http://localhost:8089/get_metadata

Key Headless Endpoints

Endpoint Method Description
/load_program POST Load binary file for analysis
/run_analysis POST Run Ghidra auto-analysis
/list_functions GET List all discovered functions
/list_exports GET List exported symbols
/list_imports GET List imported symbols
/decompile_function GET Decompile function to C code
/create_function POST Create function at address
/get_metadata GET Get program metadata
/create_project POST Create a Ghidra project
/list_analyzers GET List available analyzers
/server/status GET Check Ghidra Server connection

Configuration

Environment variables for Docker:

  • GHIDRA_MCP_PORT - Server port (default: 8089)
  • GHIDRA_MCP_BIND_ADDRESS - Bind address (default: 0.0.0.0 in Docker)
  • JAVA_OPTS - JVM options (default: -Xmx4g -XX:+UseG1GC)

🤝 Contributing

See CONTRIBUTING.md for detailed contribution guidelines.

Quick Start

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Build and test your changes (mvn clean package assembly:single -DskipTests or GHIDRA_INSTALL_DIR=/path/to/ghidra gradle buildExtension)
  4. Update documentation as needed
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

📄 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

🏆 Production Status

Metric Value
Version 6.0.0
MCP Tools 249 fully implemented
GUI Endpoints 196 (GhidraMCPPlugin)
Headless Endpoints 195 (GhidraMCPHeadlessServer)
Compilation ✅ 100% success
Batch Efficiency 93% API call reduction
AI Workflows 7 proven documentation workflows
Ghidra Scripts Automation scripts included
Documentation Comprehensive with AI prompts

See CHANGELOG.md for version history and release notes.

🙏 Acknowledgments

This project was originally derived from LaurieWired/GhidraMCP in August 2025 and has since been substantially rewritten and extended. We acknowledge LaurieWired's original work as the starting point. See NOTICE for license attribution.

👥 Contributors

This project has benefited from the work of dedicated contributors:

Core Contributors

@heeen — Significant contributions including:

  • Fuzzy function matching and structured diff for cross-binary comparison (#13)
  • Script execution improvements and bug fixes (#12)
  • New API endpoints: save_program, exit_ghidra, delete_function, create_memory_block, run_script_inline (#11)
  • Architectural vision: annotation-driven design, UDS transport, Python bridge optimization proposals

@huehuehuehueing — Significant contributions including:

  • Address-space prefix support — added <space>:<hex> syntax (e.g., mem:1000, code:ff00) to address parsing across the entire endpoint surface, unlocking multi-space targets like embedded firmware (#84, closes #65)

  • Optional program parameter + required-param schema fixes — made program optional on every endpoint with a sane currentProgram fallback, and fixed several required-vs-optional schema bugs the catalog had inherited (#92)

  • Seeded #44 (data-type / enum tools) — the issue that motivated the v5.0 enum + struct enforcement layer

  • Ghidra Team - For the incredible reverse engineering platform

  • Model Context Protocol - For the standardized AI integration framework

  • Contributors - For testing, feedback, and improvements


🔗 Related Projects

  • re-universe — Ghidra BSim PostgreSQL platform for large-scale binary similarity analysis. Pairs perfectly with GhidraMCP for AI-driven reverse engineering workflows.
  • cheat-engine-server-python — MCP server for dynamic memory analysis and debugging.

Ready for production deployment with enterprise-grade reliability and comprehensive binary analysis capabilities.

About

Ghidra MCP Server — 200+ MCP tools for AI-powered reverse engineering. GUI plugin + headless server, lazy tool loading, convention enforcement, batch operations, Ghidra Server integration, and Docker deployment.

Topics

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages