astro-webmcp: Integração WebMCP para Sites Astro
O que é astro-webmcp
astro-webmcp é uma integração Astro que expõe automaticamente o conteúdo do seu site via WebMCP em uma linha de configuração. Agentes de IA com suporte ao protocolo descobrem, buscam e navegam no seu conteúdo diretamente no browser — sem esforço adicional.
- npm: astro-webmcp
- Requisitos: Astro 6+, Chrome 149+
- Licença: MIT
- Autor: ft.ia.br
Nota: Este site (prompt.api.br) usa
astro-webmcpem produção. Se você está acessando com um agente compatível no Chrome, as tools de busca e navegação já estão ativas agora.
Instalação
npm install astro-webmcp
Configuração mínima
// astro.config.mjs
import { defineConfig } from 'astro/config';
import webmcp from 'astro-webmcp';
export default defineConfig({
integrations: [webmcp()],
});
Pronto. Após o build, todas as páginas do site terão tools WebMCP registradas automaticamente. Sério — é só isso.
Configuração com opções
// astro.config.mjs
import { defineConfig } from 'astro/config';
import webmcp from 'astro-webmcp';
export default defineConfig({
integrations: [
webmcp({
collections: ['blog', 'docs'], // Apenas essas collections
security: {
exposedTo: [], // Same-origin only (default)
maxOutputLength: 1500, // Chrome character budget
sanitizeOutputs: true, // Strip injection patterns
},
}),
],
});
Para configuração completa, veja astro-webmcp Config.
Tools registradas automaticamente
A integração registra 4 tools sem código adicional:
| Tool | Ação | readOnlyHint | untrustedContentHint |
|---|---|---|---|
search_content | Busca artigos/páginas por keyword | ✅ | ✅ |
list_sections | Lista seções (collections) com contagem | ✅ | — |
go_to | Navega para página por slug | — | — |
get_page_info | Retorna metadata da página atual | ✅ | ✅ |
search_content
Busca no manifesto por keyword em títulos, descrições e tags.
Schema:
{
"name": "search_content",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string", "description": "Search term" },
"collection": { "type": "string", "description": "Filter by collection name (optional)" },
"limit": { "type": "number", "description": "Max results to return (default: 5)" }
},
"required": ["query"]
}
}
Comportamento:
- Busca case-insensitive em
title,descriptionetags - Cap interno de 20 resultados (independente do
limit) - Output truncado a
maxOutputLength(default: 1500 chars) - Marcado com
untrustedContentHint: true(conteúdo pode ser editável)
Exemplo de retorno:
[
{
"title": "WebMCP: O Protocolo para Agentes de IA",
"url": "/webmcp/introducao/",
"description": "Entenda o que é WebMCP...",
"collection": "webmcp"
}
]
list_sections
Lista as collections disponíveis no site com contagem de itens.
Schema:
{
"name": "list_sections",
"inputSchema": { "type": "object", "properties": {} }
}
Exemplo de retorno:
[
{ "name": "blog", "count": 42 },
{ "name": "docs", "count": 15 },
{ "name": "webmcp", "count": 9 }
]
go_to
Navega para uma página específica por slug.
Schema:
{
"name": "go_to",
"inputSchema": {
"type": "object",
"properties": {
"slug": { "type": "string", "description": "Page slug or path" }
},
"required": ["slug"]
}
}
Comportamento:
- Executa
window.location.href = url - Retorna
null(causa navegação — response não é possível) - Não marcado com
readOnlyHint(muda estado da página)
get_page_info
Retorna metadata da página atual.
Schema:
{
"name": "get_page_info",
"inputSchema": { "type": "object", "properties": {} }
}
Exemplo de retorno:
{
"title": "API Imperativa do WebMCP",
"description": "Guia completo da API Imperativa...",
"url": "/webmcp/imperative-api/",
"headings": ["Visão geral", "registerTool()", "getTools()", "executeTool()"]
}
Como funciona internamente
Fluxo build → runtime → agente
BUILD TIME
├── Astro compila páginas HTML
├── Hook astro:build:done extrai títulos e descriptions
└── Gera /_webmcp/manifest.json (estático, CDN-cacheable)
RUNTIME (Browser)
├── Script injetado em toda página (~1KB gzipped)
├── Feature detection: document.modelContext ?? navigator.modelContext
├── Fetch do manifesto: /_webmcp/manifest.json
└── Registra 4 tools via mc.registerTool()
AGENTE
├── Descobre tools via protocolo WebMCP
├── Chama tools com argumentos tipados
└── Recebe resultados estruturados
Para detalhes de arquitetura, veja Arquitetura do astro-webmcp.
Combinando com API Declarativa
As tools automáticas do astro-webmcp usam a API Imperativa. Você pode complementar com formulários declarativos na mesma página:
---
// src/pages/contact.astro
---
<html>
<body>
<!-- Tools imperativas (astro-webmcp): search, list, navigate, page_info -->
<!-- Tool declarativa: formulário de contato -->
<form toolname="send_contact_message"
tooldescription="Send a message to the site owner. Include email for reply."
toolautosubmit
action="/api/contact"
method="POST">
<label for="email">Email</label>
<input type="email" name="email" required
toolparamdescription="Your email address for receiving a reply">
<label for="subject">Subject</label>
<input type="text" name="subject" required>
<label for="message">Message</label>
<textarea name="message" required
toolparamdescription="Your message (max 1000 characters)"></textarea>
<button type="submit">Send</button>
</form>
</body>
</html>
O agente verá 5 tools: as 4 do astro-webmcp + send_contact_message do formulário declarativo.
Como testar
Pré-requisitos
- Chrome 149+ instalado
- Flag habilitada:
chrome://flags/#enable-webmcp-testing→ Enabled → Relaunch
Testando em desenvolvimento
# Inicie o dev server
npm run dev
# Abra http://localhost:4321 no Chrome
# As tools serão registradas automaticamente
Verificando no console
Abra o DevTools (F12) e execute:
// Verificar se WebMCP está ativo
const mc = document.modelContext ?? navigator.modelContext;
console.log('WebMCP:', mc ? 'disponível' : 'não suportado');
// Listar tools registradas
const tools = await mc.getTools();
tools.forEach(t => console.log(`${t.name}: ${t.description}`));
Testando com Model Context Tool Inspector
- Instale a extensão
- Abra seu site local
- Clique no ícone da extensão
- Veja as tools listadas com schemas
- Teste execução com linguagem natural
Verificando o manifesto
# Em produção (após build)
curl http://localhost:4321/_webmcp/manifest.json | jq .
# Deve retornar:
{
"generatedAt": "2026-06-16T...",
"site": "http://localhost:4321",
"collections": [...],
"entries": [...]
}
Troubleshooting
| Problema | Causa provável | Solução |
|---|---|---|
| Tools não aparecem | Flag não habilitada | chrome://flags/#enable-webmcp-testing → Enabled → Relaunch |
| Tools não aparecem | Manifesto não carregou | Network tab: /_webmcp/manifest.json retorna 200? |
| Tools não aparecem | Browser sem suporte | Verificar Chrome 149+ |
| Manifesto vazio | Build falhou | astro build completou sem erros? |
| Busca sem resultados | Conteúdo sem description | Busca opera em title, description, tags |
document.modelContext undefined | Chrome < 149 ou flag off | Atualizar Chrome e habilitar flag |
| Erro CORS no manifesto | Manifesto em outro origin | Manifesto é fetched de same-origin by design |
Logs úteis
// Adicionar ao browser console para debug
const mc = document.modelContext ?? navigator.modelContext;
if (!mc) {
console.error('[WebMCP] Não suportado neste browser');
} else {
mc.addEventListener('toolchange', async () => {
const tools = await mc.getTools();
console.log('[WebMCP] Tools atualizadas:', tools.map(t => t.name));
});
}
Segurança out-of-the-box
O astro-webmcp implementa as práticas de segurança recomendadas por default:
O que é exposto (informação já pública)
| Dado | Fonte | Equivalente a |
|---|---|---|
| URLs | HTML compilado | sitemap.xml |
| Títulos | <title> tag | View source |
| Descriptions | <meta description> | Crawlers |
| Headings (h1-h3) | DOM | Visível na página |
O que NÃO é exposto
- ❌ Dados server-side, APIs, endpoints privados
- ❌ Tokens, credenciais, env vars
- ❌ Rotas admin ou páginas protegidas
- ❌ Dados de usuário (plugin é fully static)
Defesas ativas
| Camada | Proteção |
|---|---|
| Output truncation | Max 1.500 chars (character budget Chrome) |
| Sanitização | Strip de injection patterns (default: on) |
| Origin isolation | Same-origin only por default |
| Cap de resultados | Max 20 itens em search |
| Annotations | untrustedContentHint onde aplicável |
Para configuração avançada de segurança, veja astro-webmcp Config.
Recomendações para agentes consumindo astro-webmcp
Se você está construindo um agente que consome sites com astro-webmcp:
- Respeite
untrustedContentHint— Aplique spotlighting em outputs marcados - Confirme
go_to— Não temreadOnlyHint: true, causa navegação - Set token limits — Outputs já são limitados, mas aplique limites agent-level também
- Use
list_sectionsprimeiro — Entenda a estrutura antes de buscar - Filtre por collection — Use o parâmetro
collectionemsearch_content
Uso em sites multilíngues
Para sites com conteúdo em múltiplos idiomas (como este — prompt.api.br em PT-BR), configure collections por idioma:
webmcp({
collections: ['blog-pt', 'docs-pt', 'webmcp'],
})
O manifesto incluirá apenas as collections filtradas. Agentes operando no contexto PT-BR terão acesso apenas ao conteúdo relevante.
Performance em produção
Impacto no carregamento
| Métrica | Valor | Impacto |
|---|---|---|
| Script injetado | ~1KB gzipped | Imperceptível |
| Fetch do manifesto | 5-50KB (varia com tamanho do site) | Async, non-blocking |
| Registro de tools | <1ms | Negligível |
| CPU em browsers sem suporte | 0 | Script sai imediatamente |
Caching
O manifesto /_webmcp/manifest.json é estático — pode (e deve) ser cacheado agressivamente:
# Headers CDN recomendados
Cache-Control: public, max-age=3600, s-maxage=86400
Em plataformas como Vercel, Netlify ou Cloudflare Pages, o caching é automático para assets estáticos.
Comparação com abordagens alternativas
| Abordagem | Prós | Contras |
|---|---|---|
| astro-webmcp | Zero config, seguro, automatic | Busca limitada a metadata |
| Sitemap.xml | Universalmente suportado | Sem semântica, sem schema |
| RSS feed | Conteúdo completo | Formato diferente, sem tools |
| Custom MCP server | Full-text search, auth-aware | Infraestrutura adicional |
| Actuation (scraping) | Funciona sem cooperação do site | Frágil, lento, impreciso |
astro-webmcp é a opção de menor fricção para sites Astro. Para necessidades avançadas (full-text, auth), combine com um MCP server — veja WebMCP vs MCP.
Próximos passos
- astro-webmcp Config — Configuração completa de segurança e collections
- astro-webmcp Arquitetura — Design decisions e manifest build-time
- API Imperativa — A API que o plugin usa internamente
- Segurança — Modelo de segurança detalhado