Skip to main content
Glama

OpenRouter Sidecar

Image generation, image editing, and side-advisor chats for Northwestern MPD AI classes, through OpenRouter. Claude stays the main assistant; the Sidecar adds image models and lets Claude consult other models (Gemini, ChatGPT and others) with a deliberately chosen brief. Each student gets their own OpenRouter key from the class automatically, inside their cohort's Northwestern workspace; nobody needs an OpenRouter account.

The Sidecar is a hosted connector: an authenticated remote MCP server on Railway that works in claude.ai, Claude Desktop and Claude Code. There is nothing to install. The earlier local version that ran on each student's computer is retired; see Moving from the local Sidecar to bring its chats across.

Status: instructor testing only. Only the instructor account has access to the hosted server, for acceptance testing. Students are not onboarded yet, and student rollout is on hold until OpenRouter increases organization capacity. Do not point students at it yet.

Repository: jrenaldi79/openrouter-sidecar (private). Adapted from skelly-77/openrouter-image-mcp, with the original MIT license and commit history retained.

Connect

The server runs on Railway (US East, single replica, Postgres for chats and settings, a volume for images):

https://sidecar-production-e110.up.railway.app/mcp

Access. Sign-in is through Auth0. An account needs the sidecar:use permission and a profile claim carrying its cohort's workspace_id. Without them the server answers 403. Auth0 and class membership are managed outside this repository (../mpd-auth).

Cohort

Students

OpenRouter workspace

2027

Capstone, full-time and second-year

Class of 2027 (21082e84-ae02-4639-ad40-c7251b98ab10)

2028

First-year

Class of 2028 (8804f9c5-afd2-4de3-8d9f-f74b3d58c651)

The server takes the workspace from the signed-in profile; there is no personal-account fallback.

1. Add the connector.

  • claude.ai and Claude Desktop: add a custom connector in the Connectors settings, paste the URL above, and sign in when prompted.

  • Claude Code: install the plugin (see Claude Code plugin and skills), or add the server directly. Then run /mcp inside Claude Code to sign in:

    claude mcp add --transport http openrouter-sidecar https://sidecar-production-e110.up.railway.app/mcp

2. Check your account. Ask Claude for account_status. There is nothing to link: the first time you use the Sidecar, the server issues your own OpenRouter key in your cohort's workspace (named Sidecar · <your email> · <cohort>). The key is stored encrypted on the server and used only for your requests. account_status shows the key, what you have spent this month and your budget. Each key has a monthly budget ($25 a month) set on the cohort workspace by the instructor; when it runs out, paid calls fail until it resets. If account_status says no key is available or that your key was disabled, ask your instructor.

3. Try it.

  • Ask a side advisor a question with ask_advisor (see Headless advisor).

  • Generate or edit an image (see Images).

  • In claude.ai and Desktop, ask Claude to "open Sidecar settings" to pick default advisor models.

What is stored on the server: advisor transcripts and any files you chose to send, job metadata and costs, preferences, your encrypted OpenRouter key, and image uploads and results. Auth0 tokens and model reasoning traces are not stored. Chats idle for 90 days are purged, and images are kept for 30 days. See the decision record. The student-facing notice wording is not yet approved.

Per-person limits (server defaults): 2 concurrent advisor jobs, 20 requests per minute and $5.00 per day of reported advisor cost; image calls are limited to 2 at a time and 20 per minute. Advisor sessions are inline by default: files go into the prompt and the advisor has no tools. A chat started with sandbox: true gives the advisor a shell with no network; files sent to it and files it writes stay in the class workspace for 30 days, where instructors (not other students) can see them.

The connector brings its own workflow guide (server instructions) and the class skills, adapted for hosted use, as prompts and skill:// resources: openrouter-image and architectural-render-polish. Nothing needs installing in claude.ai or Claude Desktop, and Claude can pass these skills to an advisor.

