Skip to main content
Glama
vmhq

OpenRouter MCP Server

by vmhq

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/models de 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: whichmodel-mcp

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/mcp

Para 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-server

Etiquetas 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: 3
docker compose up -d

Nota: el contenedor se ejecuta como el usuario no privilegiado node. Asegúrate de que el directorio montado ./data sea 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=300

Variables de entorno

Consulta .env.example — las principales:

Variable

Descripción

OPENROUTER_API_KEY

Obligatoria. Tu clave de https://openrouter.ai/keys

PORT

Puerto HTTP (por defecto 3000)

MCP_AUTH_TOKEN

Si se define, los clientes deben enviar Authorization: Bearer <token>. Prácticamente obligatoria si expones el servidor fuera de localhost.

MCP_PUBLIC_URL

URL pública del servidor (p. ej. https://mcp.example.com); necesaria para el flujo OAuth detrás de un proxy inverso

POCKETID_ISSUER / POCKETID_CLIENT_ID / POCKETID_CLIENT_SECRET

Habilita el inicio de sesión OAuth interactivo delegando la autenticación a tu instancia de PocketID (ver más abajo)

DEFAULT_MODEL

Modelo usado por openrouter_delegate_task cuando el agente no especifica uno

MAX_PROMPT_PRICE_PER_M / MAX_COMPLETION_PRICE_PER_M

Tope de precio (USD/M tokens); los modelos más caros se rechazan

ALLOWED_MODELS / BLOCKED_MODELS

Listas separadas por comas: ids exactos o prefijos (openai/)

ALLOW_FREE_MODELS

Permitir modelos gratuitos (por defecto true)

TIER_*_MAX_PRICE

Topes de precio combinados (0.7·entrada + 0.3·salida) para cada nivel de la selección automática

Herramientas expuestas

Herramienta

Descripción

openrouter_list_models

Lista modelos con precios en vivo; filtra por texto, precio, contexto, llamada a herramientas; ordena por precio/contexto/recencia; paginado

openrouter_get_model

Detalle completo de un modelo + si la política del .env lo permite

openrouter_delegate_task

Delega una tarea a un modelo específico; devuelve respuesta, tokens y costo estimado

openrouter_auto_delegate

El servidor elige el modelo según el nivel de precio (economy/balanced/quality) y delega

openrouter_check_credits

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/mcp

Con 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:

  1. En PocketID, crea un nuevo cliente OIDC.

  2. Registra la devolución de llamada: <MCP_PUBLIC_URL>/oauth/callback.

  3. Restringe quién puede iniciar sesión usando los grupos permitidos del cliente OIDC en PocketID.

  4. Copia el Client ID y Client Secret en POCKETID_CLIENT_ID / POCKETID_CLIENT_SECRET, y establece la URL base de PocketID en POCKETID_ISSUER.

  5. Establece MCP_PUBLIC_URL a 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

  1. Filtra el catálogo según la política del .env y los requisitos de la llamada (require_tools, min_context, salida de texto).

  2. Calcula el precio combinado por modelo: 0.7·input_price + 0.3·output_price (USD/M tokens).

  3. 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).

  4. 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 .env del servidor; nunca se expone a los agentes.

  • El archivo .env está en .gitignore.

  • Si el puerto es accesible desde fuera, establece MCP_AUTH_TOKEN y sirve detrás de HTTPS.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • SaaS intelligence for AI agents. 5 unified tools cover 1,000+ services with 91-96% token savings.

  • See, price, and control every tool call your AI agents make: policy checks, cost, and audit tools.

  • Human-as-a-Service for AI agents. Delegate tasks that need a real human, get results via API.

View all MCP Connectors

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/vmhq/openrouter-mcp-server'

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