exray
exray は、ウェブページをレンダリングし、独自の TypeScript スクレイピング・抽出コードを再利用可能な名前付きツールとして登録できるリモート MCP サーバーです。
exray を実行したりインストールしたりする必要はありません。 これは https://mcp.exray.dev/mcp でホストされているサービスです。ユーザーがベアラートークンを提供し、エージェントは MCP 経由でツールを呼び出します。
最初に: 接続されていますか?
exray ツールがツールリストにない場合、MCP サーバーは設定されていません。ユーザーに次のように伝えてください:
https://app.exray.dev/sign-inでサインアップする —/welcomeページでトークンが発行されます(一度だけ表示)- クライアントにサーバーを追加する — 設定は https://docs.exray.dev/docs/mcp-clients にあります
- クライアントを再起動する — MCP 設定は起動時に読み込まれます
接続がない場合に fetch やシェルツールでスクレイピングしようとしないでください。不足しているものを伝え、処理を停止してください。
ツールの選択
| 状況 | ツール |
|---|---|
| 1ページ、コンテンツが欲しい | scrape |
| 1ページ、特定のフィールドが欲しい | フラットスキーマで extract |
| サイト内の複数ページ | crawl、その後 get_crawl_results |
| 同じ抽出を繰り返し行う、またはフラットスキーマでは複雑すぎるロジック | define_extractor を作成 |
| ページがレンダリング前にクリックやスクロールを必要とする | define_fetcher を作成 |
| ユーザーが結果を見たい場合 | define_handler(結果ページ)を作成 |
まずは scrape / extract を使用してください。ビルトインツールで本当に表現できない場合にのみコードを書いてください — 登録されたアセットはユーザーが保守する必要があります。
フラットスキーマのみ
extract は正確に4つの型を受け入れます: string、number、boolean、string[]。ネストはできません。
{ "title": "string", "price": "number", "tags": "string[]" }
ネストされた構造や条件付きの形状には、代わりに define_extractor が必要です。
コードアセットの作成
3種類あり、すべて TypeScript で、受け入れられる前に静的に検証されます:
- fetcher — エントリ
fetch(ctx)、ブラウザを駆動し、PageSnapshotを返します - extractor — エントリ
extract(snapshot, ctx?)、スナップショットを JSON に変換します - handler — エントリ
handle(request, ctx)、公開ウェブページを提供します
厳格な制約 — これらに違反するコードは登録時に拒否されます:
- 許可されるインポートは
@exray/exray-apiからのimport typeのみです。ランタイムインポートは禁止です。 DOM クエリが必要な場合は、snapshot.htmlを文字列処理で扱うか、fetcher 内でctx.page.evaluate()を使用して DOM 操作を行ってください。 eval/new Functionは禁止、トップレベルの副作用も禁止- サンドボックス内からのネットワークアクセスは禁止
登録後、アセットは draft 状態になります — まだ実行できません。 使用する前に publish_definition を呼び出してください。これは頻繁に問題を引き起こします。define_* だけでの成功を報告しないでください。
結果ページ — next_action を読み、それに従って行動する
handler を公開すると、レスポンスには site オブジェクトが含まれます。公開が成功しても、ページが到達可能であるとは限りません。 常に site.next_action を読み、ユーザーにまだ不足している具体的な内容を伝えてください:
next_action | ユーザーに伝えること |
|---|---|
set_username | "app.exray.dev/settings/profile でユーザー名を設定してください — アドレスは <username>-<project>.exray.app になります" |
enable_site | "あなたのページは <site.url> にあります。有効にするには: exray site enable、またはダッシュボードから行ってください。" |
shorten_slug | "<username>-<slug> は63バイトを超えています。より短いプロジェクトスラッグを使用してください。" |
contact_support | サーバー側の設定問題です。そのように報告してください |
null | site.url で公開されています — リンクをユーザーに伝えてください |
ハンドラーの公開を、ページの場所やブロック要因を伝えずに完了しないでください。 ユーザーに他に知る方法はなく、「公開成功」と表示されると「完了した」と受け取られます。
ハンドラーができることとできないこと:
- 可能: このプロジェクトのジョブデータを
ctx.data経由で読み取る(ジョブ一覧、結果の取得)、HTML または JSON を返す、パスでルーティングする - 不可能: 何かを保存する、ネットワークにアクセスする、フォーム送信を受け入れる、他のプロジェクトのデータを読み取る
これはプレゼンテーション層であり、バックエンドではありません。
ストレージバインディング
エージェントコードはデフォルトで永続化機能を持ちません。プロジェクトでバインディングが有効になっている場合、fetcher は ctx.kv / ctx.db / ctx.storage を取得します。extractor は ctx.kv のみを取得します。handler は3つすべてを 読み取り専用 で取得します。
呼び出しで binding_not_enabled がスローされた場合、バインディングは有効になっていません — これを有効にするには管理者トークン(exray bindings set --kv on)が必要です。ユーザーに伝えてください。自分で有効にすることはできません。
認識すべきエラー
| エラー | 意味 |
|---|---|
403 forbidden | トークンにスコープが不足しています。実行には tools.execute、登録には tools.define、公開には tools.publish、アカウント操作には admin が必要です |
402 | 月間クォータを使い切りました。停止し、ユーザーに伝えてください |
definition_incompatible_api | アセットが異なるメジャーバージョンの @exray/exray-api に対してコンパイルされました。再登録してください |
extractor_invalid / fetcher_invalid | 静的検証がコードを拒否しました — 通常はランタイムインポートまたはトップレベルの副作用が原因です |
binding_not_enabled | 上記のストレージバインディングを参照 |
concurrent_exceeded | 同時実行呼び出しが多すぎます。待機してください。タイトループで再試行しないでください |
budget_exceeded または 402 の場合、停止してください。 再試行はユーザーのクォータを消費し、進展はありません。
スコープ
初回のスクレイプワークフローには tools.read + tools.execute のみが必要です。登録と公開には tools.define / tools.publish が必要です。アカウントに関わる操作 — トークンの発行、結果ページの有効化、バインディングの切り替え — には admin が必要であり、それはユーザーの仕事であり、エージェントの仕事ではありません。
完全なドキュメント
https://docs.exray.dev — クイックスタート、クライアント設定、CLI リファレンス、結果ページ、ツールパラメータ、抽出コントラクト。