Aller au contenu principal
Principal11 min1951 mots

MCP tools vs resources vs prompts : quand les utiliser

Comparaison pratique des tools, resources et prompts MCP : contrôle, discovery, schémas, permissions, fraîcheur, UX, tests et conception sûre du serveur.

Sommaire de l’article
  1. 01Réponse courte : action, contexte et modèle d’interaction sont des contrats distincts
  2. 02Le control plane façonne l’UX mais n’accorde pas l’autorisation
  3. 03Tools : contrat d’opération typé avec le plus fort risque d’autorité
  4. 04Resources : URI, fraîcheur et budget de contexte doivent être explicites
  5. 05Prompts : workflow réutilisable avec arguments visibles, pas une policy boundary
  6. 06Decision matrix et anti-patterns pour un workflow métier
  7. 07Contract tests, canary rollout et rollback

Réponse courte : action, contexte et modèle d’interaction sont des contrats distincts

Un tool MCP décrit une opération que le modèle peut proposer d’appeler avec des arguments typés : rechercher une commande, calculer un tarif ou créer un brouillon. Une resource fournit du contexte que l’application hôte peut lire par URI et ajouter à la conversation : fichier, schéma, référence ou snapshot. Un prompt est un modèle paramétré de messages que l’utilisateur choisit consciemment pour un workflow réutilisable. Ce sont trois control planes différents, pas trois façons de publier la même fonction.

Choisissez le primitive selon le propriétaire de l’étape suivante. Utilisez un tool pour une opération externe ou un lookup autoritatif avec paramètres runtime. Utilisez une resource lorsque l’utilisateur ou l’application doit sélectionner et lire un contenu comme contexte. Utilisez un prompt quand le produit a besoin d’une commande de départ visible avec arguments et messages préparés. Un même server peut combiner les trois : le prompt structure la tâche, la resource apporte la policy, le tool réalise le lookup autorisé. Prompt ou resource ne doivent pas masquer un side effect, et un tool ne devrait pas servir uniquement à transporter du texte statique.

  • Modifie ou calcule un état à partir du runtime input → tool.
  • Fournit un contenu adressable comme contexte → resource.
  • Démarre une interaction réutilisable choisie par l’utilisateur → prompt.
  • Nécessite deux rôles → composer des primitives avec des contrats séparés.

Le control plane façonne l’UX mais n’accorde pas l’autorisation

La spécification décrit les tools comme model-controlled : un client peut les exposer au modèle et lui permettre de choisir un appel. Pour une opération sensible, le client devrait afficher les inputs et permettre à une personne de refuser. Les resources sont application-driven : l’hôte décide d’un picker, d’une recherche, d’une inclusion automatique ou d’une autre interface. Les prompts sont user-controlled et pensés comme commandes ou templates accessibles à l’utilisateur, sans UI imposée par le protocole.

Ces labels ne constituent pas une autorisation. Le choix d’un tool par le modèle ne donne aucun droit sur un side effect ; sélectionner une resource ne prouve pas l’accès à chaque URI ; lancer un prompt n’autorise pas toutes les actions décrites dans son texte. Client et server valident séparément identity, scopes, tenant, target et état courant. Une action conséquente exige preview, confirmation ou policy gate au moment de l’exécution, et non la confiance dans un choix antérieur de prompt.

Tools : contrat d’opération typé avec le plus fort risque d’autorité

Une définition de tool a besoin d’un name stable, d’une description claire et d’un JSON Schema valide pour l’input. Un outputSchema optionnel permet au client de valider structuredContent ; c’est utile pour l’automatisation downstream mais cela ne prouve pas la véracité des données. Le server valide schema et contraintes métier, vérifie la permission sur l’objet concret et renvoie un tool execution error pour les erreurs de domaine récupérables. Réservez les protocol errors aux requests mal formées ou tools inconnus.

Séparez les opérations read et write. `orders.get` peut être un lookup à faible risque, tandis que `orders.refund` devrait exiger amount, currency, order version, reason, idempotency key et approval receipt. Évitez un `execute_api` universel avec path et body arbitraires : il masque l’autorité au modèle, au reviewer et à l’audit log. Les tool annotations sont des indications UX utiles, pas une security policy fiable sans confiance dans le server.

