mcpField
S
Share HTML

Share HTML

リモート
github.com/lifeodysseyファイル・ストレージ65 週間前に更新
リポジトリ

Share HTML について

Share HTMLは、単体HTMLファイルをサンドボックス化されたプレビューとして共有するCloudflareホストのサービスです。ページURLをすぐに用意したい人やエージェント向けに、非公開リンクまたはアクセスキー付きリンクとHTMLリスクスキャンを提供します。

主な機能

  1. 01単一HTMLファイルのアップロード
  2. 02非公開または保護付きリンクの作成
  3. 03サンドボックス内でのHTMLプレビュー
  4. 04不審なHTMLパターンのスキャン
  5. 05アカウントで共有を管理
  6. 06直接プレビューURLの提供

活用シーン

  1. 01サイトを構築せずにプロトタイプを共有
  2. 02モックアップや小規模デモをURLで送信
  3. 03アクセスキー保護付きプレビューの配布
  4. 04アカウント経由でアップロードを保持・削除

MCP 対応

リモートMCPサーバーは `describe_share_html`、`get_public_share`、`create_share` を提供します。`create_share` は非公開リンクとプライベートリンクに対応し、ウェブアップロードと同じレート制限およびリスクスキャンを適用します。

設定

リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。

エンドポイントhttps://share-html.zhenjiazhou0127.workers.dev/mcp
インストールコマンドをコピー
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。

ツール

3

このツールにパラメーターはありません。

詳細

HTML を共有する

利用状況調査は /report/0923 で確認できます。2026年9月23日のレポートでは固定されたスナップショットを使用し、集計結果と匿名化されたユースケースのみを公開しています。

ファーストパーティ分析では、ブラウザのレポート、HTTP/MCP のビジネス成果、獲得シグナル、ボットの証拠を分けて記録しています。分析に関する設定、データの制限、保持期間、GA4 の設定については、計測の仕様と運用ガイドを参照してください。ANALYTICS_ENABLED=true を指定してデプロイする前に、分析用マイグレーションを適用してください。サービスが有効な場合、ブラウザ分析はデフォルトで有効になり、分析設定から無効にできます。既存のオプトアウト、DNT/GPC、または読み取りできない設定ストレージがある場合は、データを収集しません。対象となるブラウザイベントには、専用の Share HTML GA4 プロパティを使用します。拡張計測は無効になっており、非公開の共有ページから Google イベントは送信されません。

Share HTML のロゴ

HTML ファイルを 1 つアップロードし、サンドボックス化されたプレビューを、非公開の公開リンクまたはアクセスキーで保護された非公開リンクとして共有できます。

公開サイト GitHub 上のソースコード CI Cloudflare Workers Supabase TypeScript

リンク

プロジェクトドキュメント

機能

Share HTML は、自己完結型の HTML ファイルを共有するための、Cloudflare でホストされる小規模なツールです。サイトを用意せずに URL が必要な場合に、簡易プロトタイプ、モックアップ、レシート、小規模なデモ、一度限りのページを手軽に共有できます。

  • 365 日で期限切れになる匿名アップロードフロー。
  • 共有ファイルの保存や削除に使用する Supabase のマジックリンク認証。認証メールの送信は Cloudflare Email Service が処理します。
  • 後から匿名アップロードをアカウントに紐付けるためのクレームトークンフロー。
  • 非公開の公開リンクと、アクセスキーで保護された非公開リンクの公開設定モード。
  • 必要に応じて非公開リンクのロックを解除すると、ステータス、リスクスコア、埋め込みプレビューを表示する共有ページ。
  • アップロードした HTML を単独で開くための直接プレビュー URL。
  • 疑わしい HTML パターンを検出する軽量スキャナー。
  • レポート API と管理者向けモデレーションエンドポイント。

URL の種類

Share HTML は、アップロード後に意図的に異なる 2 種類の URL を公開します。

  • Share URL は、/s/:slug にあるラッパーページを開きます。ステータス、安全性に関する情報、報告アクション、埋め込みプレビューが含まれるため、共有するリンクとして最適です。
  • Preview URL は、/v/:slug/ にあるサンドボックス化された HTML レンダリングを開きます。プライベートリンクの場合、ロック解除時に作成された有効期間の短いプレビュー Cookie が必要です。
  • Claim token は非公開です。匿名でアップロードしたデータを自分のアカウントに移す場合は、サインイン後に共有 ID とともに使用してください。

各アップロードでは、公開範囲も 1 つ選択します。

  • public_unlisted がデフォルトです。URL を知っている人なら誰でもメタデータを読み取り、プレビューを開けます。共有ルートとプレビュールートには noindex が設定され、sitemap.xml に追加されることはありませんが、限定公開は認証済みと同じではありません。
  • private_link は、32 バイトの base64url accessKey を返します。返される share.share_url には、クライアント側の #key= フラグメントにキーが含まれるため、最初の HTTP リクエストでキーがサーバーに送信されることはありません。プライベート URL 全体は秘密として扱ってください。

