feat(mcp): update bigmind/mcp-image-gen/webscraper servers; add image-gen batch scripts

This commit is contained in:
Patrick Plate
2026-06-11 09:02:09 +02:00
parent 0cb94122bf
commit bf721c1379
9 changed files with 2659 additions and 297 deletions
+133
View File
@@ -0,0 +1,133 @@
#!/usr/bin/env python3
"""
Quick CLI for generating images via ComfyUI + FLUX.2 Klein Heretic.
Usage:
python gen.py "your prompt here"
python gen.py "your prompt" --steps 20 --width 1280 --height 720
python gen.py "your prompt" --seed 12345
python gen.py "your prompt" --count 3
Output saved to ~/Pictures/mcp-generated/
"""
import argparse
import json
import random
import sys
import time
import urllib.request
from pathlib import Path
COMFYUI = "http://localhost:8188"
OUTPUT_DIR = Path.home() / "Pictures" / "mcp-generated"
WORKFLOW_PATH = Path(__file__).parent / "src/workflows/flux2_klein_heretic.json"
def load_workflow():
with open(WORKFLOW_PATH) as f:
return json.load(f)
def submit(workflow):
data = json.dumps({"prompt": workflow}).encode()
req = urllib.request.Request(
f"{COMFYUI}/prompt", data=data,
headers={"Content-Type": "application/json"}
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read())["prompt_id"]
def wait(prompt_id, timeout=300):
print(" ⏳ Waiting for ComfyUI...", end="", flush=True)
start = time.time()
while time.time() - start < timeout:
with urllib.request.urlopen(f"{COMFYUI}/history/{prompt_id}") as resp:
history = json.loads(resp.read())
if prompt_id in history:
print(" done.", flush=True)
outputs = history[prompt_id].get("outputs", {})
for node_out in outputs.values():
if "images" in node_out:
return node_out["images"][0]
return None
print(".", end="", flush=True)
time.sleep(2)
raise TimeoutError(f"Timed out after {timeout}s")
def download(filename, subfolder=""):
url = f"{COMFYUI}/view?filename={filename}&subfolder={subfolder}&type=output"
with urllib.request.urlopen(url) as resp:
return resp.read()
def generate(prompt, steps=20, width=1024, height=1024, seed=-1, name="cli"):
if seed == -1:
seed = random.randint(0, 2**32 - 1)
workflow = load_workflow()
# Patch positive prompt (node 2)
workflow["2"]["inputs"]["text"] = prompt
# Patch negative prompt (node 3) — leave empty
workflow["3"]["inputs"]["text"] = ""
# Patch seed (node 10)
if "10" in workflow:
workflow["10"]["inputs"]["noise_seed"] = seed
# Patch dimensions (node 6)
workflow["6"]["inputs"]["width"] = width
workflow["6"]["inputs"]["height"] = height
# Patch steps (node 7)
workflow["7"]["inputs"]["steps"] = steps
# Patch output filename (node 13)
workflow["13"]["inputs"]["filename_prefix"] = name
print(f" Prompt : {prompt[:80]}{'...' if len(prompt) > 80 else ''}")
print(f" Size : {width}×{height} Steps: {steps} Seed: {seed}")
prompt_id = submit(workflow)
image_info = wait(prompt_id)
if not image_info:
print(" ❌ No output image returned.", file=sys.stderr)
return None
img_data = download(image_info["filename"], image_info.get("subfolder", ""))
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
out_path = OUTPUT_DIR / f"{name}_{seed}.png"
out_path.write_bytes(img_data)
print(f" ✅ Saved: {out_path} ({len(img_data) // 1024}KB)")
return out_path
def main():
parser = argparse.ArgumentParser(
description="Generate images via ComfyUI FLUX.2 Klein Heretic"
)
parser.add_argument("prompt", help="Text prompt for the image")
parser.add_argument("--steps", type=int, default=20, help="Inference steps (default: 20)")
parser.add_argument("--width", type=int, default=1024, help="Width in pixels (default: 1024)")
parser.add_argument("--height", type=int, default=1024, help="Height in pixels (default: 1024)")
parser.add_argument("--seed", type=int, default=-1, help="Seed (-1 = random)")
parser.add_argument("--count", type=int, default=1, help="Number of images (default: 1)")
parser.add_argument("--name", default="cli", help="Output filename prefix (default: cli)")
args = parser.parse_args()
for i in range(args.count):
if args.count > 1:
print(f"\n[{i+1}/{args.count}]")
seed = args.seed if args.seed != -1 else -1
generate(
prompt=args.prompt,
steps=args.steps,
width=args.width,
height=args.height,
seed=seed,
name=f"{args.name}_{i+1:02d}" if args.count > 1 else args.name,
)
if __name__ == "__main__":
main()