Skip to content

lumirth/ghidra-agent-plugin

v1.0.5MIT

Inspect and improve an existing Ghidra Program through a small local MCP interface.

Ghidra Agent Plugin

A small, GUI-independent MCP interface for an existing Ghidra Program. It works as a native Codex plugin and as a portable Agent Plugin for clients including Cursor.

The private stdio process keeps the PyGhidra JVM warm. Each tool call opens the selected Program for that operation and releases it before returning. There is no network listener, Ghidra extension, daemon, index, cache, mutation journal, unsaved edit session, or custom lock protocol.

Requirements

  • Ghidra installed locally; 12.1.2 is the currently validated version.
  • A 64-bit JDK 21, as required by Ghidra 12.1.
  • uv available on PATH or through UV_PATH.
  • Python 3.9 or newer to run the small launcher. The Python 3.10+ analysis runtime is managed by uv.

The launcher discovers common Ghidra installations. Set GHIDRA_INSTALL_DIR when discovery is not sufficient. Call select_program with an explicit absolute .gpr path; the server never chooses a project from ambient configuration.

Codex

The Codex package is described by .codex-plugin/plugin.json and .mcp.json. Codex owns installation, skill loading, and MCP process lifecycle. No plugin-specific installer is required.

For development, validate the checkout and expose it through a local Codex marketplace. For distribution, publish this repository through the Codex plugin directory.

Cursor and other Agent Plugin clients

The portable package is described by plugin.json and mcp.json. Cursor can load it in either of its local workflows:

  • Select this repository in Cursor's local marketplace folder picker. The thin .cursor-plugin/marketplace.json entry points back to this same plugin root.
  • Place or copy the checkout at ~/.cursor/plugins/local/ghidra-agent-plugin, then reload Cursor.

For symlink-based development:

ln -s /absolute/path/to/ghidra-agent-plugin \
  "$HOME/.cursor/plugins/local/ghidra-agent-plugin"

Reload Cursor, enable the ghidra MCP server, and ask it to select a Program. The root MCP bootstrap accepts Cursor's CURSOR_PLUGIN_ROOT and the portable standard's PLUGIN_ROOT; the launcher uses host-provided PLUGIN_DATA when available or the normal per-user application-data directory for the locked runtime. The Cursor package contains no separate implementation or mutable configuration state.

Cloud agents

The same stdio server works in a cloud agent when its environment contains:

  1. this plugin;
  2. uv, Python 3.10+, and a 64-bit JDK 21;
  3. an official Ghidra release, with GHIDRA_INSTALL_DIR set if it is outside the usual locations; and
  4. the complete .gpr and sibling .rep tree to inspect.

Nothing needs to reach back into the desktop GUI. A cloud VM gets its own Ghidra process and its own project copy. Do not point two writable environments at the same project repository.

Tool surface

Eight read tools cover Program selection, search, function and address inspection, decompilation, listing, raw references, and exact-ID SSA tracing.

Reads use Ghidra's native read-only project path. Each call releases the Program and project data before returning; an idle server does not hold the project open.

Two write tools remain first-class:

  • apply_changes applies one coherent batch in a native Ghidra transaction, saves, and closes.
  • reanalyze runs ordinary Ghidra analysis over one explicit address range, saves, and closes.

Writes ask Ghidra for normal writable access. When another Ghidra process owns the project, the tool returns project_in_use; the plugin does not inspect or circumvent Ghidra locks.

Read the tool reference for the exact operations and change kinds.

Diagnose

python3 scripts/ghidra_agent.py doctor

The first launch or doctor run may download the pinned Python dependencies. Runtime files live in PLUGIN_DATA when the host provides it, or in the normal per-user application-data directory. Set GHIDRA_AGENT_DATA_DIR to override that location.

Scope

Project creation, import and deletion, GUI cursor control, and arbitrary script execution are outside this connector. Repeatable bulk transformations and project-specific imports belong in repository-owned Ghidra scripts or the official headless runner.

Decompiler output is not recovered original source and does not by itself prove compiler, object, linker, translation-unit, or byte-reproduction claims.