Tool permissions. claude.ai asks before each connector tool call; a server can't turn that off. It does group the Sidecar's tools under Connectors → OpenRouter Sidecar → Tool permissions, using the tools' MCP annotations (src/openrouter_image_mcp/tool_annotations.py):

  • Read-only tools are free lookups; setting the whole group to Always allow is safe.

  • Write/delete tools create or change something, or open an in-chat app. ask_advisor, send_advisor_message, generate_image and edit_image cost money; delete_advisor_chat deletes things. The Open… viewers, remask_image, create_image_upload, start_advisor_chat and set_sidecar_preferences are free. The viewers sit here because claude.ai doesn't render the app of a tool labelled read-only.

Reconnect the connector after an update that changes tools: claude.ai keeps the tool list from when it was added. In Claude Code, allow the free tools with permissions.allow entries such as mcp__openrouter-sidecar__account_status.

Operators: see docs/HOSTED_OPERATIONS.md for configuration, Auth0, Railway setup, deployment, key rotation and retention.

Related MCP server: openrouter-imgen-mcp

Tools

Account, images and migration

Tool

What it does

account_status

Shows your sign-in, cohort, your class OpenRouter key (issued on first use), spend this month and budget. No cost.

list_image_models

Discovers available image models and pricing.

get_image_model

Shows model parameters, providers and prices.

create_image_upload

Returns a one-time PUT URL for uploading an image (curl -T file URL); the response holds the asset id.

generate_image

Generates images; results are stored as assets with 24-hour download links and reported cost.

edit_image

Edits images given as asset ids (images=[asset_id], optional mask_id); results are stored as assets.

remask_image

Re-blends a masked edit with a new mask by asset id. Free: no model call.

get_image_download

Returns fresh 24-hour download links for one of your assets.

open_image_uploader

MCP Apps clients only: opens a drop zone that uploads from your computer and adds the asset ids to the conversation.

create_local_import

Returns a one-time link and the two commands that move your local Sidecar chats and settings here (see below).

Advisors and settings

Tool

What it does

list_chat_models

Discovers text advisor models supporting tools, with pricing and context limits.

start_advisor_chat

Creates a chat using an exact ID, a saved brand default, or the general default; no inference.

send_advisor_message

Starts a background advisor job and opens its result viewer; returns status only. Accepts files, images and search.

ask_advisor

Headless: asks an advisor and returns its answer to the caller (wrapped as untrusted output). Creates a session or continues one by chat_id; accepts files, images and search.

wait_advisor_job

Headless: keeps waiting for a long ask_advisor job and returns the same result shape.

list_advisor_chats

Lists your chats.

get_advisor_chat

Shows metadata and a bounded message count, without returning the transcript to the parent model.

reset_advisor_sandbox

Assigns a fresh container while preserving chat history. Only relevant to sandbox chats.

delete_advisor_chat

Deletes the owned transcript and mapping.

retry_advisor_cleanup

Retries exact recorded skill-upload deletions without inference.

get_advisor_job

Checks an owned job's status, cost, and cleanup without reading the answer.

open_advisor_result

Reopens the viewer for an owned job without inserting its response into the parent chat.

open_sidecar_settings

Opens first-use onboarding or lets the user change defaults at any time.

get_sidecar_preferences

Reads defaults, settings ID, save revision, and walkthrough completion.

set_sidecar_preferences

Saves validated defaults atomically; preserves omitted choices and rejects stale saves.

resolve_advisor_model

Resolves Gemini, ChatGPT, Claude or a one-off exact model ID without inference.

get_advisor_result

App-only: retrieves owned partial or final answer text for the viewer.

summarize_advisor_result

App-only: starts a paid summary job, which the viewer shares in place of a long answer.

share_advisor_result

App-only: records that the user shared a result (or its summary) with Claude.

wait_for_advisor_share

Waits (up to 5 minutes a call) while the user reads in the viewer, and returns the answer as soon as they share any answer from that advisor chat.

read_shared_advisor_result

Returns the advisor answers the user shared from the viewer, as untrusted text, and marks them read.

get_sidecar_settings

App-only: loads model choices, pricing, context limits and the cohort.

run_sidecar_demo

