Skip to content

Operations

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

Operations

Check before deployment

  1. Read the root VERSION file and pass the full Git commit as a Docker build argument.
  2. Build with --platform linux/amd64 --no-cache and confirm the Ghidra SHA-256 check succeeds.
  3. Generate a random long token and provide it through the environment or an untracked .env.
  4. Mount input read-only at /data/input and a dedicated named volume at /data/projects.
  5. For non-loopback access, terminate TLS at a trusted reverse proxy and restrict allowed sources.

Start and verify the service

Replace <VERSION> with the value from the root VERSION file:

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='<random token of at least 32 bytes>' \
  -v ghidra-mcp-projects:/data/projects \
  -v /absolute/path/to/binaries:/data/input:ro \
  ghcr.io/xjoker/ghidra-mcp:<VERSION>
curl -fsS http://127.0.0.1:8765/health

Expected response shape:

{
  "status": "ok",
  "version": "<VERSION>",
  "git_commit": "<full Git commit>",
  "schema_version": "<16 hexadecimal characters>"
}

status=ok proves only that the MCP process started. Compare all metadata with the intended build, then perform one authenticated program_open against a real fixture.

Back up projects

Stop writes first to avoid an inconsistent copy:

docker run --rm \
  -v ghidra-mcp-projects:/source:ro \
  -v "$PWD":/backup \
  ubuntu:24.04@sha256:4fbb8e6a8395de5a7550b33509421a2bafbc0aab6c06ba2cef9ebffbc7092d90 \
  tar -C /source -czf /backup/ghidra-mcp-projects.tar.gz .

Restore without replacing the only copy

docker volume create ghidra-mcp-projects-restored
docker run --rm \
  -v ghidra-mcp-projects-restored:/target \
  -v "$PWD":/backup:ro \
  ubuntu:24.04@sha256:4fbb8e6a8395de5a7550b33509421a2bafbc0aab6c06ba2cef9ebffbc7092d90 \
  tar -C /target -xzf /backup/ghidra-mcp-projects.tar.gz

Start a separate container on the restored volume. Use a real program_open and confirm saved names and comments before switching traffic. Never overwrite the only project volume in place.

Troubleshoot

Symptom Cause and action
HTTP startup rejects a missing or short token Set a random GHIDRA_MCP_AUTH_TOKEN of at least 32 UTF-8 bytes; stdio does not require one
HTTP startup rejects the public URL Set the client-visible HTTP(S) root; do not use 0.0.0.0 or ::
HTTP startup rejects the input root Set GHIDRA_MCP_INPUT_ROOT; containers default to /data/input and should mount it read-only
program_open rejects a path Place the regular file under the input root; symlinks cannot escape it
/mcp returns 401 Supply the correct Authorization: Bearer <token> header
/mcp returns 400 Authentication passed, but the body is not a valid MCP message
Unable to lock project Another session or process owns it; call program_close or stop the owner cleanly
Ghidra installation is missing Check GHIDRA_INSTALL_DIR; the container uses /opt/ghidra
Analysis exceeds its deadline Adjust GHIDRA_MCP_ANALYSIS_TIMEOUT_SECONDS within 1–3600 after checking sample complexity and resources
Health commit differs from the intended build The image or container is stale; update it before functional verification

Maintain the security boundary

  • The Bearer token is one deployment credential, not a user permission model. Rotate it and restart after exposure.
  • Never mount sensitive host directories under GHIDRA_MCP_INPUT_ROOT.
  • Ghidra parses untrusted files. Limit container resources, privileges, and network access.
  • Logs go only to stdout/stderr and must not contain tokens, binary content, or personal information.
  • Never mount the Docker socket, host root, or sensitive executable directories into the service.