Skip to main content
Glama

License GitHub release (latest by date) GitHub stars GitHub forks GitHub contributors Follow @lauriewired

ghidra_MCP_logo

ghidraMCP

ghidraMCP is an Model Context Protocol server for allowing LLMs to autonomously reverse engineer applications. It exposes numerous tools from core Ghidra functionality to MCP clients.

https://github.com/user-attachments/assets/36080514-f227-44bd-af84-78e29ee1d7f9

Features

MCP Server + Ghidra Plugin

  • Decompile and analyze binaries in Ghidra

  • Automatically rename methods and data

  • List methods, classes, imports, and exports

Installation

Prerequisites

  • Install Ghidra 12.1.4

  • Install uv (or Python 3.10+ with pip install git+https://github.com/LaurieWired/GhidraMCP, then use ghidra-mcp as the command below)

Related MCP server: GhidraMCP

Ghidra

First, download the latest release from this repository. This contains the Ghidra plugin and Python MCP client. Then, you can directly import the plugin into Ghidra.

  1. Run Ghidra

  2. Select File -> Install Extensions

  3. Click the + button

  4. Select the ghidra_12.1.4_PUBLIC_<date>_GhidraMCP.zip from the downloaded release

  5. Restart Ghidra

  6. Make sure the GhidraMCPPlugin is enabled in File -> Configure -> Developer

  7. Optional: Configure the port in Ghidra with Edit -> Tool Options -> GhidraMCP HTTP Server

Video Installation Guide:

https://github.com/user-attachments/assets/75f0c176-6da1-48dc-ad96-c182eb4648c3

MCP Clients

Theoretically, any MCP client should work with ghidraMCP. Most clients accept a JSON config like the following:

{
  "mcpServers": {
    "ghidra": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/LaurieWired/GhidraMCP",
        "ghidra-mcp",
        "--ghidra-server",
        "http://127.0.0.1:8080/"
      ]
    }
  }
}

The server IP and port are configurable and should be set to point to the target Ghidra instance. If not set, both will default to localhost:8080.

For clients that connect to a URL instead of launching a command, first run the MCP server yourself:

uvx --from git+https://github.com/LaurieWired/GhidraMCP ghidra-mcp --transport streamable-http --mcp-host 127.0.0.1 --mcp-port 8081 --ghidra-server http://127.0.0.1:8080/

Then add http://127.0.0.1:8081/mcp as a remote server in your client.

Example 1: VS Code

Run MCP: Add Server from the Command Palette, or add the following to .vscode/mcp.json in your workspace:

{
  "servers": {
    "ghidra": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/LaurieWired/GhidraMCP",
        "ghidra-mcp",
        "--ghidra-server",
        "http://127.0.0.1:8080/"
      ]
    }
  }
}

Example 2: Claude Code

Run the following command:

claude mcp add ghidra -- uvx --from git+https://github.com/LaurieWired/GhidraMCP ghidra-mcp --ghidra-server http://127.0.0.1:8080/

Headless (no Ghidra GUI)

ghidra-mcp can also import and analyze a binary itself using PyGhidra, with no Ghidra GUI running. This needs Python 3.10–3.13, the GhidraMCP extension installed in Ghidra (or --extension-jar /path/to/GhidraMCP.jar), and GHIDRA_INSTALL_DIR set to your Ghidra 12.1.4 directory:

uvx --python 3.13 --from "ghidra-mcp[headless] @ git+https://github.com/LaurieWired/GhidraMCP" ghidra-mcp --headless --binary /path/to/target

Use the same command and arguments in any of the client configs above. Add --project DIR to keep the Ghidra project (and save changes) between runs. On macOS, build Ghidra's decompiler once with support/gradle/gradlew buildNatives from the Ghidra directory.

Building from Source

  1. Set GHIDRA_INSTALL_DIR to your Ghidra 12.1.4 directory

  2. Build the extension with Gradle (Java 21) by running:

cd extension && $GHIDRA_INSTALL_DIR/support/gradle/gradlew buildExtension

The generated zip file in extension/dist/ includes the built Ghidra plugin and its resources. These files are required for Ghidra to recognize the new extension.

  • lib/GhidraMCP.jar

  • extension.properties

  • Module.manifest

The Python MCP server can be run from a checkout with uv run ghidra-mcp, and tested with uv run pytest.

Available Tools

30 tools
decompile_functionA

Decompile a function by name and return C pseudocode. Fails if the name is ambiguous; use decompile_function_by_address in that case.

Inputs: name (required). Returns: object

decompile_function_by_addressB

Decompile the function at or containing an address and return C pseudocode.

Inputs: address (required). Returns: object

disassemble_functionC

Disassemble the instructions in a function's body (address, bytes, instruction, end-of-line comment).

Inputs: address (required), limit, offset. Returns: object

get_current_addressA

Get the address currently selected in the Ghidra GUI listing.

Inputs: no named parameters. Returns: object

get_current_functionA

Get the function containing the address currently selected in the Ghidra GUI.

Inputs: no named parameters. Returns: object

get_function_by_addressA

Get the function at or containing an address: name, signature, body range, calling convention.

Inputs: address (required). Returns: object

get_function_callsA

Function-level call graph, one level deep. Callers are call sites that reach this function; callees are calls made from anywhere in its body, including indirect calls (direct=false). offset/limit apply to each list separately.

Inputs: address (required), limit, offset, direction. Returns: object

get_function_xrefsB

List references to a function's entry point, by name or (preferably) address.

