关于 loopback
loopback 是面向编码 Agent 的反馈队列,可将应用页面上的问题固定到具体元素,并收集请求、控制台和 AI 运行上下文。Claude Code、Codex 和 Gemini CLI 可通过同一 MCP 队列领取反馈,修复验证后页面标记会变绿。
主要功能
- 01页面元素反馈标记
- 02自动收集请求与控制台上下文
- 03项目分类的共享反馈队列
- 04查看状态、评论和附件
- 05修复验证后更新标记
适用场景
- 01记录本地应用中的界面或流程问题
- 02将失败请求及响应信息交给编码 Agent
- 03集中处理多个项目的反馈
- 04通过脚本或 CI 提交反馈
MCP 相关
loopback 提供 MCP 服务,让 Claude Code、Codex 和 Gemini CLI 使用相同工具处理共享队列。可通过 stdio 启动,也可连接运行中的 HTTP 服务。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
10收录的工具列表 · 更新于 3 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| url | string | 否 | 观察到问题的完整 URL。 |
| body | string | 否 | 反馈/观察的完整描述 |
| type | enum | 是 | 反馈维度:'ui'(视觉/设计)、'backend'(错误/API)、'usage'(分析/行为)、'ux'(流程/体验)ui | backend | usage | ux |
| extra | object | 否 | 自由格式的上下文对象:AI 功能的 LLM 运行 ID/模型/跟踪 URL、自动化运行元数据、视口、元素 HTML 片段等。 |
| route | string | 否 | 观察到问题时所在的应用路由,例如 '/checkout' |
| title | string | 是 | 简短摘要,例如 'Checkout button dead on mobile Safari' |
| source | enum | 否 | 此反馈的来源manual | widget | stagewise | sentry | posthog | jam | other |
| console | array | 否 | 与问题相关的近期控制台日志行 |
| network | array | 否 | 相关网络请求(url、method、status、ms) |
| project | string | 是 | 此反馈所属的项目/仓库 slug,例如 'appbroda-web' |
| reporter | enum | 否 | 报告者human | agent | system |
| severity | enum | 否 | p0=严重,p1=高,p2=普通,p3=锦上添花p0 | p1 | p2 | p3 |
| replay_url | string | 否 | 会话回放链接(例如 PostHog 回放 URL) |
| repro_steps | array | 否 | 复现步骤 |
| dom_selector | string | 否 | 受影响元素的 CSS 选择器 |
| screenshot_path | string | 否 | 截图的路径或 URL |
详细介绍
Loopback
在你正在构建的应用上固定反馈。任何编码 Agent 都可以认领。修复验证通过后,标记会变绿。
Loopback 是真实产品使用与编码 Agent 之间的交互式反馈层:只需添加一个脚本标签,就能让你在本地运行的应用支持评论(类似 Vercel 工具栏的工具栏,固定在元素上的标记;已部署的公开网站则通过 /ingest 通道接入——参见界面兼容性)。每个标记都会自动捕获功能性上下文——失败的请求及其响应正文、控制台记录、此前的路由轨迹、LLM 运行元数据、输入的复现步骤——并汇入一个按项目标记的队列,供 Claude
Code、Codex 和 Gemini CLI 通过 MCP 共同处理。Agent 的修复通过验证后,页面上的标记会实时变绿。
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)中标记projectslug。每台机器只需注册一次 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/:
| Agent | MCP 注册 | 指引/技能渠道 |
|---|---|---|
| Claude Code | claude 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 分钟)
- 确保中央实例正在运行(每台机器只需设置一次):运行
loopback-mcp-server --http,并按照 keep-alive.md 保持其运行。 - 将组件标签粘贴到应用中,并填入你的 slug
(模板):
<script src="http://127.0.0.1:7077/widget.js" data-project="my-app" data-endpoint="http://127.0.0.1:7077"></script> - 在代码仓库根目录中:
一份标准操作手册 (integrations/instructions-src.md) 会转换为每个 Agent 的原生机制:AGENTS.md 中的队列部分(标准版本;Codex 和 Gemini 原生读取它)、CLAUDE.md 和 GEMINI.md 中的npx loopback-mcp-server init --project my-app --write@AGENTS.md导入、为 Claude(.claude/skills/)和 Codex(.agents/skills/)安装的同一份 SKILL.md、为三者注册 MCP(.mcp.json、.gemini/settings.json、.codex/config.toml),以及 Gemini 的/loopback命令。合并不会破坏现有内容,且具有幂等性——可以随时重新运行。 - 在任意一个 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 是它自己的参考集成——它以身作则,你也可以。以下是四种提交方式,按便捷程度从高到低排列:
- 在队列页面置顶。 Hub 运行后,打开
http://127.0.0.1:7077/queue——捕获组件已嵌入其中,并带有data-project=loopback。点击 ✦ Loopback → Pin feedback on an element, 点击有问题的地方并描述问题。流程与其他项目相同。 - 告诉 Agent。 在此仓库中(已通过其自身的
init完成自助接入),说 "file feedback for loopback: <what's wrong>"——技能和 AGENTS.md 章节已为 Claude、Codex 和 Gemini 安装完毕。 - 从任何地方使用
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"}' - 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_status | open → 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.json | mcpName | io.github.joshidikshant/loopback |
server.json | name | io.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/(原始规范、构建还是借用的备忘录、交互层分析、技术路线)。本次构建中的决策:
- 使用
node:sqlite,绝不使用 better-sqlite3 — 在干净环境中原生构建会失败;零原生依赖才是这项功能的意义所在。 - 仅支持 stdio + 无状态的可流式 HTTP,不支持 SSE — 这是 Claude Code、Codex 和 Gemini CLI 共同支持的传输方式(SSE 在 Claude Code 中已弃用,Codex 中则不存在)。
- AGENTS.md 是权威来源 — Codex 和 Gemini 原生读取它;Claude 通过
@AGENTS.md导入(出于 Windows 安全考虑,导入优于符号链接)。同一份操作手册会渲染为每种 Agent 的原生机制;没有哪个 Agent 是“默认选项”。 - Codex 使用项目级
.codex/config.toml— 已确认支持(信任此仓库后即可加载);init也会打印全局配置块。 - 如果服务端位于待接入的仓库内,
init会写入相对于仓库的路径;其他情况则写入npx loopback-mcp-server— 提交的配置必须在每个克隆版本中都能正常工作;机器上的路径只在一台机器上有效。(最初采用稳定检出版本使用绝对路径、临时运行使用npx github:的方案——npm 上架该软件包后,这两种方案都已弃用。) /ingest接受未知的额外字段(不使用.strict())— 较旧的枢纽不得拒绝较新的小组件;在数据接收边界,向前兼容比严格校验更重要。- 小组件为 58KB / gzip 压缩后 19KB,而不是草案中的约 10KB — 环形缓冲区、失败响应正文捕获、实时固定项、复现步骤、路由历程和交互演示都值得占用这些字节;它仍然零依赖、仅一个文件,并以预压缩形式提供,带有 ETag。
- 基于标记进行合并 —
init重复运行时字节级保持幂等;已由人工接管的文件(移除了生成标记)不会被改动。 - 在注明出处的前提下改编交互模式(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
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。