Skip to main content
Glama
theosera

claude-openai-image-mcp

by theosera

claude-openai-image-mcp

A small, security-first MCP server that generates images with OpenAI's image model (gpt-image-2) and returns them as MCP image content — usable from Claude Code (CLI), Claude Desktop, and other stdio MCP clients.

The OpenAI API key is held server-side only. The default provider is a mock that returns a real 1×1 PNG with no network call and no billing, so you can wire up and test the whole flow before spending a cent.

Status: Phase 2 wired — the live OpenAI call (src/openaiImageClient.ts) is implemented with typed 429/timeout/5xx mapping, and every upstream branch is mock-reproduced in tests. The default provider is still mock; a real paid API call happens only when you explicitly set IMAGE_MCP_PROVIDER=openai with an OPENAI_API_KEY. Real-API E2E evidence is still pending. See Roadmap.

Tool

generate_image

Field

Type

Required

Notes

prompt

string

yes

1..IMAGE_MCP_MAX_PROMPT_CHARS chars

size

string

no

must be in IMAGE_MCP_ALLOWED_SIZES (default 1024x1024)

quality

string

no

must be in IMAGE_MCP_ALLOWED_QUALITIES (default low)

output_format

string

no

must be in IMAGE_MCP_ALLOWED_FORMATS (default png)

The server chooses the model; clients never pass a model name. Requests outside the allowlist are rejected before any provider call.

Returns MCP image content { type: "image", data: <base64>, mimeType } plus schema-validated structuredContent with { provider, model, size, quality, requested_output_format, output_format, request_id }. requested_output_format records the request; output_format describes the bytes actually returned and always agrees with mimeType.

Related MCP server: gemini-nano-banana-mcp

Quick start

Requires Node ≥ 22.12 and pnpm.

pnpm install
cp .env.example .env        # defaults to the mock provider (no key needed)
pnpm run build
pnpm test

Run the server over stdio:

pnpm run dev                # tsx src/index.ts
# or, after build:
node dist/index.js

Register with Claude Code

claude mcp add openai-image -- node /absolute/path/to/dist/index.js

