Tutoriels

Créer des serveurs MCP avec IBM Bob

Apprends à utiliser IBM Bob pour créer un serveur Model Context Protocol (MCP) personnalisé qui connecte des modèles d'IA à des outils externes et des sources de données. Ce tutoriel pratique couvre le mode avancé, le flux d'approbation et la configuration MCP.

Dans ce tutoriel, tu utilises IBM Bob pour créer un serveur MCP personnalisé qui offre un accès en lecture seule à arXiv, un dépôt de contenu en accès libre pour les articles scientifiques. En option, tu peux étendre le serveur pour l'intégrer à un agent IA watsonx Orchestrate.

Le Model Context Protocol (MCP) est un standard ouvert qui permet aux grands modèles de langage (LLMs) de communiquer avec des outils externes, des sources de données et des dépôts de contenu via une architecture client-serveur unifiée. Avant MCP, chaque assistant IA avait besoin de sa propre intégration pour chaque outil externe, via du function calling sans interopérabilité. MCP définit à la place un protocole JSON-RPC 2.0 unique que tout hôte MCP peut utiliser pour se connecter à n'importe quel serveur MCP.

Prérequis

Ce tutoriel crée un serveur MCP en TypeScript qui interroge l'API arXiv. Aucune expérience préalable en TypeScript ou en intégration MCP n'est requise.

Pour suivre ce tutoriel, tu as besoin de :

Configurer ton workspace

Lance IBM Bob, ouvre le panneau de paramètres MCP et prépare un répertoire de travail pour le projet de serveur.

Lancer IBM Bob

Lance l'application IBM Bob sur ton ordinateur.

Ouvrir le panneau de chat Bob

Si le panneau de chat n'est pas déjà ouvert, clique sur l'icône Bob à côté de la barre de navigation ou utilise le raccourci Option + Command + B (Mac) ou Ctrl + Alt + B (Windows).

Ouvrir le panneau de paramètres MCP

Clique sur l'icône d'engrenage dans le coin supérieur droit de la fenêtre de chat, puis sélectionne MCP dans la barre latérale gauche.

Le panneau de paramètres MCP te permet de gérer le contrôle d'accès en activant ou désactivant des serveurs, en approuvant automatiquement des outils spécifiques, et de créer des intégrations personnalisées avec le MCP SDK.

  • Global : Stocké dans mcp_settings.json, appliqué à tous les workspaces.
  • Projet : Stocké dans .bob/mcp.json à la racine du projet, partageable avec ton équipe via le contrôle de version. Les paramètres au niveau du projet écrasent les paramètres globaux.

Configurer l'approbation automatique

Dans le chat Bob, assure-toi que les permissions d'approbation automatique juste en dessous du champ de saisie du chat sont définies sur « Read » (Lecture) uniquement. Cette configuration permet à Bob de consulter tes fichiers et le contenu des répertoires, tout en te demandant de vérifier et d'approuver chaque commande avant de l'exécuter.

Ouvrir ton répertoire de projet

Si tu as un répertoire préféré pour le projet, ouvre-le dans l'IDE. Tu peux aussi demander à Bob de le faire dans la fenêtre de chat.

Configurer un environnement virtuel Python

Il est courant de créer des environnements virtuels Python pour isoler les dépendances d'un projet et éviter les conflits entre projets. Passe Bob en mode Agent, le mode qui peut lire, écrire et exécuter des commandes de terminal, puis crée l'environnement.

Créer et activer l'environnement virtuel

Dans le panneau de chat Bob, entre le prompt suivant :

In this directory, activate a Python virtual environment.

Bob exécute une série de commandes de terminal. Approuve chacune lorsqu'on te le demande. Les commandes créent un nouvel environnement virtuel dans le répertoire venv/ et l'activent.

Générer le plan de construction du serveur MCP

Passer en mode Plan

Clique sur le bouton juste en dessous du champ de saisie du chat pour changer le mode d'interaction en Plan. Ce mode permet à Bob de générer un plan structuré pour le serveur MCP avant d'écrire du code.

