MCP Pacemaker
Utilidad para desarrolladores para la supervisión local de procesos MCP y puente HTTP, con sesiones aisladas, uso compartido compatible opcional y un panel web.
Documentación
mcp-pacemaker
Un supervisor de procesos local y puente de transporte para tus servidores MCP. Gestiona la vida útil del servidor fuera de tu editor o CLI, con pre-calentamiento opcional y compartición de sesiones compatible. El puente de larga duración no tiene dependencias de ejecución de terceros; la CLI de configuración y los paneles tienen sus propias dependencias.
Instalar desde npm · Reportar un problema · Notas de versión
Este README describe 2.1.0. Verifica su disponibilidad en npm antes de instalar; una rama de origen o una etiqueta de GitHub no es prueba de publicación. Consulta los cambios de versión.
Los hosts MCP — editores (VS Code, Cursor, Claude Desktop) y CLIs (Claude Code, Copilot CLI,
Codex, Gemini) — ejecutan servidores MCP stdio como procesos hijos. Cuando el host se reinicia, falla o
sale (en cada ejecución de CLI de un solo uso), esos servidores mueren. mcp-pacemaker ejecuta tus servidores como
hijos de un puente pequeño y de larga duración y expone cada uno a través del transporte MCP HTTP+SSE / Streamable HTTP.
Múltiples hosts usan un solo puente, con un hijo aislado por sesión de forma predeterminada.
Opta por el pre-calentamiento o reutiliza un hijo inicializado para sesiones de herramientas sin estado compatibles
con el modo compartido. Conecta hosts a un puente, o dale a cada uno el suyo propio.
Un supervisor multiplataforma + inicio automático del sistema operativo mantienen el puente vivo a través de reinicios y
suspensión/activación, y una capa de autenticación conectable inyecta un token nuevo por solicitud para servidores HTTP.
Después de un reinicio, un cliente que regresa puede reutilizar un ID de sesión registrado para restablecer su protocolo de enlace contra un servidor nuevo. Esto no restaura el estado arbitrario de las herramientas ni preserva las conexiones TCP. Los clientes que dejan de reintentar después de una conexión caída pueden necesitar una recarga; la transferencia de sockets es un trabajo planificado separado.
Inicio rápido
Instala mcp-pacemaker 2.1.0 desde npm. Usa una versión mantenida de Node.js 22 o 24; Windows también necesita PowerShell 7 y Windows Script Host. Consulta los requisitos de instalación antes de la configuración.
npm view mcp-pacemaker@2.1.0 version
npm install -g mcp-pacemaker@2.1.0
mcp-pacemaker --version
La verificación de versión imprime 2.1.0 sin ejecutar la configuración.
Ejecútalo como un usuario normal. Desde 2.1.0, el puente, el supervisor y las actualizaciones predeterminadas rechazan a un llamador privilegiado al inicio — una terminal no administradora en Windows y una sesión no root en Linux/macOS, incluido el usuario
rootpredeterminado en la mayoría de los contenedores. Un inicio rechazado imprimeUser-runtime execution refused: …. No hay anulación; ejecuta como un usuario normal en su lugar. Consulta el contrato de ejecución de usuario.
Antes de la configuración, ten un archivo de configuración JSON legible que contenga definiciones de servidor, o
prepara ~/.mcp-pacemaker/servers.json. Las fuentes de importación compatibles son
vscode, cursor, claude (Claude Desktop), copilot-cli y gemini.
Codex y Claude Code son destinos de conexión, no fuentes de importación.
Luego ejecuta la configuración interactiva:
mcp-pacemaker init
init detecta hosts compatibles, importa una fuente de host (o reutiliza servers.json),
pide confirmación antes de conectar los hosts seleccionados, registra el inicio automático del sistema operativo y
inicia el puente. Recarga o reinicia los hosts seleccionados después.
La configuración cambia la configuración local y el inicio automático. La importación puede crear o actualizar
servers.json antes de la confirmación de conexión. Los archivos de host JSON/TOML existentes reciben una .bak
antes del reemplazo; los registros nativos de Claude Code no. Mantén tu propia copia de seguridad de configuración protegida,
especialmente antes de repetir la configuración.
--from elige la fuente de importación; --client elige los destinos de conexión. Por ejemplo,
mcp-pacemaker init --from vscode --client codex importa las definiciones de VS Code y conecta
Codex. Sin --from, la configuración prefiere el primer host JSON detectado; no fusiona
cada host detectado. Omite --yes para mantener el mensaje de confirmación.
Verifica el puente en ejecución:
mcp-pacemaker status # status without entering first-run setup
mcp-pacemaker top # live terminal dashboard
mcp-pacemaker doctor # diagnose config, reachability, wiring
¿Prefieres manejarlo tú mismo? Los mismos pasos, uno a la vez
plan, install y emit aceptan cualquier host compatible como destino de conexión.
import --from acepta las cinco fuentes de importación JSON enumeradas anteriormente. Ejecuta la importación primero a menos que
ya tengas servers.json; plan necesita ese archivo.
mcp-pacemaker import --from <source> # write servers.json from one JSON host config
mcp-pacemaker plan --client <host> # dry run: show what install would change
mcp-pacemaker install --client <host> # wire one host (--port N gives it its own bridge)
mcp-pacemaker start # start the bridge
# e.g. import from Cursor, then wire three hosts to the same bridge
mcp-pacemaker import --from cursor
mcp-pacemaker install --client cursor
mcp-pacemaker install --client claude-code
mcp-pacemaker install --client gemini
Ejecuta install una vez por host que quieras conectar; repite con --port N en su lugar para darle a un host su
propio puente. emit imprime las entradas de configuración sin escribir nada, si prefieres pegarlas.
¿Qué modo de compartición de procesos?
Compartir un puente no comparte automáticamente un proceso de servidor.
| Modo | Comportamiento del proceso | Úsalo cuando |
|---|---|---|
isolated (predeterminado) | Un hijo por sesión | El servidor necesita estado de espacio de trabajo, cuenta o conversación por cliente |
pool (opt-in) | Hijos pre-iniciados, no inicializados; cada uno se asigna exclusivamente a una sesión | El inicio es lento pero las sesiones deben permanecer separadas |
shared (opt-in) | Un hijo inicializado para sesiones compatibles | Las herramientas son sin estado, las entradas son explícitas y el contexto de credenciales es común |
Los clientes compartidos deben enviar parámetros de inicialización idénticos, incluido clientInfo, y
capacidades de cliente vacías. No es compartición automática entre editores. Consulta
los límites del modo compartido antes de habilitarlo.
Elegir una herramienta de transporte
Documentación verificada el 27 de septiembre de 2026; esta es una guía de casos de uso, no una comparativa de características.
| Herramienta | Considérala cuando |
|---|---|
| Supergateway | Quieras conversión de línea de comandos entre transportes stdio y HTTP/SSE/WebSocket |
| mcp-proxy | Quieras un adaptador basado en Python entre clientes/servidores stdio locales y transportes MCP remotos |
| mcp-pacemaker | Quieras supervisión de procesos de estación de trabajo, conexión de hosts, inicio automático, diagnósticos de ciclo de vida y políticas explícitas de aislamiento/agrupación/compartición |
Estos proyectos tienen capacidades superpuestas. Reconectarse a un servidor nuevo no es recuperación del estado arbitrario de la aplicación, y un puente de transporte no es un sandbox para herramientas no confiables.
Hosts compatibles
Los editores y CLIs se detectan automáticamente y se conectan al puente. La mayoría de los hosts obtienen Streamable HTTP
(/<name>/mcp); Cursor y Claude Desktop se conectan a través de SSE (/<name>/sse) hasta que Streamable HTTP
se verifique allí. El puente centraliza la autenticación, por lo que los hosts se comunican con él sin autenticación a través de
loopback.
| Host | Tipo | Configuración | Conexión | Transporte |
|---|---|---|---|---|
| VS Code | editor | Code/User/mcp.json | edición directa | Streamable HTTP |
| Cursor | editor | ~/.cursor/mcp.json | edición directa | SSE |
| Claude Desktop | editor | claude_desktop_config.json | edición directa | SSE |
| Claude Code | CLI | ~/.claude.json | claude mcp add nativo | Streamable HTTP |
| Copilot CLI | CLI | ~/.copilot/mcp-config.json | edición directa | Streamable HTTP |
| Codex CLI | CLI | ~/.codex/config.toml | TOML (preserva comentarios) | Streamable HTTP |
| Gemini CLI | CLI | ~/.gemini/settings.json | edición directa | Streamable HTTP |
Topologías: conecta cada host a un puente compartido (predeterminado), o dale a cada host su propio puente
(install --client X --port N) — o cualquier combinación. status/doctor informan todos los puentes + hosts conectados.
Instalación
Usa una versión mantenida de Node.js 22 o 24. Node 20 sigue siendo un objetivo de compatibilidad pero está al final de su vida útil, no es un runtime seguro recomendado. El puente no tiene dependencias de ejecución npm; la CLI de configuración y el panel tienen sus propias dependencias.
Ejecuta como un usuario normal. Desde 2.1.0, el puente, el supervisor y las actualizaciones predeterminadas verifican al
llamador antes de cualquier trabajo de runtime y rechazan llamadores elevados o root al inicio con
User-runtime execution refused: …. En Linux y macOS eso incluye root, que es el
usuario predeterminado en la mayoría de las imágenes de contenedores, así que ejecuta el puente como una cuenta normal allí. El
contrato de ejecución de usuario describe qué se verifica y por qué; la administración explícita de cuentas de Windows
tiene una ruta de controlador/trabajador separada.
Instala el paquete publicado desde npm.
Su enlace de repositorio debe apuntar a
girishkvs/mcp-pacemaker.
Usa una versión exacta para una instalación reproducible:
npm view mcp-pacemaker@2.1.0 version
npm install -g mcp-pacemaker@2.1.0
mcp-pacemaker --version
La línea actual usa el canal npm latest; la línea de mantenimiento usa legacy cuando ese
canal se ha publicado. Verifica los valores reales del registro antes de elegir un canal:
npm view mcp-pacemaker dist-tags --json
Las etiquetas de GitHub y la publicación en npm son separadas: una etiqueta no establece que la misma
versión o canal esté disponible en npm, o que sus bytes de paquete sean idénticos.
@1 y @2 son rangos de versión, no los canales mantenidos. Pueden seleccionar una versión
retirada de un canal. upgrade --self resuelve el canal de la versión principal instalada e imprime
un comando de versión exacta; nunca instala ni degrada nada.
Usa un directorio de instalación duradero para un servicio de larga duración. No registres el inicio automático
desde una caché de npx: esa caché puede eliminarse más tarde. La invocación CLI simple puede entrar al asistente
de configuración; usa --version para una verificación de instalación de solo lectura.
La configuración de Windows también necesita PowerShell 7 (pwsh) y Windows Script Host para su lanzador.
Las ediciones automáticas de configuración necesitan .NET Framework 4.6.2 o más reciente. El asistente incluido está
sin firmar; la procedencia de npm no es firma Authenticode ni una lista de permitidos de control de aplicaciones.
Windows ARM64 no está validado.
Compatibilidad de versiones
Este README describe 2.0.x. Para el comportamiento de guardado inmediato de 1.3.x, consulta la documentación heredada y la política de soporte. Esos documentos no establecen que una versión heredada esté disponible en npm.
Las líneas base históricas siguen siendo 1.3.0 / 2.0.0. La evidencia del par de parches anterior 1.3.1 / 2.0.1 no es transferible a una nueva versión. El par seleccionado 1.3.1 / 2.0.2 requiere compatibilidad de bytes exacta nueva y compuertas de reemplazo de servicio. Un cliente 2.x maneja guardados inmediatos heredados. Un cliente 1.x no puede escribir configuraciones de agrupación en un puente 2.x: actualiza la CLI y actualiza las pestañas antiguas del panel. Antes de degradar, resuelve transacciones pendientes o interrumpidas con 2.x. Consulta las compuertas de versión reales para pares exactos; solo los pares ejecutados exactos están cubiertos.
Referencia de comandos
| Comando | Qué hace |
|---|---|
init [--from source] [--client a,b] [--yes] | Configuración interactiva: importa una fuente, conecta los hosts seleccionados, auto-inicio, lanzamiento |
status | Puentes, hosts conectados, servidores y cualquier servidor que esté fallando actualmente |
reload | Vuelve a leer servers.json en el puente en ejecución sin reiniciarlo |
doctor | Diagnostica configuración, alcanzabilidad del puente, cableado de hosts |
prewarm [--port N] [--json] | Una vista de candidatos stdio, pools, estado de child compartido y inicios de procesos medidos |
prewarm --enable <server> [--count N] | Habilita explícitamente los slots cálidos; --disable <server> los desactiva |
logs [--follow] [--since 2h] [--server name] [--grep text] | Lee y filtra registros duraderos, incluida la rotación retenida |
top / dashboard | Interfaz de terminal en vivo / panel web |
plan --client <host> | Ejecución de prueba: muestra exactamente qué cambiaría install |
import --from <source> | Construye ~/.mcp-pacemaker/servers.json a partir de una configuración de host JSON compatible |
install --client <host> [--port N] | Conecta un host (su propio --port le da su propio puente) |
emit --client <host> | Imprime las entradas de configuración sin escribir nada |
start / stop | Inicia o detiene puentes (--port para uno, si no, todos) |
upgrade --to <version> [--plan] [--yes] | Prepara y reemplaza una instalación administrada, incluida su CLI, conservando puerto/configuración/cableado de hosts |
upgrade --to <version> --sxs [--port N] | Mantiene la instancia anterior e inicia una nueva aislada; el puerto omitido lo asigna el sistema operativo |
upgrade --recover | Reanuda o revierte un reemplazo administrado interrumpido desde su diario duradero |
[--instance <directory>] | Selecciona una instalación cuando el descubrimiento encuentra varias; válido antes o después del comando |
upgrade [--self] | Reparación de host heredada; --self solo imprime guía de instalación de la misma versión principal |
update-check [--json] | Compara la versión instalada con su canal npm mantenido |
uninstall | Detiene puentes administrados, elimina el auto-inicio, restaura copias disponibles de .bak del archivo de host; las entradas nativas no se restauran |
La instalación del paquete por sí sola no actualiza un backend en ejecución. Use
upgrade --toexplícito para el reemplazo administrado.upgradesimple conserva el comportamiento de reparación de host anterior.
Al iniciar, pacemaker sondea el puerto: adopta un puente pacemaker existente y se niega a colisionar con un servicio externo (el asistente ofrece otro puerto).
Para un supervisor creado por estas versiones de parche, stop --port N verifica la identidad
de instalación/configuración coincidente, espera el apagado y mantiene el auto-inicio administrado hasta un
start --port N explícito. El apagado normal del sistema operativo no crea esa retención. Use la CLI
de la instalación coincidente. Los puentes más antiguos o lanzados directamente no tienen registro de detención administrada y se
rechazan en lugar de informarse como detenidos; desactive su auto-inicio del sistema operativo y verifique el apagado primero.
En Linux/macOS, el socket de control reside junto a la configuración, independiente de TMPDIR.
Su ruta completa debe caber en 103 bytes UTF-8. install y init verifican esto antes de
cambiar la configuración o el auto-inicio; use una ubicación de configuración más corta en lugar de
depender de una alternativa implícita de ubicación de socket.
Los servidores stdio aislados y agrupados admiten HTTP+SSE (/<name>/sse) y Streamable HTTP
(/<name>/mcp). El modo compartido requiere Streamable HTTP.
install respalda un archivo de host JSON/TOML existente en .bak; repetirlo reemplaza ese respaldo.
uninstall restaura los respaldos de archivos de host disponibles, deja los archivos sin respaldo como están y
conserva servers.json. Los registros nativos de Claude Code no se respaldan ni se restauran
automáticamente; registre sus definiciones originales por separado y restáurelas a través de Claude Code.
Reemplazar o revertir una instalación en ejecución
Estos comandos de actualización administrada requieren 2.1.0 o más reciente. La versión 2.0.2 no los incluye.
Ejecute el puente, el supervisor, las actualizaciones predeterminadas y la recuperación como un usuario normal: una terminal normal no administradora en Windows y una sesión no root en Linux/macOS. El contrato de tiempo de ejecución del usuario rechaza llamadores privilegiados o no verificados antes del trabajo en tiempo de ejecución, por lo que un reemplazo no hereda autoridad diferente. Los planes de solo lectura siguen disponibles. La administración explícita de cuentas de Windows tiene una ruta de controlador/trabajador y requisitos de calificación separados.
Para una instancia administrada estable creada por esta implementación:
mcp-pacemaker upgrade --to <exact-version> --plan
mcp-pacemaker upgrade --to <exact-version>
# Noninteractive confirmation of the displayed local plan:
mcp-pacemaker upgrade --to <exact-version> --yes
# Keep the existing service and host wiring:
mcp-pacemaker upgrade --to <exact-version> --sxs
mcp-pacemaker upgrade --to <exact-version> --sxs --port 9001
--to requiere SemVer estable canónico, no latest, un rango o una especificación Git/archivo.
Seleccionar otra versión principal es explícito y se imprime en el plan; no es una afirmación
de compatibilidad. El objetivo debe incluir el protocolo administrado de admisión/disponibilidad. Los objetivos más antiguos
sin ese protocolo se rechazan antes de la interrupción, incluidos los puertos SxS automáticos.
Las actualizaciones normales conservan el puerto seleccionado: --port es válido solo con --sxs.
Sin un puerto SxS, el nuevo listener de loopback real se vincula al puerto 0 y permanece abierto;
el puerto seleccionado por el sistema operativo se muestra y se guarda para inicios posteriores. El plan de solo lectura dice
"asignado por el sistema operativo", no un puerto adivinado. Un puerto ocupado solicitado explícitamente falla sin adopción.
SxS obtiene configuración, nonce, registros y archivos de sesión separados. Conserva el directorio de trabajo de origen
para comandos de servidor relativos y no recablea ningún host ni habilita la agrupación.
Cuando el descubrimiento encuentra varias instancias, use el directorio exacto impreso por la configuración/actualización:
mcp-pacemaker upgrade --instance <directory> --to <exact-version> --plan
mcp-pacemaker start --instance <directory>
mcp-pacemaker stop --instance <directory>
--instance <directory> y --instance=<directory> funcionan antes o después del
comando. La selección se normaliza una vez, incluidas las rutas con espacios; los selectores en conflicto
o las anulaciones de puerto/configuración se rechazan antes de una acción. El texto después de --
no se interpreta como selector. Una selección explícita no válida nunca recurre
a la instancia predeterminada.
Las opciones de puerto de CLI usan enteros decimales canónicos del 1 al 65535; notación científica, hexadecimal,
signos, espacios circundantes y grafías con ceros a la izquierda se rechazan antes de las solicitudes.
Los comandos seleccionados start, stop, reload, prewarm, status, doctor, top, logs,
dashboard, versión/ayuda y actualización usan el mismo contexto de instancia.
La tecla de reciclaje de la TUI usa el puerto y el directorio de nonce de esa instancia; los registros usan
su directorio de configuración. mcp-pacemaker --instance <directory> simple muestra el estado
incluso cuando SxS no tiene estado de cableado de hosts. Los comandos de configuración/eliminación de hosts (init,
import, install, uninstall) se rechazan con --instance; la selección sola
no autoriza reescribir la configuración de hosts ni cambiar el auto-inicio.
Los comandos generados de Cancelar/Deshacer de precalentamiento conservan la instancia y la configuración seleccionadas,
por lo que resuelven la misma versión de CLI y el mismo directorio de nonce. Los comandos de Windows usan
un lanzador de PowerShell codificado con una lista de argumentos nativa explícita para conservar
espacios, comillas y caracteres de shell; los comandos --config no administrados siguen siendo compatibles.
El lanzador estable por instancia selecciona directorios de versiones verificados. Las actualizaciones nunca
sobrescriben un paquete en ejecución ni reescriben tareas de auto-inicio por versión. La selección anterior
y el paquete se conservan. El punto de entrada de comando existente despacha a la CLI de la versión confirmada
y sus propias dependencias: --version, status, update-check ordinarios
y el siguiente upgrade usan esa versión. Una activación sin terminar mantiene la CLI anterior
disponible para recuperación; la reversión restaura esa selección de CLI. SxS no cambia
la CLI predeterminada. Use --instance <directory> para seleccionar su CLI explícitamente.
Las dependencias objetivo se resuelven en un bloqueo privado y se restauran con las verificaciones de integridad
de archivo de npm antes de la interrupción. Tanto el bloqueo como los archivos de dependencias instalados entran
en el inventario de versiones verificado. El inicio y la versión de la CLI objetivo se verifican antes de la pausa.
El archivo objetivo y las dependencias de CLI resueltas requieren metadatos de integridad SHA-512.
La información de integridad solo SHA-1 o faltante se rechaza antes de la interrupción; el
actualizador no degrada sus verificaciones para adaptarse a un registro.
La adquisición usa el registro npm configurado, o --registry explícito,
sin respaldo de registro ni cambios globales de npm. Los permisos npm existentes,
TLS, política de antigüedad de lanzamiento y mapeo de prefijos de URL permanecen en vigor; los scripts de ciclo de vida se
deshabilitan para la adquisición. Para espejos npm 12, use su mapeo de prefijo de URL completa
replace-registry-host aprobado por comando de vuelta a través de ese registro, no una
URL de espejo codificada ni una omisión del registro público.
La descarga, la integridad del archivo, las verificaciones de paquete/entorno/binario nativo y una verificación de inicio de paquete propio se completan antes de la interrupción. La admisión luego cierra y espera hasta ocho segundos para que el trabajo seguro se drene. Las sesiones MCP abiertas y las transacciones de configuración no resueltas actualmente causan un rechazo; ciérrelas/resuélvalas y reintente. Ninguna llamada de herramienta incierta ni confirmación de configuración fallida se reproduce. Este es un reinicio corto, no una transferencia de socket ni tiempo de inactividad cero. Los clientes y las pestañas del panel pueden necesitar una recarga.
El supervisor persiste la retención de admisión antes de reenviar la pausa. Una respuesta perdida, un drenaje fallido, un bloqueo del puente o un child de reemplazo no la liberan. Solo la reanudación/recuperación explícita o una activación verificada abre la admisión nuevamente. La detención de la actualización está vinculada a la generación drenada; cualquier generación de reemplazo debe permanecer retenida.
El diario de activación bloquea los inicios no supervisados después de una transición interrumpida. La selección y la intención de lanzamiento son transiciones duraderas separadas. Un objetivo seleccionado que se demostró que nunca se lanzó puede recuperarse usando el recibo exacto de generación detenida anterior. Después de la intención de lanzamiento, un puerto vacío por sí solo no es prueba de apagado. La recuperación analiza identidades de instancia/diario limitadas antes de verificar los bytes del ejecutable. Verifica y ejecuta completamente la CLI de recuperación retenida, por lo que un archivo objetivo dañado o faltante no puede impedir una reversión segura previa al lanzamiento. Un paquete anterior dañado, una identidad obsoleta o un diario desconocido aún causan un rechazo.
| Estado del diario | Límite de recuperación |
|---|---|
| Preparado / en pausa | Reanudar explícitamente el servicio anterior coincidente |
| Deteniendo | Reconciliar la generación drenada exacta |
| Detenido / seleccionando / seleccionado | Requerir el recibo de detención completa anterior; el objetivo no tiene intención de lanzamiento |
| Lanzando | Requerir una nueva generación retenida y apagado verificado; sin inferencia de puerto vacío |
| Seleccionando-reversión / seleccionado-reversión | Requerir la prueba de detención de reversión duradera antes de seleccionar/reiniciar el código anterior |
| Lanzando-reversión | Requerir prueba para la generación anterior recién lanzada; de lo contrario, rechazar |
| Admitiendo / admitiendo-reversión | La admisión puede haber ocurrido; sin reversión automática |
| Confirmado / revertido / abortado | No queda activación interrumpida |
La reversión automática se restringe al fallo de inicio antes de la admisión del objetivo, con bytes de configuración sin cambios, identidad y seguridad, y apagado verificado. Si la admisión puede haber ocurrido, la recuperación rechaza en lugar de sobrescribir el estado del usuario.
mcp-pacemaker upgrade --recover --instance <directory> --yes
Un bloqueo puede dejar upgrade.lock. La recuperación no lo roba basándose en un PID reutilizable.
Verifique que el actualizador original haya salido, conserve el diario y elimine solo el
bloqueo de esa instancia antes de la recuperación. Mantenga paquetes, configuración y archivos de transacción.
Las escrituras del diario se vacían a archivo y se renombran atómicamente; la durabilidad de las entradas de directorio
de Windows ante pérdida de energía no se afirma.
Migración de reinicio única de Windows 1.3
La confirmación normal de upgrade --to <exact-version> también admite la forma exacta conocida
1.3.0 de supervisor/lanzador de Windows y tarea por usuario, con un puerto en el
estado de instalación existente. Invoque una CLI capaz de actualizar desde un paquete duradero separado;
no sobrescriba primero el paquete 1.3 en ejecución. --plan permanece de solo lectura.
Esta transición reinicia Pacemaker, no Windows. Pausa a los llamadores antes de confirmar.
La confirmación interactiva indica que los clientes se desconectarán y que 1.3 no puede drenar
ni certificar cada resultado HTTP en vuelo. Cero sesiones reportadas o PIDs hijos no
prueba que las llamadas HTTP hayan terminado. La invocación ordinaria de --yes y la invocación desatendida rechazan esta
transición; no hay una bandera de mantenimiento separada ni reproducción automática de llamadas.
El paquete objetivo, las dependencias CLI, las identidades nativas y el inicio empaquetado se verifican antes del tiempo de inactividad. Un broker separado conserva manejadores para el supervisor seleccionado, el puente y un conjunto acotado de descendientes con propiedad demostrable. Solo se retiene la tarea seleccionada verificada. La detención usa esos manejadores y verifica su salida antes de iniciar el objetivo retenido en el mismo puerto. No usa un kill por nombre/PID ni asume que la desactivación de la tarea detuvo el supervisor en ejecución. La configuración, el cableado del host y el puerto permanecen sin cambios; la entrada CLI existente despacha la CLI gestionada recién seleccionada.
La preparación permanece fuera del descubrimiento gestionado hasta que la identidad de la instancia y el diario de recuperación sean duraderos; el directorio preparado se publica entonces junto. Una falla de E/S anterior al diario deja la instalación antigua descubrible. La preparación fallida se conserva, no se asume segura para eliminar. Un candidato terminal en estado revertido/abortado se excluye solo después de que su diario acotado y el enlace de origen heredado validen, de modo que los archivos de destino dañados no impidan reintentar la instalación heredada aún en ejecución.
El propietario del recurso y el descriptor de seguridad completo de la tarea son separados de su cuenta
de ejecución. La planificación y cada operación de tarea requieren inspección de propietario/grupo/DACL/SACL/integridad
a través del Programador de tareas. Si la lectura de seguridad requerida se deniega o no es compatible,
la migración se niega antes de tocar la tarea; no habilita privilegios ni eleva.
Las actualizaciones de tareas existentes preservan la seguridad en lugar de reasignar su propietario: limpian
solo el descriptor incrustado de la definición temporal, no pasan un descriptor de seguridad de reemplazo,
deshabilitan las ediciones automáticas de ACE de principal y verifican el descriptor de recurso crudo completo
nuevamente después. Las copias de seguridad protegidas conservan el descriptor crudo original y el XML.
La restauración requiere igualdad exacta de todos los campos de registro/seguridad no XML y el
XML normalizado por el Programador de tareas, ignorando solo la representación exacta de Task/RegistrationInfo/SecurityDescriptor incrustada.
Las condiciones previas de revisión cruda, las copias de seguridad y el XML/hash devuelto real no se reescriben;
otra deriva de metadatos o XML se niega. Los cambios de seguridad concurrentes o inciertos requieren inspección,
no reparación de permisos. El propietario del recurso puede ser el usuario en tiempo de ejecución o los Administradores
integrados canónicos; eso no cambia la cuenta de ejecución. El ámbito predeterminado sigue siendo usuario actual,
pero la ejecución y recuperación de Windows requieren un llamador ordinario recién verificado
antes del staging o la mutación; un llamador elevado o no verificado se niega en lugar de
lanzar un runtime con autoridad diferente. La planificación de solo lectura no cambia.
La administración explícita de la cuenta original usa un controlador de confianza solo para tareas
y un trabajador de usuario original; consulte
ámbito y calificación de actualización de cuenta.
--all-users no es compatible explícitamente.
El recibo heredado reporta legacyRootStopVerified, observedDescendantsStopped y
treeCompleteness: "unproven" por separado. Esto no es la prueba moderna de descendientes completos
del Job Object. Los procesos huérfanos históricos o no capturados no pueden atribuirse completamente;
se dejan intactos y la limitación se reporta sin reclamar un
recuento de huérfanos. El nuevo runtime gestionado contiene futuros hijos desde el nacimiento.
Formas de paquete/tarea desconocidas, propietario/generación/configuración cambiados, una detención de proceso capturado fallida o un listener externo impiden la activación. Un listener externo nunca se detiene. El código original y las copias de seguridad de configuración/tarea protegidas se conservan. Una falla de objetivo verificada antes de la admisión puede restaurar la CLI original y la tarea con ámbito y verificar un backend heredado fresco; resultados inciertos de lanzamiento, registro o admisión requieren recuperación explícita. No se elimina ni reproduce ninguna configuración.
| Fase del diario heredado | Límite de recuperación |
|---|---|
legacy-prepared / legacy-held | Verificar las generaciones originales y el estado sin cambios; restaurar solo la retención de tarea registrada |
legacy-holding | El resultado de escritura de la tarea puede ser desconocido; inspeccionar antes de la recuperación |
legacy-stopping | Verificación de ausencia de generación capturada de solo lectura; un conjunto observado incompleto rechaza la recuperación |
legacy-stopped | Revalidar la detención parcial y el puerto libre antes de la reversión segura a la versión antigua |
legacy-launching / legacy-wiring | Requerir prueba de apagado del objetivo retenido moderno; un puerto cerrado solo es insuficiente |
legacy-admitting | El tráfico puede haber entrado; sin reversión automática |
| Fases de intención de reversión heredada | Un resultado interrumpido de tarea/CLI/lanzamiento se reporta como incierto, no se reintenta a ciegas |
legacy-rolled-back / legacy-aborted | La instalación original permanece seleccionada; el candidato gestionado en staging permanece inactivo |
Una migración interrumpida también puede dejar el legacy-upgrade/upgrade.lock del perfil.
Verifique que el actualizador exacto haya salido antes de eliminar su bloqueo; nunca lo robe adivinando el PID.
Conserve el diario y los archivos de copia de seguridad.
Este adaptador no admite puentes no registrados directos, otras versiones heredadas,
múltiples puertos heredados, registros de Linux/macOS o SxS de origen heredado. Los objetivos deben
declarar legacyRestartProtocol: 1; los objetivos publicados más antiguos sin él se niegan antes del
tiempo de inactividad heredado.
SxS gestionado mantiene su propia copia de paquete verificada, así como estado de runtime separado. Si ocurre un bloqueo durante el inicio en el puerto 0 antes de que el puerto se registre de forma duradera, la recuperación reporta un resultado de lanzamiento desconocido en lugar de marcarlo como abortado de forma segura. Preserve esa instancia y su diario hasta que la preparación o el apagado puedan verificarse.
Para una instalación más antigua que requiere una migración manual verificada por separado:
No sobrescriba un directorio de paquete mientras su supervisor o puente esté en ejecución. Los trabajadores y los ayudantes nativos pueden cargarse más tarde, y los activos del panel se leen desde el disco: el reemplazo puede mezclar código antiguo y nuevo incluso cuando el proceso original aún reporta su versión antigua.
Identifique el puerto seleccionado, el directorio de instalación, el directorio de configuración y la entrada de inicio automático del SO primero. Liquide o cancele lotes de 2.x, recupere transacciones interrumpidas con 2.x y mantenga una copia de seguridad de configuración protegida. Desactive la entrada de inicio automático seleccionada y detenga su supervisor y puente antes de reemplazar archivos; demuestre que no pueden reiniciarse durante el reemplazo. Mantenga la instalación conocida como buena hasta que la versión del nuevo backend y la identidad de la instancia estén confirmadas. Vuelva a registrar la ruta de inicio automático prevista, actualice las pestañas del panel y confirme el cableado del host.
Un prefijo npm global contiene una versión de paquete y sus nombres de comando compartidos. Instalar la
otra versión principal allí la reemplaza. Los puertos separados no aíslan credenciales, nonces, registros o
archivos de sesión: la operación manual en paralelo necesita raíces de código duraderas separadas y directorios de configuración
separados, además de estado de host/HOME separado para la configuración gestionada por CLI.
init/import --config selecciona una configuración de host de origen, no un perfil de runtime aislado.
No hay interruptor de paquete --profile o MCP_HOME; SxS gestionado usa directorios de instancia explícitos
en su lugar. No use una operación de detención/desinstalación sin ámbito
cuando otra instancia debe permanecer en ejecución.
Paneles
Dos vistas del mismo estado en vivo. Ninguna es obligatoria — el puente se ejecuta sin cabeza — pero ambas son útiles para responder "¿este servidor está realmente activo y quién lo está usando?"
Panel web
mcp-pacemaker dashboard, o abra http://127.0.0.1:<port>/ui. Se transmite por SSE, por lo que
se actualiza solo sin sondeo ni actualización.

