openai-image-mcp
Provides tools for generating and editing images through the OpenAI Images API, including prompt-based generation, image/mask edits from prior result IDs or public URLs, configurable size, quality, background, and output format, and returning stored image URLs with usage and model metadata.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
openai-image-mcp
A small, single-user remote MCP server on Cloudflare Workers. Claude can generate and edit images through the OpenAI Images API. Full-size images stay in R2; tool results contain unguessable public URLs, IDs, token usage, the model used, and optional small JPEG previews.
Stack and defaults
TypeScript,
agentsMcpAgent, MCP Streamable HTTP at/mcp.@cloudflare/workers-oauth-provider: OAuth 2.1, browser-bound consent, PKCE, dynamic client registration, and Client ID Metadata Documents. The owner signs in withAUTH_PASSWORD; no external identity provider is required.R2 (
IMAGES_BUCKET), Images (IMAGES), a SQLite Durable Object (IMAGE_MCP), and OAuth KV (OAUTH_KV).Default
IMAGE_MODEL:gpt-image-2.5-sunburst, confirmed inopenai@7.47.0's installedresources/images.d.ts. That package also lists the same-generationgpt-image-2.5-flare; sunburst is the chosen default. SetIMAGE_MODELinwrangler.jsoncto change it. The OpenAI package is a development-only reference; the Worker usesfetchdirectly.The current
agentspackage additionally imports the optional peer@modelcontextprotocol/server. It is explicitly installed for bundling; thisMcpAgentstill uses the v1@modelcontextprotocol/sdkserver API as required by its installed types and runtime.
Related MCP server: nano-banana-mcp-app
Setup and deployment
Use Node.js 24 or newer and a Cloudflare account with Workers, R2, KV, Durable Objects, and Images transformations enabled.
npm ci
npx wrangler login
npx wrangler r2 bucket create openai-image-mcp
npx wrangler kv namespace create OAUTH_KVThe committed wrangler.jsonc contains only an all-zero placeholder KV ID. For your deployment, copy it to wrangler.local.jsonc, which is git-ignored:
cp wrangler.jsonc wrangler.local.jsoncIn wrangler.local.jsonc, replace the placeholder KV ID with the ID printed by the last command. Adjust the R2 bucket name if needed. To serve the Worker on a custom domain, add a routes entry such as "routes": [{ "pattern": "mcp.example.com", "custom_domain": true }]. Configure these Worker secrets interactively:
npx wrangler secret put OPENAI_API_KEY -c wrangler.local.jsonc
npx wrangler secret put AUTH_PASSWORD -c wrangler.local.jsoncUse a restricted OpenAI project key with only the necessary image-model/API permissions and a long, randomly generated authorization password. Keep both private; never put real values in wrangler.jsonc or committed files.
npm run typecheck
npm test
npx wrangler deploy --dry-run -c wrangler.local.jsonc --outdir dist
npx wrangler deploy -c wrangler.local.jsoncnpm run deploy runs the same deploy command with wrangler.local.jsonc.
In claude.ai → Settings → Connectors → Add custom connector, paste:
https://openai-image-mcp.<your-workers-subdomain>.workers.dev/mcpUse the actual URL printed by Wrangler (or your Worker custom domain). Complete OAuth in the browser, verify the client's name/domain and redirect destination, enter AUTH_PASSWORD, and click Allow. The same origin publishes OAuth discovery, /authorize, /oauth/register, and /oauth/token. No separate client secret or third-party login is needed. Requests to /mcp without a valid OAuth bearer token receive 401; the images scope is enforced.
Tools
generate
Input | Values / default |
| Required, nonempty text; at most 1500 UTF-8 bytes |
|
|
|
|
| Integer 1–4, default 1 |
|
|
|
|
edit
prompt and images are required. images has 1–16 entries, each a previous result's 22-character image ID or a public https URL. Optional mask takes the same reference format; supply a PNG with transparency marking the area to edit, matching the source dimensions. size, quality, background, and output_format are the same as generate. There is no n parameter for edit.
IDs are resolved directly from R2, without downloading through the public endpoint. URLs are downloaded server-side; PNG, JPEG, and WebP are accepted, with a 50 MiB limit per downloaded image, a 30-second fetch timeout, and at most three redirects. Redirect destinations are checked again. HTTP, embedded credentials, localhost, and IP literals are rejected; Workers' global_fetch_strictly_public flag also blocks private DNS destinations. The OpenAI request has a 180-second timeout. Additional model-specific input constraints are reported by OpenAI.
A transparent background cannot be combined with JPEG; choose PNG or WebP.
Results and errors
The first MCP content block is JSON text, also exposed as structuredContent:
{
"images": [
{
"id": "aB0123456789cDeF012345",
"url": "https://openai-image-mcp.example.com/img/aB0123456789cDeF012345",
"preview": true
}
],
"usage": { "total_tokens": 42 },
"model": "gpt-image-2.5-sunburst"
}Each available preview follows as an MCP image content block in result order: JPEG, quality 75, long edge at most 512 px, preserving aspect ratio and never upscaling. Full-size base64 is never included in results. preview: false means no preview was available. If the Images binding is absent, generation/editing still succeeds without previews. If a transformation fails, the stored image remains accessible and the summary includes a warning. No image-processing WASM dependency is used. usage is preserved from OpenAI, or null if absent; the returned model is the response's model when available, otherwise the requested one.
Input and upstream failures are MCP tool errors (isError: true). Errors name invalid fields, include OpenAI HTTP status/code/message/parameter, and name the exact ID or URL that failed to resolve. Expired IDs should be replaced with a current result ID or downloadable URL.
R2 storage and 30-day expiration
Each object has key img/{id}.{ext}, correct HTTP Content-Type, and custom metadata prompt, model, size, and created-at (ISO 8601). The entire validated prompt is stored. R2 custom metadata is limited to 2 KiB, so prompts are deliberately capped at 1500 UTF-8 bytes to leave room for the other fields. Size metadata uses the OpenAI response's size when supplied, otherwise the requested size (possibly auto).
To automatically delete images after 30 days:
In the Cloudflare dashboard, open R2 → openai-image-mcp → Settings → Object lifecycle rules.
Add an enabled rule named
expire-generated-images-30-days.Set its prefix to
img/and the action to Delete objects after 30 days.Save the rule. It also applies to existing matching objects based on their age; lifecycle processing is asynchronous.
GET /img/:id (and HEAD) is intentionally public and serves only stored image bytes, not custom metadata. Unknown/expired IDs return 404. IDs use unbiased, cryptographically random 22-character base62 strings (about 131 bits); possession of the URL grants access. Treat URLs as bearer secrets. Responses may be cached for one hour, including after an object is deleted. Do not use this service for images requiring authenticated downloads.
OAuth records live in KV, separate from the image lifecycle. Changing AUTH_PASSWORD does not revoke previously issued OAuth tokens; to revoke all grants, use a fresh OAuth KV namespace and redeploy. Consider a Cloudflare rate-limiting rule for /authorize to restrict password guessing.
Local development and MCP Inspector
Local bindings use Wrangler's local emulators; do not enable remote bindings or --remote for local tests.
For a manual session, create a gitignored .dev.vars with your local-only values:
OPENAI_API_KEY=YOUR_RESTRICTED_OPENAI_KEY
AUTH_PASSWORD=YOUR_LOCAL_AUTHORIZATION_PASSWORDnpm run dev -- --local
# In a second terminal:
npx @modelcontextprotocol/inspectorOpen the Inspector URL printed in the terminal. Choose Streamable HTTP, enter http://localhost:8787/mcp, and use the Inspector's OAuth authentication flow. Register/connect, complete the local authorization form, and list tools. Secure browser-bound consent cookies are supported on localhost; use localhost consistently. Calling an image tool with a real key incurs a real OpenAI request; merely initializing or listing tools does not.
For an automated, entirely local check without real secrets:
npm run smokeThis starts wrangler dev --local with an ephemeral test password and isolated temporary storage, dynamically registers a public OAuth client, exercises wrong-password and unauthenticated rejection, completes browser-bound consent and PKCE, then uses the real MCP SDK client for initialize and tools/list. It never calls either image service and has no production auth bypass. Port 8787 must be free (SMOKE_PORT=8790 npm run smoke selects another port). The script stops Wrangler and removes its temporary storage on exit.
Verification
npm ci && npm run typecheck && npm test
npx wrangler deploy --dry-run --outdir /workspace/tmp/forge/oim-dist
npm run smoke
grep -rnIP '[\x{4e00}-\x{9fff}]' --exclude-dir=node_modules --exclude-dir=.git .Vitest mocks OpenAI fetch, R2 and Images. It tests validation, output formats, IDs/metadata, preview behavior, usage/model reporting, editing from IDs/URLs/masks, resolution failures, upstream errors, public image serving, and OAuth rejection. Unit tests stub only the Durable Object runtime and the unused WorkerEntrypoint base for Node; the smoke test runs the actual Worker, OAuth provider, Durable Object, and MCP transport.
This server cannot be deployed
Maintenance
Related MCP Connectors
Generate and edit images and create short videos inside Claude. Prepaid credits, no subscription.
Generate images from Claude, ChatGPT, Cursor and Codex with 12 top AI image models. Up to 4 images per call, SVG vectorization, background removal, upscaling and image-to-video. Remote MCP with OAuth, no API keys.
Generate images from Claude, ChatGPT, Cursor and Codex with 12 top AI image models and 10 tools: up to 4 images per call, SVG vectorization, editing and more. Remote MCP with OAuth, no API keys. Pay per image, no subscription.
Generate images with your own ChatGPT subscription (Plus, Pro or Team), without spending API credits
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables generating images from text prompts using OpenAI's GPT-Image-2 model within Claude Code and Codex conversations.1MIT
- FlicenseNot gradedqualityDmaintenanceEnables Claude to generate and edit images using Google Gemini AI.-
- AlicenseAqualityBmaintenanceConnects Claude Code to image generation models (OpenAI GPT Image 2, Google Nano Banana) for generating, editing, and converting images via natural language.638 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables Claude Code to generate and edit raster images through OpenRouter, including image-to-image editing with up to 16 ordered references, text-to-image generation, and balance/credit checks.MIT