langchain-custom-mcp-server-adapters-test

vinzlac/langchain-custom-mcp-server-adapters-test

3.2

If you are the rightful owner of langchain-custom-mcp-server-adapters-test and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

This project demonstrates the use of `@langchain/mcp-adapters` to automatically load tools from a custom MCP server without manual declarations in LangChain.

Tools
2
Resources
0
Prompts
0

LangChain Custom MCP Server Adapters Test

Ce projet démontre l'utilisation de @langchain/mcp-adapters pour charger automatiquement les outils depuis un serveur MCP personnalisé sans avoir à les déclarer manuellement dans LangChain.

🎯 Différences avec l'approche précédente

❌ Approche précédente (déclaration manuelle)

  • Création manuelle de wrappers LangChain pour chaque outil MCP
  • Déclaration explicite de chaque outil dans le code LangChain
  • Maintenance nécessaire lors de l'ajout de nouveaux outils
  • Fichiers séparés pour chaque outil (mcpSearchTool.ts, mcpWeatherTool.ts)

✅ Nouvelle approche (chargement automatique)

  • Chargement automatique de tous les outils depuis le serveur MCP
  • Aucune déclaration manuelle nécessaire
  • Les outils sont découverts dynamiquement via le protocole MCP
  • Ajout de nouveaux outils = aucune modification du code LangChain nécessaire
  • Utilisation de @langchain/mcp-adapters v1.0.0 avec LangChain v1.0.0

🏗️ Architecture

Vue d'ensemble

┌─────────────────┐
│   User Query    │
└────────┬────────┘
         │
         ▼
┌─────────────────────────────────────┐
│   LangChain Agent (GPT-4)          │
│   - createAgent() API v1.0.0       │
│   - Orchestre les outils           │
│   - Sélection intelligente         │
└────────┬────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────┐
│   @langchain/mcp-adapters v1.0.0   │
│   MultiServerMCPClient              │
│   - Charge automatiquement          │
│     tous les outils MCP            │
│   - getTools() discovery           │
└────────┬────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────┐
│   MCP Server (custom, stdio)       │
│   - Serveur MCP personnalisé        │
│   - Expose les outils               │
│   - search, weather                 │
└────────┬────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────┐
│   External APIs                     │
│   - Brave Search                    │
│   - OpenWeatherMap                  │
└─────────────────────────────────────┘

Diagramme de séquence

sequenceDiagram
    participant User as 👤 User
    participant Agent as 🤖 LangChain Agent
    participant MCPClient as 📦 MCP Client<br/>(@langchain/mcp-adapters)
    participant MCPServer as 🔧 MCP Server<br/>(Custom)
    participant LLM as 🧠 LLM<br/>(OpenAI GPT-4)
    participant API as 🌐 External APIs<br/>(Brave, OpenWeather)

    Note over Agent,MCPClient: Initialisation
    Agent->>MCPClient: initialize()
    MCPClient->>MCPServer: ListTools request
    MCPServer-->>MCPClient: Tools list (search, weather)
    MCPClient->>Agent: getTools()[search, weather]
    Agent->>LLM: createAgent(model, tools, systemPrompt)
    LLM-->>Agent: Agent ready

    Note over User,API: Exécution d'une requête
    User->>Agent: Question: "Météo à Paris"
    Agent->>LLM: invoke({messages: [HumanMessage]})
    
    Note over LLM: Analyse la question et décide d'utiliser l'outil weather
    LLM-->>Agent: ToolCall: weather(city="Paris")
    
    Agent->>MCPClient: Call tool: weather
    MCPClient->>MCPServer: CallTool request (weather, {city: "Paris"})
    
    Note over MCPServer,API: Exécution de l'outil weather
    MCPServer->>API: GET /geo/1.0/direct?q=Paris
    API-->>MCPServer: Coordinates (lat, lon)
    MCPServer->>API: GET /data/2.5/forecast?lat=X&lon=Y
    API-->>MCPServer: Weather data
    
    MCPServer-->>MCPClient: Response: Weather text
    MCPClient-->>Agent: Tool result
    
    Note over Agent,LLM: L'agent traite le résultat et génère la réponse finale
    Agent->>LLM: invoke({messages: [HumanMessage, ToolMessage, ...]})
    LLM-->>Agent: Final response message
    
    Agent-->>User: Réponse: "Météo actuelle à Paris..."

Flux détaillé avec logs

