AIREITER

OpenRouter CLI: Ori, curl, llm y aichat

Última actualización: 2026-09-01 01:50:52

Cuando buscas un OpenRouter CLI, en realidad puedes estar hablando de dos cosas muy distintas. El comando oficial ori de OpenRouter configura y lanza agentes de programación existentes, mientras que los clientes de la comunidad ofrecen prompts puntuales, chat mediante REPL, salida JSON o una cobertura más amplia de la API. Si solo necesitas una tubería de shell, la API de OpenRouter y curl son suficientes.

Qué significa “OpenRouter CLI” en la práctica

“OpenRouter CLI” no es el nombre de un único cliente oficial y universal para la terminal. En la práctica, engloba tres flujos distintos: lanzar un agente a través de OpenRouter, llamar directamente a la API desde un shell o utilizar una herramienta de terminal de terceros como llm o aichat.

Lo que quieres hacer en la terminalEmpieza por aquíPor qué
Ejecutar Claude Code, Codex, OpenCode u otro agente compatibleHarness oficial de OriAplica OAuth, la selección de modelo y los ajustes de OpenRouter alrededor del agente existente
Enviar un prompt o procesar stdincurl más jqNo añade dependencias de otro CLI y ofrece control total sobre la petición
Consultar muchos endpoints de OpenRouter y devolver JSON@aaronjmars/openroutercliIncluye una cobertura amplia de comandos, modo JSON y una vía genérica para realizar peticiones
Usar un REPL de chat con búsqueda de modelos@letuscode/openrouter-cliOfrece prompts puntuales, chat REPL, búsqueda difusa de modelos y perfiles de configuración
Ejecutar prompts con varios modelos, lotes o cadenas de promptsorcIncluye perfiles, plantillas, procesamiento por lotes, encadenamiento y análisis de código
Conservar registros, esquemas, adjuntos y pluginsllm-openrouterAñade modelos de OpenRouter al CLI extensible llm
Combinar chat, asistencia para shell, RAG, agentes y proveedores localesaichatEs una herramienta de terminal más amplia basada en Rust, no un cliente exclusivo de OpenRouter

La diferencia importante está en quién mantiene cada herramienta y cuál es su alcance. La integración ori de OpenRouter y el paquete oficial @openrouter/cli de DevTools son oficiales, pero ninguno funciona como un cliente general del tipo openrouter ask: el paquete DevTools se centra en un visor de telemetría del SDK y en una línea de estado para Claude Code, mientras que Ori lanza harnesses ya existentes.

La vía oficial: instalar y usar Ori Harness

Ori es el CLI oficial de OpenRouter para configurar harnesses compatibles de agentes de programación. Se autentica con OpenRouter, pasa el modelo elegido al agente subyacente y conserva los comandos y flags habituales de ese agente; no sustituye a Claude Code, Codex, OpenCode ni a los demás harnesses.

Instálalo con el comando incluido en el anuncio y la guía de OpenRouter:

curl -fsSL https://openrouter.ai/labs/ori/install.sh | bash

Después, autentícate y lanza un agente:

ori login
ori claude
ori codex
ori opencode
ori hermes

La documentación actual de Ori también incluye grok, pi, prime-agent y dsh entre los comandos compatibles. ori dsh configura DeepSeek Harness, pero no lo inicia; después hay que ejecutar dsh. Puedes actualizar Ori con ori update.

OpenRouter Ori Harness page showing the official CLI entry point

Elige un modelo sin cambiar de agente

Ori acepta un ID de modelo de OpenRouter y reenvía al harness subyacente los argumentos que no reconoce:

ori claude --model anthropic/claude-sonnet-4.6
ori codex --model openai/gpt-5.2 --full-auto
ori opencode --model openrouter/auto
ori hermes --model openrouter/auto

Los detalles del endpoint no son idénticos en todos los agentes. Por ejemplo, las indicaciones de OpenRouter para Claude Code utilizan la URL base compatible con Anthropic https://openrouter.ai/api, mientras que los clientes compatibles con OpenAI, como Codex, usan https://openrouter.ai/api/v1. En parte, Ori existe para ocultar esas diferencias de configuración entre harnesses.