Soumettre les exigences du serveur

Avec l'environnement virtuel actif, soumets le prompt suivant à Bob. Fournir des exigences précises dès le départ donne à Bob suffisamment de contexte pour formuler un plan complet avant d'écrire du code :

Create an MCP server named arxiv-server that provides read-only access to arXiv. The server should:
- Expose one tool, search_papers, for querying arXiv papers by keyword
- Accept a query string and an optional max_results parameter (default 5, max 20)
- Limit results to paper metadata and abstracts (no PDFs)
- Return title, authors, publication date, abstract, and arXiv URL for each result
- Normalize responses into a clean, structured JSON schema
- Handle API errors and empty results gracefully, returning a clear message instead of failing
- Use TypeScript/Node.js with the stdio transport
- Use the arXiv API v2, which requires no authentication

Bob produit une liste de tâches structurée couvrant le scaffolding du projet, l'implémentation du serveur MCP, l'installation des dépendances, la configuration du serveur et les tests. Remarque que Bob planifie automatiquement la gestion des erreurs et les considérations d'authentification. Même quand l'API cible (arXiv) ne nécessite pas de clé, Bob indique où les identifiants seraient injectés pour les serveurs qui en ont besoin.

Si Bob pose des questions de clarification, réponds du mieux que tu peux ou demande-lui de faire des hypothèses raisonnables.

Créer et examiner le serveur MCP

Une fois le plan vérifié et approuvé, passe en mode Agent pour exécuter chaque étape. Ton résultat et l'ordre peuvent légèrement varier par rapport à l'exemple suivant, car Bob génère des réponses en temps réel.

Dis à Bob de commencer à construire le serveur avec le prompt suivant :

Implement the plan.

D'abord, Bob crée la structure du projet et exécute mkdir -p arxiv-server/src pour créer le répertoire du projet.

Ensuite, Bob génère arxiv-server/package.json, le hub de configuration Node.js qui déclare les métadonnées, scripts et dépendances du projet :

{
  "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"
  },
  "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"
  }
}

Bob crée également arxiv-server/tsconfig.json pour configurer le compilateur TypeScript :

{
  "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"]
}

Ensuite, Bob crée le fichier principal du serveur dans arxiv-server/src/index.ts. Ce fichier enregistre l'outil search_arxiv auprès du MCP SDK, implémente l'analyse XML vers JSON pour les réponses de l'API arXiv, applique les limites de résultats et démarre le serveur sur le transport STDIO — le type de transport local à faible latence adapté aux serveurs tournant sur la même machine que l'hôte MCP.

L'appel server.tool() du MCP SDK est le point d'intégration principal. Il expose l'outil à tout client MCP.

#!/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';

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;
}

const server = new McpServer({ name: "arxiv-server", version: "0.1.0" });

const arxivApi = axios.create({
  baseURL: 'http://export.arxiv.org/api',
  timeout: 30000,
});

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 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(),
    sort_order: z.enum(["ascending", "descending"]).optional()
  },
  async ({ query, max_results = 10, start = 0, sort_by = "relevance", sort_order = "descending" }) => {
    try {
      const params: Record<string, string | number> = {
        search_query: query,
        start: Math.max(start, 0),
        max_results: Math.min(max_results, 50),
        ...(sort_by && { sortBy: sort_by }),
        ...(sort_order && { sortOrder: sort_order }),
      };
      const response = await arxivApi.get('/query', { params });
      return {
        content: [{ type: "text", text: formatSearchResults(parseArxivXML(response.data)) }],
      };
    } catch (error) {
      if (axios.isAxiosError(error)) {
        return {
          content: [{ type: "text", text: `arXiv API error: ${error.response?.data?.message ?? error.message}` }],
          isError: true,
        };
      }
      throw error;
    }
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);
console.error('arXiv MCP server running on stdio');

Le flag isError: true dans le bloc catch est le pattern standard de gestion des erreurs MCP. Il signale au client MCP que l'appel à l'outil a échoué sans arrêter le processus du serveur.

