読み取り専用MCPサーバー
自分のCloudflareデプロイでドキュメントの検索・取得ツールを公開します。
概要
このMCPサーバーを有効にすると、エージェント向けエクスポートを使う2つの読み取り専用ツールが利用できます。新規プロジェクトにはCloudflare Workers向けのデプロイ設定が生成されます。サイトとエンドポイントは自分のCloudflareアカウントにデプロイします。静的エクスポートだけならWorkerは不要です。共用ゲートウェイ、AIプロバイダーの認証情報、Durable Object、検索データベースも不要です。
プロジェクトの作成とデプロイ
イニシャライザーで「MCP」を選ぶか、オプションを指定します。
pnpm create zudo-doc my-docs --mcp --mcp-deploy cloudflare --yes
cd my-docs
pnpm install
pnpm build
pnpm preview:workerMCPを選んでagentExportを省略すると、自動的に有効になります。mcpDeployの省略時は"cloudflare"が選ばれます。生成されるzfb.config.tsにはagentExport: true、mcp: true、Cloudflareアダプターが入ります。wrangler.jsonc、preview:workerとdeployのスクリプト、任意のMCP SDKとデプロイ用依存パッケージも追加されます。Wranglerのmainは.を指します。ルートとSDK対応のバンドル解決はパッケージが提供します。ホスト側のWorkerラッパーや共用サービスは生成されません。通常の--yes生成では、これらの機能は有効になりません。
安定した引用URLのために、zfb.config.tsのsiteUrlを公開サイトのオリジンに設定します。生成されたWrangler設定を確認し、自分のWorker名とルート・ドメインを選んでください。ローカルで検証した後、所有者がデプロイします。
wrangler login
pnpm deploypnpm deployはビルドしてからwrangler deployを実行します。ChatGPTへの接続登録は行いません。Cloudflareアカウント設定、公開ドメイン、プロバイダーの利用には費用がかかる場合があります。公開エンドポイントにはCloudflare標準のレート制限と不正利用対策を利用してください。
検証とクライアント接続
pnpm preview:workerの実行中に、<base>/が読めることを確認し、MCPクライアントから<base>/mcpに接続します。エンドポイントはセッションを持たないStreamable HTTP POSTを使います。本番環境のGET/HEADはAllow: POST, OPTIONS付きの405を返します。ショーケースのプレビューではGET/HEADが静的アセットの404になる場合があります。OPTIONSはCORSプリフライトに応答します。サーバー間クライアントではOriginなしを受け入れ、許可されていないOriginがある場合は拒否します。
ChatGPTなどのリモートMCPクライアントには、デプロイ済みのHTTPS URLをカスタムMCP連携として追加します。たとえばhttps:、baseが/ならhttps:です。接続画面はクライアントごとに異なります。接続後にツールを検出し、具体的な語句でsearchを呼び、返されたIDをfetchに渡して、回答が人が読むページのURLを引用することを確認します。実際のChatGPTアカウントでの接続はリポジトリのローカルテストでは未検証です。デプロイ後に確認してください。検証済みの旧プロトコルは2024-11-05のメッセージをセッションなしのPOSTで送る方式です。SSEから始めるクライアントや再開可能なセッションには対応しません。
| ツール | 入力 | 結果 |
|---|---|---|
search | {query: string} | 順位付きの{id,title,url}を最大10件。該当なしなら[] |
fetch | 現在の検索結果から得た{id: string} | 選択した項目の{id,title,text,url,metadata}全体。存在しなければ明確なnot-found結果 |
人が読むページのurlは引用に利用できます。長いページには複数の項目IDがあります。関係する各部分を取得するか、ページ全体のMarkdownを開いてください。ツールは構造化データと同内容のJSONテキストを返し、読み取り専用、冪等、非破壊であると宣言します。AIへの質問、書き込み、履歴、公開用のツールはありません。検索対象はエージェント向けコーパスの全文で、ブラウザー検索の既定の3,000文字を超える部分や日本語も含みます。
既存プロジェクトへの追加・削除
プロジェクトを置き換えずにMCPを追加する
MCPに対応した同じリリースの@takazudo/zudo-docとcreate-zudo-docを使います。対象は6.0.0以降です。5.xのリリースはこの手順に対応していません。
必要なら先に移行ガイドに従って既存プロジェクトを更新し、静的エクスポートを有効にします。コンテンツ、siteUrl、base、ロケール、バンドル設定、他の機能と共有する依存関係、既存スクリプトを保持します。既存ディレクトリに対してイニシャライザーを実行しないでください。
既存プロジェクトのルートから、インストール済みドキュメントパッケージと同じ厳密なバージョンの一時参照プロジェクトを生成します。
ZUDO_DOC_VERSION=6.0.0
MCP_REFERENCE=$(mktemp -d)/mcp-reference
pnpm dlx "create-zudo-doc@$ZUDO_DOC_VERSION" "$MCP_REFERENCE" --mcp --mcp-deploy cloudflare --yes
mkdir -p scripts
cp -n "$MCP_REFERENCE/scripts/stage-cloudflare-base.mjs" scripts/stage-cloudflare-base.mjs後のリリースを使う場合は6.0.0をインストール済みバージョンに置き換えます。参照プロジェクトのpackage.jsonとwrangler.jsoncを確認し、ヘルパーだけをコピーして、デプロイ設定は既存プロジェクトに統合します。同じヘルパーパスが存在する場合は上書きせず比較してください。検証が終わるまで参照プロジェクトを残します。これにより、作成済みの設定を置き換えずに、バージョンに合ったビルド処理を入手できます。
参照プロジェクトに記載されたMCP依存関係をインストールします。現在対応する組み合わせは次のとおりです。
pnpm add @modelcontextprotocol/sdk@1.32.1 @takazudo/zfb-adapter-cloudflare@4.3.3
pnpm add -D wrangler@4.149.0アダプターはプロジェクトが対応するzfbバージョンに合わせます。既存のzudoDoc({ ... })内で、他の設定を維持して次のフィールドを有効にします。
agentExport: true,
mcp: true,
adapter: "@takazudo/zfb-adapter-cloudflare",siteUrlはhttps:のような正規オリジンのままにします。ルート配置ではbaseを省略するか/にし、サブディレクトリ配置ではbase: "/manual"を維持します。MCPが有効なとき、パッケージは既存バンドル設定を保持しながら、SDKに必要なmoduleとmainの解決フィールドを加えます。
自分のDNSに使えるWorker名を選んでwrangler.jsoncを追加または統合します。他の機能で使うバインディングやルートを保持してください。現在の生成済み構成は次の形です。
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "my-docs",
"main": "./dist/_worker.js",
"compatibility_date": "2024-12-01",
"compatibility_flags": ["nodejs_compat"],
"assets": {
"directory": "./dist",
"binding": "ASSETS",
"not_found_handling": "404-page",
"run_worker_first": false
}
}&を、後処理も含めた既存のビルドコマンド全体が成功した後に追加します。たとえば既存のzfb build &は次の形になります。
{
"scripts": {
"build": "zfb build && node scripts/postbuild.mjs && node scripts/stage-cloudflare-base.mjs",
"preview:worker": "wrangler dev",
"deploy": "pnpm build && wrangler deploy"
}
}scriptsオブジェクトを置き換えずに統合します。既存のpreviewまたはdeployスクリプトがある場合は保持し、MCPの検証・デプロイには別の名前を選びます。.gitignoreに.wrangler/がなければ追加します。ヘルパーはエクスポート済みマニフェストのbaseを読みます。ルート配置では何も移動せず、/配置ではプリレンダリング済みページ、llmsファイル、ブラウザーアセットをdist/manual/配下に配置してWranglerが提供できるようにします。Workerエントリーはdist/のままです。移動したり、エクスポートをラップしたりしないでください。
以下のllmsパスはllmsTxt: trueの場合だけ確認します。MCPを有効にしても、この独立したエクスポートは有効になりません。
pnpm buildとpnpm preview:workerを実行します。ルート配置では/、/、/、/を、/配置では/、/、/、/を確認します。実際のコンテンツページと参照先のJS/CSSを開き、SDKクライアントでsearch/fetchを検出し、ENとJAのコンテンツを検索し、返されたIDをfetchして引用用の人間向けURLを開きます。マニフェストのMarkdownと項目URLも確認してください。正規引用URLには公開オリジンとbaseが必要です。ローカルランタイムでは、表示されたオリジンの同じパスで確認できます。この検証が終わってから、前述の手順でデプロイとアカウント接続を行います。
MCPを削除して静的エクスポートを残す
mcp: falseにするかフィールドを削除し、agentExport: trueと既存のサイト・base・ロケール設定を保持します。Cloudflareアダプター設定は他の機能で不要な場合だけ削除します。Cloudflare設定がすべてMCP専用だった場合、完全な静的プロジェクトに戻す手順は次のとおりです。
buildから追加した&だけを削除し、元のコマンドと後処理を保持します。不要になったヘルパーを削除します。& node scripts/ stage- cloudflare- base. mjs MCP専用のpreview/deployスクリプトと
wrangler.jsoncを削除します。共有していた場合はMCP用の追加部分だけを削除します。.wrangler/のignore指定は、残るツールが使わない場合だけ削除します。pnpm remove @modelcontextprotocol/は、残るすべての機能で使わない依存関係に対してだけ実行します。共有するアダプター、SDK、デプロイツールは保持します。sdk @takazudo/ zfb- adapter- cloudflare wrangler pnpm buildを実行します。完全な静的出力にはMCPルートとdist/がなく、マニフェスト、項目JSON、ページごとのMarkdownが_ worker. js dist/<base>/agent/v1/配下に残ることを確認します。有効なllmsファイルはdist/とllms. txt dist/に戻り、リンクには正規オリジンとbaseが保持されます。静的ページ、llmsファイル、ブラウザーアセットには、静的ホストの通常のbase配置方式を使います。削除したヘルパーはWrangler専用です。既存の静的ホスト公開手順で再ビルドした出力を公開し、古いWorkerデプロイを置き換えてエンドポイントを公開しなくします。<locale>/ llms. txt
MCPの無効化だけでは、公開静的コーパスは削除されません。それも不要な場合はagentExportを別途無効にして再ビルドし、公開成果物を置き換えて古い/ファイルを削除します。独立したllmsTxt設定はドキュメントを公開し続ける場合があります。その公開も不要なら無効にしてください。
上限と公開時の安全性
検索クエリの上限はUTF-16コード単位で500、空のクエリは無効です。各項目の本文は最大8,000 UTF-16コード単位で、サロゲートペアの途中では分割しません。最終JSON-RPC応答は131,072 UTF-8バイト、POST本文は65,536バイトが上限です。マニフェストは8 MiB、エージェント検索インデックスは16 MiBおよび10,000項目が上限です。超過時は本文を黙って切らず、明示的に失敗します。サーバーは現在のマニフェストの項目IDと成果物ハッシュを検証し、異なるビルドの混在を防ぎます。
エンドポイントと静的ファイルは公開ドキュメントを提供します。robots.txt、noindex、unlisted、search_excludeは認証ではありません。保護された資料にコーパスを有効化しないでください。将来の非公開モードでは、/と静的成果物の両方を保護する必要があります。取得した文書は信頼できないデータであり、コマンド実行や追加権限の根拠にはなりません。MCPが不要なら、ブラウザークライアントにサイトURLとllms.txt、または生成されたMarkdown URLを明示的に渡してください。ホームページURLだけでは、クライアントがllms.txtを読むとは限りません。