/** * Tool Definition Validator * * Validates MCP tool definitions to prevent tool poisoning attacks: * - Name validation (no impersonation of built-in tools) * - Description sanitisation (strip injection-like language) * - Schema validation (depth/size limits, suspicious params) */ import type { ExternalMCPTool } from '../types/mcp-client.types.js'; import { type SecurityEvent } from './security-event.types.js'; export interface ToolValidationResult { issues: string[]; tool: ExternalMCPTool; valid: boolean; } export declare class ToolDefinitionValidator { private events; /** * Validate and sanitise an MCP tool definition. * Returns a sanitised copy of the tool with any issues noted. */ validateToolDefinition(tool: ExternalMCPTool): ToolValidationResult; /** * Get recorded security events. */ getEvents(): SecurityEvent[]; /** * Clear recorded events. */ clearEvents(): void; /** * Check description for injection-like patterns. */ private validateDescription; /** * Remove injection-like content from a description. */ private sanitizeDescription; /** * Validate tool input schema for depth, size, and suspicious params. */ private validateSchema; /** * Measure the nesting depth of an object. */ private logEvent; private measureDepth; /** * Return a copy of the schema with any suspicious-named parameter (and its * entry in "required", if present) removed — mirrors sanitizeDescription's * strip-on-flag behaviour, so a caller that only reads `result.tool` (not * `result.issues`/`result.valid`) still gets a schema with the flagged * credential-extraction parameter actually removed, not just logged. */ private sanitizeSchema; /** * Single traversal that both detects suspicious parameter names and builds * a sanitised copy with them removed — detection and stripping used to be * two separate recursive methods that only walked `properties`, so a * suspicious parameter hidden behind a JSON Schema composition keyword * (`anyOf`/`oneOf`/`allOf`, an array `items` schema, or a `definitions`/ * `$defs` entry) was neither flagged nor stripped. Keeping detection and * sanitisation in one method makes that class of divergence structurally * impossible. Does not follow `$ref` pointers (that requires resolving * against the whole schema document, not just the local subtree) — a * suspicious parameter reachable only via `$ref` is a known limitation. */ private processSchema; /** * Named-parameter containers: `properties` entries are real invocation * parameters (checked against SUSPICIOUS_PARAM_NAMES and stripped); * `definitions`/`$defs` are reusable type definitions (recursed into for * nested suspicious properties, but the definition's own name is not a * parameter name so it is never itself flagged/stripped). */ private processDictEntries; private processNamedContainers; private sanitizeRequired; /** * `items`: either a single schema (list validation) or an array of * per-position schemas (tuple validation). */ private processItems; /** * `anyOf`/`oneOf`/`allOf`: arrays of alternative or combined schemas — * a suspicious parameter under any of them is just as reachable by the * caller as one under `properties` directly. */ private processCombinators; } export declare function getToolDefinitionValidator(): ToolDefinitionValidator; export declare function resetToolDefinitionValidator(): void; //# sourceMappingURL=tool-definition-validator.d.ts.map