import type { CallToolResult, Tool } from "@modelcontextprotocol/sdk/types.js"; const READ_ONLY_PREFIXES = ["get_", "list_", "search_", "validate_", "audit_", "ping_"]; const DESTRUCTIVE_PREFIXES = ["delete_", "remove_", "restore_", "sync_"]; /** Advertise intent without changing the existing tool names or input contracts. */ export function presentToolDefinitions(tools: Tool[]): Tool[] { return tools.map((tool) => { const readOnly = READ_ONLY_PREFIXES.some((prefix) => tool.name.startsWith(prefix)); const destructive = DESTRUCTIVE_PREFIXES.some((prefix) => tool.name.startsWith(prefix)); return { ...tool, annotations: { ...tool.annotations, readOnlyHint: readOnly, ...(readOnly ? { idempotentHint: true, destructiveHint: false } : {}), ...(destructive ? { destructiveHint: true } : {}), ...(tool.name === "upload_product_image_from_url" ? { openWorldHint: true } : {}), }, }; }); } /** Keep text responses for existing clients while exposing JSON as machine-readable data. */ export function withStructuredContent(result: CallToolResult): CallToolResult { if (result.structuredContent) return result; const textBlocks = result.content.filter((item) => item.type === "text"); if (textBlocks.length !== 1) return result; try { const parsed: unknown = JSON.parse(textBlocks[0]!.text); if (parsed === null || typeof parsed !== "object") return result; return { ...result, structuredContent: Array.isArray(parsed) ? { data: parsed } : parsed as Record, }; } catch { return result; } }