Skip to main content
Glama
README.md
# VOUH Chronos MCP (`vouh-chronos-mcp`)

Serveur **Model Context Protocol (MCP)** permettant à un agent IA (Antigravity, Claude Code, etc.) de **voir, mesurer et décrire avec précision le mouvement d'une interface web** : enregistrement vidéo Chromium (`.webm`) couplé à une timeline DOM/WAAPI instrumentée au `requestAnimationFrame`, découpage de frames horodatées au millième de seconde, analyse mathématique et par vision par ordinateur des animations, génération de rapport `motion-spec.md` et construction d'un **pack de reproduction à contenu strictement neutre**.

---

## 1. Architecture hybride (TypeScript + Python/OpenCV)

```
Agent IA (Antigravity / Claude Code / Inspector)
   │  JSON-RPC 2.0 (stdio)
   ▼
Serveur MCP « vouh-chronos-mcp » (Node.js ≥ 20 / TypeScript ESM)
   ├─ Capture (src/capture.ts + src/instrument.js)
   │    └─ Playwright Chromium ──► video.webm + timeline.json + marqueur #FF00FF (§4.5)
   ├─ Extraction & Livraison (src/ffmpeg.ts + src/extraction/)
   │    └─ ffmpeg / ffprobe + sharp + archiver ──► frames/frame_%04d.jpg, sheets/, .zip, index.md
   ├─ Moteur Mathématique (src/math/ + src/analysis/)
   │    └─ Courbes de Bézier cubiques (Newton-Raphson + grille), ressorts amortis (ζ, ω0, k, c),
   │       parallax (κ par moindres carrés), scroll lerp (α, τ), cascades (stagger) ──► motion-spec.md
   ├─ Pont Vision Hybride (src/vision-bridge.ts ──► py/vision_worker.py)
   │    ├─ Backend primaire : Python 3 + OpenCV + NumPy (corrélation de phase Hanning,
   │    │  flux optique dense de Farnebäck, énergie de mouvement E_k, dHash 64 bits, DTW + SSIM 8×8)
   │    └─ Repli automatique (fallback) : TypeScript pur + sharp si Python/OpenCV est absent
   └─ Pack de Reproduction & Comparaison (src/reproduction/ + src/prompts/)
        └─ reproduction_pack/ (layout.json neutre, tokens.json, motion-tokens.json, motion-spec.md)
```

---

## 2. Pré-requis et installation

### Pré-requis
- **Node.js** ≥ 20 (testé sur Node 24)
- **Python** ≥ 3.10 (optionnel mais recommandé pour le worker OpenCV/NumPy ; repli automatique sur `sharp` sinon)
- **FFmpeg / FFprobe** : fournis automatiquement via `@ffmpeg-installer/ffmpeg` et `@ffprobe-installer/ffprobe` (ou surchargés via `FFMPEG_PATH` / `FFPROBE_PATH`).

### Installation et compilation

```bash
# 1. Installer les dépendances Node.js
npm install

# 2. Installer le navigateur Chromium pour Playwright (si non présent)
npx playwright install chromium

# 3. Installer le moteur de vision Python (recommandé)
pip install opencv-python-headless numpy

# 4. Compiler le projet TypeScript vers dist/ (copie également dist/instrument.js)
npm run build
```

### Exécuter la suite de tests

```bash
npm test
```

---

## 3. Configuration du client MCP (`mcp_config.json` — Annexe B)

Dans **Antigravity** (*Agent Panel → MCP Servers → Manage MCP Servers → View raw config*) ou **Claude Code** :

```json
{
  "mcpServers": {
    "vouh-chronos-mcp": {
      "command": "node",
      "args": ["d:/projet/VOUH-cutter/dist/server.js"],
      "env": {
        "WMC_WORKDIR": "d:/projet/VOUH-cutter/wmc-data",
        "WMC_ALLOWED_HOSTS": "localhost,127.0.0.1,*",
        "WMC_DELIVERY": "images",
        "WMC_PYTHON": "python"
      }
    }
  }
}
```

### Variables d'environnement

