RestRuno

Cliente REST de escritorio (Windows y macOS) — estilo Postman/Bruno, con colecciones 100 % locales, variables, scripts, runner con datos y generación de CSV.

Free y Pro

RestRuno es gratis para el trabajo diario: colecciones, peticiones, ambientes, variables, scripts con tests, import/export Postman/Bruno, cookies y consola. Dos funciones avanzadas forman parte de RestRuno Pro (pago único, licencia para 2 dispositivos):

Free Pro
Colecciones, requests, ambientes, variables
Scripts pre/post con tests
Import/Export Postman y Bruno
✨ Asistente de IA
▶ Runner data-driven (CSV/JSON, reportes, CSV de salida)
🔌 Servidor local MCP + API (control desde IA)

Comprar RestRuno Pro — $20 — pago único, actualizaciones incluidas, 2 dispositivos. La compra la procesa Polar y recibes tu license key por email; actívala en la app con el botón Upgrade de la barra superior. Términos de uso en la licencia (EULA).

¿Para tu equipo? RestRuno Enterprise — $149: pago único, 25 seats (una sola key para todo el equipo, 50 activaciones), rollout simple y soporte prioritario por email.

Instalación y actualizaciones

Instalar (los botones de restruno.com detectan tu sistema, o descarga del release más reciente):

Actualizaciones:

  1. Automáticas y silenciosas: poco después de abrir la app (cuando ya terminó de cargar, para no estorbar el arranque) se revisa este repositorio; si hay versión nueva se descarga completa en segundo plano.
  2. Cuando la descarga está lista aparece un botón naranja Update en la esquina inferior derecha: clic → se instala y la app se reinicia. Si no lo pulsas, la actualización se instala sola al cerrar la app.
  3. Buscar manualmente: haz clic en el número de versión (vX.Y.Z) de la esquina inferior derecha. Te dice al momento si hay versión nueva (y arranca la descarga en segundo plano), si ya estás al día, o el error si no hay conexión.
  4. Botón Docs (barra superior) abre esta documentación en tu navegador.

Colecciones

Una colección es una carpeta en tu disco que tú eliges. Cada petición es un archivo *.rr.json legible; las subcarpetas son folders. Puedes versionarlas con Git o respaldarlas copiando la carpeta.

Acción Cómo
Crear colección Botón New → nombre → elige la carpeta padre
Abrir colección existente Botón Open → selecciona la carpeta de la colección
Importar de Postman/Bruno Botón Import → elige el JSON exportado (Postman v2.x o Bruno)
Exportar Click derecho en la colección → Export Collection (genera Postman v2.1 + un archivo por ambiente)
Nueva petición / folder Click derecho en la colección o folder → New Request / New Folder
Duplicar Click derecho → Duplicate (peticiones, folders o la colección completa)
Renombrar / Eliminar Click derecho → Rename / Delete
Mover Arrastra y suelta peticiones o folders (con todo su contenido) a otro folder o a otra colección
Expandir / contraer todo Botón ⊟/⊞ junto a Import
Ocultar panel lateral Botón ◧ arriba a la izquierda o Ctrl+B

Peticiones

Variables

Sintaxis {{variable}} en URL, params, headers, auth y body. Precedencia (mayor gana):

runtime (scripts) → fila del data file → colección → ambiente → globales

Scripts (pestaña Scripts de cada petición)

Dos paneles: Pre Request (antes de enviar) y Post Response (validaciones). Cada panel tiene un menú Snippets… con ejemplos listos y un botón ⛶ para maximizarlo.

// Pre Request
rr.variables.set('token', 'abc');              // runtime: solo memoria, fluye entre peticiones
rr.variables.setGlobal('clave', 'valor');      // se guarda en globales (globals.json)
rr.variables.setEnvironment('token', 'abc');   // se guarda en el AMBIENTE ACTIVO (environments/<nombre>.json)
rr.request.headers['X-Trace'] = '1';           // modificar la petición saliente

// Post Response (tests)
rr.test('status es 200', () => rr.expect(rr.response.status).toBe(200));
rr.test('tiene id', () => rr.expect(rr.response.body.id).toBeDefined());
rr.variables.set('token', rr.response.body.token);  // encadenar login → siguiente petición

Referencia de comandos rr

Los scripts son JavaScript síncrono en un sandbox. No hay require/import/fetch/process/setTimeout, ni async/await, ni acceso a red. Timeout de 5 segundos.

