Le bouton Connecter connecte désormais
Approuver un assistant ne faisait rien. La page disait que le formulaire ne venait pas d’ici, et elle avait raison d’une façon qui était fausse : la page d’approbation demandait aux navigateurs de n’envoyer aucun référent, et Chrome déduit l’origine d’une page de ce même réglage — le formulaire de la page elle-même arrivait donc en prétendant venir de nulle part, et la vérification censée empêcher un autre site d’approuver des choses en votre nom arrêtait la page elle-même.
Rien n’avait jamais été connecté par ce biais. Les tests ne pouvaient pas le voir, car un test n’est pas un navigateur et envoie les en-têtes qu’on lui demande d’envoyer ; la base de données, elle, le pouvait, et le disait clairement : chaque requête affichée, aucune jamais approuvée.
Derrière cela se trouvait un second problème. La page indique au navigateur qu’il ne peut vous renvoyer qu’à l’assistant qui a demandé — et elle disait qu’elle ne pouvait vous renvoyer que vers nous-mêmes, si bien qu’approuver fonctionnait et que le retour vers l’assistant était refusé par la page elle-même. Elle ne nomme désormais plus que cette seule adresse.
Approuver un assistant, c’est une page et un bouton — voici ce qu’il y a derrière.
Ce que l’approbation fait réellement
Vous vous connectez ici avec votre compte, lisez une page qui nomme le client et l’adresse pour laquelle il va agir, et appuyez sur Connecter. Le client emporte un jeton émis par ce site — ni votre session, ni une clé API — qui n’atteint que les documents du compte, rien de plus : pas le compte, pas la connexion, pas vos clés API. Une connexion en lecture seule ne peut ni enregistrer, partager ni supprimer, imposé sur l’identifiant plutôt que sur les outils.
TransformPipe doit être son propre serveur d’autorisation pour cela : la spécification MCP interdit à une ressource d’accepter un jeton émis par quelqu’un d’autre, la session de connexion ne peut donc pas simplement être transmise.
L’ordre des événements
- L’assistant envoie un POST à
/api/mcpsans jeton et reçoit un 401 indiquant où chercher. - Il lit
/.well-known/oauth-protected-resource, puis/.well-known/oauth-authorization-server, pour trouver les points d’accès. - Il s’identifie — par un document de métadonnées publié, ou en s’enregistrant ici. Aucun secret dans les deux cas : un client sur la machine de quelqu’un d’autre ne peut en garder un, et c’est à cela que sert PKCE.
- Il vous envoie vers
/authorizeavec un défi.code_challenge_method=S256est obligatoire ; un défi en clair est refusé net. - Vous approuvez par un POST depuis la page qui vous a été montrée, si bien qu’un simple lien n’autorise rien.
- Il échange le code et son vérificateur à
/token.
Ce que font les jetons par la suite
Un code vit cinq minutes et est brûlé au début de l’échange, avant toute vérification, si bien qu’une copie rejouée pendant le premier appel n’obtient rien. Les jetons de rafraîchissement tournent : en remettre un le révoque et délivre une paire neuve. En remettre un déjà tourné met fin à toute l’autorisation — accès, rafraîchissement et toutes les rotations précédentes — car un jeton présenté deux fois est le seul signal qu’il a été copié.
Retirez-le depuis le menu du compte, sous connecteur MCP ; il cesse de marcher au prochain appel.
Pourquoi le bouton n’avait jamais rien fait
Deux en-têtes sur notre page. Elle demandait aux navigateurs de n’envoyer aucun référent, et Chrome déduit l’Origin d’un POST de formulaire de ce même réglage : la soumission de la page arrivait donc en prétendant venir de nulle part, et la vérification censée empêcher un autre site d’approuver des choses en votre nom arrêtait la page elle-même. Derrière cela, le form-action ne nommait que ce site, si bien que le retour vers l’assistant était refusé après que le code avait déjà été émis. Elle ne nomme désormais que la seule adresse où la requête sera réellement envoyée.
Autres lectures : convertir des documents depuis un assistant, et un convertisseur en ligne est-il sûr.