Cómo autoalojar Paperclip con Docker y qué hace con tus agentes de IA
Índice de contenidos
- Puntos clave
- Qué es Paperclip y qué problema resuelve
- Qué conceptos tiene: empresas, agentes, adaptadores, presupuestos y latidos
- Cómo instalar Paperclip con Docker
- Qué falla si cambias el puerto
- Qué pasa con el asistente inicial si no tienes claves de pago
- Cómo conectar un agente a un modelo local sin claves de pago
- El adaptador process con un script de 40 líneas
- Qué respondió el agente local y qué cuesta
- Cuándo compensa usar Paperclip y cuándo no
- Preguntas frecuentes
- ¿Paperclip funciona sin claves de pago?
- ¿Qué adaptador uso para un modelo local?
- ¿Cómo se actualiza Paperclip?
- Conclusión
- Fuentes
Paperclip es una plataforma de código abierto, con licencia MIT, que organiza equipos de agentes de IA como una empresa: tareas, presupuestos y latidos. Se autoaloja con un Docker Compose en el puerto 3100, pero el asistente inicial pide una suscripción de Claude u OpenAI. Probé un agente con un modelo local de 0,8B y respondió mal.
Paperclip es una plataforma de código abierto que coordina agentes de IA como si fueran los empleados de una empresa: les asigna tareas, les pone un presupuesto y los despierta con latidos en lugar de dejarlos corriendo. Lo levanté el 7 de octubre de 2026 en Docker con la versión v2026.1005.0 y le conecté un modelo local de 0,8B de parámetros, sin ninguna clave de pago. El servidor arranca bien, pero el asistente inicial da por hecho que tienes una cuenta de Claude u OpenAI, y mi agente local respondió mal. También tienes la versión en inglés.
Puntos clave
- Paperclip, según su README, es "open-source orchestration for teams of AI agents" y tiene licencia MIT. A 7 de octubre de 2026 el repositorio suma 98 209 estrellas, y se creó el 2 de marzo de 2026.
- Se autoaloja con un solo contenedor y una base de datos PostgreSQL embebida. La imagen se construye desde el código fuente, porque el Compose oficial no descarga una imagen ya hecha, y ocupa 7,29 GB.
- Sus conceptos son cinco: empresas, agentes, tareas, presupuestos y latidos. Cada agente se conecta mediante un adaptador, y la v2026.1005.0 trae 12 integrados.
- Sin claves de pago, el asistente inicial y el formulario de agente nuevo no te dejan avanzar con un modelo local. Funcionó el adaptador
processcreado por la API: 4 de 8 ejecuciones terminaron bien y 2 produjeron una respuesta. - El coste de ese agente local quedó registrado como 0 céntimos, con 55 tokens de entrada y 85 de salida en dos eventos de coste.
Qué es Paperclip y qué problema resuelve
Paperclip es un servidor Node.js con una interfaz React que gestiona agentes de IA con la lógica de una empresa. Su propia definición es corta: "If OpenClaw is an employee, Paperclip is the company", según el README del proyecto[1]. El agente hace el trabajo; Paperclip decide a quién le toca, cuánto puede gastar y cuándo se despierta.
Si ya has leído qué es un agente de IA, la diferencia es de capa. Un agente razona y usa herramientas. Paperclip no sustituye a ninguno: los envuelve en un organigrama, con tareas con historial, aprobaciones y un registro de actividad. Para coordinar dos o más agentes sin esa capa tienes los patrones de sistemas multiagente, que son un paso anterior y más artesanal.
El proyecto es reciente y se mueve deprisa. La versión v2026.1005.0[2], publicada el 5 de octubre de 2026, reúne 179 commits, y su nota de cambios incluye cambios que rompen compatibilidad, así que lee el log antes de actualizar.
Qué conceptos tiene: empresas, agentes, adaptadores, presupuestos y latidos
Los conceptos básicos de Paperclip[3] son pocos y caben en una tabla:
| Concepto | Qué es | Dato verificado |
|---|---|---|
| Empresa | La unidad superior: objetivo, agentes, tareas y presupuesto | Una instancia puede alojar más de una; cada una usa un prefijo (JAC en mi prueba) |
| Agente | Un empleado de IA con rol, jefe, adaptador y presupuesto | Estados: active, idle, running, error, paused, terminated |
| Tarea | La unidad de trabajo, con un solo responsable a la vez | Recorre los estados backlog, todo, in_progress, in_review y done |
| Adaptador | El puente entre Paperclip y el programa que ejecuta al agente | 12 integrados, entre ellos claude_local, codex_local, opencode_local, process y http |
| Presupuesto | Un tope mensual en céntimos, por empresa y por agente | Aviso al 80 % y parada automática al 100 % |
| Latido | Una ventana corta de ejecución que Paperclip dispara | Se dispara por horario, asignación, comentario, invocación manual o resolución de aprobación |
El latido merece una frase aparte. Un agente de Paperclip no está encendido: se despierta, mira su identidad, lee sus tareas asignadas, hace el checkout de una, trabaja y actualiza el estado. Ese ciclo es el protocolo de latido[4], y el checkout es atómico: si dos agentes reclaman la misma tarea, uno recibe un 409 Conflict.
El tope de gasto encaja con FinOps de tokens en agentes: un bucle descontrolado cuesta dinero real. Que el orquestador pare al agente al 100 % del presupuesto es una red de seguridad útil. En mi prueba el gasto fue cero, así que no vi ese freno actuar.
Cómo instalar Paperclip con Docker
El Compose oficial de arranque rápido está en docker/docker-compose.quickstart.yml y construye la imagen desde el repositorio. Clona la versión exacta, genera el secreto de sesión y levanta el servicio:
git clone https://github.com/paperclipai/paperclip
cd paperclip
git checkout v2026.1005.0
export BETTER_AUTH_SECRET="$(openssl rand -hex 32)"
docker compose -f docker/docker-compose.quickstart.yml up --build -d
La construcción compila un toolchain de Rust dentro de la imagen, y el resultado pesa 7,29 GB. El Compose publica el puerto 3100 y guarda la base de datos, los espacios de trabajo de los agentes y la clave local de secretos en ./data/docker-paperclip. Dentro del contenedor corren Node 24.21.0 y los CLI de Claude Code 2.1.292, Codex 0.160.1 y OpenCode 1.18.35. Para comprobar que responde:
curl -s http://localhost:3100/api/health
En mi caso la respuesta incluía "status":"ok", "deploymentMode":"authenticated" y "bootstrapStatus":"bootstrap_pending", que significa que aún no hay ningún administrador.
Qué falla si cambias el puerto
Yo no usé el 3100 porque este equipo reparte rangos de puertos entre pruebas simultáneas: publiqué el 29200 con PAPERCLIP_PORT=29200 y PAPERCLIP_PUBLIC_URL=http://localhost:29200. Crear la cuenta devolvió Invalid origin. El registro del servidor mostraba authPublicBaseUrl en http://localhost:3100/ y solo cuatro orígenes de confianza, todos con el puerto 3100, a pesar de la variable. Lo arreglé con un fichero de sobreescritura que añade el origen real:
services:
paperclip:
environment:
BETTER_AUTH_TRUSTED_ORIGINS: "http://localhost:29200"
Lo pasé con un segundo -f al mismo docker compose up -d. No probé el puerto 3100 por defecto, así que no sé si el fallo es exclusivo del puerto remapeado. Lo que sí sé es que PAPERCLIP_PUBLIC_URL no bastó.
Qué pasa con el asistente inicial si no tienes claves de pago
El asistente de incorporación tiene cuatro pasos: nombre de la organización, primer agente, conexión de un modelo y confirmación. Tras crear la cuenta con una petición a /api/auth/sign-up/email y pulsar Claim this instance, llegué al paso 3, "Connect a model", que solo ofrece Claude o OpenAI por suscripción, o una clave de API.

