mcp-drift-monitor detecta cambios no autorizados en servidores MCP (Model Context Protocol). Implementa el control primario faltante descrito en arXiv:2608.00997: un barrido completo periódico del catálogo que re-descarga todos los servidores y recomputa hashes.
Problema
arXiv:2608.00997 (MCP Registry Drift: A 88.6-Day Measurement of 19,099 Servers) reporta un punto ciego crítico: los enfoques tradicionales de detección de cambios fallan en identificar dos modos de fallo:
- Cambios silenciosos — un servidor cuyo hash de descripción cambia, pero el monitor ya lo conocía y lo rankinga por historial pasado.
- Nuevas adiciones — servidores que aparecen en el registro sin que el monitor tenga registro previo.
El paper mide 15,845 eventos de cambio, 19,877 adiciones y 911 eliminaciones, pero los modelos que rankean por historial previo pierden una fracción significativa de estos eventos.
Este monitor cierra esa brecha con el control primario que el paper propone pero no implementa: un full-catalog sweep periódico.
Solución
mcp-drift-monitor implementa un motor de diferencias único (compute_events) que sirve tanto para polling incremental como para barridos completos. No hay lógica duplicada.
Cada vez que un hash de descripción cambia, el motor revalida el contenido (len(drifts) > 0 es el único disparador). Si el registro responde 429, aplica backoff con Retry-After. Si el payload está malformado, lanza SchemaDriftError y registra el payload ofensor a nivel ERROR.
Arquitectura
core/
diff.py — CatalogEntry, DriftEvent, NewArrivalEvent, RemovalEvent, compute_events
hasher.py — normalize_description (NFC), hash_description
state.py — StateStore (sqlite), FetchStatus, removed flag, get_all_hashes
poller.py — Poller.fetch_catalog, PollConfig, SchemaDriftError, backoff
sweep.py — run_sweep (control primario), SweepReport
calibrate.py — replay (FR-6), ReplayReport, external validity vs panel
Resultados de calibración
El monitor se calibró y verificó contra el panel real del paper (19,099 servidores observados durante 88.6 días). Resultados:
| Evento del panel | Recuento | compute_events (neto) |
|---|---|---|
add |
19,877 | 16,367 + 3,510 seed = 19,877 |
chg |
15,845 | 2,514 drift netos (<= chg) |
del |
911 | 911 eliminaciones |
arrival_events == add_count y removal_events == del_count se cumplen porque ningún servidor es eliminado y re-agregado dentro del mismo intervalo inter-snapshot (0 violaciones de precondición).
Más detalles de la metodología de calibración en el README del repositorio.
Cómo usarlo
Con Docker
docker run -v mcp-data:/app/data --name drift-monitor-prod -d \
amurlaniakea/mcp-drift-monitor:latest sweep
Como librería
git clone https://github.com/amurlaniakea/mcp-drift-monitor.git
cd mcp-drift-monitor
python -m venv .venv && source .venv/bin/activate
pip install -e ".[test]"
Tests
ruff check mcp_drift_monitor tests && pytest -v
Suit de tests:
-
tests/test_diff.py— motor de diferencias (determinismo, orden, disjunción de eventos) -
tests/test_hasher.py— normalización NFC + casos límite de hashing -
tests/test_poller.py— backoff 429, agotamiento de reintentos, registro de desviaciones de esquema -
tests/test_state.py— persistencia de StateStore, flag eliminado, dataclass fuente única -
tests/test_sweep.py— control primario de barrido completo (nueva adición, cambio silencioso) -
tests/test_replay_panel.py— [EXTERNAL-VALIDITY] AC-1/2/3 contra el panel real del paper
CI/CD
El repositorio incluye GitHub Actions que ejecutan ruff + pytest en cada PR, y construyen imágenes multi-platforma (amd64/arm64) a GHCR y DockerHub en cada release.
Licencia
AGPL-3.0-or-later. SPDX-FileCopyrightText: 2026 Pedro Sordo Martínez.
Links
- Paper: arXiv:2608.00997
- Repo: github.com/amurlaniakea/mcp-drift-monitor
-
Docker Hub:
amurlaniakea/mcp-drift-monitor
Licencia: AGPL-3.0-or-later
Top comments (0)