Pourquoi les CLI surpassent MCP pour les agents IA — Et comment créer votre propre arsenal CLI
Six mots. C'est tout. Voilà ce que Peter Steinberger — le créateur d'OpenClaw, 190 000 étoiles GitHub, fraîchement recruté par Sam Altman — a posté sur X le mois dernier. Ma réaction immédiate ? Screenshot et envoi à trois potes dev avec "JE VOUS L'AVAIS DIT" en majuscules.
Ça fait des années que je développe sur Ubuntu.
Tous mes outils quotidiens sont des CLI.
Supabase CLI, Vercel CLI, Docker, git, n8n — toute ma stack tourne depuis un terminal. Quand les serveurs MCP ont commencé à faire le buzz l'année dernière, j'en ai testé quelques-uns. Ça marchait. Ça bouffait aussi 40% de ma fenêtre de contexte, ça plantait au hasard, et ça ajoutait une dépendance pour quelque chose que je pouvais déjà faire avec une ligne de commande et un pipe.
Alors quand le dev open-source le plus prolifique de 2026 dit que les CLI sont la vraie interface entre les agents IA et le monde — et qu'OpenAI est assez d'accord pour l'embaucher — peut-être qu'il est temps d'écouter.
TL;DR : Les serveurs MCP gonflent votre fenêtre de contexte, ajoutent des dépendances fragiles, et résolvent un problème qui n'existe pas si vos outils sont des CLI 😂 Peter Steinberger a construit ~10 CLI custom pour OpenClaw, s'est fait recruter par OpenAI pour ça.
Vous pouvez utiliser le même pattern avec Claude Code aujourd'hui (documenter les CLI dans CLAUDE.md), les brancher dans OpenClaw comme skills, ou construire votre propre agent autonome avec l'API tool_use d'Anthropic. Les CLI sont l'interface native entre les agents IA et le monde réel. Les GUI sont pour les humains. Les API sont pour les services. Les CLI sont pour les agents.

Le Procès de MCP (Et Pourquoi le Gars d'OpenClaw Est d'Accord Avec Mon Terminal)
Classons les façons dont un agent IA peut interagir avec des outils externes. Du pire au meilleur.
Les GUI sont évidemment hors course. Vous ne demanderiez pas à votre pipeline CI/CD de cliquer sur des boutons dans un navigateur. Même logique pour les agents. Passons.
Les API REST et SDK fonctionnent. Mais chaque service a son propre flow d'auth, son propre format de réponse, sa propre gestion d'erreur. Vous finissez par écrire du code wrapper pour chaque intégration. C'est correct pour un backend SaaS. C'est excessif pour un agent qui doit juste vérifier si vous avez de nouveaux emails.
MCP — le Model Context Protocol — était censé corriger ça. Un protocole standard pour connecter les agents aux outils. Ça sonne bien en théorie. En pratique ? Chaque serveur MCP que vous ajoutez déverse tout son schéma dans la fenêtre de contexte de votre agent. Descriptions d'outils, listes de paramètres, déclarations de capacités — tout. Avant même que votre agent ait commencé à réfléchir à votre vraie demande, 30-40% de son contexte est déjà consommé par du boilerplate MCP.
Peter Steinberger a essayé. Il a construit le support pour ça. Puis il a construit MCPorter — un outil qui convertit littéralement les serveurs MCP en CLI. C'est dire à quel point il pense que le format est foireux.
Ses mots exacts sur ce que MCP a vraiment apporté à l'écosystème : "La seule bonne chose avec MCP, c'était que les entreprises ont ouvert quelques API."
Brutal. Et précis.
Le protocole lui-même était un détour — les API qu'il a forcé à exister sont le vrai cadeau.
Les CLI gagnent parce qu'ils sont l'opposé de tout ce bloat. Un CLI, c'est :
- Zéro overhead de contexte. Votre agent n'a pas besoin de charger un schéma. Il lit une doc d'une page (ou lance
--help) et connaît toutes les commandes disponibles. - Composable. Pipez la sortie d'un CLI dans un autre.
goplaces search "coffee" --json | jq '.[0].address'- essayez de faire ça avec un serveur MCP. - Testable en 2 secondes. Ouvrez un terminal, lancez la commande, voyez ce qui se passe. Pas de serveur à démarrer, pas de handshake de protocole, pas de connexion WebSocket.
- Sortie structurée gratuite. Ajoutez un flag
--jsonet votre agent récupère des données parsables sans aucune couche de sérialisation.
Un appel exec. C'est tout ce dont un agent a besoin pour utiliser un CLI. Pas de middleware, pas de protocole, pas de processus serveur qui tourne en arrière-plan en bouffant de la RAM pour le privilège d'être disponible.