Ori utiliza OAuth PKCE mediante el navegador, así que normalmente no hace falta pegar una clave de API de OpenRouter en cada agente. La documentación de Ori Harness de OpenRouter indica que las peticiones utilizan la facturación y los informes de actividad estándar de OpenRouter, sin una factura independiente de Ori; el coste de inferencia sigue dependiendo del modelo seleccionado y del harness subyacente.

Ori no es un REPL de chat independiente

Usa Ori cuando ya quieras las herramientas, las operaciones con archivos o el modelo de aprobaciones de un agente. Recurre a curl, a un cliente directo, a llm o a aichat cuando la tarea consista en enviar un prompt, obtener una respuesta estructurada o montar una tubería de shell sin iniciar un agente de programación.

Esta diferencia es importante porque el material oficial de lanzamiento presenta Ori como una capa de compatibilidad y configuración. El paquete oficial @openrouter/cli genera otra posible confusión: sus comandos documentados actualmente son openrouter devtools y openrouter statusline, y la rama 1.0 eliminó comandos de proxy anteriores como start, stop, restart y code.

Clientes comunitarios de OpenRouter que conviene conocer

Los clientes de la comunidad se diferencian por la interfaz de terminal que ofrecen. La elección práctica depende de si necesitas un selector interactivo, cobertura completa de la API, un binario pequeño, automatización con varios modelos o una salida predecible y legible por máquinas.

ClienteForma de instalación o lanzamientoUso más destacadoAspectos que conviene comprobar
@aaronjmars/openrouterclinpm install -g @aaronjmars/openroutercliAcceso amplio a la API de OpenRouter, OAuth PKCE, --json, datos de uso, trabajos multimedia y request METHOD pathNo es oficial; requiere Node.js 20+; los comandos de gestión necesitan una clave de gestión
@letuscode/openrouter-clinpm i -g @letuscode/openrouter-cliopenrouter ask, repl, búsqueda difusa de modelos, perfiles, plantillas y salida en Markdown o texto planoEl README describe un desarrollo MVP; requiere Node.js 18.17+; Polyform Noncommercial 1.0.0
orcnpm install -g openrouter-cliPrompts con varios modelos, perfiles, plantillas, procesamiento por lotes, encadenamiento de prompts y análisis de códigoRequiere Node.js 22+; utiliza el comando orc; el proyecto y el paquete tienen nombres distintos del cliente con ámbito anterior
ortcargo +nightly-2026-03-25 install --locked ort-openrouter-cliUso rápido en terminal Linux, selección de proveedores, stdin, imágenes, continuación consciente de tmux y estadísticas de latencia y costeSolo Linux/x86_64; el README informa de que no valida los certificados TLS
llm-openrouterllm install llm-openrouterRegistros, alias, esquemas, adjuntos, herramientas y un flujo de trabajo maduro basado en pluginsUtiliza la convención OPENROUTER_KEY; el catálogo de modelos se almacena en caché durante una hora
aichatInstalación mediante gestor de paquetes o binarioREPL, asistente de shell, RAG, agentes, MCP, proveedores locales y un servidor HTTP localOfrece una abstracción amplia; el README no incluye una matriz de funciones o seguridad proveedor por proveedor

Estas son capacidades documentadas, no benchmarks de rendimiento comparables.

El flujo más pequeño y fiable: curl y jq

Si ya tienes instalados curl y jq, la API directa de OpenRouter es la vía más pequeña y transparente para trabajar desde la terminal. La guía Quickstart de OpenRouter documenta la autenticación Bearer, el endpoint compatible con OpenAI /api/v1/chat/completions, el campo model, el array messages y el streaming opcional.

Define una clave y un modelo en la sesión del shell:

export OPENROUTER_API_KEY='sk-or-v1-...'
export OR_MODEL='openai/gpt-4o'

Después, envía un prompt:

curl -sS https://openrouter.ai/api/v1/chat/completions \
  -H "Authorization: Bearer ${OPENROUTER_API_KEY}" \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg model "$OR_MODEL" \
    --arg prompt "Explain Unix pipes in three sentences." \
    '{model: $model, messages: [{role: "user", content: $prompt}], stream: false}')" \
  | jq -r '.choices[0].message.content // .error.message'

