Communitygithub.com

rtx3/exray-kit

Agent skill and user docs for exray — an agent-native MCP web-scraping runtime. Service is hosted at mcp.exray.dev; nothing here to run.

Was ist exray-kit?

exray-kit is a Claude Code agent skill that agent skill and user docs for exray — an agent-native MCP web-scraping runtime. Service is hosted at mcp.exray.dev; nothing here to run.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add rtx3/exray-kit

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

exray

exray is a remote MCP server that renders web pages and lets you register your own TypeScript scraping and extraction code as reusable named tools.

You do not run or install exray. It's a hosted service at https://mcp.exray.dev/mcp. The user supplies a bearer token; you call tools over MCP.

Before anything else: is it connected?

If exray tools aren't in your tool list, the MCP server isn't configured. Tell the user to:

  1. Sign up at https://app.exray.dev/sign-in — the /welcome page issues a token (shown exactly once)
  2. Add the server to their client — the config is at https://docs.exray.dev/docs/mcp-clients
  3. Restart the client — MCP config is read at startup

Do not try to work around a missing connection by scraping with fetch or shell tools. Say what's missing and stop.

Picking a tool

SituationTool
One page, want the contentscrape
One page, want specific fieldsextract with a flat schema
Many pages under a sitecrawl, then get_crawl_results
The same extraction repeatedly, or logic too complex for a flat schemawrite a define_extractor
Page needs clicks/scrolling before it renderswrite a define_fetcher
User wants to look at the resultswrite a define_handler (result page)

Reach for scrape / extract first. Only write code when a built-in tool genuinely can't express what's needed — a registered asset is something the user then has to maintain.

Flat schemas only

extract accepts exactly four types: string, number, boolean, string[]. No nesting.

{ "title": "string", "price": "number", "tags": "string[]" }

Nested or conditional shapes need a define_extractor instead.

Writing code assets

Three kinds, all TypeScript, all validated statically before they're accepted:

  • fetcher — entry fetch(ctx), drives the browser, returns a PageSnapshot
  • extractor — entry extract(snapshot, ctx?), turns a snapshot into JSON
  • handler — entry handle(request, ctx), serves a public web page

Hard constraints — code violating these is rejected at registration:

  • The only import allowed is import type from @exray/exray-api. No runtime imports. If you need DOM querying, work from snapshot.html with string handling, or do the DOM work in a fetcher via ctx.page.evaluate().
  • No eval / new Function, no top-level side effects
  • No network access from inside the sandbox

Registration leaves the asset in draft — it cannot run yet. Call publish_definition before trying to use it. This trips people up constantly; don't report success after define_* alone.

Result pages — read next_action and act on it

When you publish a handler, the response carries a site object. Publishing successfully does not mean the page is reachable. Always read site.next_action and tell the user the specific thing that's still missing:

next_actionWhat to tell the user
set_username"Set a username at app.exray.dev/settings/profile — the address is <username>-<project>.exray.app"
enable_site"Your page will be at <site.url>. Enable it: exray site enable, or in the dashboard."
shorten_slug"<username>-<slug> is over 63 bytes. Use a shorter project slug."
contact_supportA server-side configuration problem; report it as such
nullIt's live at site.url — give them the link

Never finish a handler publish without saying where the page is or what's blocking it. The user has no other way to find out, and "published successfully" reads as "it's done".

What a handler can and can't do:

  • Can read this project's job data via ctx.data (list jobs, fetch a result), return HTML or JSON, route by path
  • Cannot store anything, reach the network, accept form submissions, or read other projects' data

It's a presentation layer, not a backend.

Storage bindings

Agent code has no persistence by default. If the project has bindings enabled, fetchers get ctx.kv / ctx.db / ctx.storage; extractors get ctx.kv only; handlers get all three read-only.

If a call throws binding_not_enabled, the binding isn't turned on — that requires an admin token (exray bindings set --kv on). Tell the user; you can't enable it yourself.

Errors worth recognising

ErrorMeaning
403 forbiddenThe token lacks a scope. Execution needs tools.execute, registering needs tools.define, publishing needs tools.publish, account actions need admin
402Monthly quota exhausted. Stop and tell the user
definition_incompatible_apiThe asset was compiled against a different @exray/exray-api major. Re-register it
extractor_invalid / fetcher_invalidStatic validation rejected the code — usually a runtime import or a top-level side effect
binding_not_enabledSee storage bindings above
concurrent_exceededToo many calls in flight. Wait; don't retry in a tight loop

On budget_exceeded or 402, stop. Retrying burns the user's quota without progress.

Scopes

A first-scrape workflow needs only tools.read + tools.execute. Registering and publishing need tools.define / tools.publish. Anything touching the account — issuing tokens, enabling result pages, toggling bindings — needs admin and is the user's job, not yours.

Full documentation

https://docs.exray.dev — quickstart, client configs, CLI reference, result pages, tool parameters, and the extractor contract.

Verwandte Skills