惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
有赞技术团队
有赞技术团队
WordPress大学
WordPress大学
月光博客
月光博客
T
Tailwind CSS Blog
阮一峰的网络日志
阮一峰的网络日志
小众软件
小众软件
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Last Week in AI
Last Week in AI
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
罗磊的独立博客
Jina AI
Jina AI
酷 壳 – CoolShell
酷 壳 – CoolShell
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 三生石上(FineUI控件)
量子位
雷峰网
雷峰网
Apple Machine Learning Research
Apple Machine Learning Research
美团技术团队
博客园 - 聂微东
V
V2EX

Hacker News: Show HN

PurrrrrFocus: Pomodoro Timer App - App Store Workflow Engine — Multi-Step Orchestration for Bun RapidPhoto: Pro Photo Editor App - App Store GitHub - DheerG/swarms: Achieve extraordinary results with claude code across a variety of tasks SPICE simulation → oscilloscope → verification with Claude Code — Lucas Gerads Show HN: VCoding – A 5 MB native Windows IDE with no dynamic dependencies Show HN: LLMs don't hallucinate because they're bad at math, it's the format GitHub - Agent-FM/agentfm-core: AgentFM is a peer-to-peer network that turns everyday computers into a decentralized AI supercomputer. AgentFM lets you run massive AI workloads directly across a global mesh of idle CPUs and GPUs. Show HN: Tracking Top US Science Olympiad Alumni over Last 25 Years GitHub - Potarix/agent-hub: One place to talk to all your agents Show HN: Runtime security for AI agents(injection,tool abuse, data exfiltration) GitHub - dubeyKartikay/lazyspotify: Terminal Spotify client for macOS and Linux GitHub - the-banana-tool/king-louie: Easy to use GUI Personal AI Assistant. Win/Linux/Mac. Show HN I made my vacation rental bookable by AI agents–no Airbnb, 0% commission GitHub - basteez/jsf-autoreload: maven plugin to enable hot reload on jsf projects uvm32/hosts/host-gdbstub at main · ringtailsoftware/uvm32 GitHub - labsai/EDDI: Config-driven engine that turns JSON into production-grade AI agents. Multi-agent orchestration, 12+ LLM providers, MCP/A2A protocols, RAG, persistent memory, and enterprise compliance (EU AI Act, GDPR, HIPAA). Built on Quarkus. GitHub - glitchnsec/fortyone-oss: AI Executive Assistant Platform Quickstart | Alien GitHub - muxshed/shed: One stream in, or many. Every destination, simultaneously. No cloud middleman, no per-channel fees, no limits. GitHub - ocrbase-hq/ocrbase: 📄 PDF/IMG ->.MD/JSON Document OCR API for PaddleOCR and GLMOCR. Self-hostable. GitHub - impactjo/home-memory: MCP server that lets your AI assistant remember everything about your home. GitHub - Sets88/dbcls: DbCls is a powerful terminal database client that supports various databases GitHub - neptun2000/heor-agent-mcp GitHub - SeanFDZ/macmind: Single-layer transformer in HyperTalk for the classic Macintosh RollQuation: Math Puzzles - Apps on Google Play GitHub - dropbox/witchcraft Show HN: Agent-cache – Multi-tier LLM/tool/session caching for Valkey and Redis GitHub - opentalon/opentalon: OpenTalon is an open-source platform built from the ground up in Go as a robust alternative to OpenClaw LinkedIn™ 职位抓取工具 - Chrome 应用商店
GitHub - thebenlamm/image-gen-mcp
benlamm · 2026-05-04 · via Hacker News: Show HN

An MCP (Model Context Protocol) server for multi-provider image generation. Works with Claude Code, Claude Desktop, and other MCP-compatible clients.

Features

  • 8 providers — OpenAI, Google Gemini, Replicate, Together AI, xAI Grok, Photoroom, fal.ai, Ideogram
  • 6 toolsgenerate_image, process_image, generate_asset, image_op, image_task, list_capabilities
  • Goal-shaped MCP toolimage_task: hand off a natural-language image goal, receive the final image plus a structured DAG trace
  • Capability operations — Directly invoke extract_subject, edit_prompt, composite_layers, generate, transform, upscale, and analysis ops through image_op
  • Asset presets — One-call generation of profile pics, post images, hero photos, avatars, and scenes
  • Image processing — Resize, crop, aspect crop, and circle mask operations
  • Style modifiers — Prepend style directives (e.g., "watercolor painting") to any prompt
  • Smart defaults — Configure a default provider, override per-request
  • Persistent output — Images saved to disk with descriptive filenames, atomic writes

