Documentation technique
Intégration MCP
FAIDEROCK expose ses outils via un serveur MCP (Model Context Protocol). Un assistant compatible — Claude, ChatGPT, Cursor, Codex ou le chat Lovable — s'y connecte, s'authentifie en tant que membre FAIDEROCK, puis appelle les outils de l'Académie, de GHOST et de la boutique. L'accès est protégé par OAuth 2.1 : chaque client agit au nom du membre connecté.
01
Points d'entrée
| Endpoint MCP | https://faiderock.lovable.app/mcp |
|---|---|
| Métadonnées de ressource | https://faiderock.lovable.app/.well-known/oauth-protected-resource |
| Page de consentement | https://faiderock.lovable.app/.lovable/oauth/consent |
| Transport | Streamable HTTP (JSON-RPC 2.0) |
| Nom du serveur | faiderock-luxe-ai-ecosystem |
| Version | 0.1.0 |
| Authentification | OAuth 2.1 — audience authenticated |
L'enregistrement dynamique des clients (DCR) est activé : aucune clé ni identifiant client à créer à la main.
02
Connecter un client
- 1 — Dans le client MCP, ajouter un serveur distant et coller https://faiderock.lovable.app/mcp.
- 2 — Le client découvre les métadonnées OAuth et s'enregistre automatiquement.
- 3 — Une fenêtre s'ouvre sur FAIDEROCK : se connecter (email ou Google).
- 4 — La page de consentement affiche le client demandeur. Approuver.
- 5 — Le client reçoit son jeton et liste les outils. La connexion est prête.
Le jeton est émis pendant ce flux OAuth. Un jeton de session de l'application copié à la main est rejeté.
03
Outils exposés
| Outil | Rôle | Entrées | Scope requis | Nature |
|---|---|---|---|---|
| get_my_access | Niveau GHOST et scopes du membre | — | authentification seule | Lecture |
| list_academy_tracks | Lister les parcours et leurs modules | — | academy:read | Lecture |
| get_academy_module | Lire un module complet | slug | academy:read + module:<niveau> | Lecture |
| get_my_progress | Progression du membre connecté | — | academy:read | Lecture |
| set_module_progress | Mettre à jour statut et score | module_slug, status, score? | academy:write + module:<niveau> | Écriture |
| submit_ghost_application | Déposer une candidature GHOST | full_name, email, tier, objectives | ghost:apply | Écriture |
| search_shop_products | Rechercher dans la boutique | query?, limit? | shop:read | Lecture |
// get_academy_module — entrée
{ "slug": "gov-audit" }
// sortie (structuredContent)
{
"module": {
"slug": "gov-audit",
"title": "Évaluation, traçabilité et audit des modèles",
"level": "vip",
"duration_min": 35,
"objectives": ["…"],
"tracks": { "slug": "gouvernance", "title": "Gouvernance IA avancée" }
}
}
// set_module_progress — entrée
{ "module_slug": "gov-cadre", "status": "completed", "score": 90 }
// search_shop_products — entrée
{ "query": "casquette", "limit": 5 }04
Exemples de requêtes
En-têtes obligatoires sur chaque POST :
Content-Type: application/json
Accept: application/json, text/event-stream
Authorization: Bearer <access_token>curl -sS https://faiderock.lovable.app/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": { "name": "curl", "version": "1.0" }
}
}'curl -sS https://faiderock.lovable.app/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $TOKEN" \
-d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }'curl -sS https://faiderock.lovable.app/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_academy_module",
"arguments": { "slug": "gov-audit" }
}
}'{ "error": "unauthorized" }
# accompagné d'un en-tête WWW-Authenticate pointant vers
# /.well-known/oauth-protected-resource05
Erreurs OAuth et diagnostic
| Symptôme | Cause probable | Correction |
|---|---|---|
| 401 unauthorized sur /mcp | Jeton absent, expiré, ou jeton de session applicatif copié | Refaire le flux OAuth depuis le client ; ne jamais coller un jeton de session |
| 406 Not Acceptable | En-tête Accept incomplet | Envoyer Accept: application/json, text/event-stream |
| Retour sur l'accueil au lieu du consentement | URL de retour perdue pendant la connexion | Relancer depuis le client ; l'URL de consentement doit contenir authorization_id |
| invalid_client / échec d'enregistrement | Client incompatible avec l'enregistrement dynamique | Utiliser un client supportant DCR, ou demander un client déclaré manuellement |
| redirect_uri refusée | URL de rappel hors liste autorisée | Ajouter l'URL exacte (schéma, hôte, port, chemin) à la liste autorisée |
| issuer mismatch | Le client interroge un domaine différent de l'émetteur publié | Utiliser l'émetteur annoncé par les métadonnées de découverte |
| « Authentification requise » renvoyé par un outil | Appel effectué hors session validée | Vérifier que le jeton est joint à l'appel et non expiré |
| tools/list vide | Connexion non finalisée | Vérifier que le consentement a été approuvé et que le connecteur est prêt |
06
Limites
- — Les données Académie et GHOST sont propres au membre authentifié : les règles d'accès de la base s'appliquent au jeton transmis.
- — search_shop_products interroge le catalogue public et ne nécessite pas de session.
- — Les appels d'outils sont synchrones et doivent rester courts ; les traitements longs restent dans l'application.
- — Les niveaux VIP et Elite sont attribués manuellement après revue ; aucun outil MCP ne modifie le niveau d'un membre.
07
Jetons et renouvellement automatique
Le jeton d'accès est de courte durée. Le renouvellement est automatique : le client MCP conserve un refresh_token et le rejoue sur le point de jeton, sans intervention. Aucune reconnexion n'est nécessaire à l'expiration.
| Grants supportés | authorization_code, refresh_token |
|---|---|
| Scopes supportés | openid, profile, email, phone, offline_access |
| Signature | ES256 (clé publique via JWKS) |
À l'expiration, le point MCP renvoie le signal qui déclenche le renouvellement silencieux côté client :
HTTP/1.1 401
WWW-Authenticate: Bearer realm="mcp",
resource_metadata="https://faiderock.lovable.app/.well-known/oauth-protected-resource",
error="invalid_token", error_description="…"
{ "error": "unauthorized" }curl -sS https://<project-ref>.supabase.co/auth/v1/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=$REFRESH_TOKEN" \
-d "client_id=$CLIENT_ID"Une reconnexion complète reste nécessaire uniquement si :
- — le consentement a été révoqué par le membre ;
- — le client OAuth a été supprimé ou ré-enregistré ;
- — le refresh token a expiré après une longue inactivité ;
- — le client n'a pas demandé le scope offline_access et n'a donc jamais reçu de refresh token.
08
Scopes par niveau — Access, VIP, Elite
L'accès aux outils est découpé en scopes applicatifs, attribués selon le niveau GHOST du membre.
| Scope | Autorise | Niveau minimal |
|---|---|---|
| shop:read | Recherche dans la boutique | Access |
| academy:read | Parcours, modules, progression | Access |
| academy:write | Enregistrer statut et score | Access |
| ghost:apply | Déposer une candidature GHOST | Access |
| module:access | Contenu des modules niveau Access | Access |
| module:vip | Contenu des modules niveau VIP | VIP |
| module:elite | Contenu des modules niveau Elite | Elite |
Le serveur d'autorisation n'émet que des scopes d'identité : il ne peut pas signer un scope métier. Ces scopes sont donc résolus côté serveur, à chaque appel d'outil, à partir du niveau attribué en base. C'est plus strict qu'un scope porté par le jeton — un client ne peut pas demander un scope qu'il n'a pas, et retirer un niveau prend effet immédiatement, sans attendre l'expiration du jeton.
Un appel hors scope échoue proprement, sans divulguer le contenu :
{
"content": [{
"type": "text",
"text": "Accès refusé : le scope "module:vip" requiert le niveau VIP. Votre niveau actuel est Access."
}],
"isError": true
}- — list_academy_tracks renvoie required_scope et unlocked par module : le client filtre avant d'appeler.
- — get_my_access renvoie le niveau, les scopes courants et la table complète des niveaux.
- — Les niveaux VIP et Elite sont attribués manuellement après revue ; aucun outil MCP ne peut élever le niveau d'un membre.