Blog Logo

Tengo agentes de IA trabajando 24/7 en un VPS: así monté Multica (y todo lo que se me rompió)

Si quieres un VPS como el que uso en este post (es de HostGator) con descuento, puedes pillarlo con este enlace. Aprovecha las ofertas de Black Friday.

Claude Code, Codex o Cursor programan muy bien. El problema es todo lo de alrededor. Cada uno vive en su terminal, con su contexto, y cuando tienes varias tareas en paralelo el que acaba repartiendo trabajo y copiando contexto de un sitio a otro eres tú. O sea, justo lo que queríamos quitarnos de encima con la IA.

Hace unas semanas encontré Multica en GitHub y le da la vuelta a eso. Es un tablero de tareas al estilo Linear o Jira donde los agentes son miembros del equipo. Les asignas una issue como se la asignarías a un compañero, la cogen, te van comentando si se atascan y te la pasan a revisión.

Lo he montado en un VPS y lo he grabado entero, con errores incluidos. Aquí te dejo lo importante por escrito: cómo funciona, los comandos y, sobre todo, los seis sitios donde tropecé, para que tú no tropieces.

Un equipo de agentes de IA trabajando en un tablero de tareas estilo Jira, con una persona revisando el trabajo y un servidor al fondo


Por qué en un VPS y no en mi portátil

Multica se puede instalar en local, y es lo primero que hice. Duró poco. Me comía memoria y batería, y en cuanto cerraba el portátil para irme a algún sitio, los agentes se desconectaban y el trabajo se quedaba a medias.

Tiene sentido si entiendes cómo funciona por dentro. Multica tiene dos mitades:

  • El servidor: un backend en Go, una base de datos PostgreSQL y una web en Next.js. Ahí viven las issues, los comentarios, los agentes y el historial. Esta parte no ejecuta código, solo coordina.
  • El daemon: un proceso que corre en la máquina donde trabajan los agentes. Al arrancar detecta qué CLIs de IA tienes instalados (Claude Code, Codex, OpenCode… soporta unos 26) y se registra en el servidor como un runtime.

Y ojo con esto: Multica no trae ningún modelo. Usa los CLIs que ya tienes, con tu sesión iniciada. Cambiar de proveedor es cambiar un desplegable.

Cuando asignas una issue, el servidor crea un run y lo deja en cola. Avisa al daemon por WebSocket, el daemon lo reclama, crea un directorio de trabajo aislado (un git worktree del repo, para que dos agentes puedan tocar el mismo proyecto a la vez sin pisarse) y lanza el CLI. Todo lo que hace el agente, cada comando y cada error, vuelve a la issue en tiempo real.

Las dos mitades de Multica: el servidor que coordina (base de datos, backend y web) y el daemon con los agentes, cada uno en su propio worktree

¿Y si el daemon está apagado? El run se queda en la cola esperando. Por eso, con el portátil cerrado, tu equipo de agentes no trabaja. En un VPS está encendido siempre.


El servidor

Uso un VPS de HostGator. Para esto te recomiendo el plan de 4 GB de RAM como mínimo, y de ahí para arriba. El servidor de Multica gasta poco, pero cada agente es un proceso de Claude Code que además instala dependencias, compila y ejecuta cosas, y eso se nota.

Desde el panel añadí una clave SSH para entrar sin contraseña. En tu máquina:

ssh-keygen -t ed25519 -C "tu@email.com"
cat ~/.ssh/id_ed25519.pub     # esta, la pública, es la que pegas en el panel
ssh -i ~/.ssh/id_ed25519 -p PUERTO root@IP_DEL_VPS

Importante: pega la clave pública, nunca la privada.

Tropiezo 1. La primera vez no me dejó entrar. El puerto SSH que te dan no es el 22 de siempre, y hay que indicarlo con -p. El propio panel te dice cuál es. Revísalo antes de pensar que algo está mal.

Claude Code en el servidor

HostGator te da la opción de tener Claude Code preinstalado desde su panel. A mí se me pasó, así que lo instalé a mano:

curl -fsSL https://claude.ai/install.sh | bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc

Tropiezo 2. Después de instalarlo, claude no aparecía. El instalador te avisa de que tienes que añadir ~/.local/bin al PATH, y yo no lo leí (esto me pasa por no leer). Añádelo, sal del servidor, vuelve a entrar y ya sí. Después inicias sesión y listo.

Ojo: esta instalación no me sirvió al final. Lo explico en el tropiezo 6.

Preparar el sistema e instalar Multica

Lo básico: actualizar, instalar un par de herramientas, el cortafuegos dejando pasar solo SSH y web, y Docker.

apt update && apt -y upgrade
apt -y install git gh curl ufw systemd-container

# Deja pasar TU puerto SSH, el que usa realmente el servidor
ufw allow "$(sshd -T | awk '/^port /{print $2}')"/tcp
ufw allow 80/tcp && ufw allow 443/tcp
ufw --force enable

curl -fsSL https://get.docker.com | sh

