OpenRouter MCP Server
OpenRouter MCP Server
Servidor MCP remoto (HTTP streamable, JSON sin estado) que permite a los agentes de IA delegar tareas en modelos más baratos a través de la API de OpenRouter, consultando el catálogo y los precios en vivo, con una política de costos configurable mediante un archivo .env.
Qué hace
Catálogo en vivo: consulta
GET /api/v1/modelsde OpenRouter (con caché de 5 minutos) y expone precios en USD por millón de tokens, ventana de contexto y soporte de llamada a herramientas.Delegación explícita: el agente elige el modelo mirando los precios y delega la tarea.
Delegación automática basada en precio: el servidor elige el modelo según un nivel (
economy/balanced/quality) usando bandas de precio configurables.Política mediante
.env: topes de precio máximo, listas de modelos permitidos/bloqueados, modelo predeterminado, proveedores preferidos.Costo real: cada delegación devuelve los tokens usados y el costo estimado en USD.
Related MCP server: frugal
Instalación
npm install
cp .env.example .env # edit and set your OPENROUTER_API_KEY
npm run build
npm start # listens on http://localhost:3000/mcpPara desarrollo con recarga automática: npm run dev.
Docker
Una imagen multi-arquitectura (linux/amd64, linux/arm64) se compila automáticamente mediante GitHub Actions y se publica en GHCR:
ghcr.io/vmhq/openrouter-mcp-serverEtiquetas disponibles: latest (rama principal), vX.Y.Z / X.Y (lanzamientos), main y sha-<commit>.
Docker Compose
services:
openrouter-mcp:
image: ghcr.io/vmhq/openrouter-mcp-server:latest
container_name: openrouter-mcp
restart: unless-stopped
ports:
- "3000:3000"
env_file:
- .env
volumes:
# Persists OAuth state (registered clients, token hashes)
- ./data:/app/data
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
interval: 30s
timeout: 5s
retries: 3docker compose up -dNota: el contenedor se ejecuta como el usuario no privilegiado
node. Asegúrate de que el directorio montado./datasea escribible por el UID 1000 (chown -R 1000:1000 ./data); de lo contrario, el estado de OAuth no se puede persistir.
Ejemplo de .env
# --- Required ---
# Your OpenRouter API key (https://openrouter.ai/keys)
OPENROUTER_API_KEY=sk-or-v1-...
# --- HTTP server ---
# Port where the MCP endpoint is exposed (http://host:PORT/mcp)
PORT=3000
# Optional static bearer token. If set, MCP clients must send
# "Authorization: Bearer <token>". Strongly recommended if the server
# is reachable outside localhost.
MCP_AUTH_TOKEN=
# --- Interactive OAuth with PocketID (for AI agents like Claude) ---
# Public URL of this server (e.g. https://mcp.example.com). Required so the
# OAuth metadata and callback point to the right URL behind a reverse proxy.
MCP_PUBLIC_URL=
# When all three POCKETID_* variables are set, the /oauth/authorize flow
# delegates the human login to your PocketID instance (passkey).
# In PocketID: create an OIDC client and register this callback:
# <MCP_PUBLIC_URL>/oauth/callback
POCKETID_ISSUER=
POCKETID_CLIENT_ID=
POCKETID_CLIENT_SECRET=
# Optional OIDC scopes (space-separated). Default: "openid profile email".
# POCKETID_SCOPES=openid profile email
# Path of the file where OAuth state is persisted (registered clients,
# one-time codes, and token hashes). Default: ./data/oauth-state.json
# MCP_OAUTH_STATE_PATH=./data/oauth-state.json
# OAuth access token lifetime, in seconds. Default: 2592000 (30 days).
# MCP_OAUTH_TOKEN_TTL_S=2592000
# --- Optional OpenRouter attribution (rankings) ---
APP_URL=
APP_TITLE=OpenRouter MCP Server
# --- Delegation policy ---
# Default model when the agent doesn't specify one in openrouter_delegate_task
DEFAULT_MODEL=
# Price caps (USD per million tokens). Models above them are rejected
# with an explanatory error. Empty = no limit.
MAX_PROMPT_PRICE_PER_M=
MAX_COMPLETION_PRICE_PER_M=
# Comma-separated control lists. Accept exact ids ("openai/gpt-4.1-mini")
# or provider prefixes ("openai/"). Empty ALLOWED_MODELS = all allowed
# (except blocked ones).
ALLOWED_MODELS=
BLOCKED_MODELS=
# Allow free models (price 0)? They usually have strict rate limits.
ALLOW_FREE_MODELS=true
# Preferred providers for automatic selection (openrouter_auto_delegate)
PREFERRED_PROVIDERS=openai,anthropic,google,meta-llama,mistralai,deepseek,qwen,x-ai,amazon
# "Combined" price caps (70% prompt + 30% completion, USD/M tokens)
# for each tier of the automatic selection.
TIER_ECONOMY_MAX_PRICE=0.5
TIER_BALANCED_MAX_PRICE=3
TIER_QUALITY_MAX_PRICE=15
# Model catalog cache, in seconds
MODELS_CACHE_TTL_SECONDS=300Variables de entorno
Consulta .env.example — las principales:
Variable | Descripción |
| Obligatoria. Tu clave de https://openrouter.ai/keys |
| Puerto HTTP (por defecto 3000) |
| Si se define, los clientes deben enviar |
| URL pública del servidor (p. ej. |
| Habilita el inicio de sesión OAuth interactivo delegando la autenticación a tu instancia de PocketID (ver más abajo) |
| Modelo usado por |
| Tope de precio (USD/M tokens); los modelos más caros se rechazan |
| Listas separadas por comas: ids exactos o prefijos ( |
| Permitir modelos gratuitos (por defecto |
| Topes de precio combinados (0.7·entrada + 0.3·salida) para cada nivel de la selección automática |
Herramientas expuestas
Herramienta | Descripción |
| Lista modelos con precios en vivo; filtra por texto, precio, contexto, llamada a herramientas; ordena por precio/contexto/recencia; paginado |
| Detalle completo de un modelo + si la política del |
| Delega una tarea a un modelo específico; devuelve respuesta, tokens y costo estimado |
| El servidor elige el modelo según el nivel de precio ( |
| Uso y límites de la clave API configurada |
Flujo típico del agente: openrouter_list_models (o directamente openrouter_auto_delegate con el nivel economy) → delegar la tarea → usar la respuesta, sabiendo cuánto costó.
Importante: el modelo delegado no ve la conversación del agente; la tarea (task) debe ser autocontenida, con todo el contexto necesario.
Conectar un agente
Claude Code:
claude mcp add --transport http openrouter http://localhost:3000/mcpCon un token de autenticación:
claude mcp add --transport http openrouter http://YOUR_HOST:3000/mcp --header "Authorization: Bearer YOUR_TOKEN"Cualquier cliente MCP: apúntalo al endpoint POST /mcp con el transporte "streamable HTTP". Hay un endpoint GET /health para monitoreo.
claude.ai (conector remoto): requiere una URL HTTPS pública — despliega el servidor en un VPS detrás de un proxy inverso (Caddy/nginx) o usa un túnel (p. ej. cloudflared tunnel). Con OAuth habilitado (ver más abajo), añade el conector apuntando a https://YOUR_HOST/mcp y deja vacíos los campos avanzados de OAuth Client ID/Secret: el servidor publica metadatos OAuth y soporta Dynamic Client Registration, por lo que Claude se registra solo y obtiene su token automáticamente al hacer clic en Authorize.
OAuth con PocketID
El servidor implementa OAuth 2.1 completo para agentes de IA (Claude, Cursor, …): actúa como servidor de autorización hacia los clientes MCP (Dynamic Client Registration RFC 7591 + PKCE S256 + emisión de sus propios tokens, con metadatos RFC 8414/9728) y delega el inicio de sesión humano a tu instancia de PocketID mediante OIDC (passkey).
Flujo: el cliente MCP recibe un 401 con WWW-Authenticate → descubre los metadatos en /.well-known/oauth-protected-resource → se registra en /oauth/register → abre /oauth/authorize en el navegador → el usuario inicia sesión en PocketID con su passkey → PocketID devuelve a /oauth/callback → el servidor emite su propio código y el cliente lo intercambia en /oauth/token por un token de acceso (30 días por defecto).
Configuración:
En PocketID, crea un nuevo cliente OIDC.
Registra la devolución de llamada:
<MCP_PUBLIC_URL>/oauth/callback.Restringe quién puede iniciar sesión usando los grupos permitidos del cliente OIDC en PocketID.
Copia el Client ID y Client Secret en
POCKETID_CLIENT_ID/POCKETID_CLIENT_SECRET, y establece la URL base de PocketID enPOCKETID_ISSUER.Establece
MCP_PUBLIC_URLa la URL HTTPS pública del servidor.
Si las variables POCKETID_* no están definidas, el flujo interactivo /oauth/authorize muestra un error; el bearer estático MCP_AUTH_TOKEN sigue funcionando en paralelo para acceso máquina a máquina (curl, Codex, etc.).
El estado de OAuth (clientes registrados, códigos de un solo uso y hashes SHA-256 de los tokens — nunca los tokens en texto plano) se persiste en ./data/oauth-state.json (configurable mediante MCP_OAUTH_STATE_PATH). Si el conector falla después de un reinicio con el estado borrado, elimínalo en Claude y vuelve a añadirlo para que se vuelva a registrar.
Cómo openrouter_auto_delegate elige un modelo
Filtra el catálogo según la política del
.envy los requisitos de la llamada (require_tools,min_context, salida de texto).Calcula el precio combinado por modelo:
0.7·input_price + 0.3·output_price(USD/M tokens).Según el nivel, busca dentro de su banda de precio (con respaldo a la banda vecina si está vacía):
economy(≤ $0.5/M por defecto): el más barato.balanced($0.5–$3/M): el más barato en la banda media.quality($3–$15/M): el de mayor precio dentro del tope (el precio como proxy de capacidad, sin llegar a los modelos insignia).
Prefiere proveedores de
PREFERRED_PROVIDERS, e informa en la respuesta el modelo elegido, el razonamiento y las alternativas descartadas.
Seguridad
La clave API de OpenRouter vive solo en el
.envdel servidor; nunca se expone a los agentes.El archivo
.envestá en.gitignore.Si el puerto es accesible desde fuera, establece
MCP_AUTH_TOKENy sirve detrás de HTTPS.
This server cannot be deployed
Maintenance
Related MCP Connectors
Real-time, drift-verified LLM pricing across 31 providers with cost+quality model routing.
Cost-optimized LLM model routing recommendations for autonomous AI agents
AI model routing on your own vendor keys: pick the best model per prompt, or route and run it.
Pay-per-call ($0.01 USDC) model-routing for AI coding agents: which LLM to call, cost vs. quality.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI agents to discover models, pricing, and chat completions through RouterBase, an API gateway for 200+ AI models.501MIT
- FlicenseNot gradedqualityAmaintenanceIntelligently routes AI tool calls (search, extract, browse) to the cheapest capable provider by default with automatic failover and audit receipts, enabling cost-effective agent workflows.2-
- AlicenseNot gradedqualityCmaintenanceEnables Claude to route sub-tasks to the cheapest suitable model tier based on semantic rules, with tools for dispatching and previewing routing decisions.MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to route chat completion requests to task-appropriate models via LiteLLM/OpenRouter, track usage and budgets, and run side-by-side eval comparisons of models based on cost, latency, and response quality.552 npmMIT