Et ce n'est pas une préférence théorique.
Steinberger a construit tout son écosystème OpenClaw autour des CLI. Une douzaine environ : goplaces pour Google Maps, imsg pour iMessage, bird pour X/Twitter, wacli pour WhatsApp, gog pour Gmail et Calendar, camsnap pour les caméras de sécurité, peekaboo pour les screenshots macOS avec vision IA, summarize pour digérer vidéos et podcasts. Chacun suit le même pattern : fait une chose bien, supporte --json, a un --help clair.
Puis OpenAI l'a embauché.
Il a passé le plus clair d'une année à construire cette armée de CLI. Puis OpenAI l'a embauché. Sam Altman n'a pas recruté un gars qui construisait de jolis dashboards — il a recruté le gars qui a prouvé que bash est la meilleure interface d'agent. Tirez-en les conclusions que vous voulez.
Utiliser les CLI Maintenant pour Construire Plus Vite (OpenClaw Pas Requis)
Vous n'avez pas besoin d'OpenClaw pour en bénéficier. Si vous utilisez Claude Code, Codex, ou n'importe quel agent avec accès shell, vous avez déjà l'infrastructure.
L'astuce que la plupart ratent : votre agent peut déjà appeler des CLI. Mais il ne connaît pas VOS CLI spécifiques sauf si vous le lui dites.
# CLAUDE.md (racine de votre projet)
## CLI Disponibles
### Supabase
- `supabase db push` - appliquer les migrations sur le distant
- `supabase functions deploy
- `supabase db dump --data-only` - exporter les données de production
- `supabase migration new
### Vercel
- `vercel deploy --prod` - déployer en production
- `vercel env pull .env.local` - synchroniser les variables d'env
- `vercel logs
### Spécifique au projet
- `./scripts/check-mrr.sh` - sort du JSON avec MRR actuel, inscriptions, churn
- `./scripts/seed-demo.sh` - remet à zéro l'env de démo avec des données d'exemple
C'est tout.
Claude Code lit CLAUDE.md au début de chaque session. La prochaine fois que vous dites "déploie en prod et vérifie si le MRR a changé", il sait exactement quelles commandes lancer. Pas de plugin, pas de serveur MCP, pas de fichier de config avec 47 clés imbriquées.
Pour Codex, même concept — le fichier s'appelle AGENTS.md.
Pour Cursor, .cursorrules.
Nom de fichier différent, pattern identique.
Mais le vrai power move, c'est de construire vos propres CLI. Et avant de fermer cet onglet en pensant "j'ai pas le temps de construire des outils CLI" — on parle de 20-30 lignes de code. Sérieusement.
Trois règles pour un CLI agent-friendly :
1. Sortie structurée avec **--json**
Votre agent ne peut pas parser un joli tableau avec des caractères de dessin. Il a besoin de JSON.
#!/usr/bin/env node
// scripts/check-mrr.js
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY)
const args = process.argv.slice(2)
const jsonMode = args.includes('--json')
const { data } = await supabase
.from('subscriptions')
.select('plan, status, created_at')
const active = data.filter(s => s.status === 'active')
const mrr = active.reduce((sum, s) => sum + (s.plan === 'pro' ? 29 : 9), 0)
const today = data.filter(s =>
new Date(s.created_at).toDateString() === new Date().toDateString()
)
const stats = {
mrr,
active_subscriptions: active.length,
signups_today: today.length,
timestamp: new Date().toISOString()
}
if (jsonMode) {
console.log(JSON.stringify(stats))
} else {
console.log(`MRR: $${mrr}`)
console.log(`Actifs: ${active.length}`)
console.log(`Inscriptions aujourd'hui: ${today.length}`)
}
2. Un **--help** qui explique vraiment les choses
Les agents lisent --help comme les humains lisent les README. Si votre texte d'aide est pourri, votre agent va halluciner les flags.
$ ./check-mrr.js --help
Usage: check-mrr [options]
Vérifier les métriques SaaS actuelles depuis Supabase.
Options:
--json Sortie en JSON (défaut: lisible par humain)
--period Filtre: today | week | month (défaut: today)
--help Afficher ce message
3. Codes de sortie propres
0 = succès. 1 = erreur.
Votre agent utilise ça pour décider quoi faire ensuite. Si votre CLI sort 0 en cas d'échec, votre agent pense que tout va bien et continue.
J'ai appris ça à la dure à 2h du mat quand mon script de déploiement échouait silencieusement et que Claude continuait à me dire "déploiement réussi" — ça m'a pris 20 minutes pour réaliser que le script avalait les erreurs et sortait 0 quand même, mais je digresse.
Une fois que vous avez quelques-uns de ces CLI, quelque chose change.
Vous arrêtez de demander à Claude Code d'écrire des requêtes Supabase. Vous commencez à dire "vérifie mes métriques, et si les inscriptions ont chuté de plus de 20% par rapport à hier, rédige un message Slack pour l'équipe." Claude enchaîne les CLI, décide la logique, agit sur le résultat. Ce n'est plus de l'autocomplétion. C'est un agent.
Le Pattern Qui Fait Que Ça Scale : CLI + Doc de Skill
Alors voilà le truc que Steinberger a pigé tôt, et que la plupart des gens n'ont toujours pas intériorisé : un CLI sans documentation est inutile pour un agent.
Votre agent ne peut pas explorer un CLI par essai-erreur comme le ferait un humain. Il doit savoir à l'avance quelles commandes existent, quels flags sont disponibles, à quoi ressemble la sortie. C'est pourquoi chaque CLI de l'écosystème OpenClaw est livré avec un SKILL.md — une doc structurée qui fait office de manuel d'instruction pour l'agent.
Le pattern c'est : binaire CLI + doc de skill = capacité autonome.
Le CLI fait le boulot. La doc de skill apprend à l'agent comment l'utiliser. Ensemble, ils forment une unité autonome que n'importe quel agent peut récupérer et lancer. Steinberger appelle ça des "skills". Le concept est le même que vous appeliez ça un skill, un outil, ou "ce script bash que Dave a écrit mardi dernier."
Et vous n'avez pas besoin d'OpenClaw pour utiliser ce pattern. Vous le faites déjà, en fait — quand vous écrivez un CLAUDE.md qui documente vos CLI, c'est une doc de skill. La différence c'est que Steinberger a standardisé le format et construit une couche de distribution par-dessus : ClawHub, avec 3 000+ skills que vous pouvez parcourir et installer.
Le truc intéressant ? Vous pouvez piquer n'importe lequel de ces skills pour votre propre setup. Chaque skill sur ClawHub est juste un CLI que vous pouvez installer indépendamment (brew install steipete/tap/goplaces, npm install -g @steipete/oracle, etc.) et un SKILL.md que vous pouvez lire. Vous n'avez pas besoin du runtime OpenClaw. Installez le binaire, collez les commandes pertinentes dans votre CLAUDE.md, et Claude Code peut l'utiliser immédiatement.
# Dans votre CLAUDE.md — piqué direct de ClawHub
## goplaces (CLI Google Maps)
- `goplaces search "coffee near me" --open-now --json` - trouver des lieux
- `goplaces search "pizza" --lat 40.8 --lng -73.9 --radius-m 3000 --json` - recherche biaisée par localisation
- `goplaces details <place_id> --json` - détails complets du lieu avec avis
- `goplaces resolve "Soho, London" --json` - géocoder un nom de lieu
Requis: variable d'env GOOGLE_PLACES_API_KEY
## summarize (CLI de résumé Vidéo/Podcast/Web)
- `summarize --url "https://youtube.com/watch?v=xxx" --json` - résumer une vidéo
- `summarize --url "https://some-blog.com/post" --json` - résumer une page web
- `summarize --url "https://podcast.fm/ep42" --cli claude --json` - choisir quel modèle utiliser
Voilà goplaces et summarize — deux des propres outils de Steinberger — qui tournent dans Claude Code avec zéro dépendance OpenClaw. Juste un binaire et une doc.
C'est pourquoi l'approche CLI scale d'une façon que MCP ne fera jamais. Un serveur MCP est un processus qui tourne et qui a besoin de configuration, d'un handshake de protocole, et d'espace dans la fenêtre de contexte. Un skill CLI est un binaire statique et un fichier texte. L'un nécessite de l'infrastructure. L'autre nécessite un brew install et 10 lignes de markdown.
Brancher les CLI dans OpenClaw
Si vous faites déjà tourner OpenClaw, transformer un CLI en skill d'agent prend environ 5 minutes.
Le système fonctionne comme ça : chaque skill a un fichier SKILL.md qui décrit ce que fait le CLI, comment l'installer, et quelles commandes sont disponibles. L'agent lit ce fichier et sait comment utiliser l'outil.
---
name: check-mrr
description: Vérifier les métriques SaaS (MRR, inscriptions, churn) depuis Supabase.
metadata:
openclaw:
requires:
env:
- SUPABASE_URL
- SUPABASE_KEY
bins:
- node
primaryEnv: SUPABASE_URL
---
# check-mrr
Récupérer les métriques SaaS actuelles depuis Supabase de production.
## Install
npm install -g @yourhandle/check-mrr
## Commandes
- `check-mrr --json` - métriques complètes en JSON
- `check-mrr --period week` - métriques pour la semaine actuelle
- `check-mrr --period month` - aperçu mensuel
## Format de sortie (--json)
{
"mrr": 1247,
"active_subscriptions": 89,
"signups_today": 3,
"timestamp": "2026-02-17T10:30:00Z"
}
Publiez-le sur ClawHub (clawhub publish) et n'importe qui qui fait tourner OpenClaw peut installer votre skill. Mais la vraie valeur est locale : combinez-le avec un cron job, et votre agent vérifie vos métriques chaque matin et vous ping sur WhatsApp si quelque chose cloche.
// Dans openclaw.json
{
"cron": [
{
"schedule": "0 8 * * *",
"message": "Lance check-mrr --json. Si signups_today est 0 ou que le mrr a chuté de plus de 5% par rapport à hier, alerte-moi sur WhatsApp avec un résumé. Sinon log juste ça.",
"channel": "whatsapp"
}
]
}
C'est la boucle complète. Cron déclenche l'agent, l'agent lit le skill, appelle le CLI, interprète le résultat, décide quoi faire. Pas de dashboard à vérifier. Pas de fatigue de notification d'alertes dont vous n'avez pas besoin. L'agent utilise son jugement — même pattern que Steinberger fait tourner sur tout son setup.
Le répertoire ClawHub a déjà 3 000+ skills tiers, la plupart suivant exactement cette structure. goplaces pour la recherche de lieux, himalaya pour l'email via IMAP, bird (😭) pour X/Twitter, sonoscli pour le contrôle d'enceintes - toute l'armée. Vous les installez, l'agent les apprend, terminé.
Construire Votre Propre Agent (Le Pattern OpenClaw, Sans OpenClaw)
OK alors et si vous ne voulez pas faire tourner OpenClaw ?
Peut-être que vous voulez quelque chose de plus léger, plus custom, ou vous aimez juste construire des trucs from scratch. (Je comprends. J'auto-héberge tout. C'est une maladie.)
Le pattern de base est mort simple : un script qui appelle l'API Anthropic avec tool_use, mappe les appels d'outils aux exécutions CLI, et boucle jusqu'à ce que l'agent ait fini.
import Anthropic from '@anthropic-ai/sdk'
import { execSync } from 'child_process'
const client = new Anthropic()
// Vos CLI, déclarés comme outils
const tools = [
{
name: "check_mrr",
description: "Récupérer les métriques SaaS actuelles (MRR, abonnements actifs, inscriptions aujourd'hui)",
input_schema: {
type: "object",
properties: {
period: { type: "string", enum: ["today", "week", "month"], default: "today" }
}
}
},
{
name: "deploy_production",
description: "Déployer le dernier commit sur Vercel production. Retourne l'URL de déploiement.",
input_schema: {
type: "object",
properties: {}
}
},
{
name: "send_slack",
description: "Envoyer un message à un canal Slack",
input_schema: {
type: "object",
properties: {
channel: { type: "string" },
message: { type: "string" }
},
required: ["channel", "message"]
}
}
]
// Mapper les noms d'outils aux commandes CLI
function executeTool(name, input) {
const commands = {
check_mrr: `node ./scripts/check-mrr.js --json --period ${input.period || 'today'}`,
deploy_production: `vercel deploy --prod --yes 2>&1`,
send_slack: `curl -X POST -H 'Authorization: Bearer ${process.env.SLACK_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"channel":"${input.channel}","text":"${input.message}"}' \
https://slack.com/api/chat.postMessage\`
}
try {
const result = execSync(commands[name], { encoding: 'utf-8', timeout: 30000 })
return result
} catch (err) {
return JSON.stringify({ error: err.message, exitCode: err.status })
}
}
// La boucle d'agent
async function runAgent(task) {
let messages = [{ role: "user", content: task }]
while (true) {
const response = await client.messages.create({
model: "claude-sonnet-4-5-20250514",
max_tokens: 4096,
system: "Tu es un agent autonome. Utilise les outils disponibles pour accomplir les tâches. Sois concis dans ton raisonnement.",
tools,
messages
})
// Si Claude a fini de parler, on a fini
if (response.stop_reason === "end_turn") {
const text = response.content.find(b => b.type === 'text')
return text?.text || 'Terminé.'
}
// Si Claude veut utiliser des outils, les exécuter
const toolBlocks = response.content.filter(b => b.type === 'tool_use')
if (toolBlocks.length === 0) break
messages.push({ role: "assistant", content: response.content })
const toolResults = toolBlocks.map(block => ({
type: "tool_result",
tool_use_id: block.id,
content: executeTool(block.name, block.input)
}))
messages.push({ role: "user", content: toolResults })
}
}
// Le lancer
const result = await runAgent(
"Vérifie notre MRR. Si c'est au-dessus de 1000$, déploie en production et notifie #team sur Slack avec les métriques. Si c'est en-dessous, envoie juste un warning sur Slack."
)
console.log(result)
~80 lignes. Voilà votre mini-OpenClaw. L'agent décide quels outils appeler et dans quel ordre basé sur la tâche que vous lui donnez. Ajouter un nouveau CLI prend 30 secondes — ajoutez une définition d'outil, ajoutez une ligne dans la map commands, terminé.
Pour la partie autonome, wrappez-le dans un cron :
# crontab -e
0 8 * * * cd /home/deploy/my-agent && node agent.js "Check matinal: métriques, déploie si stable, notifie l'équipe"
0 20 * * * cd /home/deploy/my-agent && node agent.js "Fin de journée: résume les inscriptions, signale toute anomalie sur Slack"
Vous pouvez aussi lancer ça comme un service systemd avec un timer, ou le balancer dans un container Docker sur votre serveur. Même résultat, différentes saveurs de devops.

GitHub Actions est une autre option si vous voulez zéro infrastructure. Un workflow programmé qui installe vos CLI dans le runner et appelle l'API Anthropic :
name: Daily Agent Run
on:
schedule:
- cron: '0 8 * * *'
jobs:
agent:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm install @anthropic-ai/sdk
- run: node agent.js "Routine matinale"
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
SUPABASE_KEY: ${{ secrets.SUPABASE_KEY }}
Gratuit pour les repos publics, 2 000 minutes/mois sur les privés. Pas mal pour un agent quotidien qui tourne en 30 secondes.
Et n8n ?
Vous pouvez techniquement orchestrer des CLI via n8n en utilisant le nœud Execute Command ou en les wrappant dans des containers FastAPI.
Mais honnêtement, c'est plus de friction que l'approche script pour ce cas d'usage. n8n brille quand vous avez besoin de workflows visuels avec 15 étapes et des branchements complexes — pas pour "appeler un CLI et laisser le LLM décider."
Si vous voulez creuser plus sur l'exécution de code custom dans n8n, j'ai écrit un guide complet sur appeler des scripts Python depuis n8n qui couvre le setup Docker + FastAPI.
Ce Que Ça Signifie Pour Vous
La tendance est claire.
Les builders les plus productifs dans l'espace des agents IA ne stackent pas des serveurs MCP et ne configurent pas d'adaptateurs de protocole. Ils écrivent des CLI petits et tranchants et laissent leurs agents les appeler.
Peter Steinberger l'a prouvé à l'échelle avec OpenClaw. OpenAI l'a validé avec une offre d'emploi. Et vous pouvez commencer aujourd'hui avec un fichier CLAUDE.md et un script Node de 20 lignes.
La stack n'a pas d'importance. OpenClaw, Claude Code, Codex, une boucle d'agent custom — le pattern est le même. Wrappez vos outils dans des CLI. Documentez-les pour votre agent. Laissez le LLM gérer l'orchestration.
Votre terminal était une interface IA depuis le début. La plupart des gens ne s'en sont juste pas encore rendu compte.
Si ça vous a parlé, suivez-moi pour plus de contenu d'automatisation IA testé au combat. La suite : je construis un agent autonome complet qui gère mon SaaS — déploie, monitore, et gère les tickets de support — entièrement via des CLI. Pas de dashboard. Pas de GUI. Juste un homard et un cron job. 🦞
Dans le monde des agents IA, les CLI sont le couteau suisse que chaque développeur devrait avoir. Découvrez comment construire votre propre arsenal de lignes de commande puissantes.