claimToken と accessKey は、意図的に異なる権限を持ちます。前者はサインイン後に所有権を移転し、後者はプライベートリンクを開くためのもので、所有権は付与しません。

HTTP API

パブリック限定公開の共有を作成します(デフォルト)。

curl -X POST https://sharehtml.zhenjia.dev/api/shares \
  -F '[email protected]' \
  -F 'title=My page'

プライベートリンクを作成します。

curl -X POST https://sharehtml.zhenjia.dev/api/shares \
  -F '[email protected]' \
  -F 'visibility=private_link'

どちらの成功レスポンスも同じ形式です。

{
  "share": { "id": "...", "slug": "...", "share_url": "...", "preview_url": "..." },
  "claimToken": "... or null",
  "accessKey": "... or null",
  "message": "Uploaded."
}

public_unlisted の場合、accessKey は null です。ブラウザーのラッパーを使わずにプライベートリンクのロックを解除するには、次のようにします。

curl -X POST https://sharehtml.zhenjia.dev/api/shares/SLUG/access \
  -H 'content-type: application/json' \
  --data '{"accessKey":"PRIVATE_ACCESS_KEY"}'

成功すると { "share": ... } が返され、有効期間の短いホスト限定 HttpOnly グラントが 2 つ設定されます。1 つはプレビュー用に /v/:slug にスコープされ、もう 1 つは正確なロック解除エンドポイントにスコープされます。これにより、ブラウザーがアドレスバーから #key を削除した後も、更新時にメタデータを復元できます。プライベートリンクに対する単純な GET /api/public/shares/:slug は、code: "share_access_required" を伴う 401 を返します。誤ったキーの場合は、code: "invalid_share_access_key" を伴う 403 を返します。キーをクエリパラメーターに移したり、プライベート URL 全体をログ、問題報告、パブリック出力に含めたりしないでください。

認証済みの所有者は、POST /api/shares/:id/access-key を使って、紛失または漏えいしたプライベートキーを置き換えられます。ローテーションでは新しいキーが 1 度だけ返され、以前のキーに対して発行されたメタデータおよびプレビューのグラントは直ちに無効になります。

エージェントからのアクセス

Share HTML は、人間だけでなく AI エージェントからも発見し、利用できるように構築されています。

  • llms.txt — AI が読み取れるサイトガイドです(リクエストに Accept: text/markdown が含まれる場合は、/ からも配信されます)。
  • openapi.json — 両方の公開範囲モードと、非公開のロック解除/Cookie フローを含む、機械可読な HTTP API の説明です。ホームページの HTML にも静的コンテンツと JSON-LD が埋め込まれているため、JavaScript を使わないエージェントもサイトの概要と呼び出し方法を確認できます。
  • MCP マシンエンドポイント — https://share-html.zhenjiazhou0127.workers.dev/mcp は、describe_share_html、get_public_share、create_share を公開します。ブランドサイトと同じ本番 Worker を使用し、マシン間通信に対するゾーンレベルのブラウザーボットポリシーを回避します。このページでは、WebMCP(navigator.modelContext)を介して、同じツールをブラウザー内でも公開します。
  • /a2a — describe_share_html スキルを実装した A2A 1.0 JSON-RPC エンドポイントです。カードには、実行可能なこの A2A 機能のみが意図的に掲載されています。
  • WebMCP の create_share では、エージェントが public_unlisted または private_link を選択できます。access_private_share は、アクセスキーをメタデータと、範囲が限定されたメタデータおよびプレビューの許可情報と交換します。どちらも通常の HTTP API を介して実行されます。
  • MCP の create_share は、public_unlisted と private_link の両方に対応しています。ウェブアップロードと同じ匿名ユーザー向けレート制限とリスクスキャナーを介して実行されます。迂回経路はなく、非公開の作成時にはキーが一度だけ返されます。
  • 検出用ファイル:明示的な AI ボットルールを含む robots.txt、sitemap.xml、auth.md、および /.well-known/ リソース(api-catalog、mcp/server-card.json、webmcp.json、agent-skills、agent-card.json、OAuth/OIDC メタデータ、security.txt)。不明な /.well-known/ パスでは、SPA シェルではなく 404 を返します。

ファーストパーティのホームページと検出ドキュメントでは、検索インデックスへの登録とリアルタイム AI 入力を許可し、レスポンスレベルの Content-Signal によって AI トレーニングをオプトアウトしています。ユーザーが提供する共有メタデータとプレビューには、より厳格な search=no, ai-input=no, ai-train=no, use=immediate を設定し、noindex にして、サイトマップには決して掲載しません。このレスポンスレベルでの切り分けにより、同じホスト上のアップロードコンテンツにファーストパーティの GEO 許可が適用されるのを防ぎます。