sequenceDiagram
    participant User as 👤 User
    participant Client as 📱 LangChain Client
    participant MCPClient as 📦 MCP Client
    participant MCPServer as 🔧 MCP Server
    participant LLM as 🧠 LLM
    participant API as 🌐 External APIs

    User->>Client: ask("Météo à Paris")
    Note right of Client: [USER] 📥 Question reçue<br/>[LANGCHAIN-AGENT] 📤 Request payload
    
    Client->>LLM: agent.invoke({messages})
    Note right of LLM: Analyse et décide d'utiliser weather
    
    LLM-->>Client: ToolCall: weather(city="Paris")
    Note left of Client: [LANGCHAIN-AGENT] 🔧 Appel d'outil
    
    Client->>MCPClient: Call tool: weather
    Note right of MCPClient: [MCP-CLIENT] 📤 Tool call
    
    MCPClient->>MCPServer: CallTool request
    Note right of MCPServer: [MCP-SERVER] 📥 Appel d'outil reçu<br/>[MCP-SERVER] 📤 Request payload<br/>[TOOL:weather] 🌤️ Recherche météo
    
    MCPServer->>API: GET /geo/1.0/direct?q=Paris
    Note right of API: [TOOL:weather] 📤 API Request payload (geo)
    API-->>MCPServer: Coordinates
    Note left of API: [TOOL:weather] 📥 API Response payload (geo)
    
    MCPServer->>API: GET /data/2.5/forecast?lat=X&lon=Y
    Note right of API: [TOOL:weather] 📤 API Request payload (weather)
    API-->>MCPServer: Weather data
    Note left of API: [TOOL:weather] 📥 API Response payload (weather)
    
    MCPServer-->>MCPClient: Response with weather text
    Note left of MCPServer: [MCP-SERVER] 📥 Response payload<br/>[TOOL:weather] ⏱️ Temps d'exécution
    
    MCPClient-->>Client: Tool result
    Note left of MCPClient: [MCP-CLIENT] 📥 Tool response
    
    Client->>LLM: invoke({messages: [..., ToolMessage]})
    Note right of LLM: Génère la réponse finale
    
    LLM-->>Client: Final response
    Note left of LLM: [LANGCHAIN-AGENT] ✅ Agent terminé<br/>[LANGCHAIN-AGENT] 📥 Response payload
    
    Client-->>User: Réponse finale
    Note left of Client: [LANGCHAIN-AGENT] 📤 Réponse finale extraite

📋 Prérequis

  • Node.js 18+
  • Clés API pour :
    • OpenAI (GPT-4)
    • Brave Search
    • OpenWeatherMap

🚀 Installation

  1. Cloner le repository :
git clone <votre-repo>
cd langchain-custom-mcp-server-adapters-test
  1. Installer les dépendances :
npm install
  1. Créer le fichier .env à partir de env.example :
cp env.example .env
  1. Éditer le fichier .env et ajouter vos clés API :
OPENAI_API_KEY=votre_cle_openai
BRAVE_API_KEY=votre_cle_brave
OPENWEATHER_API_KEY=votre_cle_openweather
OPENAI_MODEL=gpt-4

💻 Utilisation

Mode développement (avec auto-reload)

npm run dev

Lancer le client directement (sans compilation)

npm run client

Note : Ce script utilise tsx pour exécuter directement les fichiers TypeScript sans compilation, ce qui est plus rapide pour le développement.

Lancer le serveur MCP seul (pour tests)

npm run mcp-server

Compiler le projet

npm run build

Exécuter le projet compilé

npm start

Une fois lancé, vous pouvez poser des questions dans le terminal. Tapez exit ou quit pour quitter.

📁 Structure du projet

langchain-custom-mcp-server-adapters-test/
├── src/
│   ├── index.ts              # Point d'entrée principal
│   ├── client.ts             # Client LangChain avec chargement automatique des outils MCP
│   ├── mcpServer.ts          # Serveur MCP custom (expose les outils search et weather)
│   ├── mcpServerRunner.ts    # Runner pour le serveur MCP en mode stdio
│   └── config.ts             # Gestion de la configuration
├── dist/                     # Fichiers compilés
├── .env                      # Variables d'environnement (à créer)
├── env.example               # Exemple de configuration
├── package.json
├── tsconfig.json
├── ADAPTATION.md             # Documentation de l'adaptation avec Context7
└── README.md

🔧 Comment ça fonctionne

1. Serveur MCP Custom