Cuidado con el cortafuegos. Si el puerto SSH de tu VPS no es el 22 (en HostGator suele no serlo), un ufw allow OpenSSH a pelo te deja fuera de tu propio servidor. Por eso el comando de arriba lee el puerto real.

Y Multica, que se instala con un solo comando:

curl -fsSL https://raw.githubusercontent.com/multica-ai/multica/main/scripts/install.sh | bash -s -- --with-server

Tropiezo 3. Al terminar te sugiere ejecutar multica setup. Yo le hice caso y me pidió autenticación, y no funciona: está pensado para localhost, y en un servidor tú vas a entrar desde fuera, con tu dominio. Hay que pararlo y publicarlo primero.

Dominio y HTTPS

Primero le digo a Multica cuál va a ser su dominio. No abro el .env en pantalla porque tiene secretos dentro, así que cambio solo las variables que necesito con un comando:

cd ~/.multica/server
DOMINIO=multica.tudominio.com
setenv() { grep -q "^$1=" .env && sed -i "s|^$1=.*|$1=$2|" .env || echo "$1=$2" >> .env; }

setenv FRONTEND_ORIGIN https://$DOMINIO
setenv CORS_ALLOWED_ORIGINS https://$DOMINIO
docker compose -f docker-compose.selfhost.yml up -d

Estas variables importan: por defecto el backend solo acepta conexiones WebSocket desde localhost, y si no le dices tu dominio, la web carga pero el tablero no se actualiza en directo.

Delante pongo Caddy como proxy inverso, porque saca el certificado HTTPS solo. Hay más opciones, como Traefik, que es muy típico, pero a mí me gusta Caddy:

apt -y install debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
apt update && apt -y install caddy