App-only: starts an explicitly selected tiny advisor, history or skill demo (the one-image demo is unavailable on the server).

get_sidecar_demo

App-only: reads an owned image demo status and preview without inference.

The app-only operations are omitted for clients without MCP Apps capability.

Headless advisor (subagent mode)

ask_advisor behaves like a subagent: the parent model gets the answer back.

  1. Call ask_advisor(prompt, files=[{path, content}, ...]) without a chat_id. It creates a session, waits up to wait_s seconds (default 25, max 45, with progress notifications), and returns {status: "completed", chat_id, job_id, answer, cost_usd}.

  2. If the advisor needs longer, it returns {status: "running", job_id}. Call wait_advisor_job(job_id) until it completes.

  3. Reuse chat_id for follow-ups. The session keeps its transcript and files, so a later call from any client signed in as the same person continues where it left off. If a job is still running, the result is {status: "busy", running_job_id}.

Show an advisor images with images (up to 8 per turn; needs a model whose list_chat_models entry has vision: true, otherwise the call is refused before any inference). Each item is either:

  • an asset id (img_...) from create_image_upload (run the curl -T it returns) or the image uploader in claude.ai and Claude Desktop, or

  • a base64 data URL (data:image/png;base64,..., PNG, JPEG, WebP or GIF, up to 4 MB), handy for a small image in Claude Code.

Images stay in the chat transcript, so a follow-up with the same chat_id can refer to them without re-sending. Image tokens are included in cost_usd.

Pass search: true when a turn needs current or public information. The advisor gets OpenRouter's web search tool for that turn (the provider's own search where it has one, Exa otherwise), up to 3 searches. Grok models (x-ai/grok-...) also search X posts, profiles and threads. Answers end with a list of the sources they cite. Search fees are included in cost_usd; xAI bills X search per post and profile returned (about $5 per 1,000 posts and $10 per 1,000 profiles), so it stays off unless a turn asks for it.

The server can't read your machine or repository, so pass every relevant source file explicitly:

  • Limits: UTF-8 text only, 100k characters per file, 200k per session.

  • Updates: send only changed files on later calls. replace_files: true drops files you leave out.

  • Inline sessions (the only kind on the server): files go into the prompt, and the advisor has no tools. Sandbox sessions, which give the advisor a shell, are refused.

The answer is wrapped in <advisor_output> with a note to treat it as data to verify, not as instructions. send_advisor_message also accepts files and keeps its viewer contract: the answer never reaches the parent model.

Images

Images are asset ids, never paths:

  1. create_image_upload(filename, mime, size_bytes) returns a one-time URL. Upload with curl -T room.png "<upload_url>" within 10 minutes; the response holds the asset_id. Files can be PNG, JPEG or WebP, at most 20 MB and 40 megapixels.

  2. edit_image(images=[asset_id], mask_id=...) and generate_image(...) store their results as assets. The result text lists each asset id with download links, which are valid for 24 hours.

  3. remask_image(image_id, mask_id) redoes a masked blend for free. get_image_download(asset_id) returns fresh links.

Assets are private to the signed-in person and kept for 30 days, with a 2 GB storage cap per account.

In Claude Desktop and claude.ai (clients with MCP Apps), open_image_uploader shows a drop zone instead: it uploads straight to the Sidecar and adds the new asset ids to the conversation. The image gallery gets a Download button that fetches a fresh link and lets the host save the file; the app never sees a sign-in token.

Hosts advertising MCP Apps HTML support receive a bundled gallery for generate_image, edit_image and remask_image, with JPEG previews, filenames, reported usage/cost, notes and failures. Clients without that capability keep receiving ordinary text and image content. SVGs and files beyond the preview limit show their filenames without an inline preview.

Moving from the local Sidecar