Es mejor guardar el modelo en una variable de entorno que copiar un ID en cada script. La API oficial de modelos expone id, longitud de contexto, precios, parámetros compatibles, límites del proveedor y metadatos opcionales de benchmarks.

Convierte la petición en funciones de shell reutilizables

Estas funciones mantienen el cuerpo JSON de la petición a salvo, ya que dejan que jq codifique el prompt. orask recibe un argumento; orpipe lee toda la entrada estándar como un único prompt.

orask() {
  local prompt="$*"
  local model="${OR_MODEL:?Set OR_MODEL to an OpenRouter model ID}"

  jq -n \
    --arg model "$model" \
    --arg prompt "$prompt" \
    '{model: $model, messages: [{role: "user", content: $prompt}], stream: false}' \
  | curl -sS --fail-with-body \
      https://openrouter.ai/api/v1/chat/completions \
      -H "Authorization: Bearer ${OPENROUTER_API_KEY:?Set OPENROUTER_API_KEY}" \
      -H "Content-Type: application/json" \
      -d @- \
  | jq -r '.choices[0].message.content // .error.message // "Unknown OpenRouter error"'
}

orpipe() {
  orask "$(cat)"
}

Ejemplos:

orask "Turn this error message into a likely diagnosis: connection reset by peer"
cat README.md | orpipe

Si tus scripts necesitan metadatos, conserva el JSON en lugar de extraer solo el texto:

orjson() {
  local prompt="$*"
  local model="${OR_MODEL:?Set OR_MODEL to an OpenRouter model ID}"

  jq -n \
    --arg model "$model" \
    --arg prompt "$prompt" \
    '{model: $model, messages: [{role: "user", content: $prompt}], stream: false}' \
  | curl -sS --fail-with-body \
      https://openrouter.ai/api/v1/chat/completions \
      -H "Authorization: Bearer ${OPENROUTER_API_KEY:?Set OPENROUTER_API_KEY}" \
      -H "Content-Type: application/json" \
      -d @-
}

Así mantienes disponible el objeto usage de la respuesta para contabilizar costes y puedes distinguir los errores de la API de una respuesta vacía del modelo.

Descubre modelos compatibles desde la línea de comandos

Que un modelo aparezca en el catálogo no significa que sea compatible con todos los parámetros de una petición. La API de modelos de OpenRouter permite filtrar por supported_parameters, incluido tools, y ordenar por precio, contexto, rendimiento, latencia, popularidad o actualidad.

Lista los modelos compatibles con herramientas empezando por los más baratos según el orden documentado:

curl -sS -G https://openrouter.ai/api/v1/models \
  --data-urlencode 'supported_parameters=tools' \
  --data-urlencode 'sort=pricing-low-to-high' \
| jq -r '.data[] | [.id, .context_length, .pricing.prompt, .pricing.completion] | @tsv' \
| head -20

Inspecciona un modelo antes de incorporarlo a un script de producción. OpenRouter documenta la ruta singular de detalle como /api/v1/model/{author}/{slug}:

curl -sS \
  "https://openrouter.ai/api/v1/model/${OR_MODEL}" \
| jq '.data | {id, context_length, architecture, pricing, supported_parameters, top_provider}'

Los valores de pricing se expresan por token o por unidad, así que no conviene interpretar un decimal sin más como un precio en dólares por millón de tokens. El campo usage de la respuesta es la fuente más fiable para saber cuántos tokens de entrada y salida consumió realmente una petición.

Procesamiento por lotes en una tubería de shell

Un flujo por lotes práctico consiste en guardar un prompt por línea en un archivo de texto y generar un objeto JSON por resultado. El siguiente script conserva el prompt original, la respuesta, el uso y un campo de error, sin mezclar la prosa del modelo con la salida legible por máquinas.

Crea prompts.txt:

Summarize the release notes in one paragraph.
List three security risks in this configuration.
Extract the names and versions from this sentence.

Ejecuta el lote:

#!/usr/bin/env bash
set -u

