mcpField
L
loopback

loopback

本地服务
github.com开发工具013 周前更新

关于 loopback

loopback 是面向编码 Agent 的反馈队列,可将应用页面上的问题固定到具体元素,并收集请求、控制台和 AI 运行上下文。Claude Code、Codex 和 Gemini CLI 可通过同一 MCP 队列领取反馈,修复验证后页面标记会变绿。

主要功能

  1. 01页面元素反馈标记
  2. 02自动收集请求与控制台上下文
  3. 03项目分类的共享反馈队列
  4. 04查看状态、评论和附件
  5. 05修复验证后更新标记

适用场景

  1. 01记录本地应用中的界面或流程问题
  2. 02将失败请求及响应信息交给编码 Agent
  3. 03集中处理多个项目的反馈
  4. 04通过脚本或 CI 提交反馈

MCP 相关

loopback 提供 MCP 服务,让 Claude Code、Codex 和 Gemini CLI 使用相同工具处理共享队列。可通过 stdio 启动,也可连接运行中的 HTTP 服务。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"joshidikshant-loopback": {
"command": "npx",
"args": [
"-y",
"loopback-mcp-server"
]
}
}
}
启动命令npx -y loopback-mcp-server

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmloopback-mcp-server0.9.4

工具

10

收录的工具列表 · 更新于 3 周前

参数类型必填说明
urlstring否观察到问题的完整 URL。
bodystring否反馈/观察的完整描述
typeenum是反馈维度:'ui'(视觉/设计)、'backend'(错误/API)、'usage'(分析/行为)、'ux'(流程/体验)ui | backend | usage | ux
extraobject否自由格式的上下文对象:AI 功能的 LLM 运行 ID/模型/跟踪 URL、自动化运行元数据、视口、元素 HTML 片段等。
routestring否观察到问题时所在的应用路由,例如 '/checkout'
titlestring是简短摘要,例如 'Checkout button dead on mobile Safari'
sourceenum否此反馈的来源manual | widget | stagewise | sentry | posthog | jam | other
consolearray否与问题相关的近期控制台日志行
networkarray否相关网络请求(url、method、status、ms)
projectstring是此反馈所属的项目/仓库 slug,例如 'appbroda-web'
reporterenum否报告者human | agent | system
severityenum否p0=严重,p1=高,p2=普通,p3=锦上添花p0 | p1 | p2 | p3
replay_urlstring否会话回放链接(例如 PostHog 回放 URL)
repro_stepsarray否复现步骤
dom_selectorstring否受影响元素的 CSS 选择器
screenshot_pathstring否截图的路径或 URL

详细介绍

Loopback

在你正在构建的应用上固定反馈。任何编码 Agent 都可以认领。修复验证通过后,标记会变绿。

Loopback 是真实产品使用与编码 Agent 之间的交互式反馈层:只需添加一个脚本标签,就能让你在本地运行的应用支持评论(类似 Vercel 工具栏的工具栏,固定在元素上的标记;已部署的公开网站则通过 /ingest 通道接入——参见界面兼容性)。每个标记都会自动捕获功能性上下文——失败的请求及其响应正文、控制台记录、此前的路由轨迹、LLM 运行元数据、输入的复现步骤——并汇入一个按项目标记的队列,供 Claude Code、Codex 和 Gemini CLI 通过 MCP 共同处理。Agent 的修复通过验证后,页面上的标记会实时变绿。

CI npm node License: MIT

https://github.com/user-attachments/assets/1e1b2f9f-0130-4b1d-a0dd-3aff8d801d5a

![闭环流程:表单上的绿色已验证标记由 claude-code 修复(已关联 PR),AI 回答上有一个琥珀色未处理标记,Loopback 面板列出了这两项]

预置的演示捕获(由 scripts/screenshot.mjs 生成):联系表单的后端错误已固定,已由 claude-code 认领,标记为已修复并关联变更,且已验证——标记和徽章均为绿色。错误的 AI 回答仍为琥珀色/未处理状态。

为什么