Supported Providers

Provider Models Notes
OpenAI gpt-image-1 (generation default), gpt-image-2, dall-e-3, dall-e-2; gpt-image-1.5 for image_op edits Highest quality, supports revised prompts. gpt-image-2 requires OpenAI org verification (verify at https://platform.openai.com/settings/organization/general, wait up to 15 min for propagation), then set OPENAI_DEFAULT_MODEL=gpt-image-2.
Google Gemini gemini-2.5-flash-image (default), gemini-3-pro-image Fast default, pro for higher quality
Replicate black-forest-labs/flux-1.1-pro (default), any Replicate model Huge model variety
Together AI black-forest-labs/FLUX.1-schnell (default) Fast, affordable
xAI Grok grok-imagine-image (default), grok-imagine-image-pro, grok-2-image Aurora image generation
Photoroom Remove Background API; Image Editing API Capability-only provider for extract_subject and composite_layers with Image Editing shadows/relighting. Requires PHOTOROOM_API_KEY.
fal.ai fal-ai/flux-pro/kontext Capability-only edit_prompt mirror for Flux Kontext. Requires FAL_KEY.
Ideogram ideogram-v3-0 Capability-only generate provider for text-fidelity generation. Requires IDEOGRAM_API_KEY.

Installation

Claude Code Plugin (Recommended)

The easiest way to install — no manual config needed:

# Add the marketplace
claude plugin marketplace add thebenlamm/image-gen-mcp

# Install the plugin
claude plugin install image-gen@image-gen-marketplace

The plugin automatically registers the MCP server. Set API keys for the remote providers you want to use. Local extract_subject works without an API key:

export OPENAI_API_KEY=sk-...
export OPENAI_DEFAULT_MODEL=gpt-image-1
export OPENAI_EDIT_MODEL=gpt-image-1.5
export ANTHROPIC_API_KEY=sk-ant-...
export GEMINI_API_KEY=...
export REPLICATE_API_TOKEN=...
export TOGETHER_API_KEY=...
export XAI_API_KEY=...
export PHOTOROOM_API_KEY=...
export FAL_KEY=...
export IDEOGRAM_API_KEY=...
export IMAGE_GEN_INPUT_ROOT=/absolute/path/to/allowed-inputs

Restart Claude Code and the tools will be available.

Manual Installation

If you prefer manual setup or want to use with other MCP clients:

git clone https://github.com/thebenlamm/image-gen-mcp.git
cd image-gen-mcp
npm install

The postinstall script builds automatically. Then configure your client (see below).

Configuration

Claude Code (Manual)

Add to ~/.claude/settings.json:

{
  "mcpServers": {
    "image-gen": {
      "command": "node",
      "args": ["/absolute/path/to/image-gen-mcp/dist/index.js"],
      "env": {
        "IMAGE_GEN_DEFAULT_PROVIDER": "openai",
        "IMAGE_GEN_OUTPUT_DIR": "~/Downloads/generated-images",
        "IMAGE_GEN_INPUT_ROOT": "/absolute/path/to/allowed-inputs",
        "OPENAI_API_KEY": "sk-...",
        "OPENAI_DEFAULT_MODEL": "gpt-image-1",
        "OPENAI_EDIT_MODEL": "gpt-image-1.5",
        "ANTHROPIC_API_KEY": "sk-ant-...",
        "GEMINI_API_KEY": "...",
        "REPLICATE_API_TOKEN": "...",
        "TOGETHER_API_KEY": "...",
        "XAI_API_KEY": "...",
        "PHOTOROOM_API_KEY": "...",
        "FAL_KEY": "...",
        "IDEOGRAM_API_KEY": "..."
      }
    }
  }
}

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "image-gen": {
      "command": "node",
      "args": ["/absolute/path/to/image-gen-mcp/dist/index.js"],
      "env": {
        "IMAGE_GEN_DEFAULT_PROVIDER": "openai",
        "IMAGE_GEN_OUTPUT_DIR": "~/Downloads/generated-images",
        "IMAGE_GEN_INPUT_ROOT": "/absolute/path/to/allowed-inputs",
        "OPENAI_API_KEY": "sk-...",
        "OPENAI_DEFAULT_MODEL": "gpt-image-1",
        "OPENAI_EDIT_MODEL": "gpt-image-1.5",
        "ANTHROPIC_API_KEY": "sk-ant-...",
        "GEMINI_API_KEY": "...",
        "REPLICATE_API_TOKEN": "...",
        "TOGETHER_API_KEY": "...",
        "XAI_API_KEY": "...",
        "PHOTOROOM_API_KEY": "...",
        "FAL_KEY": "...",
        "IDEOGRAM_API_KEY": "..."
      }
    }
  }
}