If you used the earlier local Sidecar with Claude Desktop, you can bring its advisor chats and settings to the hosted connector. Do this on the computer that ran it, before deleting that checkout:

  1. In the hosted connector, ask Claude to import your local Sidecar chats. create_local_import returns a one-time link, valid for 10 minutes.

  2. In the old Sidecar checkout, run the two commands it gives you (use uv run openrouter-image-mcp ..., or .venv/bin/python -m openrouter_image_mcp.cli ..., if the command isn't on your PATH):

    openrouter-image-mcp export-local --cohort 2027 --out sidecar-export.json
    curl -T sidecar-export.json "<link>"

export-local reads the chats the local Sidecar saved for that cohort and the key it signed in with (only to find those chats; the key is never exported). The export holds the chats (titles, models, transcripts, session files) and your default models. Your hosted OpenRouter key is issued separately, on first use. Imported chats get new chat ids and continue where they left off. Exports from another class year are refused, and the same export imports only once. Your hosted settings are only filled in if you haven't chosen any yet. Delete the export file afterwards, since it contains your transcripts. Once the import is done, remove the old Sidecar entry from Claude Desktop's configuration.

Cost and privacy

Prompts and input images go through OpenRouter to third-party providers. Get explicit permission before uploading other people's images, research materials or confidential project information. Start with one low-cost draft and relay reported spending. Use the live catalog for model choice and prices. The reported cost is whatever OpenRouter returns, not an independent guarantee of total spending. Budgets are administered in OpenRouter (each cohort workspace's default guardrail); this server creates one key per student but never sets or raises a budget. Instructors manage student keys with scripts/ops/openrouter_keys.py (see docs/HOSTED_OPERATIONS.md). Nothing replays a potentially billed request automatically after a timeout or provider error.

Advisor settings and viewer

For first use, ask “Use openrouter-sidecar to open onboarding.” The app confirms the cohort and sign-in, then offers a general advisor default plus Gemini/Google, ChatGPT/OpenAI, Grok/xAI and Open Weight defaults. Open Weight choices are limited to GLM, Qwen, Kimi, MiniMax and DeepSeek. All choices, including the general default and list_chat_models, use the same approved families and a rolling six calendar months of OpenRouter catalog age. Models with missing, invalid or future dates are omitted. OpenRouter's created field is its listing date, not necessarily the original model release date. Claude is omitted from setup. Choices show exact OpenRouter IDs, context limits and catalog pricing in USD per million tokens. Batch model variants are omitted. Saving choices is free and automatic; a failed save offers a deliberate retry. The general advisor is required to finish setup, and brand defaults are optional. Later ask “Open Sidecar settings” or “Change my default Gemini model.”

start_advisor_chat(model="Gemini") resolves the saved Google default; omit model for the general default; model="Open Weight" uses the saved Open Weight choice. An exact ID overrides only that new chat. Existing chats retain their models. Missing, retired or aged-out defaults require a replacement in settings. Starting or listing chats does not run inference; sending a message incurs model charges. Defaults are stored per signed-in person and workspace.

The How it works visual guide explains separate advisor conversations, model defaults, relevant skill handoffs, image generation, and controlled return of results. The main assistant selects relevant available shareable skill instructions and deliberately sends them with the brief. Sidecar does not automatically scan installed plugins or synchronize local skill files. Follow-ups use the advisor's own saved history; the main chat chooses any additional context to include. The guide has no live demo controls: navigation, preferences, and Finish do not invoke inference.

