Skip to main content
Glama
giancta92
by giancta92

Cloudflare Image MCP

Servidor MCP local por stdio que expone generate_image y solicita imágenes a Cloudflare Workers AI. Guarda la respuesta como PNG auténtico; las llamadas pueden generar consumo o cargos.

Requisitos

  • Python 3.11 o posterior.

  • OpenCode V2 para usarlo como MCP (opcional para ejecutar pruebas).

  • Cuenta Cloudflare con Workers AI habilitado y un API token con los permisos mínimos que Cloudflare indique actualmente para ejecutar Workers AI. Confirma los permisos en documentación oficial; este repositorio no valida una cuenta ni garantiza acceso.

  • Internet para generar imágenes. Instalación y pruebas no llaman a Cloudflare.

Dependencias Python: mcp, httpx y Pillow; dependencias de pruebas en el extra dev de pyproject.toml.

Related MCP server: Cloudflare Image MCP

Instalación desde cero (Linux/macOS)

Desde la carpeta del repositorio:

python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install -e '.[dev]'

Todo queda en .venv; no se instalan paquetes globales. Para ejecutar manualmente:

.venv/bin/python -m cloudflare_image_mcp.server

El servidor usa stdio y normalmente lo inicia OpenCode. No escribas depuración en stdout, canal del protocolo MCP.

Credenciales seguras

Por defecto se busca ~/.config/opencode/secrets/cloudflare.env. Crea el archivo fuera del repositorio:

mkdir -p ~/.config/opencode/secrets
cat > ~/.config/opencode/secrets/cloudflare.env <<'EOF'
CLOUDFLARE_ACCOUNT_ID=REEMPLAZA_CON_TU_ACCOUNT_ID
CLOUDFLARE_API_TOKEN=REEMPLAZA_CON_TU_TOKEN
EOF
chmod 600 ~/.config/opencode/secrets/cloudflare.env

Sustituye los marcadores localmente. No compartas el archivo, no lo añadas al repositorio ni pongas tokens en argumentos, configuración OpenCode, prompts o logs. CLOUDFLARE_CREDENTIALS_PATH o CLOUDFLARE_ENV_FILE pueden apuntar a otro archivo con esas dos claves; no contienen directamente los secretos.

OpenCode V2 global

Integra este bloque mcp.servers en la configuración global del usuario (habitualmente ~/.config/opencode/opencode.json en Linux), conservando el resto. Sustituye las rutas de ejemplo por rutas absolutas locales: Python de .venv y carpeta del proyecto donde guardar imágenes.

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "cloudflare-image": {
        "type": "local",
        "command": [
          "/RUTA/AL/REPOSITORIO/.venv/bin/python",
          "-m",
          "cloudflare_image_mcp.server"
        ],
        "cwd": "/RUTA/AL/PROYECTO-DE-SALIDA",
        "disabled": false,
        "timeout": {
          "startup": 10000,
          "catalog": 10000,
          "execution": 180000
        }
      }
    }
  }
}

Si ya tienes $schema, no lo dupliques: integra solo mcp. Forma V2 consultada el 2026-10-30; puede cambiar. Referencias: MCP servers y migración V1 a V2.

Comprueba el arranque/catálogo sin generar:

opencode mcp list

Que aparezca conectado no autentica con Cloudflare, verifica saldo ni genera una imagen.

Uso de generate_image

Pide explícitamente a OpenCode que invoque generate_image. Ejemplo:

Usa generate_image con model="flux-2-klein-4b", prompt="Una casa roja sobre una colina al amanecer", output_path="public/images/casa.png".

output_path relativo se resuelve bajo la raíz de salida; también se acepta una ruta absoluta dentro de esa raíz. Se rechazan escapes fuera de ella, incluidos .. y symlinks que escapen. Se crean carpetas padre. No se reemplazan archivos existentes salvo overwrite=true. Sin ruta, se crea generated-image-<marca-de-tiempo>-<id>.png en la raíz. El resultado informa ruta, modelo y bytes escritos.

Parámetro

Uso

prompt

