Skip to main content
Glama
marouabah

tracking

by marouabah

MCP Tracking

MCP-сервер отслеживания в реальном времени с терминальным дашбордом. Позволяет Claude/Lyra отслеживать любую длительную операцию и автоматически наполнят сессии из media-server (qBittorrent, Bazarr, конвертация DV).


Содержание


Related MCP server: Claude Session MCP

Архитектура

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)

Файлы состояния и конфигурации

Файл

Расположение

Переопределение

tracking_state.json

~/.local/state/tracking/

TRACKING_STATE_DIR

poller_state.json

~/.local/state/tracking/

TRACKING_STATE_DIR

templates.json (пользовтельские шаблоны, необязательно)

~/.config/tracking/

TRACKING_TEMPLATES_FILE

credentials/*.cred (qBittorrent, Bazarr)

рядом с кодом, gitignore

--

Старый tracking_state.json рядом с кодом автоматически переносится при первом запуске (копируеся, никогдa не удаляеся).

Переменные окружения срока храения:

Переменная

По умолчанию

Роль

TRACKING_TL_DAYS

7

Очистка сессий done / error / paused

TRACKING_TL_RUNNING_H

24

Очистка осиротевших running-сессий (больше не обновляемых)

Полный оток данных

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)

Файл состояния записывается при каждом изменени через атомарную запись (os.replace) под файловой блокировкой (tracking_state.lock). Все процессы (MCP, API, poller, dashboard) используют этот единственный файл; каждое чтение проверяет mtime для инвалидации своео кэша.

Любая мутация (HTTP или MCP) проходи через mutations.py, которая гарантируеет одинаковое поведение на обои путях: started_at / finished_at устанавливаются на элементах и сессии, история прогресса (скользящее окно из 40 точе), уровни логов info / warn / error, автоматическое завершение, когда все элементы выполнены.

Производные метрики

GET /sessions и tracking_get возвращают блок metrics, вычисляемый на лету в metrics.py:

Полe

Значение

percent

прогресс (ограничен 100)

rate, rate_str

скорсть за последие 120 секунд (2.0 MB/s, 30.0 u/min)

eta_seconds, eta_str

оценочное оставшееся время (только для running-сессий)

elapsed_seconds, elapsed_str

с created_at до finished_at или до текущего момента

idle_seconds, stale

stale = running без обновлений в течение 10 мин (отображается в TUI)


Установка

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"

MCP зарегистрирован в Claude Code (scope user):

claude mcp list        # -> tracking: Connected

Чтобы перерегистрировать:

claude mcp add tracking -s user -- \
  /home/amineutron/dev/MCP/tracking/.venv/bin/python \
  /home/amineutron/dev/MCP/tracking/server.py

Службы systemd

Две службы работают постоянно и запускаются при загрузке:

Служба

Роль

Порт

tracking-api.service

Локальный HTTP API для внешних скриптов

127.0.0.1:8765

tracking-poller.service

Опрос qBittorrent (10s) + Bazarr (60s)

--

Первичная установка и повторное развертывание

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 rapide

Инстансы MCP server.py, уже открытые сессиями Claude Code, не перезапускаются deploy.sh: переподключите tracking через /mcp в этих сессиях.

Полезные команды

# 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/sessions

Запуск

Дашборд (ярлык wofi)

Ищите «MCP Tracking» в wofi/launcher. Запустите дашборд в Kiry.

Дашборд (терминал)

# 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 errors

Через инструмент MCP (из 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 uniquement

Тестовый режим (демо)

.venv/bin/python server.py --test

Имитируе 4 параллельные сессии: download, machine (12 узлов), free, movie (полный конвейер DV).


Дашборд

Макет сессии

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

Иконки элементов

Иконка

Статус

Цвет

[ ]

pending

серый

[>]

running

циан

[ok]

done

зелёный

[!]

error

красный

Цвета сессии

Цвет

Статус

циан

running

зелёный

done

красный

error

жёлтый

paused

Горячие клавиши

Клавиша

Действие

f

Следующий фильтр (динамический цикл по шаблону)

e

Переключить фильтр «только ошибки»

r

Ручное обновление

s

Чистая остановка сессии (ввести ID) -> статус paused

k

Принудительное завершение (kill) сессии (ввести ID) -> удаление

q

Выйти

Стрелки / Колесо

Прокрутка

Модальные окна stop/kill

Нажмите s или k, чтобы открыть модальное окно с полем ввода ID сессии.

  • s помечает сессию как paused и добавляет лог

  • k окончательно удаляет сессию из дашборда

  • Echap отменяет

Динамическая фильтрация

Цикл фильтров автоматически строится из присутствующих сессий:

all -> download -> free -> movie -> lyra_task -> errors -> all -> ...
  • all всегда присутствует

  • Каждый шаблон, присутствующий в JSON, добавляется автоматически

  • errors появляется, только если хотя бы одна сессия имеет ошибку

  • Активный фильтр отображается в подзаголовке: filtre: movie | 2/5 session(s)

  • Если отфильтрованный шаблон исчезает из JSON, автоматический возврат к all


Интеграция media-server

qBittorrent (автоматически)

Пойлер опрашивает http://localhost:8080/api/v2/torrents/info каждые 10 секунд.

  • Активный торрент = сессия [DOWNLOAD] с именем, размером, скоростью, ETA

  • Сессия автоматически удаляется, когда торрент завершается или исчезает

  • Учетные данные: credentials/qbt-password.cred (зашифровано с помощью systemd-creds --user, сгенерировано media-server/scripts/secrets/rotate-secrets.sh)

Bazarr отсуствующие субтитры (автоматически)

Пойлер опрашивает API Bazarr каждые 60 секунд.

  • Единая сессия [SUBTITLES] перечисляе все эпизоды/фильмы без субтитров FR

  • В заголовке сессии указывется обще количество: Sous-titres manquants (151)

  • Первые 50 отсуствующих файлов перечислены как элементы

  • API-ключ Bazarr: credentials/bazarr-api-key.cred (тот же механизм). Без учетных данных соответствующий пойлер просто отключается.

Конвертация Dolby Vision (автоматически)

Запускается dv-webhook.service, когда Radarr/Sonarr импортируют фильм DV Profile 4 или 7.

Поток:

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 erreur

6 отслеживаемых этапов с их метриками:

Этап

Инструмент

Отображаемые метрики

1/6 извлечение HEVC

ffmpeg

frame / speed / size / time

2/6 демукс BL/EL

dovi_tool

frames X/Y (%), bl: X GB, el: X GB

3/6 извлечение RPU + конвертация P8

dovi_tool

frames X/Y (%), RPU: X KB

4/6 внедрение RPU P8 в BL

dovi_tool

frames X/Y (%), P8 HEVC: X GB

5/6 восставление временых меток

ffmpeg

frame / fps / size

6/6 финальный ремукс MKV

ffmpeg

frame / speed / size

Общая полоса прогресса движеся непрерывно на протяжении каждо этапа (а не скачками по 1/6 в конце каждо этапа).

Ручной режим:

# 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/movies

В ручном режиме tracking-сессия создаеся автоматически в process_file.

Локальный HTTP API (порт 8765)

Внешние скрипты могут создавать/изменять сессии напрямую:

# 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/sessions

Полное тело PUT (все поля необязательны):

{
  "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
  }
}

Инструменты 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 formate

tracking_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

Добавляет запись в лог без изменения прогресса.

Parametres:
  session_id  (str)
  message     (str)

tracking_complete

Помечае как done на 100%.

Parametres:
  session_id  (str)
  message     (str, opt)

tracking_error

Помечае как ошибу (автоматический префикс «ERREUR:», отображеся в колонке «Ошики»).

Parametres:
  session_id  (str)
  message     (str)

tracking_stop

Чисто останавливает сессию (status -> paused). Остаеся видимой в дашборде.

Parametres:
  session_id  (str)
  message     (str, opt)

tracking_kill

Принудительно удаляе сессию. Немедленно исчезает из дашборда.

Parametres:
  session_id  (str)

tracking_get

Возвращае полное форматированное состояние сессии.

tracking_list

Parametres:
  template  (str, opt)   Filtrer par template
  status    (str, opt)   Filtrer par statut ("running", "done", "error", "paused")

tracking_delete

Удаляе сессию (эквивалент tracking_kill).

tracking_templates

Отображае список шаблонов и их пола.

open_tracking_ui

Открывает дашборд в терминале Kiry.

Parametres:
  filter_template  (str, opt)   Template a afficher au lancement

Шаблоны

download

Скачивание файлов. Автоматически наполняеся qBittorrent через пойлер.

Champs extra : speed, eta
Unite par defaut : MB

machine

Операции над машинами (update, clone, snapshot, deploy). Используеся Lyra для операций VM/кластера.

Champs extra : operation, target
Unite par defaut : machines

free

Свободный формат. Используеся пойлером для отсуствующих субтитров Bazarr.

Aucun champ extra impose, aucune unite par defaut.

lyra_task

Операции Lyra (VM clone, backup, update, snapshot).

Champs extra : operation, target, phase, eta
Unite par defaut : %

movie

Полный конвейер фильма: загрузка -> конвертация Dolby Vision. Автоматически наполняется dv_convert.py, когда Radarr/Sonarr импортируют файл 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"

Безопасность

  • api.py слушает только на 127.0.0.1:8765 -- недоступен из сети

  • n8n ограничен адресом 127.0.0.1:5678 в docker-compose.yml

  • dv_webhook_server.py слушает на 0.0.0.0:8787 (необхоимо для приема Docker-вебхуков) -- защитите этот порт файрволом, если машина доступна извне

  • Службы systemd работают с NoNewPrivileges=true

  • Никаких секретов в откртом виде в коде: poller.py читае $CREDENTIALS_DIRECTORY (пользовтельская служба) или расшифровывае credentials/*.cred через systemd-creds decrypt --user (системная служба), с откатом на переменные QBT_PASSWORD / BAZARR_KEY для отладки


Добавление шаблона

  1. Откройте templates.py и добавьте запись в TEMPLATES:

"mon_template": {
    "description": "Description courte",
    "extra_fields": ["champ1", "champ2"],
    "default_unit": " unites",
    "example_extra": {"champ1": "valeur", "champ2": "valeur"},
},
  1. Необязательно: добавьте симуляцию _im_mon_template() в sim.py.

Шаблон сразу доступен без каких-либо дополнительных изменений.

Не трогая код, шаблон также можно объявить в ~/.config/tracking/templates.json (та же структура, ключ = имя шаблона); он загружаеся при запуске.


Тесты

make test     # unitaires (storage, metrics) + integration (API HTTP reelle sur port ephemere)

Фикстура autouse в conftest.py перенаправляе хранение в tmp_path: тесты никогдa не затрагивают состояние продакшена.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    A
    quality
    D
    maintenance
    Provides 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.
    5
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A 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.
    20
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    A 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.

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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