jerem 5d3899fdfb Auth headless durable via storage_state + refresh navigateur (homelab-ready)
- capture_token s'appuie sur storage_state.json (cookies ~60j) en new_context :
  fonctionne headless, la SPA rafraîchit le token (contourne l'anti-bot OAuth)
- session 'roule' (storage_state ré-exporté à chaque refresh) ; access token 30min,
  refresh token 60j
- goto en domcontentloaded + attente (networkidle ne se déclenche jamais sur la SPA)
- Dockerfile/Playwright alignés en 1.60.0 (chromium préinstallé) ; doc déploiement maj :
  session créée via attach_capture (login direct Playwright bloqué par anti-bot)
2026-06-15 23:08:09 +02:00

AntiCoco 🥥🚫

Serveur MCP qui donne accès à ton compte HelloFresh (France, hellofresh.fr) pour : lire le menu de la semaine, exclure des ingrédients (la noix de coco en priorité), proposer une shortlist de recettes, puis enregistrer ta sélection après confirmation.

Client MCP visé : Hermes (Nous Research), qui tourne sur le même homelab.

⚠️ HelloFresh n'a pas d'API publique. AntiCoco s'appuie sur l'API interne gw/ du site (non documentée, susceptible de changer) — usage strictement personnel.

État (validé de bout en bout, 2026-06)

Boucle complète testée sur le vrai compte : lecture du menu (menus-service/menus → détails batch recipes/recipes?ids=…), filtrage coco (4/85 détectées, faux positifs des tags internes neutralisés), proposition classée, et écriture réelle réussie (PUT /v1/carts/{week}, HTTP 200) — sélection par index de course, ids de compte dérivés dynamiquement.

Auth headless durable : le token (30 min) est rafraîchi par un navigateur headless chargé avec la session (storage_state.json, refresh ~60 j) — contourne la protection anti-bot des endpoints OAuth. Aucune intervention pendant ~60 j ; la session « roule » à chaque refresh.

⚠️ La connexion directe automatisée (Playwright/Chromium qui remplit le formulaire) est bloquée par l'anti-bot HelloFresh. La session se crée donc via attache CDP à ton vrai Chrome (tools/attach_capture.py), où le login marche normalement.

Architecture

Hermes ──HTTP──▶ server.py (FastMCP, :9200/mcp)
                   ├─ hellofresh/auth.py    session storage_state + refresh token headless
                   ├─ hellofresh/api.py     httpx : menu, détails, deliveries, PUT cart
                   ├─ hellofresh/filter.py  exclusion (coco !) + scoring préférences
                   └─ config/               excludes.json · prefs.json · endpoints.json

Mise en route

1. Installer

pip install -r requirements.txt
playwright install chromium
cp .env.example .env

2. Créer la session (login via TON Chrome, anti-bot contourné)

Lance ton Chrome avec un port de debug + profil dédié (ta fenêtre Chrome habituelle peut rester ouverte), connecte-toi à HelloFresh (email + mot de passe), puis attache la capture :

"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
    --remote-debugging-port=9222 --user-data-dir="$HOME/.hf-chrome-debug" \
    https://www.hellofresh.fr/my-account/deliveries/menu
python tools/attach_capture.py        # capture trafic + exporte .session/storage_state.json

storage_state.json (cookies, ~60 j) est la session réutilisable. config/endpoints.json est déjà rempli ; rejoue attach_capture si l'API change (cf. config/endpoints_discovered.json).

3. Tester en local (headless, comme le homelab)

python server.py        # auth via storage_state, refresh token automatique

Déploiement homelab (Docker)

.session/ et .env ne sont jamais versionnés. Workflow :

# 1. Sur le Mac : générer la session (cf. « Mise en route » §2 → .session/storage_state.json)

# 2. Pousser le code
git add -A && git commit -m "..." && git push

# 3. Synchroniser la session vers le homelab (NON versionnée ; endpoints.json est dans git)
#    storage_state.json suffit (le homelab tourne headless et rafraîchit le token tout seul).
scp .session/storage_state.json jerem@192.168.0.43:<path>/AntiCoco/.session/

# 4. Sur le homelab : déployer
ssh homelab
cd <path>/AntiCoco && git pull && docker compose up -d --build

Vérifier : curl -s http://127.0.0.1:9200/mcp (le serveur répond au handshake MCP).

Intégration Hermes

Enregistrer AntiCoco dans la config MCP de Hermes (côté homelab), URL http://127.0.0.1:9200/mcp (transport streamable-http).

Si Hermes n'accepte que le stdio, changer la dernière ligne de server.py (mcp.run(transport="stdio")) et lancer le serveur en sous-processus — le reste est identique.

Outils MCP exposés

Outil Rôle
hf_auth_status() état de connexion
hf_login() (re)connexion + capture token
hf_list_weeks() semaines modifiables
hf_get_menu(week) toutes les recettes, avec flag contains_excluded
hf_propose(week, count=0) shortlist sans coco, classée par préférences
hf_confirm_selection(week, recipe_ids) écrit la sélection (refuse la coco)
hf_get_excludes() / hf_add_exclude(term) / hf_remove_exclude(term) gérer la liste d'exclusion

Configuration

  • config/excludes.json — ingrédients bannis (matching insensible casse/accents). Coco déjà listée.
  • config/prefs.json — mots-clés liked/disliked pour classer les propositions.
  • config/endpoints.json — URLs gateway réelles (généré par discover_api.py, non versionné).
Description
No description provided
Readme 183 KiB
Languages
Python 99.5%
Dockerfile 0.5%