Free & open source MIT licensed

Ghidra analysis.
Connected to your tools.

Follow call graphs and data flow, refine native types, compare functions, and preserve your analysis. Ghidra MCP connects compatible AI clients to native Ghidra through a local Rust server and Java adapter.

85 MCP tools Local stdio transport Background + GUI

Native analysis, structured operations

Work from bytes to evidence.

The Model Context Protocol lets a client discover tools and call them with defined inputs. This adapter brings a focused Ghidra workflow to that interface, with project identities, explicit processor selection, and results you can inspect.

Understand the program

Inspect control flow and call graphs, search instructions and constants, and trace decompiler SSA with explicit memory and call boundaries.

Record your analysis

Define structures and signatures, edit guarded variables, batch labels and comments, then explicitly save and verify your work.

Choose how to work

Use 85 tools in a background or GUI workflow, with 84 supported headlessly. Compare fingerprints and run bounded isolated emulation with explicit inputs.

What has been tested

The repository records native headless and GUI acceptance on Windows, Ghidra 12.1.3 PUBLIC, and JDK 21, using generated synthetic binaries. These runs exercise actual Ghidra; transport tests with a simulated mailbox are recorded separately. The GUI harness uses a hidden CodeBrowser and does not automate extension-installation dialogs.

Generated x86 and TriCore arithmetic fixtures exercise isolated emulation; they do not certify an ECU's code, memory layout or peripheral behavior. In particular, the current raw importer rejects TC29x processor-default multiple memory blocks. Read the import limits and native acceptance scope.

Quickstart

Build it. Start a bridge. Connect locally.

Install Ghidra 12.1.3 PUBLIC, JDK 21, and Rust. The repository pins Rust 1.88.0. Build the Java adapter against the Ghidra version you will run. Ghidra and Java are separately installed; neither is bundled.

1. Build the server and Java adapter

git clone https://github.com/amirdauti/redline-autohaus-ghidra-mcp.git
cd redline-autohaus-ghidra-mcp
cargo build --locked --release
.\scripts\build-extension.ps1 -GhidraHome 'C:\tools\ghidra_12.1.3_PUBLIC' -JavaHome 'C:\tools\jdk-21'

Substitute your own paths. The Rust executable is target/release/ghidra-mcp.exe. The extension ZIP and latest-build.json are written under dist/; the build metadata records the adapter JAR path. A shell build helper is also included. Node.js is needed only for the optional acceptance test, and normal operation requires neither Node.js nor Python.

2. Start a background Ghidra bridge

Create private project, input, and mailbox directories, then start the bridge. The project and input directories must already exist.

