docs(mcp): clarify tool selection and recovery guidance (#9817)

* docs(mcp): clarify tool selection and recovery guidance

* test(mcp): prune wording assertions and preserve scope checks
This commit is contained in:
morluto authored and GitHub committed 2026-11-10 07:49:23 -05:00
1 parent 433fd9486d
commit a4da4e7230
58 files changed
+227 -182

No files matched your search

+32
View File
@@ -93,6 +93,38 @@ include the smallest useful reproduction, impact and coverage limits. Do not
claim autonomous-agent selection from a scripted trace. Check related reports
before proposing another issue, and avoid treating lack of API parity as a bug.
### Write descriptions for selection and a valid first call
Start with the analyst task, selected source and useful result. Put material
effects and the deciding boundary between neighboring tools early. Progressive
discovery previews the first 240 characters, so those characters should identify
the operation without requiring the rest of its reference documentation.
Keep exact call syntax where the advertised schema cannot convey it. The compact
input profile strips most annotation prose and can reduce nested controls to
`{type: "object"}`. Moving selectors into parameter descriptions alone does not
make them available to those clients. For example, retained pseudocode needs
both `source.kind: "retained-evidence"` and `view: {kind: "native", facet:
"pseudocode"}`; a short exact example can be more useful than many paragraphs.
Use the producer's handoff for other supported views rather than maintaining
another supposedly exhaustive list in the shared consumer description.
Keep configuration tutorials and detailed matching algorithms with their owning
parameter contracts, product guides and actionable failures. Retain applicability,
source identity, uncertainty, authority and cleanup facts needed to choose or
safely continue the operation. An unresolved symbol lookup is not a completed
reference search; an exhausted page does not establish absence in unexamined
source. Shorter copy must preserve these distinctions.
For wording changes, use a small set of representative agent tasks at the affected
boundaries. Hold schemas, tool order, fixtures and host configuration fixed when
comparing copy; add repetitions only for failures or ambiguous outcomes. Score
actual arguments, corrective calls and supported final claims separately. A
correct eventual answer can conceal malformed-call loops, while a valid call
can still produce an overstated answer. Report whole-task usage, including
retries and cached input, rather than treating fewer description bytes as proof
of lower token cost.
## Design recovery around the failure
Distinguish a request that violates its input contract from a valid selection
+54 -2
View File
@@ -60,6 +60,48 @@ Evidence. `build_call_path.functions` also accepts retained references to the
complete dossiers. Request `detail: "complete"` only when the record must travel
inline.
The `inspect_analysis_view` description gives common call shapes rather than an
exhaustive second catalog of view families. Follow the producing tool's named
view kind and selector handoff. A summary's `normalized_result.parent_evidence_id`
names the complete parent, not the summary record itself. Preserve that ID and
the source discriminator:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "ev_<parent digest>"
},
"view": {
"kind": "native",
"facet": "pseudocode",
"offset": 0,
"limit": 128
}
}
```
The same source form works for a compatible inventory occurrence page with
`view: {"kind":"inventory","collection":"occurrences","offset":0,"limit":64}`,
a saved network record page with
`view: {"kind":"capture","detail":"preview","offset":0,"limit":20}`, or a
managed method page with
`view: {"kind":"managed-members","collection":"methods","offset":0,"limit":64}`.
`view: {"kind":"summary"}` has no facet. These are examples, not all supported
families; use the producer and its guide for collection-specific fields and
selection. The full input schema exposes accepted variants, while the default
compact profile can omit nested shapes and parameter descriptions. Refreshing
the same compact catalog does not restore those missing shapes; do not invent
selectors from an opaque object declaration.
Text pages use UTF-16 code units; row pages count the selected retained
collection. Source coverage and retained-page coverage remain distinct. A
source's null or unavailable collection stays unknown, while an exhausted
partial inventory does not prove that unexamined branches contain no matches.
Likewise, a returned text page does not establish the whole parent's length
unless the result reports that extent or exhaustion. Paging reuses completed
Evidence and does not establish current live state.
Saved records from the pre-6.6 identity projection that omitted
`relationship_coverage: null` from its digest remain incompatible, even when
the serialized field is present. REA recognizes that exact previous commitment
@@ -576,13 +618,23 @@ batch-workload limit tracked in issue #5930.
### Error recovery and deadline ownership
Initialization instructions and the static JavaScript tool description teach
recovery before a host can discard a tool response. Invalid input calls should be corrected from the connected schema
Initialization instructions retain the deadline distinction before a host can
discard a tool response; detailed recovery stays with the failure that owns it.
Invalid input calls should be corrected from the connected schema
(refresh `tools/list` only if stale), not retried unchanged. REA's returned
`provider_timeout` describes its server/provider deadline; provider-authored
remediation names the applicable controls and preserves partial Evidence and
cleanup uncertainty.
An unresolved symbol lookup is a valid result, not a malformed request. It does
not establish that a reference search completed or that the binary lacks the
feature. Preserve the exact selector and the provider inventory's coverage.
When remediation names an editable setting and its bounds, call
`update_analysis_settings` directly if advertised; inspecting those same bounds
first is optional. Explicit per-call values override runtime defaults, so fix
the selected argument when remediation identifies it. Runtime updates apply to
new work and cannot release retained cleanup resources.
A host timeout without a REA result is different: execution and cleanup remain
unknown. Increasing an advertised `analysis_timeout_ms` cannot fix a shorter
client deadline. Configure the client's tool timeout with execution, cleanup
+1 -1
View File
@@ -273,7 +273,7 @@ export const ADB_TOOL_CONTRACTS = [
name: "resolve_adb_packages",
...toolContractMetadata("resolve_adb_packages"),
description:
"Find installed packages by case-insensitive substring of the package name (e.g. `whatsapp` → `com.whatsapp`), returning each match's base APK device path. The first step of an easy get: resolve, then pull_adb_package the exact name. Read-only.",
"Find installed packages by case-insensitive package-name substring and return each base APK device path. Pass an exact returned name to pull_adb_package to retrieve its base and split APKs. Read-only.",
kind: "adb-provider",
inputSchema: adbInputSchemas.resolve_adb_packages,
outputSchema: evidenceResultOf(adbResultSchemas.resolve_adb_packages),
+1 -1
View File
@@ -106,7 +106,7 @@ export const ANALYSIS_SETTINGS_TOOL_CONTRACTS = [
...toolContractMetadata("update_analysis_settings"),
kind: "application",
description:
"When REA names an adjustable limit, atomically set or reset its runtime default, then retry once work and cleanup have settled. No inspection call is required when the error supplies the bounds. Changes apply only to new work, survive target close/open, and disappear on REA restart. Reset restores launch configuration. Does not edit files, restart providers, raise host limits, or override explicit per-call arguments.",
"Atomically set or reset editable runtime defaults for new work. Changes survive target close/open but disappear on REA restart; reset restores launch configuration. Follow an error's named setting/bounds directly, then retry after work and cleanup settle; no inspection is needed when they are supplied. Does not change active work, edit files, restart providers, raise client limits or override explicit per-call arguments.",
inputSchema: updateAnalysisSettingsInputSchema,
outputSchema: updateAnalysisSettingsResultSchema,
examples: [
+1 -1
View File
@@ -17,7 +17,7 @@ export const ANALYSIS_VIEW_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_analysis_view"),
kind: "application",
description:
'For trace_web_source_location parents, summary returns body-free source/map identities, lookup and original-position metadata with total/next_offset for the first match page. Use source-location collection matches to page every original match_index without embedded text; collection source-text selects an exact match_index and UTF-16 offset/limit, returning content identity and only that text page. Both accept max_bytes (default 1048576); increase it or reduce limit after a byte refusal. Complete map text and diagnostics remain in the parent, even after local artifacts are removed. Use native-procedure-references to page retained procedure reference or unresolved-call rows. Endpoint kind selected-procedure refers to the summary procedure, null preserves the original null, and shared carries an index into items.endpoints, where each other procedure is stored once per page. Exact source_address and target_address filters apply to reference rows. For inspect_api_contract parents, graphql-contract pages retained SDL types/fields, operation definitions, field references, fragment-spreads or diagnostics with exact filters and selected columns. Use javascript-routes collections to query route patterns, source-linked occurrences, source status, unknowns or summary counts from retained JavaScript application or web-bundle Evidence. Use web-bundle collections endpoints or inferences to page endpoint observations and inferences from retained analyze_web_bundle Evidence; summary returns target URL, origin, and counts. For retained trace_feature Evidence, kind native-feature-trace pages matches, references or unknowns; matches filter exact address, references filter exact source_address and target_address, source_index identifies each original row, and list_unknowns pages durable question heads. Inspect selected views of supported completed Evidence without repeating analysis. Use recorded-array with an exact raw_result object-member path to page a provider-recorded array when the producer supplies that path; rows keep their raw meaning and the parent retains coverage. For procedure_pseudo_code Evidence, summary reports text availability and the original selection; kind native with facet pseudocode pages the original UTF-16 text. Other native facets require analyze_function. Choose a view compatible with the parent operation described below. Command summary views preserve ordered GDB records or opaque objdump stdout/stderr once, source parameters, completion facts and parent identity. They do not establish current target state. Historical capture summaries return identity and counts without bodies or archive inventories. Capture views page retained records: view {kind: "capture", detail: "preview" | "complete", offset: 0, limit: 20}; preview selects recorded headline fields and binary descriptors, complete returns exact records with all sidecars. Offsets follow the selected parent record order, preserving original producer ordinals. Paging never reopens the source or reruns the decoder. Native export tables use kind native-exports, collection exports/issues, exact names or original indices, selected fields and matching-row pagination; parent Evidence plus source_index identifies each row. Source coverage stays separate from page coverage. BEAM views use kind beam, collections atoms/exports/imports/lambdas/chunks, exact names/indices/fields and matching-row pages; import modules intersects function names. source_index identifies original parent-and-collection rows, preserving every arity and raw atom index. beam.counts preserves null missing tables versus decoded empty tables; runtime absence remains unknown. PYC views use kind python-pyc, collection code_objects, names/indices/fields and paging; source_index scopes every same-name alternative to the parent, nested_code keeps code-constant references, and pyc.coverage preserves source coverage. Go metadata uses kind go, collection dependencies/settings, exact paths/keys or indices, fields and pagination. Row index refers to the original collection; empty selections return no rows, and dependency coverage remains unknown. Rust metadata uses kind rust, collection packages/edges, exact names/versions or original indices, selected fields, edge from_indices/to_indices and matching-row pagination. Embedded-record coverage is separate from unknown runtime dependencies. For inspect_pcap_capture parents, kind pcap pages endpoints, dns-queries, tls-sni, protocols, http-uris or unattributed-addresses. Select an exact query for dns-addresses, or a tshark/capinfos stream for UTF-16 diagnostics text. Page totals count retained facts; source coverage remains explicit. Qlog summaries keep profile/scope and counts; kind qlog pages traces, streams, loss-declarations, incomplete-records, contributions, ranges or final-sizes. Except traces, select trace_index; stream-specific facets also require exact stream_id and direction. Facts retain all-recorded-events-before-selection scope, aLine truncated
'Read summaries, selected facts, or pages from completed Evidence without rerunning analysis. Use the producing tool’s retained-view handoff for compatible selectors; the examples here are not exhaustive. Copy normalized_result.parent_evidence_id from a summary into source: {kind: "retained-evidence", evidence_id: "<parent_evidence_id>"}. Other sources are {kind: "inline", evidence: <complete Evidence>} or {kind: "evidence-file", path: "<absolute JSON path>", evidence_id?: "<record ID>"}; select an ID for a multi-record bundle. For native pseudocode use {source: {kind: "retained-evidence", evidence_id: "<parent_evidence_id>"}, view: {kind: "native", facet: "pseudocode", offset: 0, limit: 128}}; procedure_pseudo_code parents support this text facet, while other native function facets require analyze_function. Common views: {kind: "summary"} has no facet; {kind: "inventory", collection: "occurrences", logical_paths: ["package.json"], offset: 0, limit: 64} selects artifact paths; {kind: "capture", detail: "preview", offset: 0, limit: 20} pages saved network records; {kind: "managed-members", collection: "methods", offset: 0, limit: 64} pages managed members. Use the producer’s named kind for other families; compact schemas may omit nested shapes, so do not invent selectors. Text offsets/limits use UTF-16 code units; row pages count the selected retained collection. Preserve parent identity, null/unavailable values, source coverage, limitations and unknowns; exhausting pages does not prove complete discovery, runtime use or absence. Smaller pages can resolve delivery limits without repeating analysis; complete parent Evidence remains available for export.',
inputSchema: inspectAnalysisViewInputSchema,
outputSchema: evidenceResultOf(analysisViewResultSchema),
examples: [
@@ -26,7 +26,7 @@ export const ANDROID_TOOL_CONTRACTS = [
name: "inspect_android_jni_bindings",
...toolContractMetadata("inspect_android_jni_bindings"),
description:
'Link raw APK DEX ACC_NATIVE declarations to observed Java_* function exports and relocated static JNINativeMethod table candidates, per ABI and exact library occurrence. Optional class_name/method_names/descriptors narrow bindings; abis/library_paths narrow parsed libraries. RegisterNatives class attribution always uses the global native declaration inventory before these filters. Matched records establish observed candidate presence; partial coverage does not establish uniqueness, and empty partial scans remain unknown. Includes APK/library digests, stable relation IDs and table slot/relocation provenance. No target execution, library load or runtime registration claim. Omitted detail defaults to summary: a bounded relation preview retaining complete Evidence. Optional view:{kind:"android-jni",collection:"bindings"|"declarations"|"candidates"|"libraries",offset:0,limit:64,fields:[...]} selects exact columns/pages; [] matches none. Read later pages with inspect_analysis_view and the returned parent_evidence_id without reopening files or rerunning analysis. Explicit complete detail returns full retained facts inline. Requires caller-supplied JADX MCP JAR and JDK.',
"Link an APK's DEX native declarations to Java_* exports and static JNINativeMethod candidates by ABI and exact library occurrence, without executing it or loading libraries. Returns digests, relation IDs, slot/relocation provenance and explicit partial/unknown coverage; a candidate match does not prove uniqueness or runtime registration. Declaration filters and ABI/library filters narrow results; RegisterNatives attribution uses the full declaration inventory first. Default summary retains complete Evidence. Optional view kind android-jni selects bindings/declarations/candidates/libraries, fields and pages; use inspect_analysis_view with parent_evidence_id for later pages. Empty selections match none. Requires caller-supplied JADX MCP JAR and JDK.",
kind: "android-provider",
inputSchema: androidJniInspectionInputSchema,
outputSchema: evidenceResultOf(
@@ -53,7 +53,7 @@ export const ANDROID_TOOL_CONTRACTS = [
name: "inspect_android_package",
...toolContractMetadata("inspect_android_package"),
description:
'Inspect a local APK\'s package, SDK and permission declarations, decoded manifest and class/resource counts, with a bounded static component projection. Omitted or complete detail preserves the complete result. Select detail: "summary" for all declarations, engine identity and counts without decoded manifest text or duplicate raw calls; retains the complete source and returns a distinct linked inspect_analysis_view summary. With summary detail, optionally select view kind android: facet components supports offset/limit, fields and exact kinds/names/actions/exported filters; source_index preserves the retained parent array ordinal and declaration_coverage preserves historical unknowns. Facet component-summary counts selected kinds and exported declarations separately from defaults. Facet manifest pages exact UTF-16 text. Reuse the same views with inspect_analysis_view and normalized_result.parent_evidence_id; complete detail rejects view selection. Does not execute the APK or verify signatures. Requires a caller-supplied JADX MCP JAR and JDK; uses one worker in an isolated temporary workspace.',
"Inspect APK package/SDK/permission declarations, decoded manifest, static components and class/resource counts without executing it or verifying signatures. Requires caller-supplied JADX MCP JAR and JDK. Default complete returns full Evidence; detail summary retains it and omits manifest text/raw duplicates. With summary, view kind android selects facet components (exact filters, fields, paging), component-summary or manifest (UTF-16 text pages); complete detail rejects view. Use normalized_result.parent_evidence_id with inspect_analysis_view for later views. Component source_index identifies the original declaration, and declaration_coverage preserves unknowns.",
kind: "android-provider",
inputSchema: androidPackageInspectionInputSchema,
outputSchema: evidenceResultOf(
@@ -114,7 +114,7 @@ export const ANDROID_TOOL_CONTRACTS = [
name: "inspect_android_class",
...toolContractMetadata("inspect_android_class"),
description:
"Inspect one exact Android class's parsed methods, fields and inner classes, including synthetic members. Returns display signatures, exact DEX prototypes and encoded static final field values without generating source. A prototype is not a complete raw method ID; overload indices remain consistent within the artifact and engine session. Optional mapping_path annotates observed raw DEX names with R8/ProGuard mapped names in a separate mapping block, verified by DEX type or prototype; observed names stay primary. Select detail summary to retain complete Evidence and return these normalized symbols without duplicate raw provider calls; omitted or complete detail preserves the complete inline response.",
"Inspect one exact Android class's methods, fields, inner classes, DEX prototypes and encoded static final values without generating source. Select an overload_index from these results for inspect_android_method; indices are artifact/engine-session scoped and prototypes are not complete raw method IDs. Optional mapping_path adds verified R8/ProGuard names separately; observed names remain primary. detail summary retains complete Evidence and returns normalized symbols without duplicate raw calls; complete remains the default.",
kind: "android-provider",
inputSchema: androidSymbolInspectionInputSchemas.inspect_android_class,
outputSchema: evidenceResultOf(
@@ -143,7 +143,7 @@ export const ANDROID_TOOL_CONTRACTS = [
name: "inspect_android_method",
...toolContractMetadata("inspect_android_method"),
description:
"Decompile one Android method with smali fallback. Requires explicit overload_index when multiple methods share a name. Reports its DEX prototype, representation, fallback markers and source truncation; display signatures may be aliases. Optional mapping_path adds R8/ProGuard mapped names for the class and selected method without replacing observed names. Prefer detail summary to retain complete Evidence and return the selected body and annotations without repeating raw class metadata. Omitted or complete detail preserves complete inline Evidence.",
"Decompile one Android method, with explicit overload_index when names collide and smali fallback when needed. Reports DEX prototype, representation, fallback markers and source truncation; display signatures may be aliases. Optional mapping_path annotates R8/ProGuard names without replacing observed names. detail summary retains complete Evidence and returns the selected body without duplicate class metadata; complete remains the default. Use inspect_android_class to choose the overload.",
kind: "android-provider",
inputSchema: androidSymbolInspectionInputSchemas.inspect_android_method,
outputSchema: evidenceResultOf(
+1 -1
View File
@@ -18,7 +18,7 @@ export const API_CONTRACT_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_api_contract"),
kind: "application",
description:
"Inspect local OpenAPI JSON (default) or GraphQL SDL offline; no session, network, endpoint requests or target execution. OpenAPI 3.0/3.1/3.2 inventories inline path operations with exact method/path keys, source JSON Pointers and source-scoped IDs; references stay unresolved and malformed siblings explicit. GraphQL format graphql-sdl inventories type/field declarations and optional operations_path field bindings, operation/fragment owners and explicit spread edges without expanding fragments. It preserves aliases, wrappers, source digests/UTF-16 ranges and unknown/model-only bindings; field resolution is not full operation validation. Introspection, contract diff and runtime behavior are outside scope. Default summary retains complete Evidence; view selects facts immediately, overriding detail. Retained inspect_analysis_view supports kind api-contract or graphql-contract with exact batch filters, fields and paging. Coverage describes examined declarations, independently of page exhaustion. Each file and expanded facts have 32 MiB allowances plus heap admission. GraphQL additionally bounds lexical tokens (262144), comments (65536) and subsequent AST traversal depth (128). Reply paging does not increase parser allowances.",
'Inspect declared APIs in local OpenAPI JSON or GraphQL SDL without a session, network requests or target execution. OpenAPI 3.0/3.1/3.2 returns inline method/path operations with source pointers; references remain unresolved. format:"graphql-sdl" returns types/fields and optional operations_path bindings, preserving aliases, fragment/spread owners and unknowns without expanding fragments or claiming full operation validation. Default summary retains Evidence; view overrides detail. For HTTP rows use view {kind:"api-contract",collection:"operations",methods:["GET"],limit:20}; GraphQL uses view {kind:"graphql-contract",collection:"references",limit:20}. inspect_analysis_view pages the same retained facts. Source declaration coverage stays separate from page exhaustion; paging does not increase parser allowances. Introspection, runtime behavior and contract comparison are outside scope.',
inputSchema: inspectApiContractInputSchema,
outputSchema: evidenceResultOf(
z.union([
@@ -16,7 +16,7 @@ export const INSPECT_APK_SIGNATURE_CONTRACT = {
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Inspect declared v1/v2/v3/v3.1 APK signers, certificate fingerprints, algorithm IDs, content digests, SDK ranges, rotation lineage and source stamp without executing Android code. SHA-256 identifies the exact local file. Summary retains complete Evidence; an optional view selects signers/digests/lineage using stable IDs, scheme or signer-ID batches, fields and paging. Read retained pages with inspect_analysis_view kind apk-signature after the source is removed. IDs include artifact digest, scheme and source ordinal; certificates retain raw-DER SHA-256. Content-digest equality is not cryptographic signature verification: modified declarations can match modified bytes. Authenticity, signatures, lineage trust and v1 entry coverage remain unverified. Malformed structures and resource refusals are explicit; no device, network or SDK is used by REA.",
"Inspect declared APK v1/v2/v3/v3.1 signers, certificate fingerprints, digests, SDK ranges, rotation lineage and source stamp without executing Android code. Returns exact file SHA-256; identities include scheme/source ordinal and certificates retain DER digests. Default summary retains complete Evidence; optional view selects signers/digests/lineage by IDs/schemes/fields and pages. Reuse inspect_analysis_view kind apk-signature after removing the source. Matching content digests do not verify signatures or authenticity; lineage trust and v1 entry coverage remain unverified. No device, network or SDK; malformed structures and resource refusals are explicit.",
inputSchema: inspectApkSignatureInputSchema,
outputSchema: evidenceResultOf(
z.union([
@@ -22,7 +22,7 @@ export const APKTOOL_TOOL_CONTRACTS = [
name: "decode_android_resources",
...toolContractMetadata("decode_android_resources"),
description:
"Decode one local APK's resources with `apktool d --no-src` in a provider-owned workspace that is removed after projection: the readable AndroidManifest.xml, apktool.yml version and SDK facts, selected string resources, selectable locales, and decoded file count. Strings default to the first 2000 valid entries per table; string_offset/string_limit retrieve later pages, with table.page.next_offset and full source counts. Verify target.sha256 across calls. Per-call max_total_strings, max_string_table_bytes and max_total_string_table_bytes adjust output/read budgets without a REA restart. Smali is skipped because Java-source recovery belongs to JADX. decode_timeout_ms is the decode wall clock in milliseconds (default 600000, range 1..2147483647); it does not raise output capture or version-probe limits.",
"Decode APK resources with apktool d --no-src: readable manifest, version/SDK facts, string resources/locales and decoded file count. Uses a temporary workspace removed after projection; smali/source recovery belongs to JADX. Strings default to 2000 valid entries per table; use string_offset/string_limit and table.page.next_offset for later pages, checking target.sha256 across calls. Per-call string budgets can be raised without restart. decode_timeout_ms controls decoding (default 600000 ms), independently of output capture and version probes.",
kind: "apktool-provider",
inputSchema: apktoolInputSchemas.decode_android_resources,
outputSchema: evidenceResultOf(
+10 -10
View File
@@ -100,7 +100,7 @@ export const APPLICATION_TOOL_CONTRACTS = [
name: "search_guidance",
...toolContractMetadata("search_guidance"),
description:
"Search only the installed REA workflow guidance. Every non-generic query word must occur in a section; sections holding every word in their own text rank before parents whose words are spread across subsections. Returns ranked sections, bounded pages, and locators for read_guidance_section. No target or provider is accessed.",
"Find installed REA workflow guidance by query words. Returns ranked sections, pages and locators for read_guidance_section; every non-generic word must match, with direct section matches ranked before matches spread across children. Reads documentation only, without accessing a target or provider.",
kind: "application",
inputSchema: searchGuidanceInputSchema,
outputSchema: searchGuidanceOutputSchema,
@@ -193,7 +193,7 @@ export const APPLICATION_TOOL_CONTRACTS = [
name: "compare_application_versions",
...toolContractMetadata("compare_application_versions"),
description:
"Compare two authenticated JavaScript Application Graph versions supplied as inline Evidence or exact same-session retained references. Uses unique-only exact digest, module source digest, source-map identity, structural fingerprint, and non-module semantic-key tiers. Reports added, removed, changed, ambiguous, and unknown entities plus the complete matching changed_from graph without fuzzy or module-ordinal pairing.",
"Compare two authenticated JavaScript Application Graph versions, supplied inline or by exact retained reference. Returns added, removed, changed, ambiguous and unknown entities with the full changed_from graph. Pairing uses unique exact digest, source-map, structural or semantic-key tiers; no fuzzy or module-ordinal pairing.",
kind: "application",
inputSchema: compareApplicationVersionsRequestSchema,
outputSchema: comparisonOutputSchema,
@@ -220,7 +220,7 @@ export const APPLICATION_TOOL_CONTRACTS = [
name: "compare_static_and_observed_endpoints",
...toolContractMetadata("compare_static_and_observed_endpoints"),
description:
"Compare authenticated analyze_javascript_application and HAR Evidence, inline or by exact retained reference. No files, targets or URLs are acquired. Default summary retains the full comparison; optional view returns an endpoint-comparison page in this call (takes precedence over detail). inspect_analysis_view kind endpoint-comparison pages static-endpoints, observed-groups or matches with filters and fields. detail complete returns all facts. Pairings identify exact or inferred template-compatible basis; candidate/partial targets and ambiguous methods remain unknown. Root-relative targets need a caller-declared origin. Not-observed requires an exercised origin, every parent record retained and no excluded records; it never means hidden, unused or inaccessible. Copies no query strings, fragments, headers or bodies. Sensitive-declaration parents are refused; the shared 96 MiB representation budget includes source admission and derived state.",
"Compare static JavaScript endpoints with requests recorded in HAR Evidence, supplied inline or retained; acquires no files, targets or URLs. Returns exact or inferred template pairings and explicit unknowns; root-relative targets need a declared origin. Not-observed requires an exercised origin, all parent records retained and none excluded; it never means hidden, unused or inaccessible. Default summary retains the full comparison for inspect_analysis_view kind endpoint-comparison (static-endpoints, observed-groups, matches); a selected view overrides detail, and detail complete returns all facts. Copies no query strings, fragments, headers or bodies. Sensitive-declaration parents are refused; the 96 MiB representation budget covers source admission and derived state.",
kind: "application",
inputSchema: compareStaticObservedEndpointsRequestSchema,
outputSchema: evidenceResultOf(
@@ -241,7 +241,7 @@ export const APPLICATION_TOOL_CONTRACTS = [
name: "compare_source_to_bundle",
...toolContractMetadata("compare_source_to_bundle"),
description:
"Compare a cryptographically committed HistoricalSourceGraph supplied inline or as reference {kind:file,path:absolute-local-JSON-path} with authenticated JavaScript Application Graph Evidence supplied inline or by exact same-session retained reference. Omitted view preserves the full report. Optional view {kind:summary} or {kind:source-to-bundle,collection:mappings|candidates,source_paths?,mapping_ids?,statuses?,fields?,offset?,limit?} retains the full parent and returns selected facts. Query it again using inspect_analysis_view. Empty filters select none; identity fields always remain. Candidate signals are opt-in; classifications use the full comparison. Page coverage never upgrades source coverage. Uses explicit exact-digest, source-map path, current-path, suffix, and basename signals with stable weights. Classifies unchanged, modified, removed, split, merged, duplicated, and unknown; incomplete coverage and ambiguous weak signals never become absence or forced matches.",
'Map committed historical source to an authenticated JavaScript Application Graph. Supply HistoricalSourceGraph inline or as {kind:"file",path:"/absolute/source.json"}, and graph Evidence inline or retained. Uses explicit digest, source-map and path signals to classify unchanged, modified, removed, split, merged, duplicated or unknown; incomplete coverage and ambiguous weak matches never establish absence or force pairing. Candidate signals are opt-in. Omitted view returns the full report; view {kind:"summary"} or {kind:"source-to-bundle",collection:"mappings"} retains it for later inspect_analysis_view pages. Filters intersect, empty filters select none, and page coverage never upgrades source coverage.',
kind: "application",
inputSchema: compareSourceToBundleRequestSchema,
outputSchema: sourceToBundleOutputSchema,
@@ -257,7 +257,7 @@ export const APPLICATION_TOOL_CONTRACTS = [
name: "compare_javascript_export_shapes",
...toolContractMetadata("compare_javascript_export_shapes"),
description:
"Compare static return shapes for one exact module/export selector on each authenticated JavaScript Application Graph supplied as inline Evidence or exact same-session retained references. Variants pair only by reciprocal unique literal discriminants. Each retained variant lists observed return-property names even when values stay unknown. Presence (present, absent, or unknown-coverage) is separate from value resolution: a name present on only one paired shape is added or removed when parent-property coverage is complete on both sides, including when the static value is unresolved. Dynamic values, incomplete parent coverage, and unpaired variants remain unknown. Reports JSON Pointer changes without executing JavaScript; runtime behavior requires a separate agent-run probe.",
"Compare static return-property shapes for one exact module/export on each authenticated JavaScript Application Graph, inline or retained. Variants pair only by reciprocal unique literal discriminants. Returns JSON Pointer changes while keeping property presence separate from value resolution: complete property coverage can establish an addition/removal even when values are unresolved. Dynamic values, incomplete coverage and unpaired variants stay unknown. Does not execute JavaScript; runtime behavior needs a separate probe.",
kind: "application",
inputSchema: compareJavaScriptExportShapesRequestSchema,
outputSchema: exportShapeComparisonOutputSchema,
@@ -285,7 +285,7 @@ export const APPLICATION_TOOL_CONTRACTS = [
name: "build_reconstruction_obligation_ledger",
...toolContractMetadata("build_reconstruction_obligation_ledger"),
description:
"Generate the complete deterministic ReconstructionObligationLedger from an authenticated Evidence bundle, reviewed obligations, and an explicit reconstruction manifest. Static candidates remain candidates; duplicate ownership, missing original or reconstruction cases, missing parser/type, weak verifier authority, unenumerated claims, contradictions, dependencies, and residual unknowns fail closed. The inline result carries the full-ledger closure digest and typed per-obligation diagnostics.",
"Build a deterministic reconstruction-obligation ledger from an authenticated Evidence bundle, reviewed obligations and an explicit reconstruction manifest. Returns the complete ledger, closure digest and typed diagnostics. Duplicate owners, missing cases or parser/type, weak verifier authority, unenumerated claims, contradictions, dependencies and residual unknowns fail closed; static candidates remain candidates.",
kind: "application",
inputSchema: reconstructionObligationLedgerInputSchema,
outputSchema: reconstructionObligationLedgerOutputSchema,
@@ -315,7 +315,7 @@ export const APPLICATION_TOOL_CONTRACTS = [
name: "evaluate_reconstruction_coverage",
...toolContractMetadata("evaluate_reconstruction_coverage"),
description:
"Evaluate inline evidence-backed reconstruction coverage against one named boundary. Missing ownership or inventory is partial; stale, weak, truncated, skipped, unresolved, or conflicting tied verifier proof is unknown; contradictions, failed proof, missing owners, and authority routing fail closed.",
"Check evidence-backed reconstruction coverage for one named boundary. Missing ownership or inventory is partial; stale, weak, truncated, skipped, unresolved or conflicting verifier proof is unknown. Contradictions, failed proof, missing owners and authority-routing failures fail closed.",
kind: "application",
inputSchema: reconstructionCoverageEvaluationInputSchema,
outputSchema: reconstructionClosureResultSchema,
@@ -366,7 +366,7 @@ export const APPLICATION_TOOL_CONTRACTS = [
name: "project_android_application_graph",
...toolContractMetadata("project_android_application_graph"),
description:
"Project authenticated APK inventory_artifact Evidence into an execution-free Android application inventory. Reports exact component paths and hashes, runtime-family hints, and path-based bridge hypotheses without decoding DEX, executing the APK, or claiming observed runtime calls.",
"Build a static Android application inventory from the authenticated nested inventory Evidence returned by inspect_artifact for an APK. Returns component paths/hashes, runtime-family hints and path-based bridge hypotheses. Does not decode DEX, execute the APK or establish runtime calls.",
kind: "application",
inputSchema: applicationInventoryProjectionInputSchema,
outputSchema: evidenceResultOf(androidApplicationProjectionResultSchema),
@@ -382,7 +382,7 @@ export const APPLICATION_TOOL_CONTRACTS = [
name: "project_apple_application_graph",
...toolContractMetadata("project_apple_application_graph"),
description:
"Project authenticated IPA, macOS .app directory, ZIP, or DMG inventory Evidence into an execution-free Apple application inventory. Reports application roots, nested bundles with path-convention roles (app extensions, XPC services, login items, privileged helpers, system extensions, frameworks), launchd plists, exact component paths and hashes, runtime-family hints, and path-based bridge hypotheses without parsing plist/CMS semantics or claiming observed runtime calls.",
"Build a static Apple application inventory from the authenticated nested inventory Evidence returned by inspect_artifact for an IPA, .app directory, ZIP or DMG. Returns application roots, nested-bundle roles, launchd plists, component paths/hashes, runtime hints and bridge hypotheses. Roles follow path conventions; plist/CMS semantics and runtime calls are not established.",
kind: "application",
inputSchema: applicationInventoryProjectionInputSchema,
outputSchema: evidenceResultOf(appleApplicationProjectionResultSchema),
@@ -402,7 +402,7 @@ export const APPLICATION_TOOL_CONTRACTS = [
name: "project_harmony_application_graph",
...toolContractMetadata("project_harmony_application_graph"),
description:
"Project authenticated HarmonyOS HAP, HSP, or App Pack inventory Evidence into an execution-free application inventory. Reports packaging-model hints (Stage module.json versus FA config.json), exact component paths and hashes (manifests, Ark bytecode, resources, native libraries, JavaScript, signing), authenticated files outside those categories in unclassified_components, App Pack child packages, runtime-family hints, and path-based N-API bridge hypotheses without decoding Ark bytecode, parsing manifest semantics, or claiming observed runtime calls.",
"Build a static HarmonyOS inventory from the authenticated nested inventory Evidence returned by inspect_artifact for a HAP, HSP or App Pack. Returns packaging hints, component paths/hashes, child packages, runtime hints, unclassified components and path-based N-API bridge hypotheses. Does not decode Ark bytecode, parse manifest semantics or establish runtime calls.",
kind: "application",
inputSchema: applicationInventoryProjectionInputSchema,
outputSchema: evidenceResultOf(harmonyApplicationProjectionResultSchema),
+2 -2
View File
@@ -109,13 +109,13 @@ const artifact = <
export const ARTIFACT_TOOL_CONTRACTS = [
artifact(
"inspect_artifact",
"Inspect an active archive, application package, firmware container (including FIT and legacy uImage), Node.js SEA carrier, or Deno compile executable in one call. By default returns the complete content-addressed artifact graph once, as the typed nested inventory Evidence, with root and integrity observations, integrity contradictions, hypotheses, unexplored branches, limitations, and next probes inline. Bun standalone inventory describes stored module, sourcemap and opaque bytecode regions. Deno compile inventory reports the embedded virtual filesystem, remote modules, and recorded options. Environment-file values and certificate bytes are retained in local Evidence with their counts and byte lengths. The npm snapshot length is reported and not decoded, and the executable is not run. For PCK, Bun and large containers prefer detail summary: it retains the complete inspection and returns its derived summary view; read exact paths, batch occurrence/content IDs and selected fields with inspect_analysis_view using parent_evidence_id. This changes delivery, not inventory coverage. Classic iNES includes header facts, PRG/CHR file-region hashes and byte-exact reconstruction evidence; mapper execution and CPU bank mappings remain unobserved. Read-only DMG mounting is used automatically on supported macOS hosts. Integrity mismatches fail by default; record-and-continue keeps mismatches explicitly untrusted. It does not extract files; use extract_artifact to materialize regular contents of supported formats. DMG extraction is unavailable; use a caller-managed read-only mount on macOS to access its files.",
"Inventory the active archive, app package, firmware container or supported packaged executable without running it. Returns nested content-addressed inventory Evidence with integrity observations, unexplored branches and next probes. Default complete returns the full graph; detail summary retains it for inspect_analysis_view kind inventory using parent_evidence_id, exact paths/IDs, fields and paging. Summary changes delivery, not inventory coverage. Bun/Node SEA/Deno carriers expose stored modules/assets and recorded metadata; opaque bytecode and npm snapshots are not decoded. Local Evidence can include environment-file values and certificate bytes. Classic iNES adds file-region/reconstruction facts, not mapper execution. Integrity mismatches fail unless record-and-continue explicitly retains untrusted contradictions. Supported macOS DMGs are mounted read-only. Use extract_artifact to materialize regular contents; DMGs instead need a caller-managed read-only mount.",
artifactInspectionInputSchema,
{ evidenceParameters: "preserve-detail" },
),
artifact(
"extract_artifact",
"Extract all or caller-selected regular files (including Node.js SEA scripts and assets and Deno compile virtual files) exposed by a supported active archive reader. Optionally select exact inventory occurrence_ids and an absent absolute output_root on the REA host; otherwise use a fresh temporary directory. The result records selected IDs and the actual output location; successful files persist after the call. Nested archive files are copied as files; inspect and extract them separately to unpack their contents. DMG extraction is unavailable; use a caller-managed read-only mount on macOS. Rejects traversal and symlink escapes, never overwrites, and verifies cleanup. Inventory integrity checks still cover the full input: mismatches fail by default; record-and-continue keeps extracted contradictions explicitly untrusted.",
"Write all or selected regular files from the active supported archive to an absent absolute output_root, or a fresh temporary directory if omitted. Use exact inventory occurrence_ids to select files. Returns IDs and actual output paths; successful files persist. Nested archives are copied, not recursively unpacked. Never overwrites; rejects traversal/symlink escapes and verifies cleanup. Full-input integrity checks still apply: mismatches fail unless record-and-continue retains explicitly untrusted contradictions. DMG extraction is unavailable; use a caller-managed read-only mount on macOS.",
artifactExtractionInputSchema,
),
artifact(
@@ -30,7 +30,7 @@ export const BROWSER_SCENARIO_TOOL_CONTRACTS = [
name: "capture_browser_scenario",
...toolContractMetadata("capture_browser_scenario"),
description:
"Run a controlled browser scenario when passive observation cannot exercise the application. Launch the selected executable or connect to a loopback CDP target, provide a start URL and actions, and select storage or artifacts when needed. A request action sends one HTTP request to the start origin through the page's own fetch, with header values from secrets, page cookies or local storage; write methods change application state. Environment, empty storage, a URL-only final capture, and measured event-retention budgets are defaults. capture.network selects request_body, response_body, and header_values independently; capture.limits lets callers raise or lower the event count, retained-allocation estimates, network transaction count, and network content budgets. Selected content is returned inline with transaction and event references, byte digests, and explicit unavailable states. Budget omissions identify affected event kinds and network transactions. Credentials and declared secrets are redacted. Agents can run their own local fixture servers to control application responses. Actions run until completion or cancellation unless timeout_ms is set. Default detail complete returns the capture inline. Detail summary retains complete Evidence and returns step outcomes, the final or first unsuccessful step’s accessibility tree, and event/network counts. Read exact steps with selected artifacts, UTF-16 text pages, transactions with opt-in content, or events filtered by step, kind and transaction, through inspect_analysis_view kind browser-scenario.",
'Drive a browser scenario when passive observation cannot exercise the app. Launch the selected executable or connect to a loopback CDP target; actions can change application state and make network requests. Supply browser, start_url and actions, e.g. {browser:{mode:"launch",executable_path:"/opt/chromium/chrome"},start_url:{url:"https://app.example.test/"},actions:[{step_id:"settle",action:"wait_for_timeout",duration_ms:250}]}. Empty storage and a URL-only final capture are defaults. Request actions use page fetch on the start origin; capture.network independently opts into request_body, response_body and header_values. Credentials and declared secrets are redacted. capture.limits controls retained event/content budgets; omissions identify affected events/transactions. Actions wait for completion or cancellation; per-action timeout_ms bounds a step. Default complete delivery returns Evidence inline. detail summary retains it and returns step outcomes, final/first-unsuccessful accessibility, and counts; inspect_analysis_view kind browser-scenario pages steps, events, transactions and UTF-16 text. Use inspect_web_page for observation without actions.',
kind: "browser-provider",
inputSchema: browserScenarioInputSchema.extend({
detail: analysisDetailSchema,
+3 -3
View File
@@ -171,7 +171,7 @@ export const BROWSER_TOOL_CONTRACTS = [
name: "list_browser_targets",
...toolContractMetadata("list_browser_targets"),
description:
"List page targets exposed by the selected loopback Chrome DevTools Protocol endpoint. Optionally filter by exact origin. URLs preserve query values and fragments; only URL userinfo credentials are removed. HTTP discovery and browser-socket discovery use optional discovery_timeout_ms (default 10000 ms, range 1..2147483647, applied on the next call) without running a post-discovery target command, so this operation accepts no command_timeout_ms. An admitted browser-socket endpoint stays retained on the active browser provider for later calls and closes on unconfirmed target-session cleanup or when that provider closes; a discovery deadline or cancellation on a clean shared socket releases only that call's lease.",
"List pages exposed by one loopback Chrome DevTools Protocol endpoint, optionally filtered by exact origin. Returns target IDs and URLs; query values and fragments are preserved, with URL userinfo credentials removed. Use a returned target ID with inspect_web_page. discovery_timeout_ms controls discovery; command_timeout_ms does not apply. Browser-socket endpoints remain shared by the active browser provider until it closes or target-session cleanup is unconfirmed; cancellation/deadline on a clean socket releases only this call’s lease.",
kind: "browser-provider",
inputSchema: listBrowserTargetsInputSchema,
outputSchema: listOutputSchema,
@@ -206,7 +206,7 @@ export const BROWSER_TOOL_CONTRACTS = [
name: "analyze_web_bundle",
...toolContractMetadata("analyze_web_bundle"),
description:
"Capture JavaScript source from one selected CDP page and statically derive a chunk graph, route and endpoint candidates, vendor fingerprints, page-declared WebMCP metadata, and optionally fetch source maps from the selected target origin or explicitly requested origins. JavaScript is parsed but never executed. Select detail summary with a web-bundle view for filtered endpoint observations, inferences or counts, or a javascript-routes view for route patterns, occurrences, sources, unknowns or counts. Complete Evidence remains retained for later views. Static candidates do not establish reachability or a complete application route denominator.",
'Recover a static chunk graph, route/endpoint candidates, vendor fingerprints and page-declared WebMCP metadata from JavaScript on one selected CDP page. May fetch source maps only from the target origin or explicitly selected origins; application JavaScript is not executed. detail summary retains complete Evidence; view {kind: "web-bundle", collection: "endpoints"} selects endpoint rows, and javascript-routes views select route patterns/occurrences/sources/unknowns. Read later pages with inspect_analysis_view. Static candidates do not establish runtime reachability or a complete route set.',
kind: "browser-provider",
inputSchema: analyzeWebBundleRequestSchema,
outputSchema: bundleOutputSchema,
@@ -267,7 +267,7 @@ export const BROWSER_TOOL_CONTRACTS = [
name: "compare_web_captures",
...toolContractMetadata("compare_web_captures"),
description:
"Compare passive web captures by providing before and after, each with the complete inspect_web_page normalized_result in inspection and an optional complete discover_webmcp_tools normalized_result in webmcp; or compare recorded scenarios by passing complete capture_browser_scenario normalized_result objects in before_scenario and after_scenario with an optional normalization policy. Use exactly one input group. Network comparison includes observed HTTP requests and WebSocket frame streams; same-URL connections are compared as an unordered collection of ordered streams, retaining connection counts without claiming stable identity between individual connections. Scenario comparison aligns exact step IDs, records deterministic literal normalization, and returns every artifact-level difference plus alignment failures inline. Missing or truncated evidence never proves equality.",
"Compare two passive page inspections or two recorded browser scenarios. For passive captures, pass before/after with each complete inspect_web_page normalized_result in inspection and optional complete discover_webmcp_tools normalized_result in webmcp. For scenarios, pass complete normalized_result objects as before_scenario/after_scenario; use exactly one input group. Returns artifact differences and alignment failures. Scenario steps align by exact IDs; optional literal normalization is recorded. HTTP requests and ordered WebSocket streams are compared without inventing stable identities for same-URL connections. Missing or truncated Evidence never proves equality.",
kind: "browser-provider",
inputSchema: browserCaptureComparisonInputSchema,
outputSchema: captureDiffOutputSchema,
@@ -16,7 +16,7 @@ export const CAPTURE_TOOL_CONTRACTS = [
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Discover protocols or field names/types registered in the installed TShark 4.x. kind defaults to protocols; use fields and optional exact protocol abbreviation to select field definitions. query searches name/abbreviation/description by case-insensitive literal substring using Unicode simple case folding. Return 50 matches by default with offset/limit paging; null requests all remaining within resource limits. Preserve type/base/bitmask/description, duplicate registrations, source line numbers, coverage, tool identity and diagnostics. Linux, TShark 4.x (PATH or absolute REA_TSHARK_COMMAND) and prlimit required. No capture file, interface or binary target needed. Registrations describe tool capabilities, not observed traffic. Each call rereads the glossary; use selected fields with inspect_packet_capture.",
"Find protocols or field definitions registered in installed TShark 4.x. kind defaults to protocols; use fields with an optional exact protocol abbreviation, then pass selected names to inspect_packet_capture. query is a case-insensitive literal substring. Returns definitions, duplicate registrations, source lines, tool identity and coverage; offset/limit pages matches (default 50; null means all remaining). Requires Linux, prlimit and TShark on PATH or absolute REA_TSHARK_COMMAND. Each call rereads the glossary. No capture/target is needed; registrations describe capabilities, not observed traffic.",
inputSchema: inspectPacketFieldsInputSchema,
outputSchema: evidenceResultOf(packetFieldsCatalogSchema),
examples: [
@@ -33,7 +33,7 @@ export const CAPTURE_TOOL_CONTRACTS = [
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Inspect caller-selected fields in an existing local packet capture with TShark 4.x. Return 50 matching frames by default, with match_offset/match_limit paging and coverage counts; match_limit:null requests all remaining matches. Preserve repeated values, frame numbers, display filter, decode-as rules and pass mode in inline Evidence with source/tool identity and diagnostics. Optional packet_limit counts input packets before filtering; output paging does not shorten dissection or two-pass reassembly. Requires Linux, util-linux prlimit, and TShark 4.x on PATH or through absolute REA_TSHARK_COMMAND. File-only analysis; no live capture or device communication. Missing fields or no matches do not establish absence of device traffic.",
"Extract caller-selected TShark fields from a saved packet capture, with display filters, decode-as rules and pass mode preserved. Returns frame numbers, repeated values, coverage and diagnostics; use inspect_pcap_capture for a prepared endpoint/DNS/TLS/HTTP summary. Defaults to 50 matching frames; match_offset/match_limit page output and null requests all remaining. packet_limit counts input packets before filtering; output paging does not shorten dissection or reassembly. Requires Linux, prlimit and TShark 4.x on PATH or absolute REA_TSHARK_COMMAND. No live capture/device communication; no matches does not prove absence of traffic.",
inputSchema: inspectPacketCaptureInputSchema,
outputSchema: evidenceResultOf(packetCaptureSchema),
examples: [
+2 -2
View File
@@ -42,7 +42,7 @@ export const CUTTER_TOOL_CONTRACTS = [
...toolContractMetadata("list_cutter_sessions"),
kind: "native-provider",
description:
"List live REA bridge sessions hosted by upstream Cutter instances, including observed document identity and bridge-directory security status. Discovery admits at most 256 descriptor candidates (16 MiB at the descriptor byte limit). That candidate budget is separate from REA_BRIDGE_MAX_REQUEST_BYTES and has no runtime override. Discovery reads and probes at most eight concurrently, and reports bridge_directory_capacity_exceeded rather than claiming no sessions when that budget is exceeded.",
"Find live REA bridge sessions in Cutter and return document identity and bridge-directory security status. Examines at most 256 descriptors with up to eight concurrent probes; excess capacity returns bridge_directory_capacity_exceeded, not an empty session list. The fixed discovery budget is separate from REA_BRIDGE_MAX_REQUEST_BYTES and cannot be raised at runtime.",
inputSchema: cutterListInputSchema,
outputSchema: cutterDiscoverySchema,
examples: [{ title: "List open Cutter instances", input: {} }],
@@ -52,7 +52,7 @@ export const CUTTER_TOOL_CONTRACTS = [
...toolContractMetadata("cutter_command"),
kind: "native-provider",
description:
"Run one arbitrary Rizin command in a selected live Cutter session. Commands may edit and persist analysis state or execute plugin-provided effects; completion uncertainty is returned as Evidence and must not be retried automatically. The authenticated request and response frame is bounded by REA_BRIDGE_MAX_REQUEST_BYTES (default 16777216 bytes, floor 7464, maximum 536870887). The payload budget excludes the terminating LF. An out-of-band Cutter process without the setting uses 16777216 bytes; a mismatch is refused before the command is sent. In a shared MCP server, this admitted command closes any active binary-analysis session; after its effects have settled, call open_binary before further analysis. Close an active Ghidra session explicitly first.",
"Run one arbitrary Rizin command in a selected Cutter session; it may persist edits or execute plugin effects. Reports completion uncertainty as Evidence; do not retry automatically. An admitted command retires shared binary analysis: close active Ghidra explicitly first, then reopen with open_binary after command effects settle. Supply session_id and expected_generation from discovery. REA_BRIDGE_MAX_REQUEST_BYTES bounds authenticated request/response payloads excluding LF (default 16777216, range 7464..536870887); mismatched client/Cutter budgets refuse dispatch. An out-of-band Cutter without this setting uses the default.",
inputSchema: cutterCommandInputSchema,
outputSchema: evidenceResultOf(cutterCommandResultSchema),
examples: [
@@ -16,7 +16,7 @@ export const DESKTOP_APPLICATION_TOOL_CONTRACTS = [
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Inspect a local desktop application directory using bounded listings, file headers and selected metadata. Returns .NET, Unity Mono/IL2CPP, Unreal, Godot, GameMaker and Electron candidates, supporting paths/range hashes, component path markers and concrete next probes. No target execution, extraction, network or target changes. Default summary retains complete Evidence for inspect_analysis_view kind desktop-application; the view supports paging and field selection. detail complete returns every retained fact inline. Snapshot identity covers examined metadata/read ranges, not all file contents; coverage and unavailable probes remain explicit.",
"Identify runtime candidates and next probes in a local desktop app directory from bounded listings, headers and metadata. Recognizes .NET, Unity Mono/IL2CPP, Unreal, Godot, GameMaker and Electron; returns supporting paths and range hashes. Default summary retains complete Evidence for inspect_analysis_view kind desktop-application; detail complete returns retained facts inline. Identity covers examined ranges, not every file byte. Coverage and unavailable probes remain explicit. No target execution, extraction, network or target changes.",
inputSchema: inspectDesktopApplicationInputSchema.extend({
detail: z.enum(["summary", "complete"]).default("summary"),
}),
+8 -8
View File
@@ -139,7 +139,7 @@ export const DESKTOP_BUILD_TOOL_CONTRACTS = [
...toolContractMetadata("start_build_computer"),
kind: "application",
description:
"Start a local agentenv computer to build a desktop app environment on, and return its id with a first screenshot as an image. From a request, REA renders a bundle that installs the app from the Ubuntu archive, an apt repository or a .deb URL, opens it on demand from its desktop entry (it is not open at first: start_build_capture opens it under capture, and only when no capture is under way is it opened from the desktop's Applications menu, under Other, by the environment's name), and installs REA itself in a build-only layer from REA_BUILD_COMPUTER_REA_ARCHIVE. Set source.electron for an Electron app: the install rewrites that desktop entry's command with the same launch policy an export uses, adding --no-sandbox right after the program unless the command already has it, because the container does not grant the user namespaces Chromium needs and Electron exits without the flag. From a bundle folder, such as an exported one, it starts that bundle's smoke task as it is. Needs Docker and the agentenv runner named by REA_AGENT_ENV_COMMAND; the first start of a bundle builds its image, which downloads packages and can take minutes, and agentenv makes a start wait while another agentenv run on this host writes its bundle's ids, so starts at the same time can wait minutes for each other. screenshot sets the first screenshot's region, format and quality. The computer stays up, reachable on this host, until close_build_computer or the server closes; when a start fails before its teardown is confirmed, the error's computer_id names what close_build_computer retries.",
"Start a local agentenv computer, installing/downloading app packages as needed; returns computer_id and a first screenshot. Requires Docker and REA_AGENT_ENV_COMMAND. Request sources install from Ubuntu, apt repositories or a .deb URL and add REA from REA_BUILD_COMPUTER_REA_ARCHIVE in a build-only layer. The app starts later: use start_build_capture, or its Applications > Other menu entry when no capture is active. Set source.electron to apply the export launch policy, adding --no-sandbox unless present because the container lacks Chromium user namespaces. Bundle-folder sources run their existing smoke task unchanged. Initial image builds and concurrent agentenv state updates can take minutes. screenshot selects initial region/format/quality. The computer stays reachable until close_build_computer or server shutdown; if failed-start teardown is unconfirmed, use the error's computer_id to retry close_build_computer.",
inputSchema: z.strictObject({
source: buildSourceSchema,
screenshot: screenshotOptionsSchema.optional(),
@@ -178,7 +178,7 @@ export const DESKTOP_BUILD_TOOL_CONTRACTS = [
name: "act_on_build_computer",
...toolContractMetadata("act_on_build_computer"),
kind: "application",
description: `Drive the app on a build computer: one action, ${COMPUTER_ACTIONS.join(", ")}. Each but reset and type_secret is sent to the computer's computer_<action> tool with the fields given, which are the driver's own arguments; type_secret types into the focused field the value of the secret its handle names, a file the person wrote in REA's build-secrets folder on this host (${secrets.BUILD_SECRETS_FOLDER}), readable only by them: no result, log or record shows the value, only the handle, so it takes no screenshot, and the field must be one that masks what is typed, since a later screenshot shows the screen; reset restores the app's data to its seed with data/reset, which relaunches the app, and returns once the computer is ready again; a screenshot asked of it that then fails leaves the reset done, its result naming why in screenshot_error. Points are pixels of the latest frame, so take a screenshot first, or space norm on a 0..norm_scale grid; count 2 double-clicks; a drag's path takes 2 to 50 points; a screenshot with region does not capture the screen again, it crops the latest frame, so take a full screenshot, or a wait with screenshot true, first; keys names one chord in W3C names, and spellings such as ctrl+s are translated. Returns the driver's content unchanged, its images included, and its structured result; an action's screenshot is taken at once, so after one that opens a menu or a window, take it with a wait instead; a refusal, such as a stale frame, is an error with the computer's message. Each action is logged on the computer. Actions, capture steps and checks on one computer run one at a time, in the order they arrive; computers run side by side.`,
description: `Act on a running build computer with ${COMPUTER_ACTIONS.join(", ")}; actions can change app state. Returns driver content/images and structured results, with each action logged. Points use the latest frame's pixels (take a screenshot first), or space norm on 0..norm_scale; count 2 double-clicks, drag path has 2..50 points, and keys names one W3C chord (ctrl+s is translated). Region screenshots crop the latest frame rather than recapture; use a full screenshot or wait with screenshot true first. After opening a menu/window, wait for its screenshot instead of taking the action's immediate one. type_secret reads the user-created handle file at ${secrets.BUILD_SECRETS_FOLDER} into a focused masked field: only the handle is recorded and no screenshot is taken, but later screenshots can expose unmasked fields. reset restores seed data through data/reset and relaunches; screenshot_error after reset does not undo it. Other actions forward the driver's arguments unchanged; refusals such as stale frames retain its message. Actions, capture steps and checks run sequentially per computer; different computers run independently.`,
inputSchema: computerActionInputSchema,
outputSchema: z.strictObject({
computer_id: z.uuid(),
@@ -219,7 +219,7 @@ export const DESKTOP_BUILD_TOOL_CONTRACTS = [
name: "start_build_capture",
...toolContractMetadata("start_build_capture"),
kind: "application",
description: `Begin REA's capture of the app on a build computer started from a request, inside the computer: REA downloads the package lists as the computer's user so the capture finds the app's sources, launches the app from its desktop entry under capture (do not open it from the menu first) and returns once its window is open, with a screenshot. When the app exits before its window opens, the error gives its exit code and the end of its stderr, with the capture's record of the session in its details. REA counts a file as the app's document when an app window's title shows its name or ~/ path; name the file the app will save in state_paths when its title shows something else, such as a score's title. Then make the seed through the app and save it, mark_build_checkpoint ${SEED_CHECKPOINT}, make the change the task asks for and save it, mark_build_checkpoint ${END_CHECKPOINT}, and stop_build_capture.`,
description: `Launch the app under capture on a request-built computer and return its open-window screenshot. Downloads package lists as the computer user to identify sources; do not open the app from its menu first. Early exit reports code, stderr tail and capture details. Documents are recognized from file names/~/ paths in window titles; supply state_paths when titles name something else. Save the seed through the app, mark_build_checkpoint ${SEED_CHECKPOINT}, make and save the requested change, mark ${END_CHECKPOINT}, then stop_build_capture.`,
inputSchema: z.strictObject({
computer_id: computerId,
arguments: z
@@ -270,7 +270,7 @@ export const DESKTOP_BUILD_TOOL_CONTRACTS = [
name: "mark_build_checkpoint",
...toolContractMetadata("mark_build_checkpoint"),
kind: "application",
description: `Take a named checkpoint of the app's state in the capture under way and wait for the capture to acknowledge it, with its counts (entries walked, paths changed since the checkpoint before, files retained) and up to ${String(MAX_ACKNOWLEDGED_FILES)} of the files that changed, those a window title named first, then those under state_paths and those the app held open, caches last, so you can see which file a save wrote. Mark ${SEED_CHECKPOINT} once the seed is saved and ${END_CHECKPOINT} once the change is; a name already taken is refused. For several tasks, make each later task's change on top and mark ${END_CHECKPOINT}-<task name> once it is saved; then, for any task, make a near miss of its change, save it and mark near-<task name>, which the export requires to fail one of that task's checks.`,
description: `Checkpoint the running capture under a unique name; returns acknowledged counts and up to ${String(MAX_ACKNOWLEDGED_FILES)} changed files. Files named by window titles rank first, then state_paths/open files, with caches last. Mark ${SEED_CHECKPOINT} after saving the seed and ${END_CHECKPOINT} after saving the first change. For later tasks, build on the preceding change and mark ${END_CHECKPOINT}-<task name>; mark near-<task name> after saving a near miss that must fail one task check. Duplicate names are refused.`,
inputSchema: z.strictObject({
computer_id: computerId,
name: buildCheckpointNameSchema,
@@ -312,7 +312,7 @@ export const DESKTOP_BUILD_TOOL_CONTRACTS = [
name: "stop_build_capture",
...toolContractMetadata("stop_build_capture"),
kind: "application",
description: `Stop the capture: the app is closed and the capture finishes inside the computer. Returns its checkpoints, the package and sources it found, its limitations and, when ${SEED_CHECKPOINT} and ${END_CHECKPOINT} were marked and this server has not used a declared secret, the task draft between them, with one draft in later_drafts per later task's ${END_CHECKPOINT}-<task name> checkpoint, from the end checkpoint before it: the files that changed under the paths the bundle owns, each with its net change and, for XML files, archives, JSON and key files, the values it added, changed and removed (before and after, at the pointers a check names them by); suggested checks; and guards, optional checks that the rest stays as it was. Notes say why a draft is empty (nothing changed; the changes lie outside the owned paths, listed with their roles; the app saved its change only in dconf, which no check reads; a dconf database changed that REA could not read; or REA recognized no document: capture again with state_paths naming the file, or make a change the app saves in a file) or why a file's suggestions are thin (only position names the change, it is all view state, its text is too long, or its view is cut or unreadable). If the server has used a declared secret, automatic drafting is withheld before it runs; write the tasks manually and give them to export_build_environment. Otherwise write each task from its draft, its prompt in the user's words, and give them to export_build_environment.`,
description: `Close the captured app and finish its capture. Returns checkpoints, package/sources, limitations and a draft between ${SEED_CHECKPOINT} and ${END_CHECKPOINT} when both exist and no declared secret was used. later_drafts contains one draft per later ${END_CHECKPOINT}-<task name>, relative to the preceding end checkpoint. Drafts list owned-path changes, supported before/after structured values, suggested checks and optional unchanged-state guards. Notes explain missing/thin drafts and recovery: add unrecognized documents to state_paths, or make a change saved in a readable file rather than only dconf. After secret use, automatic drafting is withheld; write the tasks manually. Otherwise write each task from its draft in the user's words and pass the tasks to export_build_environment.`,
inputSchema: z.strictObject({ computer_id: computerId }),
outputSchema: z.strictObject({
computer_id: z.uuid(),
@@ -354,7 +354,7 @@ export const DESKTOP_BUILD_TOOL_CONTRACTS = [
name: "export_build_environment",
...toolContractMetadata("export_build_environment"),
kind: "application",
description: `Export the stopped capture as an agentenv computer app bundle with the given tasks, inside the computer, seeded at ${SEED_CHECKPOINT}, each task checked at its own end checkpoint, ${END_CHECKPOINT} by default, and at its near miss near-<task name> when the capture took one, then copy the bundle to a new or empty folder on this host, every file checked against its digest. The bundle's eval lists every task. A bundle whose file names or contents hold a secret from REA's build-secrets folder, as it is, in UTF-16, hex, base64, URL encoding or inside a gzip file, is refused and written nowhere, the error naming the secrets' handles and the files. ${secrets.WITHHELD_EXPORT_DESCRIPTION} A task the export refuses, such as a check that already passes on the seed, or a near miss every check passes, is an error naming the task and why, and no bundle is written. Witness each task next, each on a fresh computer: start_build_computer from the folder and check_build_task.`,
description: `Export the stopped capture and given tasks as an agentenv app bundle, seeded at ${SEED_CHECKPOINT}. Each task uses its selected end checkpoint (${END_CHECKPOINT} by default) and its captured near-<task name> when present. The bundle's eval lists every task; verified files are copied to a new/empty host directory. Refuses publication if names or contents contain declared secrets, including UTF-16/hex/base64/URL/gzip forms; errors identify handles and files. ${secrets.WITHHELD_EXPORT_DESCRIPTION} A check already passing on the seed or a near miss passing every check refuses the whole export, naming the task and reason. Witness each task on a fresh computer with start_build_computer and check_build_task.`,
inputSchema: z.strictObject({
computer_id: computerId,
tasks: z
@@ -425,7 +425,7 @@ export const DESKTOP_BUILD_TOOL_CONTRACTS = [
name: "check_build_task",
...toolContractMetadata("check_build_task"),
kind: "application",
description: `Grade a task's checks against the app's live state on a computer of an exported bundle: REA reads the app's data/get views and evaluates each check as the bundle's verifier does, one result per check, once the app's files settle (a screen_judge task instead takes a screenshot and runs the bundle's own judge on it with the agentenv runner's Python and model endpoint, three votes a question): it reads data/get every ${String(SETTLE_TIMING.intervalMs / 1000)} s and grades once every file has held for ${String(SETTLE_TIMING.windowMs / 1000)} s, counted from the read that returned its bytes, so an app that saves a few seconds after the last key is graded on what it saved; no read begins ${String(SETTLE_TIMING.boundMs / 1000)} s or more after the first one began, one still in flight then is cut (read_cut), and files still changing are graded on the last completed read, with settled false. With stage, the check is part of the witness, in order: seed (give directory; REA begins recording) must fail a check, and on a computer started from a bundle folder it refuses a task whose steps and verifier in the bundle differ from what the export writes for it; after_edit, after acting on the app from the task's prompt alone, must pass every check; near_miss, after a deliberately almost-right change, must fail one; after_reset, after act_on_build_computer action reset, must give each check the result it had on the seed. Only a check that fails on what the app's view shows counts as failing: one that fails because the view could not be read or is cut short is undecided, and a stage only undecided checks would settle files nothing and is refused, to be checked again. A stage that does not hold, or after_reset, ends the witness: REA ends the recording and writes witness.json, the record as Evidence, with the recording's segments into directory, and returns the record.`,
description: `Evaluate saved-state task checks or run a screen_judge through its configured model endpoint on a running exported app. Returns per-check results, settling status and optional witness state. Reads data/get after files settle using exported verifier semantics; screen_judge captures the screen and uses the agentenv runner with three votes per question. Reads every ${String(SETTLE_TIMING.intervalMs / 1000)} s, waits for ${String(SETTLE_TIMING.windowMs / 1000)} s of stable bytes, and bounds observation at ${String(SETTLE_TIMING.boundMs / 1000)} s; unsettled results use the last completed read, with read_cut for interrupted reads. Witness stages run in order: seed (supply directory to begin recording) must fail a check, after_edit must pass all, near_miss must fail one, and after_reset must restore every seed result. Use the task prompt alone for the edit. Seed rejects exported task/verifier mismatches. Unreadable or truncated views are undecided, not witnessed failures; an undecidable stage is refused for retry. A failed stage or after_reset ends recording and writes witness.json plus recording segments to directory.`,
inputSchema: z.strictObject({
computer_id: computerId,
task: desktopTaskSchema,
@@ -478,7 +478,7 @@ export const DESKTOP_BUILD_TOOL_CONTRACTS = [
...toolContractMetadata("close_build_computer"),
kind: "application",
description:
"Tear a build computer down and discard its state. agentenv's teardown is tried first; if it leaves the computer up, REA removes that exact sandbox's containers, the one named agent-<sandbox id> and any labelled agentenv.sandbox=<sandbox id>, with REA_DOCKER_COMMAND. When neither confirms it, the error names what is left and the computer stays listed, so closing again retries. Closing cancels the call in progress on the computer and refuses those waiting for it.",
"Tear down a build computer and discard its state, cancelling its active call and refusing queued calls. Tries agentenv first, then REA_DOCKER_COMMAND on only that sandbox's named/labelled containers. Unconfirmed teardown reports remaining resources and retains the computer for another close attempt.",
inputSchema: z.strictObject({ computer_id: computerId }),
outputSchema: z.strictObject({
computer_id: z.uuid(),
+10 -10
View File
@@ -32,12 +32,12 @@ const enhanced = <
export const ENHANCED_TOOL_CONTRACTS = [
enhanced(
"inspect_native_dispatch_metadata",
"Inspect the bound provider's name inventory for Objective-C class/method symbols and Swift mangled symbols, returning at most max_records decoded names. Optional objc_class_import_addresses request exact pointer-slot binding facts for those addresses; they are decoded only from the selected Mach-O slice and retain partial or unsupported coverage when not established. Includes target SHA-256 when available, provider identity/version, analysis-profile digest, facet coverage, and per-record Evidence. This is static symbol and metadata evidence, not runtime metadata: ivar layouts, protocol conformances, witness/class tables, and relative pointers are explicitly marked unsupported unless a provider supplies those decoders. The provider controls how its name inventory is acquired. The Mach-O byte reader holds the whole file in memory: max_input_bytes (default 64 MiB, at most 1 GiB) bounds it, and results record input_admission.",
"Inspect analyzed Objective-C class/method and Swift mangled symbols, with optional exact Objective-C import-pointer binding facts from the selected Mach-O slice. Returns decoded names up to max_records, provider/profile identity, target digest when available, facet coverage and per-record Evidence. Symbol observations do not establish runtime layouts, conformances or witness/class tables. The selected provider owns name discovery. max_input_bytes bounds the whole-file Mach-O read; unresolved bindings remain partial or unsupported.",
enhancedInputSchemas.inspect_native_dispatch_metadata,
),
enhanced(
"get_objc_classes",
"Discover Objective-C class labels, optionally filtering by literal substring. Rows are coalesced only when exact selected-image pointer-fixup evidence proves that their own addresses bind the same imported class symbol, binding stream, raw library ordinal and resolved library, weak status, and addend. Rows without that evidence remain separate, with identity coverage reported as unknown, partial, or unsupported.",
"Find Objective-C class labels, optionally by literal substring. Labels remain separate unless exact selected-image pointer-fixup Evidence establishes the same imported class binding, including library, ordinal, weak status and addend. Missing binding proof remains unknown, partial or unsupported.",
enhancedInputSchemas.get_objc_classes,
),
enhanced(
@@ -47,42 +47,42 @@ export const ENHANCED_TOOL_CONTRACTS = [
),
enhanced(
"batch_decompile",
"Decompile each explicit procedure symbol or address, with one provider read active per batch. Preserves each input selector in address and reports the observed canonical entry and entry label in procedure; identity or label failures remain explicit without discarding usable pseudocode. Returns ordered per-item outcomes and aggregate counts. An unavailable item means the provider returned null pseudocode; its limitations retain any reported reason without asserting provider capability or retryability. Errors report failed operations or malformed output. Failed counts include unavailable items. The complete reply carries every pseudocode body. Select detail summary to retain the batch and receive only counts, then read rows or one body by index through inspect_analysis_view. A per-function limit is not a batch deadline; allow for every item or split calls.",
"Decompile an explicit list of procedure symbols/addresses in input order, with one provider read active per batch. Returns per-item pseudocode, unavailable or error outcomes and aggregate counts; input selectors and observed canonical procedure identities remain separate. Null pseudocode is unavailable, without an inferred capability or retry reason; failed counts include unavailable items. detail summary retains the batch for inspect_analysis_view item/body pages; complete includes every body. Per-function limits do not bound the whole batch.",
enhancedInputSchemas.batch_decompile.extend({
detail: analysisDetailSchema,
}),
),
enhanced(
"decompile_all",
"Write provider pseudocode for every analyzed function, or a filtered subset, into a caller-selected directory and return only a manifest. Each file records the provider function name, canonical address, inclusive body ranges when procedure_info supplies them, and that function's procedure_info and pseudocode limitations. Each function's index record keeps its latest attempt and its complete limitations; the journal keeps earlier attempts and their limitations. Evidence keeps at most eight first-observed distinct per-function limitations within an encoded-text budget; the omitted count measures observations, not distinct warnings. The manifest reports counts, the output directory, the index path, at most 32 failure details within 2,048 JSON-encoded UTF-8 bytes (names can be omitted; full names remain in the index), provider identity, and the analysis-profile digest. Pseudocode stays in the files. An existing directory is refused unless resume is set and the journal matches the target SHA-256, provider, and analysis profile; verified files are skipped and conflicting files are left unchanged. layout dwarf reports that compilation-unit paths are unavailable and names files by address. Set retry_failed: independent_fresh to retry a null result explicitly reported as a function failure when supported; the failed attempt stays in the journal and the new attempt may use different analysis context. Errors and omissions without that typed fact are not retried. A failure of one function does not stop the others. Functions procedure_info classifies as external are counted as external, get no file, and are not decompiled; a resume skips them. Cancellation leaves files already written. Per-function limits do not bound the whole call; use limit and resume to select work that fits the client deadline, including import, listing and file work.",
"Export pseudocode for all or selected analyzed functions to a directory; returns a manifest/index, with bodies kept in files. Existing output requires resume with matching target, provider, profile and layout; verified files are skipped and conflicts preserved. External functions produce no file. Item failures do not stop others; cancellation keeps written files. retry_failed: independent_fresh retries only provider-reported function failures when supported, retaining each attempt and its limitations; independent attempts may use different analysis context. layout dwarf falls back to address filenames when compilation-unit paths are unavailable. Select limit/resume to fit the whole client deadline; per-function limits do not bound the export.",
enhancedInputSchemas.decompile_all,
),
enhanced(
"get_call_graph",
"Resolve one symbol or address to its canonical procedure entry, then traverse the bound provider's caller or callee relationships until the reachable graph is exhausted. Every node uses a canonical address and has an ok/error status; failures use safe typed projections. Unresolved indirect calls may be missing and results are not a whole-program CFG. Select detail summary for a bounded first node page with shared message references; native-observation pages and native-context fields retain complete source access.",
"Traverse the provider-observed caller or callee graph from one symbol/address, returning canonical-address nodes with per-node outcomes. Use trace_call_path for a shortest path to a goal, or build_call_path to compose existing function dossiers without provider reads. Indirect calls may be unresolved; this is not a whole-program CFG. detail summary retains the complete graph for native-observation pages and native-context caveats.",
enhancedInputSchemas.get_call_graph.extend({
detail: analysisDetailSchema,
}),
),
enhanced(
"analyze_swift_types",
'Categorize analyzed Swift procedure names using their manglings or same-address Swift symbol aliases. Decodes legacy and literal modern nominal contexts into classes, structs, enums, protocols, and extensions. Preserves provider names and supporting mangled_names; unresolved categories appear in other and in unclassified, which remains inline even under category filters. Returns deduplicated procedure-name counts, not unique source types, plus identification limitations. Optionally select one category and/or apply a case-sensitive literal filter to provider names or supporting manglings; for example, use {category: "structs", pattern: "Pair"}.',
'Classify analyzed Swift procedure names into classes, structs, enums, protocols and extensions using manglings or same-address symbol aliases. Returns deduplicated procedure-name counts, not unique source types; provider names, mangled_names and unresolved classifications remain available. Category and case-sensitive literal pattern filters do not suppress unclassified rows. Example: {category: "structs", pattern: "Pair"}.',
enhancedInputSchemas.analyze_swift_types,
),
enhanced(
"find_xrefs_to_name",
"Resolve an exact name against the bound provider's name inventory and return a resolved or unresolved result. Unresolved names use the stable name_not_found reason; this xref workflow returns address-only projections. Kuna lacks this general name inventory; xrefs can instead resolve names present in Kuna's inventory, but unlisted names may still exist in the target.",
"Find references to an exact analyzed symbol name: resolves the name, then returns its address and referencing addresses. name_not_found means lookup is unresolved, not that a reference search found none or the target lacks the symbol. References are address-only; use inspect_native_instruction for typed incoming references where supported. Kuna lacks the required general name inventory; xrefs can resolve names its inventory knows.",
enhancedInputSchemas.find_xrefs_to_name,
),
enhanced(
"binary_overview",
"Return the bound document and procedure/string counts totalling every row of the bound provider's inventories (inventory_coverage: provider scope, discovery unknown; not comparable across providers), plus every segment and segment_count when the provider supports segment enumeration. If segment fields are omitted, segment coverage is unavailable rather than empty. When every observed segment agrees on an analysis image base, return it as image_base so callers can relate provider addresses to their loader coordinates. Use search_procedures, list_procedures, or analyze_function directly when you already know which procedure to inspect.",
"Summarize the bound document, complete provider-inventory procedure/string row counts, and segments when supported. Counts do not establish discovery of every function/string and are not comparable across providers. Omitted segments mean unavailable coverage. image_base is returned only when observed segments agree. Use search_procedures, list_procedures or analyze_function directly when the procedure is already known.",
enhancedInputSchemas.binary_overview,
),
...FUNCTION_WORKFLOW_TOOL_CONTRACTS,
enhanced(
"trace_feature",
"Search provider string and procedure inventories for the complete literal query, preserving spaces, then query xrefs at each matched start address. References to interior bytes of strings and procedures are not searched. An empty result or truncated: false does not prove there are no references. Preserve an explicit unavailable owner for a non-retryable containment capability refusal; reference kinds remain unknown. For a procedure match, use procedure_references with direction incoming for provider-reported kinds when supported; it covers the procedure body, so compare target addresses when selecting exact-entry references. Select detail summary to retain complete Evidence and page matches, references and unknowns with inspect_analysis_view kind native-feature-trace.",
"Search procedure/string inventories for the complete literal query, then query xrefs at matched start addresses. Interior-byte references are not searched; empty results or truncated: false never establish no references. Containment refusals preserve an unavailable owner, and reference kinds remain unknown. For typed incoming procedure references use procedure_references, comparing target addresses for exact-entry matches. detail summary retains matches/references/unknowns for inspect_analysis_view kind native-feature-trace.",
enhancedInputSchemas.trace_feature.extend({ detail: analysisDetailSchema }),
),
enhanced(
@@ -97,7 +97,7 @@ export const ENHANCED_TOOL_CONTRACTS = [
),
enhanced(
"trace_native_values",
"Trace a bounded static dependency graph from one explicit native procedure. Includes high-p-code def-use, constants, operators, memory and branch operations, resolved call edges, and derived argument/parameter and return/output bindings. Missing bindings, alias semantics, persistent state and RNG roles remain unknown. Budgets bound depth, decompilations, graph size and payloads; nodes are paginated. A Ghidra per-function timeout does not bound the whole traversal; allow startup, every attempted function and other work, or reduce max_functions.",
"Trace static value dependencies across resolved calls from one native procedure: high-p-code def-use, constants, operators, memory/branch operations and derived argument/return bindings. Alias effects, missing bindings, persistent state and RNG roles remain unknown. Caller-selected budgets bound traversal and retained facts; nodes are paged. A Ghidra per-function timeout does not bound the traversal: allow startup and every attempted function, or reduce max_functions.",
enhancedInputSchemas.trace_native_values,
),
] as const satisfies readonly ToolContract[];
+1 -1
View File
@@ -11,7 +11,7 @@ export const ENVIRONMENT_TOOL_CONTRACTS = [
name: "export_environment_bundle",
...toolContractMetadata("export_environment_bundle"),
description:
"Write an agent environment bundle folder from capture Evidence (capture_browser_scenario, or HAR inspect_web_network_capture Evidence) into an absent absolute output_directory whose parent exists, as rea environment-build does. It projects the environment manifest with the default template rules, derives the state the bundle serves, and reports read tools answered from the state or replayed with their reason, and write tools served or withheld with a hint about what to record next; check the same coverage first with inspect_analysis_view view environment-coverage. dry_run reports without writing. The bundle copies the capture Evidence byte for byte, recorded response bodies included, and its README names how the agentenv framework uses it. Reads that Evidence, and package_tarball when given, and writes only that folder; no network access. dry_run still checks output_directory. Destination refusals name this tool; the others name their stage as environment-build's do.",
"Write an agent environment bundle from capture_browser_scenario Evidence or HAR inspect_web_network_capture Evidence to an absent absolute output_directory whose parent exists. Copies complete capture Evidence, including recorded bodies, and derives replay/state read tools and served/withheld writes with coverage and next-recording hints. Preview the same coverage with inspect_analysis_view kind environment-coverage. dry_run reports without writing but still validates the destination. Uses default template rules, reads only selected Evidence and optional package_tarball, and writes only that directory; no network access. The bundle README explains agentenv use. Destination refusals name this tool; other failures name their export stage.",
kind: "application",
inputSchema: exportEnvironmentBundleInputSchema,
outputSchema: environmentBuildReportSchema,
+1 -1
View File
@@ -31,7 +31,7 @@ export const ERLANG_BEAM_TOOL_CONTRACTS = [
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Inspect one explicit local Erlang BEAM IFF container without executing bytecode or installing Erlang. Returns form/chunk byte ranges and payload SHA-256, atoms, export/import/lambda tables with resolved atom names, and the Code header. Complete output is the default. detail summary retains complete Evidence and returns module/header/counts; include a beam view for selected atoms/exports/imports/lambdas/chunks in the first call, then page retained or offline facts with inspect_analysis_view. Exact names/indices/fields select facts; import modules intersects function names. Same-name arities survive under parent-and-collection-scoped source_index; atom and lambda indexes retain their original meaning. Missing tables stay null in counts; unresolved names stay null and runtime absence remains unknown. Reads a stable regular file; malformed/truncated input and exhausted parser budgets return no partial success. Portable on supported Node hosts; no BEAM emulator required.",
"Inspect an Erlang BEAM IFF file without executing bytecode or requiring Erlang. Returns chunk byte ranges/digests, atoms, exports/imports/lambdas and Code header. Default complete returns full Evidence; detail summary retains it, and an optional beam view selects collection rows in the first call. Reuse inspect_analysis_view kind beam for atoms/exports/imports/lambdas/chunks, exact names/indices/fields and paging. source_index scopes rows to parent/collection, preserving every arity; original atom/lambda indices remain distinct. Missing tables/counts stay null, not empty; runtime absence is unknown. Malformed/truncated input or exhausted budgets fail without partial success.",
inputSchema: inspectErlangBeamRequestSchema,
outputSchema: analysisDetailOutputSchemaOf(
erlangBeamSchema,
+1 -1
View File
@@ -24,7 +24,7 @@ export const INSPECT_EVM_INTERFACE_CONTRACT = {
kind: "artifact-provider",
requiresActiveTarget: true,
description:
'Inspect explicit local flat EVM bytecode without target execution or chain/RPC access. Select raw or hex encoding explicitly. Omitted or complete detail returns original carrier and decoded identities, full bytecode and all inferred interface candidates inline. For all inferred selectors/offsets/arguments/mutability and identities without bytecode hex or duplicated stdout, select detail: "summary" on this first call: it retains unchanged complete Evidence and returns a distinct linked inspect_analysis_view summary. Read original function rows or bytecode_hex/stdout/stderr text pages using view kind evm and normalized_result.parent_evidence_id; original complete Evidence remains accessible. Bytecode kind, hardfork, deployed authenticity and discovery completeness stay unknown; summary coverage covers only producer-returned candidates. Unchanged bundled EVMole 0.9.3/WASM in an owned bounded worker is initially real-verified on Linux x64; EOF-style EF00 containers are unsupported. Adjust timeout_ms (default 30000 ms, integer 1..2147483647) for the owned worker command on the next call; omitted timeout_ms keeps 30000 ms. Per-call producer_limits adjusts carrier/reply/diagnostic bytes, address-space/file bytes and CPU seconds; omitted file_bytes follows selected output_bytes. Tighter inherited Linux limits stay enforced; timeout_ms and the 256 MiB worker heap remain independent. No signature lookup, wallet action or transaction broadcast.',
"Infer interface candidates from explicit local flat EVM bytecode using bundled EVMole 0.9.3/WASM; select raw or hex encoding. Linux x64 profile; EOF-style EF00 containers are unsupported. Returns selectors, offsets, arguments and mutability candidates, not verified deployment or runtime behavior. Bytecode kind, hardfork and discovery completeness stay unknown. Default complete includes bytecode/full Evidence; detail summary retains it for inspect_analysis_view kind evm, facets functions/bytecode_hex/stdout/stderr, via parent_evidence_id. timeout_ms and producer_limits are independent of each other and worker heap; tighter inherited limits still apply. No target execution, chain/RPC access, signature lookup, wallet action or broadcast.",
inputSchema: evmInterfaceInspectionInputSchema,
outputSchema: analysisDetailOutputSchemaOf(
evmInterfaceSchema,
@@ -32,7 +32,7 @@ export const FIRMWARE_TOOL_CONTRACTS = [
name: "extract_firmware",
...toolContractMetadata("extract_firmware"),
kind: "firmware-provider",
description: `Extract caller-selected firmware bytes with ${FIRMWARE_TOOL_REQUIREMENTS[FIRMWARE_OPERATION_ENGINES.extract_firmware].requirement} into an absent output directory. Returns verified child paths/digests, task derivations, unknown chunks and uncovered selected input ranges, extraction diagnostics and explicit extraction_gaps rows naming unextracted regions, missing extractor dependencies and a continuation_id referencing shared extraction_continuations recovery instructions. Preserves the default sandbox; publishes regular files only. Linux, caller-supplied tool, format-specific extractors, util-linux prlimit and procps ps required. No mounts or extracted-code execution. Select a returned native file with open_binary for Ghidra analysis; decompressed offsets are not original-file addresses.`,
description: `Extract selected local firmware bytes with ${FIRMWARE_TOOL_REQUIREMENTS[FIRMWARE_OPERATION_ENGINES.extract_firmware].requirement} into an absent output directory. Returns verified child paths/digests, derivations, uncovered ranges, unknown chunks and extraction_gaps with continuation_id recovery instructions. Linux, format-specific extractors, prlimit and procps ps are required. Preserves the sandbox and publishes only regular files; no mounts or extracted-code execution. Select a returned native file with open_binary for analysis. Decompressed offsets are not original-file addresses.`,
inputSchema: firmwareInputSchemas.extract_firmware,
outputSchema: evidenceResultOf(firmwareResultSchemas.extract_firmware),
examples: [
@@ -30,7 +30,7 @@ export const FLUTTER_TOOL_CONTRACTS = [
name: "inspect_dart_aot",
...toolContractMetadata("inspect_dart_aot"),
description:
'Inspect one ABI\'s legacy split VM/isolate Dart AOT snapshot inside an APK (complete structural coverage: Dart 2.14 FullAOT kind 3). Unified _kDartSnapshotData/_kDartSnapshotText profiles are unsupported. Returns the four snapshot exports through the ELF dynamic symbol table with offsets, sizes and headers (magic, kind, length), snapshot hash, and a bounded string-pool projection from isolate data (package: source URIs, dart: SDK URIs, identifier-like tokens). Use pool_policy.contains to select omitted strings before collection, or raise uri_limit/token_limit/run_bytes/token_bytes for the next call without restart. pool_policy does not raise APK, library, ELF or response limits. String-pool entries are byte-pattern observations, not deserialized cluster semantics; typed class and function recovery needs an SDK-specific parser. Omitted or complete detail returns the full observation. Select detail: "summary" for target/ABI/library identity, all snapshot headers, coverage and original lower-bound counts without string lists. The complete source stays retained; read returned strings via inspect_analysis_view with parent_evidence_id and kind dart-aot, collection package_uris/dart_uris/class_like_tokens, offset and limit. Exhausting pages does not imply complete pool coverage. No engine, no execution.',
"Inspect one APK ABI's legacy split VM/isolate Dart AOT snapshot without executing it. Structural coverage supports Dart 2.14 FullAOT kind 3; unified snapshot layouts are unsupported. Returns snapshot exports/headers/hash and bounded package:/dart:/identifier-like byte-pattern strings, not deserialized classes/functions. pool_policy.contains selects strings before collection; other pool budgets do not raise APK/ELF/response limits. Default complete returns all facts; detail summary retains them for inspect_analysis_view kind dart-aot, collections package_uris/dart_uris/class_like_tokens, using parent_evidence_id and row paging. Counts are lower bounds and page exhaustion never proves complete pool coverage.",
kind: "flutter-provider",
inputSchema: dartAotInspectionInputSchema,
outputSchema: evidenceResultOf(
+1 -1
View File
@@ -247,7 +247,7 @@ export const FRIDA_TOOL_CONTRACTS = [
...toolContractMetadata("instrument_with_frida"),
kind: "native-provider",
description:
"Run one caller-authored Frida script against an explicitly selected process and detach when the observation window ends. The CLI and MCP share this ephemeral workflow; use MCP session operations for persistent sessions. Remote authentication is used only for this call and excluded from Evidence.",
"Run caller-authored Frida JavaScript against a selected process for one observation window, then detach. Scripts can read/change target memory and behavior and use the process's capabilities. CLI and MCP share this ephemeral workflow; use start_frida_session/load_frida_script for a persistent session. Remote authentication is call-local and excluded from Evidence. Detachment does not establish target termination.",
inputSchema: z
.strictObject({
mode: z.enum(["attach", "spawn"]),
@@ -50,10 +50,10 @@ const functionWorkflow = <Name extends FunctionWorkflowName>(
export const FUNCTION_WORKFLOW_TOOL_CONTRACTS = [
functionWorkflow(
"analyze_function",
"Build a dossier for one native function identified by symbol or provider-returned address. Returns identity with complete inclusive analyzed body ranges or explicit unknown, provider-specific pseudocode and assembly, comments, calls, references, referenced strings/names, local CFG blocks, and available native API boundary observations. Ghidra terminal-call assumptions that may cut the analyzed body are reported in limitations with available callee identities. Default detail summary returns a compact dossier (identity, pseudocode size, facet counts, value-flow availability) and retains the complete dossier Evidence in this session; page pseudocode, references, assembly, comments and value-flow through normalized_result.parent_evidence_id with inspect_analysis_view. detail complete returns the full dossier inline.",
"Inspect one native function by symbol or provider-returned address. Default summary returns identity, pseudocode size, facet counts and value-flow availability while retaining the complete dossier. Read selected facts with inspect_analysis_view using normalized_result.parent_evidence_id; detail complete returns everything inline. Facets include pseudocode, assembly, body ranges, comments, calls, references, strings/names, CFG and native API observations. Extents reflect provider analysis; limitations report unknown ranges and possible Ghidra terminal-call truncation.",
),
functionWorkflow(
"inspect_native_api",
"Analyze a native API boundary in one function identified by symbol or provider-returned address. Returns confidence, evidence, jump-table dispatch/data/case mappings, separately evidenced default targets, unsupported branches, and residual unknowns. Null case values mean unresolved cases, never a known default.",
"Inspect recovered parameter/return boundary types and jump-table dispatch for one native function selected by symbol or address. Returns confidence, supporting Evidence, case/data/target mappings, unsupported facets and residual unknowns. Null case values are unresolved, never known defaults. Use analyze_function for the broader function dossier.",
),
] as const satisfies readonly ToolContract[];
+2 -2
View File
@@ -19,7 +19,7 @@ export const GDB_TOOL_CONTRACTS = [
...toolContractMetadata("start_gdb_session"),
kind: "native-provider",
description:
"Start a BYO GDB process in MI3 mode when available, suppress startup files, and disable auto-loading. Persistent GDB sessions are available only on Linux, where REA can verify live inferior output descriptors through /proc before detaching; macOS descriptor verification is not implemented, and Windows Job Object cleanup can terminate debugger inferiors. Optionally set inferior_tty to a caller-selected terminal for future inferior runs; REA verifies the setting through GDB/MI before the session becomes ready. The selected terminal must remain available after GDB exits. A live inferior can be detached during close only while this durable output sink remains verified. The session persists in this REA MCP server process and receives an explicit session ID.",
"Start a persistent caller-supplied GDB session and return its session ID. Linux only; detaching a live inferior during close requires a verified durable output TTY. Startup suppresses init files and auto-loading, preferring MI3. Optional inferior_tty selects a verified terminal for later inferior runs; keep it available after GDB exits so close can detach a live inferior safely. The session belongs to this REA server process.",
inputSchema: z.strictObject({
inferior_tty: localPathStringSchema
.optional()
@@ -38,7 +38,7 @@ export const GDB_TOOL_CONTRACTS = [
...toolContractMetadata("gdb_console"),
kind: "native-provider",
description:
"Run one unrestricted GDB CLI command through MI interpreter-exec console and return raw MI, console, target, and log records inline with Evidence. Default detail complete preserves the original Evidence. Explicit detail summary retains that complete parent and returns every ordered MI record once, omitting duplicate stream groupings and raw mirrors; parent_evidence_id supports later inspect_analysis_view summary queries and complete Evidence export. A command timeout preserves collected records with completion_status unknown and stops the owned debugger session. Commands can execute shell, alter target state, access files, and use network. Closing the debugger never implies target termination. In a shared MCP server, this admitted command closes any active binary-analysis session; after its effects have settled, call open_binary before further analysis. Close an active Ghidra session explicitly first.",
"Run one unrestricted command in a persistent GDB session; commands can run shell, change target state, access files and network. Returns ordered MI/console/target/log Evidence. A timeout retains collected records with completion_status unknown and stops the owned debugger; closing does not imply target termination. Default complete preserves full Evidence; summary retains it and omits duplicate stream/raw mirrors for inspect_analysis_view summary queries. In a shared server this command retires active binary analysis: close Ghidra explicitly first, then reopen the binary after command effects settle.",
inputSchema: z.strictObject({
session_id: sessionId,
command: z.string().min(1),
+1 -1
View File
@@ -15,7 +15,7 @@ export const GO_TOOL_CONTRACTS = [
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Inspect embedded Go compiler version, main module, dependency/replacement versions, build settings and optional inferred static (ptr, len) UTF-8 string literals in an explicit local ELF, PE or thin Mach-O image, or the slice of a universal Mach-O named by architecture (read without lipo; artifact stays the universal file, selected_slice records the slice and source ranges stay file offsets). Default detail complete returns original artifact SHA-256, exact build-info source ranges, raw framed module bytes and unparsed module-text lines inline as observed Evidence; include_string_literals: true adds bounded deduplicated string_literals (default max_string_literals 2,000, max_string_literal_bytes 4,096, max_string_bytes 512 KiB, max_string_header_scan_bytes 64 MiB and max_string_candidates 100,000; each budget is selectable per call) recovered from word-aligned (ptr, len) headers in non-executable mapped data pointing within single read-only spans. Explicit detail summary retains the same complete parent and returns compiler/main-module identity, counts, source ranges and parent_evidence_id. Query retained rows through inspect_analysis_view kind go, collection dependencies, settings or string_literals (exact values or substring contains when collected); select indices, fields and pagination. Rows always retain their original index scoped to the parent Evidence; empty filters select none. Runtime dependency completeness and string reachability remain unknown. Supports inline and historical pointer encodings without installing Go, opening a disassembler, executing the target, writing temporary files or accessing the network. Missing metadata is reported as unknown, not proof that an image is not Go. Does not recover functions, source mappings, types or runtime behavior. Per-call max_input_bytes defaults to 256 MiB, max_header_search_bytes to 256 MiB of cumulative distinct search-span work (partial overlaps charged separately), max_build_info_bytes to 1 MiB and max_report_bytes to 8 MiB. Increase the exact reported request budget and retry the same complete artifact without restarting; these controls do not raise MCP delivery limits or the separate 16 MiB structural decoding boundary. Malformed, unsupported and oversized inputs receive typed failures rather than partial success.",
"Read embedded Go compiler, module, dependency/replacement and build-setting metadata from a local ELF, PE or selected Mach-O slice without running it or requiring Go. include_string_literals: true adds inferred static UTF-8 literals; runtime use and dependency completeness remain unknown. Missing build info does not prove the image is not Go. Default complete returns artifact SHA-256, source ranges and original metadata; detail summary retains it for inspect_analysis_view kind go, collections dependencies/settings/string_literals, with parent_evidence_id. Slice ranges remain offsets in the original universal file. No function/type/source recovery. Increase only the reported per-call budget and retry the same artifact; it does not raise parser or MCP delivery limits. Malformed/unsupported inputs fail explicitly.",
inputSchema: inspectGoBinaryInputSchema,
outputSchema: analysisDetailOutputSchemaOf(
goBinarySchema,
+1 -1
View File
@@ -17,7 +17,7 @@ export const GPU_TOOL_CONTRACTS = [
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Inspect static CUDA/HIP GPU code objects in local ELF/PE hosts, CUDA fatbins, CUBIN, PTX and Clang HIP bundles (CUDA LZ4/Zstd and CCOB v1/v2/v3 zlib/Zstd). Default inventory reads directories; full-file SHA-256 always streams every byte. analysis kernels decodes only selected object_ids/targets (object_ids require expected_sha256 from their inventory), retaining all inventory rows and explicit partial/unknown states. Reports PTX virtual registers, CUBIN physical registers/nv.info parameters/shared memory and AMDGPU MessagePack kernel declarations separately. No GPU tools, target execution, network, SASS disassembly or host launch correlation. Unsupported CUDA compression retains encoded locations. Default summary retains complete Evidence; optional view returns a selected targets/objects/kernels page or PTX text page in this call. inspect_analysis_view kind gpu-code-objects reuses retained facts without reopening files; PTX text uses UTF-16 code-unit pages. Object IDs are positional within artifact.sha256. One active inspection; 128 MiB/object, 512 MiB decoded work, 16 MiB retained facts. Full Evidence includes selected PTX text artifacts with SHA-256 and encoded/decoded provenance.",
"Inspect CUDA/HIP code objects in local ELF/PE, fatbins, CUBIN, PTX or Clang HIP bundles without GPU tools or target execution. Default inventory hashes the full file; analysis kernels decodes selected object_ids/targets, with object_ids requiring the inventory expected_sha256. IDs are positional within that digest. Returns distinct PTX/CUBIN/AMDGPU kernel declarations, encoded/decoded provenance and explicit partial/unknown coverage; unsupported compression retains encoded locations. Default summary retains complete Evidence. Optional view selects targets/objects/kernels or PTX text; inspect_analysis_view kind gpu-code-objects pages retained facts without reopening (PTX offsets are UTF-16 units). No SASS disassembly, host-launch correlation or network; decoded-work/retention limits remain independent of selection.",
inputSchema: inspectGpuCodeObjectsInputSchema,
outputSchema: evidenceResultOf(
z.union([
+1 -1
View File
@@ -16,7 +16,7 @@ export const IL2CPP_TOOL_CONTRACTS = [
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Inspect local Unity IL2CPP metadata (24/27/29/31/39), optionally linking a caller-selected 64-bit little-endian Mach-O, PE or ELF binary. Static reading only. Default summary retains complete Evidence; use parent_evidence_id with inspect_analysis_view kind il2cpp-metadata for named collections, indices, fields and paging. Parameters accept method_indices; method_addresses accept addresses and states. Stable row indices are scoped to the metadata digest; native pages also identify the binary. Native states distinguish executable code, observed zero slots (no-body), and unknown owners/relocations. Shared addresses preserve all methods. code_gen_modules pages accept image_indices; summaries omit that table. Type names are C#-like; version27 retains indices with unknown names. generic_instances adds genericMethodTable rows with Il2CppDumper-style names (versions 27/29/31, static CodeRegistration and MetadataRegistration); generic_method_instances pages accept method_indices, addresses and states; summaries count issues, paged as generic_method_issues. Unrequested native counts are null. Static-table links are derived; the x86-64/arm64 executable-byte fallback is inferred and does not verify instruction boundaries. Input guards:256MiB metadata/1GiB binary;64MiB encoded report; one active inspection. Unsupported layouts, pointer encodings and resource limits have typed reasons. Full Evidence remains available with detail complete. Neither static linking nor structural agreement proves runtime behavior or a same-build pair.",
"Inspect Unity IL2CPP metadata versions 24/27/29/31/39, optionally linking a selected 64-bit little-endian Mach-O/PE/ELF binary without execution. Returns metadata tables and derived native method links; shared addresses retain every method, zero slots mean no-body, and unknown ownership/relocations stay unknown. Default summary retains complete Evidence for inspect_analysis_view kind il2cpp-metadata using parent_evidence_id, named collections, original indices, fields and pages. Unrequested native counts are null; version27 names may be unknown. generic_instances adds supported static registration-table matches for versions 27/29/31. Executable-byte fallback is inferred and does not verify instruction boundaries. Full detail remains available; static agreement proves neither same-build pairing nor runtime behavior. Resource/unsupported-layout failures name their reasons.",
inputSchema: inspectIl2cppMetadataInputSchema,
outputSchema: evidenceResultOf(
z.union([il2cppMetadataSchema, il2cppMetadataSummaryViewResultSchema]),
@@ -111,7 +111,7 @@ export const ELECTRON_TOOL_CONTRACTS = [
name: "analyze_javascript_application",
...toolContractMetadata("analyze_javascript_application"),
description:
"Reconstruct one local ASAR or extracted JavaScript application as an inline application graph without executing it. Returns recovered graph nodes, edges, semantic relations, integrity contradictions, limitations, and coverage. Select source_paths to acquire and analyze only exact inventoried file paths; the complete artifact inventory and identity remain intact, and unselected sources remain explicit unknowns. Dependencies are not implicitly analyzed. Select detail summary to retain the complete analysis Evidence in this session and receive only its summary view, then inspect selected modules or pages with inspect_analysis_view. Select a javascript-routes view with summary detail to query deduplicated static patterns, source-linked occurrences, source status or interpretation gaps with filters, fields and paging. Static routes do not establish reachability or the full application route set. Summary detail reduces delivery, whereas source_paths bounds source analysis. Integrity mismatches fail by default; record-and-continue retains observed bytes as untrusted and marks graph coverage partial. Timeout recovery: returned provider_timeout uses the per-source analysis_timeout_ms budget. A host-only 'timed out awaiting tools/call' needs a longer client tool deadline, not a larger analysis_timeout_ms. Never repeat the unchanged call to test whether that timeout persists; report the host setting if configuration is not editable (Codex: mcp_servers.<server>.tool_timeout_sec, seconds).",
'Build a static application graph from a local ASAR or extracted JavaScript app without executing it. Supply input_path, e.g. {input_path:"/apps/client",source_paths:["main.js"],detail:"summary"}. Copy source_paths exactly from the inventory, not host-absolute paths inferred from input_path. Returns nodes, edges, semantic relations, integrity contradictions, coverage and unknowns. source_paths limits source analysis to exact inventoried paths without narrowing inventory or artifact identity; dependencies are not implicitly analyzed and unselected sources remain unknown. detail summary reduces delivery, retaining complete Evidence for inspect_analysis_view; it does not reduce analysis. With summary detail, view {kind:"javascript-routes",collection:"routes",offset:0,limit:64} selects static route patterns; static routes do not prove reachability or the complete route set. Integrity mismatches fail by default; record-and-continue retains untrusted observed bytes and partial coverage. analysis_timeout_ms is a per-source provider budget. A host-only timeout needs a longer client deadline, not that budget; do not repeat unchanged work or assume it stopped. If configuration cannot be edited, report the host setting (Codex: mcp_servers.<server>.tool_timeout_sec, seconds).',
kind: "electron-provider",
inputSchema: analyzeJavaScriptApplicationRequestSchema,
outputSchema: applicationOutputSchema,
@@ -160,7 +160,7 @@ export const ELECTRON_TOOL_CONTRACTS = [
name: "capture_electron_scenario",
...toolContractMetadata("capture_electron_scenario"),
description:
"Use this for a provider-owned Electron run when passive CDP or Inspector observation cannot exercise application behavior. REA owns startup and teardown, accepts caller-defined click/wait actions plus window-targeted renderer reload/crash and synthetic open-url/second-instance delivery, and returns correlated window/WebContents/process/preload/session/navigation/shell/IPC evidence without retaining payload values. Actions wait for completion or request cancellation; a missing click target can keep the request pending. Results identify observed and unavailable event families, coverage status, action targets, and truncation. Cleanup failures retain collected observations with explicit cleanup uncertainty. External shell, navigation, permission, download, popup, updater, and OS-integration effects are blocked and recorded. Use passive Electron tools for observation-only work.",
"Launch and exercise an owned Electron app when passive CDP/Inspector observation cannot answer the question. REA owns startup/teardown; selected click/wait, renderer reload/crash and synthetic open-url/second-instance actions change runtime behavior. Returns correlated window/WebContents/process/preload/session/navigation/shell/IPC observations without payload values, plus action targets and coverage/truncation. Actions wait for completion or cancellation; a missing click target can remain pending. External shell, navigation, permission, download, popup, updater and OS-integration effects are blocked and recorded. Cleanup failures retain observations with explicit uncertainty. Use inspect_electron_page or observe_javascript_runtime for passive observation.",
kind: "electron-provider",
inputSchema: electronActiveObservationInputSchema,
outputSchema: evidenceResultOf(electronActiveObservationResultSchema),
@@ -13,7 +13,7 @@ export const JAVASCRIPT_RECOVERY_TOOL_CONTRACTS = [
...toolContractMetadata("recover_javascript_sources"),
kind: "application",
description:
"Recover readable modules from local UTF-8 JavaScript scripts/bundles into an absent directory, using caller-supplied Wakaru ^1.13.0 (verified with 1.14.0) on Linux x64. Use additional_paths for related chunks; each input retains its own snapshot and provenance. Returns original/derived digests, extraction byte ranges, emitted source maps, warnings and analysis_input inline. Structural splitting may fall back to one module; original names and runtime equivalence remain unknown. No application code execution. Requires util-linux prlimit; one worker, 1 GiB address-space ceiling, 120-second deadline, 64 MiB total input, 128 MiB output, 10000 entries and 8 MiB per diagnostic/report stream.",
"Recover readable modules from local UTF-8 JavaScript bundles into an absent output_directory, without executing application code. Requires caller-supplied Wakaru ^1.13.0 (verified 1.14.0), Linux x64 and util-linux prlimit. additional_paths includes related chunks, preserving each input’s snapshot/provenance. Returns original/derived digests, extraction ranges, source maps, warnings and analysis_input for analyze_javascript_application. Splitting may fall back to one module; original names and runtime equivalence remain unknown. One worker has a fixed 120-second deadline and bounded input/output/report admission; limit failures are explicit and roll back output.",
inputSchema: javascriptRecoveryInputSchema,
outputSchema: evidenceResultOf(javascriptRecoveryResultSchema),
examples: [
@@ -33,7 +33,7 @@ export const JAVASCRIPT_RUNTIME_OBSERVATION_TOOL_CONTRACTS = [
name: "observe_javascript_runtime",
...toolContractMetadata("observe_javascript_runtime"),
description:
"Attach passively to one Node/Electron V8 Inspector target by supplying its loopback Inspector endpoint and target ID. The provider rechecks target presence and attachability; a Node discovery file location may remain unresolved. Loaded script locations are validated independently from Debugger.scriptParsed. Authorized file script items retain their exact Inspector URL in optional reported_url separately from verified location.file_path, and query/fragment variants remain distinct script identities. Valid Debugger.scriptFailedToParse events are counted at scripts.parse_failed_total separately from malformed protocol values. Captures script and Runtime execution-context metadata. REA never evaluates, pauses, resumes, reads source, or instruments the target; require/import edges, EventEmitter activity, and Electron IPC remain explicit unknowns. Reconcile the result with static Application Graph Evidence using reconcile_javascript_runtime. The selected endpoint exposes every target it serves to this tool.",
"Passively observe loaded-script and execution-context metadata on one loopback Node/Electron V8 Inspector target, selected by inspector_endpoint and target_id. Presence/attachability and file locations are rechecked; verified file paths stay separate from reported URLs, including distinct query/fragment identities. Parse failures are counted separately from malformed events. REA does not read source, evaluate, pause/resume or instrument execution; imports, EventEmitter activity and Electron IPC remain unknown. Use reconcile_javascript_runtime with static application Evidence. The selected endpoint exposes every target it serves to this tool.",
kind: "runtime-provider",
inputSchema: observeJavaScriptRuntimeInputSchema,
outputSchema: evidenceResultOf(javascriptRuntimeObservationSchema),
@@ -65,7 +65,7 @@ export const MANAGED_TOOL_CONTRACTS = [
retainedSummary: { evidenceParameters: "omit-detail" },
...toolContractMetadata("inspect_managed_artifact"),
description:
'Inspect an explicit PE/CLI path, or the selected managed target, without loading or executing target code. Omitted or complete detail returns complete metadata inventories with original coverage. Select detail: "summary" on the first call for complete identity, PE/CLI, classification with its evidence, module/MVID, assembly, frameworks, returned-collection counts, coverage/issues and limitations. It retains complete Evidence and returns a distinct linked inspect_analysis_view summary. Page original references/resources/attributes with view kind managed and normalized_result.parent_evidence_id. Counts cover producer-returned rows; partial, unavailable or malformed metadata remains explicit and tokens remain build-local.',
"Inspect PE/CLI identity, classification and metadata inventories from an explicit path or selected managed target without loading or executing code. Default complete returns all producer facts; detail summary retains them and returns identity, assembly/MVID, frameworks, coverage and counts. Page references/resources/attributes with inspect_analysis_view kind managed and normalized_result.parent_evidence_id. Counts cover returned rows; partial, malformed and unavailable metadata stay explicit. Tokens are build-local. Use inspect_managed_members for methods, signatures and CIL anchors.",
kind: "managed-provider",
inputSchema: managedArtifactInputSchema,
outputSchema,
@@ -86,7 +86,7 @@ export const MANAGED_TOOL_CONTRACTS = [
retainedSummary: { evidenceParameters: "omit-detail" },
...toolContractMetadata("inspect_managed_members"),
description:
'Inspect PE/CLI metadata members, signatures, raw CIL hashes, decoded-instruction-tuple hashes, separately reported exception regions, call edges, field-access anchors, and the #US string literals that ldstr loads, without loading or executing target code. Select type_names to decode only the members of those exact declaring types and the literals their bodies load, which keeps large assemblies such as a base class library within the representation budget. Metadata tokens are reported as build-local coordinates bound to the artifact SHA-256 and MVID; the tuple hash does not resolve them or fully commit control flow. Omitted or complete detail returns every collection, including the assembly-wide member_refs and exported_types, which type_names does not narrow. Select detail: "summary" for identity, metadata status, selection with unmatched names, coverage/issues, limitations and per-collection counts; it retains complete Evidence and returns a linked inspect_analysis_view summary. Page original rows with view kind managed-members, normalized_result.parent_evidence_id and collection types/exported_types/fields/methods/member_refs/call_edges/field_accesses/user_strings. Filter retained members by exact names/declaring_types and select fields; omit body to avoid returning IL anchors.',
"Inspect PE/CLI types, members, signatures, CIL hashes/instruction tuples, exception regions, static calls, field accesses and loaded #US strings without executing code. type_names selects exact declaring types and their body literals; assembly-wide member_refs/exported_types are still included. Tokens remain local to artifact SHA-256/MVID; tuple hashes do not resolve them or fully commit control flow. Default complete returns collections; detail summary retains them for inspect_analysis_view kind managed-members using parent_evidence_id. Page types/exported_types/fields/methods/member_refs/call_edges/field_accesses/user_strings; exact names/declaring_types and fields narrow supported rows. Omit body to avoid IL anchors. Unmatched names and incomplete coverage stay explicit.",
kind: "managed-provider",
inputSchema: managedMembersInputSchema,
outputSchema: memberOutputSchema,
@@ -37,7 +37,7 @@ export const MANAGED_WORKFLOW_TOOL_CONTRACTS = [
name: "compare_managed_members",
...toolContractMetadata("compare_managed_members"),
description:
"Compare two authenticated inspect_managed_members Evidence records, supplied inline or by exact retained reference, using unique-only tiers: exact declared type, name, and CIL/signature; exact declared type, name, and signature (decoded or not); exact declared type, name, and decoded structural method shape; then exact CIL/signature or decoded structural method shape alone, which never takes a member whose own declared type and name remain unpaired on the other side or whose declaring type is unresolved. Signatures compare type operands by name, not by build-local metadata row. Names alone are never a matching basis; a member whose signature was not decoded, or whose same-named counterpart's was not, stays unknown rather than added or removed. Matched methods also compare aligned call-site shapes and observed target declaring-type/method names; missing or unaligned call edges and target names remain unknown. These static names do not prove overload identity or runtime dispatch. Metadata tokens remain build-local coordinates bound to each artifact SHA-256 and MVID, and the tuple digest does not itself remap them.",
"Compare two authenticated inspect_managed_members Evidence records, inline or retained, using unique exact type/name/signature/CIL or decoded structural matches. Names alone never establish correspondence; undecoded signatures, unresolved declaring types and ambiguous candidates remain unknown rather than added/removed. Structural cross-name matching cannot consume a member whose own type/name counterpart remains unpaired. Matched methods compare aligned call-site shapes and observed target names; unaligned or missing facts stay unknown. Tokens remain local to each artifact SHA-256/MVID; tuple hashes do not remap them. Static call names do not prove overload identity or runtime dispatch.",
kind: "application",
inputSchema: compareManagedMembersRequestSchema,
outputSchema: comparisonOutputSchema,
+1 -1
View File
@@ -15,7 +15,7 @@ export const INSPECT_MODEL_ARTIFACT_CONTRACT = {
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Inspect local GGUF v2/v3 or safetensors declarations by content, without loading models or executing code. Default hash header reads only the header: full-file SHA-256 and Evidence subject are unknown; artifact.header_sha256 is a scoped prefix commitment, not weight identity. hash full additionally streams all file bytes for SHA-256. Optional view returns a selected metadata/tensor/type page plus model context in this call. Summary retains complete Evidence for inspect_analysis_view kind model-artifact; its pages support selection, stable header-scoped indices and paging. Metadata arrays retain eight-element typed previews; scalar metadata is complete. Tensor counts, shapes, numeric type IDs and offsets are observed; textual types and parameter/storage totals use established format facts. Unknown or historically ambiguous GGUF types retain IDs with unknown nonempty byte lengths; ambiguous identities use AMBIGUOUS_<id> labels. Unresolved Q8_1 and K-block layouts also keep nonempty byte lengths unknown. Tensor payload, model behavior and inference quality are not inspected. One active inspection, 100 MB header ceiling and 32 MiB retained-facts budget; resource refusals are explicit. No network, external files, Python, model runtime, extraction or deserialization of pickle.",
'Inspect GGUF v2/v3 or safetensors metadata and tensor declarations without loading weights or running inference. Default hash header commits only a prefix: full-file SHA-256 and Evidence subject remain unknown; hash full streams every byte for file identity. Tensor shapes/IDs/offsets are observed; textual types and totals are derived, with ambiguous layouts retaining unknown byte lengths. Metadata arrays are eight-element previews; scalar metadata is complete. Default summary retains complete Evidence; detail complete returns all declarations inline. Optional view selects metadata/tensors/types. To page retained tensors, use inspect_analysis_view with source:{kind:"retained-evidence",evidence_id:"<parent_evidence_id>"} and view:{kind:"model-artifact",collection:"tensors",offset:0,limit:32}. No payload inspection, quality claim, network, model runtime or pickle deserialization; one inspection at a time with explicit resource refusals.',
inputSchema: inspectModelArtifactInputSchema,
outputSchema: evidenceResultOf(
z.union([
@@ -130,7 +130,7 @@ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_binary_hardening"),
kind: "native-provider",
description:
"Inspect compile-time and link-time hardening of one explicit local ELF, PE, or Mach-O file, including one image per universal Mach-O slice. Reports PIE or ASLR, NX, RELRO, stack-protector signs, FORTIFY signs, control-flow flags and stripped state, each with the header field or import behind it. States are enabled, disabled, partial, unknown, or not_applicable. A missing import in a static or stripped image is unknown, not disabled. Authenticode and Mach-O code-signature rows report table or load-command presence, not validity. Mach-O hardened runtime stays unknown and names inspect_signature. This inspection states that it does not execute the image and does not assess exploitability. Reads a stable regular file. A malformed header returns no partial report, except one bad slice in a universal Mach-O. A symbol table, symbol name, or GNU property note over its budget leaves those rows unknown and keeps the header rows. A dynamic-table budget still fails the ELF report.",
"Inspect static hardening declarations in a local ELF, PE or Mach-O, including every universal slice. Reports PIE/ASLR, NX, RELRO, stack-protector/FORTIFY signs, control-flow flags and stripped state with supporting header/import facts. Missing signs may be unknown, especially for static/stripped images. Signature presence does not establish validity; use inspect_signature for Mach-O hardened runtime. No target execution or exploitability claim. Malformed headers/budgets may fail; limited symbol/property-note reads retain header facts and mark affected rows unknown.",
inputSchema: inspectBinaryHardeningInputSchema,
outputSchema: evidenceResultOf(binaryHardeningSchema),
examples: [
@@ -146,7 +146,7 @@ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_native_initializers"),
kind: "native-provider",
description:
"List the initializer and finalizer functions declared by one explicit local ELF32/ELF64 or Mach-O image (thin, or one selected universal slice) without executing it or opening a disassembler. ELF: DT_PREINIT_ARRAY, DT_INIT, DT_INIT_ARRAY, DT_FINI, DT_FINI_ARRAY and legacy .ctors/.dtors, with section fallback for relocatable and static images. Mach-O: S_MOD_INIT_FUNC_POINTERS, S_INIT_FUNC_OFFSETS and S_MOD_TERM_FUNC_POINTERS. Each paged entry gives the slot address and file offset, the resolved target address, file offset, containing section, an exact-address symbol name when one exists, and how the value was resolved (raw, RELATIVE addend, RELR, symbol plus addend, chained fixup, offset table, or unresolved import). Slots that relocations or fixups do not establish are reported unresolved, never as their stored zero. A missing tag or section is observed absence of that declaration, not proof that no code runs before main.",
"List declared initializer/finalizer functions in a local ELF32/64 or selected Mach-O slice without execution. Returns paged slots and resolved target addresses/file offsets, sections, exact symbols and resolution basis from dynamic tags, constructor sections, relocations and fixups. Unestablished slots remain unresolved, never treated as stored zero targets. Missing declarations do not prove no code runs before main.",
inputSchema: inspectNativeInitializersInputSchema,
outputSchema: evidenceResultOf(nativeInitializersSchema),
examples: [
@@ -177,7 +177,7 @@ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_elf_unwind_ranges"),
kind: "native-provider",
description:
"Inspect one explicit local ELF32/ELF64 image's .eh_frame and .eh_frame_hdr without executing it or opening a disassembler. Returns a page of FDE function ranges with start, end, size, containing section, exact symbol name when one exists, CIE index, LSDA, and personality, plus version, augmentation, alignments, return-address register, and pointer encoding for only the CIEs those ranges name, with a total CIE count in coverage. Coverage counts ranges that match a symbol, ranges without a symbol, and whether the .eh_frame_hdr search table agrees with the decoded FDEs. .debug_frame is reported present, absent, or incomplete and is not decoded. A missing unwind table is observed absence of those declarations, not proof the image has no functions. Truncated records stay incomplete coverage. Reads a stable regular file; malformed ELF headers and exhausted CIE or FDE budgets return no partial success. CFA instructions are counted and not evaluated. Indirect EH pointers are not dereferenced. Portable on supported Node hosts.",
"Inspect ELF32/64 .eh_frame and .eh_frame_hdr for paged FDE function ranges, associated CIE facts, LSDA/personality pointers, symbol matches and search-table agreement. No execution or disassembler. Missing unwind declarations do not prove no functions; truncated records remain incomplete. .debug_frame is detected but not decoded, CFA instructions are not evaluated, and indirect EH pointers are not dereferenced. Malformed headers or exhausted CIE/FDE budgets fail without partial success.",
inputSchema: inspectElfUnwindRangesInputSchema,
outputSchema: evidenceResultOf(elfUnwindRangesSchema),
examples: [
@@ -192,7 +192,7 @@ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_apple_ips"),
kind: "native-provider",
description:
"Inspect one explicit local Apple .ips crash report without executing a target, launching atos, or opening a disassembler. Parses the first-line metadata object and, when bug_type is the string 309, the crash body: process identity, exception and termination facts, threads, usedImages, lossless integer registers, and deterministic classification from documented SIGKILL, EXC_GUARD, pointer-authentication and dyld strings. Other bug_type values, including 288 stackshots, return no crash result. A missing or truncated body fails without partial success. With join_path, every frame whose image UUID and architecture match a slice LC_UUID reports the slice static __TEXT vmaddr plus its image offset as a static address; symbolication and dSYM symbol lookup remain unobserved. Portable on supported Node hosts; no Xcode or pwntools required.",
"Inspect a local Apple .ips crash report for process, exception/termination, thread, image and lossless register facts with deterministic classification. Crash parsing supports bug_type string 309; other types, including 288 stackshots, return no crash result. join_path derives static addresses only when image UUID and architecture match a Mach-O slice; it does not symbolicate or read dSYMs. Missing/truncated bodies fail without partial success. No target execution, atos, disassembler or Xcode required.",
inputSchema: inspectAppleIpsInputSchema,
outputSchema: evidenceResultOf(appleIpsSchema),
examples: [
@@ -214,7 +214,7 @@ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_kernel_module"),
kind: "native-provider",
description:
"Inspect one explicit local ELF32/ELF64 ET_REL Linux kernel module without executing it or opening a disassembler. Returns ordered .modinfo key/value entries (duplicates preserved), __versions symbol CRCs, presence of .gnu.linkonce.this_module and __ksymtab sections, observed .init.text and .exit.text sizes, and an appended module signature trailer with its module_signature fields plus a PKCS#7 byte range and SHA-256. Does not execute the module, decode struct module, or validate certificates. A missing section is observed absence when section names are known, not proof the module never carried that metadata. Other ELF types are not applicable. gzip, xz, and zstd containers are unsupported and name external_decompression as the next probe; neither this tool nor extract_artifact decodes those codecs, so decompress with an external utility and inspect the result. Reads a stable regular file; malformed ELF headers and exhausted entry budgets return no partial success. Portable on supported Node hosts.",
"Inspect an uncompressed local ELF32/64 ET_REL Linux kernel module for ordered .modinfo entries, symbol CRCs, module/export/init/exit section facts and appended signature ranges/digests. No execution, struct module decoding or certificate validation. Missing known sections describe this image only. gzip/xz/zstd require external decompression; extract_artifact does not decode those module containers. Malformed headers or exhausted entry budgets fail without partial success. Portable on supported Node hosts.",
inputSchema: inspectKernelModuleInputSchema,
outputSchema: evidenceResultOf(kernelModuleSchema),
examples: [
@@ -230,7 +230,7 @@ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_kernel_build_config"),
kind: "native-provider",
description:
"Inspect one explicit local Linux kernel image (vmlinux ELF, raw arm64 Image, x86 bzImage/zImage, or configs.ko) without executing it or opening a disassembler. Returns the `Linux version` banner split into version, builder, and compiler, and the embedded CONFIG_IKCONFIG build config: option count, SHA-256 of the inflated text, and paged CONFIG_* entries with value kind (y, m, string, number, not_set), optionally filtered by exact name. A config is accepted only when IKCFG_ST is immediately followed by a gzip member that inflates to config text and is immediately followed by IKCFG_ED, so an ordinary IKCFG_ST string is not a config. A bzImage gzip payload located through the setup header is inflated with a bounded output budget and searched; xz, lz4, lzma, zstd, bzip2, and lzo payloads are named as unsupported with external_decompression as the next probe. Truncated payloads and gzip members are incomplete, not absent. Reads a stable regular file; exhausted budgets return no partial success. Portable on supported Node hosts.",
"Inspect a local Linux kernel image (vmlinux, raw arm64 Image, x86 bzImage/zImage or configs.ko) for the version/builder/compiler banner and embedded CONFIG_IKCONFIG. Returns config digest/count and paged, optionally exact-name-filtered CONFIG_* values. Only validated marker-framed gzip config is accepted; a literal marker is insufficient. Supported gzip bzImage payloads are searched; other compressed payloads require external decompression. Truncation is incomplete, not absence; budget exhaustion fails without partial success. No target execution or external tools.",
inputSchema: inspectKernelBuildConfigInputSchema,
outputSchema: evidenceResultOf(kernelBuildConfigSchema),
examples: [
@@ -277,7 +277,7 @@ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_pe_certificates"),
kind: "native-provider",
description:
"Inspect one explicit local PE32/PE32+ image's IMAGE_DIRECTORY_ENTRY_SECURITY table without executing it, verifying signatures or opening a disassembler. Returns WIN_CERTIFICATE file ranges, types and payload SHA-256, plus structurally decoded PKCS#7 signedData digest algorithms, embedded X.509 serial/issuer/subject/validity fields and signer identifiers, including a subject key identifier, when type 2 is present. A missing directory is observed absence of that table, not proof the image is unsigned in every catalog or overlay sense. Authenticode digest coverage, chain validity and timestamp trust remain unobserved. Reads a stable regular file; malformed PE headers, truncated WIN_CERTIFICATE entries, X.509 certificates missing subjectPublicKeyInfo or signatureValue, and non-signedData PKCS#7 return no partial success. Portable on supported Node hosts; no Windows SDK or engine installation required.",
"Inspect a local PE32/PE32+ certificate directory without executing it or verifying signatures. Returns WIN_CERTIFICATE ranges/types/digests and structurally decoded PKCS#7 signer, algorithm and X.509 identity fields when present. Missing directory does not establish globally unsigned status. Authenticode digest coverage, trust chains and timestamp validity remain unobserved. Malformed/truncated structures and unsupported PKCS#7 signed-data shapes fail without partial success. No Windows SDK or disassembler required.",
inputSchema: inspectPeCertificatesInputSchema,
outputSchema: evidenceResultOf(peCertificatesSchema),
examples: [
@@ -292,7 +292,7 @@ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_pe_imports"),
kind: "native-provider",
description:
"Inspect one explicit local PE32/PE32+ image's IMAGE_DIRECTORY_ENTRY_IMPORT and delay-load tables without executing it or opening a disassembler. Returns DLL names, named and ordinal functions, ILT/IAT RVAs, delay-load descriptors, and the pefile import hash of the standard import table, withheld with a reason when that table is partial or pefile would hash a different row sequence. A missing import directory is observed absence of that table, not proof the image never imported APIs through another table or overlay. Bound snapshots, loaded IAT contents and export-forward resolution remain unobserved. Reads a stable regular file; malformed PE headers and exhausted DLL or function budgets return no partial success. Unreadable names or thunks and descriptors missing a required table are reported as partial coverage with issues. Portable on supported Node hosts; no Windows SDK or engine installation required.",
"Inspect local PE32/PE32+ standard and delay-load imports without execution. Returns DLL/named/ordinal imports, ILT/IAT RVAs, descriptors and a pefile-compatible standard-table import hash only when its row sequence is complete and comparable. Missing declarations do not establish no API use; loaded IAT, bound snapshots and forward resolution remain unknown. Unreadable names/thunks or missing tables yield partial coverage; malformed headers or exhausted budgets fail. No Windows SDK or disassembler required.",
inputSchema: inspectPeImportsInputSchema,
outputSchema: evidenceResultOf(peImportsSchema),
examples: [
@@ -307,7 +307,7 @@ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_windows_shortcut"),
kind: "native-provider",
description:
"Inspect one explicit local Windows Shell Link (.lnk) file without resolving or executing the target, using COM, or opening a network path. Returns ShellLinkHeader flags, FILETIMEs, ShowCommand and hotkey; LinkTargetIDList item count with documented root/drive/file-entry names and raw hashes for unknown items; LinkInfo volume serial, label, local base path and network share names; StringData name, relative path, working directory, arguments and icon location; and ExtraData blocks including EnvironmentVariable, IconEnvironment, Tracker droid/MAC facts labelled derived, KnownFolder, SpecialFolder, ConsoleFE code page, and PropertyStore raw hashes. Unknown ExtraData signatures are listed. Derived observations cover argument presence and length, target extension, minimized ShowCommand, and an icon location that differs from the target. Reads a stable regular file; malformed HeaderSize or CLSID, exhausted budgets, and odd Unicode lengths return typed failures or partial coverage with the failing offset, never a complete partial inventory. Portable on supported Node hosts; no Windows SDK or engine installation required.",
"Inspect a local Windows Shell Link (.lnk) without resolving or executing its target, COM, or network access. Returns header/time/display facts, target-ID/link-info paths, arguments, working directory/icon and ExtraData observations, with raw hashes for unknown structures. Tracker and behavioral observations are derived. Malformed structures, odd Unicode lengths or exhausted budgets return typed failures or explicitly partial coverage with the failing offset. No Windows SDK required.",
inputSchema: inspectWindowsShortcutInputSchema,
outputSchema: evidenceResultOf(windowsShortcutSchema),
examples: [
@@ -322,7 +322,7 @@ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_pe_resources"),
kind: "native-provider",
description:
"Inspect one explicit local PE32/PE32+ image's complete bounded type/name/language resource tree without executing it or opening a disassembler. Returns numeric IDs versus original UTF-16 names, directory identity paths including empty branches, directory/data-entry file locations, payload RVA/file ranges, complete SHA-256 hashes and static RT_GROUP_ICON image-resource candidates. Language fallback, image decoding and actual shell/window loading remain unobserved. Reads a stable regular file; malformed or ambiguous mappings, non-identical overlapping ranges and exhausted budgets return no partial success. Portable on supported Node hosts; no Windows SDK or engine installation required.",
"Inspect a local PE32/PE32+ resource tree without execution: type/name/language identities, empty branches, UTF-16 names, payload RVA/file ranges/digests and static group-icon candidates. Language fallback, image decoding and actual UI loading remain unknown. Malformed/ambiguous mappings, non-identical overlaps or exhausted budgets fail without partial success. No Windows SDK or disassembler required.",
inputSchema: inspectPeResourcesInputSchema,
outputSchema: evidenceResultOf(peResourcesSchema),
examples: [
@@ -337,7 +337,7 @@ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_native_exports"),
kind: "native-provider",
description:
"Inspect one explicit local PE or ELF image's export table without executing it or opening an engine: PE export-directory names, ordinals, addresses and forwarders, or ELF defined default/protected global, weak and unique .dynsym symbols with type, binding and symbol version. Ordinal-only, forwarded and hidden-version exports stay distinct. Portable on any supported host. Coverage is partial when table entries are unreadable and unsupported when ELF dynamic symbols cannot be enumerated from the available section metadata; an empty complete inventory means the image declares no exports. Mach-O exports use inspect_macho. Omitted/complete detail preserves inline delivery. Select detail summary to retain complete Evidence and return identity, counts and source coverage. Query inspect_analysis_view kind native-exports, collection exports or issues, with exact names/original indices, fields and matching-row pagination. Names return every version or alias; source_index is scoped to the parent Evidence. ELF name projections keep raw-byte and encoding qualifications.",
"Inspect PE/ELF exports without execution or an analysis engine; use inspect_macho for Mach-O. Returns named/ordinal/forwarded PE exports or defined ELF dynamic symbols with binding/type/version, preserving aliases, hidden versions and raw-name qualifications. Unreadable entries are partial; unavailable ELF section metadata can make enumeration unsupported. An empty complete inventory means no declared exports. detail summary retains full Evidence for inspect_analysis_view kind native-exports, collection exports/issues, with exact names/indices, fields and paging; source_index is parent-scoped.",
inputSchema: inspectNativeExportsRequestSchema,
outputSchema: analysisDetailOutputSchemaOf(
nativeExportsSchema,
@@ -355,7 +355,7 @@ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_binary_layout"),
kind: "native-provider",
description:
"Inspect an explicit local binary without launching it as a host process. Returns file-backed section/segment ranges, linked addresses, original symbol/REL/RELA table identities, complete encoded RELR tables and upstream-derived offsets with unknown per-word locations/addends, raw name bytes, dependency/interpreter names and static mitigation inferences inline with artifact SHA-256 Evidence. Profile: EXEC/DYN/REL ELF64 x86-64, ELF64 little-endian AArch64, ELF32 i386, ELF32 little-endian ARM and ELF32 little- or big-endian MIPS on Linux x64 via caller-supplied Python with unchanged pwntools 4.15.0, pyelftools 0.33 and Unicorn 2.1.2. Runtime addresses/library paths, overall relocation inventory completeness and complete derived GOT/PLT coverage remain unknown. Zero executable entry values mean absence; relocatable entries are not applicable. Upstream can emulate PLT instructions with Unicorn for derived static maps. Uses bounded complete output and owned temporary files/processes; malformed, unsupported or oversized objects return no partial success. Select detail summary to retain the complete layout Evidence in this session and receive only its summary view, then inspect sections, symbols, mitigations or linkage with inspect_analysis_view. pwntools_timeout_ms is each owned pwntools command's deadline (omitted means 30000 ms, range 1..2147483647, next call). producer_limits selects input/output/diagnostic/file/address-space bytes and CPU seconds for the next call; defaults remain unchanged and inherited tighter OS limits are retained. pwntools_timeout_ms does not raise those independent limits.",
"Inspect static ELF section/segment, symbol, relocation, linkage and mitigation facts with artifact SHA-256 Evidence, without launching the image. Linux x64 requires caller-supplied pwntools 4.15.0/pyelftools 0.33/Unicorn 2.1.2; supports ELF64 x86-64/little-endian AArch64 and ELF32 i386/little-endian ARM/little- or big-endian MIPS. Unicorn may emulate PLT instructions for derived maps. Runtime addresses/paths and complete relocation/GOT/PLT discovery remain unknown; RELR per-word locations/addends can be unknown. detail summary retains full Evidence for layout section/symbol/mitigation/linkage views. pwntools_timeout_ms bounds each command independently of producer_limits and inherited OS limits. Unsupported, malformed or oversized inputs fail without partial success.",
inputSchema: inspectBinaryLayoutRequestSchema,
outputSchema: analysisDetailOutputSchemaOf(
binaryLayoutSchema,
@@ -377,7 +377,7 @@ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_recorded_crash"),
kind: "native-provider",
description:
"Inspect a supplied Linux ELF64 amd64 or AArch64 little-endian core without launching its target or attaching to any live PID. Returns all recorded segments, raw note owners/descriptors and source ranges, every Linux CORE PRSTATUS thread/register and SIGINFO fields inline with SHA-256 Evidence. Historical PID is recorded metadata; current process/file identity, note coverage and signal-thread associations stay unknown. Optionally add derived core-only GDB/pwndbg mapping candidates through explicit BYO configuration; zero map flags mean unknown permissions. Uses the same stable snapshot for both stages, bounded complete output and owned cleanup. Linux x64 host profile: unchanged pwntools 4.15.0/pyelftools 0.33/Unicorn 2.1.2; optional unchanged pwndbg 2026.09.15. No implicit executable/library pairing, GDB command language, host configuration changes or dependency installation. pwntools_timeout_ms is each owned pwntools command's deadline (omitted means 30000 ms, range 1..2147483647, next call). producer_limits selects input/output/diagnostic/file/address-space bytes and CPU seconds for the next call; defaults remain unchanged and inherited tighter OS limits are retained. pwntools_timeout_ms does not raise those independent limits.",
"Inspect a saved Linux ELF64 little-endian amd64/AArch64 core without launching its target or attaching to a live PID. Returns recorded segments, raw notes/ranges, thread registers and SIGINFO as digest-bound Evidence. Historical PIDs do not establish current identity; note coverage and signal/thread joins remain unknown. Optional caller-configured GDB/pwndbg adds core-only mapping candidates from the same snapshot; zero flags mean unknown permissions. Linux x64 requires the documented pwntools profile, with optional pwndbg 2026.09.15. No implicit executable/library pairing, command language or installation. pwntools_timeout_ms and producer_limits control independent per-command budgets; malformed or oversized input fails without partial success.",
inputSchema: inspectRecordedCrashInputSchema,
outputSchema: evidenceResultOf(recordedCrashSchema),
examples: [
+8 -9
View File
@@ -1,4 +1,3 @@
import { MAX_NATIVE_PLIST_NESTING_DEPTH } from "../../domain/apple/plistValue.js";
import { requireOutputSchema } from "../toolOutputSchemaPrimitives.js";
import { z } from "zod";
import { nativeCallObservationInputSchema } from "../../domain/native/nativeCallObservation.js";
@@ -86,22 +85,22 @@ export const swiftSymbolsSchema = z.array(
export const NATIVE_TOOL_CONTRACTS = [
native(
"observe_native_ui",
"Observe an already-running native app by PID and window ID, bound to the active Mach-O target. Captures a bounded accessibility tree and selected-window screenshot; OS permission denial fails without broad capture or target launch. native_ui_deadline_ms is the observation deadline (omitted means 180000 ms, range 1..2147483647, next call). It does not raise the fixed 67108864-byte output allowance or the 180000 ms wait-step cap.",
"Observe one already-running native app window by PID/window ID, bound to the active Mach-O target. Returns a bounded accessibility tree and window screenshot; permission denial does not broaden capture or launch the target. native_ui_deadline_ms sets this call's deadline independently of output and wait-step limits. Use capture_native_ui_scenario to interact.",
nativeUiObservationInputSchema,
),
native(
"capture_native_ui_scenario",
"Run selected-element press, increment/decrement scroll, AXValue text entry and bounded wait steps in one exact native app window. Returns ordered before/after captures and action/capture failures. Actions can change app data, network activity and persistent state; application state is left as-is and restoration is not attempted. native_ui_deadline_ms is the scenario deadline (omitted means 180000 ms, range 1..2147483647, next call). It does not raise the fixed 67108864-byte output allowance or the 180000 ms wait-step cap.",
"Interact with one exact native app window through selected-element press, scroll, AXValue text entry and bounded waits. Returns ordered before/after captures and per-step failures. Actions may change app data, network activity and persistent state; REA leaves that state in place. native_ui_deadline_ms controls the scenario deadline, independently of output allowance and wait-step caps. Use observe_native_ui for observation only.",
nativeUiScenarioInputSchema,
),
native(
"observe_native_calls",
"Launch the active Mach-O as an owned process under LLDB and record each entry into caller-selected functions or Objective-C methods: thread, module, symbol, load and file address, raw argument registers, selector, receiver class and optional caller frames. Every hit auto-continues. No expression is evaluated and no other process is attached. The process is killed when max_events or duration_ms is reached; exit status, captured stdout/stderr, unresolved breakpoints and limitations are returned inline. The process runs with the current user's permissions and may change files, show UI or use the network. A hardened-runtime target needs the get-task-allow entitlement. Select capture_limits before launch to adjust trace bytes/frames, breakpoint metadata, repeated stops, selector reads and retained output; omitted fields keep defaults, and changing them cannot recover an earlier observation.",
"Launch the active Mach-O under LLDB and record selected function/Objective-C method entries; the owned process is killed at max_events or duration_ms. Target execution uses the caller's permissions and may write files, show UI or use network. Hits auto-continue; REA evaluates no expressions and attaches to no other process. Returns addresses, thread/module/symbol, raw argument registers, selector/receiver facts, optional frames, stdout/stderr and limitations. Hardened-runtime targets need get-task-allow. Set capture_limits before launch; later changes cannot recover omitted observations.",
nativeCallObservationInputSchema,
),
native(
"inspect_macho",
"Inspect Mach-O slices, load commands, imports, exports, dependencies, build metadata, segments, sections, permissions, and exact command provenance without launching Hopper. Large frameworks return megabytes of symbols; detail summary retains the complete Evidence and returns slice identity with per-collection counts, then page rows with inspect_analysis_view kind macho. native_command_timeout_ms is each Xcode command's wall clock (omitted means 60000 ms, range 1..2147483647, next call) and is distinct from objdump/rizin command_timeout_ms. It does not raise the fixed 67108864-byte output allowance.",
"Inspect Mach-O slices, load commands, linkage, build metadata, segments/sections and permissions without launching Hopper. Returns command provenance and explicit coverage. detail summary retains complete Evidence for inspect_analysis_view kind macho rather than delivering large symbol lists inline. native_command_timeout_ms bounds each Xcode command, independently of output admission.",
z.object({
detail: analysisDetailSchema
.unwrap()
@@ -115,14 +114,14 @@ export const NATIVE_TOOL_CONTRACTS = [
),
native(
"inspect_signature",
"Inspect the selected Mach-O architecture's code-signing identity, hashes, authorities, designated requirement, entitlements and hardened-runtime state from a temporary digest-verified byte snapshot. Other slices are checked for unsigned state, with their metadata coverage stated separately. Exact command provenance is retained. native_command_timeout_ms is each codesign command's wall clock (omitted means 60000 ms). It does not raise the fixed 67108864-byte output allowance.",
"Inspect the selected Mach-O slice's signing identity, hashes, authorities, requirement, entitlements and hardened-runtime state from a digest-verified snapshot. Other slices are checked for unsigned state with separate metadata coverage. Returns command provenance; native_command_timeout_ms bounds each codesign command independently of output admission.",
z.object({
native_command_timeout_ms: nativeCommandTimeoutField,
}),
),
native(
"inspect_plist",
`Requires an open binary or bundle-resource session; use open_binary or open_bundle_resources first. Parse its Info.plist by default, or select a local plist with path within that session. Supplying path does not open a session. Returns normalized JSON rather than plutil text. native_command_timeout_ms is each file or plutil command's wall clock (omitted means 60000 ms). The 67108864-byte plist input and decode allowances and the ${MAX_NATIVE_PLIST_NESTING_DEPTH}-level nesting allowance have no runtime override. XML sources also require native plutil validation, which can refuse shallower inputs with its own diagnostics. The 4096-byte markup probe is a probe window, not a document cap, and has no runtime override.`,
"Parse Info.plist from an open binary or bundle-resource session, or select path within that session. Use open_binary or open_bundle_resources first; path alone does not open one. Returns normalized JSON. native_command_timeout_ms bounds each file/plutil command, not fixed input/decode/nesting allowances. XML also requires plutil validation and may be refused at a shallower depth; errors name the applicable limit.",
z.object({
path: localPathStringSchema
.optional()
@@ -134,14 +133,14 @@ export const NATIVE_TOOL_CONTRACTS = [
),
native(
"list_architectures",
"List thin or universal Mach-O slices with offsets, sizes, alignment, explicit coverage, and native-tool provenance. native_command_timeout_ms is the lipo wall clock (omitted means 60000 ms). It does not raise the fixed 67108864-byte output allowance.",
"List thin/universal Mach-O slices with file offsets, sizes, alignment, coverage and native-tool provenance. native_command_timeout_ms bounds lipo, independently of output admission.",
z.object({
native_command_timeout_ms: nativeCommandTimeoutField,
}),
),
native(
"demangle_swift",
"Demangle an ordered list of single-line Swift symbols without requiring Hopper. Each input returns demangled, unchanged, or invalid status. An exact underscore input skipped by swift-demangle is invalid with empty output; it does not discard valid companion results. native_command_timeout_ms is the swift-demangle wall clock (omitted means 60000 ms) and does not raise the fixed 67108864-byte output allowance.",
"Demangle an ordered list of single-line Swift symbols without Hopper. Returns demangled, unchanged or invalid for every input; invalid entries do not discard valid companions. native_command_timeout_ms bounds swift-demangle, independently of output admission.",
z.object({
symbols: swiftSymbolsSchema,
native_command_timeout_ms: nativeCommandTimeoutField,
+8 -11
View File
@@ -20,9 +20,6 @@ import { functionInstructionInputSchema } from "./functionInstructionContract.js
import { HOPPER_MEMORY_TOOL_DEFINITIONS } from "./hopperMemoryContracts.js";
import { nativeSearchInput } from "../domain/native/nativeSearch.js";
const hopperRegexDeadline =
"Regex dialect depends on the provider: Ghidra uses Java Pattern; Kuna, IDA and Hopper use ECMAScript Unicode. See binary_session for selected-provider limits. Hopper regex mode uses a cancellable worker. The matching deadline is REA_REGEX_MATCHING_DEADLINE_MS (a positive decimal integer of milliseconds from 1 to 2147483647, default 5000). Unset keeps the default. A deadline failure names the effective milliseconds, source (default or setting), the default, and the maximum, and leaves the API usable. The worker old-generation request is REA_REGEX_WORKER_HEAP_REQUEST_MIB (a decimal integer of mebibytes from 7 to 16384, default 128). Unset keeps the default. A positive Node --max-old-space-size, including NODE_OPTIONS, overrides that request and is not limited by the setting's floor or maximum. A heap failure names the effective request, its source (default or setting), the default, the floor, and the maximum.";
export const decompileAnalysisSelection = z
.enum(["independent_fresh"])
.optional()
@@ -57,12 +54,12 @@ const official = <
export const OFFICIAL_TOOL_CONTRACTS = [
official(
"annotate_native_function",
"Atomically update one function name and/or entry comments, read them back, and return a refreshed complete function dossier. Ghidra resolves an interior address to its containing function and applies edits at the function entry, not at the selected instruction; use procedure_address first to find that entry. Ghidra edits owned Program metadata; original executable bytes remain unchanged. Empty comment text clears that comment. With REA_GHIDRA_CHECKPOINT_DIR configured at startup, normal close saves edits for the next process; ephemeral mode discards them. CLI follows the same setting after returning its updated dossier. Check binary_session capabilities for the current mode. Invalid edits roll back the entire operation. Windows P0 and providers without this capability are unsupported.",
"Atomically rename one function and/or change entry comments, verify readback, and return its refreshed complete dossier. Ghidra resolves interior addresses to function entries; use procedure_address to select the entry explicitly. Edits change analysis metadata, never executable bytes; empty comment text clears it. Invalid edits roll back together. Ghidra checkpoint mode saves on normal close; ephemeral mode discards edits, including in CLI cleanup. Check binary_session for the mode. Windows P0 and providers without this capability are unsupported.",
nativeFunctionAnnotationsInputSchema,
),
official(
"inspect_native_load_image",
"Inspect the provider's measured source digests, memory mappings, relocations, entry points and entry register context. Ghidra relocation symbols are provider observations, not runtime binding proof; older Evidence may not record them. Independent snapshot verification supports DOS MZ, explicitly selected COM, raw binaries and GameCube DOL; other formats retain their observations with unsupported verification. Overlay and uninitialized coverage remain explicit. Select detail summary for verification state and counts, retaining complete Evidence for inspect_analysis_view kind native-load-image: collection source_files, mappings, relocations, entry_points, entry_context, checks or sections, with indices, fields and offset/limit paging. Relocation bytes and check expected/observed payloads require explicit fields; defaults keep metadata. Null collections are unrecorded or inapplicable. Does not execute or modify the target.",
"Inspect provider source digests, loaded mappings, relocations, entries and register context without executing or changing the target. Independent snapshot checks support DOS MZ, selected COM, raw binaries and GameCube DOL; other formats retain observations with unsupported verification. Relocation symbols do not prove runtime binding. detail summary retains complete Evidence for inspect_analysis_view kind native-load-image, collection source_files/mappings/relocations/entry_points/entry_context/checks/sections. Null collections are unrecorded/inapplicable; payload bytes require explicit fields. Overlay and uninitialized coverage remain explicit.",
z.strictObject({ detail: analysisDetailSchema }),
{ evidenceParameters: "omit-detail" },
),
@@ -73,7 +70,7 @@ export const OFFICIAL_TOOL_CONTRACTS = [
),
official(
"inspect_native_instruction",
"Inspect one exact code or data address: decoded bytes, mnemonic, ordered operand tokens, flow, outgoing instruction references and typed incoming references where available. For a byte inside a listed instruction or defined data, Ghidra reports the containing instruction or data object separately, preserving the query and address space. Inspect the starting address of a data object with inspect_native_data_type for its layout; a containing object does not select a field or union member. Incoming references preserve source, access kind, operand index and analysis provenance even at data addresses; they do not prove runtime access. Page retained references with inspect_analysis_view kind native-instruction-references; null coverage means the selected collection was unavailable or not recorded. Memory addressing decomposition is unavailable when the provider supplies only tokens. Ghidra reports in-memory addresses without a listed instruction or defined data as not-in-listing, without attempting a decode.",
"Inspect bytes, mnemonic, operand tokens, flow and typed incoming/outgoing references at one code/data address. Ghidra preserves the query and separately reports a containing listed instruction/data object; unlisted memory is not decoded. References do not establish runtime access, and token-only operands do not establish memory decomposition. Use inspect_native_data_type at a data object's start for layout, without inferring a selected field. Retained references use inspect_analysis_view kind native-instruction-references; null coverage is unavailable or unrecorded.",
nativeInstructionInputSchema,
),
official(
@@ -88,7 +85,7 @@ export const OFFICIAL_TOOL_CONTRACTS = [
),
official(
"comment",
"Read the regular analysis comment at an address, defaulting to the current cursor. This is read-only and returns null when no comment exists; use set_comment to persist a finding.",
"Read the regular analysis comment at an explicit address, or the current cursor where supported. Returns null when absent; use set_comment to write one.",
z.object({ document, address: optionalAddress }),
),
official(
@@ -113,7 +110,7 @@ export const OFFICIAL_TOOL_CONTRACTS = [
),
official(
"inline_comment",
"Read the inline instruction comment at an address, defaulting to the current cursor. Returns null when absent; use set_inline_comment to write one.",
"Read the inline instruction comment at an explicit address, or the current cursor where supported. Returns null when absent; use set_inline_comment to write one.",
z.object({ document, address: optionalAddress }),
),
official(
@@ -216,7 +213,7 @@ export const OFFICIAL_TOOL_CONTRACTS = [
),
official(
"procedure_pseudo_code",
"Decompile one analyzed procedure by symbol name or provider-normalized address. To request a fresh independent attempt, use analysis: independent_fresh when binary_session reports independent_decompile for this provider operation; otherwise it is refused. The independent result may have different analysis context. Ghidra also accepts file-offset:0x... selectors and falls back to a unique source-file mapping when a 0x-prefixed number resolves to no procedure; existing analysis addresses take precedence and ambiguous mappings fail explicitly. A space-qualified address such as ram:0x... avoids that fallback; inspect_native_load_image reports Ghidra's observed default address space. Returns provider-specific pseudocode, never original source or cross-provider text equivalence, and may return null. When supplied, raw_result.pseudocode_absence distinguishes provider-failure from not-in-export; absence of that fact means unknown. Request procedure_assembly when instruction precision matters. Ghidra no-return assumptions may cut the analyzed body; Evidence limitations report observed terminal calls and available callee identities. Select detail summary to retain complete Evidence and receive text availability and counts; inspect_analysis_view summary or native/pseudocode pages read the original observation without decompiling again. Complete remains the default.",
"Decompile one analyzed procedure by symbol or provider-normalized address. Returns provider-specific pseudocode or null, never original source; raw_result.pseudocode_absence distinguishes reported provider-failure from not-in-export, otherwise the cause is unknown. Use procedure_assembly for instruction precision. detail summary retains text for inspect_analysis_view native/pseudocode pages without another decompile; complete is default. analysis: independent_fresh requests a separate attempt only when binary_session advertises independent_decompile; it may use different analysis context. Ghidra accepts file-offset:0x... or unique file offsets when a 0x selector resolves to no procedure; existing analysis addresses take precedence, and space-qualified addresses avoid that fallback. Its terminal-call assumptions may truncate the analyzed body, as limitations report.",
z.object({
procedure,
document,
@@ -233,13 +230,13 @@ export const OFFICIAL_TOOL_CONTRACTS = [
),
official(
"search_procedures",
`Search every analyzed procedure name, including secondary names exact lookup accepts, using literal matching by default or regex when requested. Each procedure appears once under its primary name; matched_aliases lists matching secondary names. Results are deterministic and complete. Ghidra rows retain their reported external and thunk classification. For Ghidra case-insensitive literal searches, raw_result contains unfiltered candidates; normalized_result contains matches. ${hopperRegexDeadline} Select detail summary for counts and retained native-inventory pages; complete remains the default.`,
"Find analyzed procedures by literal name (default) or regex, including accepted secondary names. Returns deterministic provider-inventory matches under primary names with matched_aliases and available thunk/external metadata. For Ghidra case-insensitive literal searches, raw_result retains unfiltered candidates; normalized_result holds matches. detail summary retains native-inventory pages. Regex uses Java Pattern in Ghidra and ECMAScript Unicode in Kuna, IDA and Hopper; binary_session and errors report effective limits and recovery.",
z.object({ ...nativeSearchInput, detail: analysisDetailSchema }),
{ evidenceParameters: "omit-detail" },
),
official(
"search_strings",
`Search every provider-reported string object or candidate using literal matching by default or regex when requested. Results are deterministic and complete over that provider inventory, not every text sequence in artifact bytes. Kuna scans mapped sequences of at least five characters, including unterminated fragments, without computing references. Ghidra reports each defined string's encoding, byte length and termination; it may omit packed or undefined literals, including Rust strings; an empty result does not prove text is absent. For known encoded bytes, Ghidra search_bytes can find byte matches; a hit does not establish a string or use. If an address is known, xrefs can look for references; read_bytes can inspect bytes where supported (not available with Kuna). Hopper retains typed byte decoding, native display, and explicit decoding unknowns. Adjacent long-literal fragments match independently. For Ghidra case-insensitive literal searches, raw_result contains unfiltered candidates; normalized_result contains matches. ${hopperRegexDeadline} Select detail summary for counts and retained native-inventory pages; complete remains the default.`,
"Find provider-reported strings by literal text (default) or regex. Complete results cover that inventory, not all artifact text; packed/undefined strings or independently matched fragments may be missing. Ghidra search_bytes finds known encoded bytes without establishing string identity/use; xrefs inspects references at a known address. Kuna scans mapped sequences of at least five characters without references or read_bytes. Hopper preserves decoded typed objects, display text and decoding unknowns. For Ghidra case-insensitive literal searches, raw_result holds candidates; normalized_result holds matches. detail summary retains native-inventory pages. Regex uses Java Pattern in Ghidra and ECMAScript Unicode elsewhere; binary_session/errors report limits.",
z.object({ ...nativeSearchInput, detail: analysisDetailSchema }),
{ evidenceParameters: "omit-detail" },
),
+1 -1
View File
@@ -27,7 +27,7 @@ export const PCAP_TOOL_CONTRACTS = [
name: "inspect_pcap_capture",
...toolContractMetadata("inspect_pcap_capture"),
description:
"Request detail summary for capture identity/counts, then page retained facts with inspect_analysis_view kind pcap. Default detail complete preserves inline delivery. Inspect one saved pcap or pcapng capture through an owned snapshot: metadata, exact packet count, SHA-256, IPv4/IPv6 address counts, DNS questions and address values from the same single-question response, TLS SNI, protocol distribution and HTTP URIs. All derived inventories are retained within declared resource budgets; unknown DNS attribution and excluded credentials remain explicit. Linux requires util-linux prlimit; Windows uses owned Job Objects. Requires caller-supplied capinfos and tshark; REA never captures traffic.",
"Summarize a saved pcap/pcapng snapshot: exact packet count, SHA-256, IP endpoints, DNS questions/addresses, TLS SNI, protocols and HTTP URIs. Use inspect_packet_capture for caller-selected TShark fields or display filters. Default complete returns full Evidence; detail summary retains it for inspect_analysis_view kind pcap. Unknown DNS attribution and excluded credentials stay explicit. Requires caller-supplied capinfos/tshark and Linux prlimit or Windows Job Objects; never captures live traffic.",
kind: "pcap-provider",
inputSchema: pcapInputSchemas.inspect_pcap_capture.extend({
detail: analysisDetailSchema,
@@ -15,7 +15,7 @@ export const PLAYWRIGHT_TRACE_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_playwright_trace"),
kind: "application",
description:
"Inspect a caller-selected Playwright v10 trace ZIP offline. No browser, replay or recorded-URL requests. Retains action boundaries, console text, network facts and screenshot/body references with archive/member/line identity. No cross-stream total order or complete-capture claim. Credentials use existing HAR/URL projection; context options, most action arguments/results, DOM and resource bytes are not analyzed. Default summary retains complete supported Evidence; view selects events/streams/members/diagnostics with batch IDs, fields and paging. Default text previews cover 256 UTF-16 units; event-text reads further exact text chunks and fields text returns the complete value. Archive/decoded-stream/fact allowances are 256/32/32 MiB; individual lines 4 MiB with bounded JSON node admission. One archive import is admitted at a time per decoder; retained views remain independent. Paging does not increase parsing allowances.",
'Inspect a local Playwright v10 trace ZIP offline, without browser replay or requests to recorded URLs. Returns action boundaries, console/network facts, screenshot/body references and archive/member/line provenance; no cross-stream total order or complete-capture claim. Context options, most action arguments/results, DOM and resource bytes are not analyzed; credentials use HAR/URL projection. Default summary retains supported Evidence. Use view {kind:"playwright-trace",collection:"events",kinds:["network"],limit:10}, or streams/members/diagnostics pages. Text previews cover 256 UTF-16 units; event-text with exact event_id reads further chunks, and fields ["text"] selects full text. Paging does not raise parsing allowances; one archive import is admitted per decoder while retained views remain independent.',
inputSchema: inspectPlaywrightTraceInputSchema,
outputSchema: evidenceResultOf(
z.union([
@@ -31,7 +31,7 @@ export const PYTHON_PYC_TOOL_CONTRACTS = [
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Inspect one explicit local CPython 3.7–3.13 .pyc file with a supported 16-byte header without executing bytecode, invoking CPython or recovering source. Returns the header (magic, pinned python_version, PEP 552 flags, source hash or mtime/size), the top-level code object with nested functions, names, const summaries, and bytecode length/SHA-256. Complete output is the default. detail summary retains the complete Evidence and returns header/coverage. Include an optional python-pyc code_objects view to return selected names/indices/fields in the first call; inspect_analysis_view pages the same retained source later. Every matching display name survives under its parent-scoped source_index; nested_code represents code-constant references, not runtime calls. Marshal is walked with object, depth and string budgets; unsupported magics/layouts, truncated streams and exhausted budgets return no partial success. A recognized 3.14 (3627) or 3.15 (3666) magic is qualified from its packed 16-byte header — the refusal names the observed version and flags — but no marshal code layout is pinned for those versions, so no code object is reported. A decoded header is not proof the matching .py is present. Portable on supported Node hosts; no Python installation required.",
"Inspect local CPython 3.7–3.13 .pyc headers and nested code objects without executing bytecode, invoking Python or recovering source. Returns pinned version/header fields, names, constant summaries and bytecode lengths/digests; nested_code links code constants, not runtime calls. Default complete returns full Evidence; detail summary retains it for inspect_analysis_view kind python-pyc, collection code_objects, with exact names/indices/fields and paging. source_index preserves same-name alternatives. Unsupported layouts, truncation and exhausted budgets fail without partial success. Recognized 3.14/3.15 headers receive a version/flags-qualified refusal, not decoded code objects. A header does not prove matching .py source exists.",
inputSchema: inspectPythonPycRequestSchema,
outputSchema: analysisDetailOutputSchemaOf(
pythonPycSchema,
@@ -17,7 +17,7 @@ export const REVERSE_ENGINEERING_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_with_objdump"),
kind: "native-provider",
description:
"Run a caller-selected objdump command using GNU-style arguments against a local artifact, or request operation=architectures without a path to capture its response to -i. The executable implementation and version are not verified; other implementations may differ in options and output. For operation=disassemble, optional symbol selects native symbol-scoped disassembly before output collection; omission preserves all code sections. Matching and symbol boundaries follow the selected executable. Preserves decoded stdout and stderr inline with SHA-256 Evidence for artifact inspections, up to max_output_bytes (a shared 16 MiB combined limit by default); invalid UTF-8 bytes are represented by replacement characters and flagged in Evidence limitations. output_truncated reports output beyond that limit and completion_status is unknown if buffer enforcement terminated the process. The raw output is authoritative and REA does not claim a stable normalized format. DWARF does not follow local debug links by default. Set follow_debug_links to true to follow them; identities of external debug files are not bound to Evidence. REA clears DEBUGINFOD_URLS for objdump so DWARF processing does not make debuginfod network requests. Default detail complete returns original Evidence. Explicit detail summary retains the complete parent and returns its command observation once, without the raw mirror; parent_evidence_id supports later inspect_analysis_view summary queries and complete Evidence export. Architecture output is subjectless and does not establish support for any artifact. Optional command_timeout_ms is the per-phase wall clock in milliseconds (default 120000, range 1..2147483647); omitted means 120000 and the value applies on the next call. Output admission is selected independently with max_output_bytes; raising it affects the next call without restarting REA and does not raise client receive limits.",
"Inspect a local artifact with caller-selected objdump and GNU-style arguments; the executable implementation/version is unverified. operation disassemble optionally scopes to symbol; omission selects all code sections. operation architectures needs no path and captures -i output without establishing artifact support. Returns authoritative stdout/stderr and artifact SHA-256, with lossy UTF-8 and truncation explicit; there is no stable normalized disassembly format. DWARF debug links are off unless follow_debug_links true; external file identities remain unbound. DEBUGINFOD_URLS is cleared to prevent debuginfod requests. Default complete returns Evidence; summary retains it and returns one command observation for later inspect_analysis_view/export via parent_evidence_id. command_timeout_ms bounds each phase; max_output_bytes independently bounds combined output (16 MiB default). Both apply next call without restart; truncation termination leaves completion unknown, and raising output does not raise client receive limits.",
inputSchema: objdumpInputSchema,
outputSchema: analysisDetailOutputSchemaOf(
commandObservationSchema,
@@ -39,7 +39,7 @@ export const REVERSE_ENGINEERING_TOOL_CONTRACTS = [
...toolContractMetadata("execute_rizin_command"),
kind: "native-provider",
description:
"Execute one caller-selected Rizin command against a local artifact using the Rizin CLI profile that suppresses user settings and scripts while retaining plugins. Preserves decoded stdout and stderr inline with SHA-256 Evidence, up to max_output_bytes (a shared 16 MiB combined limit by default); invalid UTF-8 bytes are represented by replacement characters and flagged in Evidence limitations. output_truncated reports output beyond that limit and completion_status is unknown if buffer enforcement terminated the process. Rizin commands and retained plugins can execute foreign code, mutate files, access the network, and read files outside the selected artifact; identities and contents of those external inputs are not bound to Evidence. Command effects depend on the Rizin command and loaded plugins; JSON is command-specific and raw output remains authoritative. For a raw image, asm_arch, asm_bits and asm_cpu select the decoder and base_address maps file offset 0 there; base_address also passes -n, which skips format loaders even for an ELF, and REA confirms neither. In a shared MCP server, this admitted command closes any active binary-analysis session; after its effects have settled, call open_binary before further analysis. Close an active Ghidra session explicitly first. Optional command_timeout_ms is the per-phase wall clock in milliseconds (default 120000, range 1..2147483647); omitted means 120000 and the value applies on the next call. Output admission is selected independently with max_output_bytes; raising it affects the next call without restarting REA and does not raise client receive limits or a Rizin debugger session deadline.",
"Run one caller-selected Rizin command on a local artifact. Commands/plugins can execute code, mutate files, access network and read outside the artifact; those external inputs are not Evidence-bound. Suppresses user settings/scripts but retains plugins. Raw stdout/stderr is authoritative, JSON is command-specific, and UTF-8 loss/truncation is explicit; output-limit termination leaves completion unknown. For raw images, asm_arch/asm_bits/asm_cpu select decoding and base_address maps offset 0; base_address also passes -n to skip loaders even on ELF, without REA confirming either. An admitted command retires shared binary analysis: close Ghidra explicitly first, then open_binary after effects settle. command_timeout_ms is per-phase and max_output_bytes bounds combined output (16 MiB default); both apply next call without restart and do not raise client receive limits or persistent debugger deadlines.",
inputSchema: rizinInputSchema,
outputSchema: evidenceResultOf(commandObservationSchema),
examples: [
+2 -2
View File
@@ -23,7 +23,7 @@ export const RIZIN_DEBUG_TOOL_CONTRACTS = [
...toolContractMetadata("start_rizin_debug_session"),
kind: "native-provider",
description:
"Start a persistent Rizin debugger session using `-N` to suppress user settings and scripts while retaining plugins, `-0` for NUL framing, and `-d` with an optional caller-selected IO debugger backend. Requires a caller-selected Linux TTY for inferior stdin, stdout and stderr; the target may read from and write directly to that terminal while running and after detach. Before detaching, REA verifies both output destinations, that the target does not hold the debugger command stream, and `dbg.exitkills=false`. Backend and target capabilities depend on the installed build. The session lives in this REA MCP process. Persistent sessions require Linux `/proc` descriptor readback. In a shared MCP server, starting this session retires any active binary-analysis session; after target effects have settled, call open_binary before further analysis. Close an active Ghidra session explicitly first.",
"Start a persistent Rizin debugger for one selected target/backend. Linux and a caller-selected TTY for inferior stdin/stdout/stderr are required; the target may use that terminal after detach. Startup suppresses user settings/scripts while retaining plugins. Detach requires verified output sinks, no target access to the debugger command stream, and dbg.exitkills=false. Capabilities depend on the installed backend. This shared-server operation retires binary analysis: close Ghidra explicitly first, then reopen the binary after effects settle.",
inputSchema: z.strictObject({
path: localPathStringSchema,
inferior_tty: localPathStringSchema,
@@ -45,7 +45,7 @@ export const RIZIN_DEBUG_TOOL_CONTRACTS = [
...toolContractMetadata("rizin_debug_command"),
kind: "native-provider",
description:
"Execute one unrestricted command in a persistent Rizin debugger session. Returns raw output inline with Evidence, including backend output interleaved before the completion marker. If the command exceeds the output-byte, frame-byte, or frame-count limit, `output_truncated` is true and `completion_status` is `unknown`; retained partial output is returned and the owned debugger session is stopped. Evidence names the cap that stopped capture. Unsolicited frames already queued before the command make the session unavailable because correlation is ambiguous. Commands can access local files, shell, network, plugins, and target state; effects depend on the active backend and target. In a shared MCP server, this admitted command closes any active binary-analysis session; after its effects have settled, call open_binary before further analysis. Close an active Ghidra session explicitly first.",
"Run one unrestricted command in a persistent Rizin debugger; it can access target state, plugins, shell, files and network. Returns raw/interleaved session output as Evidence. Output/frame limits stop the owned debugger and retain partial output with output_truncated and unknown completion. Prequeued unsolicited frames refuse the call because correlation is ambiguous. This shared-server operation retires binary analysis: close Ghidra explicitly first, then reopen the binary after effects settle.",
inputSchema: z.strictObject({
session_id: sessionId,
command: z
+1 -1
View File
@@ -17,7 +17,7 @@ export const RUST_TOOL_CONTRACTS = [
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Inspect the cargo-auditable crate dependency list embedded in an explicit local ELF, PE or thin Mach-O image, or the slice of a universal Mach-O named by architecture (read without lipo; artifact stays the universal file, selected_slice records the slice and offsets stay file offsets). Returns the artifact SHA-256, the .dep-v0 section file offset and size, compressed and uncompressed sizes, format version, packages in their original order, the root package index, and dependency edges by index. Omitted or explicit complete detail preserves the full report. Optional detail summary retains that complete Evidence and returns source ranges, counts and parent_evidence_id. Optional view directly selects packages or edges in this call; it cannot be combined with explicit complete detail. Query the same retained facts with inspect_analysis_view kind rust: exact names/versions or package indices, edge from_indices/to_indices, fields and matching-row pagination. Row indices are original and scoped to the parent Evidence; empty filters select none. Default package fields omit dependency vectors; explicitly select dependencies for direct index references. Every matching observed version is retained. No current runtime state is inferred from historical reads. Reads zlib-compressed JSON without installing Rust, opening a disassembler, executing the target, writing temporary files or accessing the network. A missing section is null metadata with a limitation and is not proof that the binary has no dependencies. A rustc commit hash is reported only as an inference when a /rustc/<40-hex>/ path is present in read-only data. Resource guards bound files to 256 MiB, compressed dependency streams to 1 MiB, inflated JSON to the smaller of 8 MiB and 64 times the consumed compressed-stream length, and the complete report to 8 MiB. Malformed, unsupported and oversized inputs receive typed failures rather than partial success.",
"Read the embedded cargo-auditable crate dependencies of a local ELF, PE or selected Mach-O slice without running it or requiring Rust. Returns artifact identity, source ranges, ordered packages and dependency edges. Missing metadata does not prove no dependencies; a rustc commit from an observed source path is inferred. Default complete returns the report; detail summary retains it for inspect_analysis_view kind rust, collections packages/edges, via parent_evidence_id. Optional view selects a page in this call and cannot accompany explicit complete detail. Original row indices and every matching version survive selection; select dependencies explicitly for package dependency vectors. Runtime dependencies remain unknown; malformed or oversized inputs fail rather than return partial success.",
inputSchema: inspectRustBinaryRequestSchema,
outputSchema: evidenceResultOf(
z.union([
+12 -12
View File
@@ -68,7 +68,7 @@ export const exportEvidenceBundleInputSchema = z.strictObject({
export const SESSION_TOOL_CONTRACTS = [
session(
"open_binary",
"Open a local executable, application bundle, archive, JavaScript, source map, plist, or analysis database after validation. format=dos-com explicitly interprets 1..65280 headerless bytes as a DOS COM analysis image. format=raw-binary interprets headerless bytes with a required architecture and entry_point; file offset 0 maps at that address. Omission preserves header-based detection. provider_id selects one deep provider or deterministic auto selection; the binding remains stable until close or an explicit switch, with no failure fallback. Reopening the same target and profile retains its active database and metadata edits. Changing target or provider can retire the active Ghidra database and discard its ephemeral edits, including before a later provider call fails; retained investigation records are historical and do not restore those edits. For editable Ghidra persistence across processes, set REA_GHIDRA_CHECKPOINT_DIR to a private absolute directory in the startup environment (stock ELF/PE/Mach-O on Linux/macOS; restart MCP). Opens and normal close then restore/save automatically; no separate persistence tool or runtime setting update is needed. An optional analysis snapshot is imported atomically and must match the binary identity, concrete provider, and canonical analysis profile exactly; importing into a session with metadata mutations requires closing and reopening it first. Switching targets preserves investigation records. A failed admitted open reports error.details.selection_at_failure, target_at_open_completion, and provider_id_at_open_completion. The target summary and provider id are the selected binary and bound provider when that attempt settled, or null when absent. Later calls can change the selection, so use binary_session for current state. Call close_binary to release engine resources; reset_investigation explicitly clears investigation records.",
"Open a validated local artifact or analysis database and bind its analysis provider. Switching target/provider can discard ephemeral Ghidra edits even if the later open fails; retained investigation Evidence does not restore them. Reopening the same target/profile retains the engine and edits. provider_id selects a provider or deterministic auto routing, with no failure fallback. Omitted format uses headers; format dos-com admits 1..65280 headerless bytes, while raw-binary requires architecture and entry_point and maps file offset 0 there. Optional snapshots must match target, provider and analysis profile; close/reopen before importing into a mutated engine. For Ghidra cross-process edits, set a private absolute REA_GHIDRA_CHECKPOINT_DIR at startup (stock ELF/PE/Mach-O on Linux/macOS); normal opens/closes restore/save metadata. Failed opens report selection_at_failure and target/provider at completion; use binary_session for current state. close_binary releases engine resources; reset_investigation clears retained records.",
openBinaryInputSchema,
),
session(
@@ -78,17 +78,17 @@ export const SESSION_TOOL_CONTRACTS = [
),
session(
"close_binary",
"Drain earlier requests and release the active engine, replay cache and owned resources while retaining investigation Evidence references and complete Unknown history in memory. Optionally save a target-bound analysis snapshot before closing; resource-only sessions have no binary snapshot binding. Later requests wait for this transition. Existing files require overwrite; a failed snapshot save keeps the engine open. Metadata edits prevent snapshot saves until the engine is recreated. Use reset_investigation to clear records explicitly, optionally saving a complete cross-domain Evidence bundle for import in a new process. With Ghidra checkpoint mode enabled, normal close saves Program metadata; a failed save retains the live Program for close retry. Closing does not automatically persist investigation Evidence/Unknown records.",
"Release the active engine and owned resources while retaining investigation Evidence and complete Unknown history in memory. Drains earlier requests and queues later ones. If cleanup fails, keep this connection and retry close_binary without snapshot_path after the reported condition settles. Optional snapshot_path saves a target-bound snapshot first; resource-only sessions have no snapshot binding, existing files require overwrite, and failed saves keep the engine open. Metadata edits prevent immutable snapshot saves until recreation. Ghidra checkpoint mode saves metadata on normal close and retains the Program for retry if saving fails. Closing does not persist investigation records: export_evidence_bundle to save them, or reset_investigation to clear them.",
closeBinaryInputSchema,
),
session(
"reset_investigation",
"Explicitly clear all retained Evidence and Unknown revision history, including engine replay/source bindings, while keeping a healthy active engine open. Drain earlier admitted work and queue later requests. Optional save_path writes the complete canonical Evidence bundle with file sync and atomic publication before clearing; import_evidence_bundle restores its original IDs and Unknown history in another process. Cancellation, save failure or incomplete cleanup preserves records; a published checkpoint remains reported on a later failure. Without save_path this discards in-memory records. No automatic persistence or eviction occurs; binary_session reports the representation budget.",
"Discard retained Evidence and Unknown revision history, including engine replay/source bindings, while keeping a healthy active engine open. Drains earlier work and queues later requests. Optional save_path atomically syncs and publishes a complete bundle first; import_evidence_bundle restores its IDs/history. Cancellation, failed save or incomplete cleanup preserves records; any already-published checkpoint is reported. Without save_path, records are lost. binary_session reports the representation budget; no automatic persistence or eviction occurs.",
resetInvestigationInputSchema,
),
session(
"binary_session",
'Report the active binary target or resource-only app root, provider and capability availability when applicable, client-feature, analysis, and server-identity status without starting analysis. analysis_provider_candidates_observed distinguishes this status request from retained target-selection observations; selection-time readiness may have changed. Set refresh_candidates true to inspect current candidates without changing the active binding or engine. open_binary with an explicit provider_id reselects and may retire the previous engine and its ephemeral edits; reopening the same target without provider_id reuses its current route. A selected provider may report release_verification under its binding; omission means not reported, and reported-version verification does not authenticate executable bytes. Start with the default summary: after selecting Ghidra, capabilities[].shared_limitations already reports enabled checkpoint or ephemeral mode. Request detail: "complete" only for provider diagnostics, candidate capabilities or static tool flags; omitted_fields lists what summary leaves out.',
"Inspect current target, provider capabilities, analysis and server identity without starting analysis. Default summary reports Ghidra checkpoint/ephemeral mode in capabilities[].shared_limitations; detail complete adds diagnostics, candidate capabilities and tool flags. Set refresh_candidates true to recheck provider readiness without changing the active engine. analysis_provider_candidates_observed distinguishes fresh observations from selection-time facts. open_binary with provider_id can replace the engine and discard ephemeral edits; reopening without it reuses the route. release_verification is optional reported-version evidence, not executable authentication. omitted_fields names facts left out of summary.",
binarySessionInputSchema,
),
session(
@@ -103,22 +103,22 @@ export const SESSION_TOOL_CONTRACTS = [
),
session(
"capture_process_scenario",
"Run one caller-selected command under a PTY and return process capture Evidence with residual unknowns. Set dry_run: true to validate and return the resolved scenario without launching it; planned Evidence uses the rea.process-scenario-plan predicate and is not a capture. The renderer admits at most 1,000,000 combined terminal cells, computed as columns × (rows + scrollback); every resize uses the selected scrollback and must fit the same budget. Supply a smaller terminal shape when that product is too large; dimensions are never clamped. This release has no runtime override for that cell budget. A command name resolves through the inherited PATH; the working directory defaults to the caller's current directory; host environment variables are inherited with scenario overrides. Environment keys cannot contain '=' or NUL, and REA_PROCESS_RUN_ID is reserved for process ownership. Filesystem snapshots are opt-in through filesystem_observation_paths. A positive finalization_ms makes a timeout or idle deadline send SIGTERM to the captured root through its start identity, keep observing, and send SIGKILL once after the interval; exit.finalization records each attempt with its delivery result and the observed exit, and cancellation still ends the run at once. The target runs with the current user's permissions; this is not a security sandbox.",
"Run a caller-selected command under a PTY and return process capture Evidence and unknowns. It runs with the user's permissions, can change files or use network, and is not a sandbox. dry_run validates and returns a rea.process-scenario-plan without launching. Command names use inherited PATH; cwd defaults to the caller's and environment overrides augment inheritance. Filesystem observation is opt-in through filesystem_observation_paths. Terminal size must satisfy columns × (rows + scrollback) <= 1,000,000 on every resize; dimensions are never clamped and this limit has no override. Environment keys reject =/NUL and REA_PROCESS_RUN_ID is reserved. With positive finalization_ms, timeout/idle sends identity-checked SIGTERM, observes until the interval ends, then sends SIGKILL once; exit.finalization records attempts and observed exit. Cancellation still ends the run immediately.",
processScenarioSchema,
),
session(
"compare_process_captures",
'Compare two compatible process capture observations, supplied inline or as exact {kind: "retained-evidence", evidence_id} references from this session, across terminal, interaction, lifecycle, process, filesystem, command-shim, HTTP, and WebSocket evidence. Capture-local observer timing is retained as provenance but does not by itself establish a behavior change. Optional trace_spec validates exact events, including caller-selected timing assertions, against an explicit partial order or finite trace language; concurrency is never inferred from timestamps or broad sorting. Missing, journal-free, or truncated observations are never treated as equivalent.',
'Compare compatible process captures, inline or by {kind:"retained-evidence",evidence_id}, across terminal, interaction, lifecycle, process, filesystem, command-shim, HTTP and WebSocket observations. Optional trace_spec checks explicit partial-order or finite-trace assertions, including selected timing. Observer timing alone does not establish changed behavior; timestamps or sorting never establish concurrency. Missing, journal-free or truncated observations never establish equivalence.',
processComparisonInputSchema,
),
session(
"compare_artifacts",
'Compare complete artifact inventories, including FIT and legacy uImage firmware components, by logical occurrence path, content identity, metadata, and graph relations. The root path . describes the outer container separately from its components. Name each side once without resending Evidence: {kind: "retained-evidence", evidence_id} selects an inspect_artifact result, its nested inventory, or its inspect_analysis_view summary retained in this session; {kind: "evidence-file", path, evidence_id?} reads one record from a local Evidence file or bundle at an absolute path. Complete inline Evidence is also accepted. Summary facts are not treated as a complete inventory; comparison resolves the exact complete parent from the same source bundle or the retained session. Every delta cites both complete inputs, and gaps yield truncated or unknown, never equivalence. Returns every change inline.',
'Compare complete artifact inventories by occurrence path, content identity, metadata and graph relations; root . identifies the outer container separately. Accepts complete inline Evidence, {kind:"retained-evidence",evidence_id} for inspect_artifact/nested inventory/retained summary, or {kind:"evidence-file",path:"/absolute/bundle.json"} with optional evidence_id. Summaries resolve to their complete parent in that session/source bundle; summary facts alone are insufficient. Returns every delta inline with both source identities; coverage gaps remain truncated or unknown, never equivalence. Includes FIT and legacy uImage components.',
artifactComparisonInputSchema,
),
session(
"match_native_functions",
"Match two retained list_procedures inventories by unique exact reported symbols, then unique identical observed function bytes. Optional same-context list_names/procedure_info/read_bytes/analyze_function Evidence supplies symbol origin, exact bodies, bytes and dossier links as supplied static facts. Optional compatible CFG/call/string fingerprints from supplied dossiers propose unresolved groups only. Duplicate candidates remain unresolved groups; only_left/right mean unpaired within supplied observations, never proof of addition/removal. Default summary retains complete Evidence for filtered, selected-column, paged function-matches views. The byte-sources collection identifies selected read_bytes Evidence and its limitations; intersect its IDs with each function's evidence_links to identify its sources. Complete detail returns every group. Existing dossier pairs provide direct retained-reference compare_functions inputs.",
"Pair two retained list_procedures inventories by unique exact symbols, then unique identical observed bytes. Optional same-context name/body/byte/dossier Evidence adds static facts; compatible CFG/call/string fingerprints propose unresolved groups only. Duplicate candidates stay unresolved, and only_left/right means unpaired within inputs, not proven addition/removal. Default summary retains the full matching for function-matches pages; complete returns every group. byte-sources identifies selected read_bytes Evidence: intersect IDs with function evidence_links. Dossier pairs supply retained-reference compare_functions inputs.",
matchNativeFunctionsInputSchema,
),
session(
@@ -153,7 +153,7 @@ export const SESSION_TOOL_CONTRACTS = [
),
session(
"list_unknowns",
"List current residual-unknown heads in deterministic ID order, with optional exact status, severity, and domain filters. Results are complete inline by default; supply offset and limit to page the filtered order. total is the matching-head count and next_offset is null when the page exhausts the result. This is read-only; unresolved, contradicted, and non-truth dispositions remain distinct. An empty registry does not mean retained Evidence has no residual questions; inspect the relevant Evidence or its analysis view.",
"List tracked questions' current revisions in deterministic ID order, with exact status/severity/domain filters. Complete inline by default; offset/limit pages the filtered order, total counts matches and next_offset null means exhausted. Unresolved, contradicted and non-truth dispositions stay distinct. An empty registry does not mean retained Evidence has no residual questions; inspect that Evidence or its analysis view.",
listUnknownsInputSchema,
),
session(
@@ -163,17 +163,17 @@ export const SESSION_TOOL_CONTRACTS = [
),
session(
"update_unknown",
"Append one immutable full-state revision and mutation evidence. The unknown retains its original scope; the mutation Evidence subject is the active binary analysis target, or null without one, and can differ from that scope. Requires exact expected_revision; stale concurrent writers fail instead of overwriting newer analysis.",
"Append a full-state revision to one tracked question, with immutable mutation Evidence. Requires exact expected_revision; stale writers fail rather than overwrite. The question keeps its original scope, while mutation Evidence uses the active target digest or null and can have a different subject.",
updateUnknownInputSchema,
),
session(
"verify_unknown_resolution",
"Revalidate the current residual-unknown head against live bundled evidence, exact authority/confidence/environment requirements, and revision integrity. Withdrawn and out-of-scope dispositions are not truth claims.",
"Check a tracked question's current resolution against bundled Evidence, required authority/confidence/environment and revision integrity. Withdrawn and out-of-scope dispositions do not establish truth.",
verifyUnknownResolutionInputSchema,
),
session(
"get_evidence_bundle",
"Return every retained Evidence record and residual unknown as a complete canonical bundle by default. detail=summary discovers retained records without copying or transferring their payloads; optionally filter by exact Evidence ID, operation, target SHA-256, analysis-profile digest or canonical native procedure address. Metadata distinguishes complete record retention from native value-flow truncation or unavailable/unknown coverage. detail=records returns a page (offset, limit) of the matching complete records with unchanged IDs and their missing direct evidence_links; it is not an importable bundle. detail=links reads which evidence_links of the selected records this session or bundle retains, without their payloads: traversal retained-closure also follows retained links, the walk composed workflows require, and rows default to missing links. For supported parent operations, use a discovered evidence_id with a compatible inspect_analysis_view without restarting a provider. Filters apply to summary, records and links delivery.",
"Read retained Evidence and tracked questions without rerunning providers. Default complete returns an importable canonical bundle. detail summary lists record metadata; records pages complete records with unchanged IDs and missing direct evidence_links, but is not an importable bundle. detail links inspects retained/missing links without payloads; traversal retained-closure follows retained links and defaults to missing rows. Summary/records/links filters accept Evidence ID, operation, target SHA-256, analysis-profile digest or canonical procedure address. Metadata keeps retention distinct from truncated/unavailable source coverage. Use a discovered evidence_id with a compatible inspect_analysis_view to read selected facts.",
getEvidenceBundleInputSchema,
),
{
+2 -2
View File
@@ -16,7 +16,7 @@ export const SIGNAL_TOOL_CONTRACTS = [
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Discover installed sigrok protocol decoders or inspect one decoder's channel/option help on Linux. Omit decoder to list ID/name pairs; supply its exact ID for literal help lines with source line numbers. query is a case-insensitive literal substring using Unicode simple case folding; catalog queries match the ID or name independently. Page matches with offset/limit (default 50; null returns all remaining). Reports tool identity, version, diagnostics and examined/matching coverage. Uses configured REA_SIGROK_COMMAND and prlimit; no recording, binary target, hardware scan or acquisition. Each call probes again; decoder modules are trusted, not fully fingerprinted. Use returned IDs/options with decode_signal_recording.",
"List installed sigrok decoder IDs/names, or supply an exact decoder ID to inspect its channel/option help. Use returned IDs/options with decode_signal_recording. query matches a case-insensitive literal substring; offset/limit pages matches (default 50; null means all remaining). Returns original help lines, coverage and current tool identity. Requires Linux, REA_SIGROK_COMMAND and prlimit. Each call probes again; decoder modules are trusted but not fully fingerprinted. No recording, target, hardware scan or acquisition.",
inputSchema: inspectSignalDecodersInputSchema,
outputSchema: evidenceResultOf(signalDecodersSchema),
examples: [
@@ -33,7 +33,7 @@ export const SIGNAL_TOOL_CONTRACTS = [
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Decode an existing local logic/signal recording on Linux with sigrok-cli 0.7.2 and util-linux prlimit. Supply decoder stack, channels and options explicitly; optionally select input format and annotation classes. Return 50 literal output lines by default, with line_offset/line_limit paging; line_limit:null requests all remaining lines. Output windows count display lines, not annotations or samples, and do not shorten decoding. Preserve selected text, sample ranges, stderr, source/tool identity and coverage inline. Configure absolute REA_SIGROK_COMMAND. File-only analysis; no hardware acquisition or device communication. Empty output does not prove absence of traffic.",
"Decode a saved logic/signal recording with an explicitly selected sigrok decoder stack, channels and options. Returns literal text, sample ranges, diagnostics, source/tool identity and coverage. line_offset/line_limit page display lines (default 50; null means all remaining), not annotations or samples; paging does not shorten decoding. Requires Linux, sigrok-cli 0.7.2 through absolute REA_SIGROK_COMMAND, and prlimit. No acquisition or device communication. Empty output does not prove absent traffic.",
inputSchema: decodeSignalRecordingInputSchema,
outputSchema: evidenceResultOf(signalRecordingSchema),
examples: [
+1 -1
View File
@@ -14,7 +14,7 @@ export const SQLITE_TOOL_CONTRACTS = [
kind: "artifact-provider",
requiresActiveTarget: true,
description:
"Inspect an explicit local SQLite database snapshot and its existing sibling WAL without modifying source files or opening a native analysis provider. Requires Node.js 24.x >=24.15 or 26+ with native DatabaseSync.limits support, checked by the worker. Returns observed Evidence with database/WAL SHA-256 and a compact schema inventory. Selecting an exact ordinary table expands only its schema and samples rows (default 20, subject to byte and worker resource limits). Retained rows are read in a stated unique order (rowid, or the declared primary key for WITHOUT ROWID tables) and report row_offset/next_row_offset, so a caller can page with row_offset; pages compose only while the reported artifact and WAL SHA-256 match. A rowid table whose rowid, _rowid_ and oid are all shadowed by declared columns has no unique order to report: it returns order=unspecified with a null next_row_offset and refuses any non-zero row_offset and cannot be paged; raise row_limit for a larger first sample within the resource limits. Select exact columns in the requested order to avoid unrelated or large values; schema_scope=database explicitly expands the whole schema; returned rows retain 64-bit integers, text bytes and blobs with explicit truncation. Adjust worker_timeout_ms (default 30000 ms) for worker startup, queries and reply writing; allow separate client headroom for snapshot acquisition, reply reads, cleanup and delivery. The result retains the actual budget; byte/heap safety limits stay fixed. No arbitrary SQL, ORDER BY or WHERE, view or virtual-table execution, extension loading, database repair, encryption support or live-snapshot atomicity claim. At most two inspections per provider are admitted; occupied capacity is retryable. An isolated temporary copy and owned worker enforce input, value/record, SQL-statement, JSON-reply, JavaScript-heap and deadline limits; overall native heap is not capped. Supply a quiescent snapshot for coherent database/WAL evidence.",
"Inspect a local SQLite snapshot and sibling WAL without modifying them. Returns their SHA-256 and schema inventory; select an exact ordinary table and columns for rows (default 20), or schema_scope database for expanded schema. row_offset pages a stated rowid/primary-key order only while database/WAL digests match; fully shadowed rowid aliases have unspecified order and cannot page. Values preserve 64-bit integers, text bytes and blobs with explicit truncation. Requires Node.js 24.x >=24.15 or 26+ with DatabaseSync.limits. worker_timeout_ms bounds worker startup/query/reply work, not snapshot acquisition, cleanup or host delivery; independent safety budgets remain. Supply a quiescent snapshot; no atomic live-snapshot claim. No arbitrary SQL, WHERE/ORDER BY, views/virtual tables, extensions, repair or encryption. Two inspections may run per provider; occupied capacity is retryable. Temporary-copy/worker bounds do not cap overall native heap.",
inputSchema: inspectSqliteDatabaseInputSchema,
outputSchema: evidenceResultOf(sqliteDatabaseSchema),
examples: [
+1 -1
View File
@@ -13,7 +13,7 @@ export const V8_CODE_CACHE_TOOL_CONTRACTS = [
...toolContractMetadata("inspect_v8_code_cache"),
kind: "artifact-provider",
description:
"Inspect one explicit local V8 code cache container (a bytenode .jsc, the bytes vm.Script.createCachedData writes, or a cache embedded in a Node single-executable application or Electron app) as static bytes, with no child process, no bytenode dependency, and no decompiler. Returns the artifact path/SHA-256/byte length, the eight observed header words each with its role and whether that role is confirmed, inferred, or unconfirmed, the observed magic and the build-stable high half, the producer family, the recorded source length, the payload offset/length/SHA-256, and printable byte sequences inside the payload with absolute byte ranges. Admission is narrow: a header this reader pins, the V8 code cache magic high half, and a payload length that reaches exactly the end of the file; an unknown magic, a short header, or a payload-length disagreement returns a typed failure and never a partial parse. Header field roles other than magic, source length, and payload length are inferred from one producer and are version-dependent, so they are reported as observations rather than a fixed ABI. Embedded strings are byte-pattern observations inside serialized V8 heap data, not parsed heap objects: a reported sequence is not proof V8 retained it as a string and a missing literal is not proof it is absent. The payload is not source; recovering logic needs a version-pinned View8-style decompiler that this tool neither provides nor depends on. Reads a stable regular file; exhausted observation budgets return no partial success. Portable on supported Node hosts; no V8 runtime is required.",
"Inspect a local bytenode .jsc or compatible V8 code-cache container as static bytes, without V8, bytenode, child processes or decompilation. Returns artifact identity, header words with confirmed/inferred roles, producer family, recorded source length, payload identity and printable sequences with file ranges. Only pinned header/magic and exact payload-length layouts are admitted; unknown or malformed layouts fail, not partial-parse. Most header roles are version-dependent inferences, not a fixed ABI. Payload strings are byte patterns, not parsed heap objects; missing literals do not prove absence. The payload is not source: logic recovery needs a separate version-pinned decompiler. Resource refusals remain explicit.",
inputSchema: inspectV8CodeCacheInputSchema,
outputSchema: evidenceResultOf(v8CodeCacheSchema),
examples: [
+1 -1
View File
@@ -23,7 +23,7 @@ export const INSPECT_WASM_ARTIFACT_CONTRACT = {
kind: "artifact-provider",
requiresActiveTarget: true,
description:
'Validate an explicit local WASM artifact with caller-supplied WABT 1.0.42. Optional custom-section interpretation errors do not invalidate the core module; warnings and name-section interpretation status remain in the result. Omitted or complete detail returns exact byte SHA-256, sections, upstream import/export WAT forms and decoded WAT inline as Evidence. For counts, validation and WAT identity without WAT text, pass detail: "summary" on this first call; it retains the complete original Evidence and returns the same typed summary as inspect_analysis_view, avoiding oversized complete delivery. Read exact imports/exports or WAT pages with inspect_analysis_view using normalized_result.parent_evidence_id. Delivery selection does not change analysis, provider inputs or source identity. Adjust command_timeout_ms for each WABT command (default 30000 ms), separately from the client deadline. max_artifact_paths admits auxiliary candidate/glue selections (default 16 paths per list). max_interface_bytes selects typed interface precision admission (default 32MiB), independently from producer text retention. max_input_bytes, max_tool_bytes and max_output_bytes select independent per-call file/tool/combined-command-output allowances with unchanged defaults of 8/64/32 MiB; limit errors name the exhausted control and retry action. Optionally associate selected JavaScript glue literals with explicit local candidates while preserving ambiguous URL/basename matches. Configure absolute REA_WABT_BIN_DIRECTORY. No installation, implicit fetch, WASM execution or original-source claim.',
"Validate and inspect local WASM with caller-supplied WABT 1.0.42, without executing it or fetching dependencies. Returns artifact SHA-256, sections, import/export WAT forms and decoded WAT; custom-section interpretation warnings do not invalidate the core module. Default complete returns full Evidence; detail summary retains it for inspect_analysis_view kind wasm using normalized_result.parent_evidence_id, with import/export rows or UTF-16 WAT pages. Delivery does not change analysis. Optional JavaScript glue associations preserve ambiguous candidates. Configure absolute REA_WABT_BIN_DIRECTORY. Per-call command_timeout_ms, input/tool/output, interface-precision and auxiliary-path budgets are independent; reported limit errors identify the control to adjust. No installation or original-source claim.",
inputSchema: wasmArtifactInspectionInputSchema,
outputSchema: analysisDetailOutputSchemaOf(
wasmArtifactSchema,
@@ -16,7 +16,7 @@ export const WEB_NETWORK_CAPTURE_TOOL_CONTRACTS = [
name: "inspect_web_network_capture",
...toolContractMetadata("inspect_web_network_capture"),
description:
"Explicit record_ordinals also decode retained protobuf/gRPC bodies whose declared content type is recognized. Optional protobuf selects exact body_pointers, framing, and a caller-supplied local FileDescriptorSet with message_type. Native gRPC and gRPC-web framing remain distinct. Wire fields are flat byte-range facts; ambiguous readings stay candidates, compressed payloads stay unknown. Page retained decoding with inspect_analysis_view kind protobuf, collection bodies/frames/fields, exact batch selectors and fields. Large text and schema values require explicit fields selection in those pages. Request detail summary for capture identity and counts; then page retained records with inspect_analysis_view kind capture (preview or complete), avoiding repeated decoding. Default detail complete preserves existing inline delivery. Inspect retained local HAR 1.2, native mitmproxy, Fiddler SAZ or aioquic 1.5.0 JSON qlog 0.3 events without contacting recorded URLs. Returns original ordinals, pointers/byte ranges/archive member names, preserved producer fields, precise numeric representations and exact exposed binary bytes inline. Excludes known transport credentials and explicitly marked values. Decodes every record before optional ordinal selection; malformed or oversized captures return no partial success. Duplicate JSON members are invalid; prototype-named members such as __proto__ are preserved as ordinary own JSON members without prototype mutation. Qlog reports trace-scoped STREAM interval unions and endpoint loss declarations; it does not recover bodies, prove network loss or correlate PCAP. Other qlog layouts are unsupported. Uses pinned upstream parsers, owned temporary files and bounded offline processes. SAZ preserves HTTP fields, XML metadata and encoded body/message bytes without replay or HAR conversion; encrypted archives are unsupported. Native mitmproxy requires caller-supplied mitmdump 12.2.3 on Linux. Browser transaction IDs, runtime attribution and original bytes of HAR Unicode text remain unknown.",
"Inspect a saved local HAR 1.2, mitmproxy, Fiddler SAZ or supported aioquic qlog capture without contacting recorded URLs. Returns source-linked records, preserved producer fields, precise numbers, exposed bytes and explicit coverage/limitations; transport credentials and explicitly marked sensitive values are excluded. Use inspect_web_page for a live CDP page. Preserve capture_path exactly as supplied; it names a path on the REA host, not a path to rebase onto the client workspace. Select format; record_ordinals selects records after full decoding and also decodes recognized protobuf/gRPC bodies. Optional protobuf selects body_pointers, framing and a local FileDescriptorSet/message_type; native gRPC and gRPC-web remain distinct, ambiguous readings stay candidates and compressed payloads stay unknown. Default complete delivery is inline. detail summary retains Evidence for inspect_analysis_view kind capture (preview/complete), protobuf (bodies/frames/fields), or qlog; large text/schema values require explicit fields. Qlog supports aioquic 1.5.0 JSON qlog 0.3 and reports STREAM interval unions/endpoint loss declarations, not recovered bodies or proved network loss. SAZ preserves encoded bytes without replay/HAR conversion; encrypted archives are unsupported. Mitmproxy requires caller-supplied mitmdump 12.2.3 on Linux. Malformed or oversized captures return no partial success; browser transaction attribution and HAR text’s original bytes remain unknown.",
kind: "application",
inputSchema: inspectWebNetworkCaptureInputSchema.extend({
detail: analysisDetailSchema,
+3 -3
View File
@@ -21,7 +21,6 @@ import {
import { toolContractMetadata } from "./toolEffects.js";
import { evidenceResultOf } from "./toolOutputSchemaPrimitives.js";
import {
WEB_SOURCE_MAP_LIMITS,
webSourceLocationInputSchema,
webSourceLocationResultSchema,
} from "../domain/webSourceLocation.js";
@@ -38,7 +37,8 @@ export const WEB_SCRIPT_TOOL_CONTRACTS = [
{
name: "trace_web_source_location",
...toolContractMetadata("trace_web_source_location"),
description: `Trace one generated position in an exported website script through an explicitly paired local source map. Verifies manifest, selected script and map SHA-256/byte identities; returns every equal-position mapping, reported source/root, resolved source URL, embedded sourcesContent and original position inline. One-based lines and zero-based UTF-16 columns; greatest generated position <= requested across lines. Duplicate sources and generated-only mappings remain distinct. Caller-selected pairing does not establish deployment authenticity or execution. Regular maps and inline indexed sections only; external section URLs are unsupported. No network access or application execution; uses the pinned upstream codec in an owned Node process with private temporary files, independent default ${WEB_SOURCE_MAP_LIMITS.codecHeapMiB} MiB old-generation heap and ${WEB_SOURCE_MAP_LIMITS.decodeTimeoutMs / 1000}-second deadline. Defaults: ${WEB_SOURCE_MAP_LIMITS.mapBytes / (1024 * 1024)} MiB map, ${WEB_SOURCE_MAP_LIMITS.outputBytes / (1024 * 1024)} MiB reply, ${WEB_SOURCE_MAP_LIMITS.decodedRecords} decoder records. Select source_map_limits to change byte, decoder or heap admission for the next call without restart; failures name the exhausted field and recovery. Complete delivery remains the default. Select detail summary to retain complete Evidence and return source/lookup identities and body-free match metadata with explicit page coverage. An optional source-location matches view selects offset/limit/max_bytes; source-text selects an exact match_index and UTF-16 offset/limit, returning content identity and only the requested text. inspect_analysis_view queries the same parent without rereading artifacts; export_evidence_bundle preserves the complete record. Summary requires session retention. Complete evidence or actionable resource failure. Cleanup may extend the deadline.`,
description:
'Map one generated position in an exported script through a caller-paired local source map, verifying manifest/script/map byte identities. Returns all equal-position matches, original positions, resolved source URLs and embedded sourcesContent; pairing does not prove deployment authenticity or execution. Lines are one-based, columns zero-based UTF-16; lookup uses the greatest generated position <= requested across lines. Regular maps and inline indexed sections only; external section URLs are unsupported. No network or application execution; decoding uses an owned codec process. Complete delivery is default. detail summary retains Evidence; view {kind:"source-location",collection:"matches",offset:0,limit:64} pages match metadata. source-text additionally requires match_index and pages UTF-16 text. inspect_analysis_view reuses the retained parent; export_evidence_bundle preserves it. source_map_limits changes byte/record/heap admission per call; decode_timeout_ms is separate. Refusals name the exhausted control; cleanup may outlast the deadline.',
kind: "application",
inputSchema: webSourceLocationRequestSchema,
outputSchema: analysisDetailOutputSchemaOf(
@@ -70,7 +70,7 @@ export const WEB_SCRIPT_TOOL_CONTRACTS = [
name: "trace_web_module_imports",
...toolContractMetadata("trace_web_module_imports"),
description:
"Trace one exported website script's outgoing native ES imports/re-exports, using exact URL and optional selected import-map context. Reads a local export_web_scripts manifest and verifies the selected source's SHA-256/size; returns source positions, native resolved URLs or exact errors, every matching captured candidate and explicit unknown execution. Query/fragment identities are preserved. Computed imports and bundler IDs remain unknown. Select importer_url for unknown inline/document-base context. Caller-supplied Chromium executes only a trusted REA resolver stub in an owned context with page requests locally fulfilled/blocked; no captured application execution or asset refetch. Requires absolute REA_BROWSER_EXECUTABLE for literal imports. 32 MiB manifest, 16 MiB source, 4 MiB map and 20-second native deadline; cleanup may extend the deadline.",
"Resolve native ES imports/re-exports from one script in a local export_web_scripts manifest. Verifies the selected source digest/size and returns source positions, resolved URLs/errors and every matching captured candidate. URL query/fragment identities remain distinct; computed imports, bundler IDs and execution remain unknown. Supply importer_url when inline/document-base context is unknown and an import_map when needed. Literal resolution requires absolute REA_BROWSER_EXECUTABLE: caller-supplied Chromium runs only a trusted REA resolver stub with page requests fulfilled locally or blocked, without captured app execution or asset refetch. The native deadline is 20 seconds; cleanup may extend it.",
kind: "application",
inputSchema: webModuleTraceInputSchema,
outputSchema: evidenceResultOf(webModuleTraceResultSchema),
+1 -15
View File
@@ -2,7 +2,6 @@ import { expect, it } from "vitest";
import { z } from "zod";
import { Ajv2020 } from "ajv/dist/2020.js";
import { SESSION_TOOL_CONTRACTS } from "../../contracts/sessionToolContracts.js";
import { projectInputIssues } from "../inputIssueProjection.js";
import { nativeCallObservationInputSchema } from "../native/nativeCallObservation.js";
import {
@@ -214,6 +213,7 @@ it("keeps scenario identity without finalization while versioning corrected port
});
it("admits the default and the exact combined terminal-cell budget", () => {
expect(PROCESS_TERMINAL_CELL_BUDGET).toBe(1_000_000);
expect(
processScenarioSchema.parse({ executable: "/bin/true" }).terminal,
).toEqual({
@@ -234,20 +234,6 @@ it("admits the default and the exact combined terminal-cell budget", () => {
).toBe(true);
});
it("tells the agent the terminal cell budget has no runtime override", () => {
const description = SESSION_TOOL_CONTRACTS.find(
(tool) => tool.name === "capture_process_scenario",
)?.description;
expect(PROCESS_TERMINAL_CELL_BUDGET).toBe(1_000_000);
expect(description).toContain("1,000,000 combined terminal cells");
expect(description).toContain(
"This release has no runtime override for that cell budget.",
);
expect(processScenarioSchema.shape.terminal.unwrap().description).toContain(
"This release has no runtime override.",
);
});
it("rejects an oversized initial buffer without clamping caller dimensions", () => {
const input = {
executable: "/bin/true",
+5 -5
View File
@@ -1,15 +1,15 @@
// A host deadline can discard the response before error remediation reaches the
// agent. Teach that distinction at initialization, not just in returned errors.
const RECOVERY_START =
"Recovery: For invalid arguments, read the connected tool's input schema (refresh tools/list if stale), fix the reported fields and do not repeat the unchanged call. If the MCP connection drops, retry that call once only when it is safe to repeat or known not to have started. If it may already have changed the target, or it fails again, tell the user and ask them to restart the MCP client. If REA could not start its connection, retry once, then tell the user and ask them to restart the MCP client. Do not retry a startup failure that returns the same unchanged result. Run `rea doctor` when REA could not start or tools stay missing after that restart. A returned REA provider_timeout is a server/provider deadline: follow its remediation and reuse accessible partial Evidence. ";
"Recovery: Correct malformed arguments from the reported fields and connected schema; refresh tools/list only if stale. Do not repeat unchanged failures. A valid unresolved lookup is not an argument error or a completed reference search. Follow returned remediation for REA provider_timeout and resource errors; reuse partial Evidence. ";
const RUNTIME_SETTINGS_RECOVERY =
"When a returned error names an editable setting and its bounds, call update_analysis_settings directly, then retry after work and cleanup settle; inspect_analysis_settings is optional when those facts are already supplied.";
"When an error names an editable setting and bounds, call update_analysis_settings directly; inspection is optional when those facts are supplied.";
const LAUNCH_SETTINGS_RECOVERY =
"When a returned error names an editable setting and its bounds, change that launch setting and restart REA, or add application to REA_MCP_TOOL_FAMILIES and restart to enable runtime settings controls.";
"For an editable launch setting, follow the error's restart instructions; add application to REA_MCP_TOOL_FAMILIES and restart to enable runtime settings tools.";
const EXPLICIT_ARGUMENT_RECOVERY =
" Explicit per-call arguments take precedence, so correct those fields when selected. Runtime updates affect new work only and do not clear cleanup blockers.";
" Explicit per-call arguments override runtime defaults. Change only the recommended control, then retry after work and cleanup settle. Runtime updates affect new work and do not clear cleanup blockers.";
const RECOVERY_END =
" Change other request fields or REA_* settings only when remediation recommends it. Restart REA when that text says the value is read at startup. A mention that a control does not raise the deadline is not a recommendation to change it. A host error such as 'timed out awaiting tools/call' without a REA result is a client deadline, not proof that work or cleanup stopped. Do not repeat the unchanged analysis. Increase the host's tool deadline with execution/cleanup/delivery headroom; when configuration is not editable, report the required setting (Codex: mcp_servers.<server>.tool_timeout_sec, seconds). Server analysis_timeout_ms, when advertised, is a separate millisecond budget; raising it cannot fix a shorter client deadline. Session state does not establish completion of every target-free operation.";
" A host timeout without a REA result is a client deadline, not proof that work or cleanup stopped; session status cannot establish completion of all target-free work. Do not replay uncertain analysis. Increase the client deadline with execution/cleanup/delivery headroom, or report the needed change (Codex: mcp_servers.<server>.tool_timeout_sec, seconds). Server analysis_timeout_ms is a separate millisecond budget and cannot fix a shorter client deadline. Keep the connection for reported cleanup retries. After a connection/startup failure, retry once only if safe or known not to have started. If it persists, ask the user to restart the MCP client; run rea doctor if REA cannot start or tools remain missing. Preserve needed Evidence before restarting REA.";
/** Only direct callers to runtime settings tools when they are advertised. */
export const recoveryInstructions = (
+5 -2
View File
@@ -19,6 +19,9 @@ const ACTIVE_TARGET_INSTRUCTIONS =
const FUNCTION_DOSSIER_INSTRUCTIONS =
"analyze_function provides a function dossier, and focused procedure tools return individual facets.";
const EVIDENCE_INTERPRETATION_INSTRUCTIONS =
"Preserve caller-selected paths and returned IDs; do not rebase REA host paths onto the client workspace. An unresolved lookup or exhausted page with partial source coverage does not establish target absence.";
/** Whether the scope advertises the family that owns a named tool. */
const advertisesToolFamily = (
advertisedToolFamilies: ReadonlySet<string> | undefined,
@@ -39,6 +42,6 @@ export const serverInstructions = (
advertisesToolFamily(advertisedToolFamilies, "update_analysis_settings"),
);
if (!hasSession)
return `${ACTIVE_TARGET_INSTRUCTIONS}${guidance("analyze_function", FUNCTION_DOSSIER_INSTRUCTIONS)} ${recovery} ${UNTRUSTED_CONTENT_INSTRUCTIONS}`;
return `${TARGET_FREE_INSTRUCTIONS}${guidance("close_binary", SESSION_LIFECYCLE_INSTRUCTIONS)} ${recovery} ${UNTRUSTED_CONTENT_INSTRUCTIONS}`;
return `${ACTIVE_TARGET_INSTRUCTIONS}${guidance("analyze_function", FUNCTION_DOSSIER_INSTRUCTIONS)} ${EVIDENCE_INTERPRETATION_INSTRUCTIONS} ${recovery} ${UNTRUSTED_CONTENT_INSTRUCTIONS}`;
return `${TARGET_FREE_INSTRUCTIONS}${guidance("close_binary", SESSION_LIFECYCLE_INSTRUCTIONS)} ${EVIDENCE_INTERPRETATION_INSTRUCTIONS} ${recovery} ${UNTRUSTED_CONTENT_INSTRUCTIONS}`;
};
@@ -186,12 +186,9 @@ it("passes Rizin decoder and map inputs as flags before the artifact", async ()
expect.arrayContaining([...rizinCommandLimitations(input)]),
);
// Compact schemas drop property descriptions, so the tool description names
// the input that changes how Rizin loads the file.
const { tools } = await client.listTools();
const listed = tools.find((tool) => tool.name === rizinContract.name);
expect(listed?.description).toBe(rizinContract.description);
expect(listed?.description).toContain("base_address");
const refused = await client.callTool({
name: "execute_rizin_command",
+1 -6
View File
@@ -535,12 +535,7 @@ describe("target-free MCP workflow", () => {
const beforeTools = (await mcp.listTools()).tools;
const beforeNames = beforeTools.map(({ name }) => name);
expect(mcp.getInstructions()).toContain(
"Use the tool that directly answers the question",
);
expect(
beforeTools.find(({ name }) => name === "inspect_artifact")?.description,
).toMatch(/\breturns the complete content-addressed artifact graph\b/iu);
expect(beforeNames).toContain("inspect_artifact");
expect(beforeNames).toContain("open_binary");
expect(beforeNames).toContain("binary_session");
expect(beforeNames).toContain("current_document");
@@ -120,7 +120,7 @@ it.each(["session", "session,application"])(
"update_analysis_settings",
"inspect_analysis_settings",
]) {
expect(instructions.includes(name)).toBe(names.includes(name));
if (instructions.includes(name)) expect(names).toContain(name);
}
if (!scope.includes("application"))
expect(instructions).toContain("REA_MCP_TOOL_FAMILIES");
@@ -13,24 +13,8 @@ import { providerSnapshot } from "../support/reverseEngineeringCompositionFixtur
import { createReverseEngineeringService } from "../../src/composition/reverseEngineering.js";
import { projectAnalysisError } from "../../src/domain/analysisErrorProjection.js";
import { AnalysisCancelledError } from "../../src/domain/analysisErrorCore.js";
import { REVERSE_ENGINEERING_TOOL_CONTRACTS } from "../../src/contracts/reverseEngineeringToolContracts.js";
import { rizinCommandLimitations } from "../../src/rizin/RizinCommand.js";
it("documents the shared combined capture limit for both command tools", () => {
expect(REVERSE_ENGINEERING_TOOL_CONTRACTS.map(({ name }) => name)).toEqual(
expect.arrayContaining(["inspect_with_objdump", "execute_rizin_command"]),
);
for (const contract of REVERSE_ENGINEERING_TOOL_CONTRACTS)
expect(contract.description).toContain("shared 16 MiB combined limit");
expect(
REVERSE_ENGINEERING_TOOL_CONTRACTS.find(
({ name }) => name === "inspect_with_objdump",
)?.description,
).toContain("does not follow local debug links by default");
for (const contract of REVERSE_ENGINEERING_TOOL_CONTRACTS)
expect(contract.description).toContain("command_timeout_ms");
});
it.each(["objdump", "rizin"] as const)(
"recovers a bounded %s capture after the caller raises output admission",
async (provider) => {