cat > /etc/caddy/Caddyfile <<EOF
$DOMINIO {
    @multica_ws path /ws /ws/*
    handle @multica_ws {
        reverse_proxy localhost:8080 {
            flush_interval -1
        }
    }
    reverse_proxy localhost:3000
}
EOF
systemctl reload caddy

El WebSocket (/ws) va directo al backend, en el puerto 8080, y todo lo demás a la web, en el 3000. Con flush_interval -1 los mensajes de los agentes llegan al momento y no a trompicones.

Por último, en tu DNS creas un registro A del subdominio apuntando a la IP del VPS. Yo lo gestiono en Cloudflare. Puede tardar una hora o cinco minutos, el máximo razonable es un día, y si pasa de ahí, algo has hecho mal. A mí me tardó un minuto.

Tropiezo 4. Con el DNS ya propagado, la web seguía sin cargar. Tuve que volver a lanzar systemctl reload caddy. Si no te carga, prueba eso antes de tocar nada más.


Primer login (y en chino)

La primera vez que entré, Multica me salió en chino mandarín. Es un cambio que solo puedes hacer después de entrar: en los ajustes de tu usuario, el idioma, y lo pones en English. Hasta entonces, el traductor del navegador es tu amigo.

Para entrar te pide el email y un código de verificación. Como no he configurado ningún servicio de correo, el código no llega a tu buzón. Lo escribe el backend en sus logs:

docker compose -f docker-compose.selfhost.yml logs backend | grep "Verification code" | tail -1

Un hack tonto, pero funciona. En el asistente de bienvenida te ofrece descargar la app de escritorio. Como lo nuestro es un servidor, elige “Connect via terminal”, o sáltatelo y lo conectas después desde el apartado de agentes, que es lo que hice yo.

Y cuando estés dentro, cierra el registro para que nadie más pueda crearse una cuenta en tu instancia: ALLOW_SIGNUP=false en el .env y reinicias.

Conectar el agente

En Agents → New agent → Connect a machine marcas que esa máquina no puede abrir el navegador y te da los comandos. Necesitas un token, que se crea en los ajustes (API tokens). Los comandos son parecidos a estos, cambiando localhost por tu dominio:

multica config set server_url https://multica.tudominio.com
multica config set app_url https://multica.tudominio.com
multica login --token=TU_TOKEN
multica daemon start
multica daemon autostart enable

El autostart hace que el daemon vuelva a arrancar solo si el servidor se reinicia. Copia siempre los comandos que te da la propia pantalla, que es lo que está al día con tu versión.

Al crear el agente eliges en qué máquina trabaja, qué modelo usa, avatar, descripción e instrucciones, e incluso el nivel de razonamiento. Yo le puse Sonnet 5.5 para no fundirme la suscripción.


El tropiezo importante: root

Creé un proyecto, “YouTube”, con dos tareas: un backend que consuma la API de YouTube y un panel para ver las estadísticas de mi canal. Se las pasé al agente y falló al momento:

Claude Code refuses bypassPermissions under root/sudo privileges.
Run the Multica daemon as a non-root user, or set IS_SANDBOX=1
if running in a genuine container/sandbox

Tropiezo 5 (el que le va a pasar a todo el mundo). Para que los agentes trabajen solos, Multica lanza Claude Code con bypassPermissions, o sea, sin pedir permiso para nada. Si el daemon corre como root, Claude Code se niega, y hace bien.

Un agente trabajando dentro de una caja aislada, separado de los permisos de root y del resto del servidor

El propio error te sugiere poner IS_SANDBOX=1. No lo hagas. Eso es para cuando ya estás dentro de un contenedor aislado de verdad. Aquí el agente tiene en el servidor los mismos permisos que el usuario que lanza el daemon, y si ese usuario es root, le estás dando las llaves de todo a un proceso que no pide permiso para nada.

La solución es un usuario solo para los agentes, sin sudo y fuera del grupo docker:

adduser --disabled-password --gecos "" agente
loginctl enable-linger agente      # para que su daemon arranque con el servidor
machinectl shell agente@           # entrar como ese usuario

Tropiezo 6. Siendo agente, claude no existía. Claude Code se instala por usuario, y el que instalé al principio era el de root. Toca repetir la instalación (curl + PATH + inicio de sesión) con el usuario agente. Siento no haberlo dicho desde el principio, pero así es como se aprende.

Con el daemon pasa lo mismo. Yo lo había conectado como root, así que primero lo paro y cierro su sesión:

# como root
multica daemon stop
multica daemon autostart disable
multica auth logout

Después repito los comandos de conexión siendo agente, con un token nuevo. En la web aparecen dos runtimes: el de root, ya apagado, y el nuevo, online. Creé el agente Dev sobre el nuevo y ahora sí, se puso a trabajar.


Cómo es trabajar así

A partir de ahí es como usar Jira, pero con agentes. Asignas la issue al agente y ves cómo pasa a In Progress. En la propia issue ves cada comando que ejecuta, y cuando termina te deja un comentario con lo que ha hecho y la pasa a revisión.

En mi caso:

  • El backend lo hizo en unos minutos y me dejó un client.py listo para usar. Lo puedes revisar en el código y, si está bien, moverlo tú a Done.
  • El panel de estadísticas me lo hizo en HTML y CSS, sencillito, porque no le pedí nada más complicado. Se quedó en revisión, y ahí puedes dejarle un comentario si quieres que lo cambie.

Una cosa a tener clara: la issue no pasa sola a Done, eso lo decides tú. Y cuando quieres que el agente trabaje, se la asignas, le hablas por el chat o lo lanza un autopilot. No des por hecho que arrastrar una tarjeta a otra columna lo pone a currar.

Los Autopilots permiten programar tareas que se lanzan solas: noticias diarias, revisión de PRs o auditoría de dependencias, por ejemplo. Y lo potente de verdad viene cuando conectas más agentes (Codex, OpenCode…) y montas flujos en los que uno programa y otro revisa, y si el revisor no está de acuerdo, se lo devuelve con un comentario. Tú solo entras al final a decidir si te gusta.

Para mí, lo mejor es tener por fin a la vista qué tarea va por dónde, que es justo lo que siempre se me escapa.


Lo que conviene saber antes de lanzarte

  • No es open source puro. El código está en GitHub y lo puedes montar gratis, pero la licencia es Apache 2.0 con condiciones añadidas para servicios alojados, para incrustarlo en productos comerciales y sobre marca. Para usarlo tú o tu equipo, no hay problema, pero léete el LICENSE si quieres hacer negocio con él.
  • Cambia muy rápido. El propio proyecto avisa de que main se mueve a menudo. Si algo te funciona, fija la versión con MULTICA_IMAGE_TAG en el .env y actualiza cuando te venga bien.
  • Vigila el consumo. Cada tarea gasta tokens de tu suscripción o de tu API. Por eso yo uso Sonnet para estas cosas.
  • Escribe bien las issues. Con una tarea concreta, el agente acierta. Con una vaga, se inventa lo que falta. Si te interesa afinar eso, tienes el post sobre AGENTS.md.
  • Seguridad. Un servidor con agentes que ejecutan comandos sin pedir permiso no es un juguete. Usuario sin sudo, cortafuegos y registro cerrado son el mínimo. Si quieres profundizar, echa un ojo a seguridad en APIs y agentes y a lo que conté de mudar mis agentes a un servidor.

Para montarlo tú

  • El vídeo completo, con cada paso y cada error en directo, está arriba.
  • El VPS de HostGator con descuento de Black Friday: aquí tienes el enlace. Yo uso el de 4 GB de RAM, y de ahí para arriba es lo que te recomiendo.
  • Multica en GitHub: github.com/multica-ai/multica

Ahora cuéntame tú: ¿qué le pondrías a tu equipo de agentes? ¿Qué proyectos tienes en mente? Me encanta leeros en los comentarios del vídeo, así que dispara. Si te ha servido, suscríbete al canal, que me hace muy feliz, y nos vemos en el próximo.


¿Qué te ha parecido?

Déjame tu opinión, pregunta o sugerencia. Los comentarios se sincronizan con GitHub Discussions .

← Volver al blog