Comme étape suivante, Bob installe les dépendances dans le répertoire arxiv-server en exécutant cd arxiv-server && npm install.

Enregistrer le serveur au niveau du projet

Bob n'enregistre pas automatiquement un nouveau serveur. Dis à Bob de l'ajouter explicitement, et précise la portée du projet pour que la configuration soit dans .bob/mcp.json et puisse être partagée avec ton équipe via le contrôle de version.

Dire à Bob d'enregistrer le serveur

Dans le panneau de chat Bob, entre le prompt suivant :

Register the arxiv-server as an MCP server at project scope. Build it first if needed, then add it to .bob/mcp.json.

Vérifier la configuration générée

Bob écrit ce qui suit dans .bob/mcp.json à la racine de ton projet. Les champs command et args indiquent au client MCP comment démarrer le processus serveur en utilisant le transport STDIO.

{
  "mcpServers": {
    "arxiv-server": {
      "command": "node",
      "args": ["${workspaceFolder}/arxiv-server/build/index.js"]
    }
  }
}

Confirmer que le serveur est chargé

Bob recharge automatiquement la configuration MCP après avoir écrit ce fichier. Ouvre le panneau de paramètres MCP (icône d'engrenage > MCP) pour confirmer que le serveur arxiv-server est listé et activé avant de continuer. S'il n'apparaît pas, clique sur l'icône de rechargement à côté de la liste des serveurs.

Redémarrer Bob

Redémarre Bob pour t'assurer que le serveur tourne et est prêt à accepter des requêtes.

Tester le serveur MCP

Une fois le serveur enregistré, Bob exécute automatiquement deux requêtes de validation contre l'outil search_arxiv.

La première requête cherche trois articles de computing quantique triés par pertinence. La deuxième cherche deux articles de machine learning triés par date de soumission décroissante. Les deux s'exécutent avec succès, confirmant que l'outil est accessible et que la gestion des erreurs du serveur gère correctement différentes combinaisons de paramètres.

Lance maintenant tes propres requêtes pour vérifier que Bob extrait les bons paramètres du langage naturel. Voici un exemple de prompt à coller dans le panneau de chat Bob :

What are the latest papers on LLM agent tracing?

Documenter le serveur

Les implémentations de serveurs MCP open source incluent généralement de la documentation pour que les autres puissent démarrer rapidement. Demande à Bob de la générer :

In this directory, create a README.md file to document this MCP server.
Include setup and usage instructions.

Bob produit un README.md complet couvrant l'installation, la configuration pour plusieurs hôtes MCP (IBM Bob, Claude Desktop, Cursor, Claude Code), des conseils d'authentification pour les serveurs nécessitant des clés API, les patterns d'accès aux fichiers locaux et des conseils de dépannage.

Nettoyer les ressources

Ce tutoriel crée des fichiers locaux et un enregistrement de serveur. Supprime-les si tu ne prévois pas de continuer à utiliser le serveur MCP arXiv.

Ouvre le panneau de paramètres MCP dans Bob (icône d'engrenage > MCP) et désactive ou supprime l'entrée arxiv-server. Sinon, supprime directement le bloc arxiv-server de mcp_settings.json (portée globale) ou de .bob/mcp.json (portée projet).

Étapes suivantes

Dans ce tutoriel, tu as utilisé IBM Bob pour créer un serveur MCP TypeScript, le configurer avec le transport STDIO et le tester avec des requêtes en direct sur arXiv, le tout via des prompts en langage naturel.

Le même workflow s'applique aux implémentations de serveurs MCP plus complexes : serveurs se connectant à des bases de données, des fichiers locaux ou toute autre source de données externe. Les serveurs nécessitant une authentification ont besoin de leurs identifiants injectés comme variables d'environnement dans le JSON de configuration MCP. Pour les déploiements distants, remplace le transport STDIO par SSE.

Comment trouvez-vous ce sujet ?