rea capabilities
rea capabilities groups every operation with its declared side effects, so you know before a call whether it starts a process, writes files, or edits the session database.
An agent is about to call a tool on a file you gave it. Some rea operations start a Java process, and some write a runtime directory. Three edit the names in the analysis database, and a Hopper operation would open a window. You want that list before the call, not after. rea capabilities prints it, and the same record reaches an agent as the MCP tool binary_session.
When you finish this section, you can read a capability group, name the seven effect flags, and pick the operations that change nothing.
The command and its record
capabilities and providers are registered together, and the help describes capabilities as the list of provider capabilities and side effects. Both print the session status, the same object that binary_session returns over MCP. With no target open it starts open: false:
{
"open": false,
"cleanup_pending": false,
"capabilities": [
{
"provider": {
"id": "native-macos",
"name": "macOS native inspection utilities",
"version": null
},
"shared_limitations": [
"Availability and textual formats depend on the installed macOS/Xcode toolchain."
],
"groups": [
{
"operations": [
"capture_native_ui_scenario",
"observe_native_calls"
],
"effects": [
"launches_process",
"may_show_ui",
"may_access_network",
"may_write_filesystem"
],
"limitations": [],
"available": true,
"reason": null,
"availability_code": null
},
…
],
"analysis_provider_binding": null,
"analysis_provider_candidates": [
{
"provider": {
"id": "ghidra",
"name": "Ghidra",
"version": null
},
"availability": {
"status": "available",
…The record has nine top-level fields in the capture: open, cleanup_pending, capabilities, analysis_provider_binding, analysis_provider_candidates, analysis_run, analysis_activity, provider_operation_health, and server_identity. capabilities holds the 19 operations that need no bound provider, in four provider blocks: native-macos, rea-artifact-graph, rea-dotnet-static, and sqlite. Examples are inspect_artifact, inspect_macho, and the managed .NET readers. analysis_provider_candidates holds the four deep providers with their availability and their own provider blocks. analysis_provider_binding is null because no target is open, and every candidate reports target_support.status: "unknown" with the reason No target is open..
cleanup_pending is false in the capture. It turns true while the session holds a provider process or a file that it could not clean up. It can be true with open: false. Read it before you open the next target, because a closed target does not prove that its resources were released.
One target-free operation is not available on the capture Mac. inspect_sqlite_database has available: false and the code unsupported_version. Its reason says that it needs Node.js 24.15 or a later 24.x release, or Node.js 26 or later. The capture Mac runs Node 22.22.0.
Capability group: a list of operations that share one available flag, one list of effects, and one list of limitations. The effects list names only the flags that are true. The full limitation list of an operation is the block's shared_limitations followed by the group's limitations. When a group is not available, reason and availability_code say why. The session builds the groups from each provider's descriptors, so the field names are the same for every provider. Figure 2.3 shows one.
The seven effects
The effects list of a group names flags from a fixed set of seven. A flag that the list does not name is false for every operation of the group.
| Flag | Meaning | True in the capture for |
|---|---|---|
mutates_artifact | the operation edits the analysis database: names or comments | 3 Ghidra operations, 6 Hopper operations |
launches_process | the operation starts a program, here the Ghidra JVM or a macOS tool | every Ghidra, Hopper, and Kuna operation, 12 target-free ones |
may_show_ui | a window can open | every Hopper operation, 4 IDA operations, 2 target-free ones |
may_access_network | the operation can open a connection | every IDA adapter operation, 2 target-free ones |
may_write_filesystem | the operation writes files, here the runtime root and the project | every Ghidra and Kuna operation, 6 Hopper operations, 6 target-free ones |
changes_permissions | the operation changes file or process permissions | nothing |
requires_root | the operation needs root | nothing |
Two flags need a second look. mutates_artifact sounds like a write to your file, and it is not. A shared limitation of the Ghidra block says: "The imported Program and temporary project are ephemeral and deleted on close. Annotation operations edit session database metadata; original executable bytes are never written." (the capture). The three operations that set it, annotate_native_function, set_address_name, and set_addresses_names, rename symbols in Ghidra's database, and the edit dies with the session.
may_write_filesystem is true for every Ghidra operation, even list_documents. The first call writes the runtime root, the private copy, and the project (section 1.2). Figure 2.4 counts the flags per provider.
Four candidates, one bound
{
"provider": {
"id": "hopper",
"name": "Hopper Disassembler",
"version": null
},
"availability": {
"status": "unavailable",
"code": "executable_missing",
"reason": "Hopper launcher is missing or not executable: /Applications/Hopper Disassembler.app/Contents/MacOS/hopper",
…
{
"provider": {
"id": "ida",
"name": "IDA MCP adapter",
"version": "1"
},
"availability": {
"status": "unavailable",
"code": "not_configured",
"reason": "Set REA_IDA_MCP_CONFIG to an upstream IDA MCP JSON registration; see docs/ida-provider.md.",
…
{
"provider": {
"id": "kuna",
"name": "Kuna",
"version": null
},
"availability": {
"status": "unavailable",
"code": "not_configured",
"reason": "Set REA_KUNA_COMMAND to the absolute path of a caller-supplied kuna executable (verified with 1.833). REA does not download, install or update Kuna.",
…The ghidra candidate is available, and its diagnostics repeat the eight checks of section 2.2 with the same paths. Its block has 22 groups and 30 operations. One group is read_binary_inventory_summary, the operation behind the counts of section 3.4. hopper is unavailable with the code executable_missing, and ida and kuna with not_configured.
Each unavailable candidate still lists its operations, 37 for Hopper, 13 for IDA, and 13 for Kuna. The Hopper and IDA groups have available: true except Hopper's search_bytes, which has available: false and the reason "Masked byte search has not been verified for Hopper.". Every Kuna group has available: false with the code not_configured and the reason of the candidate. Kuna was not run for this manual, because its recorded coverage is on Linux only and the capture host is a Mac.
Availability of the engine and availability of an operation are two different facts. The docs keep the two apart: these commands describe the providers of binary sessions and the auxiliary capabilities. With --provider ghidra or provider_id: "ghidra", only the Ghidra block applies.
Limitations are part of the declaration
Every Ghidra operation carries four shared limitations before its own. The session serves operations only after default auto-analysis completes. The Program and the project are ephemeral. Cancelling a request terminates the database and discards annotations. Addresses are lowercase 0x hexadecimal in the default space (the capture).
Then each group adds its own, and these are the sentences to read before you trust an empty list. list_strings says that an empty search does not prove the text is missing from the file. procedure_callers declares no limitation of its own.
Its answer carries relationship_coverage. The Ghidra diagnostic in that field says that rea returns only resolved call references. Computed or indirect calls that Ghidra did not resolve stay unknown (the capture). The design rule behind all of them: missing coverage means unknown, not absent.
A second vocabulary in tools/list
The record ends with server_identity. Its catalog holds two things: the counts, and three SHA-256 digests of the catalog:
"catalog": {
"counts": {
"cli_commands": 153,
"mcp_tools": 207,
"mcp_prompts": 6
},
"digests": {
"tools_sha256": "af39310c…",
"prompts_sha256": "7152916a…",
"combined_sha256": "96d8f6e6…"
}
},The catalog has no per-tool entries. The side effects of each MCP tool are in the tool annotations that tools/list returns:
{
"name": "xrefs",
"title": "Xrefs",
…
"annotations": {
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": false
},
…In the source, xrefs has mutatesSession: true, because each answer goes into the Evidence ledger. rea derives the annotations from those effects, so readOnlyHint is false. The provider capability of xrefs still does not name mutates_artifact. The two vocabularies answer two questions. The capability says what the engine does to your machine, and the annotations say what the tool does to the MCP session. Read the one that matches your question, and do not mix them.
rea (rea-agents) with the Ghidra provider rea-agents 6.7.0, Ghidra 12.1.4 · 27dc42d · 2026-10-18 · Edition 2026.10