Environment Variables

Variable Description Default
IMAGE_GEN_DEFAULT_PROVIDER Provider used when none specified openai
IMAGE_GEN_OUTPUT_DIR Directory for saved images ~/Downloads/generated-images
OPENAI_API_KEY OpenAI API key -
OPENAI_DEFAULT_MODEL OpenAI model used when model param is omitted gpt-image-1
OPENAI_EDIT_MODEL OpenAI GPT Image model used by image_op edit_prompt gpt-image-1.5
ANTHROPIC_API_KEY Required for image_task. API key for Anthropic Claude Haiku planning. Get one from https://console.anthropic.com/. Calls fail clearly when unset. -
IMAGE_GEN_INPUT_ROOT Optional path-validation root for capability input paths. When set, input paths for extract_subject, edit_prompt, composite_layers.layers[].input, transform, enhance_upscale, and analyze_* must resolve under this root; .. traversal and symlinks outside the root are rejected before invocation. Recommended for image_task because the planner can emit paths the user did not type. unset
GEMINI_API_KEY Google AI Studio API key -
REPLICATE_API_TOKEN Replicate API token -
TOGETHER_API_KEY Together AI API key -
XAI_API_KEY xAI API key -
PHOTOROOM_API_KEY Photoroom API key. Enables extract_subject through the Remove Background API and composite_layers through the Image Editing API with shadow/relighting via photoroom. -
FAL_KEY fal.ai API key. Enables edit_prompt via fal using Flux Kontext as a faster/cheaper mirror to openai. -
IDEOGRAM_API_KEY Ideogram Developer API key. Enables generate via ideogram for text-fidelity generation. -

Only configure API keys for providers you want to use. Providers without keys are automatically disabled.

Checking for new models

Providers regularly release new image models. To see what's currently available from each provider's API and compare against the defaults this server uses:

npm run check-models

The script queries each provider's /models endpoint and prints a report showing which image-capable models exist and which one is currently the default in src/providers/*.ts. Providers without an API key in your environment are skipped. Replicate has no simple listing endpoint and is always skipped — browse https://replicate.com/collections/text-to-image manually.

This is a read-only report; it never changes any defaults. When you spot a new model worth adopting, update the relevant provider's defaultModel in src/providers/*.ts (and the KNOWN_DEFAULTS map in scripts/check-models.ts) by hand.

Usage

Once configured, restart Claude and ask it to generate images:

Basic Usage

Generate an image of a cat astronaut floating in space

Specify Provider

Create an image of a mountain sunset using Gemini
Use Replicate to generate a photorealistic portrait

Specify Size

Generate a landscape image of a beach at golden hour
Create a portrait-oriented image of a city skyline

Specify Model

Generate an image using dall-e-3 of a steampunk robot

Use Style Modifiers

Generate a watercolor painting style image of a forest cabin
Create a pixel art avatar of a wizard

Generate Ready-to-Use Assets

Generate a profile picture of a friendly robot
Create a hero photo of a mountain landscape for my blog

Process Existing Images

Crop this image to 16:9 and resize to 1200x675

Invoke Image Operations Directly

Extract the subject from /path/to/photo.png using image_op
Use image_op to edit /path/to/photo.png with OpenAI: change the background to a clean white studio backdrop

Hand Off a Goal to image_task

Use image_task with goal "remove the background and place this product on a clean white studio surface, 2000px square" and input_images ["/path/to/product.jpg"]

Tool Reference

generate_image

Generate an image from a text prompt.

Parameters

Parameter Type Required Description
prompt string Yes Text description of the image to generate
provider string No openai, gemini, replicate, together, grok
model string No Provider-specific model (see table below)
size string No square (default), landscape, portrait
style string No Style modifier prepended to prompt (e.g., "watercolor painting", "pixel art")
outputPath string No Exact output file path (must end in .png)
outputDir string No Output directory (filename auto-generated)

