MCP form vs URL elicitation : demander des données utilisateur en sécurité
Un choix pratique entre form et URL elicitation dans MCP : capability negotiation, données sensibles, OAuth tiers, completion, contrôles anti-phishing, tests et rollout.
Sommaire de l’article
- 01Réponse courte : le formulaire collecte les champs non secrets, l’URL isole les interactions sensibles
- 02Capability negotiation détermine l’UX disponible avant la première requête
- 03Le mode form exige un schéma minimal, une preview et une double validation
- 04Le mode URL sépare le consentement à naviguer de l’achèvement du flow externe
- 05L’autorisation tierce ne doit pas être confondue avec l’autorisation du client MCP
- 06La matrice de tests valide privacy, association et recovery
- 07Le rollout commence par un formulaire read-only et un seul flow URL allowlisted
Réponse courte : le formulaire collecte les champs non secrets, l’URL isole les interactions sensibles
Utilisez le mode form pour un petit ensemble de réponses structurées non secrètes que l’utilisateur peut vérifier et envoyer dans le client MCP : nom d’environnement, format de rapport, plage de dates ou confirmation de paramètres. Le mode URL convient lorsque l’interaction implique un mot de passe, une API key, un access token, des données de paiement ou une autorisation tierce. Ces valeurs sont saisies hors du client et ne sont pas renvoyées dans le content d’ElicitResult.
Elicitation n’autorise pas le modèle à agir et ne remplace pas authorization. Elle donne seulement au serveur un moyen contrôlé de demander la participation de l’utilisateur pendant une requête d’origine. Après la réponse, le serveur revérifie identity, scope, business policy et état courant de l’objet. Si le système autoritatif connaît déjà la valeur ou si la question n’est pas nécessaire à l’exécution, n’utilisez pas elicitation : chaque prompt supplémentaire augmente la friction et la surface de phishing.
- Champs primitifs non secrets → mode form.
- Credentials, paiement ou OAuth externe → mode URL.
- Validation d’une action à conséquences → gate de policy/approval séparé, pas un champ de formulaire arbitraire.
- Le client n’annonce pas le mode requis → fallback contrôlé ou refus.
- La valeur autoritative existe déjà → la lire dans le system of record.
Capability negotiation détermine l’UX disponible avant la première requête
Le client annonce la capability elicitation pendant l’initialisation et les modes form et/ou URL pris en charge. Un objet elicitation vide est compatible avec un comportement form-only ; le serveur ne doit pas l’interpréter comme un support URL. Conservez le capability manifest de session avec les versions négociées du protocole et de l’implémentation, puis vérifiez le mode requis avant elicitation/create. Le nom d’une application ou la présence d’un bouton dans un client ne prouve pas la compatibilité d’un autre deployment.
L’elicitation server-to-client doit être associée à une requête client d’origine, par exemple tools/call ou resources/read. Ne construisez pas un canal indépendant pour des prompts non sollicités. Le routeur détermine le besoin avant tout side effect : form-supported, URL-supported, fallback sans elicitation ou blocked. Si un workflow ne peut pas obtenir un credential en sécurité sans mode URL, le bon fallback est un lien de setup hors workflow ou un refus clair, pas une demande de secret dans un champ texte.
Le mode form exige un schéma minimal, une preview et une double validation
Une requête form contient un message lisible et un JSON Schema restreint : un objet plat composé de propriétés primitives. La restriction est utile car elle maintient elicitation comme interaction courte au lieu d’en faire une plateforme de formulaires cachée. Les noms, descriptions, valeurs par défaut, labels enum et champs required doivent expliquer la conséquence de la réponse. N’insérez pas d’URL cliquable dans les champs et ne demandez pas de secret même si le schema peut techniquement accepter une string.
Le client permet à l’utilisateur de vérifier, modifier, accept, decline ou cancel la réponse et valide le content contre le schema. Le serveur répète la validation du schema et du domaine : plage, appartenance au tenant, existence de l’objet, version actuelle et transitions autorisées. Accept signifie que l’utilisateur a envoyé des valeurs ; cela n’approuve pas automatiquement une action à haut risque ultérieure. Decline termine la requête sans default caché et cancel ne doit pas être interprété comme une décision métier négative.
- Ne collecter que les champs nécessaires à la requête courante.
- Séparer la validité du schema de l’autorisation métier.
- Ne pas journaliser tout le content sans finalité de rétention et data classification.
- Après decline ou cancel, ne pas répéter le prompt dans une agent loop infinie.
L’autorisation tierce ne doit pas être confondue avec l’autorisation du client MCP
MCP authorization protège l’accès du client au serveur MCP. URL elicitation répond à un autre besoin : le serveur demande à l’utilisateur de connecter un service downstream ou de terminer une interaction out-of-band sécurisée. Le bearer token entre client et serveur MCP ne change pas pendant ce flow. Ne renvoyez jamais un downstream token via model context, tool result ou form content ; le serveur stocke le credential dans un vault administré et le lie à une identity et un scope vérifiés.
L’URL de connexion doit résister au phishing relay. Le serveur vérifie que l’utilisateur du navigateur est le même subject autoritatif pour lequel l’elicitation a été créée au lieu de faire confiance à un email ou un nom reçu dans un query parameter. State et nonce sont à usage unique, de courte durée et liés au provider et au redirect target. Le callback vérifie issuer, audience, state et redirect URI autorisée. Réouverture, changement d’utilisateur ou record expiré se terminent sans attacher de credential.
- MCP token → accès client-vers-serveur.
- Downstream grant → accès serveur-vers-tiers pour un utilisateur ou tenant précis.
- elicitationId → identifiant de corrélation, pas preuve d’identity ni de completion.
- Browser session + subject vérifié → liaison autoritative.
La matrice de tests valide privacy, association et recovery
Les contract tests couvrent initialization avec form-only, URL-only, les deux modes et sans elicitation ; mode omis traité comme form ; mode non pris en charge ; accept, decline et cancel ; rejet du schema ; completion ID inconnu ou dupliqué ; et association à la requête. Les cas URL vérifient que le client ne précharge pas l’adresse, affiche le host, exige le consentement et ne renvoie pas de contenu externe dans le protocol result. Les cas form bloquent les fixtures password, token, API key et paiement quel que soit le nom du champ.
Les security tests tentent de modifier elicitationId, tenant, provider, redirect, state et browser subject, rejouer un callback, utiliser une URL expirée, substituer un host Punycode ou lire un secret dans les logs ou traces. Les recovery tests perdent accept response, completion notification et originating retry. Les assertions imposent une reprise idempotente : un tool request répété réconcilie d’abord elicitation state et downstream connection au lieu de créer un second OAuth grant ou paiement.
- Hard gate → secret dans form, navigation automatique, identity mismatch ou credential leakage.
- Protocol gate → requête sans association ou mode sans capability.
- Recovery gate → une notification perdue ne doit pas créer un effet externe dupliqué.
- UX gate → serveur, objectif, domaine et decline/cancel sont clairs avant le consentement.
Le rollout commence par un formulaire read-only et un seul flow URL allowlisted
Commencez avec le mode form pour un workflow réversible read-only comportant deux ou trois champs non secrets. Mesurez completion, decline/cancel, validation failures, prompts répétés et time-to-resume sans enregistrer les raw values dans la telemetry générale. Ajoutez ensuite un seul URL flow vers une origine HTTPS allowlisted avec redirect policy épinglée, identity binding vérifié, expiration, replay protection, stockage en vault, audit evidence et kill switch.
Ne promouvez le canary qu’après réussite des gates contract, privacy, phishing, recovery et accessibility. Le rollback bloque les nouvelles elicitation requests, conserve la reconciliation pour les records in-flight, révoque les state handles inachevés et restaure un manual setup path documenté. Retestez après modification de la MCP revision, du SDK/client, du capability manifest, du browser container, de l’identity provider, de la configuration OAuth downstream ou de la data classification. Le verdict concerne toujours une combinaison client-serveur-flow précise, jamais une sécurité universelle du mode URL.
Exemples pratiques
Formulaire pour paramètres d’export read-only
Le tool n’a pas le format ni la période du rapport. Le serveur demande un format enum et une plage de dates, le client affiche une preview et le serveur revalide plage et tenant. Decline termine l’export sans side effect ; aucun credential n’est collecté.
URL pour connecter un CRM
Le serveur crée un elicitation record de courte durée et affiche une URL HTTPS allowlisted. L’utilisateur du navigateur effectue l’OAuth tiers, le callback vérifie subject et state, puis le token va directement dans le vault serveur. Le client reçoit un signal de completion mais ne voit jamais le credential.
FAQ
Peut-on demander une API key avec form elicitation ?
Non. La spécification interdit le mode form pour les mots de passe, API keys, access tokens et données de paiement. Utilisez le mode URL avec un flow out-of-band sécurisé.
Accept en mode URL signifie-t-il qu’OAuth est terminé ?
Non. Il indique uniquement le consentement à naviguer vers l’URL. Un flow server-side confirme completion ; une completion notification peut informer le client, mais retry et reconciliation restent nécessaires.
URL elicitation remplace-t-elle MCP authorization ?
Non. MCP authorization contrôle l’accès client-vers-serveur. URL elicitation peut obtenir un grant tiers pour le serveur sans modifier le bearer token du client.
Que faire si le client ne prend en charge que le mode form ?
N’envoyez pas de requête URL. Proposez un manual setup path sûr hors workflow, un autre client compatible ou terminez avec une erreur claire ; ne collectez jamais le secret dans form comme fallback.
Contenus associés
Une architecture de production pratique pour la supervision humaine : faire intervenir une personne à un point de risque précis avec assez de contexte pour un contrôle réel, et non purement formel. Couvre les contrats, limites d’autorité, modes de défaillance, évaluation et déploiement contrôlé.
MCP Tasks vs tool calls synchrones : exécuter des opérations longuesUn choix pratique entre MCP tools/call standard et MCP Tasks expérimentales pour les opérations longues : capability negotiation, états, polling, annulation, sécurité, tests et rollout.