Le point de terminaison MCP distant
Le serveur MCP est un outil de développement : il s’exécute sur votre
machine et détient une clé de service ou une clé d’API. Un backend déployé peut aussi
servir lui-même du MCP, sur /mcp, aux personnes qui utilisent votre application. Un
assistant que l’une d’elles connecte lit et écrit le projet en son nom, et chaque
appel s’exécute sous sa propre sécurité au niveau des lignes.
Il est désactivé tant que vous ne l’activez pas, et les deux variables sont obligatoires :
REBASE_MCP_ENABLED=trueREBASE_PUBLIC_URL=https://app.example.com # this deployment's real originSans REBASE_PUBLIC_URL, sans secret JWT, ou sans driver de données capable de restreindre
une requête à un seul utilisateur, le point de terminaison refuse de se monter et en donne
la raison dans le log de démarrage. Aucun REBASE_ROLE ne l’active.
- OAuth, avec un écran de consentement. Un client trouve le serveur d’autorisation
via
/.well-known/oauth-protected-resource, s’enregistre lui-même (l’enregistrement dynamique est activé par défaut ;REBASE_MCP_OPEN_REGISTRATION=falsele limite aux clients que vous enregistrez), et envoie la personne vers un écran de consentement qui la connecte via votre/auth/loginexistant. Un compte doté d’un second facteur doit ensuite saisir le code de son application d’authentification ou un code de récupération, via les routes/auth/mfa/challengeexistantes. L’écran ne se connecte que par mot de passe : quelqu’un qui n’a jamais utilisé que Google, GitHub ou un lien par e-mail en définit d’abord un avec/auth/forgot-password(le « Mot de passe oublié » de votre app), et l’écran le lui indique. Il nomme aussi l’hôte vers lequel le code d’autorisation est envoyé, et précise que cet hôte n’est pas vérifié : n’importe qui peut enregistrer un client sous n’importe quel nom, l’hôte est donc la partie qu’une personne peut vérifier. - Huit outils, trois portées. Les mêmes portées
que celles de chaque identifiant.
data:readproposelist_collections,describe_collection,query_collection,count_documentsetget_document;data:writeajoutecreate_documentetupdate_document;data:deleteajoutedelete_document. Un client qui ne demande rien obtientdata:read. Chacune peut se restreindre à une collection :data:read:postsliste, décrit et litpostset rien d’autre. Une portée décide quels outils sont proposés et quelles collections ils atteignent, pas quelles lignes : une liste vide peut être le RLS qui fait son travail, etdata:writene peut toujours pas écrire une ligne que la personne ne pourrait pas écrire elle-même. - Les autorisations accordées avant la 0.24 gardent leur étendue.
mcp:readest lu commedata:read, etmcp:writecommedata:write data:delete, sur les autorisations enregistrées et sur les jetons déjà émis. - Une clé d’API fonctionne aussi.
/mcpaccepte égalementAuthorization: Bearer rk_…, pour un client configuré avec un en-tête plutôt qu’avec un flux OAuth. La clé atteint les outils que ses portéesdata:*couvrent, en tant que l’identité pour laquelle elle agit : une clé personnelle en tant que son propriétaire, une clé de service en tant queapi-key:<id>. - Le vocabulaire du SDK, les réponses de REST. Les outils prennent ce que prend le SDK —
where({"status": ["==", "paid"]}),orderBy(["created_at", "desc"]ou"created_at:desc"),limit,offset,searchString, etdatapour une écriture — et lisent par le chemin deGET /api/data/<collection>, de sorte qu’une ligne revient telle que REST la sert (dates ISO, unebelongsTosous la forme de sa clé étrangère, p. ex.authorId) et peut être renvoyée telle quelle dans une mise à jour.query_collectionrépond{ data, meta }avecmeta.totaletmeta.hasMore, etcount_documents{ count }. Comme sur REST, unlimitsupérieur à 1000, un argument non déclaré et la modification ou la suppression d’une ligne placée dans la corbeille (404) sont refusés ; mettre le champ de soft delete ànullla restaure.deleted: "only"(ou"include") surquery_collectionetcount_documentslit la corbeille, comme le?deleted=de REST, de sorte qu’une ligne quedelete_documenta mise à la corbeille peut être retrouvée pour être restaurée. Sa description indique au modèle que la suppression n’est définitive que là où la collection n’a pas de champ de soft delete. - La liste nomme les collections ;
describe_collectiondonne le schéma de l’une d’elles.list_collectionsrépond, pour chaque collection, sonname, sontitleet sadescription, etdescribe_collection { collection }les schémas OpenAPIrowetcreatede cette collection, plussoftDeleteFieldlà où les lignes vont à la corbeille. Les descriptions des outils indiquent au modèle de décrire une collection avant d’y écrire. La liste d’un projet de 200 collections pèse environ 5k tokens, et chaque description moins de 1k ; avec tous les schémas dans la liste, cela faisait environ 150k. - Un jeton valable pour ce seul point de terminaison. Un jeton d’accès MCP est refusé par
/api/data,/api/adminet le WebSocket : connecter un assistant ne lui remet donc pas une session.
Chaque requête vers /mcp relit le compte de la personne. Un compte supprimé ou désactivé,
ou une « déconnexion partout » ou un changement de mot de passe survenu après l’émission du jeton,
arrête aussitôt un client connecté avec un 401. Une rétrogradation s’applique à son
prochain appel d’outil. Chaque rafraîchissement effectue les mêmes vérifications et refuse définitivement
une telle autorisation. Une session invité ne peut pas du tout donner son consentement.
Une limite. Déconnecter un client (DELETE /api/oauth/grants/:clientId, avec la
propre session de la personne) révoque aussitôt ses jetons de rafraîchissement, mais un jeton d’accès
déjà émis continue de fonctionner jusqu’à son expiration, dans l’heure.
Les routes figurent dans l’index des points de terminaison et les variables dans Configuration.