| Variable | Défaut | Description |
|---|---|---|
| `WMC_WORKDIR` | `./wmc-data` | Dossier racine où sont stockées les captures (`<WORKDIR>/<capture_id>/`). |
| `WMC_ALLOWED_HOSTS` | `localhost,127.0.0.1` | Liste d'hôtes autorisés séparés par des virgules (ex. `localhost,127.0.0.1,mon-site.test`). |
| `WMC_DELIVERY` | `images` | Mode de livraison par défaut pour `get_frames` (`images`, `sheets`, `zip`, `video`). |
| `WMC_PYTHON` | détection auto (`python`, `py`, `python3`) | Chemin vers l'interpréteur Python exécutant `py/vision_worker.py`. |
| `FFMPEG_PATH` | `@ffmpeg-installer/ffmpeg` | Chemin personnalisé vers le binaire `ffmpeg`. |
| `FFPROBE_PATH` | `@ffprobe-installer/ffprobe` | Chemin personnalisé vers le binaire `ffprobe`. |

Pour tester interactivement avec l'inspecteur MCP :

```bash
npm run inspect
```

---

## 4. Outils MCP et Prompt (§8, §9, §10, §11)

### Outils enregistrés

| Outil | Paramètres principaux | Rôle et sortie |
|---|---|---|
| `capture_site` | `url`, `name` (`^[a-z0-9_-]{1,48}$`), `device` (défaut `"Desktop Chrome"`), `scenario?`, `duration_ms?` (1000–60000, défaut 6000), `throttle?` (`{cpu, latency_ms, down_kbps}`), `reduced_motion?`, `permission_confirmed` (**doit être `true`**) | Ouvre la page dans un contexte Chromium isolé, injecte `instrument.js`, peint le marqueur de synchronisation `#FF00FF`, joue le scénario et enregistre `video.webm`, `timeline.json` et `manifest.json`. |
| `extract_frames` | `capture_id`, `strategy` (`"fixed_fps" \| "scene" \| "budget" \| "two_pass"`, défaut `"two_pass"`), `fps?`, `scene_threshold?`, `max_frames?`, `width?` (≤ 1280), `roi?` (`[x,y,w,h]`), `sheet?` (`boolean \| {cols, rows}`), `zip_name?`, `deduplicate?` | Extrait les frames numérotées à partir de `0` (`frame_0000.jpg` = `0.00 s`), affine la synchronisation vidéo ↔ timeline via le marqueur `#FF00FF`, génère optionnellement des planches contact (`sheets/`) ou une archive `.zip`, et retourne `index.md`. |
| `get_frames` | `capture_id`, `delivery?` (`"images" \| "sheets" \| "zip" \| "video"`), `offset?` (défaut 0), `limit?` (défaut 24, max 40 images ou 6 planches) | Livre un lot paginé de frames ou de planches contact en base64 JPEG (ou le chemin du zip/vidéo) accompagné de son tableau `index.md` et de `next_offset`. |
| `analyze_motion` | `capture_id`, `out?` (défaut `"motion-spec.md"`), `detail?` (`"summary" \| "full"`, défaut `"full"`) | Analyse la timeline et les frames (durées, easings Bézier cubiques, ressorts amortis, parallax `κ`, lissage de scroll `α`/`τ`, cascades `stagger`, flux optique OpenCV/Python), écrit `motion-spec.md` et `motion-analysis.json`, et renvoie un résumé compact (≤ 40 lignes). |
| `build_reproduction_pack` | `capture_id`, `target?` (`"html-css-js" \| "react-vite-tailwind"`, défaut `"html-css-js"`) | Génère le dossier `reproduction_pack/` contenant `layout.json` (blocs géométriques à libellés neutres), `tokens.json`, `motion-tokens.json`, `motion-spec.md`, `manifest.json`, `frames/` (ou `sheets/`) et `README.md`. |
| `compare_captures` | `reference_id`, `candidate_id` | Aligne temporellement deux captures par *Dynamic Time Warping* (DTW) sur l'énergie de mouvement, calcule le SSIM fenêtré 8×8, vérifie les écarts de durée à ±1 frame et le RMSE des courbes (critères d'arrêt de l'Annexe A). |