Provider-Specific Models

Provider Available Models
OpenAI gpt-image-2, gpt-image-1, dall-e-3, dall-e-2
Gemini gemini-2.5-flash-image, gemini-3-pro-image
Replicate Any model on Replicate (e.g., stability-ai/sdxl)
Together black-forest-labs/FLUX.1-schnell, black-forest-labs/FLUX.1-pro
Grok grok-imagine-image, grok-imagine-image-pro, grok-2-image

Response

{
  "success": true,
  "path": "/Users/you/Downloads/generated-images/2026-01-29-openai-cat-astronaut-a1b2c3.png",
  "provider": "openai",
  "model": "gpt-image-1",
  "revisedPrompt": "A cute orange tabby cat wearing a NASA spacesuit..."
}

Size Mappings

Size OpenAI Gemini Replicate/Together
square 1024x1024 1:1 1:1
landscape 1792x1024 16:9 16:9
portrait 1024x1792 9:16 9:16

process_image

Process an existing image with resize, crop, aspect crop, and circle mask operations. Operations execute in the order specified.

Parameters

Parameter Type Required Description
inputPath string Yes Path to the input image file
operations array Yes Processing operations to apply in order (see below)
outputPath string No Output file path (must end in .png). Defaults to {input}_processed.png

Operations

resize — Scale image to target dimensions.

Field Type Required Description
type "resize" Yes
width integer No Target width in pixels
height integer No Target height in pixels
fit string No cover (default), contain, fill
withoutEnlargement boolean No Prevent upscaling beyond source dimensions

crop — Extract a rectangular region.

Field Type Required Description
type "crop" Yes
x integer Yes Left offset in pixels
y integer Yes Top offset in pixels
width integer Yes Crop width in pixels
height integer Yes Crop height in pixels

aspectCrop — Crop to a standard aspect ratio with gravity control.

Field Type Required Description
type "aspectCrop" Yes
ratio string Yes 1:1, 16:9, 9:16, 4:3, 3:4
gravity string No center (default), north, south, east, west

circleMask — Apply a circular mask with transparent background.

Field Type Required Description
type "circleMask" Yes

Response

{
  "success": true,
  "inputPath": "/path/to/input.jpg",
  "outputPath": "/path/to/input_processed.png",
  "originalSize": { "width": 2048, "height": 2048 },
  "outputSize": { "width": 1200, "height": 675 },
  "operationsApplied": ["aspectCrop(16:9, center)", "resize(1200x675, cover)"]
}

generate_asset

Generate a ready-to-use image asset with automatic post-processing. Combines generation and processing in one call.

Parameters

Parameter Type Required Description
prompt string Yes Text description of the image to generate
assetType string Yes Asset preset (see table below)
provider string No openai, gemini, replicate, together, grok
model string No Provider-specific model
style string No Style modifier prepended to prompt
assetId string No Clean filename identifier (e.g., "my-avatar"my-avatar.png)
outputPath string No Exact output file path (must end in .png)
outputDir string No Output directory

Asset Presets

Type Output Pipeline
profile_pic 200x200, circular Square gen → 1:1 crop → circle mask → resize
post_image 1200x675, 16:9 Landscape gen → 16:9 crop → resize
hero_photo 1080x1920, 9:16 Portrait gen → 9:16 crop → resize (no upscaling)
avatar 80x80, circular Square gen → 1:1 crop → circle mask → resize
scene 1200x675, 16:9 Landscape gen → 16:9 crop → resize

Each preset automatically selects the best generation size for the provider and applies a sequence of post-processing operations to produce a consistent output.

Response

{
  "success": true,
  "path": "/Users/you/Downloads/generated-images/my-avatar.png",
  "provider": "openai",
  "model": "gpt-image-1",
  "assetType": "avatar",
  "outputSize": { "width": 80, "height": 80 },
  "operationsApplied": ["aspectCrop(1:1, center)", "circleMask", "resize(80x80, cover)"]
}

If post-processing fails, the raw generated image is saved as a fallback with a warning field in the response.


image_op

Invoke a registered image capability directly by operation and provider. This is useful for targeted image operations that are not pure text-to-image generation.

Current Capabilities