Variables (funcionan en pre y post):

Comando Qué hace Persistencia
rr.variables.get(key) Lee una variable resolviendo la precedencia: runtime → fila de datos → colección → ambiente → global
rr.variables.set(key, value) Guarda en ámbito runtime (memoria); fluye a las siguientes peticiones de la sesión/run, se resetea entre iteraciones No se guarda a disco
rr.variables.setEnvironment(key, value) Guarda en el ambiente activo environments/<nombre>.json (visible en el editor)
rr.variables.setGlobal(key, value) Guarda una variable global globals.json (diálogo Globals)

Los valores se guardan como texto — usa JSON.stringify(obj) si necesitas guardar un objeto, y JSON.parse(...) al leerlo.

Pre Request — modificar la petición antes de enviarla (solo en el script pre):

Comando Descripción
rr.request.method Método (string), asignable
rr.request.url URL (string, admite {{vars}})
rr.request.headers['Nombre'] = valor Agrega/reemplaza un header
rr.request.params['clave'] = valor Agrega/reemplaza un query param

Post Response — leer la respuesta (solo en el script post):

Comando Descripción
rr.response.status Código HTTP (número), ej. 200
rr.response.statusText Texto del status
rr.response.headers['content-type'] Headers (claves en minúscula)
rr.response.body Body como JSON parseado (o undefined si no es JSON)
rr.response.bodyText Body como texto crudo
rr.response.timeMs Tiempo transcurrido (número)
rr.response.sizeBytes Tamaño de la respuesta (número)

Tests (post) — cada rr.test se reporta como pass/fail en el runner y el panel de respuesta:

console.log/info/warn/error(...) se captura y aparece en la consola global.

Ejemplo completo (post-response de un login que guarda el token de forma persistente):

rr.test('login OK', () => rr.expect(rr.response.status).toBe(200));
rr.test('devuelve token', () => rr.expect(rr.response.body.access_token).toBeDefined());
rr.test('content-type json', () =>
  rr.expect(rr.response.headers['content-type']).toMatch(/application\/json/));

// guarda el token en el ambiente activo para las siguientes peticiones:
rr.variables.setEnvironment('token', rr.response.body.access_token);
console.log('token guardado:', rr.response.body.access_token);

El menú Snippets… de cada panel inserta muchos de estos patrones listos para usar. Si tienes el asistente de IA activado, el botón ✨ genera scripts a partir de una descripción usando esta misma referencia.

Runner (Pro)

Función de RestRuno Pro desde la versión 3.0.

Click derecho en una colección o folder → Run Collection / Run Folder. Se abre como un tab de pantalla completa:

Asistente de IA (Pro)

Función de RestRuno Pro desde la versión 3.0. La configuración es libre; ejecutar acciones de IA requiere licencia.

Botón ✨ AI en la barra superior. Conecta cualquier endpoint compatible con OpenAI: OpenAI, Ollama, LM Studio, OpenRouter, Groq, etc. Es totalmente opcional — si no lo configuras, RestRuno funciona exactamente igual y no aparece ningún botón de IA.

💡 Funciona con modelos open source — gratis y 100 % en tu máquina. Instala Ollama o LM Studio y usa Llama, Mistral, DeepSeek, Qwen, Gemma, o cualquier otro modelo abierto, corriendo localmente: sin pagar ninguna API, sin suscripciones y sin que tus requests salgan de tu computadora. También puedes usar modelos open source alojados (OpenRouter, Groq) si prefieres no correrlos tú.

Configuración (se guarda solo en tu computadora):

Campo Ejemplos
Base URL https://api.openai.com/v1 · http://localhost:11434/v1 (Ollama) · https://openrouter.ai/api/v1
API Key tu clave del proveedor (vacío para modelos locales)
Model gpt-4o-mini · llama3.1 · claude-3-5-sonnet

Marca Enable AI assistant, usa Test Connection para verificar, y guarda. El botón ✨ AI de la barra superior muestra un punto verde cuando está habilitado y el último test de conexión fue exitoso (gris si está deshabilitado o sin verificar). Al habilitarlo aparecen botones en tres lugares:

  1. Scripts (pre y post) — ✨ en el encabezado de cada panel: describe lo que necesitas ("valida que el status sea 201 y guarda el id en una variable") y genera el script usando la API rr.* correcta, con el contexto de tu request. Botón Insert into script lo agrega al editor.
  2. Response — botón ✨ Explain: analiza el request + response + tests fallidos y te explica qué pasó, la causa probable del error y cómo corregirlo.
  3. Columnas CSV del Runner✨ AI expression: describe el valor que quieres extraer ("el id del primer item") y genera la expresión (body.items[0].id) usando como contexto el último response del run; Add as column la agrega directo.

