O seu site como servidor MCP só de leitura

O seu site como servidor MCP só de leitura

Última verificação: 14 de outubro de 2026
17 min de leitura
Guia
500+ projetos WP
Integração IA

A maior parte da orientação sobre o Model Context Protocol assume que está a construir um servidor à frente de uma loja ou de uma base de dados, algo com encomendas e inventário. Nós fizemos o menos óbvio: transformámos um site de marketing estático num servidor MCP ativo e só de leitura. Qualquer cliente MCP pode agora fazer POST para um único endpoint e perguntar que serviços existem ou como iniciar um pedido, em JSON-RPC tipado, sem analisar uma única página de HTML.

Este é um relato prático dessa construção. É deliberadamente estreito: um punhado de ferramentas só de leitura, sem base de dados, sem escritas. Essa estreiteza é o ponto central, e a maioria das decisões interessantes decorre dela. O que se segue é porque é que um site de conteúdos beneficia sequer de um endpoint MCP, porque é que o endpoint é uma Cloudflare Pages Function em vez de uma rota de framework, porque é que fizemos JSON-RPC à mão em vez de puxar o SDK, e o único bug da barra final que quebra silenciosamente todos os POST se o deixar passar.

#Porquê um servidor MCP num site de marketing estático

Uma loja expõe MCP porque um agente precisa de executar uma ação: verificar stock, montar um carrinho, fazer uma encomenda. Um site de marketing não tem carrinho. Então para que serve a superfície de ferramentas?

A resposta honesta é a descoberta por agentes. O nosso site já corria uma camada de descoberta por agentes: um llms.txt, um conjunto de documentos .well-known e um cartão de servidor MCP em /.well-known/mcp/server-card.json. Esse cartão descrevia um servidor, o seu transporte e as suas capacidades. Chegava a declarar uma capacidade tools. Havia um problema: nada existia por trás dele. O cartão anunciava um servidor que não existia. Um agente que seguisse o cartão e tentasse ligar-se não obtinha nada.

Esse é um estado comum para estes ficheiros. São gerados, são anunciados num cabeçalho Link e depois apontam para um recurso que nunca foi construído. O cartão é uma promessa sem implementação.

Por isso o objetivo não era inventar uma superfície nova. Era tornar real uma superfície existente e já anunciada. As ferramentas decorrem diretamente daquilo para que serve um site de marketing:

  • check_services devolve o catálogo de serviços: id, nome, descrição, categoria e URL canónico.
  • request_quote devolve o URL de contacto localizado e as instruções para submeter um pedido.

A primeira versão saiu com estas duas. Mais tarde chegaram outras três ferramentas só de leitura, cada uma como uma nova entrada no array TOOLS e um novo ramo em callTool, sem mexer no transporte:

  • check_tech_stack devolve a stack tecnológica com que trabalhamos, agrupada por categoria e com um filtro de categoria opcional.
  • get_case_studies devolve os casos de estudo com a respetiva stack, filtrados por um termo de pesquisa opcional.
  • search_blog_posts pesquisa o blogue por título, descrição, categorias, etiquetas ou slug, com filtros opcionais de idioma e categoria e um limite de resultados.

Cinco ferramentas, todas só de leitura. Um agente pode agora enumerar o que fazemos e dar a um utilizador o passo seguinte correto, de forma determinística, em vez de adivinhar a partir de texto corrido.

#Como correr um servidor MCP como Cloudflare Pages Function

O site é construído com Astro em modo de saída estática. Não há adaptador SSR. Todas as páginas são pré-renderizadas para HTML em tempo de build, e os ficheiros no estilo de API que serve (o JSON do catálogo de serviços, o perfil do agente) são ficheiros estáticos em public/, não rotas de servidor.

Esse único facto conduz todo o desenho. Um endpoint dinâmico que lê o corpo de um pedido e devolve uma resposta calculada não pode ser uma rota Astro aqui, porque não há servidor para o correr. Adicionar um significaria mudar o modo de saída para híbrido ou servidor e anexar um adaptador, o que é uma alteração grande e arriscada a uma build que já produz milhares de páginas.

O site já corre, no entanto, Cloudflare Pages Functions escritas à mão: um middleware que trata redirecionamentos e alguns pequenos handlers de API. É essa a costura. Um endpoint MCP dinâmico é apenas mais uma Pages Function, functions/mcp.ts, ao lado das outras. Faz deploy com a build normal, não precisa de adaptador e não muda nada quanto à forma como as páginas são renderizadas.

