* perf(native): add opt-in Mach-O summary delivery and retained pages inspect_macho returns every import and export inline. For VS Code's Electron Framework one MCP call carries 2.5 MB of text (about 828k o200k tokens), and the same again as structuredContent; the MCP response budget admits it. Agents asking for slice identity, UUID or dependency counts paid that cost on every first call. Add the established opt-in detail selection: omitted or complete keeps the existing complete result and Evidence identity, while summary retains the complete Evidence and returns slice identity with per-collection returned/total/exhaustive counts (956 tokens). inspect_analysis_view kind macho pages the original rows of any collection or the command provenance, repeating the producer's own total and exhaustive flag so page exhaustion is never read as absence. Delivery detail never reaches the native tools or the source Evidence ID: registerEvidenceTools gains a parametersForEvidence hook, so the summary's parent is the same Evidence as a complete call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(mcp): refuse unretainable summary delivery before analysis A server without Evidence retention (a fixed analysis source) ran the complete inspect_macho or inspect_artifact analysis for detail summary and only then refused it in summarizeRetainedAnalysis, paying the very cost summary delivery exists to avoid. registerEvidenceTools gains a preflight hook; both registrations check retention there, as the WASM, EVM, managed, pcap and capture handlers already do before dispatch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(native): keep whole rows in Mach-O architecture and segment pages The page item union listed plain-object row arrays, and zod returns the first union member that parses while dropping unknown keys. Entrypoint rows declare only file_offset, so every architecture and segment row (which also carry a numeric file_offset) matched it and lost its name, CPU fields, permissions and sections. Rows now use exact key sets, and imports/exports share one member. The MCP test pages every facet of a real /bin/ls and compares it with the unparsed complete rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
100 lines
8.0 KiB
TypeScript
100 lines
8.0 KiB
TypeScript
import { API_SURFACE_EXAMPLE } from "./analysisViewApiSurfaceExample.js";
|
|
import {
|
|
analysisViewResultSchema,
|
|
inspectAnalysisViewInputSchema,
|
|
} from "../domain/analysisView/analysisView.js";
|
|
import type { ToolContract } from "./toolContractTypes.js";
|
|
import { toolContractMetadata } from "./toolEffects.js";
|
|
import { evidenceResultOf } from "./toolOutputSchemaPrimitives.js";
|
|
|
|
const RETAINED_EXAMPLE_ID = `ev_${"a".repeat(64)}`;
|
|
|
|
/** Selected views of completed layout, JavaScript, native, inventory, WASM, Mach-O and web network Evidence. */
|
|
export const ANALYSIS_VIEW_TOOL_CONTRACTS = [
|
|
{
|
|
name: "inspect_analysis_view",
|
|
...toolContractMetadata("inspect_analysis_view"),
|
|
kind: "application",
|
|
description:
|
|
'Inspect selected views of completed binary-layout, JavaScript application, native analyze_function, inspect_artifact, inventory_artifact, inspect_wasm_artifact, inspect_macho, inspect_evm_interface, inspect_managed_artifact, inspect_android_package, inspect_dart_aot or inspect_web_network_capture Evidence without repeating analysis. 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. 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, and interval overlap or endpoint loss declarations do not prove retransmission or network loss. The api-surface view groups retained HAR requests by method, origin and format-rule path template; templated segments are inferences. It reads no headers or bodies and reports no query values. For a retained record use source: {kind: "retained-evidence", evidence_id: "<parent_evidence_id>"}. Use normalized_result.parent_evidence_id from a summary receipt. Source kind is required. Portable source uses {kind: "inline", evidence: <complete Evidence>}. For layout, JavaScript, inventory, WASM, Mach-O, EVM, managed artifact, Android package and Dart AOT sources, request a summary with view: {kind: "summary"}; summary is a view kind and has no facet. The WASM summary gives validation, counts, WAT digest/length, tool profile and execution/network states without reading WAT text. Select a layout mitigations/linkage facet, one section/symbol/module, or a stable page. Module pages include assets, bundled and source modules; use node_id for ambiguous or unavailable paths. Inventory uses view: {kind: "inventory", collection: "occurrences", logical_paths: ["package.json"], offset: 0, limit: 64}. Inventory views page nodes, occurrences, edges or integrity contradictions; occurrence logical_paths matches exact recorded strings (omitted means all available, [] means none). source_complete distinguishes complete inventories from partial source records; page exhaustion does not prove absence in a partial source. WASM views use kind wasm and facet sections/imports/exports/candidates/glue/wat/headers/details/tool_profile; text facets use UTF-16 code units and source forms remain exact. Mach-O views use kind macho and facet entrypoints/architectures/build_metadata/load_commands/dependencies/imports/exports/segments/provenance; source_exhaustive false means unreturned rows may exist. EVM summary returns all inferred interface candidates, carrier/decoded identities and explicit unknowns without hex or duplicate stdout. EVM views use kind evm and facet functions/bytecode_hex/stdout/stderr; function pages preserve the original candidate rows, and text offsets/limits count UTF-16 code units (hex has two characters per decoded byte). Exhausting candidate pages does not establish global interface completeness. Managed artifact summaries preserve complete identity/classification, metadata status, module/MVID, frameworks, coverage and limitations without unrelated inventories. Managed pages use kind managed and collection references/resources/attributes, retaining source coverage and build-local token scope; page exhaustion does not establish complete metadata. Android package summaries retain all declarations, engine identity and counts without decoded manifest text. Android manifest pages use kind android, facet manifest, offset and limit in UTF-16 code units; source_status preserves partial decoded coverage even when the retained text page is exhausted. Dart AOT summary preserves target/ABI/library identity, snapshot headers and pool lower bounds. String pages use kind dart-aot, collection package_uris/dart_uris/class_like_tokens; source coverage remains partial when the producer says partial. Native function Evidence requires kind native: view: {kind: "native", facet: "procedure"}. Facets select procedure, pseudocode, assembly, basic blocks, comments, callers/callees, references, unresolved calls, referenced strings/names, native API and high-pcode. Use nonnegative offset and a positive caller-selected limit (defaults 0 and 64); pseudocode uses UTF-16 code units, other native pages use rows. Returns artifact identity, parent Evidence ID, a distinct view digest, coverage, limitations and unknowns. Actual serialized size determines MCP transport admission; choose a smaller page or export the complete retained Evidence if needed.',
|
|
inputSchema: inspectAnalysisViewInputSchema,
|
|
outputSchema: evidenceResultOf(analysisViewResultSchema),
|
|
examples: [
|
|
{
|
|
title: "Read exact inventory paths from retained inspection Evidence",
|
|
input: {
|
|
source: {
|
|
kind: "retained-evidence",
|
|
evidence_id: RETAINED_EXAMPLE_ID,
|
|
},
|
|
view: {
|
|
kind: "inventory",
|
|
collection: "occurrences",
|
|
logical_paths: ["package.json", "main.js"],
|
|
offset: 0,
|
|
limit: 32,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
title: "Group requests from retained HAR Evidence",
|
|
input: API_SURFACE_EXAMPLE.input,
|
|
},
|
|
{
|
|
title: "Summarize retained analysis Evidence, including WASM",
|
|
input: {
|
|
source: {
|
|
kind: "retained-evidence",
|
|
evidence_id: RETAINED_EXAMPLE_ID,
|
|
},
|
|
view: { kind: "summary" },
|
|
},
|
|
},
|
|
{
|
|
title: "Read one ELF section from retained layout Evidence",
|
|
input: {
|
|
source: {
|
|
kind: "retained-evidence",
|
|
evidence_id: RETAINED_EXAMPLE_ID,
|
|
},
|
|
view: {
|
|
kind: "item",
|
|
collection: "sections",
|
|
selector: { name: ".text" },
|
|
},
|
|
},
|
|
},
|
|
{
|
|
title: "Page native high-pcode operations from retained Evidence",
|
|
input: {
|
|
source: {
|
|
kind: "retained-evidence",
|
|
evidence_id: RETAINED_EXAMPLE_ID,
|
|
},
|
|
view: {
|
|
kind: "native",
|
|
facet: "value_flow_operations",
|
|
offset: 0,
|
|
limit: 32,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
title: "Page module identities from retained application Evidence",
|
|
input: {
|
|
source: {
|
|
kind: "retained-evidence",
|
|
evidence_id: RETAINED_EXAMPLE_ID,
|
|
},
|
|
view: {
|
|
kind: "page",
|
|
collection: "modules",
|
|
offset: 0,
|
|
limit: 32,
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
] as const satisfies readonly ToolContract[];
|