Operation Provider Requires Description
extract_subject @imgly/local params.input Removes the background from a local image using @imgly/background-removal-node. No API key required.
extract_subject photoroom PHOTOROOM_API_KEY, params.input Removes the background using Photoroom Remove Background API. Produces a flat alpha cutout; shadow output is handled by composite_layers:photoroom.
edit_prompt openai OPENAI_API_KEY, params.input, params.prompt Edits a local image using OpenAI GPT Image through the JSON Images API. Defaults to OPENAI_EDIT_MODEL=gpt-image-1.5.
edit_prompt fal FAL_KEY, params.input, params.prompt Edits a local image using fal.ai Flux Kontext (fal-ai/flux-pro/kontext).
composite_layers sharp params.canvas, params.layers[] Deterministic local PNG composition using sharp.
composite_layers photoroom PHOTOROOM_API_KEY, params.canvas, params.layers[] Single-subject product composition through Photoroom Image Editing API. Accepts params.canvas, exactly ONE entry in params.layers, optional params.shadow.enabled for shadow/relighting, optional params.canvas.background RGB color, and optional params.background.color/params.background.prompt. Rejects per-layer placement fields (x, y, scale, opacity, anchor) because Photoroom's API does not consume them; use composite_layers:sharp for placement. Delivers PROV-01's (with shadow) qualifier through Image Editing shadow.
generate ideogram IDEOGRAM_API_KEY, params.prompt Generates a PNG through Ideogram 3.0 and downloads the ephemeral image URL.
transform sharp params.input, params.operations[] Applies deterministic local transforms such as resize, crop, rotate, flip, blur, sharpen, grayscale, and format conversion.
enhance_upscale replicate REPLICATE_API_TOKEN, params.input Runs a Replicate image upscaler/enhancer and downloads the resulting image.
analyze_dimensions sharp params.input Reads image dimensions and metadata locally.
analyze_palette sharp params.input Extracts dominant color information locally.
analyze_ocr tesseract params.input Runs local OCR and returns detected text metadata.

Photoroom, fal, and Ideogram are exposed through image_op once their API keys are present. image_task uses eval-populated quality.scores when choosing among competing providers. The Photoroom composite_layers adapter delivers the (with shadow) qualifier through the Image Editing API; the extract_subject adapter uses the simpler Remove Background API and produces a flat alpha cutout.

Parameters

Parameter Type Required Description
op string Yes Operation name: extract_subject, edit_prompt, composite_layers, transform, enhance_upscale, analyze_dimensions, analyze_palette, analyze_ocr, or generate.
provider string Yes Capability provider. Use list_capabilities to see registered pairs such as @imgly/local, openai, sharp, replicate, tesseract, photoroom, fal, or ideogram.
params object No Operation-specific parameters.
outputPath string No Exact output file path (must end in .png).
outputDir string No Output directory (filename auto-generated).

extract_subject Params

Field Type Required Description
input string Yes Absolute or relative path to the source image.

Example:

{
  "op": "extract_subject",
  "provider": "@imgly/local",
  "params": {
    "input": "/Users/you/Pictures/photo.png"
  },
  "outputDir": "/Users/you/Downloads/generated-images"
}

edit_prompt Params

Field Type Required Description
input string Yes Absolute or relative path to the source image.
prompt string Yes Edit instruction, up to 4000 characters.
size string No square, landscape, or portrait.

Example:

{
  "op": "edit_prompt",
  "provider": "openai",
  "params": {
    "input": "/Users/you/Pictures/photo.png",
    "prompt": "Change the background to a clean white studio backdrop",
    "size": "square"
  },
  "outputDir": "/Users/you/Downloads/generated-images"
}

Response

{
  "success": true,
  "output": "/Users/you/Downloads/generated-images/2026-05-01-openai-edit-prompt-openai-a1b2c3.png",
  "runId": "run-2026-05-01T22-20-57-411Z-22e913",
  "trace": {
    "nodes": [
      {
        "id": "n1",
        "op": "edit_prompt",
        "provider": "openai",
        "model": "gpt-image-1.5",
        "output": "/Users/you/Downloads/generated-images/2026-05-01-openai-edit-prompt-openai-a1b2c3.png",
        "latencyMs": 21400
      }
    ]
  }
}

list_capabilities

Lists the registered (op, provider) pairs available in the current process, including provider constraints, latency/cost hints, and eval-populated quality scores when available. Use this tool before calling image_op if provider availability may depend on API keys or local optional binaries.


