docs: spec serveur MCP HomeHub (16 outils, Streamable HTTP, Hermes)

This commit is contained in:
2026-05-25 22:28:28 +02:00
parent 273e032245
commit fefde4eb31
@@ -0,0 +1,122 @@
# MCP Server — Design Spec
## Objectif
Intégrer un serveur MCP (Model Context Protocol) directement dans le backend FastAPI de HomeHub, exposant 16 outils aux agents IA (Hermes, Claude Code, Codex) via le transport Streamable HTTP (standard 2025).
---
## Architecture
```
Hermes (10.0.0.80)
│ POST/GET http://10.0.0.50:3001/mcp (via nginx)
nginx (frontend container)
│ proxy_pass → http://backend:8000/mcp
│ proxy_buffering off, proxy_read_timeout 86400s
FastAPI backend
├── MCPAuthMiddleware → vérifie Authorization: Bearer <MCP_API_KEY>
└── /mcp ← MCP Server (Streamable HTTP, SDK officiel mcp>=1.9)
├── 5 outils Todos → SQLAlchemy async (pool partagé)
├── 5 outils Notes → SQLAlchemy async (pool partagé)
└── 6 outils Shopping → SQLAlchemy async (pool partagé)
```
Le serveur MCP partage le pool de connexions PostgreSQL du backend. Il n'y a pas de service Docker supplémentaire.
---
## Authentification
- Header requis : `Authorization: Bearer <MCP_API_KEY>`
- `MCP_API_KEY` définie dans `.env` / `docker-compose.yml` (variable d'environnement)
- Un middleware FastAPI intercepte toutes les requêtes `/mcp*` et renvoie HTTP 401 si le token est absent ou incorrect
- Les autres routes du backend (`/api/*`) ne sont pas affectées
---
## Outils exposés
### Todos (5 outils)
| Outil | Paramètres | Description |
|-------|-----------|-------------|
| `get_todos` | `status: str = "pending"`, `domain: str?`, `priority: str?` | Liste filtrée des tâches |
| `create_todo` | `title: str`, `due_date: str?` (ISO 8601), `priority: str?`, `domain: str?` | Crée une tâche |
| `update_todo` | `id: str`, `title: str?`, `status: str?`, `priority: str?` | Modifie une tâche |
| `postpone_todo` | `id: str`, `days: int` | Reporte la date d'échéance |
| `delete_todo` | `id: str` | Supprime une tâche |
### Notes (5 outils)
| Outil | Paramètres | Description |
|-------|-----------|-------------|
| `search_notes` | `query: str?`, `category: str?`, `tag: str?` | Recherche FTS PostgreSQL (français) |
| `get_note` | `id: str` | Retourne une note complète avec pièces jointes |
| `create_note` | `title: str`, `content: str`, `category: str?`, `tags: list[str]?` | Crée une note |
| `update_note` | `id: str`, `title: str?`, `content: str?`, `tags: list[str]?` | Modifie une note |
| `delete_note` | `id: str` | Supprime une note |
### Shopping (6 outils)
| Outil | Paramètres | Description |
|-------|-----------|-------------|
| `get_shopping_lists` | — | Toutes les listes avec compteurs d'articles |
| `get_active_shopping_list` | — | Première liste en statut `draft` avec ses articles |
| `search_products` | `q: str` | Recherche dans le catalogue produits |
| `create_shopping_list` | `name: str?` | Crée une liste (nom auto = semaine ISO si absent) |
| `add_shopping_item` | `list_id: str`, `name: str`, `quantity: float? = 1`, `unit: str?` | Ajoute un article à une liste |
| `check_shopping_item` | `list_id: str`, `item_id: str` | Coche un article (marque comme acheté) |
---
## Fichiers à créer/modifier
| Fichier | Action | Rôle |
|---------|--------|------|
| `backend/app/api/mcp_server.py` | Créer | Définition des 16 outils MCP, logique métier |
| `backend/app/core/mcp_auth.py` | Créer | Middleware Bearer token pour `/mcp*` |
| `backend/app/main.py` | Modifier | Mount du serveur MCP + enregistrement middleware |
| `backend/requirements.txt` | Modifier | Ajout `mcp>=1.9` |
| `backend/app/core/config.py` | Modifier | Ajout champ `mcp_api_key: str` dans Settings |
| `docker-compose.yml` | Modifier | Ajout variable `MCP_API_KEY` |
| `frontend/nginx.conf` | Modifier | Location `/mcp` dédiée (no-buffer, long timeout) |
---
## Configuration Hermes (post-déploiement)
```yaml
servers:
homehub:
url: http://10.0.0.50:3001/mcp
headers:
Authorization: "Bearer <valeur de MCP_API_KEY>"
```
Après configuration : `/reload-mcp` dans l'interface Hermes pour prendre en compte les nouveaux outils.
---
## Retours des outils
Chaque outil retourne du JSON structuré cohérent avec les schémas Pydantic existants du backend. En cas d'erreur (ID introuvable, paramètre invalide), l'outil retourne un objet `{"error": "<message>"}` sans lever d'exception MCP (pour ne pas interrompre le contexte de l'agent).
---
## Dépendances
- `mcp>=1.9` — SDK officiel Anthropic (Streamable HTTP transport)
- Aucune autre dépendance externe — SQLAlchemy, FastAPI, Pydantic déjà présents
---
## Hors périmètre
- Authentification OAuth2 / multi-utilisateur (réseau local, clé statique suffit)
- Outils de gestion des pièces jointes (upload binaire incompatible MCP)
- Analyse frigo Vision LLM (Phase 9 séparée)
- Websocket / stdio transport (Hermes utilise HTTP)