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),

29 lines • 2.5 kB
import { z } from "zod"; import { applyManifest, manifestSchema } from "../services/manifest.js"; import { errorToToolResult } from "../utils/errors.js"; export function registerManifestTools(server) { server.tool("apply_manifest", "Apply a ComfyUI setup manifest from an inline object or .json/.yaml/.yml file. Composes custom-node installs and model downloads, installs pip packages, and reports apt entries as skipped (system packages need manual/root installation). LOCAL ComfyUI: model downloads use the connected server's live/data model roots; pip uses the serving checkout (live main.py root, then COMFYUI_CODE_PATH, then COMFYUI_PATH); filesystem custom-node fallbacks use the live data/base root (live --base-directory, then COMFYUI_PATH). REMOTE ComfyUI: custom_nodes and models are routed through the ComfyUI-Manager HTTP API (handled on the host), while pip and apt entries are reported as skipped (no remote equivalent). Each item reports applied/skipped/failed/pending independently. success is true only when nothing failed AND nothing is still pending. A PARTIAL INSTALL (custom_nodes left unsubmitted when the time budget elapsed) is named in the partial field — a drained Manager queue / panel_node_queue_status does not include those entries; re-run apply_manifest to submit them. Do not restart ComfyUI until they report applied or skipped.", { manifest: manifestSchema .optional() .describe("Inline manifest object. Provide exactly one of `manifest` or `path`."), path: z .string() .optional() .describe("Path to a .json, .yaml, or .yml manifest file. Provide exactly one of `manifest`, `path`, or `pack`."), pack: z .string() .optional() .describe("A bundled installer pack by NAME, as reported by list_packs (action:\"list\"). PREFER THIS over `path` for a bundled pack: the name is resolved against the running build at apply time, while a manifest_path captured earlier points into an npx cache directory that a later respawn no longer has (#1568). Provide exactly one of `manifest`, `path`, or `pack`."), }, async (args) => { try { const result = await applyManifest(args); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }], }; } catch (err) { return errorToToolResult(err); } }); } //# sourceMappingURL=manifest.js.map