Python Command-Line Ghidra MCP server providing reverse engineering and binary analysis capabilities through Model Context Protocol
PyGhidra MCP presents a large tool suite (25 tools) with solid parameter schemas and descriptions, placing it above the median (~50). All tools have descriptive text and properly-typed input schemas with clear parameter definitions. However, several critical gaps prevent a higher score: (1) No output schemas are documented in the provided source, forcing LLMs to guess result structures; (2) Tool annotations (readOnlyHint, destructiveHint, idempotentHint) are completely absent despite 12 WRITE/DESTRUCTIVE tools; (3) Error handling guidance is not visible, no recovery hints, retryability classification, or actionable error messages; (4) Some parameter descriptions lack constraints (e.g., timeout_sec has no min/max bounds, similarity_threshold lacks valid range); (5) One tool (delete_project_binary) is marked DESTRUCTIVE with no confirmation or dry-run option visible. Strengths: naming is consistently verb-driven (decompile_, search_, list_, rename_, set_, get_), parameter names match across tools (binary_name is consistent), and descriptions explain both what and when to use each tool (e.g., decompile_function explains batch modes and flags). Pagination is properly implemented (offset/limit on list_* tools). The average description length (~150 chars) aligns with baselines (p10=34, p90=392).
Decompile function(s) to pseudo-C by name or address. Accepts a single target or a list for batch decompilation. Rich response flags attach callees, strings, and/or xrefs to each result. `timeout_sec` applies per target.
Delete a binary from the project.
Disassemble binary code at a specified address.
Generate a call graph for a function.
Get the current active user's location and metadata in the Ghidra GUI. Assume this is volatile and has changed since last call.
Navigate the Ghidra GUI CodeBrowser to an address or function.
Import a binary into the project.
No output schemas documented. LLMs cannot infer result structure (field names, types, nested objects). Forces agents to guess or request clarification.
Tool annotations completely absent. 12 tools marked WRITE or DESTRUCTIVE lack readOnlyHint/destructiveHint/idempotentHint. LLMs cannot distinguish safe reads from destructive mutations.
Error handling guidance is not visible in descriptions. No recovery hints (e.g., 'if binary not found, call list_project_binaries()'), retryability classification, or actionable error messages.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | B | 74 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 49 | - | v1 |
List exported functions and variables from a binary.
List imported functions and libraries for a binary.
List programs currently open in the Ghidra GUI.
List all binaries in the project with their status.
Get binary metadata: architecture, compiler, endianness, hashes, analysis counts.
List cross-references for a function or address.
Open a project binary in the Ghidra GUI CodeBrowser. Defaults to a new CodeBrowser unless the binary is already open.
Read raw bytes from a binary at a specified address.
Rename a function.
Rename a variable in a function.
Save the current program to disk.
Search decompiled pseudo-C code. Modes: semantic (vector similarity, default) or literal (exact match). Results include both mode counts.
Search for strings in a binary.
Search symbols by regex pattern (case-insensitive). Supports full regex (e.g. ``^main$``, ``func.*init``). Plain substrings still work since they are valid regex. Set ``functions_only=True`` to search only function symbols (excludes labels, variables, classes, namespaces).
Set a comment at an address or function.
Set the active/current program in the Ghidra GUI CodeBrowser.
Set the function signature/prototype.
Set the data type of a variable.
Destructive operation (delete_project_binary) lacks confirmation/dry-run support. No evidence of a confirm_before_execute pattern to prevent accidental data loss.
Parameter constraints incomplete. timeout_sec lacks min/max bounds; similarity_threshold has no valid range specified (only default=0). LLMs may pass nonsensical values.
Some descriptions under-specify expected input format. E.g., 'address' parameter in read_bytes/disassemble lacks format guidance (hex? decimal? with 0x prefix?). LLMs may pass invalid formats.
Batch operations not offered. decompile_function accepts list input but most tools require single calls. Agents looping over 20 functions make 20 calls instead of 1 - 2 batch calls, wasting tokens and latency.
Pagination info incomplete. list_* tools return offset/limit but no total count or next_cursor documented. Agents cannot know if more results exist or when pagination is exhausted.