image_task

Hand off a natural-language image goal and receive a final image plus a structured trace. The MCP plans a DAG of capability invocations using Anthropic Claude Haiku, validates it, executes it, and returns paths only — never base64.

Requires ANTHROPIC_API_KEY.

Parameters

Parameter Type Required Description
goal string Yes Natural-language description of the desired image outcome
input_images string[] No Absolute paths to input images. Validated against IMAGE_GEN_INPUT_ROOT when set
constraints object No {output_size, output_format, quality_tier, budget_cap_usd, latency_cap_seconds, style_refs}
dry_run boolean No When true, return the validated plan and estimated totals without invoking any provider
runId string No Reuse an existing runId; otherwise auto-generated
outputDir / outputPath string No Standard output rules apply

Dry-Run Preview

Set dry_run: true to see the validated plan without paying for any provider call. This is useful for checking provider routing and estimated cost before execution.

Budget Cap

Set constraints.budget_cap_usd to enforce a maximum estimated cost. If the plan exceeds the cap, the call returns BUDGET_CAP_EXCEEDED before any provider is called. The error includes estimated_cost_usd and cap_usd.

Response Shape

{
  "success": true,
  "output": { "path": "/path/to/final.png", "mimeType": "image/png" },
  "runId": "run_20260503_120000_abcdef",
  "total_cost_usd": 0.04,
  "total_latency_ms": 8200,
  "plan": {
    "goal": "...",
    "terminalNodeId": "transform",
    "steps": [
      { "id": "extract", "op": "extract_subject", "provider": "@imgly/local", "dependsOn": [] }
    ]
  },
  "trace": [
    {
      "id": "nextract",
      "op": "extract_subject",
      "provider": "@imgly/local",
      "status": "success",
      "output_path": "/path/to/.runs/run_.../nextract.png",
      "cost_usd": 0,
      "latency_ms": 1100
    }
  ]
}

The trace always returns filesystem paths only — never base64 image data. Intermediate artifacts live under <outputDir>/.runs/<runId>/.

Provider Breadth Evals

Run the provider evals after configuring provider keys:

PHOTOROOM_API_KEY=... FAL_KEY=... IDEOGRAM_API_KEY=... npm run eval

These cases use deterministic scorers only. Photoroom extract_subject uses alpha_coverage and pixel_delta for subject and edge preservation. Photoroom composite_layers runs through the Image Editing API with params.shadow.enabled: true and is scored with alpha_coverage on the Photoroom output. The routing question is "did Photoroom produce a clean alpha-aware product composite with shadow/relighting?" — the input baseline used by pixel_delta was removed because the adapter does not consume params.input; alpha_coverage measures the same routing signal directly on the Photoroom output. This is where PROV-01's (with shadow) qualifier is satisfied per D-15. fal Flux Kontext mirrors existing OpenAI edit_prompt fixtures and uses pixel_delta plus ocr_text_presence for instruction success on text edits. Ideogram generate uses ocr_text_presence with expectedText to measure text fidelity.

image_op allows immediate direct exploration of registered providers once API keys are present. image_task planner preference requires eval-populated quality.scores; a second provider should show either a >=0.03 relevant quality-score edge or a >=20% latency/cost edge above the acceptable quality floor before displacing an incumbent.

Trace metadata explains routing decisions:

  • metadata.qualityMeasured: whether the selected capability has eval scores.
  • metadata.qualityScores: the scorer values used for route comparison.
  • metadata.noIncumbentComparison: emitted when the provider is the only registered provider for its op.
  • metadata.qualityUnavailable: emitted when no legal provider for the op has measured quality.
  • Photoroom also reports metadata.api (remove-background or image-editing) and metadata.shadowApplied so users can verify which Photoroom path ran.

Example Photoroom composite trace node:

{
  "id": "n1",
  "op": "composite_layers",
  "provider": "photoroom",
  "outcome": "success",
  "metadata": {
    "provider": "photoroom",
    "modelVersion": "photoroom-image-editing-v1",
    "api": "image-editing",
    "shadowApplied": true,
    "qualityMeasured": true,
    "qualityScores": { "alpha_coverage": 0.95 }
  }
}

Live Human Verification

Run this when verifying provider-breadth routing with real provider credentials:

