Serveur MCP pour l'API BoondManager (ERP/CRM des ESN) : 182 outils, 12 prompts et 22 ressources pour
5.7K
Serveur MCP (Model Context Protocol) pour l'API BoondManager en mode HTTP transport. Conçu pour les déploiements distants, gateways MCP et orchestrateurs multi-utilisateurs (LobeChat, Khoj, custom gateways).
158 outils, 6 prompts, 20 ressources exposés via une API HTTP/SSE. Documentation complète sur GitHub.
L'image est construite sur node:<LTS actif>-alpine, épinglée par digest multi-arch (Dependabot rafraîchit le digest chaque semaine). Politique : la ligne Node en Active LTS au moment de la release — jamais la ligne « current ». Node 24 est LTS depuis octobre 2025 ; Node 26 ne le devient qu'en octobre 2026, date à laquelle le Dockerfile passera à node:26-alpine. Le serveur lui-même exige Node ≥ 22 (engines), donc l'image de prod tourne toujours sur une version que la CI teste (matrice 22 / 24 / 26).
Deux registres, même image multi-architecture (linux/amd64 + linux/arm64) :
docker.io/fauguste/boondmanager-mcp-serverghcr.io/silamir/boondmanager-mcp-serverTags :
:2.0.0 (recommandé en production – version pinned):2.0 (dernier patch de la minor):2 (dernier minor de la major):latest (edge – demos uniquement)Les prereleases (2.1.0-alpha) publient uniquement le tag exact (:2.1.0-alpha), jamais :latest / :2.
docker pull fauguste/boondmanager-mcp-server:2.0.0
docker run -d \
--name boondmanager-mcp \
-p 3000:3000 \
-e MCP_TRANSPORT=http \
fauguste/boondmanager-mcp-server:2.0.0
Le serveur écoute sur http://0.0.0.0:3000/mcp (0.0.0.0 par défaut dans l'image Docker).
services:
boondmanager-mcp:
image: fauguste/boondmanager-mcp-server:2.0.0
container_name: boondmanager-mcp
ports:
- "3000:3000"
environment:
MCP_TRANSPORT: http
# Port/path (optionnels, defaults = 3000 / /mcp)
MCP_HTTP_PORT: 3000
MCP_HTTP_PATH: /mcp
# Public URL (requis derrière un reverse proxy)
MCP_HTTP_PUBLIC_URL: https://mcp.example.com/mcp
# Stateful sessions (optionnel, default = false)
MCP_HTTP_STATEFUL: "false"
# Logging
LOG_LEVEL: info
LOG_FORMAT: json
# BoondManager API base (optionnel si non-standard)
BOOND_BASE_URL: https://ui.boondmanager.com/api
restart: unless-stopped
L'image Docker fonctionne en mode HTTP transport uniquement. L'authentification se fait via OAuth2 :
access_token auprès de BoondManager via le flow Authorization Code.Authorization: Bearer <access_token>.Discovery : RFC 9728 protected-resource metadata publié à /.well-known/oauth-protected-resource + /.well-known/oauth-protected-resource/mcp. Les clients compatibles MCP l'utilisent pour auto-découvrir l'authorization server (BoondManager).
| Var | Défaut | Description |
|---|---|---|
MCP_HTTP_PUBLIC_URL | http://<host>:<port><path> | URL publique advertised dans le discovery metadata. Obligatoire derrière un reverse proxy. |
BOOND_OAUTH_AUTHORIZATION_SERVER | https://ui.boondmanager.com | Issuer URL de BoondManager, advertised dans authorization_servers. |
BOOND_OAUTH_SCOPES | (vide) | Scopes space/comma-separated advertised dans scopes_supported. Vide = négociation directe client-Boond. |
BOOND_HTTP_STATIC_AUTH | false | true : credentials d'environnement (BOOND_USER_TOKEN+BOOND_CLIENT_TOKEN+BOOND_CLIENT_KEY ou BOOND_API_TOKEN) pour toutes les requêtes, sans Bearer OAuth. Plus aucune authentification client : l'image bind 0.0.0.0, donc MCP_HTTP_API_KEY est obligatoire (le conteneur refuse de démarrer sans). |
MCP_HTTP_API_KEY | (vide) | Static auth : secret que le client envoie en Authorization: Bearer <clé> ou X-Api-Key: <clé>. Absent/faux → 401. |
MCP_HTTP_INSECURE_STATIC_AUTH | false | 1 pour démarrer en static auth sans clé hors loopback (réseau privé = frontière). Explicitement nommé « insecure ». |
Documentation complète : docs/oauth.md sur GitHub.
| Var | Défaut | Description |
|---|---|---|
MCP_TRANSPORT | stdio | Obligatoire : mettre http pour activer le transport HTTP |
MCP_HTTP_HOST | 127.0.0.1 (Node), 0.0.0.0 (Docker) | Interface d'écoute. L'image Docker override à 0.0.0.0 pour bind all interfaces. |
MCP_HTTP_PORT | 3000 | Port TCP |
MCP_HTTP_PATH | /mcp | Endpoint path |
MCP_HTTP_STATEFUL | false | true pour activer les sessions Mcp-Session-Id |
MCP_HTTP_JSON_RESPONSE | false | true pour retourner JSON au lieu de streams SSE |
MCP_HTTP_SESSION_TTL_MS | 1800000 (30 min) | Stateful only : idle window avant fermeture session |
MCP_HTTP_SESSION_SWEEP_INTERVAL_MS | 300000 (5 min) | Stateful only : fréquence du sweep des sessions idle |
MCP_HTTP_ALLOWED_HOSTS | localhost,127.0.0.1,[::1] (loopback) ou disabled (other) | Comma-separated allowlist de Host header hostnames (protection DNS rebinding CVE-2025-66414). * = opt-out explicite (reverse proxy only). |
MCP_HTTP_ALLOWED_ORIGINS | toute origine loopback + MCP_HTTP_PUBLIC_URL (loopback) ou disabled (other) | Comma-separated allowlist de valeurs Origin (scheme + host + port) ; Origin hors liste → 403 (exigence spec MCP 2025-11-25). Requête sans Origin toujours acceptée (curl, gateways) ; /healthz et /.well-known/oauth-protected-resource exemptés. * = opt-out explicite (une valeur vide n'en est pas une). Dans l'image Docker (MCP_HTTP_HOST=0.0.0.0), la validation est désactivée par défaut : la définir explicitement si le serveur est appelé depuis un navigateur. |
MCP_HTTP_VALIDATE_TOKEN | false | Mode OAuth : valide chaque Bearer auprès de BoondManager avant dispatch (cache par token, MCP_HTTP_TOKEN_VALIDATION_TTL_MS = 60 s) ; token expiré/révoqué → 401 + error="invalid_token", que les clients conformes transforment en nouvelle autorisation. |
| Var | Défaut | Description |
|---|---|---|
BOOND_BASE_URL | https://ui.boondmanager.com/api | Base URL de l'API BoondManager |
BOOND_HTTP_TIMEOUT_MS | 30000 | Timeout par requête (ms) |
BOOND_HTTP_MAX_RETRIES | 2 | Nombre de tentatives supplémentaires après échec. 0 = désactiver retries. |
BOOND_HTTP_RETRY_BASE_MS | 200 | Backoff exponentiel avec full-jitter : base (ms) |
BOOND_HTTP_RETRY_MAX_MS | 5000 | Backoff max (ms) |
BOOND_HTTP_RATE_LIMIT_RPS | 10 | Client-side token bucket : requêtes/sec, par utilisateur (identité dérivée du Bearer OAuth). 0 = désactiver. |
BOOND_HTTP_RATE_LIMIT_BURST | 20 | Taille du burst autorisé |
| Var | Défaut | Description |
|---|---|---|
LOG_LEVEL | info | trace, debug, info, warn, error, fatal |
LOG_FORMAT | json (prod) / pretty (dev) | json (structured, machine-readable) ou pretty (colorized, human-friendly) |
services:
traefik:
image: traefik:v3.0
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command:
- "--providers.docker=true"
- "--entrypoints.websecure.address=:443"
- "[email protected]"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
boondmanager-mcp:
image: fauguste/boondmanager-mcp-server:2.0.0
environment:
MCP_TRANSPORT: http
MCP_HTTP_PUBLIC_URL: https://mcp.example.com/mcp
LOG_LEVEL: info
LOG_FORMAT: json
labels:
- "traefik.enable=true"
- "traefik.http.routers.mcp.rule=Host(`mcp.example.com`) && PathPrefix(`/mcp`)"
- "traefik.http.routers.mcp.entrypoints=websecure"
- "traefik.http.routers.mcp.tls.certresolver=letsencrypt"
- "traefik.http.services.mcp.loadbalancer.server.port=3000"
restart: unless-stopped
Important : MCP_HTTP_PUBLIC_URL doit pointer vers l'URL publique (celle vue par le client MCP), pas l'adresse interne Docker. Sinon le discovery metadata publiera l'URL interne et le client ne pourra pas atteindre le serveur OAuth.
CRM & Commercial : Candidats (10 tools), Ressources (15), Contacts (11), Sociétés (14), Opportunités (10)
Projets : Projets (12), Positionnements (4), Livraisons/CRA (2), Achats (4)
Facturation : Factures client (5), Factures fournisseur (2), Bons de commande (5), Paiements (2), Notes de frais (5), Produits (5)
RH & Temps : Absences (5), Planning absences (1), Feuilles de temps (3), Contrats (2), Avantages (2)
Suivi d'activité : Actions (4), Validations (2), Todolists (2)
Reporting : Sociétés, Projets, Ressources, Synthèse, Plans de production (1 chacun)
Administration : Comptes (2), Agences (2), Business Units (2), Poles (2), Roles (2), Calendriers (2), Drapeaux (2), Webhooks (2), Logs audit (2), Notifications (2), Fils de discussion (2), Application (2)
Catalogue complet : TOOLS.md
Le serveur n'expose pas de route /health dédiée — le check se fait via une requête MCP initialize. Exemple Docker healthcheck :
healthcheck:
test: ["CMD", "curl", "-f", "-X", "POST", "http://localhost:3000/mcp", "-H", "Content-Type: application/json", "-d", '{"method":"initialize","jsonrpc":"2.0","id":1,"params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"healthcheck","version":"1.0"}}}']
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
Réponse 200 = serveur opérationnel (les appels MCP réels échoueront sans Authorization: Bearer valide, mais le healthcheck lui-même ne nécessite pas d'auth pour le check basique).
Chaque image publiée inclut :
Vérification :
docker buildx imagetools inspect \
--format "{{ json .Provenance }}" \
fauguste/boondmanager-mcp-server:2.0.0
CHANGELOG.mdContributions welcome via pull requests. Tests requis (npm test) avant merge.
Multi-arch ready : linux/amd64 + linux/arm64 (x86 servers + Apple Silicon / Graviton).
Content type
Image
Digest
sha256:3c46305e6…
Size
68.4 MB
Last updated
5 days ago
docker pull fauguste/boondmanager-mcp-server