Server · #58 trending MCP repo · ↗ +126 stars this week

Ghidra MCP

bethington/ghidra-mcp

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.

Stars
6.2k
This week
+126
Forks
382
Open issues
19
Latest release
v7.0.0
Star trend · last 18 days+334 ★
Oct 20, 2026: 5,819 starsOct 21, 2026: 5,833 starsOct 22, 2026: 5,850 starsOct 23, 2026: 5,881 starsOct 24, 2026: 5,888 starsOct 25, 2026: 5,900 starsOct 26, 2026: 5,925 starsOct 27, 2026: 5,945 starsOct 28, 2026: 5,965 starsOct 29, 2026: 5,994 starsOct 30, 2026: 6,018 starsOct 31, 2026: 6,027 starsNov 1, 2026: 6,043 starsNov 2, 2026: 6,071 starsNov 3, 2026: 6,095 starsNov 4, 2026: 6,116 starsNov 5, 2026: 6,132 starsNov 6, 2026: 6,140 starsNov 7, 2026: 6,153 stars

Get started

Add it to your agent

claude mcp add ghidra -- uvx ghidra-mcp-bridge

Run in your terminal. Add --scope project to share it with your team through .mcp.json.

Documentation

README

View on GitHub ↗

Ghidra MCP Server

MCP Toplist

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. 219 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.

Quickstart: install a release (no clone, no build)