Un tool result peut contenir text, structured content, resource link ou embedded resource. Cela ne transforme pas le tool en resource : l’appel reste une opération avec inputs, timeout, sémantique d’erreur et audit event. Si un résultat volumineux possède une URI stable ou est réutilisé, renvoyez un résumé structuré concis et un resource link plutôt que de recopier tout le corpus à chaque résultat.

  • Input schema valide la forme ; policy valide le droit et l’intention.
  • Output schema valide la structure ; le système autoritatif valide le fait.
  • Write tool → target exact, confirmation, idempotency et postcondition.
  • Timeout ambigu → reconcile avant retry.

Resources : URI, fraîcheur et budget de contexte doivent être explicites

Une resource possède une URI unique et peut contenir du texte ou du contenu binaire avec un MIME type. Les resource templates publient des URI paramétrées et une completion optionnelle peut aider à compléter un argument. Le client appelle d’abord resources/list ou templates/list puis resources/read. Subscriptions et listChanged sont des capabilities optionnelles distinctes ; supporter les resources ne signifie pas refresh automatique.

En production, enregistrez source owner, data classification, revision ou lastModified, audience autorisée, size budget et cache policy. Les annotations `audience`, `priority` et `lastModified` sont des hints pour le client, pas des décisions d’access control. Le server vérifie URI, authorization et resource permission à chaque read. Ne placez pas de secret dans une URI prévisible et ne supposez pas qu’un élément non listé ne peut pas être lu par une request directe.

Une resource convient au contexte mais ne garantit pas que le modèle l’a utilisée ou citée correctement. Les evals doivent vérifier current revision, passage support, conflict disclosure, no-answer behavior et cross-scope canary. Pour un business fact qui change souvent, un read-only tool réalisant un lookup autoritatif au moment de la request peut être préférable ; pour une documentation browsable avec des identifiers stables, une resource offre un meilleur contrat de discovery et de cache.

  • Contenu stable et navigable → resource ou resource template.
  • Fait vivant paramétré → souvent read-only tool.
  • Subscription ne remplace pas revision check avant une décision importante.
  • Visibilité de l’URI ne signifie pas permission.

Prompts : workflow réutilisable avec arguments visibles, pas une policy boundary

Une définition de prompt possède un name, un title et une description optionnels ainsi qu’une liste d’arguments. prompts/get renvoie description et messages dans lesquels le server insère des arguments validés. Les messages peuvent contenir text, image, audio ou embedded resource. Un bon prompt explique l’outcome et les inputs attendus : `review_incident` avec incident ID et review depth est plus utile qu’un vague `analyze`.

Un prompt convient à une slash-command discoverable, à l’onboarding ou à une séquence d’analyse standardisée. Ce n’est pas une automation server-side et il ne garantit pas l’exécution des instructions par le modèle. Ne cachez pas approval, credential ou action irréversible dans le template. Si le workflow nécessite un tool, le prompt peut préparer les messages et demander une analyse, mais le client applique toujours la tool policy et le server réautorise l’appel.

Versionnez le contenu du template ou stockez au minimum son hash dans l’evaluation evidence. listChanged indique que le catalogue a changé, mais une conversation active peut déjà contenir d’anciens messages. Le regression set doit couvrir argument escaping, prompt injection dans les champs utilisateur, arguments manquants, locale, permissions d’embedded resources et comportement après modification du template.

Decision matrix et anti-patterns pour un workflow métier

Prenons un support server. `support://policies/refunds/2026-09` est une resource car il s’agit d’un contenu de policy versionné à lire. `draft_refund_review` est un prompt car l’utilisateur choisit un template de review réutilisable avec ticket ID. `tickets.get` et `refunds.create_draft` sont des tools car ils font un lookup runtime et créent un draft contrôlé. Le `refunds.submit` final devrait être séparé avec un scope et une confirmation plus forts. Cette composition rend source, reasoning workflow et authority visibles comme frontières distinctes.

Erreurs courantes : publier chaque ligne de base comme tool ; cacher une write request dans une resource URI ; renvoyer une policy stale via un tool sans revision ; utiliser un prompt comme system policy ; dupliquer le même content dans prompt, resource et tool description ; exposer un seul mega-tool pour toutes les API. Ces approches dégradent discovery, augmentent context, brouillent permissions et empêchent les evals de localiser le failure.

