Skip to main content
Glama
flamekk

MCP Streamable HTTP Demo

by flamekk
README.md
# TP5 - Serveur MCP Streamable HTTP avec LangChain et n8n

Ce projet implémente un exemple complet autour du **Model Context Protocol (MCP)** :

- un serveur MCP exposé en **Streamable HTTP** ;
- deux tools MCP utilisables par des clients externes ;
- un test avec `@modelcontextprotocol/inspector` ;
- un agent **LangChain** connecté au serveur MCP ;
- une configuration **n8n AI Agent** utilisant le même endpoint MCP.

L'objectif est de reproduire l'esprit de la démo vidéo avec un projet local clair, testable et réutilisable.

## Aperçu

```mermaid
flowchart LR
  User["Utilisateur"] --> Agent["Agent LangChain ou n8n"]
  Agent --> MCPClient["Client MCP Streamable HTTP"]
  MCPClient --> Server["Serveur MCP Node.js"]
  Server --> Calc["Tool: calculate"]
  Server --> Stats["Tool: text_stats"]
```

Le serveur expose l'endpoint suivant :

```text
http://127.0.0.1:3000/mcp
```

L'endpoint `/mcp` n'est pas une page web classique. Il reçoit des requêtes MCP en `POST`. Pour une vérification navigateur simple, utiliser plutôt :

```text
http://127.0.0.1:3000/health
```

<img width="1280" height="720" alt="image" src="https://github.com/user-attachments/assets/51130451-7e0f-4ef2-ae0a-ec4eb2d96065" />


## Fonctionnalités

Le serveur MCP expose deux tools :

| Tool | Description | Exemple |
| --- | --- | --- |
| `calculate` | Exécute une opération arithmétique simple sur une liste de nombres. | addition, soustraction, multiplication, division |
| `text_stats` | Analyse un texte et retourne des statistiques. | caractères, mots, lignes, temps de lecture |

Le projet contient également :

| Fichier | Rôle |
| --- | --- |
| `src/mcp-server.js` | Serveur MCP Streamable HTTP |
| `src/mcp-smoke-test.js` | Client MCP minimal pour valider le serveur |
| `src/agent-langchain.js` | Agent LangChain utilisant les tools MCP |
| `docs/n8n-agent.md` | Guide de configuration n8n |
| `scripts/create-screenshots.ps1` | Script de génération des captures du README |

## Prérequis

- Node.js récent, testé avec Node.js `v24.14.1`.
- npm.
- Une clé OpenAI valide uniquement pour lancer l'agent LangChain ou l'agent n8n.

Installer les dépendances :

```powershell
npm install
```

Créer le fichier d'environnement :

```powershell
Copy-Item .env.example .env
```

Puis modifier `.env` :

```env
OPENAI_API_KEY=your_new_openai_key
OPENAI_MODEL=gpt-4o-mini
MCP_SERVER_URL=http://127.0.0.1:3000/mcp
MCP_HOST=127.0.0.1
MCP_PORT=3000
```

Important : ne jamais commiter `.env`. La clé OpenAI donnée dans l'énoncé a été exposée et doit être révoquée/remplacée.

## Lancer le serveur MCP

```powershell
npm run server
```

Sortie attendue :

```text
MCP server ready: http://127.0.0.1:3000/mcp
```

Vérifier l'état du serveur :

```powershell
Invoke-RestMethod http://127.0.0.1:3000/health
```

Sortie attendue :

```json
{
  "status": "ok",
  "mcpEndpoint": "/mcp"
}
```

## Tester le serveur MCP

Dans un premier terminal, garder le serveur actif :

```powershell
npm run server
```

Dans un second terminal, lancer le smoke test :

```powershell
npm run smoke
```

Le test liste les tools disponibles puis appelle `calculate`.

<img width="1280" height="760" alt="image" src="https://github.com/user-attachments/assets/04185c18-e693-46d8-8c27-07f37b9690d6" />



## Tester avec MCP Inspector

Lister les tools avec l'Inspector CLI :

```powershell
npm run inspector:list-tools
```

Sortie attendue : un JSON contenant `calculate` et `text_stats`.

<img width="1280" height="760" alt="image" src="https://github.com/user-attachments/assets/cd604413-d443-4dec-997c-04d2389e7125" />



Appeler directement un tool avec l'Inspector :

```powershell
npx --yes @modelcontextprotocol/inspector --cli http://127.0.0.1:3000/mcp --transport http --method tools/call --tool-name calculate --tool-arg operation=add --tool-arg "numbers=[2,3,4]"
```