Obligatorio, 1–2048 caracteres.

model

flux-2-klein-4b (predeterminado) o flux-1-schnell; admite también ID completo @cf/....

output_path

Ruta PNG opcional relativa a la raíz.

steps

Solo Schnell: 1–8, predeterminado 4.

width, height

Solo Klein: 256–1920; predeterminados 1024×768.

guidance, seed

Opcionales, solo Klein.

overwrite

Predeterminado false.

FLUX.1 Schnell vs FLUX.2 Klein 4B

  • FLUX.1 Schnell (@cf/black-forest-labs/flux-1-schnell): el servidor envía JSON con prompt y steps (por defecto 4; rango de esta implementación 1–8).

  • FLUX.2 Klein 4B (@cf/black-forest-labs/flux-2-klein-4b): modelo predeterminado; el servidor envía multipart/form-data con prompt, dimensiones y, si se especifican, guidance y seed.

Son interfaces/modelos distintos; no se afirman diferencias de calidad, velocidad o consumo por solicitud como resultados medidos. Modelos, parámetros y disponibilidad pueden cambiar. Pillow convierte formatos compatibles a PNG real, haciendo coincidir extensión y bytes.

Directorio de salida, cwd y override

El código usa Path.cwd() del proceso servidor como raíz. Configura explícitamente el cwd del MCP en OpenCode como la carpeta de salida deseada. La salida depende del directorio efectivo del proceso hijo, no necesariamente de dónde abriste manualmente la interfaz.

CLOUDFLARE_IMAGE_MCP_ROOT, si está definida, reemplaza Path.cwd() como raíz. El servidor resuelve output_path y restringe la escritura a esa raíz. Si usas el override, defínelo en el entorno heredado por OpenCode antes de iniciarlo. No confundir con CLOUDFLARE_CREDENTIALS_PATH, que selecciona el archivo de credenciales.

Las pruebas locales verifican el override, rutas y escritura temporal. No prueban en una instalación concreta qué cwd hereda el proceso hijo OpenCode; no se hizo generación remota para demostrarlo.

Límites gratuitos y facturación

Workers AI consume Neurons y puede generar cargos según plan, uso, cuota disponible y tarifas vigentes. La página oficial de precios consultada el 2026-10-30 indicaba una cuota gratuita publicada de 10.000 Neurons diarios y, para Workers Paid, USD 0,011 por cada 1.000 Neurons sobre esa asignación. Esto no garantiza cuota disponible, plan, requisitos de facturación ni costo de una solicitud concreta. Las tarifas dependen del modelo/unidades y pueden cambiar.

Antes de usar la herramienta, revisa precios de Workers AI, cuotas, términos y consumo de tu cuenta. El uso de Cloudflare es independiente del plan/proveedor de OpenCode. Conectar MCP no solicita inferencia; invocar generate_image sí intenta contactar Cloudflare y puede tener costo.

Pruebas

.venv/bin/python -m pytest -q

Las pruebas usan mocks/respuestas simuladas y no consumen cuota.

Resolución de problemas

  • No conectado en opencode mcp list: valida configuración global, ruta de command, instalación del paquete y existencia de cwd.

  • Dependencia ausente: instala en .venv con -e '.[dev]' (o -e . sin pruebas).

  • Credenciales no encontradas: revisa ruta predeterminada o CLOUDFLARE_CREDENTIALS_PATH/CLOUDFLARE_ENV_FILE, las dos claves requeridas y permisos restrictivos.

  • HTTP 401/403: confirma token, cuenta, permisos vigentes y facturación en Cloudflare. No pegues el token en reportes.

  • Cuota/costo: revisa dashboard y precios; el MCP no conoce la cuota disponible.

  • Ruta rechazada: usa ruta dentro de cwd o CLOUDFLARE_IMAGE_MCP_ROOT, y comprueba symlinks/...

  • Archivo existente: selecciona otra ruta o confirma overwrite=true.

  • Timeout: comprueba conexión/disponibilidad y ajusta execution si corresponde.

Licencia