A lição generaliza-se. Quando quer adicionar um endpoint dinâmico a um site que de resto é estático, não recorra ao modo de servidor da framework. Recorra ao primitivo de edge function que o seu host já lhe oferece. No Cloudflare Pages isso é uma Function. O custo é um ficheiro, não uma reconstrução do seu modelo de renderização.

#Como criar um servidor MCP sem o SDK oficial

O reflexo quando lê “servidor MCP” é instalar @modelcontextprotocol/sdk. Para um servidor stdio com muitas ferramentas, recursos e prompts, esse reflexo está correto. Para poucas ferramentas só de leitura numa edge function, não está.

O protocolo de comunicação do MCP é JSON-RPC 2.0. Um servidor que responde a um cliente MCP precisa de tratar um pequeno conjunto de métodos:

  • initialize, em que o servidor devolve a sua versão do protocolo, as capacidades e a identidade.
  • tools/list, em que devolve as definições das ferramentas com o respetivo JSON Schema.
  • tools/call, em que executa uma ferramenta nomeada e devolve o resultado embrulhado em conteúdo MCP.
  • notificações como notifications/initialized, que não transportam id e não esperam resposta.

Essa é a superfície inteira para um servidor só de leitura. Implementá-la à mão são aproximadamente 120 linhas. O dispatch é um switch simples:

switch (method) {
  case "initialize":
    return ok({ protocolVersion, capabilities: { tools: { listChanged: false } }, serverInfo });
  case "tools/list":
    return ok({ tools: TOOLS });
  case "tools/call":
    return ok({ content: [{ type: "text", text: callTool(name, args, services).text }] });
  default:
    return err(-32601, `Method not found: ${method}`);
}

Pese isso contra o SDK. O SDK foi concebido para stdio e para o protocolo completo. Num runtime de edge herda as suas suposições de bundling e a sua maquinaria de transporte para funcionalidades que não está a usar. Para poucas ferramentas de leitura, uma dependência sobre a qual tem de raciocinar é uma troca pior do que 120 linhas que controla por completo. É a mesma contenção só-de-leitura-primeiro aplicada às dependências: exponha o mínimo, seja dono do mínimo.

A única coisa que vale a pena fazer com cuidado à mão é o contrato de erros. O JSON-RPC tem códigos de erro definidos, e os clientes MCP esperam-nos: -32700 para um erro de parsing, -32601 para um método desconhecido, -32602 para parâmetros inválidos. Acertar nisso é o que faz um servidor feito à mão comportar-se como um a sério perante um cliente estrito.

#Porque um servidor MCP público deve ser só de leitura

A tentadora ferramenta seguinte é uma que capta um lead: recebe um nome, um email e uma mensagem, e envia-nos por email. Não construa isso como uma ferramenta MCP aberta.

Um endpoint público com uma ferramenta de escrita é um depósito de spam. Qualquer pessoa na internet pode chamar tools/call com submit_quote e uma carga falsa, e agora a sua caixa de entrada, o seu CRM ou a sua base de dados é um alvo sem atrito e sem ninguém no circuito. No momento em que uma ferramenta escreve, o endpoint precisa de autenticação, limitação de taxa e tratamento de abusos, o que é uma superfície grande para um site de marketing defender.

Por isso request_quote não escreve nada. Devolve o URL de contacto localizado e orientação estruturada:

if (name === "request_quote") {
  const lang = LOCALES.includes(String(args?.lang)) ? String(args.lang) : "en";
  return { text: JSON.stringify({
    contact_url: CONTACT_URLS[lang],
    method: "web-form",
    note: "Read-only endpoint. Submit the inquiry through the contact form; this tool does not send it for you.",
    reply_time: "within one working day",
  }, null, 2) };
}

O agente obtém tudo o que precisa para fazer o utilizador avançar: a página de contacto certa para o idioma do utilizador, e uma indicação clara de que a submissão acontece através do formulário. A pessoa mantém-se no circuito. O endpoint não tem nada de que se possa abusar.

Isto não é um desenho mais fraco imposto pela cautela. É a mesma postura que recomendamos aos clientes que constroem MCP para os seus próprios sistemas: só de leitura primeiro, adicione escritas apenas por trás de autenticação quando houver uma razão concreta. Um servidor só de leitura é honesto sobre o que é, e é seguro deixá-lo aberto.

Escolha de desenhoFerramenta aberta de leitura-escritaEncaminhamento só de leitura
Autenticação necessáriaSimNão
Superfície de spamAltaNenhuma
Pessoa no circuitoOpcionalSempre
Código a defenderLimitação de taxa, validação, tratamento de abusosNenhum
Adequação a um site de marketing públicoFracaBoa

