Ilyes Bouzayen
11 juil. 2026

MCP + Tool Calling : Construire des Agents Autonomes en 2026

15 min de lecture

MCP + Tool Calling : Construire des Agents Autonomes en 2026

Le tool calling permet à un LLM d'invoquer des fonctions. MCP standardise ces fonctions. Ensemble, ils créent des agents qui agissent, pas juste qui répondent.

Le tool calling de base

import { generateText, tool } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';

const result = await generateText({
  model: openai('gpt-4o'),
  prompt: 'Quelle est la météo à Paris demain ?',
  tools: {
    getWeather: tool({
      description: 'Récupère la météo pour une ville',
      parameters: z.object({
        city: z.string().describe('Nom de la ville'),
        date: z.string().describe('Date au format YYYY-MM-DD')
      }),
      execute: async ({ city, date }) => {
        const res = await fetch(`https://api.weather.com/v1/${city}/${date}`);
        return res.json();
      }
    })
  }
});

// Le LLM choisit automatiquement d'appeler getWeather
// puis formule une réponse avec le résultat

Chaînage d'outils

// Agent qui cherche, analyse et écrit
const agent = await generateText({
  model: openai('gpt-4o'),
  prompt: 'Trouve les 3 derniers PRs ouverts, résume les changements, et crée un ticket de suivi si nécessaire',
  tools: {
    listPRs: tool({
      description: 'Liste les PRs ouvertes',
      parameters: z.object({ repo: z.string() }),
      execute: async ({ repo }) => {
        const res = await fetch(`https://api.github.com/repos/${repo}/pulls`, {
          headers: { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` }
        });
        return res.json();
      }
    }),
    createIssue: tool({
      description: 'Crée un ticket GitHub',
      parameters: z.object({
        repo: z.string(),
        title: z.string(),
        body: z.string()
      }),
      execute: async ({ repo, title, body }) => {
        return fetch(`https://api.github.com/repos/${repo}/issues`, {
          method: 'POST',
          headers: {
            Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({ title, body })
        }).then(r => r.json());
      }
    })
  },
  maxSteps: 5  // Permet le chaînage multi-outils
});

Architecture agent avec MCP

import { McpServer } from '@modelcontextprotocol/sdk/server';
import { z } from 'zod';
import { promises as fs } from 'fs';
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);
const server = new McpServer({ name: 'dev-agent', version: '1.0.0' });

// Outil 1 : Lire du code
server.tool('read-file', 'Lit un fichier du projet', {
  path: z.string()
}, async ({ path }) => {
  const content = await fs.readFile(path, 'utf-8');
  return { content: [{ type: 'text', text: content }] };
});

// Outil 2 : Écrire du code
server.tool('write-file', 'Écrit dans un fichier', {
  path: z.string(),
  content: z.string()
}, async ({ path, content }) => {
  await fs.writeFile(path, content);
  return { content: [{ type: 'text', text: `Fichier ${path} mis à jour` }] };
});

// Outil 3 : Exécuter les tests
server.tool('run-tests', 'Lance la suite de tests', {
  pattern: z.string().optional()
}, async ({ pattern }) => {
  const result = await execAsync(`npm test ${pattern || ''}`);
  return { content: [{ type: 'text', text: result.stdout }] };
});

// L'agent peut maintenant lire → écrire → tester → itérer

Sécurité des agents

// 1. Validation stricte des paramètres
server.tool('exec-command', 'Exécute une commande', {
  command: z.enum(['npm test', 'npm run lint', 'npm run build']),
  // Seules ces 3 commandes sont autorisées
}, async ({ command }) => { /* ... */ });

// 2. Sandbox pour l'exécution
import { Sandbox } from '@cloudflare/sandbox';
const sandbox = await Sandbox.create();
const result = await sandbox.exec('npm test');

// 3. Rate limiting par agent
const rateLimiter = new Map();
function checkRateLimit(agentId: string) {
  const count = rateLimiter.get(agentId) || 0;
  if (count > 50) throw new Error('Rate limit exceeded');
  rateLimiter.set(agentId, count + 1);
}

Patterns d'agents avancés

  • Router : un agent décide, les autres exécutent
  • Critic : un agent écrit, un autre review
  • Planner : un agent planifie, un autre implémente

Conclusion

MCP + Tool Calling = un LLM qui passe de la parole à l'action. La clé : des outils sûrs et bien décrits.