Inputs: name, limit, offset, address. Returns: object

get_program_infoA

Identify the target program: name, format, language/architecture, compiler spec, image base, address range, size, entry points, and hashes.

Inputs: no named parameters. Returns: object

get_xrefs_fromB

List references from a single instruction or data address.

Inputs: address (required), limit, offset. Returns: object

get_xrefs_toB

List references to an address, with the function each reference comes from.

Inputs: address (required), limit, offset. Returns: object

list_classesC

List class namespaces (fully qualified names).

Inputs: limit, offset. Returns: object

list_data_itemsC

List defined data with address, label, type, and value.

Inputs: limit, offset. Returns: object

list_exportsC

List exported symbols / entry points.

Inputs: limit, offset. Returns: object

list_functionsB

List functions (name and entry address), optionally filtered by a case-insensitive substring of the name.

Inputs: limit, filter, offset. Returns: object

list_importsC

List imported (external) symbols and their libraries.

Inputs: limit, offset. Returns: object

list_methodsA

Deprecated: use list_functions. Lists function names only.

Inputs: limit, offset. Returns: result

list_namespacesC

List all non-global namespaces (fully qualified names).

Inputs: limit, offset. Returns: object

list_segmentsB

List memory blocks with address range, size, and permissions.

Inputs: limit, offset. Returns: object

list_stringsB

List defined strings with their addresses, optionally filtered by a case-insensitive substring of the content.

Inputs: limit, filter, offset. Returns: object

read_memoryB

Read up to 4096 bytes of program memory as hex and ASCII. Unmapped or uninitialized bytes are shown as '??' and listed in gaps.

Inputs: address (required), length. Returns: object

rename_dataC

Rename the label of defined data (or an existing symbol) at an address.

Inputs: address (required), new_name (required). Returns: object

rename_functionA

Rename a function by its current name. Fails if the name is ambiguous; prefer rename_function_by_address.

Inputs: new_name (required), old_name (required). Returns: object

rename_function_by_addressB

Rename the function at or containing an address.

Inputs: new_name (required), function_address (required). Returns: object

rename_variableA

Rename a local variable or parameter as shown in the decompiler. Identify the function by function_address (preferred) or function_name.

Inputs: new_name (required), old_name (required), function_name, function_address. Returns: object

search_functions_by_nameC

Search for functions whose name contains the given substring (case-insensitive).

Inputs: query (required), limit, offset. Returns: object

set_decompiler_commentB

Set the pre-comment at an address (shown in the decompiler). An empty comment clears it.

Inputs: address (required), comment (required). Returns: object

set_disassembly_commentB

Set the end-of-line comment at an address (shown in the disassembly). An empty comment clears it.

Inputs: address (required), comment (required). Returns: object

set_function_prototypeC

Set a function's signature from a C prototype, e.g. "int foo(char *buf, int len)".

Inputs: prototype (required), function_address (required). Returns: object

set_local_variable_typeC

Set the data type of a decompiler variable, e.g. "char *", "DWORD", "MY_STRUCT *".

Inputs: new_type (required), variable_name (required), function_address (required). Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.2/5.0

    Scored across 30 tools

    Disambiguation4/5

    Most tools target distinct resources/actions (list vs get vs rename vs set), and the descriptions proactively resolve ambiguity (e.g. decompile_function vs decompile_function_by_address, 'prefer rename_function_by_address'). Minor overlap exists in the xref trio (get_xrefs_to, get_xrefs_from, get_function_xrefs) and between list_functions / search_functions_by_name / deprecated list_methods, but directionality and filters make each usable.

    Naming Consistency5/5

    Consistent snake_case verb_noun pattern throughout, using a small predictable verb set (list_, get_, decompile_, disassemble_, rename_, set_). Variants like get_function_by_address and decompile_function_by_address follow the same convention, so nothing surprises the agent.

    Tool Count3/5

    30 tools is heavy and pushes past the comfortable range for a single server. Reverse-engineering genuinely needs many read/analyze/write operations, but the deprecated list_methods is dead weight and several near-duplicate pairs (function vs by_address) inflate the surface.

    Completeness4/5

    Strong lifecycle coverage for an analysis server: discovery (imports, exports, functions, strings, data, segments), analysis (decompile, disassemble, xrefs, call graph), and modification (renames, prototypes, types, comments), plus raw memory reads. Gaps remain for active patching/writing memory, creating/undefining functions, or searching by bytes, but core workflows are covered.

    Maintenance

    ActivitySlowing
    ResponsivenessMostly unanswered

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      An MCP server that enables LLMs to autonomously reverse engineer applications through Cutter, allowing them to decompile binaries, analyze code, and rename methods programmatically.
      34
      Apache 2.0
    • A
      license
      Not graded
      quality
      D
      maintenance
      An MCP server that allows LLMs to autonomously reverse engineer applications by exposing Ghidra's functionality, including decompiling binaries, analyzing code, and renaming methods and data.
      Apache 2.0
    • A
      license
      Not graded
      quality
      D
      maintenance
      An Model Context Protocol server that enables LLMs to autonomously reverse engineer applications by exposing Ghidra's decompilation and analysis tools. It allows AI agents to list code structures, rename methods, and analyze binaries directly through MCP-compatible clients.
      Apache 2.0
    • A
      license
      Not graded
      quality
      F
      maintenance
      MCP server that allows LLMs to autonomously reverse engineer applications using Ghidra, exposing tools like decompilation, renaming, and listing methods.
      27
      Apache 2.0