Files
AntiCoco/README.md
jerem ef6bf9813a API HelloFresh réelle câblée + filtrage coco validé en local
- Endpoints découverts: menu (menus-service) + détails batch (recipes/recipes)
- get_menu en 2 temps: menu (ids) -> batch détails (ingrédients/allergènes)
- Fix faux positifs: exclusion sur ingrédients/allergènes/nom, plus sur les tags
  (HelloFresh pose un tag interne 'coconut' sur ~la moitié des recettes)
- Token mis en cache (pas de navigateur si frais)
- endpoints.json versionné (sans secret), semaine optionnelle (défaut = courante)
- Testé: 4 recettes coco/85 détectées, shortlist classée, tous les outils MCP OK
- set_selection (écriture) reste à découvrir sur un compte avec box active
2026-06-15 22:28:40 +02:00

103 lines
4.3 KiB
Markdown

# 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 (testé en local, 2026-06)
**Lecture validée sur le menu réel** : login Playwright + token, menu de la semaine
(`menus-service/menus`) → détails en 1 appel batch (`recipes/recipes?ids=…`), filtrage coco
correct (4 recettes coco détectées sur 85, faux positifs des tags internes neutralisés),
scoring par préférences, gestion de la liste d'exclusion. Serveur MCP fonctionnel (handshake OK).
**Écriture (`hf_confirm_selection`) à finaliser** : l'endpoint d'enregistrement de la
sélection (`set_selection`) n'a pas pu être capturé (compte de test sans abonnement actif).
À découvrir via `discover_api.py` sur un compte avec une box modifiable (changer une recette
pour observer l'appel `PUT`/`POST`), puis renseigner `config/endpoints.json`.
## Architecture
```
Hermes ──HTTP──▶ server.py (FastMCP, :9200/mcp)
├─ hellofresh/auth.py login Playwright + capture du bearer token
├─ hellofresh/api.py appels httpx vers le gateway HelloFresh
├─ hellofresh/filter.py exclusion (coco !) + scoring préférences
└─ config/ excludes.json · prefs.json · endpoints.json
```
## Mise en route
### 1. Installer
```bash
pip install -r requirements.txt
playwright install chromium
cp .env.example .env # remplir HF_EMAIL / HF_PASSWORD (optionnels, fallback re-login)
```
### 2. Découvrir les endpoints (étape 0, en local, fenêtre visible)
```bash
ANTICOCO_HEADLESS=0 python tools/discover_api.py
```
Connecte-toi, ouvre le menu de la semaine, change une recette pour capturer l'écriture, puis
Entrée. Vérifie/complète ensuite `config/endpoints.json` (généré depuis le trafic capturé,
voir aussi `.session/discovery_log.json`).
### 3. Tester en local
```bash
ANTICOCO_HEADLESS=0 python server.py # 1er run : login dans la fenêtre si besoin
```
Le login crée `.session/profile` (profil Playwright persistant) — réutilisé ensuite headless.
## Déploiement homelab (Docker)
`.session/` et `.env` ne sont **jamais** versionnés. Workflow :
```bash
# 1. Sur le Mac : générer une session connectée (fenêtre visible)
ANTICOCO_HEADLESS=0 python server.py # se connecter, puis Ctrl-C
# 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)
scp -r .session jerem@192.168.0.43:<path>/AntiCoco/
# 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é).