Por servidor muestra el transporte (stdio / http), la política de uso compartido (pool cuando se precalienta),
sesiones en vivo contra el límite, recuento de solicitudes, los PIDs reales del SO, el recuento del grupo cálido, hace cuánto
tiempo se usó por última vez y qué clientes están conectados — arriba, un servidor es compartido por
VS Code y Claude Code mientras que otros están retenidos por Copilot, Cursor y Codex. Recycle reinicia
los procesos de ese servidor; está deshabilitado para servidores sin sesión que reiniciar. El registro en vivo en
la parte inferior es el registro del propio puente, filtrable.
Controles de precalentamiento
La pestaña Pre-Warming coloca cada candidato stdio, grupo actual y servidor compartido en una tabla. Muestra p50/p95 de arranque en frío, picos de sesiones observados, inicios de procesos, recuentos cálidos/objetivo, estado de hijos compartidos y trabajo pendiente, y una acción. Los proxies HTTP se excluyen porque el puente no lanza sus procesos.
Elija Enable pre-warming (N) en una tarjeta de servidor lento o en la tabla. El botón muestra el recuento cálido exacto y el costo adicional de procesos residentes antes de hacer clic. Nada lo habilita automáticamente. Disable pre-warming elimina hijos cálidos inactivos sin matar sesiones activas después de que se aplique el cambio.
Los cambios se agrupan en una copia pendiente completa de servers.json. Cada cambio aceptado
restablece un contador de cinco segundos. Cuando la edición se detiene, la recarga valida la copia pendiente, conserva
el original como servers.previous.json, coloca el archivo pendiente en su lugar y activa
la nueva configuración. El panel muestra Pending o Applying hasta que eso tenga éxito; el
modo activo y los recuentos cálidos no se cambian antes. Reload now vacía el mismo lote inmediatamente.
Cancel batch descarta un lote pendiente sin cambiar la configuración activa. Undo batch prepara la configuración anterior completa para otro lote de cinco segundos, solo si no ha ocurrido una edición intermedia del archivo activo. Estas acciones afectan a todo el lote; el panel nombra todos los servidores afectados. Un lote pendiente no relacionado debe cancelarse o aplicarse antes de Undo.
Los mismos controles están disponibles sin navegador:
mcp-pacemaker prewarm --port 8791
mcp-pacemaker prewarm --port 8791 --enable filesystem --count 2
mcp-pacemaker prewarm --port 8791 --disable filesystem
# Changes are queued; the printed command cancels a pending batch or undoes it after application.
Use --config <path> cuando la configuración del puente y el nonce de administración estén fuera del directorio
predeterminado. --json devuelve la instantánea medida. La CLI y la UI usan los mismos datos de
elegibilidad y recomendación de servidor; una muestra de latencia faltante no se reporta como un inicio
de costo cero. La CLI regresa después del staging, por lo que los comandos consecutivos pueden unirse al mismo lote.
prewarm muestra la configuración pendiente por separado de los valores activos. La configuración sigue siendo JSON estricto,
no JSONC; la copia pendiente conserva JSON no relacionado y requiere una revisión activa coincidente.
Los conflictos se reportan en lugar de sobrescribir la edición de otra persona.
En Windows, los guardados se ejecutan con la cuenta normal del puente y usan auditoría heredada de directorio. El panel da un aviso no bloqueante: las reglas de auditoría personalizadas por archivo pueden no transferirse a la nueva copia activa. El original retenido conserva sus metadatos originales. No se requiere privilegio de lectura de auditoría, aviso de UAC ni puente elevado permanentemente.
Esto no permite un acceso más amplio a los datos de configuración. Los candidatos deben tener restricciones de acceso apropiadas antes de que se escriban bytes de configuración, y las protecciones de integridad compatibles deben conservarse. La denegación real de escritura de origen o la protección no compatible sigue siendo un error. Las operaciones de configuración se ejecutan en un trabajador serializado para que la inspección de archivos no bloquee el tráfico MCP.
La inspección de seguridad de Windows usa el ayudante .NET Framework incluido de código propio, en lugar de iniciar PowerShell o compilar código en cada escritura. Las ediciones automáticas requieren .NET Framework 4.6.2 o posterior; Windows moderno lo incluye. El código fuente del ayudante, las instrucciones de compilación y los metadatos de integridad están incluidos en el paquete. La ejecución de Windows ARM64 aún no está validada.
Las solicitudes de staging y las confirmaciones de archivos tienen cada una un presupuesto de ejecución acotado; el retraso de agrupación de cinco segundos reconocido no mantiene abierta la solicitud HTTP original. Una confirmación ya en progreso puede terminar después de su plazo. El resultado distingue una falla previa a la confirmación de un resultado confirmado o desconocido; nunca reintenta automáticamente ni afirma que una escritura con tiempo agotado se revirtió. Los dos movimientos de archivos no son un intercambio atómico. La recarga los coordina con estado de recuperación validado y colocación de destino sin reemplazo. El tráfico MCP existente continúa usando la configuración anterior en memoria durante el cambio; un lector externo puede encontrar brevemente la ruta activa ausente. La recuperación no debe sobrescribir un archivo creado por un editor externo. Vuelva a leer la configuración después de un resultado incierto.
Actualización desde 1.3.0
La versión 2.0.0 cambia el protocolo de guardado de configuración; no requiere un nuevo formato servers.json. Actualice el puente y la CLI juntos, luego recargue cualquier página de panel abierta. Un cliente 1.3.0 con un nonce actual obtiene HTTP 409 antes del staging, con una instrucción para actualizar el cliente. Una pestaña ya abierta conserva el nonce antiguo después de un reinicio del puente y obtiene HTTP 401; actualícela para cargar el nuevo panel y la sesión de administración.
Los clientes API personalizados deben enviar x-mcp-pooling-batch: 1. Trate HTTP 202 como aceptación, no como finalización, y siga el ID de lote devuelto en prewarm.batches hasta que se aplique, cancele o falle. Los scripts CLI también deben esperar la aplicación antes de confiar en la nueva configuración. Deshacer ahora restaura el lote completo y puede afectar a varios servidores. Los clientes actualizados aún entienden la respuesta HTTP 200 inmediata de un puente 1.3.0.
Antes de degradar, cancele o aplique cambios pendientes con 2.0 y resuelva cualquier transacción interrumpida usando la recuperación de 2.0. Detenga ese puente antes de iniciar 1.3.0 con la configuración activa. No use un binario 1.3.0 para recuperar archivos de transacción de 2.0 ni elimine esos archivos para omitir un error de recuperación. Mantenga una copia de seguridad protegida de la configuración antes de cambiar de versión. Si el trabajador de escritura sale, se rechazan más ediciones automáticas hasta que el puente se reinicie; las sesiones MCP existentes continúan.
Salud
La pestaña Health ejecuta las mismas comprobaciones que mcp-pacemaker doctor, para que pueda verlas sin una terminal.

