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:
@@ -0,0 +1,81 @@
|
||||
# leadtech-bmad-mcp — MCP central exposé au tailnet via sidecar Tailscale.
|
||||
#
|
||||
# Architecture (cf. docs/design_nuc_tailscale.md) :
|
||||
#
|
||||
# tailnet ──https──► [tailscale sidecar] ──http (réseau interne)──► [mcp:8080]
|
||||
#
|
||||
# - Le serveur MCP n'écoute QUE sur le réseau Docker interne (aucun port publié
|
||||
# sur l'hôte → aucune exposition LAN/WAN).
|
||||
# - Le sidecar rejoint le tailnet sous le hostname `leadtech-mcp` et termine TLS
|
||||
# via `tailscale serve` (cert MagicDNS automatique).
|
||||
# - URL client finale : https://leadtech-mcp.wyvern-snapper.ts.net/mcp
|
||||
#
|
||||
# Prérequis : copier .env.example en .env et y mettre LEADTECH_TS_AUTHKEY
|
||||
# (auth key Tailscale Reusable, NON-Ephemeral — voir README / design doc).
|
||||
|
||||
name: leadtech-mcp
|
||||
|
||||
services:
|
||||
mcp:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: leadtech-bmad-mcp:local
|
||||
container_name: leadtech-bmad-mcp
|
||||
restart: unless-stopped
|
||||
# Tourne en max:max (uid 1000) pour écrire l'index + 95_a_capitaliser.md
|
||||
# dans le bind-mont sans casser les permissions du repo Git hôte.
|
||||
user: "1000:1000"
|
||||
environment:
|
||||
LEADTECH_ROOT: /leadtech
|
||||
LEADTECH_MCP_TRANSPORT: streamable-http
|
||||
LEADTECH_MCP_HOST: 0.0.0.0
|
||||
LEADTECH_MCP_PORT: "8080"
|
||||
# Le sidecar termine TLS et forwarde le Host tailnet ; sans whitelist,
|
||||
# la protection anti-DNS-rebinding renvoie 421. Inclut le hostname interne
|
||||
# (mcp:8080) au cas où le proxy préserve l'autorité d'origine.
|
||||
LEADTECH_MCP_ALLOWED_HOSTS: "leadtech-mcp.wyvern-snapper.ts.net,leadtech-mcp.wyvern-snapper.ts.net:443,mcp:8080,mcp"
|
||||
# Instance centrale = seule à écrire (capitalisation centralisée).
|
||||
LEADTECH_MCP_ALLOW_WRITE: "1"
|
||||
volumes:
|
||||
# Source de vérité : le clone Git Lead_tech (lecture + écriture buffer/index).
|
||||
- /srv/helpers/_Assistant_Lead_Tech:/leadtech
|
||||
# Les projets cibles de route_to_project_memory (mêmes chemins que sur l'hôte).
|
||||
- /srv/projects:/srv/projects
|
||||
networks:
|
||||
- internal
|
||||
# PAS de `ports:` — jamais exposé hors du réseau Docker interne.
|
||||
|
||||
tailscale:
|
||||
image: tailscale/tailscale:v1.98.3
|
||||
container_name: leadtech-mcp-ts
|
||||
restart: unless-stopped
|
||||
# ⚠ PAS de `hostname:` ici (collision DNS Docker service vs hostname,
|
||||
# cf. knowledge/infra/risques/docker.md). TS_HOSTNAME suffit côté tailnet.
|
||||
depends_on:
|
||||
- mcp
|
||||
environment:
|
||||
TS_AUTHKEY: ${LEADTECH_TS_AUTHKEY:?LEADTECH_TS_AUTHKEY manquant — voir .env.example}
|
||||
TS_HOSTNAME: leadtech-mcp
|
||||
TS_STATE_DIR: /var/lib/tailscale
|
||||
TS_SERVE_CONFIG: /config/serve.json
|
||||
TS_USERSPACE: "false"
|
||||
TS_EXTRA_ARGS: --accept-dns=false
|
||||
volumes:
|
||||
- /srv/docker-data/leadtech-mcp/tailscale/state:/var/lib/tailscale
|
||||
- ./tailscale/serve.json:/config/serve.json:ro
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_MODULE
|
||||
networks:
|
||||
- internal
|
||||
labels:
|
||||
- "homepage.group=Infra"
|
||||
- "homepage.name=Lead_tech MCP"
|
||||
- "homepage.href=https://leadtech-mcp.wyvern-snapper.ts.net/mcp"
|
||||
|
||||
networks:
|
||||
internal:
|
||||
name: leadtech-mcp-internal
|
||||
driver: bridge
|
||||
Reference in New Issue
Block a user