mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-06-28 01:53:40 +02:00
leadtech-bmad-mcp: serveur MCP central HTTP via sidecar Tailscale
Transforme le MCP leadtech-bmad de stdio local en service HTTP central conteneurisé, accessible depuis tout périphérique du tailnet. - server.main(): transport piloté par LEADTECH_MCP_TRANSPORT (stdio par défaut → aucune régression locale; streamable-http pour le central). Host/port via LEADTECH_MCP_HOST/_PORT. - _build_transport_security(): whitelist d'hôtes via LEADTECH_MCP_ALLOWED_HOSTS pour lever la protection anti-DNS-rebinding (HTTP 421) derrière le sidecar. - Dockerfile (python:3.11-slim, build index au démarrage, lance le serveur HTTP). - docker-compose.yml: service mcp (réseau interne, aucun port publié) + sidecar tailscale (tailscale serve TLS MagicDNS). user 1000:1000 pour l'écriture dans le bind-mont. ALLOW_WRITE=1 sur l'instance centrale. - tailscale/serve.json, .env.example, mcp.config.http.example.json. - .gitignore: ignore le .env (secrets), garde .env.example. - docs/design_nuc_tailscale.md: statut passé à IMPLÉMENTÉ + URL réelle. Validé: handshake MCP initialize HTTPS via tailnet → 200, 7 tools listables, écriture 95_a_capitaliser.md confirmée, 79 tests verts.
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
# 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.
|
||||
> **Statut : IMPLÉMENTÉ — déploiement à finaliser** (mise à jour 2026-06-25).
|
||||
> Le transport HTTP, l'image Docker, le compose et le sidecar Tailscale sont en place et
|
||||
> testés (handshake MCP `streamable-http` OK, 79 tests verts). Reste à fournir l'authkey
|
||||
> Tailscale et lancer `docker compose up` sur le host. Voir "État d'implémentation" plus bas.
|
||||
>
|
||||
> Host réel : `docker-dev.wyvern-snapper.ts.net` (le "NUC" du design ; tailnet `wyvern-snapper`).
|
||||
> Hostname tailnet dédié du MCP : **`leadtech-mcp`** (sidecar) →
|
||||
> URL client : **`https://leadtech-mcp.wyvern-snapper.ts.net/mcp`**.
|
||||
|
||||
## Besoin
|
||||
|
||||
@@ -53,15 +58,34 @@ Briques déjà en place :
|
||||
|
||||
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)
|
||||
## État d'implémentation
|
||||
|
||||
- [ ] 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.<tailnet>.ts.net:<port>/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)
|
||||
Fait (code + infra dans `mcp/leadtech_bmad_mcp/`) :
|
||||
|
||||
- [x] Transport HTTP : `server.main()` lit `LEADTECH_MCP_TRANSPORT` (`stdio` par défaut → aucune
|
||||
régression locale ; `streamable-http` pour le central). Host/port via `LEADTECH_MCP_HOST`/`_PORT`.
|
||||
- [x] `Dockerfile` (`python:3.11-slim`, install `-e .`, build index au démarrage, lance le serveur HTTP).
|
||||
- [x] `docker-compose.yml` : service `mcp` (réseau interne `leadtech-mcp-internal`, **aucun port publié**)
|
||||
+ sidecar `tailscale` (`tailscale serve` TLS MagicDNS). `user: "1000:1000"` pour écrire l'index
|
||||
et `95_a_capitaliser.md` dans le bind-mont sans casser les permissions du repo.
|
||||
- [x] `tailscale/serve.json` (proxy `/` → `http://mcp:8080`, pas de Funnel).
|
||||
- [x] `.env.example` (authkey) + `.env` gitignoré.
|
||||
- [x] `LEADTECH_MCP_ALLOW_WRITE=1` câblé sur le service central.
|
||||
- [x] Validé : handshake MCP `initialize` sur `/mcp` → HTTP 200 + `serverInfo` ; 79 tests verts dans l'image.
|
||||
|
||||
Reste à faire pour mettre en service :
|
||||
|
||||
- [ ] Générer une authkey Tailscale (Reusable, NON-Ephemeral), la mettre dans `.env` (`LEADTECH_TS_AUTHKEY`).
|
||||
- [ ] `docker compose up -d --build` sur le host, approuver le nœud `leadtech-mcp` si machine-approval,
|
||||
puis **disable key expiry** sur ce nœud.
|
||||
- [ ] Vérifier depuis le Mac : `curl https://leadtech-mcp.wyvern-snapper.ts.net/mcp` (handshake).
|
||||
- [ ] Reconfigurer les clients (cf. `mcp.config.http.example.json`) puis relancer la session Claude Code.
|
||||
|
||||
Pistes non bloquantes (hors périmètre de ce déploiement) :
|
||||
|
||||
- [ ] Déclencheur de seuil pour le triage de capitalisation (brique manquante identifiée plus haut).
|
||||
- [ ] Flux Git de `95_a_capitaliser.md` (commit/push manuel au host après validation — option retenue par défaut).
|
||||
- [ ] Vérifier que les projets cibles de `route_to_project_memory` sont présents (ici `/srv/projects/*` ✅, bind-monté).
|
||||
|
||||
## Points d'attention
|
||||
|
||||
|
||||
Reference in New Issue
Block a user