Files
crowdlending-app/mcp-server/README.md
T
2026-07-15 23:08:36 +02:00

10 KiB

crowdlending-mcp-server

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.

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

  • Node.js ≥ 18 (fetch natif requis)
  • Une clé API générée dans l'app : Mon compte → Clés API → Nouvelle clé
  • Le backend accessible (en local http://localhost:4000, ou l'URL de votre instance en production)

Développement local

Comme pour backend/ et frontend/ :

cd mcp-server
npm install
npm run dev

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).

Connectez ensuite Claude Desktop : Réglages → Développeur → Serveurs MCP locaux → Modifier la config, puis ajoutez dans mcpServers :

{
  "mcpServers": {
    "crowdlending-dev": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "http://localhost:4100/mcp",
        "--header",
        "X-API-Key:${CROWDLENDING_API_KEY}"
      ],
      "env": {
        "CROWDLENDING_API_KEY": "clk_live_..."
      }
    }
  }
}

Important : claude_desktop_config.json n'accepte que des entrées command/args — il n'existe pas de champ url/headers natif dans ce fichier (contrairement à d'autres clients MCP). Pour un serveur HTTP comme celui-ci, on passe donc par mcp-remote, un petit pont stdio↔HTTP officiel : Claude Desktop lance npx mcp-remote comme d'habitude, qui se charge de parler HTTP à notre serveur en coulisses, en-tête X-API-Key inclus. Aucune installation manuelle requise, npx le télécharge à la volée.

Notez l'absence d'espace autour du : dans --header : Claude Desktop (Windows) a un bug connu qui tronque les arguments contenant un espace — on passe donc la valeur réelle (avec l'espace éventuel) via une variable d'environnement dans env plutôt que directement dans args.

Redémarrez Claude Desktop. Les outils crowdlending_* doivent apparaître (voir la liste plus bas — crowdlending_fetch_url en plus si activé, voir Configuration).

Configuration

Variables d'environnement, toutes optionnelles sauf pour un déploiement distant réel (en local, les valeurs par défaut conviennent) :

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)

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 (transmis via mcp-remote --header, voir 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.

{
  "mcpServers": {
    "crowdlending-dev": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "http://localhost:4100/mcp", "--header", "X-API-Key:${DEV_API_KEY}"],
      "env": { "DEV_API_KEY": "clk_live_..." }
    },
    "crowdlending-prod": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.crowdlending.croguennec.net/mcp", "--header", "X-API-Key:${PROD_API_KEY}"],
      "env": { "PROD_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.

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 permet de lister et appeler les outils depuis une interface web :

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) :

Outil Description
crowdlending_get_investisseur Profil de l'investisseur lié à la clé
crowdlending_get_dashboard Synthèse KPI : capital investi, capital en risque, intérêts perçus (filtrable par année), cash
crowdlending_list_investissements Liste des investissements, filtrable par statut
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 (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, la librairie du mode lecture de Firefox — menus, pubs, scripts et bandeaux cookies sont éliminés automatiquement.

Il ne fait aucune extraction métier côté serveur (pas de tentative de deviner taux/montant/durée par regex) : c'est l'agent qui lit le texte retourné et en extrait les informations pertinentes dans la conversation, pour vous les proposer avant toute saisie. Cohérent avec le reste du serveur : lecture seule, aucune création automatique d'investissement (l'API v1 n'a pas de capacité d'écriture).

Exemple d'usage : « Regarde cette page et propose-moi les infos pour créer l'investissement : https://plateforme.fr/projets/xxx ».

Garde-fous :

  • http/https uniquement, pages HTML uniquement.
  • Hôtes locaux/privés bloqués (localhost, 127.0.0.1, plages 10.x/172.16-31.x/192.168.x...) — l'outil ne peut pas cibler votre réseau local, y compris votre propre backend.
  • Texte tronqué à 8000 caractères sur les pages très longues (le champ truncated de la réponse l'indique).

Dépannage

  • En-tête X-API-Key manquant — vérifiez l'argument --header et la variable d'environnement correspondante dans votre config Claude Desktop.
  • « Certains serveurs MCP n'ont pas pu être chargés » / entrée ignorée — votre config utilise un bloc url/headers directement, non supporté par claude_desktop_config.json (voir Développement local plus haut) : il faut passer par command: "npx" + mcp-remote.
  • 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).