(For the mock provider no OPENAI_API_KEY is needed. To use the real API later, set IMAGE_MCP_PROVIDER=openai and OPENAI_API_KEY in the server's environment.)

Configuration

All configuration is via environment variables (see .env.example). .env is git-ignored — never commit real secrets.

Variable

Default

Purpose

IMAGE_MCP_PROVIDER

mock

mock (offline), openai, or plugin

OPENAI_API_KEY

Required only when provider is openai

OPENAI_IMAGE_MODEL

gpt-image-2

Server-owned effective model

IMAGE_MCP_PROVIDER_MODULE

Plugin module specifier (provider plugin only)

IMAGE_MCP_MAX_PROMPT_CHARS

2000

Reject longer prompts

IMAGE_MCP_TIMEOUT_MS

60000

Per-request generation timeout (guard-enforced)

IMAGE_MCP_MAX_RETRIES

0

Bounded transient retries (Phase 2)

IMAGE_MCP_MAX_CONCURRENCY

1

Max concurrent generations

IMAGE_MCP_MAX_IMAGE_BYTES

15728640

Max decoded image size accepted from any provider

IMAGE_MCP_ALLOWED_SIZES

1024x1024,1536x1024,1024x1536

Allowlist

IMAGE_MCP_ALLOWED_QUALITIES

low,medium

Allowlist

IMAGE_MCP_ALLOWED_FORMATS

png,webp,jpeg

Allowlist

IMAGE_MCP_DEFAULT_SIZE

first allowed size

Used when the client omits size

IMAGE_MCP_DEFAULT_QUALITY

first allowed quality

Used when the client omits quality

IMAGE_MCP_DEFAULT_FORMAT

first allowed format

Used when the client omits output_format

Provisional values

quality=low, concurrency=1, retries=0, n=1, and model=gpt-image-2 are provisional — chosen to bound cost and latency and to be confirmed by end-to-end evidence. Each carries a review condition in code comments; expect them to change as we run real E2E tests.

Experimental: pluggable provider lane (detachable)

Besides mock and openai, the server can load an external provider plugin (e.g. a Codex-CLI-backed lane that generates images inside a ChatGPT subscription instead of API billing). The core stays API-key-first; the plugin lane is strictly opt-in and detachable by design:

  • Activation needs both IMAGE_MCP_PROVIDER=plugin and IMAGE_MCP_PROVIDER_MODULE=<npm package or path>. Remove both to detach — the core has no build-time dependency on any plugin.

  • A plugin implements the contract exported at claude-openai-image-mcp/provider (createImageProvider() + providerApiVersion). The server refuses to start on a version mismatch or any load failure (fail-closed).

  • Every provider (plugin or not) runs behind a request-time guard: timeout with abort, strict base64 + magic-byte/MIME validation, decoded-size cap, and redacted error surfacing. A plugin cannot impersonate another lane in structuredContent.

  • There is no automatic fallback between lanes. If the plugin lane breaks (e.g. an upstream policy change), requests fail with a clear error; switching back to openai is a deliberate env change, never implicit billing.

  • Trust model: the plugin runs in-process with the server's full privileges. Only install plugins you wrote or audited, and do not keep OPENAI_API_KEY in the plugin lane's environment (the server warns if you do). A plugin backend may choose its own model; results report what the plugin actually used (or unknown) — the configured model is advisory there.

A reference implementation lives in packages/codex-plugin-cc — the ChatGPT-subscription lane (drives the Codex CLI, no API key). It is a separate, non-core package: the core never imports it, and a dedicated CI job builds, audits, and tests it separately so it stays detachable from the core dependency graph.

Security

The OpenAI key is server-side only and never logged, serialized, or returned. Logs are stderr-only, metadata-only, and redacted. See SECURITY.md.

Development

pnpm run lint:ox        # fast Rust correctness pass
pnpm run format:check   # prettier
pnpm run lint           # eslint
pnpm run typecheck      # tsc --noEmit
pnpm run build
pnpm test               # vitest (no network, no billing)

CI runs the same sequence (.github/workflows/node.js.yml) plus CodeQL.

Roadmap

  • Phase 1 (this repo): scaffold, generate_image, mock provider, CI. ✅

  • Phase 2: wire OpenAIImageProvider to the official SDK (allowlist, timeout, bounded retry, 429/Retry-After/timeout/5xx mapping, byte/MIME checks); mock-reproduce every branch. ✅ — implemented; real API E2E still requires explicit approval (billing) and is the remaining checkbox of this phase.

  • Phase 3: Streamable HTTP transport + client→server OAuth (the OpenAI key is never forwarded to clients). Note: there is no official OpenAI OAuth path to call the Images API on a ChatGPT user's behalf — the core stays server-side API key only. Unofficial subscription-backed lanes live as external plugins (see the pluggable provider lane above), at the user's own risk.

License

MIT

Available Tools

1 tool
generate_imageGenerate an imageA

Generate an image from a text prompt using the configured OpenAI image model. Returns an image (base64) plus metadata. size/quality/output_format are optional and restricted to the server allowlist; the server picks the model.

ParametersJSON Schema
NameRequiredDescriptionDefault
sizeNo
promptYes
qualityNo
output_formatNo

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate non-read-only and non-destructive. Description adds server model selection and parameter restrictions, but does not disclose potential side effects like API costs or rate limits, especially given openWorldHint=true.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two efficient sentences front-loading purpose and key constraints. No extraneous wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Returns are described briefly (base64+metadata) but no output schema or details on metadata structure. openWorldHint=true hints at unstated side effects, leaving gaps for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema coverage, description only notes that size/quality/output_format are optional and allowlist-restricted, without explaining their meaning or allowed values. The prompt parameter is unelaborated.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states verb (generate) and resource (image) with model context. Specific enough to distinguish from potential siblings, though none are listed.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Indicates parameters are optional and allowlist-restricted, and that the server picks the model. Provides context for when to use, but lacks explicit exclusions or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A4.1/5.0
Disambiguation5/5

Only one tool exists, so there is no possibility of confusion or overlap.

Naming Consistency5/5

With a single tool, naming consistency is perfect; the name 'generate_image' clearly describes its action.

Tool Count5/5

The one tool matches the server's narrow purpose of generating images from prompts; no additional tools are needed.

Completeness4/5

The tool covers the core functionality of generating images. Minor gaps like listing available models or presets could be added, but the current surface is adequate.

Maintenance

ActivitySlowing
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/theosera/claude_openai_image_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server