From d002435f03317f712f423952620e2aaa403cda2a Mon Sep 17 00:00:00 2001 From: MaksTinyWorkshop Date: Thu, 25 Jun 2026 01:33:40 +0200 Subject: [PATCH] =?UTF-8?q?docs(mcp):=20add=20NUC=20+=20Tailscale=20centra?= =?UTF-8?q?l=20hosting=20design=20(chantier,=20non=20d=C3=A9marr=C3=A9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Capture le design abouti d'un MCP central: - besoin: 1 instance, lecture+écriture, sans clone local sur chaque machine - hébergement NUC en HTTP (FastMCP streamable-http), exposition via Tailscale (pas de WAN) - écriture centralisée: ALLOW_WRITE=1 côté NUC, plus de conflit multi-machine - workflow capitalisation à seuil: accumulation -> triage_capitalization() au-delà de N -> rapport -> validation humaine - source de vérité données: Git (origin), NUC = clone de référence Statut: PISTE non figée (pas dans 40_decisions_et_archi.md). Reste-à-faire listé. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../docs/design_nuc_tailscale.md | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 mcp/leadtech_bmad_mcp/docs/design_nuc_tailscale.md diff --git a/mcp/leadtech_bmad_mcp/docs/design_nuc_tailscale.md b/mcp/leadtech_bmad_mcp/docs/design_nuc_tailscale.md new file mode 100644 index 0000000..f4e7a91 --- /dev/null +++ b/mcp/leadtech_bmad_mcp/docs/design_nuc_tailscale.md @@ -0,0 +1,74 @@ +# leadtech-bmad-mcp — Design : MCP central sur NUC via Tailscale + +> **Statut : PISTE / chantier non démarré** (2026-06-25). +> Ce document capture un design abouti mais non implémenté. Ce n'est PAS une décision figée +> (pas dans `40_decisions_et_archi.md` tant que le chantier n'est pas lancé). À reprendre tel quel. + +## Besoin + +Avoir **un seul MCP central**, hébergé une fois, accessible en **lecture ET écriture** +depuis n'importe quelle machine, **sans clone local ni Python** sur chaque client. + +Aujourd'hui le MCP tourne en **stdio local** : chaque machine (Mac, NUC, ...) exécute son +propre binaire. Git garantit déjà une doctrine identique partout (source de vérité = `origin`), +mais pas une instance d'exécution unique. Le besoin (écriture centralisée + appel sans clone) +impose une **instance unique exposée en réseau**. + +## Architecture cible + +``` + Mac (Claude Code) ─┐ + Autre machine ─┼─ HTTP via Tailscale ─► NUC : MCP leadtech-bmad (1 instance, Docker) + Mobile / client léger ─┘ ├─ lit : /srv/helpers/_Assistant_Lead_Tech (clone Git) + └─ écrit: 95_a_capitaliser.md (ALLOW_WRITE=1) +``` + +## Décisions de fond (prises, à confirmer au moment d'implémenter) + +| Sujet | Décision | +| --- | --- | +| Hébergement | NUC, service HTTP permanent (Docker ou systemd) | +| Transport | FastMCP en `streamable-http` (aujourd'hui `mcp.run()` = stdio par défaut → modif code) | +| Réseau / accès | **Tailscale** : bind sur l'interface du tailnet, pas d'exposition WAN, pas de reverse-proxy obligatoire. Auth réseau gérée par Tailscale. | +| URL client | `http://nuc..ts.net:/mcp` dans la config MCP Claude Code (`"type": "http"`) | +| Écriture | `LEADTECH_MCP_ALLOW_WRITE=1` (le MCP central est le seul à écrire → plus de conflit multi-machine sur `95_a_capitaliser.md`) | +| Source de vérité données | Git (`origin`). Le NUC héberge le clone de référence ; les éditions manuelles faites ailleurs remontent via Git. | + +## Workflow de capitalisation à seuil (idée structurante) + +Deux temps : + +1. Le MCP **accumule** les propositions (`propose_capitalization`) dans `95_a_capitaliser.md` + (append, write activé côté NUC). +2. Quand la section dépasse un **seuil** (N entrées / lignes), **déclencher le triage** : + le tool `triage_capitalization()` (déjà implémenté) pré-analyse — doublons, portée + PROJET vs KNOWLEDGE, décision + confiance par entrée — et le skill `capitalisation-triage` + produit un **rapport**. +3. **Choix final humain** : tu valides quoi intégrer dans `knowledge/` ou router en mémoire projet. + Rien ne part dans la base validée sans toi (cohérent avec la doctrine de capitalisation contrôlée). + +Briques déjà en place : +- tool MCP `triage_capitalization(project_filter?, max_entries?)` → rapport structuré +- skill `skills/capitalisation-triage/SKILL.md` + +Brique manquante : le **déclencheur de seuil** (compter les entrées, lancer le triage au-delà de N). + +## Reste à faire (quand le chantier démarre) + +- [ ] POC : passer le serveur en transport HTTP (`mcp.run(transport="streamable-http", host=..., port=...)`) et tester en local +- [ ] Dockerfile + compose (bind `/srv/helpers/_Assistant_Lead_Tech`, env `LEADTECH_ROOT`, `LEADTECH_MCP_ALLOW_WRITE`) +- [ ] Bind sur l'interface Tailscale du NUC ; vérifier l'accès depuis le Mac via le tailnet +- [ ] Reconfigurer les clients : `"leadtech-bmad": { "type": "http", "url": "http://nuc..ts.net:/mcp" }` +- [ ] Déclencheur de seuil pour le triage de capitalisation +- [ ] Décider du flux Git de `95_a_capitaliser.md` (commit/push manuel au NUC après validation — option retenue par défaut) +- [ ] S'assurer que les projets cibles de `route_to_project_memory` sont clonés sur le NUC (sinon tool sans effet pour eux) + +## Points d'attention + +- `route_to_project_memory` écrit dans `/CLAUDE.md` via `resolve-project-path.sh`. Depuis le NUC, + ça vise `/srv/projects/`, pas les chemins Mac (`/Volumes/TeraSSD/...`). Tool utile uniquement + pour les projets présents sur le NUC. +- Les clients Claude Code chargent les serveurs MCP **au démarrage de session** : tout changement + d'URL nécessite une nouvelle session. +- Garder `ALLOW_WRITE` maîtrisé : le MCP central écrit, donc la sécurité d'écriture (limitée à + `95_a_capitaliser.md` et CLAUDE.md projets, jamais `knowledge/*`) reste critique.