openrouter-mcp-multimodal
Servidor MCP para OpenRouter: más de 300 LLMs con visión, generación de imágenes, entrada/salida de audio, y análisis + generación de video (Veo 3.1 / Sora 2 Pro / Seedance / Wan). Errores estructurados, protecciones SSRF IPv6, sandbox de rutas.
Documentación
OpenRouter MCP Multimodal
El servidor MCP para agentes de IA multimodales.
Una instalación · 19 herramientas · más de 300 modelos de OpenRouter · texto, visión, audio y video — análisis y generación.
Inicio rápido · Herramientas · Ejemplos · Seguridad · Solución de problemas · Desarrollo · Publicación · Preguntas frecuentes
¿Qué es esto?
OpenRouter MCP Multimodal es un servidor de Model Context Protocol (MCP) de nivel de producción — listado en el registro oficial de MCP como io.github.stabgan/openrouter-multimodal. Conecta agentes de codificación de IA (Cursor, Claude Desktop, VS Code, Windsurf, Cline y otros) a la API unificada de LLM de OpenRouter a través de stdio.
A diferencia de los servidores MCP solo de texto, una sola instalación cubre la superficie multimodal completa:
| Capacidad | Herramientas | Destacados |
|---|---|---|
| Chat | chat_completion, start_chat_completion, get_chat_completion_status | Más de 300 modelos, sufijos :nitro / :floor / :free / :online / :exacto, enrutamiento de proveedores, búsqueda web, caché de respuestas, tokens de razonamiento, trabajos asíncronos para modelos de larga duración |
| Visión | analyze_image, generate_image, generate_image_dedicated | OCR, subtitulado, VQA, generación de imágenes con entradas de referencia, API de imágenes dedicada con control de resolución/calidad/formato |
| Audio | analyze_audio, generate_audio, text_to_speech, speech_to_text | Transcripción, generación de voz/música, TTS dedicado (Deepgram gratuito por defecto; voces específicas de modelo, mp3/pcm), STT dedicado (Whisper/GPT-4o Transcribe) |
| Video | analyze_video, generate_video, generate_video_from_image, get_video_status | Comprensión de clips, generación con Veo 3.1 / Seedance 2.0 / Wan 2.7 con notificaciones de progreso |
| Catálogo | search_models, get_model_info, validate_model, rerank_documents, health_check | Descubrimiento de modelos, validación, reordenamiento, salud operativa |
Endurecimiento de producción: sandboxes de rutas de entrada/salida (incluidos archivos locales analyze_* a partir de v4.5.2), protecciones SSRF, errores estructurados con _meta.code, salidas estructuradas MCP 2025-06-18, iconos de herramientas (2025-11-25), notificaciones de progreso de video asíncronas y más de 1000 pruebas automatizadas (unitarias, simuladas, de regresión e integración en vivo).
Inicio rápido
1. Obtén una clave de API (el nivel gratuito funciona) → openrouter.ai/keys
2. Ejecuta el servidor
export OPENROUTER_API_KEY=sk-or-v1-...
npx -y @stabgan/openrouter-mcp-multimodal
3. Añádelo a tu cliente MCP — copia un bloque JSON de Instalación en la configuración de tu cliente:
| Cliente | Ubicación de configuración |
|---|---|
| Cursor | Proyecto: .cursor/mcp.json · Usuario: Configuración de Cursor → MCP |
| Claude Desktop | macOS: ~/Library/Application Support/Claude/claude_desktop_config.json · Windows: %APPDATA%\Claude\claude_desktop_config.json |
| VS Code | .vscode/mcp.json (espacio de trabajo) o Configuración de usuario → MCP |
| Windsurf | Configuración de Windsurf → MCP (misma forma JSON mcpServers que Cursor) |
Usa el objeto mcpServers de Configuración manual a continuación.
No se requieren créditos para comenzar. Modelos gratuitos como
google/gemma-4-26b-a4b-it:freefuncionan para chat y visión. La generación de video/audio generalmente requiere créditos.
Instalación
Los servidores MCP se distribuyen a través de varios modelos de empaquetado. Este servidor está implementado en Node.js/TypeScript; la tabla a continuación mapea cada método del ecosistema a cómo se ejecuta aquí.
| Método | Tiempo de ejecución | Mejor para | Este servidor |
|---|---|---|---|
| npx | Node.js 22+ | La mayoría de los clientes MCP (predeterminado) | ✅ @stabgan/openrouter-mcp-multimodal |
| uvx / pipx | Python 3.10+ y Node.js 22+ | Flujos de trabajo centrados en Python, mismo patrón que los servidores MCP de PyPI | ✅ mcp-server-openrouter-multimodal |
| npm global | Node.js 22+ | Fijar una versión sin volver a descargar | ✅ |
| node (local) | Node.js 22+ | Contribuyentes / compilaciones aisladas | ✅ |
| Docker Hub | Docker | Aislamiento, sin Node en el host | ✅ stabgan/openrouter-mcp-multimodal |
| GHCR | Docker | Extracciones OCI nativas de GitHub | ✅ ghcr.io/stabgan/openrouter-mcp-multimodal |
| Smithery CLI | Node.js (a través del instalador) | Instalación interactiva en Claude/Cursor/etc. | ✅ |
| Registro MCP | npm u OCI | Descubrimiento oficial (io.github.stabgan/openrouter-multimodal) | ✅ listado |
| Enlaces directos de un clic | Node.js | Cursor, VS Code, Kiro | ✅ |
| CLI de Claude Code | Node.js | Usuarios de Claude Code centrados en terminal | ✅ |
| MCP Inspector | Node.js | Depurar / listar herramientas localmente | ✅ |
Windows cmd /c npx | Node.js | Claude Desktop / Cursor cuando npx no está en la ruta GUI | ✅ ver más abajo |
| pip / uv (directo) | — | Solo servidores MCP nativos de Python | — usa la fila uvx anterior |
| Extensiones de escritorio DXT | — | Claude Desktop empaquetado .dxt | aún no |
| HTTP / SSE remoto | — | Endpoints alojados de Smithery / Cloudflare | a través de Smithery |
uvx vs npx: En el ecosistema MCP,
npxejecuta paquetes npm (Node) yuvxejecuta paquetes PyPI (Python). Debido a que este servidor está basado en Node,uvxusa un lanzador de Python delgado que ejecutanpx -y @stabgan/openrouter-mcp-multimodal— aún necesitas tener Node instalado.
Un clic
| Cursor | |
| VS Code | |
| Kiro | |
| Claude Desktop / Windsurf / Cline | Configuración JSON manual (elige cualquier método a continuación) |
| Smithery | npx -y @smithery/cli install @stabgan/openrouter-mcp-multimodal --client claude |
| Registro MCP | Página oficial del registro — paquetes npm + OCI |
Pega tu OPENROUTER_API_KEY cuando se te solicite — los enlaces directos usan marcadores de posición para que los secretos nunca aparezcan en las URL.
Configuración manual
npx (recomendado)
export OPENROUTER_API_KEY=sk-or-v1-...
npx -y @stabgan/openrouter-mcp-multimodal
{
"mcpServers": {
"openrouter": {
"command": "npx",
"args": ["-y", "@stabgan/openrouter-mcp-multimodal"],
"env": {
"OPENROUTER_API_KEY": "sk-or-v1-..."
}
}
}
}
Fijar una versión: "args": ["-y", "@stabgan/openrouter-mcp-multimodal@5.0.1"]
uvx / pipx (lanzador de Python)
Instala uv (incluye uvx), asegúrate de que Node.js 22+ también esté en tu PATH, luego:
export OPENROUTER_API_KEY=sk-or-v1-...
uvx mcp-server-openrouter-multimodal
# pin npm version: OPENROUTER_MCP_NPM_VERSION=5.0.1 uvx mcp-server-openrouter-multimodal
{
"mcpServers": {
"openrouter": {
"command": "uvx",
"args": ["mcp-server-openrouter-multimodal"],
"env": {
"OPENROUTER_API_KEY": "sk-or-v1-..."
}
}
}
}
Equivalente con pipx: pipx run mcp-server-openrouter-multimodal
Opcional: OPENROUTER_MCP_NPM_VERSION=5.0.1 fija el paquete npm subyacente.
npm global
npm install -g @stabgan/openrouter-mcp-multimodal
{
"mcpServers": {
"openrouter": {
"command": "openrouter-multimodal",
"env": { "OPENROUTER_API_KEY": "sk-or-v1-..." }
}
}
}
node (clon local)
git clone https://github.com/stabgan/openrouter-mcp-multimodal.git
cd openrouter-mcp-multimodal
npm ci && npm run build
{
"mcpServers": {
"openrouter": {
"command": "node",
"args": ["/absolute/path/to/openrouter-mcp-multimodal/dist/index.js"],
"env": { "OPENROUTER_API_KEY": "sk-or-v1-..." }
}
}
}
Docker
docker run --rm -i -e OPENROUTER_API_KEY=sk-or-v1-... stabgan/openrouter-mcp-multimodal:latest
{
"mcpServers": {
"openrouter": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"OPENROUTER_API_KEY=sk-or-v1-...",
"stabgan/openrouter-mcp-multimodal:latest"
]
}
}
}
Usa -i (stdio interactivo). Evita -t (la TTY corrompe el marco MCP en algunos hosts).
GHCR (Registro de contenedores de GitHub)
docker run --rm -i -e OPENROUTER_API_KEY=sk-or-v1-... \
ghcr.io/stabgan/openrouter-mcp-multimodal:5.0.1
{
"mcpServers": {
"openrouter": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"OPENROUTER_API_KEY=sk-or-v1-...",
"ghcr.io/stabgan/openrouter-mcp-multimodal:5.0.1"
]
}
}
}
Smithery
Instalación interactiva (escribe la configuración para tu cliente):
npx -y @smithery/cli install @stabgan/openrouter-mcp-multimodal --client claude
# or: --client cursor | vscode | windsurf | ...
Listado: smithery.ai/server/@stabgan/openrouter-mcp-multimodal
Registro MCP
Nombre oficial: io.github.stabgan/openrouter-multimodal
- Registro: registry.modelcontextprotocol.io
- Paquete npm:
@stabgan/openrouter-mcp-multimodal - Imagen OCI:
docker.io/stabgan/openrouter-mcp-multimodal
Los clientes que admiten instalación mediante registro ofrecerán npm o Docker; de lo contrario, usa los bloques JSON anteriores.
CLI de Claude Code
claude mcp add openrouter -- npx -y @stabgan/openrouter-mcp-multimodal
# project scope:
claude mcp add --scope project openrouter -- npx -y @stabgan/openrouter-mcp-multimodal
Establece OPENROUTER_API_KEY en tu shell o entorno de cliente antes de iniciar Claude Code.
Inspector MCP
Depura herramientas/lista y llamadas a herramientas contra una clave de OpenRouter activa:
export OPENROUTER_API_KEY=sk-or-v1-...
npx -y @modelcontextprotocol/inspector npx -y @stabgan/openrouter-mcp-multimodal
npx en Windows
Cuando Claude Desktop o Cursor no puedan encontrar npx (las aplicaciones GUI a menudo no ven el PATH del shell), envuélvelo con cmd:
{
"mcpServers": {
"openrouter": {
"command": "cmd",
"args": ["/c", "npx", "-y", "@stabgan/openrouter-mcp-multimodal"],
"env": { "OPENROUTER_API_KEY": "sk-or-v1-..." }
}
}
}
Si aún falla, usa la ruta completa de where npx como comando.
¿Por qué este servidor?
| Capacidad | Este servidor | Servidores MCP LLM típicos |
|---|---|---|
| Chat de texto (más de 300 modelos) | ✅ | ✅ |
| Análisis y generación de imágenes | ✅ | parcial |
| Análisis de audio y TTS | ✅ | ❌ |
| Análisis y generación de video | ✅ | ❌ |
| Búsqueda / validación / rerank de modelos | ✅ | ❌ |
| Sandbox de rutas + protección SSRF | ✅ | raro |
| Salidas estructuradas MCP 2025 | ✅ | raro |
| Video asíncrono + notificaciones de progreso | ✅ | ❌ |
Herramientas
19 herramientas MCP. Cada descripción incluye Usar cuando, Ejemplos buenos/malos, Falla cuando y Funciona con para que los agentes elijan la herramienta correcta y se recuperen de errores.
| Herramienta | Propósito |
|---|---|
chat_completion | Chat de texto, búsqueda web, enrutamiento de proveedor, caché, razonamiento |
start_chat_completion | Trabajo en segundo plano asíncrono para modelos de razonamiento de larga duración |
get_chat_completion_status | Consultar / recuperar resultados de finalización asíncronos |
analyze_image | Visión — ruta local, URL o URL de datos + question |
analyze_audio | Transcribir / analizar archivos de audio |
analyze_video | Describir / preguntas y respuestas sobre archivos de video |
generate_image | Texto a imagen mediante finalizaciones de chat con imágenes de referencia |
generate_image_dedicated | Texto a imagen mediante /api/v1/images dedicado (resolución, calidad, formato) |
generate_audio | Texto a voz / música mediante finalizaciones de chat |
text_to_speech | TTS dedicado (/api/v1/audio/speech) — Deepgram predeterminado gratuito, voces, velocidad, mp3/pcm |
speech_to_text | STT dedicado (/api/v1/audio/transcriptions) — Whisper, GPT-4o |
generate_video | Texto a video (asíncrono, reanudable) |
generate_video_from_image | Imagen a video (esquema más limitado) |
get_video_status | Consultar / reanudar trabajos de video |
search_models | Búsqueda paginada del catálogo de modelos |
get_model_info | Precios, contexto, modalidades |
validate_model | Verificación de existencia de ID de modelo económica |
rerank_documents | Clasificación de relevancia para RAG |
health_check | Clave de API + prueba de alcance |
Los errores usan una taxonomía cerrada de _meta.code: INVALID_INPUT · UNSAFE_PATH · UPSTREAM_* · MODEL_NOT_FOUND · JOB_STILL_RUNNING · y más.
Resultados binarios de herramientas (v4.7.0+)
Las herramientas de generación (generate_image, generate_image_dedicated, generate_audio, text_to_speech, generate_video, generate_video_from_image, get_video_status) devuelven bytes de imagen, audio o video. A partir de 4.7.0 el comportamiento es explícito:
save_path | Resultado de la herramienta |
|---|---|
| Establecido | Solo puntero de texto — p. ej., Image saved to: out.png (… bytes, image/png) más _meta.save_path. Sin base64 en línea (evita duplicar cargas útiles grandes en el canal MCP). |
| No establecido, bajo el límite de bytes | Bloque de medios en línea y texto de resumen (las imágenes/audio usan tipos MCP image / audio; el video usa bloques MCP resource). |
| No establecido, sobre el límite | Solo texto con una sugerencia para pasar save_path. |
Límites en línea predeterminados (anular por tipo o globalmente):
| Tipo | Predeterminado | Variables de entorno (precedencia: por tipo → global) |
|---|---|---|
| Imagen | 1 MiB | OPENROUTER_IMAGE_INLINE_MAX_BYTES → OPENROUTER_INLINE_MAX_BYTES |
| Audio | 1 MiB | OPENROUTER_AUDIO_INLINE_MAX_BYTES → OPENROUTER_INLINE_MAX_BYTES |
| Video | 10 MiB | OPENROUTER_VIDEO_INLINE_MAX_BYTES → OPENROUTER_INLINE_MAX_BYTES |
Si antes dependías de ambos, un archivo guardado y medios en línea en el mismo resultado de herramienta, lee el archivo desde _meta.save_path (u omite save_path para obtener medios en línea cuando esté bajo el límite).
Ejemplos
Chat (modelo gratuito)
{
"tool": "chat_completion",
"arguments": {
"model": "google/gemma-4-26b-a4b-it:free",
"messages": [{ "role": "user", "content": "Summarize MCP in one sentence." }]
}
}
Analizar una imagen
{
"tool": "analyze_image",
"arguments": {
"image_path": "diagram.png",
"question": "List every label in this diagram."
}
}
Usa
image_pathyquestion— noimage/prompt.
Buscar modelos (visión + gratuito)
{
"tool": "search_models",
"arguments": {
"query": "gemma",
"capabilities": { "vision": true },
"limit": 10,
"offset": 0
}
}
Generar video (asíncrono)
{
"tool": "generate_video",
"arguments": {
"model": "google/veo-3.1",
"prompt": "Ocean waves at sunrise, cinematic drone shot",
"duration": 4,
"save_path": "river.mp4"
}
}
Si el trabajo aún se está ejecutando cuando transcurre max_wait_ms, la respuesta tiene éxito con _meta.code: JOB_STILL_RUNNING y un video_id — llama a get_video_status para reanudar. Esto no es un error.
Con save_path establecido (como arriba), el resultado es un puntero de texto al archivo guardado una vez completado — no video en línea. Consulta Resultados binarios de herramientas.
Más ejemplos: docs/plans/tool-description-improvement.md
Seguridad
- Sandbox de rutas de entrada — las rutas locales en
analyze_*y las imágenes de referencia deben permanecer dentro deOPENROUTER_INPUT_DIR(se recurre aOPENROUTER_OUTPUT_DIR, luego acwd) - Sandbox de rutas de salida —
save_pathdebe permanecer dentro deOPENROUTER_OUTPUT_DIR - Lecturas de trabajos asíncronos —
get_chat_completion_statusresuelve rutas de disco solo bajoOPENROUTER_OUTPUT_DIR/openrouter-jobs/(4.7.0+) - Protección SSRF — las IP privadas/reservadas están bloqueadas en las búsquedas de URL
- Contenido no confiable — los resultados de análisis se etiquetan con
_meta.content_is_untrusted: true
Anula los sandboxes solo con OPENROUTER_ALLOW_UNSAFE_PATHS=1 (desaconsejado).
Reporta vulnerabilidades: SECURITY.md (divulgación privada — no publiques problemas públicos para exploits).
Configuración
Variables de entorno
| Variable | Requerida | Predeterminado | Descripción |
|---|---|---|---|
OPENROUTER_API_KEY | Sí | — | Clave de API de OpenRouter |
OPENROUTER_DEFAULT_MODEL | No | google/gemma-4-26b-a4b-it:free | Predeterminado cuando las herramientas omiten model |
OPENROUTER_OUTPUT_DIR | No | cwd | Raíz del sandbox para save_path |
OPENROUTER_INPUT_DIR | No | OUTPUT_DIR o cwd | Raíz del sandbox para archivos de entrada locales |
OPENROUTER_INLINE_MAX_BYTES | No | 1048576 (imagen/audio) | Límite global de medios en línea |
OPENROUTER_IMAGE_INLINE_MAX_BYTES | No | recurre al global | Límite en línea por tipo |
OPENROUTER_AUDIO_INLINE_MAX_BYTES | No | recurre al global | Límite en línea por tipo |
OPENROUTER_VIDEO_INLINE_MAX_BYTES | No | 10485760 | Límite en línea de video |
OPENROUTER_LOG_LEVEL | No | info | error / warn / info / debug |
Consulta .env.example para la lista completa (enrutamiento de proveedor, límites de búsqueda, caché, sondeo de video, trabajos asíncronos, anulaciones de pruebas de integración).
Desarrollo
git clone https://github.com/stabgan/openrouter-mcp-multimodal.git
cd openrouter-mcp-multimodal
npm install
cp .env.example .env # add OPENROUTER_API_KEY
npm run build
Pruebas
| Comando | Qué ejecuta |
|---|---|
npm test | 1018 pruebas unitarias + simuladas (sin clave de API, <20s) |
npm run test:regression | Guardas de regresión de seguridad + esquema |
npm run test:integration | 16 escenarios en vivo de OpenRouter (requiere clave .env) |
npm run test:e2e | Prueba de humo completa de stdio MCP (scripts/live-e2e.mjs) |
npm run ci | lint + formato + compilación + todo lo anterior excepto e2e |
Modelos gratuitos para CI / cuentas sin crédito: las pruebas de integración usan por defecto google/gemma-4-26b-a4b-it:free (anula con OPENROUTER_INTEGRATION_MODEL). GitHub Actions requiere el secreto de repositorio OPENROUTER_API_KEY. |
Las pruebas simuladas se encuentran en src/__tests__/mock/ y cubren manejadores, sandboxes de rutas, bloqueos SSRF, paginación de caché de modelos, descripciones de herramientas y salidas estructuradas — más de 330 casos adicionales más allá del conjunto principal.
npm run lint
npm run format:check
npm run version:check # package.json vs src/version.ts, server.json, pyproject.toml
Publicación
Los artefactos publicados (npm, PyPI/uvx, Docker, GHCR) se distribuyen todos desde el mismo semver en una etiqueta git (vX.Y.Z). Hacer push a main ejecuta pruebas pero no publica en npm ni PyPI.
Flujo normal: fusiona commits convencionales a main → Release Please abre un PR de Release → fúndelo → se crea la etiqueta → CI publica en todas partes.
Flujo manual: incrementa todos los archivos de versión → npm run version:check → npm run ci + pruebas de humo → haz commit → git tag vX.Y.Z → git push origin vX.Y.Z.
Lista de verificación completa, lista de archivos, secretos de CI e instrucciones para agentes:
docs/RELEASING.md— guía de publicación para mantenedoresAGENTS.md— referencia rápida para agentes de IA
Solución de problemas
| Síntoma | Causa probable | Solución |
|---|---|---|
El servidor sale inmediatamente / OPENROUTER_API_KEY is required | Clave API faltante o vacía | Establece OPENROUTER_API_KEY en el env del cliente o en el shell — obtén una en openrouter.ai/keys |
_meta.code: INVALID_CREDENTIALS o HTTP 401 | Clave mala o revocada | Regenera en openrouter.ai/keys; reinicia el cliente MCP |
_meta.code: MODEL_NOT_FOUND | Error tipográfico o ID de modelo retirado | Ejecuta search_models o validate_model; consulta openrouter.ai/models |
| HTTP 402 / créditos insuficientes | Modelo de pago o generación con saldo cero | Añade créditos en openrouter.ai/credits o usa un modelo :free |
_meta.code: UPSTREAM_HTTP con 429 | Límite de velocidad | Espera a _meta.retry_after_seconds si está presente; reduce la concurrencia |
_meta.code: UNSAFE_PATH | Ruta local fuera del sandbox | Coloca archivos bajo OPENROUTER_INPUT_DIR o establece OPENROUTER_OUTPUT_DIR más amplio; consulta Seguridad |
npx no encontrado (aplicaciones GUI de Windows) | El PATH de la GUI difiere del terminal | Usa el envoltorio cmd /c de Windows npx |
| Sin imagen/audio en línea después de la actualización | v4.7.0 con save_path establecido | Esperado — el resultado es solo texto + _meta.save_path; omite save_path o lee el archivo guardado |
| El cliente MCP muestra una lista de herramientas obsoleta | Caché del cliente | Reinicia MCP / recarga la ventana después de actualizar la fijación del paquete |
Los errores estructurados incluyen _meta.suggestions con próximos pasos orientados a agentes cuando estén disponibles.
Preguntas frecuentes
¿Necesito créditos de pago de OpenRouter?
No, para empezar. Los modelos gratuitos funcionan para chat y visión. La generación de audio/video generalmente requiere créditos; el análisis puede devolver 402 en algunos modelos — el servidor lo presenta como un error estructurado.
¿Qué clientes MCP son compatibles?
Cualquier cliente compatible con MCP a través de stdio: Cursor, Claude Desktop, VS Code Copilot, Windsurf, Cline, Kiro y agentes personalizados.
¿En qué se diferencia esto de llamar a OpenRouter directamente?
Este servidor añade esquemas de herramientas MCP, sandboxes de seguridad, taxonomía de errores, caché de modelos, sondeo asíncrono de video con notificaciones de progreso y descripciones de herramientas orientadas a agentes — para que los LLM invoquen la capacidad correcta sin pegamento HTTP personalizado.
¿Dónde está el aviso de seguridad para el recorrido de rutas?
Corregido en 4.5.2+ — consulta GHSA-3q7p-736f-x44v, SECURITY.md y docs/solutions/security-issues/.
Compatibilidad
Funciona con cualquier cliente MCP. Protocolo: MCP 2025-06-18. Node ≥ 22 (la imagen Docker usa Node 24).
Licencia
Apache 2.0 — consulta LICENSE.
Contribuciones
Se aceptan issues y PRs. Para cambios grandes, abre primero un issue.
Antes de enviar: ejecuta npm run ci. Usa Conventional Commits (fix:, feat:, etc.) para que Release Please pueda preparar la próxima versión. Consulta docs/RELEASING.md si necesitas publicar una versión.