Le Model Context Protocol (MCP) est né d’un problème d’incompatibilité. Dans notre vie quotidienne, les incompatibilités peuvent nous gêner de différentes manières.
Vous est-il déjà arrivé d’emporter un appareil électrique ou un accessoire de coiffure lors d’un voyage à l’étranger, puis de constater que sa fiche n’était pas compatible avec la prise de courant ? Du point de vue d’un développeur, ce problème est aussi frustrant que de créer des API et des outils de développement pour un agent d’IA qui semble incapable de s’y connecter ou de les invoquer correctement. C’est précisément ce problème d’incompatibilité que MCP permet d’atténuer.
Le Model Context Protocol (MCP), présenté par Anthropic en 2024, sert de couche de normalisation permettant aux applications d’IA de communiquer efficacement avec des services externes tels que des outils, des sources ou jeux de données et des modèles prédéfinis. Le MCP constitue essentiellement une norme ouverte et un connecteur pour les interactions entre l’IA et les outils. L’architecture MCP peut être divisée en trois composants principaux :
Tout d’abord, qu’est-ce qu’IBM Bob ? IBM Bob est un environnement de développement intégré (IDE) et un assistant de modernisation reposant sur l’IA générative. Considérez Bob comme un IDE privilégiant l’IA et comme votre partenaire de développement : un outil qui comprend votre intention, votre base de code et les normes de votre entreprise.
Créer intégralement votre propre serveur MCP peut prendre beaucoup de temps, en particulier si vous débutez dans le développement. Dans ce tutoriel, nous allons plutôt découvrir comment lancer rapidement ce workflow avec IBM Bob à l’aide de quelques prompts simples en langage naturel.
L’intégration de MCP étend les fonctionnalités de Bob en le connectant à des outils et à des services externes. Elle peut être configurée au niveau global (auquel cas elle s’applique à tous les espaces de travail), ou au niveau du projet (auquel cas elle peut être partagée avec l’équipe par l’intermédiaire du fichier .Bob/mcp.json). Le MCP prend en charge deux types de transport : l’entrée-sortie standard (STDIO) pour les serveurs locaux à faible latence et les événements envoyés par le serveur (SSE) pour les serveurs MCP distants accessibles par HTTP ou HTTPS. Les utilisateurs peuvent configurer les serveurs au moyen de fichiers JSON dans le menu des paramètres de Bob, en définissant les commandes, les variables d’environnement et les outils approuvés automatiquement. Les deux types de transport permettent d’activer ou de désactiver les serveurs, d’approuver automatiquement certains outils et de gérer leur fonctionnement depuis le panneau des paramètres MCP de Bob.
Commençons. Si vous préférez suivre ce tutoriel sur GitHub, consultez notre référentiel.
1. Ouvrez l’IDE IBM Bob installé parmi les prérequis et familiarisez-vous avec l’interface de votre nouveau compagnon de codage fondé sur l’IA.
2. Pour accéder au panneau des paramètres MCP, cliquez sur les trois points situés à côté de l’icône en forme d’engrenage, dans le coin supérieur droit de la fenêtre de chat. Sélectionnez ensuite MCP servers (Serveurs MCP) dans le menu déroulant.
Vous pouvez y activer ou désactiver le MCP globalement ou pour chaque serveur, et gérer les outils, par exemple leur approbation automatique, leur suppression ou leur redémarrage. Vous pouvez également explorer les serveurs de la communauté dans Bob Marketplace ou créer votre propre serveur à l’aide du SDK MCP.
Si vous avez choisi d’installer un serveur depuis Bob Marketplace, vous remarquerez que les configurations peuvent être définies à deux niveaux : au niveau global (auquel cas elles sont stockées dans
Les paramètres définis au niveau du projet remplacent les paramètres globaux, ce qui vous permet d’adapter le comportement du MCP à différents cas d’utilisation. Pour gérer ces configurations, vous pouvez modifier directement les fichiers JSON depuis le menu des paramètres de Bob. Vous pouvez notamment y définir les commandes, les variables d’environnement et les outils approuvés automatiquement pour chaque serveur. Dans ce tutoriel, nous utiliserons le SDK.
3. Vérifiez que le paramètre Enable MCP Server Creation (Autoriser la création de serveurs MCP) est activé afin de pouvoir créer des serveurs MCP personnalisés avec Bob.
4. Si vous souhaitez configurer votre projet dans un répertoire particulier, vous pouvez l’ouvrir vous-même dans l’IDE ou demander à Bob de le faire depuis la fenêtre de chat.
3. Il est courant de créer des environnements virtuels Python afin d’isoler les dépendances d’un projet et d’éviter les conflits entre différents projets. Pour cela, saisissez le prompt suivant : « Dans ce répertoire, active un environnement virtuel Python ».
4. Bob devrait alors exécuter une série de commandes de terminal. Ces commandes ressembleront probablement aux suivantes :
Nous vous recommandons de laisser le bouton d’approbation automatique désactivé afin de pouvoir approuver ou refuser chaque commande avant son exécution en temps réel par Bob.
Parfait. Bob a correctement créé et activé un environnement virtuel dans le répertoire
Maintenant que notre environnement virtuel est configuré, nous pouvons passer à la création du serveur MCP. Lorsque vous demandez à Bob de générer du code, ou lorsque vous vous adressez à n’importe quel modèle ou assistant d’IA, il est utile de fournir des informations importantes. Pour voir Bob à l’œuvre, envoyons-lui le prompt suivant :
« Crée un serveur MCP qui fournit un accès en lecture seule à arXiv. Le serveur doit :
Grâce à ce seul prompt, Bob dispose de suffisamment d’informations pour comprendre la tâche et créer une liste d’étapes à accomplir. Vous remarquerez que cette liste comprend non seulement la création du serveur MCP, mais également sa configuration et ses tests. Pratique.
Dans ce tutoriel, nous utilisons l’API arXiv comme exemple simple, car elle ne nécessite aucune clé d’API ni aucune authentification pour commencer. Il s’agit néanmoins d’un simple exemple : Bob est également capable de gérer des serveurs plus complexes nécessitant des autorisations.
Avant l’exécution de chaque commande, nous pouvons approuver ou refuser l’action. Si vous constatez que les commandes sont exécutées automatiquement, il est possible que le bouton d’approbation automatique soit activé.
2. Bob crée ensuite un fichier
{
"name": "arxiv-server",
"version": "0.1.0",
"description": "MCP server for read-only access to arXiv papers",
"type": "module",
"bin": {
"arxiv-server": "./build/index.js"
},
"files": [
"build"
],
"scripts": {
"build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
"prepare": "npm run build",
"watch": "tsc --watch"
},
"keywords": [
"mcp",
"arxiv",
"research",
"papers"
],
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.4",
"axios": "^1.7.9",
"zod": "^3.24.1"
},
"devDependencies": {
"@types/node": "^22.10.5",
"typescript": "^5.7.3"
}
}
arxiv-server/tsconfig.json{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "build"]
}
4. L’implémentation principale du serveur, qui contient la fonctionnalité de recherche arXiv, est ensuite stockée dans
#!/usr/bin/env node
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import axios from 'axios';
// Définir les types des réponses de l’API arXiv
interface ArxivEntry {
id: string;
title: string;
summary: string;
authors: Array<{ name: string }>;
published: string;
updated: string;
categories: string[];
primary_category: string;
links: Array<{ href: string; rel: string; type?: string }>;
}
interface ArxivSearchResult {
entries: ArxivEntry[];
totalResults: number;
startIndex: number;
itemsPerPage: number;
}
// Créer un serveur MCP
const server = new McpServer({
name: "arxiv-server",
version: "0.1.0"
});
// Créer une instance Axios pour l’API arXiv
const arxivApi = axios.create({
baseURL: 'http://export.arxiv.org/api',
timeout: 30000,
});
/**
* Analyser la réponse XML de l’API arXiv et la convertir au format JSON
*/
function parseArxivXML(xmlData: string): ArxivSearchResult {
const entries: ArxivEntry[] = [];
// Extract total results
const totalResultsMatch = xmlData.match(/<opensearch:totalResults[^>]*>(\d+)<\/opensearch:totalResults>/);
const totalResults = totalResultsMatch ? parseInt(totalResultsMatch[1]) : 0;
const startIndexMatch = xmlData.match(/<opensearch:startIndex[^>]*>(\d+)<\/opensearch:startIndex>/);
const startIndex = startIndexMatch ? parseInt(startIndexMatch[1]) : 0;
const itemsPerPageMatch = xmlData.match(/<opensearch:itemsPerPage[^>]*>(\d+)<\/opensearch:itemsPerPage>/);
const itemsPerPage = itemsPerPageMatch ? parseInt(itemsPerPageMatch[1]) : 0;
// Extract entries
const entryRegex = /<entry>([\s\S]*?)<\/entry>/g;
let entryMatch;
while ((entryMatch = entryRegex.exec(xmlData)) !== null) {
const entryXml = entryMatch[1];
// Extract ID
const idMatch = entryXml.match(/<id>([^<]+)<\/id>/);
const id = idMatch ? idMatch[1] : '';
// Extract title
const titleMatch = entryXml.match(/<title>([^<]+)<\/title>/);
const title = titleMatch ? titleMatch[1].trim().replace(/\s+/g, ' ') : '';
// Extract summary
const summaryMatch = entryXml.match(/<summary>([^<]+)<\/summary>/);
const summary = summaryMatch ? summaryMatch[1].trim().replace(/\s+/g, ' ') : '';
// Extract authors
const authors: Array<{ name: string }> = [];
const authorRegex = /<author>\s*<name>([^<]+)<\/name>/g;
let authorMatch;
while ((authorMatch = authorRegex.exec(entryXml)) !== null) {
authors.push({ name: authorMatch[1].trim() });
}
// Extraire la date de publication
const publishedMatch = entryXml.match(/<published>([^<]+)<\/published>/);
const published = publishedMatch ? publishedMatch[1] : '';
// Extraire la date de mise à jour
const updatedMatch = entryXml.match(/<updated>([^<]+)<\/updated>/);
const updated = updatedMatch ? updatedMatch[1] : '';
// Extraire les catégories
const categories: string[] = [];
const categoryRegex = /<category[^>]+term="([^"]+)"/g;
let categoryMatch;
while ((categoryMatch = categoryRegex.exec(entryXml)) !== null) {
categories.push(categoryMatch[1]);
}
const primary_category = categories[0] || '';
// Extraire les liens
const links: Array<{ href: string; rel: string; type?: string }> = [];
const linkRegex = /<link[^>]+href="([^"]+)"[^>]+rel="([^"]+)"(?:[^>]+type="([^"]+)")?/g;
let linkMatch;
while ((linkMatch = linkRegex.exec(entryXml)) !== null) {
links.push({
href: linkMatch[1],
rel: linkMatch[2],
type: linkMatch[3]
});
}
entries.push({
id,
title,
summary,
authors,
published,
updated,
categories,
primary_category,
links
});
}
return {
entries,
totalResults,
startIndex,
itemsPerPage
};
}
/**
* Mettre en forme les résultats de recherche pour les afficher
*/
function formatSearchResults(result: ArxivSearchResult): string {
let output = `Found ${result.totalResults} résultats (${result.entries.length} affichés)\n\n`;
result.entries.forEach((entry, index) => {
output += `${index + 1}. ${entry.title}\n`;
output += ` Identifiant : ${entry.id}\n`;
output += ` Auteurs : ${entry.authors.map(a => a.name).join(', ')}\n`;
output += ` Publication : ${entry.published}\n`;
output += ` Catégories : ${entry.categories.join(', ')}\n`;
output += ` Résumé : ${entry.summary.substring(0, 300)}${entry.summary.length > 300 ? '...' : ''}\n`;
// Rechercher le lien vers le résumé (et non vers le fichier PDF)
const abstractLink = entry.links.find(l => l.rel === 'alternate');
if (abstractLink) {
output += ` URL: ${abstractLink.href}\n`;
}
output += '\n';
});
return output;
}
// Ajouter un outil permettant de rechercher des articles sur arXiv
server.tool(
"search_arxiv",
{
query: z.string().describe("Search query (supports arXiv query syntax)"),
max_results: z.number().min(1).max(50).optional().describe("Maximum number of results to return (1-50, default: 10)"),
start: z.number().min(0).optional().describe("Starting index for pagination (default: 0)"),
sort_by: z.enum(["relevance", "lastUpdatedDate", "submittedDate"]).optional().describe("Sort order (default: relevance)"),
sort_order: z.enum(["ascending", "descending"]).optional().describe("Sort direction (default: descending)")
},
async ({ query, max_results = 10, start = 0, sort_by = "relevance", sort_order = "descending" }) => {
try {
// Enforce reasonable limits
const limitedMaxResults = Math.min(max_results, 50);
const limitedStart = Math.max(start, 0);
// Build query parameters
const params: Record<string, string | number> = {
search_query: query,
start: limitedStart,
max_results: limitedMaxResults,
};
if (sort_by) {
params.sortBy = sort_by;
}
if (sort_order) {
params.sortOrder = sort_order;
}
const response = await arxivApi.get('/query', { params });
// Analyser la réponse XML
const result = parseArxivXML(response.data);
// Mettre en forme les résultats
const formattedResults = formatSearchResults(result);
return {
content: [
{
type: "text",
text: formattedResults,
},
],
};
} catch (error) {
if (axios.isAxiosError(error)) {
return {
content: [
{
type: "text",
text: `arXiv API error: ${error.response?.data?.message ?? error.message}`,
},
],
isError: true,
};
}
throw error;
}
}
);
// Commencer à recevoir des messages sur l’entrée standard et à envoyer des messages sur la sortie standard
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('arXiv Serveur MCP arXiv en cours d’exécution via stdio');
// Made with Bob
À cette étape, si votre serveur nécessite des clés d’API, Bob vous les demandera.
5. Bob installe ensuite les dépendances dans le répertoire arxiv-server en exécutant la commande suivante.
mcp_settings.json.Bob/mcp.json{
"mcpServers": {}
"mcpServers": {
"arxiv": {
"command": "node",
"args": [ "/here/is/the/path/to/arxiv-server/build/index.js"
],
"disabled": false,
"alwaysAllow": [],
"disabledTools": []
}
}
}
Ces informations concluent la série d’étapes exécutées par Bob afin de configurer le serveur MCP.
Pour terminer la série de tâches de la liste de choses à faire, Bob teste le serveur MCP. Comme le montre la capture d’écran précédente, Bob interroge l’outil
Une fois l’exécution terminée avec succès, ce que vous pouvez vérifier en cliquant sur le chevron orienté vers le bas afin de développer la fenêtre, Bob effectue un autre test. Cette fois, la requête porte sur deux articles relatifs au machine learning classés par date de soumission décroissante. Même avec ces différents paramètres, l’appel de l’outil MCP est exécuté correctement.
Ces tests ayant réussi, Bob a maintenant terminé toutes les sous-tâches.
Bob a déjà testé le serveur MCP pour nous. Essayons néanmoins de soumettre nous-mêmes quelques requêtes dans la fenêtre de chat afin de vérifier si Bob peut déterminer les termes de recherche et les paramètres nécessaires.
Demandez à Bob : « Quels sont les articles les plus récents sur le traçage des agents LLM ? »
Bob extrait lui-même la requête appropriée à partir de notre prompt et ajoute quelques mots-clés afin d’améliorer la recherche. Bob fixe également le nombre maximal de résultats à 10 et classe les articles par pertinence. Parfait.
Essayons une dernière requête.
Fait intéressant, Bob modifie automatiquement la requête de recherche lorsqu’il remarque des résultats indésirables. Bob ne se contente donc pas d’exécuter aveuglément des appels d’outils : il collabore avec l’utilisateur comme le ferait un agent utile. Après deux itérations, Bob renvoie plusieurs articles correspondant bien à notre tâche initiale.
De nombreux serveurs MCP open source comprennent également une documentation permettant à d’autres personnes de commencer facilement à les utiliser. Collons le prompt suivant dans la fenêtre de chat :
« Dans ce répertoire, crée un fichier README.md afin de documenter ce serveur MCP. Inclus des instructions de configuration et d’utilisation. »
À l’aide d’un seul prompt simple, Bob a créé un document
Souhaitez-vous peut-être créer avec watsonx Orchestrate un agent d’IA spécialisé dans la recherche, capable d’accéder à ce serveur MCP ? Bob peut créer un agent à l’aide d’un seul prompt simple. Commencez par installer le serveur ADK watsonx Orchestrate prédéfini depuis la marketplace accessible dans le panneau des paramètres MCP que nous avons exploré à l’étape 1. Envoyez ensuite la commande suivante :
« Crée un agent watsonx Orchestrate qui utilise ce serveur MCP arXiv. »
Si le service watsonx Orchestrate est exécuté localement, Bob exécutera les commandes nécessaires pour vous. Si vous préférez exécuter vous-même les commandes ultérieurement, Bob écrira les scripts et documentera toutes les commandes nécessaires.
Examinons chaque fichier afin de mieux comprendre ce que Bob a généré. Voici le fichier toolkit-config.yaml
kind: mcp
name: arxiv-toolkit
description: Boîte à outils permettant de rechercher des articles scientifiques sur arXiv. Elle donne accès aux métadonnées, aux résumés et aux informations de publication des articles de la base de données arXiv.
package_root: /local/path/to/arxiv-server
language: node
command: node /local/path/to/arxiv-server/arxiv-server/build/index.js
tools:
- "*"
# Made with Bob
Ouvrons ensuite le fichier research-assistant-agent.yaml
name: research-assistant
kind: native
description: Assistant de recherche basé sur l’IA qui aide à trouver et à résumer des articles scientifiques provenant d’arXiv. Il est spécialisé dans la recherche de publications scientifiques, l’explication des résultats de recherche et la fourniture de références.
title: Assistant de recherche
instructions: |
Tu es un assistant de recherche expert spécialisé dans la recherche de publications scientifiques sur arXiv.
## Tes capacités
- Rechercher sur arXiv des articles portant sur n’importe quel sujet scientifique
- Résumer les résultats de recherche à partir des résumés, dans un langage clair
- Identifier les principaux auteurs et les tendances de la recherche
- Suggérer des articles et des sujets connexes
- Fournir des références appropriées comprenant les identifiants arXiv et les URL
## Lorsque tu réponds aux utilisateurs
1. Fournis toujours les identifiants arXiv et les URL directes des articles
2. Résume les articles dans un langage accessible à partir de leur résumé
3. Mets en évidence les principales contributions et conclusions
4. Suggère des recherches complémentaires lorsque cela est pertinent
5. Sois concis, mais informatif
## Utilisation de l’outil search_arxiv
Paramètres disponibles :
- query (obligatoire) : requête de recherche utilisant la syntaxe arXiv
- max_results (facultatif) : de 1 à 50 articles ; valeur par défaut : 10
- start (facultatif) : indice de départ pour la pagination ; valeur par défaut : 0
- sort_by (facultatif) : "relevance", "submittedDate" ou "lastUpdatedDate"
- sort_order (facultatif) : "ascending" ou "descending"
## Syntaxe de recherche avancée
Tu peux utiliser les opérateurs suivants dans les requêtes :
- ti:keyword : rechercher dans le titre
- au:author : rechercher par nom d’auteur
- abs:keyword : rechercher dans le résumé
- cat:category : filtrer par catégorie, par exemple cs.AI, quant-ph ou math.CO
- AND, OR, ANDNOT : opérateurs booléens
Exemples :
- "ti:transformer AND cat:cs.LG" : articles sur les transformeurs dans le domaine de l’apprentissage automatique
- "au:Hinton" : articles de Geoffrey Hinton
- "quantum computing AND cat:quant-ph" : articles sur l’informatique quantique dans la catégorie de la physique quantique
## Catégories courantes
- cs.AI : intelligence artificielle
- cs.LG : apprentissage automatique
- cs.CL : informatique et langage
- cs.CV : vision par ordinateur
- quant-ph : physique quantique
- math.CO : combinatoire
- stat.ML : apprentissage automatique (statistiques)
## Format de réponse
Lorsque tu présentes des articles, utilise le format suivant :
**"Titre de l’article"**
- Auteurs : [noms des auteurs]
- Publication : [date]
- Catégories : [catégories]
- Résumé : [bref résumé de l’article]
- [Consulter l’article](URL arXiv)
## Gestion des cas particuliers
- Si aucun résultat n’est trouvé : suggère d’autres termes de recherche ou des requêtes plus générales
- Si les résultats sont trop nombreux : recommande de restreindre la recherche à l’aide de catégories ou de filtres de date
- Si l’utilisateur demande des fichiers PDF : explique que tu fournis uniquement les métadonnées, mais inclus l’URL lui permettant d’accéder à l’article
- Si la requête manque de précision : pose des questions afin de clarifier le domaine de recherche ou les centres d’intérêt précis
tools:
- search_arxiv
config:
hidden: false
enable_cot: true
tags:
- research
- academic
- papers
- arxiv
- literature-search
# Made with Bob
Ce fichier YAML configure notre assistant de recherche, un agent d’IA spécialisé qui simplifie la recherche universitaire en recherchant des articles sur arXiv, en les résumant et en fournissant des citations dans un format structuré. Il contient des instructions détaillées qui guident le comportement de l’agent, notamment la syntaxe des requêtes, l’utilisation des outils, le format des réponses et la gestion des cas particuliers. Toutes ces informations sont décrites en détail, tandis que l’outil search_arxivsetup-instructions.md
Dans ce tutoriel, nous avons utilisé IBM Bob, un IDE privilégiant l’IA qui joue également le rôle de partenaire de développement, afin de simplifier l’intégration de MCP pour la recherche universitaire. Vous avez efficacement créé un serveur MCP évolutif capable de rechercher et de récupérer des articles dans le référentiel arXiv.org. Votre solution est maintenant prête pour la production, que vous choisissiez de la publier en open source à destination de la communauté scientifique ou de la déployer dans vos applications d’entreprise afin d’améliorer la découverte des connaissances.
La véritable magie d’IBM Bob réside dans sa capacité à transformer des tâches de développement complexes en workflows intuitifs pilotés par des prompts. Avec seulement quelques entrées stratégiques, Bob accélère la création de prototypes, réduit le code standard et suggère même des optimisations, ce qui vous permet de vous concentrer sur l’innovation plutôt que sur l’implémentation.
À mesure que vous explorez ses fonctionnalités, réfléchissez aux manières dont Bob pourrait encore améliorer votre serveur MCP. Vous pourriez notamment ajouter des filtres avancés, des mises à jour en temps réel ou des intégrations à d’autres bases de données universitaires telles que PubMed ou IEEE Xplore. Toutes ces possibilités, et bien d’autres encore, peuvent être mises en œuvre au moyen de quelques prompts simples dans IBM Bob.
Prêt à passer à l’étape suivante ? Essayez de personnaliser votre serveur MCP ou explorez plus en profondeur les fonctionnalités de Bob afin de découvrir un potentiel d’automatisation encore plus important. Bon codage !
Créez, déployez et gérez de puissants assistants et agents IA qui automatisent les workflows et les processus grâce à l’IA générative.
Construisez l’avenir de votre entreprise avec des solutions d’IA en lesquelles vous pouvez avoir confiance.
IBM Consulting et ses services d'IA accompagnent les entreprises dans la redéfinition de leurs activités avec l'intelligence artificielle pour mener leur transformation.