编码 Agent 可以修复任何你能描述的问题——但真实使用情况反馈回来的闭环一直缺失。你发现某个流程坏了,截张图,在提示词里重新描述,粘贴控制台输出,再解释它属于哪个项目。每个 Agent 都要重复这一套流程。Vercel 的评论没有公开 API;Claude Design 的锚定评论仅限于特定工件;错误跟踪工具不了解你的队列。

Loopback 补上了这个缺失的环节,并将其构建为一个中枢:

  • 一个实例,支持所有项目。 每项内容都会在一个共享的 SQLite 数据库(~/.loopback/loopback.db)中标记 project slug。每台机器只需注册一次 Agent;接入的代码仓库只需添加一个 widget 标签和一个 slug。
  • 一个队列,支持所有 Agent。 MCP 是交互接口,因此 Claude Code、Codex 和 Gemini CLI 是平等的参与者——使用相同的工具、相同的操作手册和相同的审计记录。
  • 标记是锚点,而非作用范围。 为“损坏的”联系表单添加标记,Agent 就能获取失败的 POST 请求及其 500 响应正文——前端标记也能携带后端根本原因。为 AI 回答添加标记,运行元数据(run_id、model、trace_url)也会随之附上。
            CAPTURE                          THE HUB                            AGENTS
 ┌───────────────────────────┐   ┌─────────────────────────────┐   ┌─────────────────────────┐
 │ widget pin on any app     │──►│  loopback-mcp-server        │◄──│ Claude Code             │
 │  · console + network ride │   │   one shared SQLite DB      │   │ Codex          (peers)  │
 │  · 500 bodies captured    │   │   ~/.loopback/loopback.db   │   │ Gemini CLI              │
 │  · AI run context         │   │                             │   └────────────┬────────────┘
 ├───────────────────────────┤   │  stdio (per-agent spawn)    │                │
 │ POST /ingest              │──►│  --http on 127.0.0.1:7077   │     list → claim → fix →
 │  · CI hooks, cron,        │   │   (required for widgets)    │     link change → fixed →
 │    Sentry/PostHog pollers │   │                             │     verify → resolve
 └───────────────────────────┘   └──────────────┬──────────────┘                │
                                                │                               │
              pins turn green on the page ◄─────┴───── status write-back ◄──────┘

每次调用时,都可以通过 stdio 运行(由各个 Agent 启动;使用相同数据库即共享相同队列),也可以作为一个持续运行的 --http 服务运行在 127.0.0.1:7077(widget 必须使用此方式——通过 pm2/launchd/systemd 保持服务运行: integrations/keep-alive.md)。

快速开始(2 分钟体验完整闭环)

需要 Node ≥ 22.13(内置 node:sqlite——无需原生依赖)。

git clone https://github.com/joshidikshant/loopback && cd loopback
npm install                    # prepare script builds dist/
node dist/index.js --http      # the hub, on 127.0.0.1:7077
node demo/serve.mjs            # demo app on 127.0.0.1:5173 (broken backend + wrong AI answer)

打开 http://127.0.0.1:5173 → 提交表单(会友好地提示失败)→ ✦ Loopback → 在元素上固定反馈 → 点击提交按钮 → 发送。表单会显示捕获到的失败请求。然后告诉任意已连接的 Agent:“处理 acme-demo 的反馈队列”——或者在 http://127.0.0.1:7077/queue 查看该项,自己通过 MCP 扮演 Agent。问题解决后,当前打开的页面会通知你,标记也会变绿。

每台机器只需安装一次

每个 Agent 只需注册一次 MCP 服务和指引;之后,新项目只需两分钟即可完成 init。可直接复制粘贴的版本——Claude Code(在项目中使用 .mcp.json,或为所有项目配置 ~/.claude.json):

{
  "mcpServers": {
    "loopback": {
      "command": "npx",
      "args": ["-y", "loopback-mcp-server"]
    }
  }
}

Codex 和 Gemini CLI 在各自的配置中使用相同的 command/args——该服务通过 stdio 使用相同的二进制文件。三者地位相同——各 Agent 的完整配置页面见 integrations/:

