cli.py•2.62 kB
"""Command line interface for the ComfyUI MCP server."""
from __future__ import annotations
import argparse
import asyncio
import json
from pathlib import Path
from typing import Any
from .config import load_settings
from .server import ComfyUIMCPServer
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description="ComfyUI MCP server utilities")
parser.add_argument("command", choices=["list", "describe", "assets"], help="Action to perform")
parser.add_argument("name", nargs="?", help="Workflow name for describe")
parser.add_argument("--config", type=Path, help="Path to configuration file")
parser.add_argument("--base-url", help="Override the ComfyUI base URL")
parser.add_argument("--workflows-path", type=Path, help="Override the workflows directory")
parser.add_argument(
"--directory",
action="append",
metavar="CATEGORY=PATH",
help="Override an asset directory (checkpoints, loras, vaes, text_encoders, embeddings)",
)
parser.add_argument("--json", action="store_true", help="Output JSON payloads")
return parser
async def _run_async(args: argparse.Namespace) -> Any:
settings = load_settings(args.config)
if args.base_url:
settings.base_url = args.base_url
if args.workflows_path:
settings.workflows_path = args.workflows_path
if args.directory:
for override in args.directory:
if "=" not in override:
raise SystemExit("--directory overrides must be formatted as CATEGORY=PATH")
category, value = override.split("=", 1)
if not hasattr(settings.directories, category):
raise SystemExit(f"Unknown asset category '{category}' for --directory override")
setattr(settings.directories, category, Path(value).expanduser())
async with ComfyUIMCPServer(settings).lifecycle() as server:
if args.command == "list":
return await server.list_workflows()
if args.command == "describe":
if not args.name:
raise SystemExit("--name is required for describe")
return await server.describe_workflow(args.name)
if args.command == "assets":
return await server.list_assets()
raise SystemExit(f"Unsupported command {args.command}")
def main() -> None:
parser = build_parser()
args = parser.parse_args()
result = asyncio.run(_run_async(args))
if args.json:
print(json.dumps(result, indent=2, default=str))
else:
print(result)
if __name__ == "__main__":
main()