Update MCP server
This commit is contained in:
+111
-167
@@ -1,28 +1,20 @@
|
||||
# crowdlending-mcp-server
|
||||
|
||||
Serveur MCP pour le portefeuille de crowdlending. Il expose en lecture seule
|
||||
les données d'un investisseur (investissements, remboursements,
|
||||
dépôts/retraits, dashboard) à un client MCP — Claude Desktop, Claude Code,
|
||||
ou tout autre client compatible — en s'appuyant sur l'API publique `/api/v1`
|
||||
du backend.
|
||||
Serveur MCP (HTTP, Streamable HTTP transport) pour le portefeuille de
|
||||
crowdlending. Il expose en lecture seule les données d'un investisseur
|
||||
(investissements, remboursements, dépôts/retraits, dashboard) à un client
|
||||
MCP — Claude Desktop, Claude Code, ou tout autre client compatible — en
|
||||
s'appuyant sur l'API publique `/api/v1` du backend.
|
||||
|
||||
Il ne fait aucune écriture : toutes les modifications restent à faire dans
|
||||
l'app web.
|
||||
|
||||
Deux modes, deux fichiers :
|
||||
|
||||
- **Local (`index.js`, stdio)** — lancé comme process enfant par Claude
|
||||
Desktop sur votre propre machine. Nécessite Node.js et ce dépôt cloné en
|
||||
local. Inclut l'outil `crowdlending_fetch_url` (lecture de page web).
|
||||
- **Distant (`http-server.js`, HTTP)** — un service déployé une fois (par
|
||||
l'administrateur de l'instance) sur `mcp.crowdlending.croguennec.net`,
|
||||
accessible à n'importe quel utilisateur distant sans rien installer :
|
||||
juste une URL + sa clé API personnelle à coller dans son client MCP.
|
||||
N'inclut PAS `crowdlending_fetch_url` (voir plus bas).
|
||||
|
||||
Les deux partagent le même code pour les 6 outils de lecture de données
|
||||
(`tools.js`) — leur comportement ne peut donc pas diverger entre les deux
|
||||
modes.
|
||||
**Un seul serveur, un seul fichier (`server.js`)**, utilisé aussi bien en
|
||||
développement local (`npm run dev`, comme le backend et le frontend) qu'en
|
||||
production (service Docker `crowdlending-mcp`, derrière Traefik sur
|
||||
`mcp.crowdlending.croguennec.net`). Pas de distinction de code entre les
|
||||
deux — seule la configuration change (quelle API cibler, quels outils
|
||||
activer).
|
||||
|
||||
## Prérequis
|
||||
|
||||
@@ -31,130 +23,28 @@ modes.
|
||||
- Le backend accessible (en local `http://localhost:4000`, ou l'URL de votre
|
||||
instance en production)
|
||||
|
||||
## Installation
|
||||
## Développement local
|
||||
|
||||
Comme pour `backend/` et `frontend/` :
|
||||
|
||||
```
|
||||
cd mcp-server
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Configuration
|
||||
`npm run dev` (comme `backend`) relance automatiquement le serveur à chaque
|
||||
modification de fichier (`node --watch`). Par défaut, il écoute sur
|
||||
`http://localhost:4100` et cible l'API locale (`http://localhost:4000/api/v1`).
|
||||
|
||||
Trois variables d'environnement :
|
||||
|
||||
| Variable | Obligatoire | Défaut | Exemple |
|
||||
|---|---|---|---|
|
||||
| `CROWDLENDING_API_KEY` | oui | — | `clk_live_...` |
|
||||
| `CROWDLENDING_API_URL` | non | `http://localhost:4000/api/v1` | `https://mon-domaine.fr/api/v1` |
|
||||
| `CROWDLENDING_LABEL` | non | — | `dev`, `prod` |
|
||||
|
||||
`CROWDLENDING_LABEL` sert uniquement à distinguer plusieurs instances
|
||||
connectées en même temps (voir [Faire tourner dev et prod en même
|
||||
temps](#faire-tourner-dev-et-prod-en-même-temps)) : il apparaît dans le nom
|
||||
du serveur, dans le titre de chaque outil (`[DEV]` / `[PROD]`) et dans la
|
||||
description (avec l'URL API ciblée), pour que l'agent — et vous — sachiez
|
||||
toujours quel environnement est interrogé.
|
||||
|
||||
## Utiliser avec Claude Desktop
|
||||
|
||||
Localisez le fichier de config Claude Desktop — le chemin diffère selon la
|
||||
provenance de l'installation Windows :
|
||||
|
||||
- **Installeur classique** (téléchargé depuis claude.ai) :
|
||||
`%APPDATA%\Claude\claude_desktop_config.json`
|
||||
- **Microsoft Store** : Windows redirige `%APPDATA%` vers un dossier virtualisé
|
||||
propre à l'app —
|
||||
`%LOCALAPPDATA%\Packages\Claude_<id>\LocalCache\Roaming\Claude\claude_desktop_config.json`
|
||||
(le `<id>` est un identifiant généré, propre à votre installation).
|
||||
|
||||
Le plus fiable dans les deux cas : Réglages → Développeur → Serveurs MCP
|
||||
locaux → **Modifier la config**, qui ouvre directement le bon fichier quelle
|
||||
que soit la provenance de l'installation.
|
||||
|
||||
Ajoutez une entrée dans `mcpServers` :
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"crowdlending": {
|
||||
"command": "node",
|
||||
"args": ["C:\\dev\\crowdlending-app\\mcp-server\\index.js"],
|
||||
"env": {
|
||||
"CROWDLENDING_API_KEY": "clk_live_...",
|
||||
"CROWDLENDING_API_URL": "http://localhost:4000/api/v1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Redémarrez Claude Desktop. L'icône 🔌 (ou le menu des outils MCP) doit
|
||||
afficher les 7 outils `crowdlending_*` ci-dessous.
|
||||
|
||||
Pour pointer vers votre instance de production plutôt que le backend local,
|
||||
changez uniquement `CROWDLENDING_API_URL` (et utilisez une clé API générée
|
||||
sur cette instance).
|
||||
|
||||
## Faire tourner dev et prod en même temps
|
||||
|
||||
Claude Desktop peut se connecter à plusieurs serveurs MCP simultanément : il
|
||||
suffit de déclarer deux entrées avec des clés distinctes dans `mcpServers`.
|
||||
Chaque outil est alors automatiquement rattaché à son serveur d'origine —
|
||||
pas de collision technique possible entre les deux, même si les noms
|
||||
d'outils (`crowdlending_get_dashboard`, etc.) sont identiques des deux côtés.
|
||||
Connectez ensuite Claude Desktop : Réglages → Développeur → Serveurs MCP
|
||||
locaux → **Modifier la config**, puis ajoutez dans `mcpServers` :
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"crowdlending-dev": {
|
||||
"command": "node",
|
||||
"args": ["C:\\dev\\crowdlending-app\\mcp-server\\index.js"],
|
||||
"env": {
|
||||
"CROWDLENDING_API_KEY": "clk_live_...",
|
||||
"CROWDLENDING_API_URL": "http://localhost:4000/api/v1",
|
||||
"CROWDLENDING_LABEL": "dev"
|
||||
}
|
||||
},
|
||||
"crowdlending-prod": {
|
||||
"command": "node",
|
||||
"args": ["C:\\dev\\crowdlending-app\\mcp-server\\index.js"],
|
||||
"env": {
|
||||
"CROWDLENDING_API_KEY": "clk_live_...",
|
||||
"CROWDLENDING_API_URL": "https://mon-domaine.fr/api/v1",
|
||||
"CROWDLENDING_LABEL": "prod"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Utilisez deux clés API différentes (une par instance, générées séparément
|
||||
sur chaque backend) : ça permet de révoquer l'une sans affecter l'autre, et
|
||||
c'est cohérent avec le principe d'une clé par usage.
|
||||
|
||||
Avec `CROWDLENDING_LABEL` renseigné, chaque outil affiche son environnement
|
||||
dans son titre (ex. « Synthèse du portefeuille [PROD] ») et sa description
|
||||
se termine par la source exacte interrogée — de quoi lever toute ambiguïté
|
||||
si vous demandez « mon encours en prod » vs « mon encours en dev ».
|
||||
|
||||
## Serveur distant — pour les utilisateurs sans installation locale
|
||||
|
||||
Si vous n'êtes pas sur la machine qui héberge ce dépôt (pas de Node.js, pas
|
||||
envie de cloner le repo), vous pouvez vous connecter directement au serveur
|
||||
MCP distant déployé sur `https://mcp.crowdlending.croguennec.net` — aucune
|
||||
installation nécessaire, juste votre clé API personnelle.
|
||||
|
||||
**1. Créer votre clé API** — dans l'app, Mon compte → Clés API → Nouvelle
|
||||
clé (elle ne sera affichée qu'une seule fois, copiez-la).
|
||||
|
||||
**2. Ajouter le serveur dans Claude Desktop** — Réglages → Développeur →
|
||||
Serveurs MCP locaux → Modifier la config, puis ajoutez :
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"crowdlending-distant": {
|
||||
"url": "https://mcp.crowdlending.croguennec.net/mcp",
|
||||
"url": "http://localhost:4100/mcp",
|
||||
"headers": {
|
||||
"X-API-Key": "clk_live_..."
|
||||
}
|
||||
@@ -163,52 +53,95 @@ Serveurs MCP locaux → Modifier la config, puis ajoutez :
|
||||
}
|
||||
```
|
||||
|
||||
**3. Redémarrez Claude Desktop.** Les 6 outils `crowdlending_*` doivent
|
||||
apparaître (sans `crowdlending_fetch_url`, réservé au serveur local).
|
||||
Redémarrez Claude Desktop. Les outils `crowdlending_*` doivent apparaître
|
||||
(voir la liste plus bas — `crowdlending_fetch_url` en plus si activé, voir
|
||||
Configuration).
|
||||
|
||||
### Différences avec le serveur local
|
||||
## Configuration
|
||||
|
||||
- **Pas de `crowdlending_fetch_url`** : lire une page web arbitraire pour un
|
||||
utilisateur tiers non maîtrisé augmenterait le risque SSRF sans bénéfice
|
||||
réel pour ce cas d'usage. Cet outil reste réservé au serveur local.
|
||||
- **Authentification par requête, pas par process** : le serveur local a une
|
||||
clé API fixée une fois pour toutes via une variable d'environnement — un
|
||||
process = un utilisateur. Le serveur distant sert plusieurs utilisateurs en
|
||||
parallèle : chaque session est créée à partir de la clé API envoyée dans
|
||||
l'en-tête `X-API-Key` de la requête qui l'initialise, puis liée à cette
|
||||
session uniquement. Deux utilisateurs ne partagent jamais de données.
|
||||
- **Exposé publiquement, sans la liste blanche d'IP** qui protège le reste de
|
||||
l'app (`ipwhitelist-all`) : la clé API est la seule barrière d'accès.
|
||||
Traitez-la comme un mot de passe — ne la partagez pas, révoquez-la
|
||||
immédiatement en cas de doute (Mon compte → Clés API).
|
||||
- **Limite de débit** : 60 requêtes/minute par adresse IP, au-delà l'API
|
||||
répond `429`.
|
||||
- **Sessions** : une session inactive plus de 30 minutes est fermée côté
|
||||
serveur (mémoire uniquement, aucune persistance) ; votre client MCP en
|
||||
recréera une automatiquement à la prochaine requête.
|
||||
Variables d'environnement, toutes optionnelles sauf pour un déploiement
|
||||
distant réel (en local, les valeurs par défaut conviennent) :
|
||||
|
||||
### Déploiement (administrateur de l'instance)
|
||||
| Variable | Défaut | Description |
|
||||
|---|---|---|
|
||||
| `PORT` | `4100` | Port d'écoute HTTP |
|
||||
| `CROWDLENDING_API_URL` | `http://localhost:4000/api/v1` | API v1 ciblée |
|
||||
| `MCP_LABEL` | — | Étiquette d'environnement (`dev`, `prod`...) — voir plus bas |
|
||||
| `MCP_ENABLE_FETCH_URL` | `false` | Active l'outil `crowdlending_fetch_url` (voir plus bas) |
|
||||
| `MCP_ALLOWED_HOSTS` | `mcp.crowdlending.croguennec.net,localhost` | En-têtes `Host` acceptés (protection anti DNS-rebinding) |
|
||||
|
||||
Le service `crowdlending-mcp` du `docker-compose.yml` construit et lance
|
||||
`http-server.js`, exposé via Traefik sur `mcp.crowdlending.croguennec.net`
|
||||
(certificat TLS automatique, même resolver que le reste de l'app). Un
|
||||
enregistrement DNS pour ce sous-domaine, pointant vers la même IP que
|
||||
Aucune clé API fixe n'est configurée côté serveur, contrairement à une
|
||||
ancienne version qui utilisait le transport stdio : chaque session MCP lit
|
||||
sa propre clé dans l'en-tête `X-API-Key` de la requête qui l'initialise (le
|
||||
bloc `headers` de la config Claude Desktop ci-dessus). Un même process peut
|
||||
donc servir plusieurs utilisateurs/sessions en parallèle sans jamais mélanger
|
||||
leurs données — voir le déploiement distant plus bas.
|
||||
|
||||
## Faire tourner dev et prod en même temps
|
||||
|
||||
Claude Desktop peut se connecter à plusieurs serveurs MCP simultanément : il
|
||||
suffit de déclarer deux entrées dans `mcpServers`, une par URL. Chaque outil
|
||||
est automatiquement rattaché à son serveur d'origine — pas de collision
|
||||
possible, même si les noms d'outils sont identiques des deux côtés.
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"crowdlending-dev": {
|
||||
"url": "http://localhost:4100/mcp",
|
||||
"headers": { "X-API-Key": "clk_live_..." }
|
||||
},
|
||||
"crowdlending-prod": {
|
||||
"url": "https://mcp.crowdlending.croguennec.net/mcp",
|
||||
"headers": { "X-API-Key": "clk_live_..." }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Utilisez deux clés API différentes (une par instance) : ça permet de
|
||||
révoquer l'une sans affecter l'autre. Réglez `MCP_LABEL=dev` (côté serveur
|
||||
local, dans votre `.env` ou variable d'environnement au lancement) pour que
|
||||
le titre de chaque outil affiche `[DEV]` et lève toute ambiguïté — le
|
||||
serveur distant est déjà configuré avec `MCP_LABEL` correspondant en
|
||||
production.
|
||||
|
||||
## Déploiement en production (Docker)
|
||||
|
||||
Le service `crowdlending-mcp` du `docker-compose.yml` à la racine construit
|
||||
et lance ce même `server.js`, exposé via Traefik sur
|
||||
`mcp.crowdlending.croguennec.net` (certificat TLS automatique). Contrairement
|
||||
au reste de l'app, ce service n'a **pas** le middleware `ipwhitelist-all` :
|
||||
il est volontairement accessible depuis internet, pour des utilisateurs
|
||||
distants qui ne peuvent pas faire tourner le serveur en local — la clé API
|
||||
est donc la seule barrière d'accès. Traitez-la comme un mot de passe, et
|
||||
révoquez-la immédiatement en cas de doute (Mon compte → Clés API).
|
||||
|
||||
Un enregistrement DNS pour ce sous-domaine, pointant vers la même IP que
|
||||
`crowdlending.croguennec.net`, est nécessaire avant le premier déploiement.
|
||||
Variables d'environnement du service : `CROWDLENDING_API_URL` (URL interne
|
||||
du backend sur le réseau Docker, déjà configurée) et `MCP_ALLOWED_HOSTS`
|
||||
(validation de l'en-tête `Host`, protection anti DNS-rebinding — doit
|
||||
correspondre exactement au(x) nom(s) de domaine exposé(s)).
|
||||
|
||||
`MCP_ENABLE_FETCH_URL` reste à `false` en production (voir docker-compose.yml)
|
||||
: cet outil lit une URL arbitraire fournie par l'appelant, acceptable pour
|
||||
un usage perso où vous seul détenez la clé, mais risqué (SSRF) face à des
|
||||
utilisateurs distants non maîtrisés.
|
||||
|
||||
Autres protections : limite de 60 requêtes/minute par IP (au-delà, `429`),
|
||||
et fermeture automatique des sessions inactives depuis plus de 30 minutes
|
||||
(mémoire uniquement, aucune persistance).
|
||||
|
||||
## Tester sans Claude Desktop
|
||||
|
||||
Le [MCP Inspector](https://github.com/modelcontextprotocol/inspector) permet
|
||||
de lister et appeler les outils depuis une interface web, sans configurer de
|
||||
client :
|
||||
de lister et appeler les outils depuis une interface web :
|
||||
|
||||
```
|
||||
CROWDLENDING_API_KEY=clk_live_... npm run inspect
|
||||
npm run inspect
|
||||
```
|
||||
|
||||
Dans l'interface, choisissez le transport **Streamable HTTP**, entrez
|
||||
l'URL (`http://localhost:4100/mcp` en dev) et ajoutez l'en-tête
|
||||
`X-API-Key` avec votre clé.
|
||||
|
||||
## Outils exposés
|
||||
|
||||
Tous en lecture seule (`readOnlyHint: true`) :
|
||||
@@ -221,10 +154,14 @@ Tous en lecture seule (`readOnlyHint: true`) :
|
||||
| `crowdlending_get_investissement` | Détail d'un investissement + ses remboursements |
|
||||
| `crowdlending_list_remboursements` | Historique des remboursements, filtrable par période |
|
||||
| `crowdlending_list_depots_retraits` | Historique des mouvements de cash |
|
||||
| `crowdlending_fetch_url` | *(serveur local uniquement)* Lit une page web (annonce de projet) et en extrait le texte propre — voir ci-dessous |
|
||||
| `crowdlending_fetch_url` | *(actif seulement si `MCP_ENABLE_FETCH_URL=true`)* Lit une page web (annonce de projet) et en extrait le texte propre — voir ci-dessous |
|
||||
|
||||
## Lire une annonce de projet (`crowdlending_fetch_url`)
|
||||
|
||||
Désactivé par défaut — à activer avec `MCP_ENABLE_FETCH_URL=true`,
|
||||
typiquement en développement local uniquement (voir Configuration et
|
||||
Sécurité plus haut).
|
||||
|
||||
Cet outil récupère une page web et en extrait le contenu lisible (titre +
|
||||
texte principal) via [Readability](https://github.com/mozilla/readability),
|
||||
la librairie du mode lecture de Firefox — menus, pubs, scripts et bandeaux
|
||||
@@ -249,10 +186,17 @@ Garde-fous :
|
||||
|
||||
## Dépannage
|
||||
|
||||
- **`ERREUR : CROWDLENDING_API_KEY est requise`** — la variable d'env n'est
|
||||
pas transmise. Vérifiez la section `env` de votre config MCP.
|
||||
- **`En-tête X-API-Key manquant`** — vérifiez la section `headers` de votre
|
||||
config Claude Desktop.
|
||||
- **`Clé API invalide ou révoquée`** — régénérez une clé dans Mon compte →
|
||||
Clés API et mettez à jour la config.
|
||||
- **`Impossible de joindre l'API`** — le backend n'est pas démarré, ou
|
||||
`CROWDLENDING_API_URL` pointe au mauvais endroit (vérifiez le port et le
|
||||
suffixe `/api/v1`).
|
||||
- **`Invalid Host` (403)** — l'en-tête `Host` de la requête ne correspond à
|
||||
aucune valeur de `MCP_ALLOWED_HOSTS`. En local, vérifiez que vous appelez
|
||||
bien `localhost:4100` (pas `127.0.0.1:4100`, absent de la liste par
|
||||
défaut — ajoutez-le à `MCP_ALLOWED_HOSTS` si besoin).
|
||||
- **Session `404` après une longue pause** — la session a expiré après 30
|
||||
minutes d'inactivité, votre client MCP doit s'y reconnecter (généralement
|
||||
automatique).
|
||||
|
||||
Reference in New Issue
Block a user