send_advisor_message promptly returns a job_id and status; the full response stays in the database. In MCP Apps hosts, the viewer polls UI-only result metadata and displays streamed answer text, with the original user prompt collapsed. System prompts, appended skill instructions, shell output, and reasoning traces are not displayed. Opening, scrolling or polling does not update the parent model context. While a reply streams, the viewer shows a live status with elapsed time. Share with Claude is one click: it saves the share on the server without posting a chat message, and Claude reads it with read_shared_advisor_result (Claude's next Sidecar call also notes any unread share). Answers over 3,000 characters are summarized first by a fast summary model, Gemini 3.5 Flash Lite unless SIDECAR_SUMMARY_MODEL says otherwise (paid, a fraction of a cent; it sees only the answer, and the status line shows progress), and shorter ones are shared whole for free. If the summary fails, the viewer says so and offers the full answer instead. More → Share full answer always shares the whole answer for free; More also holds Copy answer. After sharing, tell Claude you shared it. Send follow-up messages the advisor in the same chat (paid). If the share can't be saved, sharing copies the text to the clipboard, or shows it read-only for manual copy when the clipboard is blocked. Use get_advisor_job to check status, or open_advisor_result to reopen a viewer.

Jobs run inside the server process and continue while the viewer is closed. A deploy interrupts unfinished jobs: they are marked interrupted, any retained answer text is labelled partial, and they are never replayed automatically. Advisor inference has a 30-minute total deadline. The chat lock lasts 40 minutes to cover inference and cleanup.

Skills sent with a brief

Claude selects relevant skills and supplies packets with name, content, and optional source and version. Supply supporting Markdown/text as additional named packets. A path or skill name alone does not share Claude's filesystem or connectors. Only shareable, nonconfidential instructions belong in this cohort arrangement; private skills or private task artifacts need a different provider boundary. Up to 20 uniquely named packets, totaling 250 KB, are sent. Complex plugins requiring unavailable tools, executable assets, or subagents still require main-chat assistance.

Claude Code plugin and skills

The repository is a Claude Code plugin marketplace (.claude-plugin/marketplace.json). Its openrouter-image plugin (plugin/) adds the hosted connector over HTTP (plugin/.mcp.json) together with the class skills, so /plugin install sets up both; run /mcp afterwards to sign in. skills/openrouter-image carries the general workflow; skills/architectural-render-polish remains optional. Run uv run python scripts/sync_plugin_skills.py after source skill changes to refresh the plugin's copy.

Development and contributing

Docs for each audience:

Topic

File

Operating the hosted server (config, Auth0, Railway, deploys, key rotation, retention)

docs/HOSTED_OPERATIONS.md

Synthetic local end-to-end stack with a fake identity provider and fake OpenRouter

docs/E2E_LOCAL.md

Hosted design and decisions

design, decision record

Every document, classified

docs/index.md

Contributor and agent guidance

CLAUDE.md, plus a CLAUDE.md note in each source folder and path-scoped rules in .claude/rules/

The project is Python 3.12+ managed with uv. The command line runs the hosted server (serve-http), its maintenance commands (purge, active-jobs) and export-local. Run the tests and lint with:

uv sync
uv run pytest -q
uv run ruff check

Live tests are excluded by default because they use OpenRouter and may cost money; run them with OPENROUTER_LIVE_KEY=... uv run pytest -m live. Postgres-only tests run with TEST_DATABASE_URL=... uv run pytest -m pg.

Enable the contributor harness once per clone: git config core.hooksPath .githooks. The pre-commit hook runs the secret scan, missing-test and file-size checks, the documentation check, the MCP App bundle check, ruff and the unit suite. Documentation is generated by node scripts/self-documentation/generate.js (add --check to validate); see CLAUDE.md for the full list of gates and gotchas.

The MCP App HTML in src/openrouter_image_mcp/ui/ is generated and committed. Node is only needed to change or rebuild it, not to run the server:

npm --prefix ui ci
npm --prefix ui run build
npm --prefix ui test

Browser tests use Playwright's pinned Chromium. They exercise the bundled viewers with a synthetic image and a mock MCP Apps host, without OpenRouter calls.

Original project provenance remains in the Git remote and MIT license. Keep student roster data in the roster spreadsheet.

Available Tools

8 tools
account_statusA

Show whether this computer is signed in to OpenRouter, with the key's spending.

Reports the key label, usage today / this week / this month / in total, and the key's spending limit and remaining credit. If a sign-in is in progress, shows its status and link. Use it after auth_login to confirm sign-in finished, or when the user asks about cost, usage or credits. Takes no parameters.

Inputs: no named parameters.

auth_loginA

Sign in to OpenRouter in the user's browser.

Opens the OpenRouter sign-in page and returns at once with a link. Show the link to the user in case the browser didn't open (it contains no secret). The user finishes in the browser; then call account_status to confirm. The new key is stored in the OS credential store and is never shown. Does nothing if already signed in, unless switch_account is true.

Args: switch_account: true to sign in as a different account or workspace. The current key is kept until the new one is stored.

Inputs: switch_account.

auth_logoutA

Sign out: delete the stored OpenRouter key from this computer.

The key stays valid on OpenRouter until it is deleted on the keys dashboard; the result links that page. Takes no parameters.

Inputs: no named parameters.

edit_imageA

Edit an image (or create one from reference images) with an OpenRouter image model.

Call list_image_models first to choose a model, picking one whose inputs column says "text+image". Options are checked against the model before anything is sent.

The input images are uploaded to a third-party model provider through OpenRouter: get the user's OK before sending client or project images to third-party providers. Each call costs money on the user's OpenRouter account; the result reports the cost.

All paths must be absolute (or start with "~"); relative paths are rejected. Results are saved next to the first input image (never overwriting it) with a JSON sidecar, unless output_dir is given. The result lists the saved paths, notes, failures, model, provider, time and cost, plus JPEG previews.

Args: prompt: The change to make, e.g. "make it dusk with warm window light". model: Model id from list_image_models. images: Absolute paths of the input images. The first is the image being edited; any others are references. mask_path: Optional absolute path of a mask for the first image: white = change, black = keep. The edit is composited locally, so only the white area changes, but there may be a visible lighting seam at the mask edge where new and old pixels meet; a soft mask edge or mask_feather_px helps. Requires fit="preserve". A masked edit also saves the model's image before the blend as <result>.unmasked.png, so remask_image can redo the blend with a different mask for free. mask_feather_px: Blur radius in pixels for the mask edge; by default it is chosen from the image size. fit: "preserve" (default) returns each result at exactly the first input's pixel size: the server picks the model's closest aspect ratio, then scales and crops back (padding the input first if no ratio is close). With fit="preserve" don't pass aspect_ratio or size. "model" keeps the size the model returns and lets you choose aspect_ratio. n: Number of images, 1 to 10. Above the model's max n, the server splits them into several calls (each billed) and says so in the notes. aspect_ratio: One of the model's aspect ratios (only with fit="model"). resolution: One of the model's resolution tiers. size: Exact pixel size such as "1024x1024" (only with fit="model"). quality: One of the model's quality values. seed: Integer for repeatable results, for models that support it. background: One of the model's background values, e.g. "transparent". output_format: One of the model's output formats, e.g. "png". output_dir: Folder to save into instead of next to the first input. Must be an absolute path or start with "~". filename_prefix: File name stem; defaults to the first input's name. provider_options: Provider passthrough options as a flat dict, e.g. {"moderation": "low"}. Keys must be in the model's passthrough parameters (see get_image_model); the server sends each key to every provider that allows it. Any other key is rejected before anything is spent.

Inputs: model (required), images (required), prompt (required), n, +13 more.

generate_imageA

Generate new images from a text prompt with an OpenRouter image model.

Call list_image_models first to choose a model, and get_image_model for its exact allowed values. Options are checked against the model before anything is sent: an invalid value fails with the allowed values and costs nothing.

Each call costs money on the user's OpenRouter account; the result reports the cost. Prompts go to a third-party model provider through OpenRouter: get the user's OK before sending client or project images or details to third-party providers.

Images are saved (never overwriting) to the configured output folder with a JSON sidecar of the settings used. The result lists the saved paths, any notes and failures, the model, provider, time and cost, plus JPEG previews.

Args: prompt: What to create. model: Model id from list_image_models. n: Number of images, 1 to 10. Above the model's max n, the server splits them into several calls (each billed) and says so in the notes. aspect_ratio: One of the model's aspect ratios, e.g. "16:9". resolution: One of the model's resolution tiers. size: Exact pixel size such as "1024x1024", for models that support it. quality: One of the model's quality values. seed: Integer for repeatable results, for models that support it. background: One of the model's background values, e.g. "transparent". output_format: One of the model's output formats, e.g. "png" or "svg". output_dir: Folder to save into instead of the default. Must be an absolute path or start with "~". filename_prefix: File name stem; defaults to a slug of the prompt. provider_options: Provider passthrough options as a flat dict, e.g. {"moderation": "low"}. Keys must be in the model's passthrough parameters (see get_image_model); the server sends each key to every provider that allows it. Any other key is rejected before anything is spent.

Inputs: model (required), prompt (required), n, seed, +9 more.

get_image_modelA

Show full details for one image model.

Returns the description, the capabilities, and one section per provider endpoint with its supported parameters and allowed values, the passthrough parameters usable in provider_options, and its pricing line items.

Args: model_id: Exact model id from list_image_models.

Inputs: model_id (required).

list_image_modelsA

List the image models available on OpenRouter right now, as a markdown table.

Use this before generate_image or edit_image to choose a model and see which options it takes. The catalog is live (cached for 10 minutes), so don't rely on remembered model ids. Columns: id, name, inputs ("text", or "text+image (max N)" input images), aspect ratios, resolutions, quality values, max n per call, seed support, whether the provider moderates prompts (yes/no/?), and a price summary ($/img-unit per image-output unit, $/image, or $/tok per completion token). Call get_image_model for one model's per-provider details.

Args: query: Case-insensitive text to find in the model id or name. accepts_images: true for models that take input images (needed by edit_image); false for text-only models. author: Only this author's models: the part of the id before "/". sort: "newest" (default, newest first) or "price" (cheapest first).

Inputs: sort, query, author, accepts_images.

remask_imageA

Redo the mask blend of a masked edit_image result with a new mask: free and offline.

Use it when a masked edit came back with a good change that blends badly, such as a seam or a ghosted edge where the model drew past the mask (a limb or shadow cut off at the mask edge), or when the mask should have been bigger or smaller. Draw a new mask and call this instead of paying for another edit_image: it re-blends the model's image that the edit already returned, on this computer. Nothing is uploaded, no model is called and it costs nothing.

It needs a result made by edit_image with mask_path by openrouter-image-mcp 0.2.0 or later: those keep the model's image before the blend as <result>.unmasked.png, next to the result and its .json sidecar. The original input image must still be in place and unchanged. A re-masked result can itself be re-masked.

All paths must be absolute (or start with "~"); relative paths are rejected. The new image is saved as a PNG next to image (never overwriting) with a JSON sidecar, unless output_dir is given. The result lists the saved path, plus a JPEG preview.

Args: image: Absolute path of a masked edit_image result (or of an earlier remask_image result). mask_path: Absolute path of the new mask for the original input: white = take the model's image, black = keep the original. Any size; it is stretched to the input's size. mask_feather_px: Blur radius in pixels for the mask edge; by default it is chosen from the image size. output_dir: Folder to save into instead of next to image. Must be an absolute path or start with "~".

Inputs: image (required), mask_path (required), output_dir, mask_feather_px.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.3/5.0

    Scored across 8 tools

    Disambiguation4/5

    Each tool targets a distinct action or resource: authentication (auth_login, auth_logout, account_status), model discovery (list_image_models, get_image_model), and image operations (generate_image, edit_image, remask_image). The only pair with potential overlap is list_image_models vs get_image_model, but they are clearly differentiated as list vs detail. No tool boundaries are confusing.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern: auth_login, list_image_models, get_image_model, generate_image, auth_logout, account_status, edit_image, remask_image. The prefix 'auth_' and 'image' nouns are used predictably.

    Tool Count5/5

    Eight tools are well-scoped for an image generation and editing server with authentication. Each tool has a clear purpose and no redundancy; the set covers the full workflow from sign-in to model discovery to image generation, editing, and local re-masking.

    Completeness5/5

    The surface covers the complete lifecycle: authentication (login, logout, status), model discovery (list, get), image generation, editing with masking, and free local re-masking. It even anticipates advanced use cases like mask adjustments without extra cost. No obvious gaps for the stated domain.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers