angr.mcp.edit_tools

Batch edit tools: rename, set_type, and set_comments.

Every tool takes a list of items and returns one result per item. Per-item failures are reported as data rather than raised, so one bad item does not discard the work done by its siblings – that is the point of batching. Only whole-call problems (an unknown project, a malformed request) raise.

angr.mcp.edit_tools.rename(project_id, items, dry_run=False, stop_on_error=False, allow_overwrite=False, auto_decompile=True)

Rename functions, decompilation variables, and globals in one call.

Each item needs a “kind” and a “new_name”:

  • kind “function”: identify it with “name” or “address”.

  • kind “variable”: “function” (name or address) plus “name”, the variable’s current name as it appears in the pseudocode. Covers locals, arguments, and stack slots – angr routes them through one path, so the item does not say which; the result reports the resolved storage.

  • kind “global”: “address”, or “name” if the global already has a label.

Renames persist across re-decompilation. Renaming a variable requires the function to have been decompiled; with auto_decompile it is decompiled on demand.

Parameters:
  • project_id (str) – The project ID

  • items (list[dict[str, Any]]) – The rename requests

  • dry_run (bool) – Resolve and validate without changing anything. Not side-effect free: resolving a variable name may decompile the function.

  • stop_on_error (bool) – Stop at the first failure and mark the rest skipped. Edits already applied are NOT rolled back; use dry_run as a pre-flight.

  • allow_overwrite (bool) – Permit a name already bound to something else (default: False)

  • auto_decompile (bool) – Decompile a function on demand when a variable rename needs it

Return type:

dict[str, Any]

Returns:

A per-item result list plus counts of succeeded/unchanged/failed/skipped

angr.mcp.edit_tools.set_type(project_id, items, dry_run=False, stop_on_error=False, redecompile=False, auto_decompile=True)

Set types on decompilation variables, globals, and function prototypes in one call.

Each item needs a “kind” and a “type”:

  • kind “variable”: “function” plus “name”. Retyping an argument rewrites the function’s prototype, which forces that function to be re-decompiled.

  • kind “function”: identify it with “function”, “name”, or “address”; “type” is a full signature, e.g. “int parse(char *buf, int len)”. The name inside the signature is ignored – use rename for that. This discards the function’s cached decompilation and variables; earlier renames and manual types, including ones set by earlier items in the same batch, are restored afterwards.

  • kind “return”: same identifiers, replaces only the return type and keeps the arguments.

  • kind “global”: “address” or “name”, plus “type”.

Types are re-inferred through the cached constraints once per affected function rather than per item. That reflow does NOT rebuild the syntax tree, so a retype that should change how an access renders – a struct field, an array index – needs redecompile=True.

Parameters:
  • project_id (str) – The project ID

  • items (list[dict[str, Any]]) – The type requests

  • dry_run (bool) – Validate and resolve without changing anything

  • stop_on_error (bool) – Stop at the first failure; already-applied edits are NOT rolled back

  • redecompile (bool) – Fully re-decompile each affected function instead of reflowing types

  • auto_decompile (bool) – Decompile a function on demand when an item needs it

Return type:

dict[str, Any]

Returns:

A per-item result list plus counts of succeeded/unchanged/failed/skipped

angr.mcp.edit_tools.set_comments(project_id, items, dry_run=False, stop_on_error=False)

Set or clear comments at addresses in one call.

Each item needs a “kind” and a “comment”; an empty comment clears it.

  • kind “address”: “address” is any address in the binary.

  • kind “function”: identify it with “function”, “name”, or “address”; comments its header.

A comment is written to the knowledge base – where the disassembly and the function header read it – and mirrored next to the matching pseudocode statement. Because pseudocode comments are keyed by instruction address, an address that is not a statement boundary is snapped down to the nearest one; each result reports “snapped_from” and whether the comment actually rendered inline (“rendered_inline”) rather than in the orphaned-comments block.

Parameters:
  • project_id (str) – The project ID

  • items (list[dict[str, Any]]) – The comment requests

  • dry_run (bool) – Resolve addresses without changing anything

  • stop_on_error (bool) – Stop at the first failure; already-applied edits are NOT rolled back

Return type:

dict[str, Any]

Returns:

A per-item result list plus counts of succeeded/unchanged/failed/skipped