# mcp-drift-monitor: detección continua de cambios no autorizados en servidores MCP

> Source: <https://dev.to/magopredator/mcp-drift-monitor-deteccion-continua-de-cambios-no-autorizados-en-servidores-mcp-f8>
> Published: 2026-08-23 00:35:55+00:00

mcp-drift-monitordetecta 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.

[arXiv:2608.00997](https://arxiv.org/abs/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:

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.

`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.

```
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
```

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](https://github.com/amurlaniakea/mcp-drift-monitor).

```
docker run -v mcp-data:/app/data --name drift-monitor-prod -d \
  amurlaniakea/mcp-drift-monitor:latest sweep
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]"
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 paperEl 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.

AGPL-3.0-or-later. SPDX-FileCopyrightText: 2026 Pedro Sordo Martínez.

`amurlaniakea/mcp-drift-monitor`

*Licencia: AGPL-3.0-or-later*
