Servidor MCP
MCP Server
Use o FourA a partir de qualquer cliente Model Context Protocol (Claude Desktop, Claude Code, Cursor, Windsurf, VS Code) como quatro ferramentas nativas e seis prompts de fluxo de trabalho. Sem código de integração, sem cliente HTTP personalizado.
Código aberto no GitHub; no npm como @fouradata/mcp. Versão atual: 0.5.0.
Início Rápido: stdio local (recomendado para o Claude Desktop)
Obtenha uma chave em foura.ai/dashboard#api-keys (um clique, exibida uma vez na criação, formato pk_live_...). Insira isso na configuração do seu cliente MCP:
{
"mcpServers": {
"foura": {
"command": "npx",
"args": ["-y", "@fouradata/mcp"],
"env": { "FOURA_API_KEY": "pk_live_..." }
}
}
}
Aviso sobre o Claude Desktop: feche totalmente o Claude Desktop (
Cmd+Qno macOS) antes de editar o arquivo de configuração. Se o aplicativo ainda estiver em execução, ele substituirá suas edições com a configuração em memória ao ser fechado.
O comando npx faz o download do @fouradata/mcp na primeira execução e o executa como um subprocesso do seu cliente MCP. Nenhuma instalação global é necessária.
| Cliente | Onde a configuração fica |
|---|---|
| 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 FOURA_API_KEY no ambiente primeiro) |
| Cursor | ~/.cursor/mcp.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| VS Code (extensão MCP) | .vscode/mcp.json |
Reinicie o cliente. As ferramentas (foura_auto, foura_single, foura_proxy, foura_browser) e seis prompts aparecem na sua lista de ferramentas.
Início rápido: hospedado (Streamable HTTP)
Para clientes que suportam o transporte Streamable HTTP (Cursor, Windsurf, VS Code, Claude Code com --transport http), aponte-os para o endpoint hospedado em vez de executar um subprocesso local:
{
"mcpServers": {
"foura": {
"url": "https://mcp.foura.ai/mcp",
"headers": {
"Authorization": "Bearer pk_live_..."
}
}
}
}
Para o Claude Desktop, use a configuração stdio acima ou faça a ponte do endpoint hospedado através do mcp-remote:
{
"mcpServers": {
"foura": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.foura.ai/mcp", "--header", "Authorization: Bearer pk_live_..."]
}
}
}
Referência do endpoint hospedado
| Propriedade | Valor |
|---|---|
| URL | https://mcp.foura.ai/mcp |
| Transporte | Streamable HTTP (POST /mcp, respostas SSE) |
| Autenticação | Authorization: Bearer pk_live_... por request |
| MCP-Protocol-Version | Por @modelcontextprotocol/sdk (atualmente 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07) |
| Desafio 401 | WWW-Authenticate: Bearer realm="foura-mcp", resource_metadata="https://foura.ai/docs/mcp/server#auth" |
O servidor hospedado é stateless. Cada request traz sua própria chave, que o servidor encaminha para a API do FourA como X-API-Key. Uma chave abre todas as quatro ferramentas.
Para proteção contra DNS-rebinding (CVE-2025-66414), o servidor valida o header Host (deve ser mcp.foura.ai ou localhost) e o header Origin quando presente (na allowlist: mcp.foura.ai, claude.ai, app.cursor.sh, app.cursor.com). Chamadores server-to-server (curl, clientes MCP em modo bridge stdio) não enviam Origin e passam direto.
Ferramentas
Todas as quatro ferramentas são anotadas como readOnlyHint: true e openWorldHint: true de acordo com a especificação MCP 2025-06-18. Clientes que aprovam automaticamente ferramentas confiáveis de leitura (read-only) as chamam sem um modal de confirmação por request.
foura_auto é o padrão inteligente: forneça uma URL e ele retorna o conteúdo, escolhendo o método de busca para você. As outras três são as primitivas de baixo nível que ele orquestra; use-as quando desejar controle explícito.
foura_auto
Forneça uma URL quando quiser que o FourA escolha o método de request. Ele faz tentativas limitadas nos caminhos disponíveis de HTTP, proxy e browser. Passe validate em alvos protegidos para que a response deva conter o conteúdo que identifica a página real. Se nenhuma tentativa satisfizer a validação, a ferramenta retorna um erro em vez de apresentar uma página de desafio como sucesso.
A response inclui detalhes de conclusão em meta e, por padrão, uma session reutilizável com proxy, cookies e userAgent. Para um follow-up simples, chame foura_single com session.proxy como proxy, serialize os cookies como um header Cookie e envie session.userAgent como o header User-Agent. Para renderização de JavaScript, passe os valores da sessão para os campos correspondentes foura_browser.
foura_single
Um request HTTP, devolve a response. Espelha POST /api/single/ um-para-um.
Use para páginas estáticas, APIs JSON e HTML renderizado no lado do servidor.
Escolhendo qual browser você apresenta
Um request apresenta a versão mais recente do Google Chrome por padrão. Quando um alvo aceita um browser e recusa outro, defina browser (Chrome, Edge, Safari, Firefox ou Tor), os (Windows, macOS, Android ou iOS) ou version, ou passe um id exato profile:
{
"method": "GET",
"url": "https://example.com",
"browser": "Firefox",
"os": "Windows"
}
A versão mais recente vence quando vários perfis correspondem. Uma combinação que não existe retorna um erro listando o que está disponível, para que uma request nunca seja enviada como um navegador que você não escolheu. A seleção precisa de unblocker, que está ativado por padrão. O catálogo está publicado em GET /api/profiles e não precisa de chave de API.
Os mesmos quatro campos ficam dentro do objeto request de foura_proxy.
foura_proxy
Roteie uma request HTTP através de proxies rotativos com repetição automática. Use-o quando foura_single estiver bloqueado ou o alvo exigir um país de saída específico.
Defina exitCountries para uma allowlist estrita de códigos de país de duas letras visíveis para o alvo, fornecidos pelo usuário ou por requisitos do alvo:
{
"maxTries": 5,
"exitCountries": ["CZ", "GB"],
"request": {
"method": "GET",
"url": "https://example.com/pricing",
"browser": "Chrome",
"os": "Windows"
}
}
Os valores são removidos de espaços, convertidos para maiúsculas e desduplicados. Proxies com saídas desconhecidas são excluídos, e a request nunca faz fallback para um país não solicitado. A seleção usa os metadados de país mais recentes visíveis pelo alvo, normalmente atualizados em dez minutos; não é uma busca de geolocalização ao vivo durante a request. Não deduza o país de serviço a partir do endereço de host do proxy.
Um sucesso no escopo retorna exitCountry e o ID proxy reutilizável. Verifique se exitCountry pertence à allowlist solicitada. Se o pool atual não tiver correspondência, a ferramenta retorna code: "no_eligible_proxy" com o escopo normalizado em details.exitCountries. Preserve esse escopo e tente novamente mais tarde. Altere ou amplie-o apenas quando o usuário alterar explicitamente o requisito.
Se a página selecionada precisar de JavaScript posteriormente, passe o ID proxy retornado para foura_browser.proxy para que o navegador reutilize a mesma saída.
foura_browser
Sessão completa do navegador. O JavaScript é executado, o DOM é renderizado, os cookies retornam. Espelha POST /api/browser/.
Use para aplicativos de página única, conteúdo carregado lentamente, ou páginas por trás de desafios anti-bot que precisam de um navegador real para serem resolvidos.
Para formas de entrada, padrões e regras de validação em cada ferramenta, consulte a referência do endpoint REST. Os esquemas da ferramenta correspondem à API REST campo por campo, além do opt-in offload_large exclusivo do MCP (veja abaixo).
Quando um alvo executa uma verificação de bot
foura_single e foura_proxy retornam defense quando o alvo executou uma verificação de bot a caminho do corpo. defense.solved: true significa que a verificação foi atendida e data é a página real; false significa que o corpo pode ser uma página de desafio. Tente novamente com um navegador, sistema operacional ou versão diferente, ou mude para foura_proxy ou foura_browser, em vez de tratar a página de desafio como conteúdo.
Respostas tipadas
Cada response de ferramenta inclui tanto content (resumo de texto legível por humanos) quanto structuredContent (JSON tipado validado contra a outputSchema da ferramenta). Cada ferramenta tem sua própria forma única:
foura_auto:{ status, headers, data }de formato único maismeta({ rung, solved, attempts, credits }, sempre presente, onderungé um decache,probe,proxy,browser,fail) e, por padrão,session({ proxy, cookies, userAgent }) para reprodução através de ferramentas de nível inferior. Semtotal_time.foura_single:{ status, headers, data, total_time, ... }(os headers são um array, uma entrada por salto de redirecionamento)foura_proxy: o mesmo que individual mais{ proxy, total }; um sucesso no escopo também incluiexitCountryfoura_browser: forma distinta{ status, headers: object, body, cookies, userAgent }(nota:bodypode ser uma string ou objeto dependendo do content-type)
Clientes que suportam structuredContent podem passar o objeto tipado diretamente para o LLM em vez de exigir que ele analise JSON a partir de texto corrido.
Headers de response com vários valores
Os headers que aparecem várias vezes (Set-Cookie, Link, WWW-Authenticate) voltam como arrays:
{
"headers": [
{
"result": { "version": "HTTP/2", "code": 200, "reason": "" },
"content-type": "text/html",
"set-cookie": ["a=1; Path=/", "b=2; Path=/"]
}
]
}
Isso é importante para sites que definem cookies de sessão + rastreamento + consentimento em uma única resposta (a maioria do comércio eletrônico).
Respostas grandes: offload_large (padrão: inline)
Por padrão (desde a v0.2.0), os corpos completos da resposta são retornados inline em structuredContent independentemente do tamanho. Isso funciona em qualquer cliente MCP sem configuração adicional.
Se o seu cliente suporta MCP resources/read E você deseja economizar tokens em páginas grandes, passe offload_large: true por chamada de ferramenta. Respostas >= 50 KB são então gravadas no disco, retornadas como um resource_link, e seu cliente busca o corpo apenas quando realmente precisa. Payloads em cache expiram após 1 hora.
{
"method": "GET",
"url": "https://en.wikipedia.org/wiki/Web_scraping",
"offload_large": true
}
| Cliente | offload_large: true |
|---|---|
| Claude Desktop | ainda não, deixe o padrão false |
| Claude Code, Cursor, Windsurf | suportado |
| Extensão MCP para VS Code | suportado |
Isolado por tenant: cada chave de API obtém seu próprio namespace (sha256(apiKey)[:16]). Apenas a chave que armazenou um payload pode lê-lo de volta. Leituras entre tenants retornam Payload not found sem vazar informações sobre a existência.
Prompts Integrados
Seis modelos de fluxo de trabalho aparecem sob /prompts em qualquer cliente MCP. Cada um recebe argumentos nomeados e retorna uma mensagem de usuário baseada em modelo orquestrando uma ou mais ferramentas.
| Prompt | Argumentos | O que faz |
|---|---|---|
smart_fetch |
url, must_contain opcional, extract |
Busca automática (escolhe o método, lida com proteção contra bots), depois retorna ou extrai o conteúdo |
scrape_product_page |
url |
Busca com navegador, depois extrai o título do produto, preço, imagem, estoque, SKU como JSON |
extract_article |
url |
Único com fallback para proxy, depois remove navegação/anúncios e retorna o artigo limpo em JSON |
monitor_pricing |
url, target_price opcional |
Busca via proxy, extrai o preço atual, compara com o alvo |
check_endpoint_health |
url, expected_text opcional |
Único com validação estrita, retorna acessibilidade e tempo |
bulk_fetch_urls |
urls (separados por vírgula) |
Único paralelo, fallback automático para proxy por URL, retorna apenas metadados |
Prompts custam zero tokens quando inativos. Apenas prompts invocados entram no contexto do LLM.
Texto completo mais prompts de fallback manual: MCP Recipes.
Envelope de erro
Cada erro (isError: true) carrega um envelope structuredContent. Campos mínimos em cada erro:
{
"service": "auto | single | proxy | browser",
"code": "rate_limited",
"error": "Rate limit exceeded"
}
Em erros upstream com status HTTP, status também está presente. Em erros de rate limit e capacidade, o envelope upstream adiciona retryAfter, current.{concurrency, rpm} e limits.{maxConcurrency, maxRpm}. Consulte Erros de API para o formato REST subjacente.
Valores code estáveis:
| Código | HTTP | Significado | Seguro para retry? |
|---|---|---|---|
ssrf_blocked |
n/d | IP de destino em intervalo privado ou reservado (RFC 5735, 6598, IPv6 reservado) | Não, altere a URL |
upstream_non_json |
varia | Upstream retornou body malformado | Talvez, investigue |
output_validation_failed |
n/d | O outputSchema do servidor MCP rejeitou o response upstream (bug do servidor ou formato upstream inesperado) |
Talvez, reporte |
bad_request |
400 | Formato de entrada rejeitado | Não, corrija os argumentos |
auth_failed |
401 | Chave ausente, inválida ou desativada | Não, corrija a chave |
forbidden |
403 | Autenticado, mas não permitido | Não, ou mude para foura_proxy |
not_found |
404 | Destino ou endpoint ausente | Não |
rate_limited |
429 | Limite de RPM atingido | Sim, aguarde retryAfter |
at_capacity |
503 | Limite de concorrência atingido | Sim, aguarde retryAfter |
service_disabled |
503 | Janela de manutenção ou seu plano não inclui esta ferramenta | Contate o suporte |
service_unavailable |
503 | 503 genérico | Sim, backoff curto |
upstream_error |
500+ | 5xx upstream | Sim, backoff exponencial |
upstream_client_error |
4xx | Outros 4xx | Geralmente não |
upstream_unknown |
outros | Defensivo, não deve ocorrer na prática | Investigue |
no_eligible_proxy |
n/d | Nenhum proxy corresponde ao escopo exitCountries estrito |
Tente mais tarde; altere o escopo apenas explicitamente |
Agentes LLM podem ler code diretamente para a lógica de retry sem fazer o parse do texto. Guia de autenticação: Autenticação.
Limites
- Body inline por padrão. Com
offload_large: true, responses >= 50 KB vão para disco +resource_link(por tenant, TTL de 1 hora). - Destinos privados são recusados (RFC 5735, RFC 6598, blocos IPv6 reservados) na camada MCP. Apenas hosts públicos são encaminhados.
- Limite de request body de 256 KB em requests
/mcpde entrada (payloads MCP reais são < 4 KB). - Os rate limits são aplicados pela FourA API por serviço. Consulte Rate Limits.
Auto-hospedagem
O código-fonte completo do servidor é público no GitHub sob a @fouradata/mcp. Clone o repositório, npm install, npm run build, e execute node dist/http.js para iniciar sua própria instância. Executa de forma stateless em um único contêiner atrás de qualquer load balancer.
Ambiente configurável:
| Variável | Padrão | Propósito |
|---|---|---|
PORT |
3076 |
Porta de escuta HTTP |
FOURA_API_BASE |
https://api.foura.ai/api |
URL base REST upstream do FourA |
FOURA_MCP_PAYLOADS_DIR |
/data/payloads |
Onde as respostas >= 50 KB são armazenadas em cache no disco (com offload_large: true) |
FOURA_MCP_ALLOWED_HOSTS |
mcp.foura.ai,localhost,127.0.0.1,[::1] |
Lista de permissões de hostname para o cabeçalho Host (defesa contra DNS-rebinding) |
FOURA_MCP_ALLOWED_ORIGINS |
https://mcp.foura.ai,https://claude.ai,https://app.cursor.sh,https://app.cursor.com |
Lista de permissões de Origin para chamadores do navegador |
FOURA_MCP_RESOURCE_METADATA_URL |
https://foura.ai/docs/mcp/server#auth |
URL retornada em WWW-Authenticate no erro 401 |
O contêiner oficial é executado como uid 1001 (não root). O bind mount do host /data/payloads deve ter permissão de gravação para esse uid.
Escale horizontalmente atrás de qualquer load balancer. Os clientes fornecem sua chave em cada request, então não há sessão fixa.