Serveur MCP
Serveur MCP
Utilisez FourA depuis n'importe quel client Model Context Protocol (Claude Desktop, Claude Code, Cursor, Windsurf, VS Code) sous la forme de trois outils natifs et de de cinq prompts de workflow. Aucun code d'intégration, aucun client HTTP personnalisé.
Démarrage rapide : stdio local (recommandé pour Claude Desktop)
Obtenez une clé sur foura.ai/dashboard#api-keys (un clic, affichée une seule fois à la création, format pk_live_...). Ajoutez-la dans la configuration de votre client MCP :
{
"mcpServers": {
"foura": {
"command": "npx",
"args": ["-y", "@fouradata/mcp"],
"env": { "FOURA_API_KEY": "pk_live_..." }
}
}
}
Piège avec Claude Desktop : quittez complètement Claude Desktop (
Cmd+Qsur macOS) avant de modifier le fichier de configuration. Si l'application est toujours en cours d'exécution, elle écrasera vos modifications avec sa configuration en mémoire lors de sa fermeture.
La commande npx télécharge @fouradata/mcp lors du premier lancement (~10s) et l'exécute en tant que sous-processus de votre client MCP. Aucune installation globale n'est requise.
| Client | Emplacement de la configuration |
|---|---|
| Claude Desktop (macOS) | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Claude Desktop (Windows) | %APPDATA%\\Claude\\claude_desktop_config.json |
| Claude Code | claude mcp add foura -- npx -y @fouradata/mcp (définissez d'abord FOURA_API_KEY dans l'environnement) |
| Cursor | ~/.cursor/mcp.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| VS Code (extension MCP) | .vscode/mcp.json |
Redémarrez le client. Les outils (foura_single, foura_proxy, foura_browser) et les cinq prompts apparaissent dans votre liste d'outils.
Démarrage rapide : hébergé (Streamable HTTP)
Pour les clients qui prennent en charge le transport Streamable HTTP (Cursor, Windsurf, VS Code, Claude Code avec --transport http), pointez-les vers l'endpoint hébergé au lieu d'exécuter un sous-processus local :
{
"mcpServers": {
"foura": {
"url": "https://mcp.foura.ai/mcp",
"headers": {
"Authorization": "Bearer pk_live_..."
}
}
}
}
Les versions actuelles de Claude Desktop rejettent la forme url brute. Utilisez la configuration stdio ci-dessus pour Claude Desktop, ou passez par une passerelle via mcp-remote :
{
"mcpServers": {
"foura": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.foura.ai/mcp", "--header", "Authorization: Bearer pk_live_..."]
}
}
}
Référence de l'endpoint hébergé
| Propriété | Valeur |
|---|---|
| URL | https://mcp.foura.ai/mcp |
| Transport | Streamable HTTP (POST /mcp, réponses SSE) |
| Authentification | Authorization: Bearer pk_live_... par request |
| MCP-Protocol-Version | Via @modelcontextprotocol/sdk (actuellement 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07) |
| Défi 401 | WWW-Authenticate: Bearer realm="foura-mcp", resource_metadata="https://foura.ai/docs/mcp/server#auth" |
Le serveur hébergé est sans état (stateless). Chaque request apporte sa propre clé, que le serveur transmet à l'API FourA sous la forme X-API-Key. Une seule clé ouvre les trois outils.
Pour se protéger contre le DNS-rebinding (CVE-2025-66414), le serveur valide le header Host (doit être mcp.foura.ai ou localhost) et le header Origin lorsqu'il est présent (autorisés : mcp.foura.ai, claude.ai, app.cursor.sh, app.cursor.com). Les appelants de serveur à serveur (curl, clients MCP en mode passerelle stdio) n'envoient pas d'header Origin et passent sans restriction.
Outils
Les trois outils sont annotés avec readOnlyHint: true and openWorldHint: true conformément à la spécification MCP 2025-06-18. Les clients qui approuvent automatiquement les outils en lecture seule de confiance les appellent sans afficher de fenêtre modale de confirmation par request.
foura_single
Une seule request HTTP, retour de la response. 200 ms à 2 s. Reflète POST /api/single/ à l'identique.
À utiliser pour les pages statiques, les API JSON et le HTML rendu côté serveur.
foura_proxy
Request HTTP acheminée via un pool de proxy tournants avec tentative automatique. 1 à 5 s. Reflète POST /api/proxy/.
À utiliser lorsque foura_single renvoie un code 403, un captcha ou du contenu géo-bloqué. La response inclut l'ID du proxy qui a réussi (proxy) et le temps total écoulé en secondes (total, float).
foura_browser
Session de navigateur complète. Le JavaScript s'exécute, le DOM s'affiche, les cookies sont renvoyés. 2 à 10 s. Reflète POST /api/browser/.
À utiliser pour les applications monopages (SPA), le contenu chargé à la demande (lazy-loaded) ou les pages protégées par des défis anti-robots qui nécessitent un vrai navigateur pour être résolus.
Pour les structures d'entrée, les valeurs par défaut et les règles de validation de chaque outil, reportez-vous à la référence de l'endpoint REST. Les schémas des outils correspondent champ pour champ à l'API REST, avec en plus l'option offload_large réservée à MCP (voir ci-dessous).
Responses typées
Chaque response d'outil comprend à la fois content (un résumé textuel lisible par l'homme) et structuredContent (du JSON typé validé par rapport à l' outputSchema de l'outil). Chaque outil possède sa propre structure unique :
foura_single:{ status, headers, data, total_time, ... }(les headers forment un tableau, une entrée par rebond de redirection)foura_proxy: identique à single avec en plus{ proxy, total }(oùtotalest un float en secondes, mesurant le temps total incluant les tentatives)foura_browser: structure distincte{ status, headers: object, body, cookies, userAgent }(remarque :bodypeut être une chaîne ou un objet selon le type de contenu)
Les clients qui prennent en charge structuredContent (Claude Desktop, Cursor, Windsurf à partir de 2026) transmettent l'objet typé directement au LLM, évitant ainsi la re-tokenisation du JSON sous forme de chaîne. Attendez-vous à une économie de 30 à 40 % de tokens sur les responses typiques.
Headers de response multi-valeurs
Les headers qui apparaissent plusieurs fois (Set-Cookie, Link, WWW-Authenticate) sont renvoyés sous forme de tableaux :
{
"headers": [
{
"result": { "version": "HTTP/2", "code": 200, "reason": "" },
"content-type": "text/html",
"set-cookie": ["a=1; Path=/", "b=2; Path=/"]
}
]
}
Ceci est important pour les sites qui définissent des cookies de session, de suivi et de consentement dans une seule response (la majorité des sites d'e-commerce).
Responses volumineuses : offload_large (par défaut : inline)
Par défaut (depuis la v0.2.0), les corps complets des responses sont renvoyés inline dans structuredContent quelle que soit leur taille. Cela fonctionne immédiatement avec n'importe quel client MCP.
Si votre client prend en charge resources/read de MCP ET que vous souhaitez économiser des tokens sur les pages volumineuses, passez offload_large: true lors de chaque appel d'outil. Les responses ≥ 50 Ko sont alors écrites sur le disque, renvoyées sous forme de resource_link, et votre client ne récupère le corps que lorsqu'il en a réellement besoin. Les charges utiles mises en cache expirent après 1 heure.
{
"method": "GET",
"url": "https://en.wikipedia.org/wiki/Web_scraping",
"offload_large": true
}
| Client | offload_large: true |
|---|---|
| Claude Desktop | pas encore, laissez la valeur par défaut false |
| Claude Code, Cursor, Windsurf | pris en charge |
| VS Code (extension MCP) | pris en charge |
Isolation par locataire (tenant-isolated) : chaque clé API obtient son propre espace de noms (sha256(apiKey)[:16]). Seule la clé ayant stocké une charge utile peut la relire. Les lectures croisées entre locataires renvoient Payload not found sans divulguer l'existence de la ressource.
Prompts intégrés
Cinq modèles de workflow apparaissent sous /prompts dans n'importe quel client MCP. Chacun d'eux prend des arguments nommés et renvoie un message utilisateur modélisé orchestrant un ou plusieurs outils.
| Prompt | Arguments | Ce qu'il fait |
|---|---|---|
scrape_product_page |
url |
Récupération via navigateur, puis extraction du titre du produit, du prix, de l'image, du stock et du SKU au format JSON |
extract_article |
url |
Récupération single avec repli sur proxy, puis suppression de la navigation/publicités et retour d'un JSON d'article propre |
monitor_pricing |
url, target_price facultatif |
Récupération via proxy, extraction du prix actuel, comparaison avec le prix cible |
check_endpoint_health |
url, expected_text facultatif |
Récupération single avec validation stricte, retour de l'accessibilité et du temps de réponse |
bulk_fetch_urls |
urls (séparées par des virgules) |
Récupération single en parallèle, repli automatique sur proxy par URL, retour des métadonnées uniquement |
Les prompts ne coûtent aucun token lorsqu'ils sont inactifs. Seuls les prompts appelés entrent dans le contexte du LLM.
Texte intégral et prompts de repli manuels : MCP Recipes.
Enveloppe d'erreur
Chaque erreur (isError: true) contient une enveloppe structuredContent. Champs minimaux pour chaque erreur :
{
"service": "single | proxy | browser",
"code": "rate_limited",
"error": "Rate limit exceeded"
}
En cas d'erreurs en amont avec un statut HTTP, le champ status est également présent. Pour les erreurs de rate limit et de capacité, l'enveloppe en amont ajoute retryAfter, current.{concurrency, rpm} et limits.{maxConcurrency, maxRpm}. Voir API Errors pour la structure REST sous-jacente.
Valeurs de code stables :
| Code | HTTP | Signification | Réessai possible ? |
|---|---|---|---|
ssrf_blocked |
n/a | IP cible dans une plage privée ou réservée (RFC 5735, 6598, IPv6 réservé) | Non, modifiez l'URL |
upstream_non_json |
varie | L'amont a renvoyé un corps malformé | Peut-être, à analyser |
output_validation_failed |
n/a | L' outputSchema du serveur MCP a rejeté la response en amont (bug du serveur ou structure amont inattendue) |
Peut-être, à signaler |
bad_request |
400 | Structure d'entrée rejetée | Non, corrigez les arguments |
auth_failed |
401 | Clé manquante, invalide ou désactivée | Non, corrigez la clé |
forbidden |
403 | Authentifié mais non autorisé | Non, ou passez à foura_proxy |
not_found |
404 | Cible ou endpoint manquant | Non |
rate_limited |
429 | Limite de RPM atteinte | Oui, attendez retryAfter |
at_capacity |
503 | Limite de concurrence atteinte | Oui, attendez retryAfter |
service_disabled |
503 | Fenêtre de maintenance ou votre forfait n'inclut pas cet outil | Contactez le support |
service_unavailable |
503 | 503 générique | Oui, court délai d'attente |
upstream_error |
500+ | 5xx en amont | Oui, délai d'attente exponentiel |
upstream_client_error |
4xx | Autre 4xx | Généralement non |
upstream_unknown |
autre | Défensif, ne devrait pas se produire en pratique | À analyser |
Les agents LLM peuvent lire directement le code pour la logique de réessai sans analyser de texte. Guide d'authentification : Authentification.
Limites
- Corps inline par défaut. Avec
offload_large: true, les responses ≥ 50 Ko vont sur le disque +resource_link(par locataire, TTL de 1 heure). - Les cibles privées sont refusées (RFC 5735, RFC 6598, blocs réservés IPv6) au niveau de la couche MCP. Seuls les hôtes publics sont transmis.
- Limite de taille du corps de la request à 256 Ko sur les requests
/mcpentrantes (les charges utiles MCP réelles sont < 4 Ko). - Les rate limits sont appliqués par l'API FourA par service. Voir Rate Limits.
Auto-hébergement
Chaque instance s'exécute dans un conteneur de manière sans état (stateless). Un miroir GitHub public sera disponible avec la v1.0. D'ici là, le code source se trouve dans un dépôt privé et l'image du conteneur est disponible sur demande. Contactez support@foura.ai pour un accès anticipé.
Environnement configurable :
| Variable | Par défaut | Objectif |
|---|---|---|
PORT |
3076 |
Port d'écoute HTTP |
FOURA_API_BASE |
https://api.foura.ai/api |
URL de base REST FourA en amont |
FOURA_MCP_PAYLOADS_DIR |
/data/payloads |
Emplacement où les responses ≥ 50 Ko sont mises en cache sur le disque (avec offload_large: true) |
FOURA_MCP_ALLOWED_HOSTS |
mcp.foura.ai,localhost,127.0.0.1,[::1] |
Liste d'autorisation des noms d'hôte pour le header Host (protection contre le DNS-rebinding) |
FOURA_MCP_ALLOWED_ORIGINS |
https://mcp.foura.ai,https://claude.ai,https://app.cursor.sh,https://app.cursor.com |
Liste d'autorisation des origines pour les appelants via navigateur |
FOURA_MCP_RESOURCE_METADATA_URL |
https://foura.ai/docs/mcp/server#auth |
URL renvoyée dans WWW-Authenticate en cas de 401 |
S'exécute en tant que uid 1001 (non-root) dans le conteneur officiel. Le montage de liaison (bind mount) de l'hôte /data/payloads doit être accessible en écriture par cet uid.
Faites évoluer horizontalement derrière n'importe quel équilibreur de charge. Les clients fournissent leur clé à chaque request, il n'y a donc pas de session persistante (sticky session).