Ce projet utilise un serveur MCP personnalisé (pas un serveur out-of-the-box) :

  • Implémenté dans src/mcpServer.ts avec le SDK @modelcontextprotocol/sdk
  • Définit manuellement les outils search et weather
  • Implémente la logique métier (appels API externes)
  • Lancement local via mcpServerRunner.ts en mode stdio

Pourquoi custom ?

  • Contrôle total sur les outils et leur logique
  • Intégration directe avec vos APIs spécifiques
  • Personnalisation des réponses et formats
  • Logs détaillés pour le debugging

2. Configuration du client MCP

Le serveur MCP est configuré dans client.ts :

const mcpServerConfig = {
  searchWeatherServer: {
    transport: "stdio" as const,
    command: "npx",
    args: ["-y", "tsx", join(__dirname, "mcpServerRunner.ts")],
  },
};

const mcpClient = new MultiServerMCPClient(mcpServerConfig);

3. Chargement automatique des outils

Les outils sont chargés automatiquement via getTools() :

// Charge TOUS les outils de TOUS les serveurs MCP configurés
const tools = await this.mcpClient.getTools();

Aucune déclaration manuelle nécessaire ! Les outils sont découverts dynamiquement via le protocole MCP.

4. Utilisation avec LangChain 1.0.0

Le projet utilise la nouvelle API de LangChain 1.0.0 avec createAgent() :

import { createAgent, ReactAgent } from "langchain";

// Créer l'agent avec la nouvelle API
this.agent = createAgent({
  model: this.model,
  tools, // Outils chargés automatiquement
  systemPrompt,
});

// Utiliser l'agent
const result = await this.agent.invoke({
  messages: [new HumanMessage(question)],
});

Note : LangChain 1.0.0 utilise createAgent() au lieu de createOpenAIFunctionsAgent() et AgentExecutor de la version 0.x.

📦 Versions utilisées

Ce projet utilise les versions 1.0.0 des packages LangChain pour la compatibilité :

  • @langchain/core: ^1.0.0
  • @langchain/mcp-adapters: ^1.0.0
  • @langchain/openai: ^1.0.0
  • langchain: ^1.0.0
  • @modelcontextprotocol/sdk: ^1.0.0

📊 Logs détaillés

Le projet inclut des logs complets pour tracer tous les appels :

Préfixes des logs

  • [MCP-CLIENT] : Client MCP (chargement des outils)
  • [MCP-SERVER] : Serveur MCP (requêtes/réponses)
  • [TOOL:nom] : Outils individuels (search, weather)
  • [LANGCHAIN-AGENT] : Agent LangChain
  • [USER] : Entrées utilisateur
  • [ERROR] : Erreurs

Contenu des logs

Chaque log inclut :

  • Payloads de requête : Données complètes envoyées (JSON formaté)
  • Payloads de réponse : Données complètes reçues (JSON formaté)
  • Métriques de performance : Temps d'exécution, taille des données
  • Détails des appels API : Requêtes/réponses des APIs externes

Exemple de logs

[MCP-CLIENT] 🔄 Chargement des outils depuis le serveur MCP...
[MCP-CLIENT] 📤 Request payload: getTools()
[MCP-SERVER] 📥 Requête ListTools reçue
[MCP-SERVER] 📤 Request payload: {"method":"tools/list",...}
[MCP-SERVER] 📥 Response payload: {"tools":[...]}
[MCP-CLIENT] ✅ 2 outils chargés depuis le serveur MCP
[LANGCHAIN-AGENT] 🔄 Invocation de l'agent avec le message utilisateur...
[LANGCHAIN-AGENT] 📤 Request payload (invoke): {"messages":[...]}
[TOOL:search] 🔍 Recherche Brave Search pour: "TypeScript"
[TOOL:search] 📤 API Request payload: {"url":"...","params":{...}}
[TOOL:search] 📥 API Response payload: {"resultsCount":5,...}
[LANGCHAIN-AGENT] ✅ Agent a terminé en 1234ms

🎯 Fonctionnalités

Recherche Web (Brave Search)

L'agent peut rechercher des informations sur le web :

  • "Qu'est-ce que TypeScript?"
  • "Recherche des nouvelles sur l'IA en 2024"

Météo

L'agent peut obtenir la météo actuelle et les prévisions :

  • "Météo à Paris"
  • "Quel temps fait-il à Lyon?"
  • "Météo 75001"

Requêtes complexes

