Introduction
Les Large Language Models (LLMs) ont révolutionné notre façon d’interagir avec l’intelligence artificielle, mais leur utilité reste limitée sans accès aux données et outils du monde réel. Les Model Context Protocols (MCP) émergent comme une solution standardisée pour connecter les LLMs à des sources de données externes, des APIs et des outils de manière sécurisée et structurée.
Dans cet article, nous allons explorer ce que sont les MCP, pourquoi ils sont importants, et comment ils transforment l’architecture des applications basées sur les LLMs.
Qu’est-ce qu’un Model Context Protocol ?
Définition
Un Model Context Protocol est un standard de communication qui permet aux LLMs d’interagir avec des sources de données et des outils externes de manière structurée. Il définit :
- Format de communication : Comment les requêtes et réponses sont structurées
- Authentification : Comment sécuriser l’accès aux ressources
- Capabilities : Quelles fonctionnalités sont disponibles
- Error handling : Comment gérer les erreurs et exceptions
Le problème qu’ils résolvent
Avant les MCP, chaque intégration était unique :
// Approche non standardisée
async function askLLMWithDatabase(prompt: string) {
const dbData = await fetchFromDatabase();
const weatherData = await fetchWeatherAPI();
const filesData = await readLocalFiles();
// Format custom pour chaque source
const context = `
Database: ${JSON.stringify(dbData)}
Weather: ${JSON.stringify(weatherData)}
Files: ${JSON.stringify(filesData)}
User question: ${prompt}
`;
return await llm.complete(context);
}
Avec MCP, l’approche devient standardisée :
// Approche standardisée avec MCP
async function askLLMWithMCP(prompt: string) {
const mcpClient = new MCPClient([
new DatabaseMCP(),
new WeatherMCP(),
new FileSystemMCP(),
]);
return await llm.complete(prompt, {
context: mcpClient.getContext(),
tools: mcpClient.getTools(),
});
}
Architecture MCP
Structure de base
interface MCPServer {
// Métadonnées du serveur
info: {
name: string;
version: string;
description: string;
};
// Capacités disponibles
capabilities: {
resources?: boolean;
tools?: boolean;
prompts?: boolean;
};
// Méthodes d'interaction
listResources(): Promise<Resource[]>;
readResource(uri: string): Promise<ResourceContent>;
listTools(): Promise<Tool[]>;
callTool(name: string, args: any): Promise<ToolResult>;
}
Exemple d’implémentation
class DatabaseMCP implements MCPServer {
info = {
name: 'postgresql-database',
version: '1.0.0',
description: 'PostgreSQL database access',
};
capabilities = {
resources: true,
tools: true,
};
async listResources() {
return [
{ uri: 'db://users', name: 'Users table', type: 'database' },
{ uri: 'db://orders', name: 'Orders table', type: 'database' },
];
}
async readResource(uri: string) {
const table = uri.replace('db://', '');
const data = await this.query(`SELECT * FROM ${table} LIMIT 100`);
return {
uri,
mimeType: 'application/json',
text: JSON.stringify(data),
};
}
async listTools() {
return [
{
name: 'execute_query',
description: 'Execute a SQL query',
inputSchema: {
type: 'object',
properties: {
query: { type: 'string' },
},
required: ['query'],
},
},
];
}
async callTool(name: string, args: any) {
if (name === 'execute_query') {
const result = await this.query(args.query);
return {
content: [{ type: 'text', text: JSON.stringify(result) }],
};
}
throw new Error(`Unknown tool: ${name}`);
}
private async query(sql: string) {
// Implémentation de la requête
}
}
Types de ressources MCP
Resources
Les ressources sont des données accessibles en lecture :
interface Resource {
uri: string; // db://users, file://config.json
name: string; // Nom lisible
description?: string; // Description optionnelle
mimeType?: string; // Type MIME du contenu
}
Tools
Les tools sont des fonctions exécutables :
interface Tool {
name: string;
description: string;
inputSchema: JSONSchema; // JSON Schema pour validation
}
Prompts
Les prompts sont des templates réutilisables :
interface Prompt {
name: string;
description: string;
arguments: Array<{
name: string;
description: string;
required: boolean;
}>;
}
Cas d’usage concrets
1. Assistant de développement
const devAssistant = new MCPClient([
new GitHubMCP({ token: process.env.GITHUB_TOKEN }),
new FileSystemMCP({ root: './src' }),
new JiraMCP({ apiKey: process.env.JIRA_KEY }),
]);
// Le LLM peut maintenant :
// - Lire et créer des issues GitHub
// - Parcourir et modifier le code source
// - Créer et mettre à jour des tickets Jira
2. Analyse de données business
const businessAnalyst = new MCPClient([
new PostgreSQLMCP({ connection: dbConfig }),
new GoogleSheetsMCP({ credentials: googleCreds }),
new SlackMCP({ token: slackToken }),
]);
// Le LLM peut :
// - Interroger la base de données
// - Lire et écrire dans Google Sheets
// - Poster des résumés dans Slack
3. Automatisation DevOps
const devopsAgent = new MCPClient([
new KubernetesMCP({ kubeconfig: k8sConfig }),
new DatadogMCP({ apiKey: datadogKey }),
new PagerDutyMCP({ token: pdToken }),
]);
// Le LLM peut :
// - Monitorer les pods Kubernetes
// - Analyser les métriques Datadog
// - Créer des incidents PagerDuty
Sécurité et bonnes pratiques
Principe de moindre privilège
const mcp = new FileSystemMCP({
root: './data', // Restreindre au répertoire data
readOnly: true, // Lecture seule
allowedExtensions: ['.txt', '.json'], // Fichiers autorisés
});
Validation des entrées
async callTool(name: string, args: any) {
// Valider les arguments
const schema = this.getToolSchema(name);
const validation = validate(args, schema);
if (!validation.valid) {
throw new Error('Invalid arguments');
}
// Sanitize les inputs
const sanitized = sanitizeInput(args);
return await this.executeTool(name, sanitized);
}
Rate limiting
class RateLimitedMCP implements MCPServer {
private limiter = new RateLimiter({
tokensPerInterval: 10,
interval: 'minute',
});
async callTool(name: string, args: any) {
await this.limiter.removeTokens(1);
return await this.executeToolInternal(name, args);
}
}
L’écosystème MCP
Serveurs MCP populaires
- @modelcontextprotocol/server-filesystem : Accès au système de fichiers
- @modelcontextprotocol/server-postgres : Base de données PostgreSQL
- @modelcontextprotocol/server-github : API GitHub
- @modelcontextprotocol/server-slack : Intégration Slack
Clients MCP
- Claude Desktop : Support natif des MCP
- Custom implementations : Via les SDKs TypeScript/Python
Créer son propre serveur
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new Server({
name: 'my-custom-mcp',
version: '1.0.0',
}, {
capabilities: {
resources: {},
tools: {},
},
});
// Définir les ressources
server.setRequestHandler('resources/list', async () => ({
resources: [
{ uri: 'custom://resource', name: 'My Resource' },
],
}));
// Définir les tools
server.setRequestHandler('tools/list', async () => ({
tools: [
{ name: 'my_tool', description: 'Does something' },
],
}));
// Lancer le serveur
const transport = new StdioServerTransport();
await server.connect(transport);
Conclusion
Les Model Context Protocols représentent une évolution majeure dans l’architecture des applications AI. En standardisant la façon dont les LLMs accèdent aux données et outils externes, ils ouvrent la voie à des intégrations plus robustes, sécurisées et maintenables.
L’adoption des MCP permet de :
- Réduire la complexité d’intégration avec des sources multiples
- Améliorer la sécurité via des abstractions standardisées
- Faciliter la réutilisation de serveurs MCP à travers différents projets
- Accélérer le développement en s’appuyant sur un écosystème croissant
Si vous construisez des applications basées sur les LLMs, explorer les MCP devrait être une priorité. Le standard est encore jeune, mais son potentiel est immense et l’écosystème se développe rapidement.
Pour aller plus loin :
- Documentation officielle : modelcontextprotocol.io
- SDK TypeScript : @modelcontextprotocol/sdk
- Exemples de serveurs : MCP Servers Repository