From fefde4eb31b538f242053e2f722d66b55737e9e4 Mon Sep 17 00:00:00 2001 From: Gilles Soulier Date: Mon, 25 May 2026 22:28:28 +0200 Subject: [PATCH] docs: spec serveur MCP HomeHub (16 outils, Streamable HTTP, Hermes) --- .../specs/2026-05-25-mcp-server-design.md | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-25-mcp-server-design.md diff --git a/docs/superpowers/specs/2026-05-25-mcp-server-design.md b/docs/superpowers/specs/2026-05-25-mcp-server-design.md new file mode 100644 index 0000000..fdc242e --- /dev/null +++ b/docs/superpowers/specs/2026-05-25-mcp-server-design.md @@ -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 ← 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` 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 " +``` + +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": ""}` 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)