獲得ループ

このプロダクトでは、検出用ファイルだけに頼るのではなく、クロール可能なファーストパーティのエントリーページを4つ用意しています。

  • /html-preview では、単一ファイルのプレビューの範囲を説明し、アップロードへの CTA を設けています。
  • /private-html-sharing では、アクセスキーによるプライバシー保護とその制限を説明しています。
  • /examples では、アップローダーに事前読み込みできる、自己完結型のファイルを3つ提供しています。
  • /agents では、MCP、HTTP、OpenAPI、WebMCP、Skill、A2A の実用的なエントリーポイントを提供しています。

sitemap.xml に登録されているのは、これらのページとホームページのみです。アップロードされた /s/:slug と /v/:slug/ の URL は引き続き noindex で、すべての検出用送信から除外されています。ラッパーページには「HTML を共有」という CTA が表示されます。その source=shared_preview 値は、visibility とともに既存の created イベントのメタデータにのみ保存されるため、新しいトラッキングサービスを追加せずに、プロダクト主導の利用開始を測定できます。

公式 MCP Registry の正規 ID は dev.zhenjia/share-html で、zhenjia.dev の DNS に公開された Ed25519 公開鍵によって認証されます。その記述子は server.json で、ホームページのリンクからエージェントを /agents のライブ統合ガイドに案内します。リモートサーバー自体は本番環境の workers.dev マシンエンドポイント上に置き、ユーザー向けページと正規 URL は sharehtml.zhenjia.dev に維持します。この分離により、ブランドドメインで Free プランの Bot Fight Mode が正規のデータセンター MCP クライアントを拒否するのを防ぎます。

手動の Publish MCP Registry metadata ワークフローでは、ライブマニフェストと MCP ツールリストを検証し、production 環境のシークレット MCP_REGISTRY_PRIVATE_KEY を使ってブランド ID を公開し、Registry の正確な投影を検証してから、レガシー ID io.github.lifeodyssey/share-html を移行メッセージ付きで非推奨としてマークします。Registry のバージョンは現在取り下げられないため、このワークフローは意図的に冪等であり、本番エンドポイントのデプロイと検証後に publish-dev-zhenjia と入力する必要があります。DNS 認証用の秘密鍵を、リポジトリ、Worker の設定、ログ、ワークフローのアーティファクトに決して置かないでください。

このホスト名ではプライベート URL と非公開 URL も配信されるため、IndexNow では Cloudflare Crawler Hints を使わず、明示的なファーストパーティの許可リストを使用します。

npm run growth:indexnow:dry-run
printf '%s' '<8-to-128-character-key>' | npx wrangler secret put INDEXNOW_KEY
INDEXNOW_KEY='<same-key>' npm run growth:indexnow

Worker は、その環境値が設定されている場合に限り、/{INDEXNOW_KEY}.txt を配信します。送信スクリプトは、グローバル IndexNow エンドポイントに接続する前に、/s/、/v/、/api/、およびオリジンの異なる URL を拒否します。

スタック

  • アプリシェルと API に Cloudflare Workers Static Assets を使用します。
  • アップロードされた HTML オブジェクトに Cloudflare R2 を使用します。
  • ブランド認証メールの配信に Cloudflare Email Service を使用します。
  • マジックリンクユーザーの認証に Supabase Auth を使用します。
  • メタデータ、レポート、イベント、モデレーション状態に Supabase Postgres を使用します。
  • フロントエンドに React、Vite、TypeScript を使用します。

ローカルセットアップ

npm install
cp .env.example .dev.vars
npm run build
npm run dev

本番環境へのデプロイ前に、以下の Cloudflare Worker シークレットを設定してください。

printf '%s' '<legacy-anon-key>' | npx wrangler secret put SUPABASE_REST_KEY
printf '%s' '<worker-api-secret>' | npx wrangler secret put WORKER_API_SECRET
printf '%s' '<random-salt>' | npx wrangler secret put IP_HASH_SALT
printf '%s' '<independent-random-32-byte-secret>' | npx wrangler secret put SHARE_ACCESS_PEPPER_V1
printf '%s' '<different-random-32-byte-secret>' | npx wrangler secret put PREVIEW_GRANT_SIGNING_KEY_V1
printf '%s' '<8-to-128-character-key>' | npx wrangler secret put INDEXNOW_KEY
printf '%s' 'v1,whsec_...' | npx wrangler secret put SUPABASE_SEND_EMAIL_HOOK_SECRET

SHARE_ACCESS_PEPPER_V1 は保存されるアクセスキーのハッシュを導出し、PREVIEW_GRANT_SIGNING_KEY_V1 は有効期間の短いメタデータとプレビューの許可情報に署名します。それぞれを個別に生成し、どちらの V1 値もその場で置き換えないでください。導出方式をローテーションする場合は新しいバージョンを追加し、保存されている access_key_version の値を移行してください。許可情報のローテーション時は、署名キーの重複利用期間を設けてください。

公開プレビューでは、別途 PREVIEW_ORIGIN を使用できます。非公開プレビューでは、意図的に APP_ORIGIN を使用します。これは、有効期間の短い認可 Cookie がホスト限定で、/v/{slug} にスコープされるためです。レスポンスの CSP sandbox では allow-same-origin を省略しているため、アップロードされた HTML がアプリのオリジンを継承したり、そのストレージを読み取ったりすることはできません。

R2 バケットを一度だけ作成します。

npx wrangler r2 bucket create share-html-prod

Supabase のすべてのマイグレーションをファイル名順に適用してください。既存のデプロイでは、supabase/migrations/0003_private_share_access.sql を適用し、この変更の Worker コードをデプロイする前に、バージョン管理された両方の非公開共有用シークレットを設定してください。このマイグレーションは既存の公開専用 Worker との後方互換性がありますが、新しい Worker は、すべてのアップロードで visibility、access_key_hash、access_key_version を書き込むため、古いスキーマとは互換性がありません。

0003 を適用する前に、既存の profiles.role = 'admin' の行を正式な管理者許可リストと照合し、想定外の行があればリセットしてください。このマイグレーションは、テーブル全体に対するブラウザーからの従来の UPDATE 権限を閉じ、セルフサービスでのプロフィール編集を display_name に制限します。ただし、すでに保存されている管理者ロールが正当なものかどうかは判定できません。

本番環境のマジックリンクを使用するには、Supabase Auth のサイト URL とリダイレクト許可リストに https://sharehtml.zhenjia.dev を追加してください。

Cloudflare Email Service フックと [email protected] の送信者設定に関する注意事項は、docs/email/auth-email-setup.md にあります。

デプロイ

本番環境は、share-html という名前の Cloudflare Worker として稼働します。デプロイ設定の正式な情報源は wrangler.jsonc です。このファイルでは、Worker のエントリーポイント、静的アセット、カスタムドメイン、R2 バケットのバインディング、公開ランタイム変数を定義しています。

デプロイは GitHub のブランチ保護によって制御され、Cloudflare Workers Builds によって実行されます。

  • プルリクエストでは、npm ci、npm run build、npx wrangler deploy --dry-run を実行します。
  • main ブランチでは、変更をマージする前に Build チェックの成功が必須です。
  • Cloudflare Workers Builds は main を監視し、そのブランチをビルドして、マージ後に Worker をデプロイします。

これにより、Cloudflare のデプロイ認証情報を GitHub に置かずに済みます。GitHub Actions に Cloudflare API トークンやデプロイフックのシークレットを設定する必要はありません。

Cloudflare Workers Builds の設定に関する注意事項は、docs/deploy/cloudflare-builds.md にあります。

ローカルマシンから手動でデプロイすることもできます。

npm run deploy

Worker は以下のように設定されています。

  • カスタムドメイン:sharehtml.zhenjia.dev
  • Worker のフォールバック:share-html.zhenjiazhou0127.workers.dev
  • R2 バケット:share-html-prod

/robots.txt の正式な情報源も Worker です。このホスト名では、Cloudflare のダッシュボードレベルの Managed robots.txt の挿入を無効にしてください。有効にすると、Cloudflare が Worker のレスポンスの前に、2つ目のワイルドカードグループと Content Signals ポリシーを追加します。

セキュリティに関する注意事項

アップロードされた HTML はサニタイズされません。代わりに隔離されます。

  • プレビューページは、専用の /v/:slug/ ルートを通じて配信されます。
  • 共有ページでは、iframe サンドボックス内にプレビューが埋め込まれます。
  • R2 オブジェクトは非公開で、Worker のみが読み取れます。
  • プレビューのレスポンスには、制限的なレスポンスヘッダーが適用されます。
  • レスポンスレベルの CSP sandbox では allow-same-origin が省略されるため、プレビューをトップレベルのタブで開いた場合も、アップロードされたスクリプトのオリジンは不透明なままです。
  • アップロードされたコンテンツを配信する前に、モデレーション状態が確認されます。
  • プライベートリンクのメタデータにアクセスするには、アクセスキー、所有者セッション、または有効なメタデータ許可が必要です。プレビューには、別途、短期間かつパススコープ付きの HttpOnly 許可が必要です。
  • プライベートアクセスキーは、ブラウザー間で受け渡すために共有 URL のフラグメントに含まれます。フラグメントは HTTP リクエストで送信されませんが、URL 全体を引き続き秘密情報として扱う必要があります。
  • Supabase RLS では、サーバー側のメタデータ書き込みに非公開の Worker シークレットヘッダーが必要です。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。