El formulario de agente nuevo es igual de estricto. Elegí el adaptador OpenCode y pidió una conexión a OpenRouter: "No connection selected. Connect an account to continue". El selector ofrece 12 adaptadores, y entre ellos no están process ni http. La documentación de Docker lo anticipa: "Without API keys, the app runs normally", pero las comprobaciones de entorno de cada adaptador avisan de lo que falta.
Salí del asistente en el paso 3. La empresa (Jacar Test Co, prefijo JAC) ya estaba creada, así que el resto lo hice con la API.
Cómo conectar un agente a un modelo local sin claves de pago
Hay dos caminos, y los probé los dos. El primero es el adaptador opencode_local, que admite cualquier proveedor compatible con OpenAI. Levanté Ollama 0.40.0 en otro contenedor, descargué qwen3.5:0.8b (752 millones de parámetros, cuantización Q8_0) y lo conecté a la red de Compose con el alias ollama. Después declaré el proveedor en la configuración de OpenCode, dentro del volumen de Paperclip:
{
"provider": {
"ollama": {
"npm": "@ai-sdk/openai-compatible",
"options": { "baseURL": "http://ollama:11434/v1" },
"models": { "qwen3.5:0.8b": {} }
}
}
}
Ese fichero va en /paperclip/.config/opencode/opencode.json, y opencode models pasó a listar ollama/qwen3.5:0.8b.
Creé el agente con una petición POST /api/companies/{id}/agents enviada con fetch desde la consola del navegador, ya con la sesión iniciada, y asigné una tarea.
La asignación disparó un latido, pero la ejecución no llegó a escribir ninguna línea de salida. La cancelé a los 5 minutos y 50 segundos. Ollama registró respuestas 500 a las llamadas del contenedor, una tras exactamente 5 minutos. La mayor petición que vio fue de 3 375 tokens, contra un contexto de 4096.
No saco una conclusión sobre OpenCode con un modelo de 0,8B. La máquina tenía una carga de entre 15 y 44 mientras probaba, así que no doy tiempos. Solo puedo decir que en mi entorno ese camino no terminó.
El adaptador process con un script de 40 líneas
El segundo camino es process, que ejecuta cualquier comando. Escribí un script en Python, sin dependencias, que sigue el protocolo de latido y consulta a Ollama. La primera mitad identifica al agente, busca sus tareas y hace el checkout:
import datetime, json, os, urllib.request
API, KEY = os.environ["PAPERCLIP_API_URL"], os.environ["PAPERCLIP_API_KEY"]
RUN, CO = os.environ["PAPERCLIP_RUN_ID"], os.environ["PAPERCLIP_COMPANY_ID"]
OLLAMA, MODEL = "http://ollama:11434", "qwen3.5:0.8b"
def call(method, url, body=None, auth=True):
h = {"Content-Type": "application/json", "X-Paperclip-Run-Id": RUN}
if auth:
h["Authorization"] = f"Bearer {KEY}"
data = json.dumps(body).encode() if body is not None else None
req = urllib.request.Request(url, data, h, method=method)
with urllib.request.urlopen(req, timeout=600) as r:
return json.loads(r.read() or "null")
me = call("GET", f"{API}/api/agents/me")
q = f"assigneeAgentId={me['id']}&status=todo,in_progress"
issues = call("GET", f"{API}/api/companies/{CO}/issues?{q}")
if not issues:
raise SystemExit(0)
issue = issues[0]
call("POST", f"{API}/api/issues/{issue['id']}/checkout", {
"agentId": me["id"], "expectedStatuses": ["todo", "backlog", "blocked"]})
Paperclip inyecta PAPERCLIP_API_URL, PAPERCLIP_API_KEY, PAPERCLIP_RUN_ID, PAPERCLIP_AGENT_ID y PAPERCLIP_COMPANY_ID en el proceso. El adaptador process no pasa el identificador de la tarea, de modo que el script lista sus asignaciones, como indica el paso 3 del protocolo. La segunda mitad pregunta al modelo, registra el coste y cierra la tarea con un comentario:
out = call("POST", f"{OLLAMA}/api/chat", {
"model": MODEL, "stream": False, "think": False,
"options": {"num_predict": 120, "temperature": 0.2},
"messages": [{"role": "user", "content": issue["title"]}]}, auth=False)
now = datetime.datetime.now(datetime.timezone.utc)
call("POST", f"{API}/api/companies/{CO}/cost-events", {
"agentId": me["id"], "provider": "ollama", "model": MODEL,
"occurredAt": now.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
"inputTokens": out["prompt_eval_count"],
"outputTokens": out["eval_count"], "costCents": 0})
call("PATCH", f"{API}/api/issues/{issue['id']}", {
"status": "done", "comment": out["message"]["content"].strip()})
Copié el script a /paperclip/scribe.py, dentro del volumen, y creé un segundo agente, Scribe, con otra petición a la API:
{
"name": "Scribe", "role": "researcher",
"adapterType": "process", "budgetMonthlyCents": 500,
"adapterConfig": {
"command": "python3", "args": ["/paperclip/scribe.py"],
"cwd": "/paperclip", "timeoutSec": 900
}
}
Cada tarea nueva asignada a Scribe despierta su latido. Tres detalles me costaron ejecuciones fallidas, y conviene que los conozcas:
occurredAtes obligatorio enPOST /cost-events, con formato ISO acabado enZ. El ejemplo de la documentación no lo incluye, y la primera respuesta fue400.- Una ejecución fallida bloquea la tarea. Paperclip la pasa a
blocked, y volver a ponerla entododesde la API no sirvió: el proceso de recuperación la bloqueó otra vez. Con una tarea nueva, funcionó. - Un título idéntico no crea otra tarea. La API devuelve la existente con un
200en lugar de un201.
Qué respondió el agente local y qué cuesta
Scribe tuvo siete ejecuciones, más la cancelada de OpenCode: 4 terminaron con éxito, 3 fallaron y 1 se canceló. De las cuatro que terminaron, dos no encontraron trabajo pendiente y dos resolvieron una tarea. El panel mostró las tareas hechas y bloqueadas con claridad, y al final el gasto del mes fue $0.00, con 55 tokens de entrada y 85 de salida repartidos en dos eventos de coste.
Lo que no salió bien fue el contenido. Pregunté a Scribe cómo protege un presupuesto a una empresa de Paperclip, y contestó que "ensures that every dollar spent is allocated to essential operational needs", que no tiene relación con el tope mensual con parada al 100 %. A la tarea siguiente, "What does a Paperclip adapter do, in two sentences?", respondió que es "a small electronic device that connects to the power supply of an old computer". Un modelo de 0,8B no conoce Paperclip, y Paperclip no se lo explica por ti en un adaptador process.
Esto no es un fallo de Paperclip, sino un recordatorio de lo que orquesta: el orquestador entrega tareas, registra el coste y guarda el comentario, pero no comprueba que la respuesta sea cierta. Para eso necesitas un humano en el bucle o las aprobaciones que Paperclip sí ofrece.
Cuándo compensa usar Paperclip y cuándo no
Compensa si ya tienes tres o más agentes, sobre todo los de código como Claude Code o Codex, y pierdes el hilo de quién hace qué. La instancia guarda tareas, comentarios, costes y actividad en un solo sitio, y el control de presupuesto está integrado. Los adaptadores claude_local y codex_local vienen listos, y el asistente inicial está pensado para ellos.
No compensa para probar un modelo local. El camino directo exige crear los agentes por la API, depurar el adaptador y asumir que las respuestas de un modelo diminuto no se pueden usar tal cual. Para eso, Ollama con un cliente sencillo es más corto. Tampoco lo pondría expuesto a internet sin leer antes su documentación de despliegue: el Compose lo deja en modo authenticated y exposición private, y conviene mantenerlo así.
Preguntas frecuentes
¿Paperclip funciona sin claves de pago?
El servidor sí. La interfaz de incorporación y el formulario de agente nuevo piden una suscripción o clave de Claude, OpenAI u OpenRouter. Con un modelo local solo me funcionó el adaptador process creado por la API.
¿Qué adaptador uso para un modelo local?
opencode_local admite proveedores compatibles con OpenAI y opencode models listó mi modelo de Ollama, pero la ejecución no terminó en mi entorno. process me resolvió una tarea con un script propio. Un modelo con más parámetros que 0,8B daría respuestas más útiles.
¿Cómo se actualiza Paperclip?
Cambia la etiqueta de Git, vuelve a construir con docker compose up --build -d y conserva la carpeta data/docker-paperclip. Lee antes las notas de la versión: la v2026.1005.0 incluye cambios incompatibles.
Conclusión
Paperclip hace bien lo que promete: tareas con responsable único, latidos, costes y un registro de actividad en una instancia que levantas con Docker. La parte débil, si no pagas a un proveedor de modelos, es la entrada. El asistente y el formulario de agente asumen Claude, OpenAI u OpenRouter, y mi modelo local contestó con datos inventados.
El siguiente paso es conectar un agente de verdad. Si tienes una suscripción de Claude o Codex, el asistente te lleva en cuatro pasos, y te recomiendo fijar un presupuesto mensual bajo antes de asignar la primera tarea.
Fuentes: [1] Paperclip[1], [2] Versión v2026.1005.0[2], [3] Conceptos básicos de Paperclip[3], [4] Descripción de los adaptadores de Paperclip[5], [5] Despliegue de Paperclip con Docker[6], [6] Proveedores de OpenCode, con Ollama[7], [7] qwen3.5 en la biblioteca de Ollama[8].
Fuentes
Código fuente
Accede a todo el código fuente de este artículo en GitHub.
Ver en GitHub