Comprueba la versión de Node, que la configuración se analice, cada definición de servidor (incluido un servidor stdio cuya ruta relativa no se resolverá desde el directorio en el que se ejecutaría — un fallo que de otro modo es silencioso hasta que un cliente lo llama por primera vez, y un servidor nombrado como una de las rutas propias del puente, que es inalcanzable), cualquier servidor que esté fallando actualmente, y que el archivo de nonce de administración exista.
Panel de terminal
mcp-pacemaker top son los mismos datos que una TUI Ink, para cuando un navegador es inconveniente:
🫀 mcp-pacemaker top ● :8850 · up 176s · v1.1.0
SERVER TYPE HEALTH SESS WARM REQ PID TOKEN ERROR / CLIENTS
filesystem stdio ok 2 1/1 8 186276,12 - ⇄ Visual Studio Code,Claude Code
github stdio ok 1 - 2 146436 - ⇄ GitHub Copilot
sqlite stdio ok 1 - 2 102108 - ⇄ Cursor
slow-tool stdio ok 1 - 2 103776 - ⇄ Codex CLI
search-api http FAIL×3 0 - 4 - 42m upstream rejected the crede
docs-api http ? 0 - 0 - -
↑↓ select · r recycle · q quit
HEALTH es ok cuando la última solicitud a ese servidor tuvo éxito, FAIL×n después de n fallos consecutivos, y ? cuando nada lo ha llamado todavía — deliberadamente no ok, ya que la ausencia de evidencia no es lo mismo que funcionar. WARM muestra warm/minWarm para servidores agrupados y - para el resto, TOKEN el tiempo restante en una credencial en caché, y la última columna ya sea los clientes conectados o el último error. ↑↓ selecciona una fila y r la recicla.
Lectura de registros duraderos
mcp-pacemaker logs --since 2h --server filesystem
mcp-pacemaker logs --follow --grep timeout
mcp-pacemaker logs --config /path/to/servers.json --since 2026-09-07T12:00:00Z
logs lee bridge.log.1 luego bridge.log junto a la configuración seleccionada, incluso cuando el puente está detenido. --since acepta duraciones en segundos/minutos/horas/días o una marca de tiempo ISO con zona horaria. --server coincide con el nombre exacto del servidor en el encabezado del registro; --grep es una coincidencia literal sin distinción de mayúsculas y minúsculas, no una expresión regular. Los registros multilínea coincidentes conservan su encabezado y contexto.
--follow maneja líneas completas nuevas, escrituras UTF-8 divididas, truncamiento y rotación hasta que se interrumpe. Advierte si la rotación ya ha descartado una generación no leída. Solo la historia retenida está disponible; no puede recuperar registros que el puente ha eliminado. Las líneas individuales de más de 1 MiB fallan explícitamente en lugar de truncarse silenciosamente.
Edición de servers.json mientras se ejecuta
Guarde el archivo y el puente lo recoge. Los servidores cuya definición no cambió se dejan completamente solos — mismos procesos, mismas sesiones en vivo — así que agregar un servidor no le cuesta los catorce que ya estaban funcionando:
$ mcp-pacemaker reload # or just save the file; the bridge watches it
✓ reloaded /Users/you/.mcp-pacemaker/servers.json on :8850
· added: postgres
· changed: github
· 2 session(s) restarted; untouched servers kept theirs
Un archivo que no se analiza, o un servidor sin command ni url, se rechaza por completo — el puente registra el motivo y sigue sirviendo la última configuración buena, por lo que un guardado a medias no puede derribar sus servidores. Establezca MCP_CONFIG_WATCH=0 para requerir un reload explícito en lugar de observar.
Salud del servidor
Cada servidor lleva un veredicto de salud en /api/status, doctor, top y el panel:
| Estado | Significado |
|---|---|
ok | La última solicitud a este servidor tuvo éxito |
failing | Las solicitudes recientes están fallando, con un conteo de cuántas seguidas |
unknown | Nada lo ha llamado todavía |
Esto es pasivo y gratuito — se deriva del tráfico que el puente ya está proxyando. Un error JSON-RPC del servidor cuenta como saludable (respondió); un 401/403, un 5xx, un fallo de spawn o una salida no cero cuenta como fallo, y el estado se limpia en el momento en que una solicitud vuelve a tener éxito.
Un servidor que nadie llama permanece unknown para siempre, lo cual es honesto pero no muy útil si su credencial expira silenciosamente durante la noche. MCP_HEALTH_INTERVAL_MS agrega una sonda periódica para servidores HTTP para que obtengan un veredicto sin esperar a un cliente:
MCP_HEALTH_INTERVAL_MS=300000 mcp-pacemaker start # probe every 5 minutes
Está desactivado por defecto porque una sonda es una solicitud real al servicio de otra persona. Establezca "healthIntervalMinutes": 0 en un servidor para excluir solo ese, o un número para darle su propio intervalo. Los servidores stdio no se sondean: una sonda significaría generar un proceso, lo que cuesta más que la solicitud que se supone debe anticipar.
API HTTP
Todo lo que muestran los paneles es HTTP simple en el mismo puerto de loopback, para que pueda scriptearlo. Los endpoints de lectura no necesitan autenticación; las escrituras administrativas requieren un nonce.
| Endpoint | Método | Devuelve |
|---|---|---|
/status | GET | Sonda de vida diminuta: ok, service, version, port y los nombres de los servidores. Se usa para distinguir un puente pacemaker de un servicio externo en el mismo puerto |
/api/status | GET | Instantánea completa — cada servidor con sesiones, pids, conteo de warm, conteo de solicitudes, health, lastError, clientes conectados |
/api/doctor | GET | Las comprobaciones de salud, como JSON |
/api/events | GET (SSE) | La misma instantánea enviada cada 2s — lo que consume el panel |
/api/logs | GET (SSE) | Registro del puente: reproduce las últimas 100 líneas, luego transmite. Para algo más antiguo, lea bridge.log junto a su configuración |
/admin/recycle/<name> | POST | Reinicia los procesos de un servidor. Omita <name> para reciclar todo |
/admin/reload | POST | Vacía un lote de configuración pendiente, o vuelve a leer un servers.json editado externamente. Solo las definiciones cambiadas se reconfiguran |
/admin/servers/<name>/pooling | POST | Etapa habilitar/deshabilitar o cancelar/deshacer lote con nonce de administración, entrada limitada y una revisión de configuración coincidente |
/<name>/mcp | POST/GET/DELETE | Transporte HTTP transmisible para ese servidor |
/<name>/sse | GET | Transporte HTTP+SSE para ese servidor |
/.well-known/oauth-protected-resource/<name> | GET | Descubrimiento OAuth retransmitido desde el upstream, para servidores HTTP donde el cliente se autentica |
Las mutaciones de agrupación requieren x-mcp-pooling-batch: 1. Un cambio en etapa devuelve HTTP 202 con pending: true, un ID de lote, un recibo privado de cancelar/deshacer y la instantánea pública. La aceptación no es activación. prewarm.batches en la instantánea informa resultados pendientes, aplicándose y completados limitados; no expone tokens de recibo ni configuraciones completas. Los clientes sin el encabezado de lote se rechazan antes de que se ponga en cola un cambio, en lugar de permitir que un cliente más antiguo informe un guardado en cola como ya habilitado. Las instantáneas enriquecidas llevan un snapshotVersion con ámbito de instancia para que una respuesta HTTP retrasada o un marco SSE más antiguo no pueda reemplazar la configuración activa más nueva ni expirar prematuramente un recibo de lote.
# is a server actually running, and who is using it?
curl -s http://127.0.0.1:8850/api/status | jq '.servers[] | {name, sessions, pids, clients}'
# watch the bridge log
curl -N http://127.0.0.1:8850/api/logs
# force a restart of one server (nonce is written next to servers.json)
curl -X POST http://127.0.0.1:8850/admin/recycle/filesystem \
-H "x-mcp-nonce: $(cat ~/.mcp-pacemaker/admin.nonce)"
/admin/* está protegido dos veces: la solicitud debe llegar en loopback, y llevar el nonce que el puente escribe en admin.nonce junto a su configuración al inicio. El nonce es nuevo en cada inicio, por lo que solo las herramientas del mismo equipo que puedan leer ese archivo — la CLI y el panel que el propio puente sirvió — pueden cambiar algo.
servers.json
La configuración vive en ~/.mcp-pacemaker/servers.json. import lo llena desde su configuración de cliente existente y transfiere audience/auth/headers, por lo que los servidores HTTP generalmente no necesitan edición manual. Vea examples/servers.example.json.
{
"filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "."] },
"my-api": {
"type": "http",
"url": "https://my-service.example.com/mcp",
"auth": { "type": "command", "command": "my-cli print-token", "refreshMinutes": 50 }
}
}
Opciones de autenticación (por servidor HTTP):
auth.type | Comportamiento |
|---|---|
command | Ejecuta cualquier comando que imprima un token en stdout; el resultado se almacena en caché y se actualiza automáticamente (refreshMinutes). Agnóstico al proveedor — vea abajo. |
env | Usa process.env[var]. |
static | header fijo + value. |
none | No se agrega ningún encabezado — el cliente se autentica, y el puente retransmite el descubrimiento OAuth y los desafíos para él. |
auth.type: "command" es deliberadamente solo "ejecuta esto y usa lo que imprime", por lo que funciona con lo que sea que emita tokens en su entorno. Algunos ejemplos — ninguno de estos tiene un caso especial:
// Azure
{ "type": "command", "command": "az account get-access-token --resource api://<id> --query accessToken -o tsv" }
// Google Cloud
{ "type": "command", "command": "gcloud auth print-access-token" }
// AWS (e.g. a signed token from your own helper)
{ "type": "command", "command": "aws-token-helper --profile prod" }
// HashiCorp Vault
{ "type": "command", "command": "vault read -field=token secret/my-api" }
// 1Password / any secret manager
{ "type": "command", "command": "op read op://vault/my-api/token" }
// A plain script
{ "type": "command", "command": "./scripts/get-token.sh" }
Por defecto, el token se envía como Authorization: Bearer <token>; establezca header para enviarlo a otro lugar (por ejemplo { "header": "X-Api-Key" }).
Cuánto tiempo se almacena en caché una credencial. Si el comando devuelve un JWT, su reclamo exp decide — refreshMinutes es solo un límite superior y un respaldo para credenciales opacas. Esto importa porque las CLI de tokens sirven desde su propio caché: az account get-access-token devolverá un token que acuñó antes y que puede estar casi agotado, y confiar en una ventana plana mantendría un token muerto en juego. Si el upstream rechaza una credencial que el puente proporcionó, ese 401 se informa en el servidor (doctor, /api/status → lastError) y la credencial se descarta en lugar de reutilizarse — nunca se le pide al cliente que inicie sesión para un servidor que el puente autentica.
Atajo de Azure. Un
"audience": "<res>"desnudo se expande aaz account get-access-token --resource <res> …. Eso es una conveniencia solo para usuarios de Azure — todos los demás proveedores usanauth.commandarriba.
Seguridad
- El puente se vincula solo a
127.0.0.1(loopback local) — no alcanzable fuera del equipo. - Los tokens se acuñan desde su propia CLI ya autenticada y se almacenan en caché en memoria; nunca se escriben en disco.
- El puente (el proceso que se ejecuta 24/7) tiene cero dependencias de terceros; la CLI de configuración usa
commander/@clack/prompts/picocolors/smol-toml, y la TUI agregaink/react.
Controles de múltiples agentes y recursos
Múltiples hosts/agentes pueden compartir un puente — cada uno obtiene su propia sesión aislada por defecto, y los servidores HTTP comparten el token en caché entre todos ellos. El panel, top y mcp-pacemaker status muestran qué agentes están conectados a cada servidor.
| Control | Env / config | Default | Effect |
|---|---|---|---|
| Recolector inactivo | MCP_IDLE_TIMEOUT_MS | 1800000 (30 min) | libera hijos de Streamable HTTP inactivos más allá del tiempo de espera. Seguro por defecto porque la sesión de un cliente que regresa se restablece de forma transparente. 0 lo desactiva |
| Límite de concurrencia | MCP_MAX_SESSIONS_PER_SERVER, o por servidor maxSessions | 0 (ilimitado) | rechaza nuevas sesiones más allá del límite (HTTP 503) |
| Cola en el límite | MCP_QUEUE_TIMEOUT_MS | 10000 (10s) | en el límite, espera este tiempo por un espacio antes de devolver 503, para que una ráfaga se absorba en lugar de fallar. 0 rechaza inmediatamente |
| Política de uso compartido | por servidor sharing (+ minWarm) | isolated | isolated = un hijo por sesión; pool pre-inicia hijos exclusivos; shared reutiliza un hijo inicializado para sesiones compatibles de herramientas sin estado. Ambas alternativas requieren activación explícita |
| Puerta de arranque en frío | MCP_MAX_CONCURRENT_SPAWNS, MCP_SPAWN_GATE_WAIT_MS | 2, 15000 | cuántos servidores respaldados por gestores de paquetes pueden arrancar en frío a la vez. npx, uvx, dnx y similares comparten una caché, y arrancar varios juntos puede corromperla — esto los pone en cola. Se detecta desde el comando, o se fuerza de cualquier manera con sharedPackageCache por servidor. Los servidores que no usan gestor de paquetes nunca se limitan. Si no se libera un espacio dentro de la espera, el arranque procede sin limitación en lugar de retener una solicitud de cliente. 0 lo desactiva |
| Consejo de agrupación | MCP_POOL_ADVICE_MS, MCP_WARM_MAX | 2s, 8 | recomienda agrupar una vez que el arranque en frío medido de un servidor supere esto, y limita el grupo sugerido (y de tamaño automático) aquí. Solo consejo — el puente nunca habilita la agrupación por sí solo |
| Reanudación de sesión | MCP_RESUME, MCP_RESUME_TTL_MS | activado, 24h | restablece un ID de sesión que el puente no ha visto — después de un reinicio, reciclaje o recolección inactiva. MCP_RESUME=0 lo desactiva |
| Reciclaje programado | por servidor recycleMinutes, o MCP_RECYCLE_MINUTES | desactivado | reinicia un servidor periódicamente, para servidores que mantienen una credencial que solo pueden renovar interactivamente |
| Tiempos de espera de solicitud | MCP_REQUEST_TIMEOUT_MS / MCP_INIT_TIMEOUT_MS | 30s / 180s | initialize también cubre el arranque del servidor, por lo que obtiene un presupuesto más largo que las llamadas ordinarias |
| Renovación de credenciales | MCP_TOKEN_REFRESH_LEAD_MS | 300000 (5 min) | renueva un token en caché antes de que expire en lugar de descubrir la expiración en una solicitud. El propio exp de un JWT aún limita cuánto tiempo se almacena en caché |
| Registro duradero | MCP_LOG_MAX_BYTES | 5242880 (5 MB) | bridge.log junto a tu configuración, rotado a bridge.log.1 en este tamaño. 0 lo desactiva. El panel solo mantiene las últimas cientos de líneas en memoria, que un cliente hablador llena en minutos |
| Vigilancia de configuración | MCP_CONFIG_WATCH | activado | recarga servers.json cuando se guarda. 0 requiere un mcp-pacemaker reload explícito. De cualquier manera, solo se reinician los servidores cuya definición cambió, y un archivo no analizable se rechaza sin perturbar nada |
| Sondeo de salud | MCP_HEALTH_INTERVAL_MS, o por servidor healthIntervalMinutes | desactivado | llama periódicamente a un servidor HTTP para que tenga un veredicto de salud antes de que un cliente lo necesite. La salud pasiva del tráfico real siempre está activa y no cuesta nada |
Medición del cambio de procesos
Para servidores stdio, /api/status informa spawn.total (lanzamientos de procesos exitosos),
spawn.attempts, spawn.failures, spawn.warmAdoptions, spawn.sessionStarts, y
spawn.sessionResumes. Los lanzamientos incluyen SSE clásico, Streamable HTTP, reabastecimiento del grupo cálido,
y reemplazos después de reciclaje o reanudación. Adoptar un hijo cálido existente no cuenta
como otro lanzamiento. La unidad es un proceso lanzado por el puente, no todos sus descendientes.
Estos contadores acumulativos no comparten el límite de latencia de 50 muestras. Se restablecen cuando el
proceso del puente se reinicia; compara instantáneas solo dentro del mismo instanceId. startedAt
identifica ese intervalo. Guarda la instantánea final antes de un reinicio planificado para una comparación
antes/después. Los servidores proxy HTTP no tienen contadores de procesos locales (spawn: null).
spawn.samples y p50/p95/max aún describen las últimas 50 inicializaciones en frío exitosas directamente observadas,
no todos los lanzamientos. Las latencias son null hasta que se observan; la vida inactiva de un hijo cálido
no es una muestra de arranque en frío. El recuento existente de requests cubre solicitudes HTTP enrutadas,
no solo tools/call; no lo etiquetes como un recuento de llamadas a herramientas.
Modo compartido
Establece "sharing": "shared" en un servidor stdio solo cuando sus herramientas no tienen estado, operan con
entradas explícitas y usan un contexto de credenciales común. Esto es una afirmación del operador, no
algo que la latencia o las capacidades de coincidencia puedan probar. Deja aislados los servidores que dependen
del espacio de trabajo, la conversación o la cuenta del cliente.
Las sesiones compatibles tienen parámetros de inicialización completos idénticos, incluido clientInfo,
y capacidades de cliente vacías. Un hijo recibe una inicialización real; cada sesión virtual
obtiene sus propios IDs, progreso, cancelación y cursores de listas de herramientas. Solo se expone la capacidad
real de herramientas del upstream. Raíces, muestreo, elicitación, tareas, suscripciones de recursos y
otros métodos con estado no son compatibles. Los clientes incompatibles fallan explícitamente, sin
volver silenciosamente a un modo diferente.
Eliminar una sesión deja las demás en ejecución. El hijo inicializado se retiene entre
reconexiones compatibles hasta sharedLingerMs (30 minutos por defecto). El reciclaje drena el trabajo,
luego reemplaza la generación en uso posterior. Un tiempo de espera o salida del hijo nunca activa automáticamente
la reproducción de una llamada a herramienta potencialmente ejecutada.
El servidor mantiene su proveedor de credenciales existente y el recycleMinutes configurado. El modo
compartido no promete renovación silenciosa de credenciales. El panel y la CLI de prewarm muestran el
estado real del hijo compartido, miembros, trabajo en cola y lanzamientos de procesos acumulativos.
Consulta el contrato de sesión compartida para límites y semántica de fallos.
Desinstalación
mcp-pacemaker uninstall # use the CLI from the matching installed version
Esto detiene los puentes gestionados, elimina las entradas de inicio automático y restaura las copias de seguridad
disponibles de archivos de host. Deja archivos sin copias de seguridad y registros nativos de Claude Code sin cambios.
No está limitado a un puerto; revisa reemplazo y reversión
primero si otra instancia debe permanecer en ejecución. No descargues una CLI diferente con npx
para eliminar una instalación existente.
Después de que el servicio instalado se haya eliminado correctamente, elimina el paquete npm global:
npm uninstall -g mcp-pacemaker
Proyecto
- CHANGELOG.md — notas de versión
- CONTRIBUTING.md — configuración de desarrollo y cómo se espera que se demuestren las pruebas de regresión
- SECURITY.md — modelo de amenazas y cómo informar una vulnerabilidad
Licencia
MIT © Girish Konda