L'agent peut combiner plusieurs outils pour répondre à des questions complexes :

  • "Compare React et Vue.js en 2024" (utilisera la recherche)
  • "Météo à Paris et recherche des événements météo cette semaine" (utilisera météo + recherche)

🔄 Ajouter de nouveaux outils

Pour ajouter un nouvel outil au serveur MCP :

  1. Ajoutez l'outil dans mcpServer.ts :

    • Ajoutez la définition dans ListToolsRequestSchema
    • Ajoutez le handler dans CallToolRequestSchema
  2. C'est tout ! L'outil sera automatiquement chargé et disponible dans LangChain sans modification du code client.

📝 Exemples d'utilisation

> Météo à Paris
🤔 Traitement en cours...
────────────────────────────────────────────────────────────
[USER] 📥 Question reçue: "Météo à Paris"
[LANGCHAIN-AGENT] 🔄 Invocation de l'agent avec le message utilisateur...
[TOOL:weather] 🌤️  Recherche météo pour: "Paris"
[TOOL:weather] 📤 API Request payload (geo): {...}
[TOOL:weather] 📥 API Response payload (geo): {...}
[LANGCHAIN-AGENT] ✅ Agent a terminé en 1234ms
────────────────────────────────────────────────────────────

💬 Réponse:
**Météo actuelle à Paris**

🌡️ Température: 15°C (ressentie: 14°C)
☁️ Conditions: nuageux
💧 Humidité: 65%
📊 Pression: 1013 hPa
💨 Vent: 12.5 km/h NE

**Prévisions (prochaines 24h):**
- lun. 14:00: 16°C, nuageux
- lun. 17:00: 17°C, partiellement nuageux
...

🐛 Dépannage

Erreur "Missing required environment variable"

Vérifiez que votre fichier .env contient toutes les clés API requises.

Erreur "Model not found"

Assurez-vous que votre clé OpenAI a accès à GPT-4. Vous pouvez utiliser gpt-4-turbo-preview ou gpt-3.5-turbo comme alternative.

Erreur de compilation TypeScript

Vérifiez que vous avez installé toutes les dépendances avec npm install.

Le serveur MCP ne démarre pas

Assurez-vous que tsx est disponible. Le projet utilise npx -y tsx pour lancer le serveur, ce qui devrait fonctionner automatiquement.

Erreur "Package subpath './agents' is not defined"

Cette erreur indique que vous utilisez une ancienne version de LangChain. Assurez-vous d'utiliser LangChain 1.0.0 avec la nouvelle API createAgent().

📚 Documentation et ressources

Utilisation de Context7

Ce projet a été développé en utilisant Context7 MCP pour obtenir la documentation de @langchain/mcp-adapters :

  1. Résolution de l'ID de la librairie :

    mcp_context7_resolve-library-id("langchain-mcp-adapters")
    

    Résultat : /langchain-ai/langchain-mcp-adapters

  2. Récupération de la documentation :

    mcp_context7_get-library-docs(
      "/langchain-ai/langchain-mcp-adapters",
      "MultiServerMCPClient getTools usage examples"
    )
    

Voir ADAPTATION.md pour plus de détails sur l'adaptation du projet.

Ressources

🔍 Différences avec les serveurs MCP out-of-the-box

Ce projet utilise un serveur MCP custom plutôt qu'un serveur pré-existant. Voici pourquoi :

Serveur MCP Custom (ce projet)

Avantages :

  • Contrôle total sur les outils et leur logique
  • Intégration directe avec vos APIs spécifiques
  • Personnalisation des réponses et formats
  • Logs détaillés pour le debugging
  • Facile à étendre avec de nouveaux outils

Serveurs MCP Out-of-the-box

Vous pouvez également utiliser des serveurs MCP pré-existants :

const mcpServerConfig = {
  // Serveur MCP pré-existant (exemple)
  math: {
    transport: "stdio" as const,
    command: "npx",
    args: ["-y", "@modelcontextprotocol/server-math"],
  },
  // Votre serveur custom
  searchWeatherServer: {
    transport: "stdio" as const,
    command: "npx",
    args: ["-y", "tsx", mcpServerPath],
  },
};

📄 License

ISC

🤝 Contribution

Les contributions sont les bienvenues ! N'hésitez pas à :

  1. Fork le projet
  2. Créer une branche pour votre fonctionnalité
  3. Commiter vos changements
  4. Pousser vers la branche
  5. Ouvrir une Pull Request