# 1. Run all provider-breadth evals (Photoroom extract + composite, fal Flux Kontext, Ideogram).
PHOTOROOM_API_KEY=sk-... \
FAL_KEY=fal_... \
IDEOGRAM_API_KEY=... \
npm run eval

# 2. Confirm the registry now shows quality.scores for all four provider-breadth surfaces.
npm run start &
# In another terminal, send a list_capabilities MCP request through your client and
# confirm extract_subject:photoroom, composite_layers:photoroom, edit_prompt:fal,
# and generate:ideogram each have a non-empty quality.scores object.

# 3. Drive a product-photography best-tier image_task and inspect the trace.
#    From your MCP client, call image_task with:
#      { goal: "product photo on a clean white surface with soft shadow",
#        input_images: ["/path/to/product.jpg"],
#        constraints: { quality_tier: "best" } }
#    Confirm the returned trace shows composite_layers selected with
#    provider=photoroom, metadata.qualityMeasured=true, metadata.api="image-editing",
#    metadata.shadowApplied=true, and a non-empty metadata.qualityScores.

If step 1 produces a case→adapter contract mismatch error for any case, the case JSON in eval/cases/ does not match the resolved adapter's constraints.requiresInputImage declaration. Fix the case (remove orphan params.input or change scorers/adapter contract) before re-running. The lint exists to make this loud rather than silently populate an invalid quality.score.

After a successful eval run, list_capabilities shows populated quality.scores for extract_subject:photoroom, composite_layers:photoroom, edit_prompt:fal, and generate:ideogram. PROV-01 is satisfied by two Photoroom adapters: extract_subject uses the Remove Background API and produces a flat alpha cutout; composite_layers:photoroom uses the Image Editing API on a single subject with shadow/relighting and is scored with alpha_coverage. The case composite-photoroom-product-with-shadow exercises this path with params.shadow.enabled: true and metadata.shadowApplied: true on the invoke return. PROV-05 (each new provider has at least one valid eval case) holds for all four Phase 11 capability surfaces.

Best-Partial on Failure

If a node fails mid-execution, downstream nodes whose dependencies cannot be satisfied are skipped. The response includes bestPartial: {nodeId, path} for the latest successful image-producing node, failedNodeId for the failed node, and a structured error: {message, code, retryable, suggestion} on that trace entry.

Output Files

Generated images are saved with descriptive filenames:

{date}-{provider}-{prompt-slug}-{hash}.png

Example: 2026-01-29-openai-cat-astronaut-floating-in-space-a1b2c3.png

Provider names are sanitized before filename generation, so capability providers such as @imgly/local produce safe filenames like 2026-05-01-imgly-local-extract-subject-imgly-local-a1b2c3.png.

Troubleshooting

"No image providers or capabilities configured"

No generation provider or local capability registered at startup. Rebuild the project and check the MCP server logs. Remote generation and OpenAI edits require API keys, but local extract_subject should register without one.

"Provider 'X' is not available"

The requested provider doesn't have an API key configured. Either:

  • Add the API key to your MCP configuration
  • Use a different provider that is configured

"Capability not registered"

image_op could not find the requested (op, provider) pair. Check the provider name exactly:

  • extract_subject uses @imgly/local
  • edit_prompt uses openai and requires OPENAI_API_KEY
  • Provider-breadth capabilities require their own API keys: PHOTOROOM_API_KEY, FAL_KEY, or IDEOGRAM_API_KEY

"The model '${OPENAI_EDIT_MODEL}' does not exist"

Restart your MCP client so it reloads the current .mcp.json. The config now defaults OPENAI_EDIT_MODEL to gpt-image-1.5, and the server treats unresolved ${...} placeholders as unset before applying defaults.

Images not appearing

  1. Check the output directory exists and is writable
  2. Look for error messages in the MCP server logs
  3. Verify the IMAGE_GEN_OUTPUT_DIR path is correct

API Errors

Each provider has different rate limits and content policies:

  • OpenAI: Check your API quota at platform.openai.com
  • Gemini: Check your quota at ai.google.dev
  • Replicate: Check your usage at replicate.com
  • Together: Check your usage at together.ai
  • xAI: Check your usage at x.ai

Development

# Install dependencies
npm install

# Build
npm run build

# Watch mode
npm run dev

# Run directly (for testing)
OPENAI_API_KEY=sk-... node dist/index.js

License

MIT