Réduire la consommation de tokens des outils MCP : comment on a allégé nos définitions de 60 %

Chaque outil MCP que ton agent peut appeler est un bloc de JSON que le modèle peut relire à chaque requête. Les nôtres pesaient environ 95 000 tokens. Comment mesurer les tiens en deux minutes, ce qu'on a coupé sans retirer un seul outil, et le contrôle de budget qui l'empêche de regrossir.

Le 27 octobre, un abonné a résilié son abonnement AgentsRoom en donnant les tokens comme raison. Avant d'en discuter, on a mesuré ce que notre app ajoute à chaque agent qu'elle lance.

Le plus gros chiffre n'était pas là où on l'attendait. Nos instructions de démarrage étaient petites. Les outils MCP qu'on donne à chaque agent (backlog, mémoire de projet, messagerie entre agents, terminaux, SSH, bases de données et le reste), c'était 191 outils et environ 380 Ko de JSON. À environ 4 octets par token, ça fait à peu près 95 000 tokens de définitions d'outils. Une semaine plus tôt, c'était 78 000. Personne ne l'avait décidé : chaque nouvel outil avait simplement ajouté son paragraphe.

On développe AgentsRoom, une app desktop qui fait tourner Claude Code, Codex et d'autres CLI de code côte à côte, et qui leur donne ces outils. Voici ce qu'on a mesuré, ce qu'on a coupé sans retirer un seul outil, et le contrôle qui empêche que ça revienne. Tu peux appliquer tout ça à tes propres serveurs MCP.

La réponse courte

  • Une définition d'outil, c'est du JSON que le modèle peut relire à chaque requête : nom, description, schéma d'entrée. Compte environ 4 octets par token.
  • Le payer à chaque tour ou non dépend du CLI. Claude Code diffère les outils MCP par défaut et charge une définition quand il en a besoin. D'autres CLI envoient tous les schémas avec chaque requête.
  • Mesure avant de couper. /context dans Claude Code, ou un script de 40 lignes qui demande sa liste d'outils à n'importe quel serveur.
  • Raccourcis le texte, garde les outils. Une description dit quoi et quand. Le mode d'emploi part dans un document que l'agent lit à la demande. Les nôtres sont passés d'environ 95 000 à environ 38 000 tokens, 2,5 fois moins.
  • Mets un plafond dans le build. Sans plafond, les définitions regrossissent toutes seules.

Ce que coûte une définition d'outil, et qui la paie

Quand un client MCP se connecte à un serveur, il lui demande la liste de ses outils. Chaque entrée est un nom, une description écrite pour le modèle et un schéma JSON des paramètres. Le client transforme cette liste en définitions d'outils envoyées au modèle : c'est comme ça que le modèle sait que l'outil existe et comment l'appeler.

Chaque mot d'une description est donc une entrée que le modèle lit. La fréquence dépend du client :

  • Claude Code diffère les outils MCP par défaut. Sa documentation, lue le 3 novembre 2026 avec Claude Code 2.1.314 installé, dit que seuls les noms des outils et les instructions des serveurs sont chargés au démarrage de la session, et qu'une définition est chargée par la recherche d'outils quand Claude a besoin de cet outil. Avec ENABLE_TOOL_SEARCH=false, avec auto sous un seuil de 10 % de la fenêtre de contexte, sur les modèles antérieurs à Claude Opus 4 et Sonnet 4, ou pour un serveur marqué alwaysLoad, les définitions sont chargées dès le départ.
  • Les autres CLI font autrement. Dans notre propre test du 28 octobre, avec un agent à qui on demandait de répondre « OK » : Claude Code démarrait à 67 500 tokens avec nos outils différés, Codex CLI 0.164 démarrait à 25 000 tokens sans envoyer nos schémas d'un bloc, et OpenCode chargeait nos 175 outils plus 19 outils de navigateur à la connexion et les envoyait avec chaque requête. Même serveur, factures très différentes.

Le cache de prompt adoucit le coût quand la liste d'outils ne change pas : après la première requête, un préfixe stable est relu depuis le cache à une fraction du prix d'entrée. Il ne rend pas la place. Les définitions occupent toujours la fenêtre de contexte à chaque requête, à côté de ton code et de ta conversation. Et le mode différé a son propre coût : une étape de recherche avant le premier usage de chaque outil.

Mesure les tiens en deux minutes

Dans Claude Code, lance /context. Il découpe la fenêtre par source et marque les outils MCP différés ou chargés à la demande. Lance-le dans une session neuve de ton projet, avant de taper quoi que ce soit : tu vois ce que coûte ta configuration avant que le travail commence.

Pour n'importe quel serveur et n'importe quel CLI, interroge directement le serveur. Un serveur MCP en stdio parle JSON-RPC, un message par ligne : tu envoies initialize, puis tools/list, et tu mesures ce qui revient. Ce script fait exactement ça, avec Node et sans aucune dépendance :