New-Item -ItemType Directory -Force -Path 'C:\GhidraWork\projects', 'C:\GhidraWork\inputs', 'C:\GhidraWork\mailbox'
.\scripts\start-bridge.ps1 `
  -GhidraHome 'C:\tools\ghidra_12.1.3_PUBLIC' `
  -JavaHome 'C:\tools\jdk-21' `
  -Mailbox 'C:\GhidraWork\mailbox' `
  -ProjectRoot 'C:\GhidraWork\projects' `
  -ImportRoot 'C:\GhidraWork\inputs'
.\target\release\ghidra-mcp.exe --bridge-dir 'C:\GhidraWork\mailbox' --doctor

The launcher reports the Java process ID and log paths. It does not open a project or import a file automatically. Project operations and imports are restricted to the configured roots, including resolved filesystem links. --doctor returns one JSON status and exits.

3. Register a local stdio server in your MCP client

Use your client's configuration format with these launch settings. Replace the executable path with your absolute build output path and use the bridge's mailbox.

{
  "command": "C:\\tools\\ghidra-mcp\\ghidra-mcp.exe",
  "args": ["--bridge-dir", "C:\\GhidraWork\\mailbox", "--timeout-ms", "45000"]
}

Leave --doctor out of the persistent connection. Allow a client tool timeout of at least 60 seconds for this 45-second bridge deadline when the bridge is already running; use 120 seconds for automatic startup. Standard output is reserved for MCP; diagnostics use standard error. This website is documentation, not a hosted Ghidra endpoint.

Optional: start the background bridge automatically on Windows

Add --launch-config and an absolute launch JSON path to the server arguments. MCP initialization and tool discovery finish before Java starts. Allow a client tool timeout of 120 seconds because the first native tool call includes cold startup and the native request. A client startup timeout covers MCP initialization only. Start from the repository's launch configuration example.

Set your Ghidra, Java, adapter JAR, project/import roots, and mailbox paths. Use the JAR recorded by your build; keep start-config.ps1, start-bridge.ps1, and common.ps1 together. The launch file's bridge_dir must match --bridge-dir.

Automatic startup can reuse a running bridge. Java remains alive when the MCP client disconnects, so unsaved work remains in that process until explicitly saved. Omit --launch-config for a manually started bridge or GUI connection.

An offline bridge or a mailbox owned by another client leaves tool discovery available. Start the bridge or disconnect the owning client, then call ghidra_status again in the same MCP session. Interrupted native startup or an uncertain dispatched request requires recovery before restarting; a timeout does not prove that Java never started.

Next: call ghidra_status, inspect capabilities, and follow the synthetic x86 walkthrough to verify import, bytes, function creation, decompilation, and saving.

CodeBrowser connection

Use the GUI when you want to see the work.

Both modes expose the same 85 MCP tool names. The current ghidra_status response tells you which operations the connected bridge supports.

Install and enable

  1. Install the generated ZIP through Ghidra's File > Install Extensions, then restart Ghidra.
  2. Open a CodeBrowser and enable RedlineMcpPlugin through File > Configure.
  3. Choose Tools > Redline MCP > Start bridge... and configure the mailbox and allowed directories.
  4. Connect your MCP client to that mailbox without automatic background startup.

Move a project between modes

Finish analysis and explicitly save changed programs in the background bridge. Close the project through MCP, then open its .gpr in Ghidra. An already owned project is not taken over.

Each mailbox accepts one bridge and one MCP client. Use different mailboxes or run bridges at different times. Stopping the GUI bridge leaves GUI-owned programs open.

WorkflowBackgroundGUI extension
Create, open, close projectsSupportedUnsupported through MCP; use the UI or background workflow
Import/select, inspect, analyze, annotate, save, exportSupported within documented limitsSupported within documented limits in the active CodeBrowser
ghidra_go_toUnsupportedNavigates the selected program

Tool reference

85 tools for a defined analysis workflow.

Headless Ghidra supports 84 tools; ghidra_go_to requires CodeBrowser. Both modes publish the same catalogue. Check ghidra_status and MCP tools/list for capabilities and strict input schemas.

The Markdown reference lists every parameter. Read the limits and evidence contract before interpreting partial results.

Context and projects

ghidra_status
Mode, version, active context, capabilities
ghidra_list_languages
Installed language IDs, processor/endian/size, compatible compiler IDs
ghidra_get_project
Active project's runtime ID, name, path
ghidra_get_program
Active program ID, project ID, domain path, language/compiler, source SHA-256, image base, blocks, changed state
ghidra_create_project
Create under an existing allowed parent directory; reject collisions; background only
ghidra_open_project
Open an existing project; refuse switching while one is open; background only
ghidra_close_project
Close; refuse unsaved programs or active analysis; background only
ghidra_list_programs
Recursive project domain paths and names

Programs and persistence

ghidra_import_program
Raw file import with the restrictions above; simple program name, no overwrite
ghidra_select_program
Select an existing program; obtain its returned identity
ghidra_save_program
Explicitly save and verify changed state
ghidra_export_program
Export a Ghidra packed program (.gzf), including analysis, to a new path under the project root; not a flashable BIN

Analysis jobs

ghidra_get_analysis_options
Read current analyzer option names, types, values
ghidra_set_analysis_options
Update existing Boolean options only; reject unknown or non-Boolean options
ghidra_analyze
Start native background analysis; return a job ID
ghidra_job_status
Poll state and any error
ghidra_cancel_analysis
Request cancellation; keep waiting until native work has stopped

Memory

ghidra_read_bytes
Current memory bytes; 1–4,096 bytes
ghidra_map_file_offset
File-backed address matches and provenance; observe alias limitation above
ghidra_set_image_base
Relocate image and read back program details
ghidra_create_memory_block
Add an uninitialized block; 1–67,108,864 bytes; reject overlaps

Code and functions

ghidra_list_functions
Defaults 0/50; limit 1–200
ghidra_get_function
Containing function, signature, parameters, bounded callers/callees
ghidra_create_instructions
Decode 1–65,536 bytes in initialized memory; do not clear existing data/code
ghidra_create_function
Create from decoded instructions using native flow detection
ghidra_rename_function
Rename a defined function and read back
ghidra_disassemble
Read 1–200 existing listing instructions; does not create instructions
ghidra_decompile
Native C output for a defined containing function; 30-second timeout, 1-MiB text cap

Search and annotations

ghidra_get_references
to or from; defaults to/100; limit 1–500
ghidra_search_bytes
Exact 1–256-byte hexadecimal pattern; default 100, maximum 500 results
ghidra_list_symbols
Substring filter; defaults 0/100, maximum 500 per page
ghidra_list_strings
Existing defined string data; defaults 0/100, maximum 500 per page
ghidra_define_data
Primitive scalar/array in undefined storage; u8, s8, u16, s16, u32, s32, u64, s64, f32, f64; count 1–65,536
ghidra_set_label
Set a user-defined symbol and read back
ghidra_set_comment
Set an EOL comment; maximum 8,192 characters; read back
ghidra_go_to
Navigate the active GUI CodeBrowser; unsupported in background mode

Stored analysis inspection

ghidra_get_comments
Read EOL, pre, post, plate and repeatable comments; each capped at 8,192 characters with truncation flags.
ghidra_get_data
Inspect existing containing data and paginated immediate components. Defaults 0/32; maximum 128 components; large values explicitly omitted.
ghidra_get_pcode
Read raw P-code for 1–200 contiguous existing instructions; at most 2,048 operations/8,192 varnodes. Ignores flow overrides; not decompiler SSA.

Function graphs and instruction searches

ghidra_get_function_details
Inspect existing function ranges, convention, parameters, locals and exact native register/stack storage; bounded read-only metadata.
ghidra_get_control_flow
Inspect native basic blocks and typed control-flow edges of an existing function, with explicit bounded truncation.
ghidra_get_call_graph
Traverse existing native call references toward callers, callees or both; bounded depth, nodes, edges and scan budget.
ghidra_find_call_paths
Find bounded simple call paths between existing functions using resolved native call references; no dynamic-target inference.
ghidra_search_constants
Search scalar instruction operand bit patterns in existing instructions, with optional CPU range, bounded scans and cursor continuation.
ghidra_search_instructions
Search existing instructions by exact mnemonic and literal operand substring; bounded CPU-address cursor pagination.
ghidra_search_pcode
Search existing instruction raw P-code by exact native opcode; bounded scan and CPU-address continuation, without decompilation.
ghidra_get_references_range
Inspect native references sourced from or targeting an inclusive CPU range, with exact address/reference-index continuation.

Decompiler data flow, batches and matching

ghidra_get_high_pcode
Read bounded decompiler SSA operations and varnodes with a content snapshot ID and operation pagination; no listing changes.
ghidra_trace_data_flow
Trace a snapshot-validated SSA varnode forward or backward within one function, bounded by depth and nodes; calls and memory boundaries stay explicit.
ghidra_batch_decompile
Decompile up to eight requested functions with per-item outcomes, text caps and native time bounds.
ghidra_batch_references
Read bounded native references for up to 32 addresses with explicit per-address truncation.
ghidra_search_decompiled_code
Search literal case-sensitive text in a bounded window of decompiled functions; return per-function outcomes and an exclusive resume cursor.
ghidra_get_function_fingerprint
Hash a bounded normalized instruction sequence; constants and addresses are abstracted and semantic equivalence is not implied.
ghidra_compare_functions
Compare two functions in the same active program using normalized instruction fingerprints and token similarity; no semantic equivalence claim.
ghidra_find_similar_functions
Rank a bounded, resumable window of functions by normalized instruction-token similarity; candidates require manual verification.
ghidra_emulate_function
Run an isolated emulator from a defined function entry to an explicit stop address with bounded steps/time and explicit register/memory inputs; program bytes are never committed.

Variables and function signatures

ghidra_get_function_variables
List bounded decompiler variables with exact name, symbol ID and serialized-storage selectors; reports current signature and valid calling conventions.
ghidra_rename_variable
Rename exactly one decompiler variable selected by ID, current name and storage; commit and verify the database variable in one transaction.
ghidra_set_variable_type
Set a selected decompiler variable to a bounded typed descriptor of the same storage size; reject stale or ambiguous selectors.
ghidra_set_function_signature
Replace a function signature with typed parameters and return type, guarded by its exact current signature; use native dynamic storage and a known calling convention.

Structures and native data types

ghidra_list_data_types
List a bounded page of program data types, optionally matching a type-path substring.
ghidra_get_data_type
Inspect an exact program type path, including bounded structure/union fields, enum members, or referenced type metadata.
ghidra_create_structure
Create a new fixed-size structure with explicit nonoverlapping offsets; reject existing type names and out-of-range fields.
ghidra_set_structure_field
Rename or replace exactly one existing structure field, guarded by its current name and type path; preserve its size and surrounding layout.
ghidra_create_enum
Create a new 1/2/4/8-byte enum with bounded signed integer values and unique member names; reject name conflicts.
ghidra_create_union
Create a new union from bounded named typed members; reject conflicts and duplicate names.
ghidra_create_typedef
Create a new typedef to a bounded builtin, named type, pointer, or array; reject name conflicts.
ghidra_apply_data_type
Apply a bounded typed descriptor only to undefined mapped storage; preserve existing code/data and firmware bytes.
ghidra_get_structure_field_references
Find bounded, verified high-P-code PTRSUB field-pointer derivations in one function for an exact structure and byte offset; explicitly partial, not a program-wide reference index.

Listing, memory and processor context

ghidra_get_listing
Inspect existing code, data and undefined storage in a bounded mapped range, with a CPU-address continuation.
ghidra_hash_memory
Compute SHA-256 of up to 16 MiB of current initialized program memory, distinct from imported source-file hash.
ghidra_preview_instructions
Decode sequential candidate instructions with native processor context without creating listing instructions; reports delay slots and decode failures.
ghidra_get_processor_context
Inspect a bounded register page and recorded context values at an address; these are analysis values, not live CPU registers.
ghidra_set_processor_context
Set and read back a register context value over a mapped range without defined instructions; transactionally updates analysis metadata.
ghidra_clear_listing
Clear complete code/data units in a bounded range with an expected-kind guard; refuses functions and verifies bytes remain unchanged.

Bookmarks and annotation batches

ghidra_list_bookmarks
List a bounded page of native bookmarks and their categories, comments and addresses.
ghidra_set_bookmark
Create or update a native bookmark guarded by its existing comment and verify readback in a transaction.
ghidra_delete_bookmark
Remove one exact bookmark only when its expected comment matches, and verify deletion.
ghidra_list_comments
Search one stored comment type by literal text over a bounded address range, with scan limits and continuation.
ghidra_batch_set_comments
Apply up to 64 guarded comment edits across all five stored types atomically, with exact readback and rollback on any mismatch.
ghidra_get_function_tags
Read native tags at an exact function entry address.
ghidra_update_function_tags
Add or remove bounded function tags transactionally and verify the final tag set.
ghidra_batch_rename
Rename up to 64 functions or primary labels atomically using exact expected-name guards; verify every result.

Saved-program comparisons

ghidra_compare_program_memory
Compare bounded current memory against a guarded saved program in the same project, returning hashes and changed byte ranges without switching programs.
ghidra_compare_saved_function
Compare an active function with a guarded saved program function without switching programs. Requires matching language/compiler; normalized similarity is not proof of semantic equivalence.

Bounded tools, explicit evidence

Graphs follow existing references. SSA traces stop at memory and call boundaries. Function fingerprints are matching candidates, not proof of equivalent behavior. Isolated emulation needs explicit inputs and a stop instruction; it supplies no live ECU, operating system or peripheral model.

Metadata edits are guarded transactions with readback and explicit saving. No tool accepts arbitrary scripts or shell commands, patches firmware bytes, or flashes an ECU.

Native contracts: graphs and search, SSA, matching and emulation, types and variables, listing and annotations, and headless coverage.

Import and memory layout

Make the processor and addresses explicit.

A raw file does not describe its CPU or memory map. Query ghidra_list_languages, select a compatible language and compiler, and establish the image base from evidence before analysis.

Keep identities separate

Project and program IDs identify runtime objects in the current bridge session. Use them in expected_project_id and expected_program_id; obtain fresh IDs after reopening. These guards do not lock out independent GUI edits.

source_sha256 identifies the imported file. It does not describe later memory edits. Use ghidra_read_bytes or ghidra_hash_memory on relevant current memory before a handoff.

Keep coordinates separate

An address such as ram:00400080 includes a CPU address space. A file offset such as 128 is a byte position in the source. A program path such as /Synthetic belongs to the Ghidra project.

Inspect memory blocks and use ghidra_map_file_offset for provenance. Verify bytes at the resulting address and any relevant aliases; do not assume one coordinate equals another.

Current raw-import and alias limits

Import accepts byte-addressed languages and files from 1 byte to 512 MiB. The native raw loader must initially return exactly one initialized block at zero, matching the input length. The adapter then relocates it to your requested hexadecimal image base.

The current importer rejects tricore:LE:32:tc29x processor-default multiple memory blocks. There is no automatic TC298 loader, flash-bank splitting, or mapped cached/uncached alias creation. Prepare complex layouts separately in Ghidra and verify blocks and bytes. ghidra_create_memory_block creates uninitialized memory only; rebasing does not establish a complex layout.

File-offset lookup requires exactly one stored source-file record. It reports direct file-backed matches and flags multiple results, but transitive byte-mapped aliases may be absent. A cached address can appear without its uncached alias. A single result or ambiguous: false does not establish that no alias exists.

Analysis and persistence

Finish the job. Inspect it. Save explicitly.

  1. Check program identity and layout. Read analyzer options; updates currently accept existing Boolean options only.
  2. Start ghidra_analyze and retain its job ID. Poll ghidra_job_status for completion or failure.
  3. Inspect resulting functions, references, and data. Add labels and comments with the evidence that supports them.
  4. Call ghidra_save_program and verify the changed state. After closing and reopening, get a fresh ID and verify retained analysis.

Cancellation is a request, not a rollback or immediate completion. Continue polling after ghidra_cancel_analysis. The job can finish before the request arrives, or leave partial analysis when cancelled. The current implementation may report cancellation as failed with a cancellation error.

The bridge requests cancellation after five minutes, but native analyzers may take longer to stop. Busy guards remain active until work exits. Independent GUI analysis is detected but is not owned by the MCP cancellation tool. Save decisions remain explicit.

Analysis completion and client disconnection do not save later changes. The initial import is persisted; subsequent metadata and analysis require saving. A running Java process retains unsaved work only for that process's lifetime.

WinOLS interoperability

Carry evidence into your map definitions.

Ghidra can help explain how firmware reads a table. WinOLS MCP can define that table in a project. Connect those steps with verified bytes, addresses, and version identity.

Explore WinOLS MCP

Match the source and selected version

Keep the source SHA-256, Ghidra runtime identity, current bytes, and intended WinOLS Original or modified version together.

Resolve the mapping

Translate file offsets to CPU addresses. Inspect memory blocks, check aliases, and compare the relevant bytes in both applications.

Support the definition

Record evidence for purpose, dimensions, axes, units, and scaling. A candidate array or analyst label alone does not establish map meaning.

Uncertain outcomes

Inspect before retrying.

A timeout or invalid response can arrive after an operation has already changed Ghidra. The client preserves a durable pending marker and stops using the connection. Do not automatically repeat a mutation, clear the mailbox, or reconnect until its outcome is understood.

  1. Stop the affected MCP client. Preserve the last request, response, pending marker, and logs privately.
  2. Inspect Ghidra and determine whether the import, annotation, save, or other operation completed.
  3. Create a stop file in the mailbox to request bridge shutdown after the current command. Confirm the process exited or the GUI bridge stopped, including native analysis.
  4. After reconciling state and releasing both process locks, move only the identified stale exchange files to a private recovery directory. Keep project data intact.
  5. Restart, get fresh identities, and verify affected data before continuing.

Empty lock files may remain after exit; active OS locks determine ownership. See the complete mailbox recovery procedure. Treat names, strings, comments, and decompiled text as analysis data, not instructions to your MCP client.

Keep building

Source, contracts, and examples.

Guide for AI clients

A machine-readable Markdown guide with all tool parameters, configuration examples, a synthetic walkthrough, and recovery steps.

WinOLS MCP

Inspect projects, validate candidate layouts, and create map definitions with explicit project identity.

UDS Evidence API

Store diagnostic evidence with provenance, uncertainty, and machine-readable contracts.