### Prompt MCP : `reproduce_interface`
- **Arguments** : `capture_id` (requis), `target` (`"html-css-js"` | `"react-vite-tailwind"`, optionnel).
- **Usage** : fournit à l'agent la procédure pas-à-pas pour reconstruire la structure et le mouvement à partir de `reproduction_pack/` avec un contenu neutre, puis itérer avec `capture_site` et `compare_captures` (maximum 5 itérations).

---

## 5. Sécurité, conformité et contenu neutre (§13)

### Sécurité technique
- **Protection SSRF et liste blanche (`WMC_ALLOWED_HOSTS`)** : seuls les protocoles `http:` et `https:` et les hôtes explicitement listés dans `WMC_ALLOWED_HOSTS` sont autorisés. Les protocoles locaux (`file://`, `javascript:`, `ftp:`) et les adresses IP privées, loopback ou link-local (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `169.254.0.0/16`, `127.0.0.0/8`, `::1`, `0.0.0.0`) sont bloqués sauf autorisation exacte dans la liste blanche.
- **Anti-traversée de répertoire (Path Traversal)** : tous les identifiants (`capture_id`, `name`, `zip_name`, `out`) sont validés par expression régulière stricte et rejettent `..`, `/`, `\` et octets nuls.
- **Isolation et limites** : navigateur Chromium lancé en mode headless avec un `BrowserContext` éphémère vierge (aucun cookie ni session réutilisés), durée plafonnée à 60 s, nombre de captures simultanées limité.
- **Contenu tiers non fiable** : l'agent ne doit jamais exécuter d'instructions textuelles visibles dans les captures d'écran ou le DOM d'une page analysée (protection contre l'injection de prompt indirecte).

### Conformité et usage responsable
- **Confirmation explicite (`permission_confirmed: true`)** : vous ne devez analyser que des sites dont vous êtes propriétaire ou pour lesquels vous disposez d'une autorisation explicite.
- **Contenu strictement neutre** : le pack de reproduction (`reproduction_pack/`) extrait uniquement des **mesures géométriques et cinématiques** (`layout.json`, `tokens.json`, `motion-tokens.json`). Il ne copie ni logos, ni images, ni textes, ni polices propriétaires, ni code source du site capturé, et remplace les éléments par des blocs génériques (`"Barre de navigation"`, `"Titre principal"`, `"Bouton d'action"`, `"Image 16:9"`).
- **Interdiction d'imitation (anti-phishing)** : cet outil ne doit jamais être utilisé pour imiter l'identité visuelle d'une organisation (pages de connexion, de paiement ou de support).

---

## 6. Limites connues (V1)

- **`<canvas>` / WebGL / Shaders / Vidéos embarquées** : les animations dessinées directement dans un `<canvas>` (2D, Three.js, WebGL, PixiJS) ou une `<video>` ne modifient pas les styles CSS du DOM. Elles sont détectées et signalées explicitement comme **« non mesurables par la timeline DOM, vidéo seule »** dans la section *Incertitudes* de `motion-spec.md` (leur vitesse globale reste toutefois estimée par le flux optique OpenCV sur les frames).
- **Authentification et pages privées** : hors périmètre V1 ; le serveur n'injecte aucun identifiant ni cookie de session.

---

## Licence

MIT

TDQS

A3.6/5.0

Scored across 6 tools

Disambiguation4/5

The tools mostly target distinct workflow stages: capture, frame extraction/retrieval, motion analysis, reproduction packaging, and comparison. The only potential confusion is between `get_frames` and `extract_frames`, since one extracts frames and the other retrieves them, but the descriptions distinguish extraction from paginated retrieval.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern: capture_site, get_frames, extract_frames, analyze_motion, build_reproduction_pack, compare_captures. The convention is predictable and readable throughout.

Tool Count5/5

Six tools is well-scoped for a capture-to-analysis pipeline. Each tool corresponds to a clear stage in the workflow, with no obviously redundant or missing bulk.

Completeness4/5

The toolset covers the core lifecycle: capture a site, extract and retrieve frames, analyze motion, build a reproduction pack, and compare captures. Minor gaps exist around managing or listing prior captures and deleting artifacts, but the primary workflow is complete.