// Usage: node mcp-tool-cost.mjs <command that starts the server> [args...]
import { spawn } from 'node:child_process';

const [cmd, ...args] = process.argv.slice(2);
const server = spawn(cmd, args, { stdio: ['pipe', 'pipe', 'ignore'], shell: process.platform === 'win32' });
const tools = [];
let buffer = '';

const send = (msg) => server.stdin.write(JSON.stringify({ jsonrpc: '2.0', ...msg }) + '\n');
const listTools = (cursor) => send({ id: 2, method: 'tools/list', params: cursor ? { cursor } : {} });

server.stdout.on('data', (chunk) => {
  buffer += chunk;
  let end;
  while ((end = buffer.indexOf('\n')) >= 0) {
    const line = buffer.slice(0, end).trim();
    buffer = buffer.slice(end + 1);
    if (line) handle(JSON.parse(line));
  }
});

function handle(msg) {
  if (msg.id === 1) {
    send({ method: 'notifications/initialized' });
    listTools();
  } else if (msg.id === 2) {
    tools.push(...msg.result.tools);
    if (msg.result.nextCursor) listTools(msg.result.nextCursor);
    else { report(); server.kill(); }
  }
}

function report() {
  const rows = tools
    .map((tool) => ({ name: tool.name, bytes: Buffer.byteLength(JSON.stringify(tool)) }))
    .sort((a, b) => b.bytes - a.bytes);
  const total = rows.reduce((sum, row) => sum + row.bytes, 0);
  for (const row of rows.slice(0, 10)) {
    console.log(`${String(row.bytes).padStart(7)} bytes  ~${Math.round(row.bytes / 4)} tokens  ${row.name}`);
  }
  console.log(`${rows.length} tools, ${total} bytes, about ${Math.round(total / 4)} tokens`);
}

send({
  id: 1,
  method: 'initialize',
  params: { protocolVersion: '2025-06-18', capabilities: {}, clientInfo: { name: 'tool-cost', version: '1.0.0' } },
});

Lance-le avec la même commande que celle que ton CLI utilise pour démarrer le serveur, par exemple node mcp-tool-cost.mjs npx -y @playwright/mcp@latest. Il affiche les dix outils les plus lourds et le total. Ce qu'on a obtenu le 3 novembre 2026 :

ServeurOutilsJSONEnviron
@modelcontextprotocol/server-filesystem 2.1.01412 554 octets3 100 tokens
@playwright/mcp 0.0.842521 034 octets5 300 tokens
Outils AgentsRoom, 28 octobre avant l'allègement191environ 380 000 octets95 000 tokens
Outils AgentsRoom, 28 octobre après l'allègement191environ 152 000 octets38 000 tokens
Outils AgentsRoom, 3 novembre203159 957 octets40 000 tokens

Quatre octets par token est une estimation, suffisante pour comparer des serveurs et voir une tendance, pas pour prévoir une facture. Les vrais tokenizers varient selon le modèle et le texte, comme on l'a vu en comptant 3,8 milliards de nos propres tokens.

Les serveurs de fichiers ci-dessus sont raisonnables. Le problème, c'est la somme : cinq serveurs de cette taille font déjà 20 000 tokens, avant même un serveur comme le nôtre.

Ce qu'on a coupé, et ce qu'on n'a pas touché

La règle qu'on s'est fixée : aucun outil retiré, aucun paramètre retiré, aucune valeur possible ni aucun champ obligatoire retiré. Les agents devaient garder toutes leurs capacités. Seul le texte pouvait changer.

  1. Une description d'outil dit quoi et quand, en une à trois phrases. Pas comment. Le comment, c'est là qu'étaient les octets : règles, valeurs par défaut, cas limites, exemples, avertissements écrits après qu'un agent avait mal utilisé l'outil une fois.
  2. Un paramètre a droit à une phrase, ou à rien quand son nom, son type et sa liste de valeurs possibles disent déjà tout. Les paramètres qui reviennent d'un outil à l'autre (project, author, identifiants de ticket) ont reçu la même phrase standard partout.
  3. Le mode d'emploi a déménagé, il n'a pas été supprimé. Chaque famille d'outils a un fichier d'instructions que l'agent lit avant son premier appel à cette famille. Pour notre plus gros outil, celui qui enregistre une équipe d'agents, la référence complète des champs est maintenant renvoyée par un appel d'outil quand l'agent la demande, au lieu de voyager dans le schéma.
  4. Une seconde passe a vérifié chaque fait. Chaque phrase retirée d'une description a été cherchée dans les fichiers d'instructions, et remise là quand elle y manquait.

Quelques résultats, en octets de JSON par outil :