El código propio de este proyecto está aprobado para publicarse bajo la licencia MIT; consulta el archivo LICENSE, que identifica el copyright de 2026 de Gian Torres Azaña. Esta licencia cubre únicamente el código propio del proyecto; no concede derechos sobre Cloudflare, Workers AI ni modelos de terceros, cuyos términos se aplican por separado.

Verificación de esta copia

En la preparación de la distribución, el 30-10-2026, se instaló esta copia en un entorno virtual temporal y pasaron 17 pruebas (17 passed). Se reutilizaron dependencias ya instaladas, sin descargas; las pruebas usan mocks y no contactan Cloudflare.

Crear el repositorio GitHub posteriormente

Estos pasos son una guía para cuando se autorice la publicación; no se han ejecutado. Antes, confirma la cuenta de destino y revisa que git status solo muestre los ocho archivos previstos.

  1. Desde esta carpeta, inicializa Git y revisa el contenido antes de confirmar:

    git init
    git add .
    git status --short
    git diff --cached --check
    git commit -m "Prepare public distribution"
  2. Crea en GitHub un repositorio público vacío llamado cloudflare-image-mcp, sin README, licencia ni .gitignore generados por GitHub (ya están en esta copia).

  3. Tras revisar el commit local y autorizar expresamente el envío, conecta el remoto y publica la rama. Por ejemplo, reemplazando OWNER por la organización o cuenta aprobada:

    git remote add origin https://github.com/OWNER/cloudflare-image-mcp.git
    git branch -M main
    git push -u origin main

    No ejecutes estos comandos hasta que la creación y el push estén autorizados. La ruta de publicación y el propietario de GitHub también quedan por decidir.

Available Tools

1 tool
generate_imageC

Generate an image with Cloudflare Workers AI and save it as a PNG file.

NameRequiredDescriptionDefault
seedNo
modelNoflux-2-klein-4b
stepsNo
widthNo
heightNo
promptYes
guidanceNo
overwriteNo
output_pathNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

C2.8/5.0
Behavior2/5

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

With no annotations provided, the description carries the full behavioral burden. It usefully discloses that the tool writes a PNG file, but says nothing about authentication, rate limits, whether existing files are overwritten, where files are saved, or what happens on failure.

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

Conciseness4/5

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

The description is a single efficient sentence with no wasted words and the core action is front-loaded. Its brevity is appropriate structurally, though the sentence is too terse to cover the tool's complexity.

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

Completeness2/5

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

Although an output schema exists and return values need not be explained, the description is still incomplete for a 9-parameter tool with zero schema descriptions and no annotations. It omits any explanation of model choice, image dimensions, seed behavior, or output path handling.

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

Parameters1/5

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

Schema description coverage is 0%, and the description provides no information about any of the 9 parameters. Parameters like seed, steps, guidance, width, height, model, overwrite, and output_path are completely undocumented in both the schema and description.

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?

The description states a specific verb ('Generate'), resource ('an image'), backend ('Cloudflare Workers AI'), and side effect ('save it as a PNG file'). An agent can immediately understand what the tool does without opening the schema.

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

Usage Guidelines2/5

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

There is no guidance on when to use this tool versus alternatives, no prerequisites, and no exclusions. The description only implies usage through the verb 'Generate', leaving the agent to infer context.

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

Tool Schema Changelog

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

  1. 1 tool updatev0.1.0
    • First observedgenerate_image

TDQS

B3.2/5.0

Scored across 1 tool

Disambiguation5/5

With only one tool in the set, there is nothing to confuse it with; its purpose (generate an image and save as PNG) is unambiguous.

Naming Consistency5/5

The single name follows a clear verb_noun convention (generate_image), which is predictable and readable even without siblings.

Tool Count3/5

A one-tool surface is thin: while image generation is the stated purpose, there is no companion operation such as listing models, retrieving the saved file path, or deleting images, so the set feels borderline under-scoped.

Completeness3/5

Generation is covered, but the lifecycle dead-ends after creation — an agent cannot list previously generated images, fetch a specific result by ID, or clean up files, which are natural follow-on operations for this domain.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers