mcpField
S
Share HTML

Share HTML

远程服务
github.com/lifeodyssey文件与存储65 周前更新
代码仓库

关于 Share HTML

Share HTML 是托管在 Cloudflare 上的服务,可将独立 HTML 文件分享为沙盒预览。它适合需要快速页面链接的用户和 Agent,支持不公开索引的公开链接或访问密钥保护的私密链接,并扫描 HTML 风险。

主要功能

  1. 01上传单文件 HTML
  2. 02创建不公开索引或受保护链接
  3. 03在沙盒中预览 HTML
  4. 04扫描可疑 HTML 模式
  5. 05通过账户登录管理分享
  6. 06提供直接预览链接

适用场景

  1. 01无需搭建网站即可分享原型
  2. 02通过链接发送模型稿或小型演示
  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 部署前,请先应用分析迁移。启用服务后,浏览器分析默认开启,可在 Analytics 偏好设置中关闭;已有的退出选择、DNT/GPC 以及无法读取的偏好设置存储都会阻止数据收集。符合条件的浏览器事件会使用单独的 Share HTML GA4 媒体资源;增强型衡量功能已停用,私密分享页面不会发送 Google 事件。

Share HTML 徽标

上传一个 HTML 文件,即可将沙盒预览分享为未列出的公开链接或受访问密钥保护的私密链接。

线上网站 GitHub 上的源代码 CI Cloudflare Workers Supabase TypeScript

链接

项目文档

功能介绍

Share HTML 是一款由 Cloudflare 托管的轻量工具,用于分享独立 HTML 文件。它适合快速原型、模型图、收据、小型演示,以及无需搭建网站即可通过 URL 分享的一次性页面。

  • 匿名上传,文件在 365 天后过期。
  • 通过 Supabase 魔法链接登录,以保留和删除分享内容;身份验证邮件由 Cloudflare Email Service 发送。
  • 通过认领令牌,将匿名上传的内容关联到之后创建的账户。
  • 提供公开但不列出的链接,以及受访问密钥保护的私密链接两种可见性模式。
  • 分享页面显示状态、风险评分,并在完成私密链接所需的解锁后嵌入预览。
  • 提供直接预览 URL,可单独打开上传的 HTML。
  • 使用轻量扫描器检查可疑的 HTML 模式。
  • 提供报告 API 和管理员审核端点。

URL 模型

上传后,Share HTML 会有两个不同的 URL:

  • 分享 URL 会打开 /s/:slug 的封装页面。这是最适合发送的链接,因为其中包含状态、安全上下文、举报操作和嵌入式预览。
  • 预览 URL 会打开沙盒中的 HTML 渲染页面 /v/:slug/。对于私密链接,需要在解锁时创建的短期预览 Cookie。
  • 认领令牌 是私密信息。登录后,可将其与分享 ID 一起使用,把匿名上传转移到你的账户。

每次上传还会选择一种可见性:

  • 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 授权 Cookie:一个作用于 /v/:slug,用于预览;另一个作用于精确的解锁端点,以便浏览器从地址栏移除 #key 后,刷新页面仍可恢复元数据。对私密链接发起不带参数的 GET /api/public/shares/:slug 会返回 401,并附带 code: "share_access_required";密钥错误则会返回 403,并附带 code: "invalid_share_access_key"。切勿将密钥放入查询参数,也不要在日志、问题报告或公开内容中暴露完整的私密 URL。

已通过身份验证的所有者可以使用 POST /api/shares/:id/access-key 替换丢失或泄露的私密密钥。轮换操作只会返回一次新密钥,并立即使基于旧密钥签发的元数据和预览授权失效。

Agent 访问

Share HTML 旨在让 AI Agent 能够发现并使用,而不仅仅是供人类使用:

  • llms.txt — 便于 AI 阅读的站点指南(请求发送 Accept: text/markdown 时,也会从 / 提供)。
  • openapi.json — 机器可读的 HTTP API 描述,包含两种可见性模式,以及私有解锁/Cookie 流程。首页 HTML 还嵌入了静态内容和 JSON-LD,让非 JS Agent 能够了解该站点的用途及调用方式。
  • MCP 机器端点 — https://share-html.zhenjiazhou0127.workers.dev/mcp 提供 describe_share_html、get_public_share 和 create_share。它使用与品牌站点相同的生产环境 Worker,同时避免区域级浏览器机器人策略影响机器间流量。页面也通过 WebMCP(navigator.modelContext)在浏览器中提供相同的工具。
  • /a2a — A2A 1.0 JSON-RPC 端点,已实现 describe_share_html 技能;其卡片有意只声明这一项可执行的 A2A 功能。
  • WebMCP create_share 允许 Agent 选择 public_unlisted 或 private_link;access_private_share 可用访问密钥换取元数据,以及受限范围的元数据和预览授权。两者都通过常规 HTTP API 运行。
  • MCP create_share 同时支持 public_unlisted 和 private_link。它与网页上传共用相同的匿名速率限制和风险扫描器——不存在绕过路径,且私有内容创建后密钥只会返回一次。
  • 发现文件:robots.txt(包含明确的 AI 机器人规则)、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/ 路径会返回 404,而不是 SPA 外壳。

第一方首页和发现文档允许被搜索引擎索引,也允许作为 AI 实时输入,同时通过响应级 Content-Signal 禁止用于 AI 训练。用户提供的分享元数据和预览会发送限制更严格的 search=no, ai-input=no, ai-train=no, use=immediate,设置为 noindex,且绝不会出现在站点地图中。这种响应级区分可确保第一方 GEO 权限不会应用于同一主机上上传的内容。

获客循环

产品现在有四个可供抓取的第一方入口页面,而不再只依赖发现文件:

  • /html-preview 说明单文件预览的边界,并包含上传 CTA。
  • /private-html-sharing 说明访问密钥隐私及其限制。
  • /examples 提供三个可独立使用的文件,可预先加载到上传器中。
  • /agents 提供可用的 MCP、HTTP、OpenAPI、WebMCP、Skill 和 A2A 入口。

只有这些页面和主页会提交到 sitemap.xml。上传后的 /s/:slug 和 /v/:slug/ URL 仍设为 noindex,并从所有发现提交中排除。包装页面包含醒目的“分享你的 HTML” CTA;其 source=shared_preview 值只与 visibility 一起存储在现有的 created 事件元数据中,因此无需新增跟踪服务即可衡量产品驱动的激活效果。

官方 MCP Registry 的规范身份为 dev.zhenjia/share-html,通过发布在 zhenjia.dev DNS 中的 Ed25519 公钥进行身份验证。其描述文件为 server.json,主页链接会将 Agent 指向 /agents 上的实时集成指南。远程服务本身仍使用生产环境的 workers.dev 机器端点;面向用户的页面和规范 URL 则保留在 sharehtml.zhenjia.dev。这种拆分可防止品牌域名上的 Free 计划 Bot Fight Mode 拒绝合法的数据中心 MCP 客户端。

手动执行的 Publish MCP Registry metadata 工作流会验证实时清单和 MCP 工具列表,使用 production Environment 密钥 MCP_REGISTRY_PRIVATE_KEY 发布品牌身份,验证精确的 Registry 投影,然后才将旧的 io.github.lifeodyssey/share-html 身份标记为已弃用并附上迁移消息。目前无法取消发布 Registry 版本,因此该工作流特意设计为幂等,并要求在生产端点部署并验证后输入 publish-dev-zhenjia。切勿将 DNS 身份验证私钥放入代码库、Worker 配置、日志或工作流制品中。

IndexNow 使用明确的第一方允许列表,而不使用 Cloudflare Crawler Hints,因为此主机名也会提供私有和未列出的 URL:

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。

技术栈

  • 使用 Cloudflare Workers Static Assets 提供应用外壳和 API。
  • 使用 Cloudflare R2 存储上传的 HTML 对象。
  • 使用 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,但无法判断已存储的管理员角色是否合法。

对于生产环境中的 magic link,请将 https://sharehtml.zhenjia.dev 添加到 Supabase Auth 的站点 URL 和重定向允许列表。

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
  • Workers 后备域名:share-html.zhenjiazhou0127.workers.dev
  • R2 存储桶:share-html-prod

Worker 也是 /robots.txt 的权威来源。请为此主机名禁用 Cloudflare 控制面板级别的 Managed robots.txt 注入;否则 Cloudflare 会在 Worker 响应前添加第二个通配符组和 Content Signals 策略。

安全说明

上传的 HTML 不会经过净化处理,而是通过隔离来保护:

  • 预览页面通过专用的 /v/:slug/ 路由进行流式传输。
  • 分享页面会在 iframe 沙箱中嵌入预览。
  • R2 对象为私有对象,只有 Worker 可以读取。
  • 预览响应会应用限制性响应标头。
  • 响应级 CSP sandbox 不包含 allow-same-origin,因此即使有人在顶层标签页中打开预览,上传的脚本仍会保留不透明源。
  • 在流式传输上传内容之前,会检查审核状态。
  • 私有链接元数据需要访问密钥、所有者会话或仍然有效的元数据授权;预览则需要单独的、短时有效且限定路径的 HttpOnly 授权。
  • 私有访问密钥通过分享 URL 片段传递,以便在浏览器间交接;片段不会随 HTTP 请求发送,但完整 URL 仍须作为机密处理。
  • Supabase RLS 要求服务器端元数据写入请求携带私有 Worker 密钥标头。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。