En cada acción puedes editar la instrucción, regenerar, copiar o insertar el resultado. Privacidad: al usar estas acciones, el request/response involucrado se envía a tu proveedor de IA configurado — con Ollama/LM Studio todo queda en tu máquina.

Ejemplos de uso:

Consola global

Barra Console al pie de la ventana: registra cada petición enviada, cada ejecución del runner y los console.log de tus scripts. Filtros All / Requests / Errors / Logs, fecha y hora ocultable, y botón Clear.

Servidor local MCP + API (Pro)

Función de RestRuno Pro desde la versión 3.0.

Botón MCP Server en la barra superior. Permite que una IA (Claude, GitHub Copilot, Cursor, Antigravity, OpenAI Codex, etc.) controle RestRuno: crear, editar, eliminar y enviar requests, y leer el response, la consola y los errores — todo local, sin nube.

Cómo configurarlo

  1. Abre MCP Server → marca Enable local server (aparece "● running").
  2. Copia el MCP endpoint (http://127.0.0.1:<puerto>/mcp) y el Bearer token.
  3. En Connect your AI — pick your client, elige tu cliente y copia el snippet listo para pegar:
Cliente Dónde va la configuración
Claude Code Un comando en la terminal: claude mcp add --transport http restruno <url> --header "Authorization: Bearer <token>"
Claude Desktop Settings → Developer → Edit Config → claude_desktop_config.json (usa el puente mcp-remote); reinicia Claude
VS Code / Copilot .vscode/mcp.json del proyecto (agent mode de Copilot)
OpenAI Codex Un comando en la terminal: codex mcp add restruno -- npx -y mcp-remote <url> --header "Authorization: Bearer <token>"
Cursor / Antigravity / otros JSON genérico mcpServers~/.cursor/mcp.json en Cursor, panel de MCP (mcp_config.json) en Antigravity; la mayoría de clientes MCP aceptan esta misma forma

Herramientas expuestas al cliente MCP: list_collections, get_tree, read_request, create_request, update_request, delete_request, create_folder, send_request, get_console.

Ejemplos de uso (desde tu IA)

Con el cliente conectado, pídele cosas como:

API REST (alternativa sin MCP)

Llamadas HTTP planas a http://127.0.0.1:<puerto>/api/* con Authorization: Bearer <token> — útil para scripts o CI local:

# listar colecciones (devuelve name + rootPath de cada una)
curl http://127.0.0.1:<puerto>/api/collections -H "Authorization: Bearer <token>"

# árbol de una colección
curl "http://127.0.0.1:<puerto>/api/tree?rootPath=/ruta/a/pagos" -H "Authorization: Bearer <token>"

# enviar un request existente (ruta absoluta) con un ambiente, y leer el response
curl -X POST http://127.0.0.1:<puerto>/api/send \
  -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
  -d '{"requestPath": "/ruta/a/pagos/login.rr.json", "environmentName": "dev"}'

# leer la consola (últimas 20 entradas)
curl "http://127.0.0.1:<puerto>/api/console?limit=20" -H "Authorization: Bearer <token>"

Endpoints: GET /api/health · GET /api/collections · GET /api/tree?rootPath= · GET|POST|PATCH|DELETE /api/request · POST /api/folder · POST /api/send · GET /api/console?limit=.

Cookies de sesión

Las respuestas con Set-Cookie se recuerdan solo en memoria (nunca en disco) y se reenvían a peticiones del mismo host — así funcionan los flujos de login. En Globals puedes desactivarlas o limpiarlas. No se almacena caché HTTP.

¿Dónde se guarda todo?

Qué Dónde
Peticiones, folders, variables de colección La carpeta de la colección (archivos JSON)
Ambientes environments/ dentro de la colección
Ejecuciones persistidas del runner runs/ dentro de la colección
Variables globales y preferencias Perfil del usuario (AppData)
Responses de peticiones manuales Solo en memoria (se pierden al cerrar)
Cookies Solo en memoria (se pierden al cerrar)

Atajos

Ctrl+Enter enviar · Ctrl+S guardar · Ctrl+W cerrar tab · Ctrl+B mostrar/ocultar panel lateral