Avant l’implémentation, remplissez une courte contract card : user outcome, controller, data owner, freshness, input/output shape, side effects, permission check, audit event, failure semantics, context cost et rollback. Si deux entités ont une authority ou un lifecycle différents, donnez-leur des primitives différents même si le backend endpoint est commun.

  • Context failure → vérifier resource revision et selection.
  • Instruction failure → vérifier prompt version et argument handling.
  • Execution failure → vérifier tool schema, policy, effect et reconciliation.
  • Failure mixte → conserver des receipts séparés pour chaque frontière.

Contract tests, canary rollout et rollback

Commencez la contract suite par les combinaisons de capabilities : server avec chaque primitive séparément, les trois ensemble et des changements de catalogue. Testez pagination, names ou URI inconnus, arguments invalides, MIME handling, structured output, listChanged et resource subscription uniquement quand la capability est déclarée. Les cas de sécurité négatifs changent tenant, target, URI, prompt argument et tool result, ajoutent une indirect injection dans la resource et répètent un write après un timeout ambigu.

Effectuez un eval end-to-end sur un cas de support synthétique : l’utilisateur choisit un prompt, le client lit une policy revision précise, le modèle propose un read tool et le write draft passe par une confirmation séparée. L’evidence pack contient protocol version, capability manifest, catalog hashes, resource revision, rendered prompt, tool inputs/results, approval receipt, final state et reviewer verdict. On peut ainsi identifier la frontière défaillante sans faire confiance à une final answer fluide.

Commencez le rollout avec une read-only resource, un prompt et un read-only tool. Après validation du scope et de l’audit, ajoutez un draft write réversible ; gardez les actions irréversibles hors de la model authority jusqu’à un approval contract séparé. Rollback désactive la capability ou le tool affecté, révoque le scope, épingle la dernière revision vérifiée de resource ou prompt et conserve les diagnostics read-only. La réactivation exige une regression du primitive modifié et de toute la composition.

  • Hard gate → cross-tenant read, side effect caché ou write non autorisé.
  • Quality gate → revision stale, claim non étayé ou prompt outcome ambigu.
  • Compatibility gate → capability annoncée incohérente avec le method behavior.
  • Recovery gate → retry ne duplique pas l’effect et ne casse pas l’audit chain.

Exemples pratiques

Workflow support avec trois primitives

L’utilisateur lance un prompt de review de ticket. Le client lit une resource de refund policy versionnée. Le modèle appelle un read-only ticket tool, prépare une conclusion puis, seulement après confirmation séparée, appelle le create-draft tool. L’evidence conserve revisions et receipts à chaque frontière.

Quand une resource est préférable à un tool

Le server publie un catalogue de schemas API versionnés sous forme de resource templates. Le host propose un picker et met en cache les revisions inchangées. Un tool n’est nécessaire que pour une validation live du schema contre un deployment précis, pas pour renvoyer un document statique.

FAQ

Quelle est la principale différence entre MCP tools, resources et prompts ?

Un tool est une opération model-controlled, une resource est du contexte application-managed adressé par URI et un prompt est un message template réutilisable choisi par l’utilisateur. Le client concret définit l’UI ; authority et permissions sont toujours vérifiées séparément.

Un tool peut-il renvoyer une resource ?

Oui. Un tool result peut contenir une embedded resource ou un resource link. L’appel reste un contrat d’opération avec inputs, errors et audit, tandis que la resource conserve ses propres sémantiques d’URI, de permission et de freshness.

Quand faut-il lire des données avec un tool plutôt qu’une resource ?

Utilisez une resource pour un contenu browsable, adressable et souvent versionné. Utilisez un read-only tool pour un lookup paramétré en direct lorsque le résultat dépend du runtime input, de l’authorization et de l’état courant autoritatif.

Un prompt peut-il approuver automatiquement un tool call ?

Non. Lancer un prompt n’autorise pas une action ultérieure. Le client applique la confirmation policy et le server vérifie identity, scope, target et state à chaque tool call conséquent.

Contenus associés

Sources

  1. Tools — MCP specification 2025-11-25primaire
  2. Resources — MCP specification 2025-11-25primaire
  3. Prompts — MCP specification 2025-11-25primaire
  4. Lifecycle — MCP specification 2025-11-25primaire
  5. MCP schema reference 2025-11-25primaire