tracking
MCP Tracking
Servidor MCP de seguimiento en tiempo real con dashboard de terminal. Permite a Claude/Lyra rastrear cualquier operación larga Y alimenta automáticamente las sesiones desde el media-server (qBittorrent, Bazarr, conversión DV).
Sumario
Related MCP server: Claude Session MCP
Arquitectura
MCP/tracking/
server.py -- Serveur MCP (outils Claude/Lyra) + point d'entree --ui / --test
api.py -- API HTTP locale (127.0.0.1:8765) pour les scripts externes
mutations.py -- Mutations d'une session, partagees par api.py ET server.py
(horodatage items, historique, niveaux de log, auto-completion)
metrics.py -- Metriques derivees (vitesse, ETA, ecoule, stale) -- logique pure,
calculees a la lecture, jamais stockees
storage.py -- Persistence JSON atomique + verrou fichier + cache mtime + purge TTL
models.py -- Modeles pydantic (TrackingSession, TrackingItem, LogEntry, ProgressPoint)
templates.py -- Templates builtin + templates utilisateur (JSON)
ui.py -- Dashboard Textual (TUI temps reel) + modales stop/kill
sim.py -- Simulations de demo (server.py --test)
poller.py -- Daemon polling qBittorrent (10s) + Bazarr (60s)
tracking-api.service -- Unite systemd (systeme) pour api.py
tracking-poller.service -- Unite systemd (systeme) pour poller.py
install.sh / deploy.sh -- Installation initiale / redeploiement des services
Makefile -- make test | smoke | deploy | ui
tests/ -- unitaires (storage, metrics) + integration/ (API HTTP reelle)Archivos de estado y configuración
Archivo | Ubicación | Anulación |
|
|
|
|
|
|
|
|
|
| junto al código, gitignore | -- |
Un tracking_state.json antiguo junto al código se migra automáticamente en el primer
arranque (copia, nunca se elimina).
Variables de entorno de retención:
Variable | Valor predeterminado | Función |
| 7 | Purga de sesiones done / error / paused |
| 24 | Purga de sesiones running huérfanas (sin actualizaciones posteriores) |
Flujo de datos completo
Claude/Lyra (outils MCP)
|
v
server.py ─────────────────────────────────────────┐
|
qBittorrent API (poll 10s) |
| |
Bazarr API (poll 60s) ──> poller.py ──> api.py ──> mutations.py ──> storage.py ──> ~/.local/state/tracking/tracking_state.json
| | |
dv_webhook_server.py | v
| | ui.py
v | (rafraichit chaque seconde)
dv_convert.py ──────────────────────────────────────>
(metriques temps reel ffmpeg/dovi_tool)El archivo de estado se escribe en cada modificación mediante escritura atómica (os.replace) bajo un bloqueo
de archivo (tracking_state.lock). Todos los procesos (MCP, API, poller, dashboard) comparten este
único archivo; cada lectura verifica el mtime para invalidar su caché.
Toda mutación (HTTP o MCP) pasa por mutations.py, que garantiza el mismo comportamiento en ambas
rutas: started_at / finished_at establecidos en los elementos y la sesión, historial de
progreso (ventana deslizante de 40 puntos), niveles de log info / warn / error,
autocompletado cuando todos los elementos están terminados.
Métricas derivadas
GET /sessions y tracking_get devuelven un bloque metrics calculado sobre la marcha por metrics.py:
Campo | Significado |
| progreso (limitado a 100) |
| velocidad en los últimos 120 segundos ( |
| tiempo restante estimado (solo sesión running) |
| desde |
|
|
Instalación
cd /home/amineutron/dev/MCP/tracking
# Creer le venv et installer les dependances
uv venv .venv
uv pip install "mcp[cli]>=1.0.0" "pydantic>=2.0" "textual>=0.80.0" "fastapi"El MCP está registrado en Claude Code (ámbito de usuario):
claude mcp list # -> tracking: ConnectedPara volver a registrarlo:
claude mcp add tracking -s user -- \
/home/amineutron/dev/MCP/tracking/.venv/bin/python \
/home/amineutron/dev/MCP/tracking/server.pyServicios systemd
Dos servicios systemd se ejecutan permanentemente y se inician al arranque:
Servicio | Rol | Puerto |
| API HTTP local para scripts externos | 127.0.0.1:8765 |
| Sondeo de qBittorrent (10s) + Bazarr (60s) | -- |
Instalación inicial y redespliegue
cd /home/amineutron/dev/MCP/tracking
./install.sh # premiere fois : venv + services (demande sudo)
sudo ./deploy.sh # apres chaque mise a jour du code : stop, unites, restart, verif
make smoke # sante rapideLas instancias MCP server.py ya abiertas por las sesiones de Claude Code no se
reinician con deploy.sh: vuelve a conectar tracking mediante /mcp en esas sesiones.
Comandos útiles
# Etat
systemctl status tracking-api.service tracking-poller.service
# Logs en direct
journalctl -fu tracking-poller.service
journalctl -fu tracking-api.service
# Redemarrage
sudo systemctl restart tracking-api.service tracking-poller.service
# Test API
curl http://127.0.0.1:8765/health
curl http://127.0.0.1:8765/sessionsLanzamiento
Dashboard (acceso directo de wofi)
Busca "MCP Tracking" en wofi/launcher. Inicia el dashboard en Kitty.
Dashboard (terminal)
# Toutes les sessions
/home/amineutron/dev/MCP/tracking/.venv/bin/python \
/home/amineutron/dev/MCP/tracking/server.py --ui
# Filtre direct au lancement
.venv/bin/python server.py --ui --filter download
.venv/bin/python server.py --ui --filter movie
.venv/bin/python server.py --ui --filter errorsMediante la herramienta MCP (desde Claude/Lyra)
open_tracking_ui() # toutes les sessions
open_tracking_ui(filter_template="lyra_task") # vue Lyra uniquement
open_tracking_ui(filter_template="errors") # erreurs uniquementModo de prueba (demo)
.venv/bin/python server.py --testSimula 4 sesiones en paralelo: download, machine (12 nodos), free, movie (pipeline DV completo).
Dashboard
Diseño de una sesión
[TEMPLATE] Nom de la session id:xxxxxxxx (status)
[=============> ] 54.2% 27100 MB / 50000 MB
champ_extra1: valeur | champ_extra2: valeur
[ok] item-1 100.0 GB -- termine
[>] item-2 frame: 94231 / 172800 (54.5%) speed: 3.2x
[ ] item-3 --
[!] item-4 erreur detail
Logs Erreurs
14:32:01 Message log 1 [!] item-4
14:32:04 Message log 2 14:32:08 ECHEC: details
14:32:07 Message log 3 --
-- --
-- --Iconos de elementos
Icono | Estado | Color |
| pending | gris |
| running | cian |
| done | verde |
| error | rojo |
Colores de sesión
Color | Estado |
cian | running |
verde | done |
rojo | error |
amarillo | paused |
Atajos de teclado
Tecla | Acción |
| Siguiente filtro (ciclo dinámico por plantilla) |
| Alternar filtro solo errores |
| Refresco manual |
| Detención limpia de una sesión (introducir el ID) -> estado paused |
| Kill forzado de una sesión (introducir el ID) -> eliminación |
| Salir |
Flechas / Rueda | Desplazamiento |
Modales de stop/kill
Pulsar s o k abre un modal con un campo de entrada para el ID de sesión.
smarca la sesión comopausedy añade un logkelimina definitivamente la sesión del dashboardEchapcancela
Filtrado dinámico
El ciclo de filtros se construye automáticamente a partir de las sesiones presentes:
all -> download -> free -> movie -> lyra_task -> errors -> all -> ...allsiempre presenteCada plantilla presente en el JSON se añade automáticamente
errorssolo aparece si al menos una sesión tiene un errorFiltro activo mostrado en el subtítulo:
filtre: movie | 2/5 session(s)Si la plantilla filtrada desaparece del JSON, retorno automático a
all
Integración media-server
qBittorrent (automático)
El poller consulta http://localhost:8080/api/v2/torrents/info cada 10 segundos.
Un torrent activo = una sesión
[DOWNLOAD]con nombre, tamaño, velocidad, ETALa sesión se elimina automáticamente cuando el torrent termina o desaparece
Credenciales:
credentials/qbt-password.cred(cifradas consystemd-creds --user, generadas pormedia-server/scripts/secrets/rotate-secrets.sh)
Subtítulos faltantes de Bazarr (automático)
El poller consulta la API de Bazarr cada 60 segundos.
Una sesión
[SUBTITLES]única lista todos los episodios/películas sin subtítulos FREl título de la sesión indica el total:
Sous-titres manquants (151)Los 50 primeros archivos faltantes se listan como elementos
API key de Bazarr:
credentials/bazarr-api-key.cred(mismo mecanismo). Sin credencial, el sondeo correspondiente simplemente se desactiva.
Conversión Dolby Vision (automática)
Desencadenado por dv-webhook.service cuando Radarr/Sonarr importan una película DV Profile 4 o 7.
Flujo:
Radarr/Sonarr import
|
v
dv_webhook_server.py (port 8787)
|-- cree session tracking via api.py
|-- passe DV_TRACKING_SESSION_ID en env
v
dv_convert.py
|-- 6 etapes avec metriques temps reel
|-- ffmpeg : frame / speed / size / time (parse stderr)
|-- dovi_tool: frames X/Y ou X% (parse stderr indicatif)
v
session tracking completee ou en erreurLas 6 etapas rastreadas con sus métricas:
Etapa | Herramienta | Métricas mostradas |
1/6 extracción HEVC | ffmpeg | frame / speed / size / time |
2/6 demux BL/EL | dovi_tool | frames X/Y (%), bl: X GB, el: X GB |
3/6 extracción RPU + conv P8 | dovi_tool | frames X/Y (%), RPU: X KB |
4/6 inyección RPU P8 en BL | dovi_tool | frames X/Y (%), P8 HEVC: X GB |
5/6 reconstrucción de timestamps | ffmpeg | frame / fps / size |
6/6 remuxado MKV final | ffmpeg | frame / speed / size |
La barra de progreso global avanza de forma continua durante cada etapa (no a saltos de 1/6 al final de cada etapa).
Modo manual:
# Fichier unique
python /home/amineutron/dev/media-server/scripts/dv_convert.py /chemin/film.mkv
# Scan dossier
python /home/amineutron/dev/media-server/scripts/dv_convert.py --scan /mnt/media/media/moviesEn modo manual, la sesión de tracking se crea automáticamente en process_file.
API HTTP local (puerto 8765)
Los scripts externos pueden crear/modificar sesiones directamente:
# Creer une session
curl -X POST http://127.0.0.1:8765/sessions \
-H "Content-Type: application/json" \
-d '{"name":"Mon operation","template":"free","total":100,"unit":"%"}'
# -> {"id": "a1b2c3d4"}
# Mettre a jour
curl -X PUT http://127.0.0.1:8765/sessions/a1b2c3d4 \
-H "Content-Type: application/json" \
-d '{"processed":45,"log":"Etape 2/5 en cours","extra":{"phase":"etape 2"}}'
# Mettre a jour un item
curl -X PUT http://127.0.0.1:8765/sessions/a1b2c3d4 \
-H "Content-Type: application/json" \
-d '{"item":{"name":"mon-item","status":"done","note":"100 frames speed: 2x"}}'
# Supprimer
curl -X DELETE http://127.0.0.1:8765/sessions/a1b2c3d4
# Lister
curl http://127.0.0.1:8765/sessionsCuerpo PUT completo (todos los campos opcionales):
{
"processed": 45.0,
"total": 100.0,
"status": "running",
"extra": {"phase": "etape 2"},
"log": "message de log",
"item": {
"name": "nom-de-l-item",
"status": "running",
"note": "metriques ici",
"processed": 50.0,
"total": 100.0
}
}Herramientas MCP
tracking_create
Parametres:
name (str) Nom de la session
template (str) "download" | "machine" | "free" | "movie" | "lyra_task" |
"subtitles" | "series_episode" | "series_season" | template utilisateur
total (float) Valeur totale
unit (str, opt) Unite affichee (ex: " MB", " machines", "%")
items (list, opt) Liste d'elements a suivre
extra (dict, opt) Champs specifiques au template
Format items:
[{"name": "fichier.iso", "total": 5100, "unit": " MB", "note": "info"}]
Retourne: ID de session + etat initial formatetracking_update
Parametres:
session_id (str) ID de la session
processed (float, opt) Nouvelle valeur de progression
message (str, opt) Message de log
item_updates (list, opt) Mises a jour des items
extra (dict, opt) Champs extra a merger
Format item_updates:
[{"name": "item-1", "status": "done", "processed": 1200, "note": "detail"}]
Status: "pending" | "running" | "done" | "error"tracking_log
Añade un log sin modificar la progresión.
Parametres:
session_id (str)
message (str)tracking_complete
Marca done al 100%.
Parametres:
session_id (str)
message (str, opt)tracking_error
Marca en error (prefijo "ERREUR:" automático, aparece en la columna Errores).
Parametres:
session_id (str)
message (str)tracking_stop
Detiene limpiamente una sesión (estado -> paused). Permanece visible en el dashboard.
Parametres:
session_id (str)
message (str, opt)tracking_kill
Elimina una sesión por la fuerza. Desaparece inmediatamente del dashboard.
Parametres:
session_id (str)tracking_get
Devuelve el estado completo formateado de una sesión.
tracking_list
Parametres:
template (str, opt) Filtrer par template
status (str, opt) Filtrer par statut ("running", "done", "error", "paused")tracking_delete
Elimina una sesión (equivalente a tracking_kill).
tracking_templates
Muestra la lista de plantillas y sus campos.
open_tracking_ui
Abre el dashboard en un terminal Kitty.
Parametres:
filter_template (str, opt) Template a afficher au lancementPlantillas
download
Descarga de archivos. Alimentado automáticamente por qBittorrent a través del poller.
Champs extra : speed, eta
Unite par defaut : MBmachine
Operaciones en máquinas (update, clone, snapshot, deploy). Utilizado por Lyra para las operaciones VM/cluster.
Champs extra : operation, target
Unite par defaut : machinesfree
Formato libre. Utilizado por el poller para los subtítulos faltantes de Bazarr.
Aucun champ extra impose, aucune unite par defaut.lyra_task
Operaciones de Lyra (VM clone, backup, update, snapshot).
Champs extra : operation, target, phase, eta
Unite par defaut : %movie
Pipeline completo de una película: descarga -> conversión Dolby Vision. Alimentado automáticamente por dv_convert.py cuando Radarr/Sonarr importan un archivo DV P4/P7.
Champs extra : phase, quality, codec, audio, source, dv, speed, eta
Unite par defaut : %
Les 6 etapes DV trackees avec metriques temps reel :
"1/6 extraction HEVC"
"2/6 demux BL/EL"
"3/6 extraction RPU + conv P8"
"4/6 injection RPU P8 dans BL"
"5/6 reconstruction timestamps"
"6/6 remuxage MKV final"Seguridad
api.pyescucha únicamente en127.0.0.1:8765-- inaccesible desde la redn8n restringido a
127.0.0.1:5678endocker-compose.ymldv_webhook_server.pyescucha en0.0.0.0:8787(necesario para recibir los webhooks de Docker) -- proteger este puerto con un firewall si la máquina está expuestaLos servicios systemd se ejecutan con
NoNewPrivileges=trueNingún secreto en claro en el código:
poller.pylee$CREDENTIALS_DIRECTORY(servicio de usuario) o descifracredentials/*.credmediantesystemd-creds decrypt --user(servicio de sistema), con respaldo a las variablesQBT_PASSWORD/BAZARR_KEYpara el debug
Añadir una plantilla
Abrir
templates.pyy añadir una entrada enTEMPLATES:
"mon_template": {
"description": "Description courte",
"extra_fields": ["champ1", "champ2"],
"default_unit": " unites",
"example_extra": {"champ1": "valeur", "champ2": "valeur"},
},Opcional: añadir una simulación
_sim_mon_template()ensim.py.
La plantilla está disponible inmediatamente sin ninguna otra modificación.
Sin tocar el código, una plantilla también puede declararse en ~/.config/tracking/templates.json
(misma estructura, clave = nombre de la plantilla); se carga al inicio.
Pruebas
make test # unitaires (storage, metrics) + integration (API HTTP reelle sur port ephemere)La fixture autouse de conftest.py redirige la persistencia hacia un tmp_path: los tests nunca
tocan el estado de producción.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseBqualityCmaintenanceEnables Claude to coordinate multiple specialized AI agents by creating tasks, tracking their complete thought process and execution in real-time, and monitoring progress across parallel workflows with full transparency.18172MIT
- AlicenseAqualityDmaintenanceProvides Claude Code with programmatic session awareness to track context usage, session history, and task progress. It enables intelligent context reset recommendations and automatic synchronization of project planning documentation.5MIT
- AlicenseNot gradedqualityDmaintenanceA comprehensive project management and workflow tracking system that integrates with Claude Code via MCP, automatically capturing sessions, tools, agents, and project tasks into a centralized dashboard and database.20MIT
- FlicenseNot gradedqualityDmaintenanceA comprehensive MCP server for monitoring Claude Code sessions, agent performance, cost tracking, project management, and GitHub synchronization with 89 tools and a real-time dashboard.
Related MCP Connectors
Uptime, SSL, DNS and domain monitoring you can talk to from Claude or any MCP client.
Let your AI sessions talk to each other — messaging, tasks, sessions, and alerts
AI agent run monitoring with incident replay and SLA receipts.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/marouabah/mcp-tracking'
If you have feedback or need assistance with the MCP directory API, please join our Discord server