This commit is contained in:
Your Name committed 2026-10-11 06:43:08 +07:00
1 parent 9237c0eded
commit f5893c3fad
16 files changed
+1230 -114

No files matched your search

+41
View File
@@ -0,0 +1,41 @@
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<string, unknown>,
};
} catch {
return result;
}
}