Zovo Image MCP Server
Genera, convierte y redimensiona imágenes desde archivos locales. Servidor MCP offline-first, plan gratuito, sin registro.
Documentación
mcp-image
Di "haz estas cinco fotos de 1200 píxeles de ancho" o "reduce esta captura de pantalla y elimina los datos GPS" y sucede, en tu máquina, en un segundo. Este servidor MCP hace los trabajos pequeños de imagen que de otro modo te llevarían a un cargador web: redimensionar, convertir entre PNG, JPEG, BMP, GIF y TIFF, comprimir con un conteo real de bytes antes y después, recortar, crear miniaturas de una carpeta, añadir una marca de agua con el nombre de tu negocio y eliminar el bloque EXIF que la cámara del teléfono escribe en cada foto. Sin subidas, sin cuenta, sin dependencias nativas, sin editor de imágenes.
En el Registro oficial de MCP (io.github.theluckystrike/image-resize-convert-compress-watermark).
Listado en el Índice de Productos de IA - endpoint remoto en vivo en mcp.zovo.one/s/image, plan gratuito, sin registro.

Las tareas de imagen de un negocio independiente, hechas desde el chat en lugar de desde una pestaña del navegador a la que preferirías no entregar la foto de un cliente.
Instalación en 60 segundos
La publicación en npm para @theluckystrike/mcp-image está pendiente. Hasta entonces, el paquete de un clic .mcpb o una clonación y compilación
es la vía funcional, ambas verificadas a continuación.
Un clic (.mcpb): descarga image.mcpb desde la última versión y haz doble clic en Claude Desktop:
https://github.com/theluckystrike/mcp-servers/releases/latest
(claude_desktop_config.json):
{
"mcpServers": {
"image": {
"command": "npx",
"args": ["-y", "@theluckystrike/mcp-image"]
}
}
}
Claude Code:
claude mcp add image -- npx -y @theluckystrike/mcp-image
(.cursor/mcp.json):
{
"mcpServers": {
"image": {
"command": "npx",
"args": ["-y", "@theluckystrike/mcp-image"]
}
}
}
El formulario npx anterior comienza a funcionar en el momento en que se publique el paquete. Hasta entonces, usa el paquete .mcpb de arriba, o
compila desde el código fuente con exactamente estos tres comandos:
git clone https://github.com/theluckystrike/mcp-servers.git && cd mcp-servers
npm install
npm run build -w packages/mcp-license -w servers/image
Luego apunta el command de tu cliente a node con un argumento: la ruta absoluta a servers/image/dist/index.js.
Para ejecutar en modo Pro, establece MCP_LICENSE_KEY en el mismo bloque de configuración, o llama a license_activate una vez con tu clave.
Herramientas
| Herramienta | Qué hace |
|---|---|
image_info | Formato, dimensiones en píxeles, megapíxeles, relación de aspecto, tamaño de archivo en bytes, si la imagen lleva canal alfa y los bytes que gasta por píxel |
image_resize | Una copia redimensionada. inside se ajusta dentro del recuadro y mantiene la proporción, cover llena el recuadro y recorta el exceso, exact estira. Da uno de ancho o alto y el otro se ajusta |
image_convert | Re-codifica como PNG, JPEG, BMP, GIF o TIFF. La transparencia al pasar a JPEG se aplana sobre blanco, y la respuesta lo indica |
image_compress | Menos bytes, con el conteo antes y después y el porcentaje ahorrado. quality (por defecto 80), max_width y max_bytes para alcanzar un tamaño objetivo en una sola llamada |
image_crop | Corta un rectángulo: x, y desde la esquina superior izquierda, width, height. Un rectángulo que sobrepasa un borde se rechaza con el tamaño real, nunca se recorta a la fuerza |
image_thumbnails | Una miniatura por archivo en out_dir, cada una ajustada dentro de size por size y manteniendo su relación de aspecto |
image_watermark | Texto sobre la imagen en una esquina y con una opacidad, blanco sobre una placa translúcida. Sin texto, se usa el nombre de tu negocio del perfil compartido mcp-invoice y mcp-docx escriben |
image_strip_metadata | Una copia con píxeles y nada más: EXIF, GPS, cámara, hora de captura, XMP y perfiles de color no se transfieren |
image_batch_resize | Redimensiona una lista completa en out_dir, cada una manteniendo su propia relación de aspecto, nombradas <name>-<W>x<H>.<ext> |
image_dominant_colors | Los colores que cubren la mayor parte de una imagen, como códigos hex con la proporción de píxeles que cubre cada uno. Gratis: 3; Pro: hasta 16 |
license_status | Muestra el modo gratuito o Pro |
license_activate | Activa una clave Pro (verificada sin conexión) |
Recurso: image://recent devuelve las últimas 25 operaciones, de más reciente a más antigua, con las entradas, los archivos escritos y cuándo.
Prompt: prepare_for_web reduce una imagen de tamaño de cámara a un JPEG de tamaño de página, elimina los metadatos que traía e informa de los bytes ahorrados.
Lo que puedes decir
| Tú dices | Herramienta |
|---|---|
| "¿Qué tamaño tiene esta imagen y tiene transparencia?" | image_info |
| "Haz esto de 1200 píxeles de ancho." | image_resize |
| "Convierte este PNG a JPEG." | image_convert |
| "Esta foto pesa 8 MB, déjala por debajo de un megabyte." | image_compress |
| "Recorta el banner superior de esta captura de pantalla." | image_crop |
| "Haz miniaturas de todo lo que hay en esta carpeta." | image_thumbnails |
| "Pon el nombre de mi empresa en la esquina de esta foto." | image_watermark |
| "Elimina las coordenadas GPS antes de que envíe esto." | image_strip_metadata |
| "Redimensiona todos estos a 1600 de ancho." | image_batch_resize |
| "¿De qué colores está hecho este logotipo?" | image_dominant_colors |
| "Prepáralo para el sitio web." | prompt prepare_for_web |
Ejemplo práctico
You: This photo is too big for the site. Get it to 1600 wide and drop the metadata.
image_info { path: "~/photos/DSC_0491.jpg" }
-> 6000x4000, 24 MP, JPEG, 8.4 MB, no alpha
image_compress {
path: "~/photos/DSC_0491.jpg",
max_width: 1600,
quality: 80,
max_bytes: 256000,
out_path: "~/photos/DSC_0491-web.jpg"
}
-> 8.4 MB -> 243.7 KB (8809124 -> 249556 bytes, -97.2%)
-> Method: JPEG quality 62 (searched down from 80 in 5 encodes to fit 250.0 KB)
and a resize to 1600 px wide
-> ~/photos/DSC_0491-web.jpg, 1600x1067, JPEG
La re-codificación JPEG también elimina el bloque EXIF que escribió la cámara, incluidas las coordenadas GPS. El archivo original queda sin cambios, byte por byte.
Gratis vs Pro
| Gratis | Pro | |
|---|---|---|
image_info | Ilimitado, a cualquier tamaño | Ilimitado |
image_resize, image_convert, image_compress, image_crop | Cualquier origen, escribiendo salidas de hasta 4 MP (2000x2000 y algo más) | Cualquier tamaño, hasta los límites de entrada de 50 MB / 10 000 px |
image_strip_metadata | Cualquier tamaño | Cualquier tamaño |
image_thumbnails, image_batch_resize | Hasta 5 archivos por llamada, salidas de hasta 4 MP cada una | Cualquier número de archivos, cualquier tamaño |
image_watermark | El nombre de tu negocio del perfil compartido | Cualquier texto que pases |
image_dominant_colors | Los 3 colores principales | Hasta 16 |
El límite gratuito está en lo que se escribe, no en lo que se lee: una foto de teléfono de 12 MP reducida a 1600 px de ancho es una llamada gratuita, porque ese es el trabajo. Escribir 12 MP de vuelta es la parte Pro.
Un límite de nivel es una respuesta, no un error, y no se escribe nada cuando se rechaza una llamada.
Pro es un pago único de $19, o $39 por todos los servidores de la colección, de por vida.
quality es un parámetro de JPEG, y solo un parámetro de JPEG
Esto es lo único de la compresión de imágenes que sorprende a la gente, así que el servidor lo dice en su propia respuesta en lugar de
aceptar un número y no hacer nada con él en silencio. Un JPEG descarta detalles para ser más pequeño, y quality
es el dial de cuánto. Un PNG no tiene pérdida: no hay dial. Pasar quality: 40 a una salida PNG no hace
un PNG un 60% más pequeño, hace exactamente el mismo PNG.
Así que el formato de salida sigue la extensión de tu out_path, y esa es la palanca:
out_path: "shot-small.jpg",qualityse aplica, y una foto normalmente baja un 80-95%.out_path: "shot-small.png",qualityse informa como no aplicable, y solomax_widthelimina bytes.
La cuantización de paleta se probó como alternativa para PNG y se rechazó: re-codificar un PNG ruidoso de 300x220 a través de un cuantizador de 16 colores produjo un archivo más grande (115 451 bytes frente a 39 262), porque el codificador aquí escribe RGBA de cualquier manera y la cuantización solo destruye la similitud fila a fila que el paso deflate estaba aprovechando. Una herramienta que dice comprimir y devuelve un archivo más grande es peor que una herramienta que dice qué perilla existe.
image_compress por lo tanto siempre informa el conteo de bytes antes y después, el porcentaje y el método que hizo
el trabajo, y, si la salida salió más grande, lo dice y te dice que conserves el original.
Las bombas de descompresión se rechazan desde la cabecera, antes de que se decodifique nada
Un PNG de 4 KB puede declarar que es de 20 000 por 20 000 píxeles. Decodificarlo asigna 1,6 GB de RGBA y tumba el proceso antes de que cualquier comprobación de tamaño escrita después de la decodificación pueda ejecutarse. Así que las dimensiones declaradas se leen de la cabecera del contenedor, PNG IHDR, el segmento SOF del JPEG, el descriptor de pantalla lógica del GIF, la cabecera de información del BMP, el primer IFD del TIFF, y un archivo de más de 10 000 px por lado se rechaza ahí, con la memoria que habría ocupado nombrada en el mensaje:
Error: /path/bomb.png declares 20000x20000 pixels in its PNG header and was refused before decoding:
this server caps a side at 10000 px. A small file that declares an enormous canvas is a decompression
bomb - decoding it would allocate 1526 MB of RGBA. Nothing was decoded.
El tamaño decodificado se comprueba de nuevo después, porque una sonda de cabecera puede volver vacía en un TIFF inusual, y un guardia que solo se ejecuta a veces no es un guardia.
Los archivos existentes nunca se sobrescriben y las entradas nunca se modifican
Cada herramienta escribe un archivo nuevo y deja sus entradas byte por byte intactas, no hay modo en el lugar, a propósito.
Un out_path que ya existe se rechaza:
Error: /path/shot-small.png already exists and nothing was written.
Pass overwrite: true to replace it, or give a different out_path.
La ruta se reserva con una creación exclusiva, no con una comprobación de existencia, así que dos procesos escribiendo el mismo out_path
al mismo tiempo no pueden pisarse: uno gana, el otro se rechaza y no escribe nada. image_thumbnails
y image_batch_resize reservan cada una de sus rutas de salida antes de escribir cualquiera de ellas, así que una colisión en el archivo
3 no deja los archivos 1 y 2 atrás como un lote a medias, y las reservas se liberan, así que tampoco queda nada vacío
en el disco.
Pasa overwrite: true cuando reemplazar el archivo es lo que quieres.
overwrite: true todavía no permite que una salida sea una entrada. Escribir un resultado sobre una de sus propias fuentes
destruye esa fuente, los píxeles ya están decodificados en memoria y se escriben sobre el archivo del que vinieron, así que un
original de 4000 px se convierte en la miniatura de 512 px y cada lectura posterior de esa ruta está silenciosamente mal. Así que un out_path
que resuelve a (o comparte un inodo con) cualquier entrada de la misma llamada se rechaza antes de que ocurra cualquier trabajo.
Qué hace realmente "eliminar metadatos"
image_strip_metadata decodifica la imagen y la re-codifica desde los píxeles en bruto. EXIF, coordenadas GPS, la cámara
y el objetivo, la hora de captura, los paquetes XMP y los perfiles de color incrustados no se eliminan uno a uno, simplemente nunca se
entregan al codificador, así que no pueden salir por el otro lado. Dos consecuencias que vale la pena conocer:
- Los píxeles son los mismos, los bytes no. Un JPEG pasa por el codificador una segunda vez, así que la copia no es bit-idéntica al original aunque se vea igual. Conserva el original si eso importa.
- Cada otra herramienta de escritura aquí tiene el mismo efecto como efecto secundario. Redimensionar una foto también elimina su EXIF.
Límites
- Entradas de más de 50 MB se rechazan: una imagen se decodifica a ancho x alto x 4 bytes de RGBA en bruto independientemente de lo bien que esté comprimida en disco.
- 10 000 px por lado, comprobado primero desde la cabecera y segundo desde la decodificación.
- Lectura y escritura: PNG, JPEG, BMP, GIF y TIFF, detectados por bytes mágicos en lugar de por extensión de archivo. Sin WebP, sin AVIF, sin HEIC, sin SVG, no hay un decodificador de JavaScript puro para esos que valga la pena enviar, y este servidor no toma dependencias nativas.
- Un GIF animado se lee como su primer fotograma. Este servidor no hace animación.
- El texto de la marca de agua se dibuja con las caras Open Sans de mapa de bits incluidas (8, 16, 32, 64 y 128 px), y se elige la más grande que quepa en la imagen. Un carácter que esas caras no llevan no se dibuja, así que no hay marca de agua CJK.
- Sin rotación, sin filtros, sin corrección de color, sin OCR, sin eliminación de fondo. Este servidor hace los trabajos de tamaño y formato; no es un editor de imágenes.
Cómo almacena datos
Solo un registro de lo que hizo: ${XDG_DATA_HOME:-~/.local/share}/mcp-servers/image/operations.json, las últimas 500
operaciones, como JSON plano. Tus imágenes se quedan donde las pusiste. Cada escritura en el registro se ejecuta dentro de un bloqueo
de asesoramiento en .../image/.lock, así que dos clientes en un directorio de datos no pueden perder un registro, y los guardados van a un archivo
temporal y se renombran en su lugar.
Si el registro no se puede leer o no es JSON válido, nunca se trata como "vacío": se mueve a un lado byte por byte como
operations.json.corrupt-<timestamp> con un marcador al lado. La imagen que pediste todavía se escribe, el archivo
está en disco antes de que se toque el registro, y la respuesta te dice que el historial no se pudo actualizar.
La marca de agua lee el único perfil compartido que usa toda la suite,
${XDG_DATA_HOME:-~/.local/share}/mcp-servers/profile/business.json, escrito por business_set en mcp-invoice o
mcp-docx. Nada se inventa: sin nombre almacenado y sin texto pasado, image_watermark se niega y dice qué herramienta
ejecutar.
Privacidad
Todos los datos permanecen locales. El servidor lee y escribe archivos en tu máquina y no realiza ninguna solicitud de red de ningún tipo -- ni para licencias (las claves se verifican sin conexión), ni para fuentes, ni para telemetría. Una foto de cliente que redimensiones nunca se sube a ningún lugar, que es la razón principal por la que esto existe.
Se combina con
- mcp-docx, ajusta un logotipo aquí y luego colócalo en el membrete:
image_resizea la altura del encabezado, y luego el escritor de.docxtoma el archivo desde el disco. - mcp-pdf, reduce los escaneos antes de fusionarlos, para que el PDF combinado no pese 40 MB.
- mcp-resume, una foto de perfil correctamente dimensionada y sin metadatos para el currículum y el formulario de solicitud.
- office-suite, varios servidores detrás de una sola instalación, una sola entrada de configuración.
Solución de problemas
npxse cuelga o no encuentra el paquete: la publicación de npm para este paquete está pendiente. Usa el paquete.mcpbo la ruta de clonar y compilar mencionada arriba hasta que esté disponible.- "quality no se aplica a una salida PNG": escribe en un
.jpgout_path, o pasamax_width. Consulta la sección anterior. - "declara NxN píxeles ... y fue rechazado antes de la decodificación": el archivo declara un lienzo de más de 10,000 px por lado. Si es genuinamente tan grande, redimensiona con una herramienta que transmita mosaicos; este servidor decodifica imágenes completas.
- "no comienza con los bytes mágicos": el archivo no es PNG, JPEG, BMP, GIF o TIFF. Un nombre
.pngen un archivo WebP es la causa habitual; conviértelo primero. - "ya existe y no se escribió nada": pasa
overwrite: true, o unout_pathdiferente. - La marca de agua es diminuta: la cara incluida más grande es de 128 px, y se elige para que quepa dentro del 80% del ancho de la imagen. En una foto muy grande, redimensiona primero y aplica la marca de agua después.
- Versión de Node: requiere Node >= 18. Verifica con
node -v.
Licencia MIT. Soporte: support@zovo.one
Creado por theluckystrike.
Usa estos documentos como un servidor MCP
Cualquier cliente MCP (Claude, Cursor, Windsurf, VS Code) puede leer la documentación de este repositorio directamente a través de GitMCP - sin instalación:
- URL de documentos MCP: https://gitmcp.io/theluckystrike/mcp-image