: "${OPENROUTER_API_KEY:?Set OPENROUTER_API_KEY}"
: "${OR_MODEL:?Set OR_MODEL}"

while IFS= read -r prompt || [[ -n "$prompt" ]]; do
  [[ -z "$prompt" ]] && continue

  request=$(jq -n \
    --arg model "$OR_MODEL" \
    --arg prompt "$prompt" \
    '{model: $model, messages: [{role: "user", content: $prompt}], stream: false}')

  response=$(curl -sS --fail-with-body \
    https://openrouter.ai/api/v1/chat/completions \
    -H "Authorization: Bearer ${OPENROUTER_API_KEY}" \
    -H "Content-Type: application/json" \
    -d "$request" || true)

  if jq -e '.choices[0].message.content' >/dev/null 2>&1 <<<"$response"; then
    jq -c --arg prompt "$prompt" \
      '{prompt: $prompt, answer: .choices[0].message.content, usage: (.usage // null)}' \
      <<<"$response"
  else
    jq -c --arg prompt "$prompt" \
      '{prompt: $prompt, answer: null, error: (.error.message // "Request failed"), usage: (.usage // null)}' \
      <<<"$response"
  fi
done < prompts.txt > results.jsonl

El script se ejecuta de forma secuencial; añade concurrencia solo después de comprobar los límites de frecuencia y el presupuesto, porque las peticiones paralelas pueden aumentar los costes rápidamente. La página de precios de OpenRouter indica 50 peticiones al día para el plan gratuito y una comisión de plataforma del 5,5 % para el modelo de pago por uso, así que utilizar un modelo gratuito no equivale a disponer de una capacidad de procesamiento por lotes ilimitada.

Dónde encajan llm y aichat

llm y aichat son herramientas generales de terminal compatibles con OpenRouter. Tienen más sentido que un wrapper pequeño cuando necesitas prompts reutilizables, sesiones, adjuntos, herramientas, modelos locales o un registro del trabajo anterior.

llm-openrouter: la opción con registros y extensible

Instala primero el comando base llm y después añade el plugin de OpenRouter:

llm install llm-openrouter
llm keys set openrouter

El plugin documenta OPENROUTER_KEY como nombre de la variable de entorno. Expone modelos de OpenRouter con nombres como openrouter/anthropic/claude-sonnet-5, almacena en caché la lista de modelos durante una hora y permite actualizarla con:

llm openrouter refresh
llm models list

Un prompt normal y una tubería de shell tendrían este aspecto:

llm -m openrouter/anthropic/claude-sonnet-5 \
  "Give me five short names for a pet tarantula"

cat app.py | llm -m openrouter/anthropic/claude-sonnet-5 \
  -s "Review this code for a security bug"

El plugin documenta esquemas, adjuntos, llamadas a herramientas, opciones de razonamiento, JSON para el enrutamiento de proveedores, herramientas web de OpenRouter e inspección de claves. Es un punto intermedio entre el curl directo y un harness de programación autónomo, aunque su caché de modelos puede tardar en reflejar el catálogo activo.

aichat: una herramienta de terminal más completa

aichat es un CLI basado en Rust que admite OpenRouter junto con más de 20 proveedores identificados y endpoints compatibles con OpenAI. Su superficie documentada incluye el modo CMD, un Chat-REPL, asistencia para shell, sesiones, macros, RAG, llamadas a funciones, herramientas MCP, agentes y un servidor local con endpoints de chat, embeddings y reranking.

Su configuración de OpenRouter utiliza un cliente compatible con OpenAI apuntando a https://openrouter.ai/api/v1, y los ejemplos del proyecto emplean el formato de modelo openrouter:<model>. Elígelo cuando la terminal empiece a convertirse en la interfaz de tu aplicación; usa curl o llm si prefieres una ruta de peticiones más pequeña y fácil de inspeccionar.

Cómo diagnosticar fallos que parecen un problema del CLI

Los fallos de un CLI de OpenRouter pueden producirse en la frontera entre el shell, el cliente, el modelo seleccionado y la cuenta. Diagnostica cada capa por separado antes de cambiar de herramienta.

