/** * MCP tool response hardening (spec-10). * * A single set of guards every tool runs through in the CallTool handler, so the * whole surface has one uniform input-validation, timeout, output-cap, and * error-normalization path: * * - Input validation BEFORE the handler runs, against the tool's own declared * `inputSchema` (reusing the hand-written JSON-Schema-subset validator from * spec-05 — no Ajv). Invalid args map to JSON-RPC -32602 (spec-12). * - Per-tool timeout via Promise.race, with slow tools overridden. * - Output size cap: oversized results are truncated DETERMINISTICALLY with a * `truncated: true` note telling the agent how to narrow the query — never a * silent drop. * - Error normalization to a stable code taxonomy, distinguishing "repo not * analyzed yet" (actionable) from real failures. */ /** Stable MCP tool error-code taxonomy. */ export type McpToolErrorCode = 'INVALID_ARGS' | 'NOT_ANALYZED' | 'TIMEOUT' | 'OUTPUT_TRUNCATED' | 'INTERNAL'; /** * Validate args against a tool's inputSchema. Returns a human-readable message on * failure, or null when valid (or when no schema is declared). */ export declare function validateToolArgs(args: unknown, inputSchema: unknown): string | null; /** Thrown when a tool exceeds its timeout — classified as TIMEOUT downstream. */ export declare class ToolTimeoutError extends Error { readonly toolName: string; readonly ms: number; constructor(toolName: string, ms: number); } /** The timeout budget for a tool (per-tool override or the default). */ export declare function toolTimeoutMs(toolName: string): number; /** Race a tool's work against its timeout. Rejects with ToolTimeoutError on expiry. */ export declare function withToolTimeout(work: Promise, toolName: string, msOverride?: number): Promise; /** * Deterministically cap a result string to a byte budget. When over budget, cut on * a UTF-8-safe boundary and append a note explaining how to narrow the query. */ export declare function capOutput(text: string, maxBytes: number): { text: string; truncated: boolean; }; /** * Cap a tool RESULT to a byte budget while keeping it parseable. * * Tool results are serialized to JSON before being sent to the agent. Naively * byte-truncating that JSON (what capOutput does to a raw string) cuts mid-string- * literal and yields UNPARSEABLE JSON — the agent can't use any of it (this is how * get_spec on a >256 KB spec broke). Instead: * - string results (raw-text tools) → capOutput, unchanged; * - object results → re-serialize with the single largest top-level string field * truncated to fit (shape preserved, valid JSON, marked `truncated: true`); * - anything else over budget → a valid JSON envelope wrapping the partial. * Binary search keeps the result within the byte budget despite JSON-escaping overhead. */ export declare function capStructuredResult(result: unknown, maxBytes: number): { text: string; truncated: boolean; }; /** Map an error to the stable taxonomy code (actionable vs real failure). */ export declare function classifyToolError(err: unknown): McpToolErrorCode; //# sourceMappingURL=tool-guard.d.ts.map