#Porque o redirecionamento da barra final perde o corpo POST

Esta custou tempo real de depuração, por isso vale a pena dizê-la sem rodeios.

O nosso site canonicaliza os URL para uma barra final. O middleware redireciona com 301 qualquer caminho que não a tenha para a versão com barra. Isso está bem para páginas. É um desastre silencioso para um endpoint JSON-RPC.

Um POST /mcp bate no redirecionamento e devolve 301 para /mcp/. Muitos clientes HTTP, ao seguir o redirecionamento, não reenviam o corpo do POST, ou baixam o método. O cliente MCP vê uma resposta vazia ou falhada e conclui que o servidor está partido. O servidor está bem. O pedido nunca chegou com o seu corpo.

A correção não é lutar contra o middleware. É anunciar o URL que o site serve de facto. O cartão do servidor MCP e todas as referências de descoberta apontam para /mcp/, com a barra final, para que um cliente bem comportado faça POST diretamente para o URL canónico e nunca toque no redirecionamento. Se a sua framework ou host normaliza barras, decida qual a forma canónica e anuncie exatamente essa forma em todo o lado.

Pode verificar o endpoint ativo da mesma forma que nós:

curl -s -X POST https://wppoland.com/mcp/ \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Um POST sem barra para o mesmo host mostrar-lhe-á o 301 em vez disso.

#Como um servidor MCP ajuda no GEO e nos agentes de IA

A generative engine optimization é sobretudo ser legível e verificável para modelos. Dados estruturados, entidades claras, afirmações consistentes entre as suas próprias superfícies e as externas. Um endpoint MCP ativo é uma versão forte dessa legibilidade: não é uma pista sobre o seu conteúdo, é uma interface invocável para ele.

Duas coisas tornam-no digno do pequeno esforço mesmo com a adoção ainda numa fase inicial. Primeiro, fecha a distância entre o que a camada de descoberta anuncia e o que existe. Um cartão que aponta para um servidor a funcionar é um sinal coerente; um cartão que aponta para nada é um sinal partido, e sinais partidos são piores do que sinais ausentes. Segundo, para quem vende esta capacidade, o endpoint é prova. Construímos servidores MCP para clientes, e a demonstração mais credível disso é um público, só de leitura, a correr no nosso próprio domínio, ao lado do servidor MCP para WooCommerce de código aberto que publicamos.

Nenhum grande fornecedor de IA se compromete formalmente hoje a ler cartões de servidor MCP ou llms.txt. É uma ressalva justa e afirmamo-la sem rodeios. O endpoint é barato de correr, torna verdadeira uma promessa anunciada, e é um artefacto a funcionar em vez de uma alegação. Esses três juntos ultrapassam o limiar.

Telemetria MCP de outro site, outubro de 2026: Amir Pournasserian contou o tráfego do servidor MCP do site dele durante três dias e meio (de 14 a 18 de outubro de 2026). Os clientes abriram cerca de 300 ligações (308 initialize, 281 tools/list) e fizeram 29 chamadas a ferramentas, 15 pesquisas e 14 obtenções. Muitos identificaram-se como diretórios e classificações de servidores MCP ou de agentes. Pediram também cerca de uma dúzia de endereços de descoberta que o servidor dele não tem, entre eles /.well-known/mcp/server-card.json, que o autor associa a rascunhos anteriores das Server Cards. É nesse endereço que está o nosso cartão, ligado a partir do nosso /.well-known/ai-catalog.json. A proposta MCP Server Cards, SEP-2127, agora com o estado Final, admite cartões em qualquer endereço não reservado indicado por um AI Catalog e recomenda <streamable-http-url>/server-card. O autor não encontrou nenhum cliente corrente que siga um catálogo por si só. O Claude Code, o Claude.ai, o VS Code e o Cursor recebem o URL do servidor de quem os usa ou de uma galeria própria. Um site pessoal e três dias e meio de dados. A maioria dos clientes pediu a lista de ferramentas e poucos chamaram alguma.

#Que funcionalidades MCP um servidor pequeno pode omitir

Uma lista curta, porque saber o que uma construção salta é tão útil como saber o que inclui.

  • Nenhuma ferramenta por antecipação. get_case_studies não existia na primeira versão, e os agentes liam os casos de estudo a partir do llms.txt e das páginas ligadas até a ferramenta chegar. Cada ferramenta da lista responde hoje a uma pergunta que os agentes fazem de facto.
  • Sem capacidade resources ou prompts. O servidor declara apenas tools, porque é tudo o que implementa. Declarar uma capacidade que não serve é pior do que omiti-la: um cliente que chame resources/list recebe um erro em vez de um limpo “não suportado”.
  • Sem SDK, como já abordado acima.
  • Sem escritas, como já abordado acima.