OutilAvantAprès
teams_save19 7059 791
triggers_save16 0144 071
backlog_update13 1504 253
backlog_create11 5654 399

Au total, 380 Ko sont devenus 152 Ko. Treize outils dépassaient 4 Ko ; quatre les dépassent encore, à cause du nombre de champs qu'ils portent. L'idée derrière toute la passe : pour choisir un outil, le modèle a besoin de savoir qu'il existe et quand l'appeler. Les détails peuvent attendre le moment où il s'en sert.

Si tu écris un serveur MCP, Claude Code te donne une raison de plus. Il coupe une description chargée dès le départ à 4 096 caractères, et quand il compare une recherche à une description, il ne lit que la partie sous cette limite. Ce qui compte et qui vient après risque de n'être jamais lu.

La même astuce pour un fichier de démarrage

Les schémas d'outils ne sont pas le seul coût fixe. Nos agents lisent aussi un fichier d'instructions sur les outils avant de s'en servir, et il avait grossi jusqu'à 57,7 Ko, environ 14 000 tokens, lus en entier à chaque démarrage et à chaque reprise. Un utilisateur nous a signalé qu'un agent Codex repris atteignait sa limite de contexte de travail en quelques minutes.

La correction a suivi la même idée. Le fichier est devenu un index d'environ 11 Ko : les règles qui valent pour tous les outils, et une ligne par famille d'outils qui pointe vers son propre fichier. Les 31 fichiers de famille ne sont lus qu'avant le premier appel à cette famille. Leur texte n'a pas changé, mot pour mot. Un agent qui ne touche qu'au backlog ne lit jamais la section sur les bases de données.

Ça marche aussi pour un long CLAUDE.md ou AGENTS.md : garde dans le fichier toujours chargé ce dont chaque tâche a besoin, et mets un lien vers le reste. On en parle davantage dans notre guide sur AGENTS.md et les fichiers de contexte.

Un budget qui fait échouer le push

Le chiffre qui nous inquiétait le plus n'était pas 95 000. C'était 78 000 une semaine plus tôt. Chaque outil ajoutait un paragraphe, chaque paragraphe était raisonnable, et la somme a pris 20 % en sept jours.

La taille est donc devenue un contrôle du build. Un fichier JSON porte le budget :

{
  "totalBytes": 160000,
  "perToolBytes": 4000,
  "oversized": {
    "teams_save": 9791,
    "triggers_save": 4071,
    "backlog_update": 4253,
    "backlog_create": 4399
  }
}

Un script démarre nos serveurs MCP dans un bac à sable, demande ses outils à chacun, mesure JSON.stringify(tool) en octets et sort en erreur quand le total dépasse totalBytes ou qu'un outil dépasse perToolBytes. Les quatre outils déjà trop gros sont listés avec leur taille : un cliquet. Ils peuvent maigrir, jamais grossir, et quand l'un d'eux maigrit, le script demande de baisser le chiffre. Il tourne avant chaque push et dans le build de release. Relever le plafond reste possible, mais c'est une décision écrite dans le fichier, pas un moyen de faire passer le contrôle.

Le 3 novembre, six jours plus tard, le même contrôle lit 203 outils et 159 957 octets : douze outils ajoutés, 43 octets sous le plafond. Le prochain outil devra se faire de la place lui-même. C'est exactement à ça que sert le contrôle.

Coupe ce dont tu ne te sers pas

Le token le moins cher, c'est celui d'un outil que ton agent ne voit jamais.

  • Limite les serveurs aux projets qui en ont besoin. Un serveur déclaré au niveau utilisateur te suit dans chaque dépôt. Dans Claude Code, un .mcp.json de projet le garde là où il sert.
  • Réserve alwaysLoad à une poignée d'outils. La documentation de Claude Code le dit clairement : chaque outil chargé dès le départ consomme du contexte qui serait sinon disponible pour ta conversation.
  • Surveille ce qu'ajoutent les résultats des outils, pas seulement les définitions. Un outil qui renvoie une page ou une table entière peut coûter plus en un appel que sa définition en une journée.

Dans AgentsRoom, Réglages > Outils AgentsRoom liste chaque famille de nos outils avec son poids, et tu peux couper une famille ou un seul outil, pour tous les projets, un projet, un dossier ou un seul agent. Un outil coupé n'est même pas présenté à l'agent, donc il ne coûte aucun contexte. La page AgentsRoom MCP décrit les outils, et la trace de session montre ce qui a rempli le contexte d'un agent, outils MCP compris, classés par taille.

Ce qu'on n'a pas changé