SíntomaPrimera comprobaciónCapa probable
Error 401 o ausencia de claveImprime el nombre de la variable que espera el cliente; llm-openrouter usa OPENROUTER_KEY, mientras que los ejemplos de la API directa utilizan OPENROUTER_API_KEYAutenticación del shell o del cliente
Ori abre un agente, pero rechaza el modeloConfirma el ID del modelo y las expectativas de API del harness subyacenteCompatibilidad entre harness y modelo
Falta un modelo en el selectorActualiza la caché de una hora de llm; con otros harnesses, compárala con /api/v1/modelsCatálogo del cliente
Falla una petición de herramientas o esquemasFiltra /models con supported_parameters=tools o inspecciona los metadatos del modeloCapacidades del modelo
Una petición gratuita se detiene inesperadamenteComprueba el límite actual de peticiones del plan gratuito y si el modelo sigue ofreciéndose gratisPolítica de la cuenta o de la plataforma
El coste es superior al esperadoRegistra .usage, el proveedor seleccionado, las opciones de enrutamiento y el comportamiento de la cachéPetición y enrutamiento del proveedor

En una conversación de Reddit sobre OpenCode y Kilo Code, el usuario u/GrevireDev escribió:

“Both Kilo Code and OpenCode maintain a hard-coded/preloaded list of OpenRouter models instead of dynamically fetching the full catalog.” — r/openrouter

El usuario u/DrunkenRobotBipBop hizo esta observación sobre costes y caché en otra conversación de OpenRouter:

“Take care of how you handle caching in openrouter. Everytime the provider changes, the cache is gone and you are going to pay full price.” — r/openrouter

Tómalas como pistas para solucionar problemas, no como reglas de facturación; verifica los costes con el uso de cada petición, los datos del proveedor y los precios actuales de OpenRouter.

Preguntas frecuentes sobre OpenRouter CLI

Estas son las dudas recurrentes que hay detrás de la búsqueda openrouter cli. Las respuestas breves apuntan a la capa adecuada: lanzador oficial, API directa, cliente comunitario o catálogo de modelos.

¿Existe un CLI oficial de OpenRouter?

Sí. OpenRouter documenta oficialmente el CLI ori, pero Ori es una capa de lanzamiento y configuración para harnesses de programación existentes. El paquete npm @openrouter/cli de OpenRouter es una utilidad de DevTools independiente, mientras que los CLI de chat y API directa, como @aaronjmars/openroutercli, son proyectos de la comunidad.

¿Puedo usar OpenRouter desde una terminal sin instalar un CLI?

Sí. Una petición curl con autenticación Bearer a https://openrouter.ai/api/v1/chat/completions basta para enviar un prompt puntual, y jq puede extraer el texto o conservar el JSON para una tubería.

¿Cuál es el mejor CLI de OpenRouter para canalizar JSON?

Para un script pequeño, usar curl directamente implica menos comportamientos ocultos. Si necesitas una superficie de comandos más amplia, elige un cliente que documente un modo JSON, como @aaronjmars/openroutercli, o utiliza llm y conserva explícitamente los datos de respuesta que necesites.

¿Por qué mi CLI muestra menos modelos que la web de OpenRouter?

Es posible que el cliente almacene el catálogo en caché o incluya una lista de modelos precargada. Compara el selector con curl https://openrouter.ai/api/v1/models, actualiza la caché del cliente cuando sea posible y pasa el ID exacto del modelo devuelto, no su nombre visible.

¿Ori necesita una clave de API de OpenRouter?

La documentación de Ori de OpenRouter indica que el inicio de sesión normal utiliza OAuth PKCE, por lo que no es necesario crear y pegar una clave de API independiente. El curl directo, llm-openrouter y la mayoría de los clientes comunitarios siguen necesitando una clave o su propia configuración de autenticación.

Antes de automatizar un flujo de trabajo con OpenRouter CLI

Consulta la API de modelos en tiempo real antes de fijar un modelo, registra el ID del modelo y el usage de la respuesta, y establece un presupuesto para la cuenta o la clave. El CLI es solo la interfaz: el modelo de OpenRouter, la ruta del proveedor, el tamaño del contexto y los límites de la cuenta siguen siendo las variables que determinan si el flujo resulta fiable y asequible.