Servidor MCP
Servidor MCP
Use FourA desde cualquier cliente de Model Context Protocol (Claude Desktop, Claude Code, Cursor, Windsurf, VS Code) como tres herramientas nativas y cinco prompts de flujo de trabajo. Sin código de integración ni cliente HTTP personalizado.
Inicio rápido: stdio local (recomendado para Claude Desktop)
Obtenga una clave en foura.ai/dashboard#api-keys (un clic, se muestra una sola vez al crearse, formato pk_live_...). Copie esto en la configuración de su cliente MCP:
{
"mcpServers": {
"foura": {
"command": "npx",
"args": ["-y", "@fouradata/mcp"],
"env": { "FOURA_API_KEY": "pk_live_..." }
}
}
}
Detalle importante de Claude Desktop: cierre por completo Claude Desktop (
Cmd+Qen macOS) antes de editar el archivo de configuración. Si la aplicación sigue ejecutándose, sobrescribirá sus cambios con su configuración en memoria al salir.
El comando npx descarga @fouradata/mcp en el primer inicio (~10 s) y lo ejecuta como un subproceso de su cliente MCP. No se requiere instalación global.
| Cliente | Ubicación de la configuración |
|---|---|
| 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 (defina primero FOURA_API_KEY en el entorno) |
| Cursor | ~/.cursor/mcp.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| VS Code (extensión MCP) | .vscode/mcp.json |
Reinicie el cliente. Las herramientas (foura_single, foura_proxy, foura_browser) y los cinco prompts aparecerán en su lista de herramientas.
Inicio rápido: alojado (Streamable HTTP)
Para clientes que admiten el transporte Streamable HTTP (Cursor, Windsurf, VS Code, Claude Code con --transport http), apúntelos al endpoint alojado en lugar de ejecutar un subproceso local:
{
"mcpServers": {
"foura": {
"url": "https://mcp.foura.ai/mcp",
"headers": {
"Authorization": "Bearer pk_live_..."
}
}
}
}
Las versiones actuales de Claude Desktop rechazan el formato de url simple. Use la configuración de stdio anterior para Claude Desktop, o realice un puente a través de mcp-remote:
{
"mcpServers": {
"foura": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.foura.ai/mcp", "--header", "Authorization: Bearer pk_live_..."]
}
}
}
Referencia del endpoint alojado
| Propiedad | Valor |
|---|---|
| URL | https://mcp.foura.ai/mcp |
| Transporte | Streamable HTTP (POST /mcp, respuestas SSE) |
| Autenticación | Authorization: Bearer pk_live_... por request |
| MCP-Protocol-Version | Según @modelcontextprotocol/sdk (actualmente 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07) |
| Desafío 401 | WWW-Authenticate: Bearer realm="foura-mcp", resource_metadata="https://foura.ai/docs/mcp/server#auth" |
El servidor alojado es stateless. Cada request incluye su propia clave, que el servidor reenvía a la API de FourA como X-API-Key. Una sola clave permite acceder a las tres herramientas.
Para protegerse contra DNS-rebinding (CVE-2025-66414), el servidor valida el header Host (debe ser mcp.foura.ai o localhost) y el header Origin cuando está presente (en lista permitida: mcp.foura.ai, claude.ai, app.cursor.sh, app.cursor.com). Los llamadores de servidor a servidor (curl, clientes MCP en modo puente stdio) no envían Origin y se procesan directamente.
Herramientas
Las tres herramientas están anotadas con readOnlyHint: true y openWorldHint: true según la especificación MCP 2025-06-18. Los clientes que autoaprueban herramientas de solo lectura de confianza las llaman sin mostrar un modal de confirmación por cada request.
foura_single
Un request HTTP, se devuelve la response. De 200 ms a 2 s. Refleja POST /api/single/ de forma idéntica.
Úselo para páginas estáticas, APIs JSON y HTML renderizado en el servidor.
foura_proxy
Request HTTP enrutado a través de un grupo de proxies rotativos con reintento automático. De 1 a 5 s. Refleja POST /api/proxy/.
Úselo cuando foura_single devuelva un error 403, CAPTCHA o contenido bloqueado geográficamente. La response incluye el ID del proxy que tuvo éxito (proxy) y el tiempo total transcurrido en segundos (total, float).
foura_browser
Sesión de navegador completa. Se ejecuta JavaScript, se renderiza el DOM y se devuelven las cookies. De 2 a 10 s. Refleja POST /api/browser/.
Úselo para aplicaciones de una sola página (SPA), contenido de carga diferida (lazy-loaded) o páginas protegidas por desafíos anti-bot que requieren un navegador real para resolverse.
Para conocer las estructuras de entrada, los valores predeterminados y las reglas de validación de cada herramienta, consulte la referencia de endpoints REST. Los esquemas de las herramientas coinciden campo por campo con la API REST, además de la opción de activación offload_large exclusiva de MCP (ver más abajo).
Respuestas tipadas
Cada response de la herramienta incluye tanto content (resumen de texto legible por humanos) como structuredContent (JSON tipado validado contra el outputSchema de la herramienta). Cada herramienta tiene su propia estructura única:
foura_single:{ status, headers, data, total_time, ... }(headers es un array, una entrada por cada salto de redirección)foura_proxy: igual que single más{ proxy, total }(dondetotalson segundos en float, tiempo externo que incluye los reintentos)foura_browser: estructura distinta{ status, headers: object, body, cookies, userAgent }(nota:bodypuede ser un string o un objeto según el content-type)
Los clientes que admiten structuredContent (Claude Desktop, Cursor, Windsurf a partir de 2026) pasan el objeto tipado directamente al LLM, omitiendo la retokenización de JSON como string. Espere un ahorro de tokens del 30 al 40 % en las respuestas típicas.
Headers de respuesta de múltiples valores
Los headers que aparecen varias veces (Set-Cookie, Link, WWW-Authenticate) se devuelven como arrays:
{
"headers": [
{
"result": { "version": "HTTP/2", "code": 200, "reason": "" },
"content-type": "text/html",
"set-cookie": ["a=1; Path=/", "b=2; Path=/"]
}
]
}
Esto es importante para los sitios que definen cookies de sesión, de seguimiento y de consentimiento en una sola response (la mayoría de los sitios de comercio electrónico).
Respuestas grandes: offload_large (predeterminado: inline)
De forma predeterminada (desde v0.2.0), los cuerpos completos de las respuestas se devuelven inline en structuredContent independientemente de su tamaño. Esto funciona de inmediato en todos los clientes MCP.
Si su cliente admite resources/read de MCP Y desea ahorrar tokens en páginas grandes, pase offload_large: true en cada llamada a la herramienta. Las respuestas ≥ 50 KB se escribirán en el disco, se devolverán como un resource_link y su cliente recuperará el cuerpo solo cuando realmente lo necesite. Los payloads almacenados en caché expiran después de 1 hora.
{
"method": "GET",
"url": "https://en.wikipedia.org/wiki/Web_scraping",
"offload_large": true
}
| Cliente | offload_large: true |
|---|---|
| Claude Desktop | aún no, deje el valor predeterminado false |
| Claude Code, Cursor, Windsurf | compatible |
| VS Code MCP extension | compatible |
Aislamiento por tenant: cada clave de API obtiene su propio espacio de nombres (sha256(apiKey)[:16]). Solo la clave que almacenó un payload puede volver a leerlo. Las lecturas entre distintos tenants devuelven Payload not found sin revelar la existencia del recurso.
Prompts integrados
Cinco plantillas de flujo de trabajo se muestran bajo /prompts en cualquier cliente MCP. Cada una acepta argumentos con nombre y devuelve un mensaje de usuario con plantilla que orquesta una o más herramientas.
| Prompt | Argumentos | Qué hace |
|---|---|---|
scrape_product_page |
url |
Extracción con navegador, luego extrae el título del producto, precio, imagen, stock y SKU como JSON |
extract_article |
url |
Extracción simple con fallback a proxy, luego elimina navegación/anuncios y devuelve el JSON limpio del artículo |
monitor_pricing |
url, target_price opcional |
Extracción con proxy, extrae el precio actual y lo compara con el objetivo |
check_endpoint_health |
url, expected_text opcional |
Extracción simple con validación estricta, devuelve accesibilidad y tiempos |
bulk_fetch_urls |
urls (separados por comas) |
Extracción simple en paralelo, fallback automático a proxy por URL, devuelve solo metadatos |
Los prompts tienen un costo de cero tokens cuando están inactivos. Solo los prompts invocados entran en el contexto del LLM.
Texto completo y prompts de fallback manuales: Recetas de MCP.
Envoltura de errores
Cada error (isError: true) lleva una envoltura structuredContent. Campos mínimos en cada error:
{
"service": "single | proxy | browser",
"code": "rate_limited",
"error": "Rate limit exceeded"
}
En caso de errores ascendentes (upstream) con estado HTTP, status también está presente. En errores de rate limit y capacidad, la envoltura ascendente agrega retryAfter, current.{concurrency, rpm} y limits.{maxConcurrency, maxRpm}. Consulte Errores de API para ver la estructura REST subyacente.
Valores estables de code:
| Código | HTTP | Significado | ¿Seguro para reintentar? |
|---|---|---|---|
ssrf_blocked |
n/a | IP de destino en un rango privado o reservado (RFC 5735, 6598, IPv6 reservado) | No, cambie la URL |
upstream_non_json |
varía | El servidor ascendente devolvió un cuerpo malformado | Quizás, investigue |
output_validation_failed |
n/a | El outputSchema del servidor MCP rechazó la respuesta del servidor ascendente (error del servidor o estructura inesperada del servidor ascendente) |
Quizás, repórtelo |
bad_request |
400 | Estructura de entrada rechazada | No, corrija los argumentos |
auth_failed |
401 | Clave faltante, inválida o desactivada | No, corrija la clave |
forbidden |
403 | Autenticado pero no permitido | No, o cambie a foura_proxy |
not_found |
404 | Destino o endpoint faltante | No |
rate_limited |
429 | Límite de RPM alcanzado | Sí, espere retryAfter |
at_capacity |
503 | Límite de concurrencia alcanzado | Sí, espere retryAfter |
service_disabled |
503 | Ventana de mantenimiento o su plan no incluye esta herramienta | Contacte al soporte |
service_unavailable |
503 | 503 genérico | Sí, breve tiempo de espera (backoff) |
upstream_error |
500+ | Error 5xx del servidor ascendente | Sí, backoff exponencial |
upstream_client_error |
4xx | Otro error 4xx | Normalmente no |
upstream_unknown |
otro | Defensivo, no debería ocurrir en la práctica | Investigue |
Los agentes de LLM pueden leer code directamente para la lógica de reintentos sin analizar prosa. Guía paso a paso de autenticación: Autenticación.
Límites
- Cuerpo inline de forma predeterminada. Con
offload_large: true, las respuestas ≥ 50 KB van al disco +resource_link(por tenant, TTL de 1 hora). - Los destinos privados se rechazan (RFC 5735, RFC 6598, bloques reservados de IPv6) en la capa MCP. Solo se reenvían hosts públicos.
- Límite de cuerpo de request de 256 KB en las solicitudes
/mcpentrantes (los payloads reales de MCP son < 4 KB). - Los rate limits son aplicados por la API de FourA por servicio. Consulte Rate Limits.
Autohospedaje
Cada instancia se ejecuta en un contenedor de forma stateless. Un mirror público de GitHub llegará con la versión v1.0. Hasta entonces, el código fuente se encuentra en un repositorio privado y la imagen del contenedor está disponible bajo solicitud. Contacte a support@foura.ai para obtener acceso anticipado.
Entorno configurable:
| Variable | Predeterminado | Propósito |
|---|---|---|
PORT |
3076 |
Puerto de escucha HTTP |
FOURA_API_BASE |
https://api.foura.ai/api |
URL base REST ascendente de FourA |
FOURA_MCP_PAYLOADS_DIR |
/data/payloads |
Dónde se almacenan en caché en el disco las respuestas ≥ 50 KB (con offload_large: true) |
FOURA_MCP_ALLOWED_HOSTS |
mcp.foura.ai,localhost,127.0.0.1,[::1] |
Lista permitida de nombres de host para el header Host (defensa contra DNS-rebinding) |
FOURA_MCP_ALLOWED_ORIGINS |
https://mcp.foura.ai,https://claude.ai,https://app.cursor.sh,https://app.cursor.com |
Lista permitida de Origin para llamadores de navegador |
FOURA_MCP_RESOURCE_METADATA_URL |
https://foura.ai/docs/mcp/server#auth |
URL devuelta en WWW-Authenticate en caso de error 401 |
Se ejecuta como uid 1001 (no root) en el contenedor oficial. El montaje de tipo bind del host /data/payloads debe tener permisos de escritura para ese uid.
Escala horizontalmente detrás de cualquier balanceador de carga. Los clientes proporcionan su clave en cada request, por lo que no hay sesiones persistentes (sticky sessions).