Despliegue HTTP
Por stdio, cada cliente MCP arranca su propio arcane-mcp y nada escucha en la red. Ejecútalo por HTTP cuando el cliente no pueda arrancar un proceso local (conectores remotos, clientes web), cuando varias personas deban compartir un servidor o cuando el servidor deba vivir junto a Arcane y no en cada portátil. Todos los ajustes que se nombran aquí se describen en Configuración; el modelo de amenazas está en Seguridad del despliegue, y los errores con los que te puedes encontrar, en Solución de problemas.
Antes de exponerlo
Sección titulada «Antes de exponerlo»- Autentica. Define
ARCANE_MCP_HTTP_TOKENo usaARCANE_MCP_HTTP_AUTH=apikey. Sin ninguno de los dos, cualquiera que llegue al puerto usa el servidor. - Cifra. El token y las claves de Arcane viajan en las cabeceras. Termina TLS en un proxy inverso o dale al servidor un certificado con
ARCANE_MCP_HTTP_TLS_CERTyARCANE_MCP_HTTP_TLS_KEY(TLS en el propio servidor). HTTP sin cifrar es para loopback, un socket unix o una red que solo compartan el proxy y el servidor: en cualquier otra dirección TCP el servidor avisa al arrancar,ARCANE_MCP_HTTP_ALLOW_PLAINTEXT=truedeclara que ese tramo se cifra delante de él yARCANE_MCP_HTTP_ALLOW_PLAINTEXT=falsehace que se niegue a arrancar (consulta HTTP sin cifrar y el modo endurecido). - Nombra los hosts. Define
ARCANE_MCP_HTTP_ALLOWED_HOSTScon los nombres que usan los clientes. - Háblale del proxy. Define
ARCANE_MCP_HTTP_TRUSTED_PROXIESyARCANE_MCP_HTTP_TRUSTED_PROXY_HEADER, o todos los clientes compartirán el cupo de autenticaciones fallidas del proxy. - Decide quién actúa en Arcane. En un servidor compartido, deja sin definir
ARCANE_API_KEY,ARCANE_USERNAMEyARCANE_PASSWORD, para que cada usuario traiga su propia clave y actúe con sus propios permisos.
Token o clave de API
Sección titulada «Token o clave de API»token (predeterminado) | apikey | |
|---|---|---|
| El cliente envía | Authorization: Bearer <ARCANE_MCP_HTTP_TOKEN> y su clave de Arcane en X-Arcane-API-Key | Authorization: Bearer <su clave de API de Arcane> |
| Va bien con | Clientes que pueden definir cabeceras propias (Claude Code, VS Code, Cursor y otros; consulta Configuración de clientes) | Clientes que solo pueden definir Authorization: conectores remotos, mcp-remote |
Credencial del servidor (ARCANE_API_KEY, inicio de sesión) | Permitida: un cliente sin X-Arcane-API-Key, o con la propia clave del servidor en ella, actúa con esa clave y con el inicio de sesión. Un cliente con otra clave actúa solo con ella y nunca recibe el inicio de sesión | Rechazada al arrancar |
| Lo que cuesta a Arcane cada petición | Nada más | Un GET /api/auth/me por clave cada ARCANE_MCP_HTTP_AUTH_CACHE_TTL (5 minutos) |
Los dos modos cuentan las autenticaciones fallidas por dirección de cliente y pueden limitar el ritmo de cada clave (ARCANE_MCP_HTTP_RATE_LIMIT_RPS). Consulta Autenticación HTTP.
Junto a Arcane con Docker Compose
Sección titulada «Junto a Arcane con Docker Compose»Añade un servicio al proyecto de Compose que ejecuta Arcane: así el servidor llega a Arcane por el nombre de su servicio en la red del proyecto y no hace falta publicar el puerto de Arcane para él:
services: arcane: image: ghcr.io/getarcaneapp/manager:v2.17.2 # ... tu servicio de Arcane tal como está hoy
arcane-mcp: image: ghcr.io/jmrplens/arcane-mcp:latest # fija una versión en producción restart: unless-stopped environment: ARCANE_URL: http://arcane:3552 ARCANE_MCP_HTTP_ADDR: ":8080" ARCANE_MCP_HTTP_ALLOW_PLAINTEXT: "true" ARCANE_MCP_HTTP_TOKEN: ${ARCANE_MCP_HTTP_TOKEN:?set it in .env} ARCANE_MCP_HTTP_ALLOWED_HOSTS: localhost,127.0.0.1 ports: - "127.0.0.1:8080:8080" depends_on: - arcanePon el token en el .env del proyecto (ARCANE_MCP_HTTP_TOKEN= seguido de la salida de openssl rand -hex 32). Los clientes de la misma máquina se conectan a http://127.0.0.1:8080/mcp con Authorization: Bearer <token> y su propia clave de Arcane en X-Arcane-API-Key.
ARCANE_URLusa el nombre del servicio y el puerto de Arcane dentro de la red (3552por defecto); no hace falta TLS en una red que solo comparten los contenedores del proyecto.- No hay
ARCANE_API_KEY, así que un cliente que no envía clave se rechaza con400. Añade una solo si todos los clientes de este servidor deben actuar como el mismo usuario de Arcane. ARCANE_MCP_HTTP_ALLOW_PLAINTEXT: "true": dentro de su contenedor el servidor escucha en todas las interfaces (:8080), así que sin él avisa al arrancar de que sirve HTTP sin cifrar a la red. Aquí el puerto se publica solo en el loopback del anfitrión y el otro tramo es la red del propio proyecto, así que el valor lo declara. Los ejemplos detrás de un proxy, más abajo, lo definen por la misma razón: el proxy termina TLS.- El puerto se publica solo en loopback. Expón el servidor a otros mediante un proxy inverso (más abajo) o con TLS en el propio servidor, no publicando HTTP sin cifrar en
0.0.0.0:8080. - La imagen tiene
HEALTHCHECK(arcane-mcp --probe), así quedocker compose psmuestra el servicio comohealthyen cuanto responde/healthz; no hace falta una entradahealthcheck:. Consulta Estado, disponibilidad y parada. - Hasta que se publique la primera versión, construye la imagen desde el repositorio (
docker build -t arcane-mcp .) y usa ese nombre.
Detrás de un proxy inverso
Sección titulada «Detrás de un proxy inverso»El proxy termina TLS y reenvía /mcp al servidor. Lo que todo proxy tiene que hacer bien:
| Requisito | Por qué |
|---|---|
Pasar el Host del cliente, e incluirlo en ARCANE_MCP_HTTP_ALLOWED_HOSTS | Con la lista definida, /mcp solo responde a los nombres que contiene (403 en otro caso). Traefik y Caddy pasan el Host; nginx necesita proxy_set_header Host $host |
Sin búfer ni compresión en /mcp | Las respuestas y las notificaciones del servidor viajan como flujo de eventos (text/event-stream). Traefik y Caddy lo reenvían según llega; nginx necesita proxy_buffering off. La compresión retiene los eventos |
Plazos de respuesta de al menos ARCANE_MCP_ACTION_TIMEOUT (30 minutos) | Una llamada puede durar eso, y el servidor no envía pings de mantenimiento, así que una llamada callada o el flujo de eventos inactivo de una sesión pasan minutos sin enviar un byte. nginx lo corta a los 60 segundos por defecto |
Cuerpos de hasta ARCANE_MCP_HTTP_MAX_BODY_BYTES (16 MiB) | Un fragmento de subida ocupa eso codificado en base64; el límite por defecto de nginx es 1 MiB |
Pasar Authorization, X-Arcane-API-Key, X-Arcane-URL, Mcp-Session-Id y MCP-Protocol-Version | Los tres proxies de abajo pasan las cabeceras de la petición sin tocarlas |
| Identificar al cliente real | Pon en ARCANE_MCP_HTTP_TRUSTED_PROXIES la dirección del proxy tal como la ve el servidor (unix para un proxy en un socket unix) y en ARCANE_MCP_HTTP_TRUSTED_PROXY_HEADER la cabecera que rellena. La cabecera solo se cree si viene de un proxy listado, y se lee desde la derecha omitiendo los proxies de confianza |
| No añadir cabeceras CORS | El servidor responde él mismo a las comprobaciones previas del navegador para los orígenes de ARCANE_MCP_HTTP_TRUSTED_ORIGINS; con dos cabeceras Access-Control-Allow-Origin el navegador rechaza la respuesta |
Encaminar solo /mcp | /healthz y /readyz no piden credencial, y /readyz nombra las instancias de Arcane; resérvalos para tus propias sondas |
Dale al proxy una dirección fija cuando comparta una red de Docker con el servidor, para que ARCANE_MCP_HTTP_TRUSTED_PROXIES lo nombre a él y a nada más: con un rango, cualquier otro contenedor de esa red podría escribir la cabecera y elegir a qué dirección se cargan sus fallos.
Traefik
Sección titulada «Traefik»Con Traefik en el mismo proyecto de Compose, en una red donde tenga una dirección fija:
services: arcane: image: ghcr.io/getarcaneapp/manager:v2.17.2 # ... tu servicio de Arcane tal como está hoy
traefik: image: traefik:v3.6 command: - --providers.docker=true - --providers.docker.exposedbydefault=false - --entrypoints.websecure.address=:443 - --certificatesresolvers.letsencrypt.acme.tlschallenge=true - --certificatesresolvers.letsencrypt.acme.email=admin@example.com - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json ports: - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - letsencrypt:/letsencrypt networks: edge: ipv4_address: 172.30.0.2
arcane-mcp: image: ghcr.io/jmrplens/arcane-mcp:latest restart: unless-stopped environment: ARCANE_URL: http://arcane:3552 ARCANE_MCP_HTTP_ADDR: ":8080" ARCANE_MCP_HTTP_ALLOW_PLAINTEXT: "true" ARCANE_MCP_HTTP_AUTH: apikey ARCANE_MCP_HTTP_ALLOWED_HOSTS: mcp.example.com ARCANE_MCP_HTTP_TRUSTED_PROXIES: 172.30.0.2 ARCANE_MCP_HTTP_TRUSTED_PROXY_HEADER: X-Forwarded-For networks: [edge, default] labels: - traefik.enable=true - traefik.docker.network=edge - traefik.http.routers.arcane-mcp.rule=Host(`mcp.example.com`) && Path(`/mcp`) - traefik.http.routers.arcane-mcp.entrypoints=websecure - traefik.http.routers.arcane-mcp.tls.certresolver=letsencrypt - traefik.http.services.arcane-mcp.loadbalancer.server.port=8080
networks: edge: name: edge ipam: config: - subnet: 172.30.0.0/24 ip_range: 172.30.0.128/25 # las direcciones dinámicas no tocan la .2
volumes: letsencrypt:Este ejemplo usa el modo apikey: cada usuario se conecta a https://mcp.example.com/mcp con su propia clave de API de Arcane como token Bearer, y no hay ningún secreto compartido que repartir.
name: edgemantiene el nombre de la red tal como está escrito; sin él, Compose le antepone el nombre del proyecto ytraefik.docker.network=edgeno coincide con nada (Traefik responde entonces504).ip_rangeaparta de la dirección de Traefik las que Docker reparte a otros contenedores; si no, un contenedor que arrancara antes podría quedársela.- Traefik sustituye el
X-Forwarded-Forque envíe el cliente por la dirección que ha visto, así que el servidor carga las autenticaciones fallidas al cliente real. - Traefik 3.5 (comprobado con la 3.5.6) no puede leer Docker Engine 29 (
client version 1.24 is too old) y responde404a todas las rutas; la 3.6 sí puede.
Con Caddy en el mismo proyecto de Compose, también con una dirección fija:
services: arcane: image: ghcr.io/getarcaneapp/manager:v2.17.2 # ... tu servicio de Arcane tal como está hoy
caddy: image: caddy:2 restart: unless-stopped ports: - "80:80" - "443:443" volumes: - ./Caddyfile:/etc/caddy/Caddyfile:ro - caddy_data:/data networks: default: ipv4_address: 172.31.0.2
arcane-mcp: image: ghcr.io/jmrplens/arcane-mcp:latest restart: unless-stopped environment: ARCANE_URL: http://arcane:3552 ARCANE_MCP_HTTP_ADDR: ":8080" ARCANE_MCP_HTTP_ALLOW_PLAINTEXT: "true" ARCANE_MCP_HTTP_TOKEN: ${ARCANE_MCP_HTTP_TOKEN:?set it in .env} ARCANE_MCP_HTTP_ALLOWED_HOSTS: mcp.example.com ARCANE_MCP_HTTP_TRUSTED_PROXIES: 172.31.0.2 ARCANE_MCP_HTTP_TRUSTED_PROXY_HEADER: X-Forwarded-For
networks: default: ipam: config: - subnet: 172.31.0.0/24 ip_range: 172.31.0.128/25 # las direcciones dinámicas no tocan la .2
volumes: caddy_data:y el Caddyfile a su lado:
mcp.example.com { handle /mcp { reverse_proxy arcane-mcp:8080 } handle { respond 404 }}Caddy obtiene el certificado por su cuenta, reenvía los flujos de eventos según llegan y no tiene plazo de respuesta propio. No añadas encode a este sitio. Este ejemplo mantiene el modo token: los clientes envían el token y su propia clave de Arcane.
nginx con un socket unix
Sección titulada «nginx con un socket unix»Cuando nginx se ejecuta en el host, el servidor puede escuchar en un socket unix en lugar de un puerto: en el host solo llegan a él los procesos que dejen pasar los permisos del socket, y no queda ningún puerto abierto. Ejecuta el binario como servicio, con un usuario de sistema propio:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin arcane-mcpDespués, con systemd:
[Unit]Description=arcane-mcp (MCP server for Arcane)After=network-online.targetWants=network-online.target
[Service]ExecStart=/usr/local/bin/arcane-mcpEnvironmentFile=/etc/arcane-mcp/arcane-mcp.envUser=arcane-mcpGroup=www-dataRuntimeDirectory=arcane-mcpRuntimeDirectoryMode=0750Restart=on-failureNoNewPrivileges=yes
[Install]WantedBy=multi-user.target# /etc/arcane-mcp/arcane-mcp.env (modo 0600: puede contener un token)ARCANE_URL=https://arcane.example.comARCANE_MCP_HTTP_ADDR=/run/arcane-mcp/mcp.sockARCANE_MCP_HTTP_AUTH=apikeyARCANE_MCP_HTTP_ALLOWED_HOSTS=mcp.example.comARCANE_MCP_HTTP_TRUSTED_PROXIES=unixARCANE_MCP_HTTP_TRUSTED_PROXY_HEADER=X-Real-IPGroup= es el grupo con el que se ejecuta nginx (www-data en Debian y Ubuntu). El socket se crea con ARCANE_MCP_HTTP_SOCKET_MODE (0660) y pertenece al usuario del servicio y a ese grupo, así que nginx puede conectarse y los demás usuarios no; se borra cuando el servicio se detiene. Después, el sitio:
upstream mcp_backend { server unix:/run/arcane-mcp/mcp.sock;}
server { listen 443 ssl; http2 on; server_name mcp.example.com;
ssl_certificate /etc/letsencrypt/live/mcp.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mcp.example.com/privkey.pem;
location = /mcp { proxy_pass http://mcp_backend; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Connection "";
# Las respuestas son flujos de eventos: reenvíalas según llegan. proxy_buffering off; gzip off; # Una llamada puede pasar ARCANE_MCP_ACTION_TIMEOUT (30m) sin enviar un byte. proxy_read_timeout 35m; proxy_send_timeout 35m; # El servidor acepta cuerpos de hasta ARCANE_MCP_HTTP_MAX_BODY_BYTES (16 MiB). client_max_body_size 16m; }
location / { return 404; }}Una conexión por socket no tiene dirección de cliente. ARCANE_MCP_HTTP_TRUSTED_PROXIES=unix le dice al servidor que se crea el X-Real-IP que nginx rellena con la dirección que ha visto; sin él, todos los clientes comparten un único cupo de fallos de autenticación con el nombre unix.
La escucha y los proxies de confianza deben casar, o todos los clientes compartirían en silencio un único cupo; el servidor se niega a arrancar con las dos combinaciones que lo provocarían:
ARCANE_MCP_HTTP_ADDR | ARCANE_MCP_HTTP_TRUSTED_PROXIES | Resultado |
|---|---|---|
| socket unix | unix (con o sin direcciones) | Arranca; la cabecera del proxy local nombra a cada cliente |
| socket unix | sin definir | Arranca; todos los clientes comparten el cupo unix |
| socket unix | direcciones, sin unix | Rechazado al arrancar: quien llega por el socket no tiene dirección, así que la cabecera nunca se creería |
| dirección TCP | direcciones | Arranca; la cabecera se cree si viene de esas direcciones |
| dirección TCP | unix entre las entradas | Rechazado al arrancar: unix no se fía de nadie en TCP |
Con Caddy en el host funciona igual (reverse_proxy unix//run/arcane-mcp/mcp.sock y ARCANE_MCP_HTTP_TRUSTED_PROXY_HEADER=X-Forwarded-For). En contenedores, el socket va en un volumen que montan los dos; la imagen se ejecuta con el usuario y el grupo 65532, así que dale al servidor un grupo que también tenga el proxy (user: "65532:<id del grupo del proxy>") o un ARCANE_MCP_HTTP_SOCKET_MODE más amplio.
TLS en el propio servidor
Sección titulada «TLS en el propio servidor»Sin proxy, el servidor puede hablar HTTPS él mismo:
services: arcane: image: ghcr.io/getarcaneapp/manager:v2.17.2 # ... tu servicio de Arcane tal como está hoy
arcane-mcp: image: ghcr.io/jmrplens/arcane-mcp:latest restart: unless-stopped environment: ARCANE_URL: http://arcane:3552 ARCANE_MCP_HTTP_ADDR: ":8443" ARCANE_MCP_HTTP_AUTH: apikey ARCANE_MCP_HTTP_TLS_CERT: /certs/fullchain.pem ARCANE_MCP_HTTP_TLS_KEY: /certs/privkey.pem ARCANE_MCP_HTTP_ALLOWED_HOSTS: mcp.example.com volumes: - /etc/arcane-mcp/certs:/certs:ro # un directorio, para que se vean los ficheros renovados ports: - "8443:8443"Los clientes se conectan a https://mcp.example.com:8443/mcp.
- TLS 1.2 o posterior, con el certificado PEM (la cadena completa) y la clave que nombran los dos ajustes. Un par que falta, que no se puede leer o que no casa detiene el servidor al arrancar.
- Renovaciones sin reiniciar. Los ficheros se vuelven a mirar como mucho una vez por segundo, según llegan conexiones; un par renovado se sirve desde el siguiente handshake y queda en el log (
reloaded the TLS certificate). Un par que no se puede cargar (a medio escribir, clave y certificado de renovaciones distintas) mantiene el certificado anterior y se registra una vez. - Monta un directorio, no los dos ficheros. La mayoría de las herramientas de renovación sustituyen un fichero renombrando otro nuevo encima, y un fichero montado con bind sigue mostrando el antiguo.
- La imagen se ejecuta con el usuario
65532, así que la clave tiene que poder leerla ese usuario. certbot escribe claves que solo lee root: copia el par al directorio montado desde un hook de despliegue (--deploy-hook) y dáselo a ese usuario. - Sin proxy, sin proxies de confianza. A cada cliente se le cargan sus propios fallos. Los puertos publicados por Docker conservan la dirección del cliente en las conexiones que llegan desde otras máquinas.
- Los handshakes fallidos se limitan en el log: los escáneres de puertos, el HTTP sin cifrar enviado al puerto HTTPS y los clientes que rechazan el certificado dejan un aviso por minuto con el número de los omitidos, y cada uno en el nivel
debug.
TLS no cambia nada de la autenticación: un servidor sin token sigue avisando de que cualquiera que llegue a él puede usarlo.
HTTP sin cifrar y el modo endurecido
Sección titulada «HTTP sin cifrar y el modo endurecido»Al arrancar, el servidor mira ARCANE_MCP_HTTP_ADDR. Una dirección TCP a la que llegan otras máquinas (un comodín como :8080, 0.0.0.0:8080 o [::]:8080, una dirección enrutable o un nombre que resuelve a algo que no es loopback) servida sin TLS en el propio servidor lleva en claro cada token, cada clave de Arcane y cada respuesta, sea cual sea el modo de autenticación. Lo que ocurre entonces lo decide ARCANE_MCP_HTTP_ALLOW_PLAINTEXT (o --http-allow-plaintext, que gana a la variable):
| Valor | Al arrancar |
|---|---|
| sin definir | Se sirve, con un aviso que nombra las salidas: the HTTP listener serves plain HTTP on an address other machines can reach, … |
true | Se sirve, con una línea en INFO: declaras que algo delante cifra ese tramo (un proxy que termina TLS y llega al servidor por una red privada o un puente de contenedores) |
false | Se rechaza antes de abrir el puerto, con estado de salida 1: serve HTTP: ARCANE_MCP_HTTP_ALLOW_PLAINTEXT=false (--http-allow-plaintext=false) refuses a listener that serves plain HTTP … |
TLS en el propio servidor, una dirección de loopback (o un nombre que solo resuelve a loopback) y un socket unix no registran nada y arrancan con cualquier valor, así que el modo endurecido sirve para un servidor que nunca debe servir HTTP sin cifrar a la red por error: dale un certificado, escucha en 127.0.0.1 para un proxy de la misma máquina o usa un socket. Un contenedor no puede usar loopback para un proxy de otro contenedor (dentro de su propio espacio de red, 127.0.0.1 es el propio contenedor), así que en el modo endurecido un servidor en contenedor necesita TLS en el propio servidor o un socket en un volumen compartido.
Varias instancias de Arcane
Sección titulada «Varias instancias de Arcane»Un servidor puede atender a varios gestores de Arcane:
environment: ARCANE_URL: home=http://arcane:3552,lab=https://arcane.lab.example.com ARCANE_MCP_HTTP_AUTH: apikeyCada petición nombra su instancia en X-Arcane-URL (home o lab); una petición sin ella se rechaza con 400, y un nombre no listado, con 403. Las claves pertenecen a un único Arcane, así que en modo token ARCANE_API_KEY, si se define, es una lista nombre=clave, y un inicio de sesión (ARCANE_USERNAME, ARCANE_PASSWORD) detiene el servidor, porque solo serviría a una instancia. Quien trabaje con las dos configura dos entradas de cliente con cabeceras X-Arcane-URL distintas. /readyz comprueba todas las instancias y responde degraded mientras alguna está caída. Consulta Varias instancias.
Con estado o sin estado
Sección titulada «Con estado o sin estado»Quédate con el transporte con estado, el predeterminado, salvo que tengas un motivo para cambiarlo:
- Con estado (predeterminado): sesiones con
Mcp-Session-Id, ligadas a la clave que las abrió; las llamadas destructivas pueden preguntar al usuario mediante elicitación en todas las revisiones del protocolo. A los clientes que hablan la revisión 2026-07-28 se les indica que bajen a la 2025-11-25, y siguen funcionando. - Sin estado (
ARCANE_MCP_HTTP_STATELESS=on): sin sesiones, cada POST va por su cuenta, así que cualquier réplica detrás de un balanceador puede responder cualquier petición. Los clientes con revisiones anteriores a la 2026-07-28 pierden la elicitación y reciben en su lugar el rechazo deconfirm: true.
Con el transporte con estado y más de una réplica, el balanceador tiene que enviar todas las peticiones de una sesión a la réplica que la abrió; una réplica que no conoce la sesión responde 404 y el cliente abre una nueva. Consulta HTTP sin estado.
Estado, disponibilidad y parada
Sección titulada «Estado, disponibilidad y parada»| Ruta | Para qué sirve | Responde |
|---|---|---|
/healthz | Vida: reinicia el contenedor cuando falla | 200 ok mientras el proceso atiende, sea cual sea el estado de Arcane. Con ?format=json: estado, draining, versión, commit, fecha de compilación y configDigest |
/readyz | Disponibilidad: saca el servidor de un balanceador cuando falla | 200 ready cuando Arcane responde a GET /api/health; 503 not ready: … cuando no responde, durante el drenaje y mientras el servidor se detiene. Con varias instancias, 200 degraded mientras respondan algunas, seguido de una línea nombre: ok o nombre: <lo que falló> por instancia. Con ?format=json: el mismo código de estado, con si la versión de Arcane coincide con la del catálogo (abajo) |
Ninguna de las dos pide el token ni toca /mcp, y la comprobación de disponibilidad se guarda 5 segundos, así que las sondas no pueden saturar Arcane. /readyz nombra las instancias a cualquiera que llegue a ella (nunca sus URL); mantenla fuera de la ruta pública, como hacen los ejemplos de arriba. Dos réplicas con el mismo configDigest se arrancaron con los mismos ajustes.
/readyz?format=json (o un Accept de solo application/json, como en /healthz) responde con el código de estado de la forma en texto y estos campos:
status:ready,degraded(varias instancias, alguna caída) onot ready;reason, solo cuando no está disponible, dice lo que la forma en texto dice tras el prefijonot ready:.catalogVersion: la versión de Arcane a partir de la que se generó el catálogo.versionMatch: si el major.minor de la versión de la que informó la instancia es el del catálogo;nullmientras la versión es desconocida o no es una versión publicada (una compilación de desarrollo comonext).- Con varias instancias,
versionMatchestá eninstances, una entrada por instancia con sunamey sustatus(oko lo que falló).
{"status":"ready","versionMatch":false,"catalogVersion":"v2.17.2"}La versión exacta de Arcane no está en la respuesta: /readyz no pide credencial, y la versión permitiría a cualquiera que llegue al servidor identificar el Arcane que hay detrás. Está en el log del servidor, en las líneas de aviso e información descritas en La versión de Arcane y la del catálogo difieren. Una versión que difiere de la del catálogo se registra como aviso y aparece aquí como versionMatch: false, pero nunca hace fallar /readyz. La forma en texto nunca pregunta a Arcane su versión; la forma JSON la vuelve a leer cuando la que tiene es de hace más de 10 minutos.
arcane-mcp --probepide/healthzal servidor local (--readypara/readyz) y termina con0ante un200y con1en otro caso, en 3 segundos como mucho (--timeout). Lee la dirección y el certificado igual que el servidor, así que encuentra un puerto TCP, un servidor con TLS o un socket unix sin argumentos. ElHEALTHCHECKde la imagen lo ejecuta cada 30 segundos; un contenedor stdio se da por sano, porque no tiene servidor que sondear. Un servidor en el puerto0no se puede encontrar así: pasa con--httpel puerto que haya registrado.- Parada. Ante
SIGTERMel servidor deja de aceptar conexiones, cierra los flujos de eventos abiertos y da hasta 10 segundos a las peticiones en curso para terminar. - Drenaje. Con
ARCANE_MCP_HTTP_DRAIN_DELAY(como mucho5m),SIGTERMpone primero/readyzen503mientras el servidor sigue atendiendo, para que el balanceador deje de enviarle peticiones nuevas; la parada de arriba llega tras el plazo. Docker espera 10 segundos antes de matar un contenedor, así que subestop_grace_perioden Compose al plazo de drenaje más esos 10 segundos.
Logs y registro de auditoría
Sección titulada «Logs y registro de auditoría»Todo va a la salida de error estándar: docker logs o docker compose logs arcane-mcp para un contenedor, journalctl -u arcane-mcp para el servicio de arriba. Cada llamada a una herramienta deja un registro de auditoría con la huella de la clave y, con varias instancias, el nombre de la instancia; los rechazos de la capa HTTP se registran en warn y las autenticaciones fallidas en info, con la dirección del cliente. Envía la salida de error adonde guardes los logs si necesitas un rastro. Consulta Logs y registro de auditoría.
Lista de comprobación
Sección titulada «Lista de comprobación»-
ARCANE_MCP_HTTP_TOKENoARCANE_MCP_HTTP_AUTH=apikey - TLS en el proxy o en el propio servidor;
/mcpencaminado sin búfer, sin compresión y sin plazos cortos -
ARCANE_MCP_HTTP_ALLOW_PLAINTEXT=truecuando un proxy cifra el tramo hasta un servidor en HTTP sin cifrar, ofalsepara rechazar HTTP sin cifrar en la red -
ARCANE_MCP_HTTP_ALLOWED_HOSTScon el nombre público -
ARCANE_MCP_HTTP_TRUSTED_PROXIES(la dirección fija del proxy, ounix) yARCANE_MCP_HTTP_TRUSTED_PROXY_HEADER - Ni
ARCANE_API_KEYni inicio de sesión en un servidor compartido, o una clave con un rol reducido - Modo de solo lectura, modo seguro o exclusiones si hay que limitar a todos los usuarios (se aplican a todo el servidor)
- La salida de error recogida, por el registro de auditoría
-
/readyzvigilado y fuera de la ruta pública