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+Q sur 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ù total est un float en secondes, mesurant le temps total incluant les tentatives)
  • foura_browser : structure distincte { status, headers: object, body, cookies, userAgent } (remarque : body peut ê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 /mcp entrantes (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).

Mis à jour : 1 juillet 2026