Cada omissão é uma decisão, não um descuido. O endpoint faz exatamente o que as suas ferramentas só de leitura exigem e nada mais, e é por isso que é pequeno o suficiente para se raciocinar sobre ele numa sentada e seguro o suficiente para se deixar aberto à internet.

#O que a especificação MCP exige de um endpoint Streamable HTTP

O transporte por trás de POST /mcp/ é o Streamable HTTP. A especificação de transportes do MCP (versão 2025-06-18) define-o como o substituto do transporte HTTP+SSE da versão 2024-11-05. A maior parte das suas regras trata de streaming, e um servidor só de leitura cumpre-as sem transmitir nada em streaming.

  • Cada mensagem JSON-RPC do cliente é um novo POST HTTP para um único caminho de endpoint. O cliente tem de enviar um cabeçalho Accept que indique tanto application/json como text/event-stream.
  • Quando o corpo do POST é uma notificação ou uma resposta, o servidor tem de responder 202 Accepted sem corpo. A nossa função faz isso para notifications/initialized.
  • Quando o corpo é um pedido, o servidor escolhe: abrir um stream SSE ou devolver um único objeto JSON com Content-Type: application/json. O cliente tem de tratar ambos os casos, por isso um servidor sem nada para transmitir pode responder sempre com JSON simples.
  • As sessões são opcionais. Um servidor pode atribuir um cabeçalho Mcp-Session-Id na resposta a initialize, mas nada o obriga. Sem identificador de sessão não há armazenamento de sessões para manter, o que serve uma edge function que não guarda estado entre pedidos.
  • Depois da inicialização, o cliente tem de enviar o cabeçalho MCP-Protocol-Version em cada pedido. Se o cabeçalho faltar e o servidor não tiver outra forma de saber a versão, deve assumir 2025-03-26. Um valor inválido ou não suportado tem de receber 400 Bad Request.

A mesma página inclui um aviso de segurança para este transporte. Os servidores têm de validar o cabeçalho Origin em todas as ligações recebidas, os servidores que correm localmente devem escutar apenas em 127.0.0.1 e não em todas as interfaces de rede, e os servidores devem autenticar as ligações. O ataque que a especificação nomeia é o DNS rebinding: um site remoto usa o browser do visitante para chegar a um servidor MCP na máquina desse visitante.

#Como funciona a negociação de versão do protocolo MCP

A negociação de versão acontece dentro de initialize, e a especificação do ciclo de vida resume-a em poucas regras. O cliente tem de enviar uma versão do protocolo que suporte, e deve ser a mais recente que suporta. Se o servidor suportar essa versão, tem de responder com a mesma. Caso contrário, tem de responder com outra versão que suporte, de novo de preferência a mais recente. Um cliente que não suporte a versão da resposta deve desligar-se.

As versões do protocolo são cadeias de data como 2024-11-05, 2025-03-26 e 2025-06-18. A nossa função usa 2025-06-18 como valor por omissão. Num servidor feito à mão a regra reduz-se a uma decisão: a lista de versões a que responde. A página do ciclo de vida mostra a forma do erro perante uma incompatibilidade: código -32602, a mensagem “Unsupported protocol version” e um objeto data com as versões suportadas e a pedida.

Depois da negociação, ambas as partes têm de respeitar a versão acordada e usar apenas as capacidades negociadas. É essa a razão formal para o servidor descrito acima declarar só tools: uma capacidade na resposta a initialize é uma promessa sobre a qual o cliente tem o direito de agir.

#Como marcar uma ferramenta MCP como só de leitura

O esquema do MCP dá a cada ferramenta um objeto opcional annotations com quatro indicações de comportamento:

IndicaçãoSignificadoPor omissão
readOnlyHinta ferramenta não modifica o seu ambientefalse
destructiveHinta ferramenta pode fazer alterações destrutivas; só conta quando readOnlyHint é falsetrue
idempotentHintrepetir a chamada com os mesmos argumentos não tem efeito adicional; só conta quando readOnlyHint é falsefalse
openWorldHinta ferramenta pode interagir com um mundo aberto de entidades externastrue