Every release ships the two pieces you need: the Ghidra extension (GhidraMCP-<version>.zip) and the MCP bridge (ghidra_mcp_bridge-<version>-py3-none-any.whl).

  1. Install the prerequisites: Ghidra 12.2, Java 25 and uv. The extension only loads in the exact Ghidra version it was built for.

  2. Install the extension: in Ghidra's project window, File > Install Extensions, click +, pick the GhidraMCP-<version>.zip you downloaded, and restart Ghidra.

  3. Enable the plugin: in the project window, File > Configure > Utility > Configure, tick GhidraMCPPlugin. Check it answers:

    curl http://127.0.0.1:8089/check_connection
    # {"status": "ok", "server_kind": "gui", "version": "7.0.0"}
    
  4. Install the bridge (copy the wheel's link from the same release page):

    uv tool install https://github.com/bethington/ghidra-mcp/releases/download/v7.0.0/ghidra_mcp_bridge-7.0.0-py3-none-any.whl
    
  5. Point your MCP client at it, using the absolute path (which bridge-mcp-ghidra, or where.exe bridge-mcp-ghidra on Windows):

    {
      "mcpServers": {
        "ghidra-mcp": { "command": "/home/<you>/.local/bin/bridge-mcp-ghidra" }
      }
    }
    

    On Windows: "command": "C:\\Users\\<you>\\.local\\bin\\bridge-mcp-ghidra.exe". A client launched from a GUI or a service does not see your shell's PATH, so a bare bridge-mcp-ghidra fails with spawn ENOENT.

Open a program in Ghidra and ask your AI tool to list its functions. Screenshots of steps 2-3: docs/INSTALL_GUI.md. Building from source, Docker, the HTTP transports and every bridge flag are further down.

Which version should I run? Tagged releases (7.0.0, 7.1.0, ...) are stable. Release candidates and main are beta: feature-complete and live-tested, but shapes can still change before final. dev is experimental: tools are merged, renamed and refactored there freely, so build nothing on its API.

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.

  • 219 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
  • 219 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 — 16 /debugger/* endpoints over Ghidra's TraceRmi framework (GUI plugin only; dbgeng on Windows PE, gdb/lldb otherwise): launch, interrupt/resume, step into/over/out, breakpoints, registers, memory reads, stack traces, ASLR-aware static↔dynamic address translation. The bridge can also proxy 22 debugger_* tools to an external debugger server; they are opt-in (see below)

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 Execution — List and run Ghidra scripts, or run inline script code, via MCP (running them is opt-in: GHIDRA_MCP_ALLOW_SCRIPTS=1)
  • 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

🚀 Install from source

The Quickstart above needs none of this. Build from source to run dev, to contribute, or to use python -m tools.setup deploy, which installs, configures and restarts Ghidra for you.

Prerequisites

  • Java 25 LTS (OpenJDK recommended)
  • Apache Maven 3.9+ for the python -m tools.setup commands below (Maven is their default backend). Not needed if you build with the committed Gradle wrapper instead — see step 6
  • Ghidra 12.2 (or compatible version)
  • Python 3.10+ with uv (recommended) or pip + venv

Shared Ghidra Server users: Ghidra 12.2 clients enforce TLS server authentication on every connection, loopback included, so the server's certificate must be trusted (Edit > Manage Certificates... on Windows and macOS). A server previously refused on the Server Allow List stays refused, including for headless ghidra:// runs, until it is changed with support/updateServerAllowList. See Ghidra's WhatsNew before upgrading a shared deployment.

Programs saved by 12.2 may not open in an earlier Ghidra. Programs from an earlier Ghidra open read-only until upgraded, because 12.2 raises the program database version. With Ghidra closed and a backup taken, upgrade a project with support/analyzeHeadless <project_dir> <project_name> -process '*' -recursive -noanalysis. Add -connect <user> -p for a shared project. Without -commit, nothing is committed to the server, but unmodified checkouts become modified.

Ghidra 12.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.2_PUBLIC"
    
  3. Build and deploy to Ghidra:

    python -m tools.setup ensure-prereqs --ghidra-path "F:\ghidra_12.2_PUBLIC"
    python -m tools.setup build
    python -m tools.setup deploy --ghidra-path "F:\ghidra_12.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.

    Prefer to click through Ghidra's own dialogs, or installing a release zip on a machine without the repo? Follow the illustrated manual GUI install guide.

  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.2_PUBLIC"
    
  5. Show command help:

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

    python -m tools.setup build
    

    Two Java backends are supported. Gradle is the default for local work — it reads Ghidra's jars straight out of the installation, so there is no install-file step and nothing to install beyond a JDK. CI builds and gates with Maven, so Maven is a maintained peer rather than a fallback.

    # Gradle (default) -- the wrapper is committed, so no Gradle install is needed.
    # -PGHIDRA_INSTALL_DIR or the GHIDRA_INSTALL_DIR env var both work.
    # In Git Bash use forward slashes; a backslash path is mangled before Gradle sees it.
    ./gradlew buildExtension -PGHIDRA_INSTALL_DIR=/path/to/ghidra
    
    # Maven (peer backend; what CI uses). Needs Ghidra's jars in the local .m2 first:
    #   python -m tools.setup ensure-prereqs --ghidra-path /path/to/ghidra
    mvn clean package assembly:single -DskipTests
    

    python -m tools.setup build routes to Maven by default; set TOOLS_SETUP_BACKEND=gradle to route it to Gradle instead.

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.2_PUBLIC
    
  4. Build and deploy to Ghidra (single command):

    python -m tools.setup ensure-prereqs --ghidra-path ~/ghidra_12.2_PUBLIC
    python -m tools.setup build
    python -m tools.setup deploy --ghidra-path ~/ghidra_12.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.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.2_PUBLIC/Extensions/GhidraMCP/.

    Note: the Homebrew path contains no version string, so tools.setup reads the Ghidra version from Ghidra/application.properties inside the installation instead.

  5. Start Ghidra and enable the plugin:

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

    The server starts with the plugin. Check it from the project window: Tools > GhidraMCP > Server Status

  6. Configure Cursor/Claude MCP (~/.cursor/mcp.json) — use the absolute path to uv (which uv), not the bare name; GUI-launched clients do not inherit your shell's PATH (#441):

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

    macOS is the sharpest case: apps launched from Finder/Dock get launchd's PATH, which never contains ~/.local/bin or /opt/homebrew/bin.

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

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

MCP client config (.mcp.json, ~/.cursor/mcp.json, Claude Desktop config, …). Use the absolute path to uv — see the note below for why:

{
  "mcpServers": {
    "ghidra-mcp": {
      "command": "/home/<you>/.local/bin/uv",
      "args": ["run", "--directory", "/path/to/ghidra-mcp", "bridge-mcp-ghidra", "--transport", "stdio"],
      "env": { "GHIDRA_MCP_URL": "http://127.0.0.1:8089" }
    }
  }
}

On Windows the same config points at uv.exe, e.g. "command": "C:\\Users\\<you>\\.local\\bin\\uv.exe". Find your own path with which uv (POSIX) or where.exe uv (Windows), or just run python -m tools.setup preflight, which prints the resolved absolute path and a ready-to-paste snippet.

Why absolute? "command": "uv" fails under service and GUI launchers. The MCP client resolves command with its own PATH, not your shell's. A client started from a systemd user service, a .desktop entry, or any other GUI session inherits that launcher's environment, which routinely lacks ~/.local/bin and ~/.cargo/bin — the very directories uv installs into. The failure lands at process-spawn time as spawn uv ENOENT, before any bridge code runs, so there is nothing in any log to read. An absolute path makes the client's PATH irrelevant and works on the first try. The same applies to python, python3, and the bridge-mcp-ghidra console script. (#441)

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

autohand mcp add ghidra /home/<you>/.local/bin/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.

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.

GHIDRA_MCP_ALLOWED_HOSTS also supports clients that route a loopback-bound bridge through another network namespace. For example, a container can address the host as host.containers.internal without exposing the bridge on a LAN interface:

GHIDRA_MCP_ALLOWED_HOSTS=host.containers.internal \
  uv run bridge-mcp-ghidra --transport streamable-http \
  --mcp-host 127.0.0.1 --mcp-port 8081

The setting extends DNS-rebinding Host/Origin validation only; it does not change the bind address or make the listener reachable on additional interfaces.

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 (default) Load only the default tool groups on connect, and let the model pull in the rest with search_tools/load_tool_group.
--project unset Exact project name to select at startup, including when multiple instances are running. Overrides GHIDRA_MCP_PROJECT.
--no-lazy off Load all tool groups immediately on connect. Needed only by MCP clients that ignore tools/list_changed; rejected outright by the Gemini API (see below).
--default-groups listing,function,program Comma-separated groups loaded on connect under --lazy.
--tools-page-size 0 Serve tools/list in pages of this size (0 = one page). Only for a client that cannot take one large response; a client that ignores nextCursor sees only the first page.
--json-response off streamable-http: answer POSTs with plain JSON instead of an SSE stream. Server-initiated messages such as tools/list_changed are then not delivered.
--stateless-http off streamable-http: no session id and no server-initiated notifications, for running several bridge workers behind a load balancer. Pair it with --no-lazy, since a group loaded later can never be announced.

To require a token from MCP clients of an HTTP transport, set GHIDRA_MCP_INBOUND_TOKEN=<secret>; clients must then send Authorization: Bearer <secret>. The bridge logs a warning when it binds a non-loopback --mcp-host without one. Separately, when GHIDRA_MCP_AUTH_TOKEN (the token the bridge sends to Ghidra) is set and the bridge binds a non-loopback host, clients must present that same token, so the bridge cannot be used to relay it.

Lazy tool loading is the default (issue #440)

Advertising all 220 endpoints in a single tools/list is over a hard limit for at least one major provider. Gemini compiles function declarations into a constrained-decoding state machine and rejects the whole request before any tool is ever called:

400 INVALID_ARGUMENT
The specified schema produces a constraint that has too many states for serving

That is not a degradation, it is an outright break, and no client-side setting could work around a server that only ever offered the full set. So the bridge now loads listing,function,program (70 endpoints plus the 8 static tools) on connect and registers the rest on demand.

If your client ignores tools/list_changed it will not notice tools that are registered later, and should turn lazy loading off:

uv run bridge-mcp-ghidra --no-lazy          # when you control the command line
export GHIDRA_MCP_LAZY=0                    # when you don't (Docker, uvx, some client configs)

GHIDRA_MCP_LAZY accepts 0/false/no/off and 1/true/yes/on; an explicit --lazy/--no-lazy on the command line wins over it. Startup logs which mode is in effect.

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, so it loads only listing,function,program on connect (see above) and lets 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_symbol,batch_set_comments") — confirm specific tools are callable right now.

To select a project before the client discovers tools, use bridge-mcp-ghidra --project MyProject --no-lazy, or set GHIDRA_MCP_PROJECT=MyProject and GHIDRA_MCP_LAZY=0 in the client's environment. Project names are matched exactly. A missing or ambiguous match leaves the bridge disconnected; background retries retain the selector. Blank environment values mean unset, and a blank --project is rejected. Without a selector, auto-connect behavior is unchanged. For TCP-only servers, GHIDRA_MCP_URL limits project discovery to that listener; otherwise the usual local TCP discovery range is searched.

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

Minimal read-only allowlist

Some MCP clients gate tools through an explicit allowlist. Cut it too far and the agent loses discovery — it cannot find entry points or enumerate functions through MCP, so it works around the allowlist by curl-ing the HTTP API on 127.0.0.1:8089 directly, which defeats the point of having one. The allowlist has to be small and self-sufficient.

Minimum viable read-only set (4 tools):

Tool Group What it buys you
get_metadata program Which binary is loaded — name, architecture, image base, function count. Orientation, and it confirms the bridge reached Ghidra at all.
find_functions listing Paginated function enumeration (offset, limit); with no filter it lists the whole program, and name_pattern/regex turn it into a name search. This is the discovery tool — without it the agent cannot answer "what is in this binary".
get_entry_points listing Where execution starts, so analysis has a root to work down from.
get_functions function The payload. Takes function= (name or address) or functions= (comma-separated names or addresses, up to 20), and fields= to pick what comes back: decompiled_code, signature, callers, callees, xrefs, comments, and more.

That set is genuinely closed: get_entry_points and find_functions supply the addresses and names that get_functions consumes, and its callees field names the next functions to feed straight back into it.

The three tools suggested in #441 were get_metadata, get_entry_points and decompile_function. The first two still exist under those names; decompile_function was folded into get_functions in 7.0.0 (fields=decompiled_code), and the migration guide maps every other removed name. find_functions is the one addition worth making: without it the agent can only reach code that is reachable by name from something it already decompiled, so anything not referenced from an entry point is invisible.

Useful next additions, in order:

Tool Group Why
get_function_call_graph xref A multi-level call graph (depth, direction) in one call. One level of callers and callees already comes from get_functions.
get_xrefs_to xref Who touches this address — the standard question about a global. Takes addresses= for several at once.
list_strings listing Strings are the cheapest orientation signal in an unknown binary.
list_program_items listing kind=imports / kind=exports: the binary's external surface. Other kinds list segments, classes, namespaces, data items and external locations.

Every tool above is a GET; none of them writes to the Ghidra database.

…

Releases

Recent versions

All releases ↗
  1. v7.0.0GhidraMCP 7.0.0
  2. v7.0.0-rc.3GhidraMCP 7.0.0-rc.3 (Pre-Release)pre-release
  3. v7.0.0-rc.2GhidraMCP 7.0.0-rc.2 (Pre-Release)pre-release
  4. v7.0.0-rc.1GhidraMCP 7.0.0-rc.1 (Pre-Release)pre-release
  5. v6.0.0GhidraMCP 6.0.0
  6. v5.14.2GhidraMCP 5.14.2