UNPKG

comfyui-mcp

Version:

Local-first, agent-native control plane for ComfyUI — MCP server + autonomous sidebar agent that drives your live graph in natural language on ANY LLM: Claude/ChatGPT/Gemini on your subscription (no API key), free local models via Ollama (fully offline),

79 lines • 2.85 kB
import { logger } from "../utils/logger.js"; /** * Captures server.tool(...) registrations into a plain map instead of a live * MCP server. This powers the compact tool mode (COMFYUI_MCP_TOOL_MODE=compact) * for small/local LLMs: the full ~200-schema surface overwhelms their context, * so the real server registers only meta-tools (list_tools / describe_tool / * call_tool) that consult this catalog and dispatch to the original handlers. * Every file in src/tools registers via the 4-arg * server.tool(name, description, zodRawShape, handler) overload; capture() * parses defensively so other SDK overloads degrade to warn-and-skip rather * than breaking startup. */ export class ToolCatalog { tools = new Map(); category = "general"; /** Category applied to subsequent captures (set per register-group). */ setCategory(category) { this.category = category; } get(name) { return this.tools.get(name); } /** Categories in first-seen order, each with its tools in registration order. */ byCategory() { const grouped = new Map(); for (const tool of this.tools.values()) { const list = grouped.get(tool.category); if (list) list.push(tool); else grouped.set(tool.category, [tool]); } return grouped; } /** * Duck-typed stand-in accepted by the registerXxxTools(server) functions. * Only .tool() is implemented — a grep of src/tools confirms no register * function touches any other McpServer member. */ asRegistrar() { const registrar = { tool: (...args) => { this.capture(args); return {}; }, }; return registrar; } capture(args) { const name = args[0]; const handler = args[args.length - 1]; if (typeof name !== "string" || typeof handler !== "function" || args.length < 2) { logger.warn("ToolCatalog: skipped a server.tool() call with an unrecognized shape", { argTypes: args.map((a) => typeof a), }); return; } let description = ""; let schema; for (const arg of args.slice(1, -1)) { if (typeof arg === "string") description = arg; else if (arg && typeof arg === "object" && schema === undefined) schema = arg; } if (this.tools.has(name)) { logger.warn(`ToolCatalog: duplicate tool '${name}' — keeping the first registration`); return; } this.tools.set(name, { name, description, category: this.category, schema, handler: handler, }); } } //# sourceMappingURL=catalog.js.map