Objectif : partir du starter-kit et obtenir un MCP minimal qui démarre, expose
/mcp,/admin, une CLI, un shell et au moins un tool métier.
Ce guide est volontairement générique. Les règles métier d'un MCP concret doivent rester dans le repo du MCP concret.
Options possibles :
- utiliser GitHub comme template si le repo est configuré ainsi ;
- forker le repo ;
- copier le contenu du dossier
boilerplate/vers un nouveau repo.
Nom recommandé :
mcp-<domain>
Exemples :
mcp-legifrance
mcp-tools
mcp-office
À adapter :
mon_service -> <python_package>
mon-mcp-service -> <mcp-service-name>
Mon Service MCP -> <display name>
Fichiers typiques :
src/mon_service/
scripts/mcp_cli.py
Dockerfile
docker-compose.yml
.env.example
README.md
Après renommage, vérifier :
python -m <python_package>
python scripts/mcp_cli.py --helpDans .env.example et .env :
MCP_BRAND=ctValeurs supportées :
ct Cloud Temple
dgy Dragonfly
isec Intrinsec
Vérifier :
curl http://localhost:8082/admin/api/brandAjouter le tool dans :
src/<python_package>/server.py
Règles :
- utiliser
@mcp.tool(); - typer les paramètres avec
Annotated[..., Field(description=...)]; - retourner un dict JSON-serializable ;
- borner les réponses (
limit,max_chars,offsetsi nécessaire) ; - refuser les chemins ou entrées dangereuses ;
- ne pas exposer de secrets.
Exemple minimal :
from typing import Annotated
from pydantic import Field
@mcp.tool()
async def my_readonly_lookup(
identifier: Annotated[str, Field(description="Business identifier to resolve")],
) -> dict:
"""Resolve a business identifier."""
return {
"status": "ok",
"identifier": identifier,
}Le starter-kit fournit déjà les commandes système et token.
Pour un tool métier important, ajouter une commande dans :
scripts/cli/commands.py
scripts/cli/shell.py
scripts/cli/display.py
Le starter-kit ne doit pas contenir toutes les commandes métier possibles, mais il doit montrer comment en ajouter.
Sans S3/Vault configuré, seul le bootstrap admin fonctionne.
Configurer :
TOKEN_STORE_BACKEND=s3
S3_ENDPOINT_URL=...
S3_BUCKET_NAME=...Configurer :
TOKEN_STORE_BACKEND=vault
MCP_VAULT_ID=<mcp-vault-id>
MCP_VAULT_TOKEN_FILE=/run/secrets/mcp_vault_token
MCP_VAULT_TOKEN_STORE_PATH=token-store/tokens.jsonVoir aussi :
docs/server-deployment.md
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt pytest pytest-asyncio
python -m pytest tests -qSi le projet a des tests Docker Compose :
docker compose -f docker-compose.ci.yml up -d --build
RUN_COMPOSE_E2E=1 python -m pytest tests/e2e -q
docker compose -f docker-compose.ci.yml down -vdocker compose up -d --buildVérifier :
curl http://localhost:8082/health
curl http://localhost:8082/admin/api/brandConsole admin :
http://localhost:8082/admin
python scripts/mcp_cli.py \
--url http://localhost:8082 \
--token "$ADMIN_BOOTSTRAP_KEY" \
token create local-client --permissions read --expires 7Tester ensuite le client MCP avec :
http://localhost:8082/mcp
Authorization: Bearer <MCP_CLIENT_TOKEN>
- package renommé proprement ;
- service name configuré ;
- branding choisi ;
-
/healthOK ; -
/adminOK ; -
/mcpOK avec token client ; - CLI et shell OK ;
- token create/list/revoke OK ;
- au moins un tool métier testé ;
- réponses métier bornées ;
- aucun secret en git ;
- WAF actif ;
- docs serveur/client adaptées au MCP.
Le MCP mcp-legifrance a servi de premier smoke test réel du starter-kit : un MCP métier read-only créé depuis ce socle, déployé en production et utilisé avec un client MCP.
La leçon principale est que le starter-kit doit fournir des guides opérationnels courts :
- déploiement serveur ;
- distinction token Vault applicatif vs token client MCP ;
- configuration client final ;
- smoke test de création d'un MCP réel.