Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
ghidra-mcp — MCP server bridging Ghidra's reverse engineering with AI tools: 256 tools for decompilation, P-code emulation, live debugging, data flow analysis, batch operations, and convention enforcement across headless and GUI modes. | Kitploit
Strumenti/GitHubGitHub/bethington/ghidra-mcp
Static AnalysisDynamic Analysis (Sandboxing)Reverse EngineeringScripting & AutomationDebuggersFuzzingUtilities & FrameworksBinary AnalysisLearning & EducationAI-Assisted Reversing
GitHubbethington/ghidra-mcp

ghidra-mcp

3.3k97731 giorno faRevisionato da Kitploit

MCP server bridging Ghidra's reverse engineering with AI tools: 256 tools for decompilation, P-code emulation, live debugging, data flow analysis, batch operations, and convention enforcement across headless and GUI modes.

Vedi Repository

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
Contenuto non disponibile nella lingua richiesta. Visualizzazione della versione inglese.
# Ghidra MCP Server

[![MCP Toplist](https://mcptoplist.com/badge/glama/bethington/ghidra-mcp.svg)](https://mcptoplist.com/server/glama%2Fbethington%2Fghidra-mcp)

[![Tests](https://img.shields.io/github/actions/workflow/status/bethington/ghidra-mcp/tests.yml?branch=main&style=for-the-badge&label=Tests&logo=github-actions&logoColor=white)](https://github.com/bethington/ghidra-mcp/actions/workflows/tests.yml)
[![Release](https://img.shields.io/github/v/release/bethington/ghidra-mcp?style=for-the-badge&logo=github&logoColor=white&color=blue)](https://github.com/bethington/ghidra-mcp/releases/latest)
[![License](https://img.shields.io/github/license/bethington/ghidra-mcp?style=for-the-badge&color=green)](LICENSE)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/bethington?style=for-the-badge&logo=githubsponsors&logoColor=white&label=Sponsors&labelColor=ea4aaa&color=ea4aaa)](https://github.com/sponsors/bethington)

[![Python](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-3776AB?style=for-the-badge&logo=python&logoColor=white)](https://www.python.org/)
[![Java](https://img.shields.io/badge/Java-21-ED8B00?style=for-the-badge&logo=openjdk&logoColor=white)](https://openjdk.org/projects/jdk/21/)
[![Ghidra](https://img.shields.io/badge/Ghidra-12.1.4-brightgreen?style=for-the-badge&logoColor=white)](https://ghidra-sre.org/)
[![MCP](https://img.shields.io/badge/MCP-Model%20Context%20Protocol-6C5CE7?style=for-the-badge&logoColor=white)](https://modelcontextprotocol.io/)

[![Stars](https://img.shields.io/github/stars/bethington/ghidra-mcp?style=for-the-badge&logo=github&logoColor=white&color=yellow)](https://github.com/bethington/ghidra-mcp/stargazers)
[![Last commit](https://img.shields.io/github/last-commit/bethington/ghidra-mcp?style=for-the-badge&logo=git&logoColor=white)](https://github.com/bethington/ghidra-mcp/commits/main)
[![Discussions](https://img.shields.io/badge/discussions-join-7B68EE?style=for-the-badge&logo=github&logoColor=white)](https://github.com/bethington/ghidra-mcp/discussions)
[![Issues](https://img.shields.io/github/issues/bethington/ghidra-mcp?style=for-the-badge&logo=github&logoColor=white&color=orange)](https://github.com/bethington/ghidra-mcp/issues)
[![OpenSSF Scorecard](https://img.shields.io/ossf-scorecard/github.com/bethington/ghidra-mcp?style=for-the-badge&logo=securityscorecard&logoColor=white&label=OpenSSF%20Scorecard)](https://scorecard.dev/viewer/?uri=github.com/bethington/ghidra-mcp)

> If you find this useful, please ⭐ star the repo — it helps others discover it!
>
> If Ghidra MCP saves you time, consider [sponsoring the project](https://github.com/sponsors/bethington). 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. **209 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](https://github.com/bethington/ghidra-mcp/releases) 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.1.4](https://github.com/NationalSecurityAgency/ghidra/releases),
   Java 21 and [uv](https://docs.astral.sh/uv/getting-started/installation/).
   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:

   ```bash
   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):

   ```bash
   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):

   ```json
   {
     "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](https://github.com/bethington/ghidra-mcp/blob/dev/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.

- **209 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
- **209 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](#optional-connect-an-external-debugger-server))

### 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](#quickstart-install-a-release-no-clone-no-build) 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 21 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.1.4** (or compatible version)
- **Python 3.10+** with [uv](https://docs.astral.sh/uv/) (recommended) or pip + venv

> Shared Ghidra Server users: Ghidra 12.1.4 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.4 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:**

   ```bash
   git clone https://github.com/bethington/ghidra-mcp.git
   cd ghidra-mcp
   ```

2. **Recommended: run environment preflight first:**

   ```text
   python -m tools.setup preflight --ghidra-path "F:\ghidra_12.1.4_PUBLIC"
   ```

3. **Build and deploy to Ghidra:**

   ```text
   python -m tools.setup ensure-prereqs --ghidra-path "F:\ghidra_12.1.4_PUBLIC"
   python -m tools.setup build
   python -m tools.setup deploy --ghidra-path "F:\ghidra_12.1.4_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](https://github.com/bethington/ghidra-mcp/blob/dev/docs/INSTALL_GUI.md).

4. **Optional strict/manual mode** (advanced):

   ```text
   # Skip automatic prerequisite setup
   python -m tools.setup build
   python -m tools.setup deploy --ghidra-path "F:\ghidra_12.1.4_PUBLIC"
   ```

5. **Show command help**:

   ```text
   python -m tools.setup --help
   ```

6. **Optional build-only mode** (advanced/troubleshooting):

   ```text
   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.

   ```bash
   # 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
   ```

   ```bash
   # 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:**

   ```bash
   git clone https://github.com/bethington/ghidra-mcp.git
   cd ghidra-mcp
   ```

2. **Install system prerequisites** (if not already installed):

   ```bash
   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](https://docs.astral.sh/uv/) (recommended — it creates and manages a
   > project-local `.venv` automatically, and is what this repo's commands use):
   >
   > ```bash
   > 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:
   >
   > ```bash
   > python3 -m venv .venv && source .venv/bin/activate
   > pip install -e .
   > bridge-mcp-ghidra
   > ```

3. **Run environment preflight:**

   ```bash
   python -m tools.setup preflight --ghidra-path ~/ghidra_12.1.4_PUBLIC
   ```

4. **Build and deploy to Ghidra (single command):**

   ```bash
   python -m tools.setup ensure-prereqs --ghidra-path ~/ghidra_12.1.4_PUBLIC
   python -m tools.setup build
   python -m tools.setup deploy --ghidra-path ~/ghidra_12.1.4_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:**

   ```bash
   python -m tools.setup install-ghidra-deps --ghidra-path ~/ghidra_12.1.4_PUBLIC
   ```

6. **Show command help:**

   ```bash
   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:**

   ```bash
   brew install openjdk@21 maven python ghidra
   ```

2. **Clone the repository:**

   ```bash
   git clone https://github.com/bethington/ghidra-mcp.git
   cd ghidra-mcp
   ```

3. **Install Ghidra JARs into local Maven:**

   ```bash
    python -m tools.setup install-ghidra-deps \
       --ghidra-path /opt/homebrew/opt/ghidra/libexec
   ```

4. **Build and deploy:**

   ```bash
    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.4_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:**

   ```bash
   /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](https://github.com/bethington/ghidra-mcp/issues/441)):

   ```json
   {
     "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](https://github.com/Pandoriaantje) maintains community AUR packages:

- [`ghidra-mcp-git`](https://aur.archlinux.org/packages/ghidra-mcp-git) — tracks `main`
- [`ghidra-mcp`](https://aur.archlinux.org/packages/ghidra-mcp) — tracks tagged releases

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

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

### Basic Usage

#### Option 1: Stdio Transport (Recommended for AI tools)

```bash
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:

```json
{
  "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](https://github.com/bethington/ghidra-mcp/issues/441))

To add the bridge to [Autohand Code](https://github.com/autohandai/code-cli/) from a cloned checkout:

```bash
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.

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

```bash
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):

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

Browser-based clients (e.g. [MCP Inspector](https://github.com/modelcontextprotocol/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:

```bash
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)

```bash
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 209 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:

```text
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` (68 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:

```bash
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).

```bash
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](https://github.com/bethington/ghidra-mcp/issues/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](https://github.com/bethington/ghidra-mcp/blob/dev/docs/project-management/MIGRATION_7.0.0_TOOL_CONSOLIDATION.md)
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. |

---

[Read more](https://github.com/bethington/ghidra-mcp)
Scarica lo strumento