Os valores por omissão são pessimistas. Uma ferramenta sem anotações fica descrita como uma que pode escrever, pode destruir dados e pode sair do seu próprio domínio. As ferramentas desta construção não têm anotações, por isso as indicações sozinhas descrevê-las-iam dessa forma. Acrescentar readOnlyHint: true à definição de cada ferramenta é uma alteração de uma linha.

O esquema diz também que estas propriedades são indicações e não uma descrição fiel do comportamento, e a especificação de ferramentas determina que os clientes têm de tratar as anotações como não fiáveis, a menos que venham de servidores de confiança. Uma indicação nunca substitui o controlo. A propriedade só de leitura deste endpoint vive no código, onde nenhuma ferramenta tem um caminho de escrita. A anotação apenas descreve essa propriedade a um cliente que decida confiar nela.

A especificação de ferramentas impõe três deveres a qualquer servidor: validar todas as entradas das ferramentas, aplicar controlos de acesso adequados e limitar a frequência das chamadas. A nossa função cumpre o primeiro, rejeitando argumentos mal formados com -32602. A especificação separa ainda dois tipos de falha: os erros de protocolo, como uma ferramenta desconhecida, voltam como erros JSON-RPC, enquanto uma ferramenta que correu e falhou devolve um resultado normal com isError: true, para que o modelo veja o texto da falha e possa reagir.

#Mais guias sobre como criar servidores MCP

Para um guia operacional detalhado sobre configuração, validação de esquemas JSON-RPC e ligação do Claude Desktop ao nosso endpoint de produção, consulte o nosso guia de implementação do servidor MCP ao vivo da WPPoland. Se quiser a versão mais completa destas decisões, o cluster à volta deste artigo cobre o terreno adjacente: construir um servidor MCP para WooCommerce para o caso com estado e voltado para a loja, MCP vs REST: quando cada um vence para saber se precisa sequer de MCP, e padrões de autenticação MCP para o momento em que adiciona uma ferramenta de escrita e precisa de autenticação. A versão comercial deste trabalho vive na página de serviço desenvolvimento de servidores MCP.

A versão curta cabe numa frase: um site de marketing pode ser um servidor MCP, o endpoint é uma edge function, mantenha todas as ferramentas só de leitura, e anuncie o URL que o seu host serve de facto.

Próximo passo

Transforme o artigo numa implementação real

Este bloco reforça a ligação interna e conduz o leitor para o passo seguinte mais útil dentro da arquitetura do site.

Quer implementar isto no seu site?

Se está a planear headless WordPress, desacoplamento de frontend ou migração para Astro, posso desenhar e implementar a arquitetura completa.

Cluster relacionado

Explorar outros serviços WordPress e base de conhecimento

Reforce o seu negócio com suporte técnico profissional em áreas-chave do ecossistema WordPress.

Perguntas frequentes

Respostas práticas para aplicar o tema na execução real.

O que significa site-como-MCP para um site de marketing?#
Significa que o site responde diretamente a chamadas Model Context Protocol. Em vez de um agente extrair HTML, ele chama ferramentas tipadas como check_services e request_quote sobre JSON-RPC. O site torna-se uma superfície legível por máquinas que os agentes podem chamar.
Porquê uma Cloudflare Pages Function em vez de uma rota Astro?#
O site compila como saída estática sem adaptador SSR, por isso não há rota de servidor à qual anexar um endpoint. Uma Pages Function é um pequeno handler autónomo que faz deploy com a mesma build e corre no edge, sem qualquer alteração ao modo de saída.
É preciso o SDK oficial de MCP?#
Não para um punhado de ferramentas de leitura. O protocolo de comunicação é JSON-RPC 2.0 com três métodos que importam aqui: initialize, tools/list e tools/call. Implementá-los à mão são cerca de 120 linhas e evita uma dependência e as suas particularidades de bundling.
Um endpoint MCP público é um risco de segurança?#
Só se uma ferramenta escrever. Manter todas as ferramentas só de leitura elimina o risco. A ferramenta request_quote devolve o URL de contacto e as instruções de envio em vez de enviar seja o que for, por isso não há depósito de leads suscetível a spam exposto à internet.
Algum fornecedor de IA lê mesmo estes endpoints?#
Nenhum grande fornecedor se compromete formalmente a consumir cartões de servidor MCP ou llms.txt para já. Aparecem nos logs do servidor com frequência suficiente para justificar o pequeno custo, e o endpoint funciona também como prova verificável da capacidade que entregamos aos clientes.

Precisa de FAQ adaptado ao setor e mercado? Criamos uma versão alinhada com os seus objetivos de negócio.

Fale connosco

Artigos Relacionados