Fix
This commit is contained in:
@@ -1091,27 +1091,30 @@ function ApiKeysSection() {
|
||||
}
|
||||
|
||||
/* ── Serveur MCP ──────────────────────────────────────────────
|
||||
Guide pas-à-pas pour connecter Claude Desktop au serveur MCP local
|
||||
(mcp-server/ à la racine du projet). Le JSON de config est généré
|
||||
côté client à partir des champs ci-dessous ; la clé API saisie ici
|
||||
reste uniquement en mémoire du navigateur, elle n'est jamais envoyée
|
||||
au backend — seulement utilisée pour composer l'aperçu à copier. ── */
|
||||
Guide pas-à-pas pour connecter Claude Desktop au serveur MCP
|
||||
(mcp-server/ à la racine du projet, un seul modèle url+headers en HTTP,
|
||||
que ce soit en développement local ou déployé à distance en prod — voir
|
||||
mcp-server/README.md). Le JSON de config est généré côté client à partir
|
||||
des champs ci-dessous ; la clé API saisie ici reste uniquement en mémoire
|
||||
du navigateur, elle n'est jamais envoyée au backend — seulement utilisée
|
||||
pour composer l'aperçu à copier. ── */
|
||||
|
||||
/** Devine une URL d'API raisonnable selon l'environnement courant :
|
||||
* en dev (Vite sur :5173), le process Node du serveur MCP ne passe pas
|
||||
* par le proxy Vite, il faut donc viser directement le port du backend (4000).
|
||||
* En prod (nginx sert front + /api sur la même origine), l'origine courante convient. */
|
||||
function guessMcpApiUrl() {
|
||||
if (typeof window === 'undefined') return 'http://localhost:4000/api/v1';
|
||||
const { hostname, port, origin } = window.location;
|
||||
if (port === '5173') return `http://${hostname}:4000/api/v1`;
|
||||
return `${origin}/api/v1`;
|
||||
/** Devine une URL de serveur MCP raisonnable selon l'environnement courant :
|
||||
* en dev (Vite sur :5173 ou localhost), le serveur MCP tourne en local sur
|
||||
* son port par défaut (npm run dev, :4100). En prod, il s'agit du
|
||||
* sous-domaine dédié mcp.<domaine de l'app>, déjà déployé en continu. */
|
||||
function guessMcpUrl() {
|
||||
if (typeof window === 'undefined') return 'http://localhost:4100/mcp';
|
||||
const { hostname, port } = window.location;
|
||||
if (port === '5173' || hostname === 'localhost' || hostname === '127.0.0.1') {
|
||||
return 'http://localhost:4100/mcp';
|
||||
}
|
||||
return `https://mcp.${hostname}/mcp`;
|
||||
}
|
||||
|
||||
/** Détecte automatiquement l'environnement ('dev' ou 'prod') à partir de
|
||||
* l'URL de l'API : localhost/IP locale ou nom d'hôte contenant "dev" →
|
||||
* dev, tout le reste → prod. Best-effort — reste modifiable manuellement
|
||||
* pour les cas particuliers (domaine de test qui ne contient pas "dev"...). */
|
||||
* l'URL du serveur MCP : localhost/IP locale → dev, tout le reste → prod.
|
||||
* Best-effort — reste modifiable manuellement pour les cas particuliers. */
|
||||
function detectLabelFromUrl(url) {
|
||||
if (!url) return 'prod';
|
||||
let hostname;
|
||||
@@ -1146,27 +1149,28 @@ function CopyBlock({ text }) {
|
||||
}
|
||||
|
||||
function McpServerSection({ goToApiKeys }) {
|
||||
const [mcpPath, setMcpPath] = useState('C:\\dev\\crowdlending-app\\mcp-server\\index.js');
|
||||
const [apiUrl, setApiUrl] = useState(guessMcpApiUrl());
|
||||
const [mcpUrl, setMcpUrl] = useState(guessMcpUrl());
|
||||
const [apiKey, setApiKey] = useState('');
|
||||
const [manualLabel, setManualLabel] = useState(null); // null = auto-détecté depuis apiUrl, sinon override manuel
|
||||
const [manualLabel, setManualLabel] = useState(null); // null = auto-détecté depuis mcpUrl, sinon override manuel
|
||||
|
||||
const detectedLabel = detectLabelFromUrl(apiUrl);
|
||||
const detectedLabel = detectLabelFromUrl(mcpUrl);
|
||||
const label = manualLabel ?? detectedLabel;
|
||||
const isLocal = label === 'dev';
|
||||
|
||||
const serverKey = `crowdlending-${label}`;
|
||||
const env = {
|
||||
CROWDLENDING_API_KEY: apiKey || '<VOTRE_CLE_API>',
|
||||
CROWDLENDING_API_URL: apiUrl,
|
||||
CROWDLENDING_LABEL: label,
|
||||
};
|
||||
// claude_desktop_config.json n'a pas de champ url/headers natif : on passe
|
||||
// par mcp-remote (https://github.com/geelen/mcp-remote), un pont stdio↔HTTP
|
||||
// que Claude Desktop lance comme n'importe quel serveur "command". La clé
|
||||
// API passe en variable d'environnement plutôt que directement dans args
|
||||
// (bug connu de Claude Desktop Windows qui tronque les valeurs à espaces).
|
||||
const envVarName = `${label.toUpperCase()}_API_KEY`;
|
||||
|
||||
const configJson = JSON.stringify({
|
||||
mcpServers: {
|
||||
[serverKey]: {
|
||||
command: 'node',
|
||||
args: [mcpPath],
|
||||
env,
|
||||
command: 'npx',
|
||||
args: ['-y', 'mcp-remote', mcpUrl, '--header', `X-API-Key:\${${envVarName}}`],
|
||||
env: { [envVarName]: apiKey || '<VOTRE_CLE_API>' },
|
||||
},
|
||||
},
|
||||
}, null, 2);
|
||||
@@ -1176,8 +1180,8 @@ function McpServerSection({ goToApiKeys }) {
|
||||
<h3 style={{ margin: '0 0 4px' }}>Serveur MCP</h3>
|
||||
<p className="text-muted" style={{ margin: '0 0 20px', fontSize: 'var(--fs-sm)' }}>
|
||||
Permet à Claude Desktop (ou tout client MCP) de consulter votre portefeuille en lecture seule.
|
||||
Le serveur (dossier <code>mcp-server/</code> du projet) doit être installé sur cette machine
|
||||
(<code>npm install</code>) — voir <code>mcp-server/README.md</code> pour le détail.
|
||||
Un seul modèle de connexion, en développement local comme en production : une URL de serveur MCP
|
||||
et votre clé API personnelle — voir <code>mcp-server/README.md</code> pour le détail.
|
||||
</p>
|
||||
|
||||
<h4 style={{ margin: '0 0 6px', fontSize: 'var(--fs-sm)' }}>1. Créer une clé API dédiée</h4>
|
||||
@@ -1194,12 +1198,8 @@ function McpServerSection({ goToApiKeys }) {
|
||||
<h4 style={{ margin: '0 0 10px', fontSize: 'var(--fs-sm)' }}>2. Renseigner les paramètres</h4>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 12, marginBottom: 20, maxWidth: 520 }}>
|
||||
<div>
|
||||
<label>Chemin vers mcp-server/index.js</label>
|
||||
<input value={mcpPath} onChange={e => setMcpPath(e.target.value)} />
|
||||
</div>
|
||||
<div>
|
||||
<label>URL de l'API</label>
|
||||
<input value={apiUrl} onChange={e => setApiUrl(e.target.value)} />
|
||||
<label>URL du serveur MCP</label>
|
||||
<input value={mcpUrl} onChange={e => setMcpUrl(e.target.value)} />
|
||||
</div>
|
||||
<div>
|
||||
<label>Clé API</label>
|
||||
@@ -1218,7 +1218,7 @@ function McpServerSection({ goToApiKeys }) {
|
||||
</span>
|
||||
<span style={{ fontSize: 'var(--fs-sm)', color: 'var(--text-muted)' }}>
|
||||
{manualLabel === null
|
||||
? <>déduit de l'URL de l'API ci-dessus (localhost / « dev » → dev, sinon prod)</>
|
||||
? <>déduit de l'URL ci-dessus (localhost → dev, sinon prod)</>
|
||||
: <>forcé manuellement</>}
|
||||
</span>
|
||||
</div>
|
||||
@@ -1236,12 +1236,26 @@ function McpServerSection({ goToApiKeys }) {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<p style={{ margin: '-8px 0 20px', fontSize: 'var(--fs-sm)', color: 'var(--text-muted)' }}>
|
||||
|
||||
{isLocal ? (
|
||||
<p style={{ margin: '-8px 0 20px', fontSize: 'var(--fs-sm)', color: 'var(--text-muted)' }}>
|
||||
En développement, ce serveur doit tourner sur votre machine pour que l'URL ci-dessus réponde :
|
||||
<code style={{ display: 'block', margin: '6px 0', padding: '6px 8px', borderRadius: 6, background: 'var(--surface-2, #f9fafb)' }}>
|
||||
cd mcp-server && npm install && npm run dev
|
||||
</code>
|
||||
comme pour le backend et le frontend. Laissez ce terminal ouvert tant que vous utilisez Claude Desktop.
|
||||
</p>
|
||||
) : (
|
||||
<p style={{ margin: '-8px 0 20px', fontSize: 'var(--fs-sm)', color: 'var(--text-muted)' }}>
|
||||
En production, le serveur tourne déjà en continu (service <code>crowdlending-mcp</code>) — aucune
|
||||
action nécessaire au-delà de renseigner l'URL et votre clé API.
|
||||
</p>
|
||||
)}
|
||||
<p style={{ margin: '0 0 20px', fontSize: 'var(--fs-sm)', color: 'var(--text-muted)' }}>
|
||||
Claude Desktop peut se connecter à plusieurs serveurs MCP en même temps : pour avoir dev et
|
||||
prod accessibles simultanément, répétez ces étapes une deuxième fois avec une URL d'API pointant
|
||||
vers l'autre environnement (et une clé API distincte) — l'étiquette et la clé de config
|
||||
(<code>{serverKey}</code> ci-dessous) s'ajustent automatiquement. Elle apparaît dans le titre et
|
||||
la description de chaque outil, pour que l'agent ne confonde jamais les deux portefeuilles.
|
||||
prod accessibles simultanément, répétez ces étapes une deuxième fois avec l'autre URL (et une clé
|
||||
API distincte) — la clé de config (<code>{serverKey}</code> ci-dessous) s'ajuste automatiquement,
|
||||
Claude Desktop ne confondra jamais les deux portefeuilles.
|
||||
</p>
|
||||
|
||||
<h4 style={{ margin: '0 0 6px', fontSize: 'var(--fs-sm)' }}>3. Copier la configuration</h4>
|
||||
@@ -1268,8 +1282,10 @@ function McpServerSection({ goToApiKeys }) {
|
||||
|
||||
<h4 style={{ margin: '0 0 6px', fontSize: 'var(--fs-sm)' }}>5. Vérifier</h4>
|
||||
<p style={{ margin: 0, fontSize: 'var(--fs-sm)', color: 'var(--text-muted)' }}>
|
||||
Dans la liste des outils MCP de Claude Desktop, les 7 outils <code>crowdlending_*</code> doivent
|
||||
apparaître. Testez avec une question du type « Quel est mon encours de crowdlending actuellement ? ».
|
||||
Dans la liste des outils MCP de Claude Desktop, les outils <code>crowdlending_*</code> doivent
|
||||
apparaître (6 en production, 7 en développement local si <code>crowdlending_fetch_url</code> est
|
||||
activé — voir <code>mcp-server/README.md</code>). Testez avec une question du type « Quel est mon
|
||||
encours de crowdlending actuellement ? ».
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user