Deux autres coûts sont sortis de la même mesure, et on les a laissés tels quels, exprès.

  • Le brief de démarrage qui donne à chaque agent son rôle et la façon de rendre compte de son état : une médiane d'environ 5 000 tokens pour Claude, environ 2,5 % d'une fenêtre de 200 000 tokens, et relu depuis le cache dès la deuxième requête.
  • Le fichier d'état que chaque agent écrit à la fin d'un tour : mesuré sur 71 transcripts Claude locaux, environ 2,5 % des tokens de contexte.

Réduire l'un ou l'autre aurait économisé moins de 3 % de la fenêtre et mis en jeu la qualité du travail des agents. Les définitions d'outils, elles, pesaient 95 000 tokens. C'est là qu'on a passé le temps.

Les questions qu'on nous pose vraiment

Combien de tokens consomment les outils MCP ?

Chaque outil coûte sa définition entière : nom, description et schéma d'entrée, envoyés en JSON. Compte grossièrement 4 octets par token. Mesuré le 3 novembre 2026 : le serveur filesystem officiel liste 14 outils pour environ 3 100 tokens, Playwright MCP 25 outils pour environ 5 300. Les outils d'AgentsRoom pesaient environ 95 000 tokens avant qu'on les raccourcisse, environ 40 000 aujourd'hui.

Claude Code charge-t-il tous les outils MCP dans la fenêtre de contexte ?

Pas par défaut. La recherche d'outils de Claude Code (tool search) diffère les définitions des outils MCP : seuls les noms des outils et les instructions des serveurs sont chargés au démarrage de la session, et Claude charge une définition quand il a besoin de l'outil. ENABLE_TOOL_SEARCH=false, un modèle antérieur à Claude Opus 4 et Sonnet 4, ou un serveur marqué alwaysLoad remettent les définitions dans le contexte dès le départ.

Les serveurs MCP réduisent-ils la consommation de tokens ?

Ils peuvent, quand un outil renvoie une réponse courte à la place de quelque chose que l'agent lirait sinon en entier, comme une requête sur une base au lieu d'un export complet. Mais les définitions coûtent du contexte, et les résultats aussi : Claude Code avertit quand un résultat MCP dépasse 10 000 tokens et le coupe à 25 000 par défaut. Un serveur MCP n'économise des tokens que si ses résultats sont plus petits que ce qu'il remplace.

Comment voir combien de contexte prennent mes outils MCP ?

Dans Claude Code, lance /context : il découpe le contexte par source et marque les outils MCP différés. Pour n'importe quel serveur et n'importe quel CLI, demande au serveur sa liste d'outils et mesure le JSON, c'est ce que fait le script de 40 lignes de cet article.

Qu'est-ce qu'une bonne description d'outil MCP ?

Une à trois phrases qui disent ce que fait l'outil et quand l'appeler, avec les mots qu'un agent chercherait placés au début. Un paramètre a droit à une phrase, ou à rien quand son nom, son type et ses valeurs possibles disent déjà tout. Les règles, les cas limites et les longs exemples vont dans un document que l'agent lit à la demande. De toute façon, Claude Code coupe une description chargée dès le départ à 4 096 caractères.

Comment empêcher les définitions d'outils de regrossir ?

Donne-leur un budget que le build peut vérifier. On garde un fichier JSON avec un plafond total et un plafond par outil, un script qui démarre nos serveurs MCP, mesure chaque outil et sort en erreur au-delà de l'une des deux limites, et on le lance avant chaque push. Les outils déjà trop gros peuvent maigrir, jamais grossir.

En bref

Tes outils MCP sont du texte que le modèle lit, et personne ne relit ce texte comme on relit du code. Mesure-le une fois : /context dans Claude Code, ou le script ci-dessus pour n'importe quel serveur. Ensuite, fais dire à chaque description quoi et quand, déplace le comment dans un fichier que l'agent lit quand il en a besoin, et mets un chiffre dans ton build pour que ça ne puisse pas redériver.

On est passés d'environ 95 000 à environ 38 000 tokens sans retirer un outil. Si tu fais tourner plusieurs agents avec les mêmes outils, AgentsRoom se télécharge gratuitement, et la page Serveurs MCP montre comment déclarer un serveur une seule fois pour tous les CLI et tous les projets.

Télécharger AgentsRoom

Lancez tous vos agents IA, sur tous vos projets, depuis une seule fenêtre.

GratuitTélécharger AgentsRoom

App companion : suivez vos agents en déplacement

Utilisez Claude, Codex, Antigravity CLI ou un autre fournisseur IA.

Installer l'extension
Chrome Web Store

Remontez bugs et demandes directement dans votre backlog public.

Multi-projets
Multi-provider
Multi-agents
Statut en direct
Diff & commit
App mobile
Aperçu live
Équipes d'agents
Tests navigateur
Dev pilotée par backlog
Bibliothèque de prompts
Bibliothèque de skills
Voir toutes les fonctionnalités

Continuer la lecture