Flujos y ficheros
Una llamada a una herramienta MCP es una petición y una respuesta. Buena parte de Arcane no funciona así: los logs y las estadísticas llegan por WebSocket, el canal en directo es Server-Sent Events, las descargas de imágenes emiten progreso y las copias de seguridad son ficheros binarios. Esta página explica cómo cada una de esas cosas se convierte en algo que una llamada a una herramienta puede devolver.
Los flujos en directo se convierten en acciones acotadas
Sección titulada «Los flujos en directo se convierten en acciones acotadas»Los flujos en directo son acciones que se conectan, escuchan durante una ventana acotada y devuelven lo que ha llegado. Toda ventana tiene un máximo de 120 segundos, y la salida recogida, el de ARCANE_MCP_MAX_DOWNLOAD_BYTES.
container.logs, project.logs y swarm_service.logs leen el flujo de logs WebSocket correspondiente.
| Parámetro | Predeterminado | Significado |
|---|---|---|
containerId / projectId / serviceId | — | Qué leer (obligatorio) |
tail | 100 | Líneas desde el final del log, o all |
since | — | Marca de tiempo RFC 3339, marca de tiempo Unix o duración relativa (10m) |
timestamps | false | Antepone a cada línea su marca de tiempo |
follow | false | Sigue escuchando líneas nuevas durante seconds tras las existentes |
seconds | 5 | Tiempo máximo de escucha |
maxLines | 1000 | Se detiene tras este número de líneas |
Por defecto la acción devuelve el final actual del log y se detiene. Con follow: true espera además líneas nuevas, algo útil para «vigila los logs mientras lo reinicio». Para el log completo como fichero, usa container.logs_download.
diagnostics.server_logs devuelve las entradas recientes del log del propio servidor Arcane y escucha las nuevas durante seconds (2 por defecto) hasta maxLines (500 por defecto).
Muestras de estadísticas y diagnóstico
Sección titulada «Muestras de estadísticas y diagnóstico»container.stats, container.stats_all, system.stats, diagnostics.snapshot y diagnostics.actors_stream recogen samples mensajes (1 por defecto, 60 como máximo) y esperan como mucho seconds (10 por defecto). Una muestra responde a «¿cuánta memoria está usando?»; varias muestran una tendencia.
El canal en directo
Sección titulada «El canal en directo»stream.snapshot se suscribe al canal SSE multiplexado de Arcane (GET /api/stream) y devuelve los eventos recibidos.
| Parámetro | Predeterminado | Significado |
|---|---|---|
channels | los cinco | Separados por comas: environments, dashboard, activities, events, version |
limit | — | Máximo de actividades en cada instantánea del canal de actividades |
seconds | 5 | Tiempo de escucha |
maxEvents | 100 | Se detiene tras este número de eventos |
Para el historial, en lugar de lo que está pasando ahora, usa event.list o activity.list.
Ejecutar un comando en un contenedor
Sección titulada «Ejecutar un comando en un contenedor»container.exec ejecuta un comando a través del terminal de contenedores de Arcane y devuelve su salida y su código de salida:
{ "action": "container.exec", "params": { "containerId": "db", "command": "df -h /var/lib/postgresql" }}| Parámetro | Predeterminado | Significado |
|---|---|---|
containerId | — | ID o nombre del contenedor (obligatorio) |
command | — | Línea de comandos de shell (obligatoria) |
shell | /bin/sh | Shell que la ejecuta |
seconds | 30 | Tiempo máximo, como mucho 120 |
El terminal es un TTY interactivo, así que el servidor primero lo silencia (prompts vacíos, sin edición de línea, stty -echo) y después ejecuta el comando en una subshell delimitada por marcadores que el eco de la línea escrita no puede contener. El resultado es {output, exitCode, completed}; si se agota el tiempo, completed es false y una nota avisa de que la salida puede estar incompleta. Los comandos que esperan entrada se detienen al agotarse el tiempo. container.exec es una acción de escritura: el modo de solo lectura la retira y el modo seguro muestra su vista previa.
Comandos de diagnóstico
Sección titulada «Comandos de diagnóstico»diagnostics.run_command envía un comando por el WebSocket de diagnóstico: leakScan (búsqueda de fugas de goroutines), dump (un perfil de ejecución con nombre, como texto) o profile (captura un perfil con nombre durante seconds y lo devuelve en base64). Las rutas de pprof son acciones aparte (diagnostics.pprof_*).
Los flujos de progreso se siguen hasta el final
Sección titulada «Los flujos de progreso se siguen hasta el final»Algunas rutas de Arcane responden con un flujo de líneas JSON de progreso en lugar de un único documento: image.pull, image.build, project.up, project.pull, project.build y project.redeploy. La acción lee el flujo hasta que Arcane lo cierra y devuelve un resumen: el estado final, el ID de la actividad, los errores notificados por el camino y las últimas líneas de progreso. El modelo recibe «nginx:1.27 descargada, terminado» en lugar de miles de actualizaciones de capas.
Estas peticiones no las corta ARCANE_MCP_TIMEOUT, porque una descarga grande puede tardar minutos con toda legitimidad.
Notificaciones de progreso
Sección titulada «Notificaciones de progreso»Cuando un cliente envía una llamada a una herramienta con un token de progreso (_meta.progressToken de MCP), las operaciones largas anteriores también informan de su avance mientras se ejecutan, mediante notifications/progress: los flujos de progreso por línea («abc123 Downloading: 45%» cuando Docker da el tamaño de la capa), las ventanas de logs, estadísticas y canal en directo por mensaje recibido, y container.exec por fragmento de salida. Las notificaciones se limitan a dos por segundo como máximo, y una final cierra cada llamada («completed (121 event(s))», «collected 12 log line(s): stream closed by Arcane»). Funciona igual en las tres superficies de herramientas. Una llamada sin token no recibe notificaciones, y el resultado es el mismo en ambos casos.
Descargas
Sección titulada «Descargas»Las rutas que devuelven un fichero —descargas de logs, ficheros Compose y de plantillas, paquetes y certificados mTLS, archivos de copia de seguridad, perfiles de pprof— se devuelven según su contenido:
| Contenido | Se devuelve como |
|---|---|
Texto (text/*, JSON, YAML, XML, PEM, o un cuerpo sin tipo y sin bytes NUL) | El texto en content, con filename, contentType, bytes y truncated |
| Binario, dentro del límite | Los mismos metadatos más un recurso incrustado MCP (arcane://download/<fichero>) con los bytes en base64 |
| Binario, por encima del límite | Solo metadatos, con una nota para subir ARCANE_MCP_MAX_DOWNLOAD_BYTES |
El texto que supera el límite se trunca en ARCANE_MCP_MAX_DOWNLOAD_BYTES (4 MiB por defecto) y lo indica. Sube el límite para copias de seguridad grandes, teniendo en cuenta que todo lo que se devuelve acaba en el contexto del modelo.
Subidas
Sección titulada «Subidas»Campos de fichero multipart
Sección titulada «Campos de fichero multipart»Cuando una ruta de Arcane recibe multipart/form-data, sus campos de fichero se convierten en objetos de fichero en el esquema de la acción:
{ "filename": "compose.yaml", "content": "services:\n web:\n image: nginx:1.27\n"}Pasa el contenido como texto UTF-8 en content o en base64 en contentBase64, exactamente uno de los dos. Los campos de fichero de tipo lista (como files de project.create) reciben una lista de esos objetos. Los demás campos del formulario son parámetros normales. Los caracteres de control y el UTF-8 no válido de filename se envían codificados con porcentajes (un retroceso pasa a ser %08), porque una cabecera multipart no puede llevarlos; Arcane recibe entonces el nombre codificado.
Cuerpos en bruto
Sección titulada «Cuerpos en bruto»Las rutas cuyo cuerpo es application/octet-stream aceptan el mismo par en el nivel superior: content para texto y contentBase64 para binario.
Sesiones de subida por fragmentos
Sección titulada «Sesiones de subida por fragmentos»Arcane mueve los ficheros grandes (archivos de imagen, copias de seguridad de volúmenes) mediante sesiones de subida por fragmentos, y el catálogo las expone como el dominio upload:
upload.session_createconkind,filenameysize→ unuploadId;upload.chunk_putpara cada fragmento (index, máscontentocontentBase64); reenviar un fragmento es idempotente;- la acción que lo consume, con el
uploadId: por ejemploimage.upload(carga un archivo dedocker save) ovolume_backup.upload(restaura un volumen).
upload.session_get informa del progreso y upload.session_delete abandona una sesión. A través de un asistente esto conviene para ficheros de tamaño moderado: cada fragmento pasa por el contexto del modelo en base64.