AgentMCP 注册指引/技能渠道
Claude Codeclaude mcp add --scope user loopback -- npx -y loopback-mcp-server — 或使用插件:claude plugin marketplace add joshidikshant/loopback && claude plugin install loopback@loopback在 CLAUDE.md 中通过 @AGENTS.md 导入,并在 .claude/skills/loopback/ 中添加技能 → claude.md
Codex~/.codex/config.toml:[mcp_servers.loopback] command/args(或使用项目范围的 .codex/config.toml)原生读取 AGENTS.md,并在 .agents/skills/loopback/ 中使用原生 SKILL.md → codex.md
Gemini CLI~/.gemini/settings.json → mcpServers.loopback通过 context.fileName 使用 AGENTS.md,在 GEMINI.md 中通过 @AGENTS.md 导入,并添加 /loopback 命令 → gemini.md

三者也都支持通过可流式传输的 HTTP 使用长期运行的实例(http://127.0.0.1:7077/mcp),而无需启动进程——详见各 Agent 的配置页面。

集成新项目(2 分钟)

  1. 确保中央实例正在运行(每台机器只需设置一次):运行 loopback-mcp-server --http,并按照 keep-alive.md 保持其运行。
  2. 将组件标签粘贴到应用中,并填入你的 slug (模板):
    <script src="http://127.0.0.1:7077/widget.js"
            data-project="my-app" data-endpoint="http://127.0.0.1:7077"></script>
    
  3. 在代码仓库根目录中:
    npx loopback-mcp-server init --project my-app --write
    
    一份标准操作手册 (integrations/instructions-src.md) 会转换为每个 Agent 的原生机制:AGENTS.md 中的队列部分(标准版本;Codex 和 Gemini 原生读取它)、CLAUDE.md 和 GEMINI.md 中的 @AGENTS.md 导入、为 Claude(.claude/skills/)和 Codex(.agents/skills/)安装的同一份 SKILL.md、为三者注册 MCP(.mcp.json、.gemini/settings.json、.codex/config.toml),以及 Gemini 的 /loopback 命令。合并不会破坏现有内容,且具有幂等性——可以随时重新运行。
  4. 在任意一个 Agent 中说: “处理 my-app 的反馈队列”——也可以什么都不说:技能描述和 AGENTS.md 部分会让与反馈相关的请求自动触发这一流程。

日常使用

Hub 运行时(loopback-mcp-server --http),所有操作只需通过两个界面,以及对 Agent 说一句话:

我想要……操作
在页面上报告问题点击**✦ Loopback → 在元素上标记反馈**,再点击目标并描述问题。失败的请求、控制台信息和 AI 运行上下文会自动附加。
查看队列http://127.0.0.1:7077/queue — 使用 ?project=<slug> 筛选,点击一行即可快速查看
查看某个条目的全部内容点击其 ID → http://127.0.0.1:7077/queue/<id>。支持深层链接:可将链接发给队友或 Agent。
自行评论或更改状态在条目页面中操作——使用普通表单,无需 Agent
修复问题在代码仓库中告诉任意 Agent:“处理 <slug> 的反馈队列”
查看问题是否已关闭页面上的标记会变绿并显示提示;条目会显示提交记录/PR
通过脚本或 CI 提交使用 {"project","type","title","body"} 调用 POST /ingest

会更改条目的写入操作(评论、状态)仅限同源请求——见下文的安全部分。

提交关于 Loopback 的反馈

Loopback 是它自己的参考集成——它以身作则,你也可以。以下是四种提交方式,按便捷程度从高到低排列:

  1. 在队列页面置顶。 Hub 运行后,打开 http://127.0.0.1:7077/queue——捕获组件已嵌入其中,并带有 data-project=loopback。点击 ✦ Loopback → Pin feedback on an element, 点击有问题的地方并描述问题。流程与其他项目相同。
  2. 告诉 Agent。 在此仓库中(已通过其自身的 init 完成自助接入),说 "file feedback for loopback: <what's wrong>"——技能和 AGENTS.md 章节已为 Claude、Codex 和 Gemini 安装完毕。
  3. 从任何地方使用 curl:
    curl -X POST http://127.0.0.1:7077/ingest -H 'Content-Type: application/json' \
      -d '{"project":"loopback","type":"ux","severity":"p2",
           "title":"…","body":"what happened / what you expected"}'
    
  4. GitHub issues,用于提交陌生人也应该看到的问题: https://github.com/joshidikshant/loopback/issues。

然后像处理任何队列一样处理它:“处理 loopback 的反馈队列”。此仓库历史 中的每个 Loopback 缺陷都完全通过这种方式提交并关闭。

仪表板

/queue 是一个 React + shadcn 应用(dashboard/,通过真正的 shadcn CLI 构建)。点击状态卡片或任意项目/严重程度/类型单元格进行筛选—— 筛选条件可以组合,并保存在 URL 中,因此每个视图都可以分享链接。打开条目后,可以 查看捕获的所有内容、编辑它(标题、正文、严重程度、类型——每项更改 都会记录在审计日志中)、评论、更改状态,以及附加文件。

附件会声明其存在的用途,因为这决定了 Agent 会如何处理:

用途含义
reference修复上下文——截图、规格说明,或“让它看起来像这样”。阅读后保留原样。它不会随产品发布。
asset交付物。Blob 存储是传输缓冲区:条目包含 target_path,Agent 会将文件复制到仓库中的该路径并提交。

Blob 存放在 ~/.loopback/blobs/<item>/ 中,与数据库并列而非存放在其中; Agent 会获得一个绝对本地路径,这样它们就会复制文件,而不是从协议中 解码文件。

构建输出已提交到 public/dashboard/,因此 npx loopback-mcp-server 仍然不需要 React、Tailwind 或构建步骤—— Hub 只需提供文件。修改 dashboard/src 后运行 npm run dashboard:build; 如果已提交的构建产物不一致,dashboard-gate 会使 CI 失败。

设计系统(兼容 shadcn,无依赖)

两个界面——组件和 /queue——都由一套原生 CSS 令牌构建,遵循 shadcn/ui 的约定(oklch 变量、.dark、乘法式圆角比例)。无需 React、Tailwind 或构建步骤; 将 design/tokens.css 放入任意 shadcn/v0 项目,即可使用该项目的调色板进行主题化。 完整设计依据和 Shadow DOM 隔离规则见: design/README.md。

Loopback 还会发布 shadcn 注册表,因此 React 项目可以安装其中的组件, shadcn MCP 也可以发现它们:

npx shadcn@latest add https://raw.githubusercontent.com/joshidikshant/loopback/main/public/r/loopback-theme.json
npx shadcn@latest add https://raw.githubusercontent.com/joshidikshant/loopback/main/public/r/loopback-components.json
npx shadcn@latest add https://raw.githubusercontent.com/joshidikshant/loopback/main/public/r/loopback-widget.json

包含三个项目:

  • loopback-theme 提供完整的 shadcn 主题约定(background、 foreground、primary、muted、ring、radius……),以及 --lb-* 反馈 状态/严重程度令牌,因此安装它会替换你的调色板。如果你只想要 Loopback 专用的令牌, 可以改为从 design/tokens.css 中复制 --lb-* 代码块。
  • loopback-components——面向 shadcn 组件词汇(lb-btn、lb-badge、lb-card……)的原生 CSS 配方, 适用于想要这种外观但不使用 React 的界面。
  • loopback-widget 将捕获组件放入 public/。

在 components.json 中注册 "@loopback",即可按名称安装,并让使用 shadcn MCP 的 Agent 浏览注册表。

适用场景(界面)

队列与传输方式无关——小组件只是功能最丰富的数据生产端。 完整矩阵、原生代码片段(Swift/Kotlin/C#/shell)以及实际限制: docs/05-surface-compatibility.md。

界面状态
本地开发中的 Web 应用(任意框架)· 浏览器扩展(打包小组件文件——MV3 禁止远程脚本)· Electron/Tauri · WebView✅ 小组件:固定标记 + 自动上下文 + 绿色回写
已部署的公开网站✖ Chrome 142+ 会阻止公开页面访问 127.0.0.1。请改用 Sentry/PostHog 通道。
原生 macOS/Windows 应用 · CLI · CI/cron · Agent/自动化✅ POST /ingest 或 MCP(约 10 行的调试菜单代码片段;通过 /queue 查看状态)
iOS/Android 模拟器✅ 共享 loopback / adb reverse
局域网上的 iOS/Android 实体设备✅ --host 0.0.0.0(选择启用;会打印 bearer token——仅限可信网络)
iOS/Android 生产环境✅ 通过 Sentry/PostHog 通道(其 SDK 会采集数据;再桥接到队列)

小组件

约 58KB(gzip 压缩后 19KB)的无依赖原生 JavaScript,运行在 Shadow DOM 容器中——不会与 应用的 CSS 或框架冲突。

  • 采集:标记模式下,悬停时会高亮元素;点击后会打开一个限制在视口范围内的表单(标题 / 发生了什么 / 预期结果 / 类型 / 严重性)。类型会预先猜测:存在失败请求时为 backend, 存在 AI 上下文时为 usage。
  • 功能上下文,始终开启:从页面加载开始使用环形缓冲区,保留最近 30 条控制台日志(log/warn/error + window 错误 + 未处理的拒绝)和最近 30 次 fetch/XHR 调用(url/method/status/ms);提交的报告会携带最新的 每类 15 条,此外,对于失败请求(status ≥ 400 或网络错误),还会将最多 2KB 的响应正文写入 extra.failed_responses。 对 Loopback 本身的调用永远不会被记录。
  • AI/自动化上下文:会解析最近祖先节点中 data-loopback-context='{"run_id":...}' 的值,并写入 extra.context。
  • 选择器 + 元素:稳定的 CSS 选择器(优先使用 #id / [data-testid] ,否则回退到 nth-of-type,并限制深度)+ outerHTML 片段 + 视口 + UA。
  • 适配 SPA:客户端路由变化(pushState/popstate)会立即刷新固定标记,不会残留上一条路由的标记。
  • 实时状态标记:加载时以及每隔 10 秒从 GET /feedback 获取数据并更新——琥珀色 open,较深的琥珀色 triaged,蓝色 in_progress,浅绿色 fixed(Agent 表示已完成),完整绿色 verified(已在运行中的应用中确认),灰色 wontfix。两种绿色刻意区分:标记只有到 verified 才会呈现完整色彩,这正是关键,因此 fixed 看起来仍是暂定状态。点击标记可查看 id/status/assignee/PR。
  • 闭环清晰可见:打开的页面中状态发生变化时,小组件会发出提示——toast(“…… open → verified by claude-code · PR linked”)、标记脉动;如果你正在查看其他标签页,还会闪烁 🔔 标签页标题(改编自 make-pages-interactive 的重新加载演示,MIT)。
  • 页面 API:window.__loopback = { pins, refresh(), project, endpoint, version }(改编自 DOM-Review 的 __domReviewAPI,MIT)——供 E2E 测试套件使用,也可供任何控制浏览器的 Agent 使用。

MCP 总线 — 10 个工具

工具功能
loopback_submit_feedback提交一条反馈:项目、类型 ui|backend|usage|ux、严重程度 p0–p3、route/url/selector、console[]、network[]、repro[]、extra(运行上下文……)
loopback_list_feedback筛选(项目/route/status/type/severity/source/assignee)并分页(total/has_more/next_offset);按严重程度排序,同级按最新优先
loopback_get_feedback完整条目:所有上下文 + 关联变更 + 评论记录
loopback_update_feedback提交后更正条目:标题、正文、严重程度、类型、项目或 route — 重新评定严重程度、修正猜错的类型,或将其移至正确的项目
loopback_claim_feedback原子性认领;冲突时会指出当前持有人;使用 force 接管;open/triaged → in_progress
loopback_update_statusopen → triaged → in_progress → fixed → verified | wontfix;备注会成为审计评论
loopback_add_comment根因记录、问题、推理过程记录
loopback_link_change将 repo/branch/commit/pr_url/diff_summary 合并到条目中
loopback_resolve_feedback以 verified(已实际确认)或 wontfix 关闭
loopback_get_stats按项目 × 状态统计

响应为 Markdown(默认)或通过 response_format 指定的 JSON,始终包含 structuredContent;长输出会在 25k 个字符处截断,并提供指引。

HTTP 接口(--http,端口 7077 / LOOPBACK_HTTP_PORT / --port)

端点用途
POST /mcp无状态 MCP 可流式传输 HTTP(每个请求都会新建服务;GET/DELETE → 405)
POST /ingest提交纯 JSON — 供组件、CI 钩子、cron 采集器使用(201 + 条目;字段级问题返回 400)
GET /feedback列出/筛选(填充组件图钉数据)
GET /queue/:id完整条目视图 — 包含所有捕获的上下文和评论/状态操作
POST /queue/:id/comment · POST /queue/:id/status人工分诊写入(仅限同源)
GET /feedback/:id以 JSON 返回单个条目及其完整记录
POST /feedback/:id/attachments为条目附加截图或资源(name/intent/target 作为查询参数,请求体为字节数据)
GET /blob/:id/:attachmentId获取一个附件的字节数据
DELETE /feedback/:id/attachments/:attachmentId移除一个附件
GET /widget.js可嵌入的组件
GET /health存活状态

安全性:信任边界并非“localhost” — 回环端口可从浏览器中打开的每个页面访问。因此:

  • 仅对 POST /ingest、GET /feedback 和 GET /widget.js 开放 CORS — 这三项是组件从外部来源实际需要的功能。
  • 跨源读取会返回图钉投影(id、status、title、assignee、 selector、PR 链接)。extra — 捕获的响应正文通常包含身份验证标头 — 绝不会跨源提供。
  • 所有读取完整上下文或更改状态的操作,包括 /mcp, 都要求来源已在启动时根据绑定配置固定。本地工具若不发送 Origin (curl、MCP 客户端)仍可使用。
  • 只有 URL 为 http(s) 时,条目中的 URL 才会呈现为链接 — 由仪表板中的 safeHref() 强制执行,该函数会解析 URL 并读取其协议。 data:、vbscript: 和 file: 会呈现为纯文本。

绑定非回环地址时必须使用令牌。 绑定到 127.0.0.1 时无需令牌 — 它无法保护操作系统原本就未保护的内容。只要 --host / LOOPBACK_HOST 扩大了绑定范围,服务就会生成令牌(或使用 LOOPBACK_TOKEN),并打印一个 ?token=… URL;令牌仅从查询字符串接受一次, 随后移入 HttpOnly cookie,并从 URL 中移除,因此不会留在历史记录或引荐来源中。工具发送 Authorization: Bearer <token>。比较操作基于摘要以恒定时间执行,因此 值或长度都不会通过计时信息泄露。

在 LAN 绑定下,以下四个端点会有意保持开放:

开放端点原因
POST /ingest组件会在手机上运行,针对任意主机页面,且无处保存密钥。接收接口仅追加写入,并受速率限制(每个 IP 每分钟 60 次,超出则返回 429):LAN 调用方可以提交噪声数据,但不能读取或更改任何内容,也无法填满磁盘。
GET /widget.js任何人都能读取嵌入所提供脚本中的内容。
GET /feedback?view=pins绘制图钉并将一个图钉显示为绿色所需的最少内容。严格投影 — 不含正文、控制台、网络、复现步骤、评论或附件 — 仅包含页面上已可见的内容。
GET /health仅用于存活检查 — {ok, name, version}。无法要求保持连接的探测请求携带令牌。

其余所有内容 — 仪表板、完整读取、所有写入,以及公开全部十个工具的 /mcp — 都会拒绝未经身份验证的调用方,并返回 401。此划分会在 scripts/e2e.mjs 中双向断言,而 npm run canary 会证明禁用检查后该断言将失败。

这是受信任网络上的共享密钥,不能替代真正的身份验证。 在 LAN 之外暴露 Loopback 前,请将其置于反向代理之后。

发布到 MCP Registry

Loopback 包含了 官方 MCP Registry 用于证明软件包所有权的身份信息:

位置字段值
package.jsonmcpNameio.github.joshidikshant/loopback
server.jsonnameio.github.joshidikshant/loopback

Registry 会获取 已发布 的 npm 版本元数据,并要求 mcpName 与 server.json 中的 name 完全一致;基于 GitHub 的身份验证 还要求使用 io.github.<username>/ 前缀。server.json 保留在 仓库中,不会打包进 npm 压缩包——软件包只需包含 mcpName。

由于 npm 版本不可变,不匹配会浪费一个版本号,而不是提供重试机会。 因此,npm run smoke 会断言所有六个相关字段(三个版本号、名称对以及 npm 标识符),而 npm run canary 则会证明这些字段不一致时断言会失败。

要发布并提交:

npm publish --otp=<code>          # 2FA code from your authenticator
mcp-publisher validate            # checks server.json against the live registry
mcp-publisher login github        # opens a browser
mcp-publisher publish             # reads server.json
npm run verify:release            # proves all three channels from a clean dir

先运行 validate,再运行 publish——它会将清单与实际的 Registry 对照检查,不会消耗一次提交机会。之后运行 verify:release,并仔细阅读其输出:它会将已发布的压缩包安装到干净目录中,从中渲染 init,与结果进行真实的 MCP 通信,确认 Registry 列表解析到刚刚发布的版本,并在空目录中运行插件自身已注册的命令。上述每一步都曾发现源代码端检查无法发现的真实错误。description 最多为 100 个字符,超出后会被拒绝而非截断,因此 npm run smoke 也会在本地断言此限制。

测试

npm run build
npm run smoke            # real MCP client over stdio: 10 tools, full loop, atomic-claim conflict
npm run e2e              # Playwright: pin capture → 500-body & run-context assertions → agent over MCP-HTTP → green pins
npm run init-gate        # init renderings ×3 agents, byte-level idempotence, merge safety
npm run registry-gate    # the published shadcn registry still resolves and installs
npm run dashboard-gate   # the committed dashboard build matches dashboard/src
npm run impeccable-gate  # design anti-patterns in the shipped UI (canary-verified)
npm run widget-token-gate # the widget's inlined tokens still equal design/tokens.css
npm run a11y-gate        # contrast, target size, names, landmarks, motion — measured in a browser

CI 会在每次推送时运行所有测试(如有需要,可通过 LOOPBACK_E2E_CHROMIUM 指定浏览器二进制文件)。

其中几项测试专门用于防止因错误原因而通过,因为底层工具会默认放行:过时的仪表板构建可以正常提供服务,不会在任何地方报错;而 impeccable detect 在没有扫描到任何内容时也会以状态码 0 退出。因此,dashboard-gate 会重新构建并进行比较,而不是依赖修改时间;impeccable-gate 会扫描一个 必须 触发问题的金丝雀样例,只有确认它能触发问题后,才会接受扫描结果为空。

之所以设置 a11y-gate 和 widget-token-gate,是因为它们检查的两项内容——无障碍性和跨界面令牌一致性——都曾多次在没有提示的情况下退化。该小组件内嵌了自己的令牌副本(它以单文件形式发布,无法使用 @import 引入令牌),且此前已经出现偏差;components.css 将图钉颜色硬编码为近白色,在状态令牌变浅时便会出错。这里的每项检查都通过故意引入错误,验证了它的两种失败路径。

配套工具(借用,而非重造)

Loopback 有意只负责总线和采集层。将它与成熟的 MCP 原生组件配合使用——完整分析请参阅自建还是借用备忘录:

  • chrome-devtools-mcp / playwright-mcp——让 Agent 查看并验证 正在运行的应用(循环中的“验证”步骤)
  • Sentry MCP——生产环境错误(包括移动端)→ POST /ingest,并设置 source: "sentry"
  • PostHog MCP——分析/回放/调查 → 设置 source: "posthog",并附加 replay_url

设计决策

完整历史记录见 docs/(原始规范、构建还是借用的备忘录、交互层分析、技术路线)。本次构建中的决策:

  1. 使用 node:sqlite,绝不使用 better-sqlite3 — 在干净环境中原生构建会失败;零原生依赖才是这项功能的意义所在。
  2. 仅支持 stdio + 无状态的可流式 HTTP,不支持 SSE — 这是 Claude Code、Codex 和 Gemini CLI 共同支持的传输方式(SSE 在 Claude Code 中已弃用,Codex 中则不存在)。
  3. AGENTS.md 是权威来源 — Codex 和 Gemini 原生读取它;Claude 通过 @AGENTS.md 导入(出于 Windows 安全考虑,导入优于符号链接)。同一份操作手册会渲染为每种 Agent 的原生机制;没有哪个 Agent 是“默认选项”。
  4. Codex 使用项目级 .codex/config.toml — 已确认支持(信任此仓库后即可加载);init 也会打印全局配置块。
  5. 如果服务端位于待接入的仓库内,init 会写入相对于仓库的路径;其他情况则写入 npx loopback-mcp-server — 提交的配置必须在每个克隆版本中都能正常工作;机器上的路径只在一台机器上有效。(最初采用稳定检出版本使用绝对路径、临时运行使用 npx github: 的方案——npm 上架该软件包后,这两种方案都已弃用。)
  6. /ingest 接受未知的额外字段(不使用 .strict())— 较旧的枢纽不得拒绝较新的小组件;在数据接收边界,向前兼容比严格校验更重要。
  7. 小组件为 58KB / gzip 压缩后 19KB,而不是草案中的约 10KB — 环形缓冲区、失败响应正文捕获、实时固定项、复现步骤、路由历程和交互演示都值得占用这些字节;它仍然零依赖、仅一个文件,并以预压缩形式提供,带有 ETag。
  8. 基于标记进行合并 — init 重复运行时字节级保持幂等;已由人工接管的文件(移除了生成标记)不会被改动。
  9. 在注明出处的前提下改编交互模式(MIT): make-pages-interactive 的可见闭包交互演示;DOM-Review 的页面 API。

仓库结构

src/            the bus: server (10 tools) · store (node:sqlite) · http · init
widget/         loopback-widget.js — the embeddable capture layer
dashboard/      React + shadcn source for /queue (built output in public/dashboard)
demo/           intentionally broken playground app
design/         shared tokens.css — one design system for widget, dashboard, registry
public/         built dashboard + the published shadcn registry (public/r)
skills/         CANONICAL loopback SKILL.md — every other copy is rendered from it
integrations/   canonical playbook + per-agent setup + widget embed + keep-alive
plugin/         Claude Code plugin (skill + MCP registration); repo doubles as its marketplace
scripts/        e2e.mjs · the seven gates · canary-all.mjs · screenshot.mjs
                release-preflight.mjs (pre-publish) · release-verify.mjs (post-publish) · bump-version.mjs
docs/           the decision history (spec → memo → paths → technical path) + ROADMAP
assets/         the README screenshot (generated by scripts/screenshot.mjs)
.github/        ci.yml · canary.yml · readme-checks.yml · issue and PR templates
.impeccable/    design-detector config (the skill itself is not vendored — see .gitignore)

CONTRIBUTING.md how to run the gates, and why a new gate needs a canary case
SECURITY.md     the trust boundary, what is deliberately open, and what is out of scope
CHANGELOG.md    every release, with the reasoning that produced it

根目录中的两个清单用途不同:registry.json 用于发布 shadcn 组件,server.json 是 MCP Registry 条目(参见发布到 MCP Registry)。

根目录还包含由 init 自行写入的 Agent 配置——仓库会接入自身,因此这些配置是命令确实能生成其所声称内容的有效证明;init-gate 会在每次 CI 运行时重新渲染这些配置,以证明它们没有发生偏移:

AGENTS.md · CLAUDE.md · GEMINI.md   the queue playbook, per agent
.claude/ .agents/                   the loopback skill for Claude Code / Codex
.codex/ .gemini/                    per-agent MCP + command registration
.mcp.json                           MCP server registration for this repo

.claude-plugin/ 是根目录中唯一一个 init 不会写入的点目录:它是本仓库托管插件的市场清单,由人工维护,并通过 npm run bump 更新版本。init-gate 会断言其版本匹配,而不会重新渲染它。

MIT © Dikshant Joshi

评论

支持 Markdown

第一次接触 MCP?

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

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