exray
exray é um servidor MCP remoto que renderiza páginas da web e permite que você registre seu próprio código TypeScript de scraping e extração como ferramentas nomeadas reutilizáveis.
Você não executa ou instala o exray. É um serviço hospedado em https://mcp.exray.dev/mcp.
O usuário fornece um token de portador; você chama as ferramentas via MCP.
Antes de tudo: está conectado?
Se as ferramentas do exray não estiverem na sua lista de ferramentas, o servidor MCP não está configurado. Diga ao usuário para:
- Cadastrar-se em
https://app.exray.dev/sign-in— a página/welcomeemite um token (mostrado apenas uma vez) - Adicionar o servidor ao seu cliente — a configuração está em https://docs.exray.dev/docs/mcp-clients
- Reiniciar o cliente — a configuração MCP é lida na inicialização
Não tente contornar uma conexão ausente fazendo scraping com fetch ou ferramentas de shell.
Diga o que está faltando e pare.
Escolhendo uma ferramenta
| Situação | Ferramenta |
|---|---|
| Uma página, quer o conteúdo | scrape |
| Uma página, quer campos específicos | extract com um esquema plano |
| Muitas páginas em um site | crawl, depois get_crawl_results |
| A mesma extração repetidamente, ou lógica complexa demais para um esquema plano | escrever um define_extractor |
| A página precisa de cliques/rolagem antes de renderizar | escrever um define_fetcher |
| Usuário quer ver os resultados | escrever um define_handler (página de resultado) |
Recorra a scrape / extract primeiro. Só escreva código quando uma ferramenta integrada realmente
não conseguir expressar o necessário — um asset registrado é algo que o usuário terá que manter.
Esquemas planos apenas
extract aceita exatamente quatro tipos: string, number, boolean, string[]. Sem aninhamento.
{ "title": "string", "price": "number", "tags": "string[]" }
Formas aninhadas ou condicionais precisam de um define_extractor.
Escrevendo assets de código
Três tipos, todos em TypeScript, todos validados estaticamente antes de serem aceitos:
- fetcher — entrada
fetch(ctx), controla o navegador, retorna umPageSnapshot - extractor — entrada
extract(snapshot, ctx?), transforma um snapshot em JSON - handler — entrada
handle(request, ctx), serve uma página web pública
Restrições rígidas — código que violar estas será rejeitado no registro:
- A única importação permitida é
import typede@exray/exray-api. Sem importações em tempo de execução. Se você precisar consultar o DOM, trabalhe a partir desnapshot.htmlcom manipulação de strings, ou faça o trabalho no DOM em um fetcher viactx.page.evaluate(). - Sem
eval/new Function, sem efeitos colaterais de nível superior - Sem acesso à rede de dentro do sandbox
O registro deixa o asset em draft — ele não pode ser executado ainda. Chame publish_definition
antes de tentar usá-lo. Isso pega as pessoas constantemente; não reporte sucesso após
define_* sozinho.
Páginas de resultado — leia next_action e aja com base nela
Quando você publica um handler, a resposta carrega um objeto site. Publicar
com sucesso não significa que a página está acessível. Sempre leia site.next_action e diga
ao usuário a coisa específica que ainda está faltando:
next_action | O que dizer ao usuário |
|---|---|
set_username | "Defina um nome de usuário em app.exray.dev/settings/profile — o endereço é <username>-<project>.exray.app" |
enable_site | "Sua página estará em <site.url>. Ative-a: exray site enable, ou no painel." |
shorten_slug | "<username>-<slug> tem mais de 63 bytes. Use um slug de projeto mais curto." |
contact_support | Um problema de configuração no lado do servidor; reporte como tal |
null | Está ativo em site.url — dê o link ao usuário |
Nunca termine uma publicação de handler sem dizer onde a página está ou o que a está bloqueando. O usuário não tem outra forma de descobrir, e "publicado com sucesso" soa como "está pronto".
O que um handler pode e não pode fazer:
- Pode ler dados de job deste projeto via
ctx.data(listar jobs, buscar um resultado), retornar HTML ou JSON, rotear por caminho - Não pode armazenar nada, acessar a rede, aceitar envios de formulário ou ler dados de outros projetos
É uma camada de apresentação, não um backend.
Vinculações de armazenamento
O código do agente não tem persistência por padrão. Se o projeto tiver vinculações ativadas, fetchers recebem
ctx.kv / ctx.db / ctx.storage; extractors recebem ctx.kv apenas; handlers recebem todos os três
somente leitura.
Se uma chamada lançar binding_not_enabled, a vinculação não está ativada — isso requer um token
de administrador (exray bindings set --kv on). Diga ao usuário; você não pode ativá-la sozinho.
Erros que vale a pena reconhecer
| Erro | Significado |
|---|---|
403 forbidden | O token não tem um escopo. Execução precisa de tools.execute, registro precisa de tools.define, publicação precisa de tools.publish, ações de conta precisam de admin |
402 | Cota mensal esgotada. Pare e avise o usuário |
definition_incompatible_api | O asset foi compilado contra uma versão major diferente do @exray/exray-api. Re-registre-o |
extractor_invalid / fetcher_invalid | A validação estática rejeitou o código — geralmente uma importação em tempo de execução ou um efeito colateral de nível superior |
binding_not_enabled | Veja vinculações de armazenamento acima |
concurrent_exceeded | Muitas chamadas em andamento. Aguarde; não tente novamente em um loop apertado |
Em budget_exceeded ou 402, pare. Tentar novamente queima a cota do usuário sem progresso.
Escopos
Um fluxo de trabalho de primeiro scraping precisa apenas de tools.read + tools.execute. Registrar e publicar
precisam de tools.define / tools.publish. Qualquer coisa que toque na conta — emitir tokens,
ativar páginas de resultado, alternar vinculações — precisa de admin e é trabalho do usuário, não seu.
Documentação completa
https://docs.exray.dev — quickstart, configurações de cliente, referência CLI, páginas de resultado, parâmetros de ferramenta e o contrato do extrator.