AntiCoco: serveur MCP HelloFresh sans noix de coco

- Auth Playwright (login local, session persistee, capture du bearer token)
- Client httpx vers l'API interne (endpoints via discover_api.py)
- Filtre d'exclusion insensible aux accents (coco & co)
- Serveur FastMCP (streamable-http) + outils hf_*
- Docker + compose pour deploiement homelab
This commit is contained in:
2026-06-15 22:09:11 +02:00
commit b881111504
15 changed files with 1019 additions and 0 deletions

90
README.md Normal file
View File

@@ -0,0 +1,90 @@
# 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**.
## 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)
scp -r .session config/endpoints.json 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é).