/** * Single source of truth for the 11 HemmaBo federation MCP tools. * * Background (#63 / ADR-0001 §3): * Tool definitions used to live in three places — api/mcp.ts TOOLS array, * src/index.ts server.tool() calls, src/stdio.ts server.tool() calls. * Only the api/mcp.ts copy was contract-tested. The other two could drift * silently (different schemas, different descriptions, missing tools). * * This module exports TOOL_SPECS as the canonical declaration. The MCP * transport derives its wire format from it: * - api/mcp.ts: re-exports TOOLS = toMcpTool(spec) for tools/list * * A drift-guard test (src/tool-definitions.singleton.test.ts) enforces * that no other module declares its own tool list and that api/mcp.ts * stays in lock-step with TOOL_SPECS. * * Schema model: * inputSchema and outputSchema are JSON-Schema (draft-07 subset). The * subset uses: type (object/string/integer/number/boolean/array), format * (uuid/email/date-time/uri), pattern, enum, minimum/maximum, minItems/ * maxItems, properties, items, required, additionalProperties. This is * intentionally narrow so toZodShape() can be a tiny pure function. */ import { z } from "zod"; export interface JsonSchemaField { type?: "object" | "string" | "integer" | "number" | "boolean" | "array"; format?: string; pattern?: string; enum?: readonly string[]; description?: string; minimum?: number; maximum?: number; minItems?: number; maxItems?: number; items?: JsonSchemaField; properties?: Record; required?: readonly string[]; additionalProperties?: boolean | JsonSchemaField; } export interface ToolInputSchema { type: "object"; properties: Record; required?: readonly string[]; /** Required by #85 — Ajv must reject unknown keys so AI agents see typo'd * field names as field-level errors instead of generic "missing required". */ additionalProperties: false; } export interface ToolOutputSchema { type: "object"; properties: Record; required?: readonly string[]; additionalProperties?: boolean; } export interface ToolAnnotations { title: string; readOnlyHint: boolean; destructiveHint: boolean; idempotentHint: boolean; openWorldHint: boolean; } export interface ToolSpec { name: string; description: string; inputSchema: ToolInputSchema; outputSchema: ToolOutputSchema; annotations: ToolAnnotations; /** Optional ChatGPT Apps SDK / vendor extensions. */ _meta?: Record; } /** * Convert a tool input JSON-Schema to a Zod raw shape ready for * `server.tool(name, description, shape, annotations, handler)`. * * Required fields are mandatory; non-required fields are `.optional()`. */ export declare function toZodShape(input: ToolInputSchema): Record; export declare const TOOL_SPECS: readonly ToolSpec[]; /** All 11 HemmaBo federation canonical tool names in declaration order. */ export declare const TOOL_NAMES: readonly string[];