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),
52 lines • 2.69 kB
JavaScript
import { ValidationError } from "./errors.js";
// ASCII control characters (incl. NUL) are never valid in a ComfyUI filename or
// output prefix and are a classic smuggling vector.
const CONTROL_CHARS_RE = /[\x00-\x1f\x7f]/;
/**
* Validate a user-supplied input-media filename (the `image` arg wired into a
* LoadImage node). It must be a single path segment that lives in ComfyUI's
* input dir — no separators, no traversal, no absolute/drive paths, no control
* chars. Throws ValidationError on any violation.
*/
export function assertSafeInputFilename(value, label = "image") {
if (typeof value !== "string" || value.trim().length === 0) {
throw new ValidationError(`${label} is required.`);
}
if (CONTROL_CHARS_RE.test(value)) {
throw new ValidationError(`${label} must not contain control characters or NUL bytes.`);
}
if (value.includes("/") || value.includes("\\")) {
throw new ValidationError(`Invalid ${label} "${value}": must be a single filename in ComfyUI's input dir, ` +
"without path separators (upload it first with upload_image (action:\"image\")).");
}
if (value === "." || value === ".." || value.includes("..")) {
throw new ValidationError(`Invalid ${label} "${value}": '..' / traversal is not allowed.`);
}
if (/^[A-Za-z]:/.test(value)) {
throw new ValidationError(`Invalid ${label} "${value}": absolute / drive paths are not allowed.`);
}
}
/**
* Validate a SaveImage/SaveVideo `filename_prefix`. ComfyUI allows a
* forward-slash-joined relative subpath (e.g. "video/ltx-2.3"), so separators
* are permitted, but absolute paths, backslashes, drive prefixes, ".." segments,
* and control chars are rejected. Throws ValidationError on any violation.
*/
export function assertSafeFilenamePrefix(value, label = "filename_prefix") {
if (typeof value !== "string" || value.length === 0) {
throw new ValidationError(`${label} must be a non-empty string when provided.`);
}
if (CONTROL_CHARS_RE.test(value)) {
throw new ValidationError(`${label} must not contain control characters or NUL bytes.`);
}
if (value.includes("\\")) {
throw new ValidationError(`Invalid ${label} "${value}": use forward slashes, not backslashes.`);
}
if (value.startsWith("/") || /^[A-Za-z]:/.test(value)) {
throw new ValidationError(`Invalid ${label} "${value}": must be relative to ComfyUI's output dir, not absolute.`);
}
if (value.split("/").some((seg) => seg === "..")) {
throw new ValidationError(`Invalid ${label} "${value}": '..' segments are not allowed.`);
}
}
//# sourceMappingURL=input-paths.js.map