Skip to content

Getting started

ghidra-mcp edited this page Jul 22, 2026 · 1 revision

Getting started

This guide covers installation, MCP client connection, the normal analysis lifecycle, persistence, and published container usage.

Choose a transport

  • Use stdio when the MCP client and Ghidra run on the same trusted machine. The client launches and owns the process; no token is required.
  • Use streamable-http for remote or containerized access. It requires an input root, a public root URL, and a Bearer token of at least 32 UTF-8 bytes. Terminate TLS at a trusted reverse proxy for non-loopback access.

Run the published container

After the GHCR package is public:

docker pull ghcr.io/xjoker/ghidra-mcp:latest
docker volume create ghidra-mcp-projects
(
read -rsp 'Ghidra MCP token: ' GHIDRA_MCP_AUTH_TOKEN && echo
export GHIDRA_MCP_AUTH_TOKEN
docker run -d --name ghidra-mcp \
  --platform linux/amd64 \
  -p 127.0.0.1:8765:8765 \
  -e GHIDRA_MCP_PUBLIC_URL=http://127.0.0.1:8765 \
  -e GHIDRA_MCP_AUTH_TOKEN \
  -v ghidra-mcp-projects:/data/projects \
  -v /absolute/path/to/binaries:/data/input:ro \
  ghcr.io/xjoker/ghidra-mcp:latest
)

The hidden prompt keeps the token out of shell history. Docker daemon users can still inspect container environment variables, so restrict daemon access.

Prefer a version tag such as 20260722.5 for reproducible deployments. Use latest only when automatic upgrades are acceptable. Verify the running build before testing functionality:

curl -fsS http://127.0.0.1:8765/health

The response contains status, version, git_commit, and schema_version. A healthy process does not prove that Ghidra can import a binary; perform a real program_open check as well.

Run from source over stdio

git clone https://github.com/xjoker/ghidra-mcp.git
cd ghidra-mcp
uv sync --locked
cp .env.example .env

Set GHIDRA_INSTALL_DIR to Ghidra 12.1.2 or later, then configure the MCP client to launch:

uv --directory /absolute/path/to/ghidra-mcp run ghidra-mcp

Pass GHIDRA_INSTALL_DIR=/absolute/path/to/ghidra and GHIDRA_MCP_TRANSPORT=stdio in the client environment.

Follow the analysis lifecycle

  1. Call program_open with a binary path. HTTP mode accepts only regular files inside GHIDRA_MCP_INPUT_ROOT.
  2. Keep the returned program_id; subsequent tools use it instead of reopening the binary.
  3. Explore with program_info, functions_list, instructions_list, references_list, and decompile_function.
  4. Use mutation tools only when intended. Writes run in Ghidra transactions and persist to the project store.
  5. Call program_close when finished. It saves first and keeps the session open if saving fails.

Addresses use Ghidra string notation. instructions_list reports requested and effective starts when Ghidra advances over undefined bytes. Detached continuation ranges are not function members until explicitly added with function_body_add.

Preserve projects

GHIDRA_MCP_STORAGE_ROOT stores persistent Ghidra projects. In containers, mount /data/projects as a dedicated volume and /data/input read-only. Never replace the only project volume during an upgrade.

Stop writes before backup. Restore into a new volume, start a separate container, and verify saved names and comments before switching traffic. See Operations for the full procedure.

Troubleshoot common failures

  • 401 from /mcp: the Bearer token is missing or incorrect.
  • Public URL error: use the client-visible HTTP(S) root URL, not 0.0.0.0 or ::.
  • Input path rejected: place the regular file under GHIDRA_MCP_INPUT_ROOT; symlinks cannot escape it.
  • Project lock error: another process owns the project; close the program or stop the owner cleanly.
  • Health commit mismatch: the container is stale. Update it before functional testing.

Review the security policy before exposing HTTP beyond the local host.