Résultat attendu :

```json
{
  "operation": "add",
  "numbers": [2, 3, 4],
  "result": 9
}
```

Note Windows : la version actuelle de l'Inspector CLI peut afficher le bon JSON puis terminer avec une assertion Node/libuv. Si le JSON des tools apparaît correctement, l'appel MCP a réussi.

## Utiliser l'Inspector UI

Lancer l'interface graphique :

```powershell
npm run inspector
```

Configurer ensuite :

```text
Transport: Streamable HTTP
URL: http://127.0.0.1:3000/mcp
```

Actions à vérifier dans l'UI :

1. Cliquer sur `Connect`.
2. Ouvrir l'onglet `Tools`.
3. Vérifier que `calculate` et `text_stats` sont listés.
4. Appeler `calculate` avec :

```json
{
  "operation": "multiply",
  "numbers": [6, 7]
}
```

Résultat attendu : `42`.

## Agent LangChain

L'agent LangChain charge les tools MCP via le protocole Streamable HTTP, puis les donne au modèle OpenAI.

Avant de lancer l'agent :

1. Le serveur MCP doit être actif.
2. `.env` doit contenir une clé `OPENAI_API_KEY` valide.

Commande :

```powershell
npm run agent
```

Prompt personnalisé :

```powershell
npm run agent -- "Calcule 42 / 6 puis analyse le texte: Bonjour depuis MCP."
```

Comportement attendu :

- l'agent charge `2 MCP tools` ;
- il utilise `calculate` pour le calcul ;
- il utilise `text_stats` si le prompt demande une analyse de texte ;
- il répond en langage naturel avec les résultats.

## Agent n8n

Le guide complet est disponible ici :

[docs/n8n-agent.md](docs/n8n-agent.md)

Résumé de la configuration du node `MCP Client Tool` :

```text
Endpoint: http://127.0.0.1:3000/mcp
Server Transport: HTTP Streamable
Authentication: None
Tools to Include: All
```

Si n8n tourne dans Docker, remplacer `127.0.0.1` par :

```text
http://host.docker.internal:3000/mcp
```

Et lancer le serveur MCP avec :

```powershell
$env:MCP_HOST="0.0.0.0"; npm run server
```

## Scripts npm

| Script | Description |
| --- | --- |
| `npm run server` | Démarre le serveur MCP |
| `npm run smoke` | Liste les tools et appelle `calculate` |
| `npm run inspector` | Lance l'Inspector UI |
| `npm run inspector:list-tools` | Liste les tools via l'Inspector CLI |
| `npm run agent` | Lance l'agent LangChain |

## Dépannage

### `/mcp` affiche une erreur dans le navigateur

C'est normal. `/mcp` attend des requêtes MCP en `POST`. Utiliser `/health` pour un test navigateur.

### `OPENAI_API_KEY is missing`

Le fichier `.env` contient encore le placeholder. Remplacer :

```env
OPENAI_API_KEY=replace_with_your_rotated_key
```

par une vraie clé OpenAI.

### `401 Incorrect API key`

La clé OpenAI est invalide, révoquée ou mal copiée. Générer une nouvelle clé et mettre à jour `.env`.

### Port `3000` déjà utilisé

Changer le port dans `.env` :

```env
MCP_PORT=3001
MCP_SERVER_URL=http://127.0.0.1:3001/mcp
```

Puis relancer :

```powershell
npm run server
```

### n8n ne se connecte pas au MCP

Si n8n est lancé en Docker, `127.0.0.1` désigne le conteneur n8n, pas la machine hôte. Utiliser `host.docker.internal` et lancer le serveur avec `MCP_HOST=0.0.0.0`.

## Sécurité

- Ne jamais publier `.env`.
- Révoquer toute clé API partagée dans un chat, un dépôt Git ou une capture.
- Préférer une clé dédiée au TP.
- En production, ajouter une couche d'authentification devant le serveur MCP.

## Structure du projet

```text
TP5/
├── docs/
│   ├── n8n-agent.md
│   └── screenshots/
│       ├── health-endpoint.png
│       ├── inspector-tools.png
│       └── smoke-test.png
├── scripts/
│   └── create-screenshots.ps1
├── src/
│   ├── agent-langchain.js
│   ├── mcp-server.js
│   └── mcp-smoke-test.js
├── .env.example
├── package.json
└── README.md
```