mcpField
C
Context Keeper (remote)

Context Keeper (remote)

远程服务
github.com/jarmstrong158记忆与知识012 周前更新
代码仓库

关于 Context Keeper (remote)

Context Keeper (remote) 是运行于 Cloudflare Workers 的 MCP 服务,将项目决策、流程和约束存入 D1 并供查询。它通过 Streamable HTTP 接入 Claude 会话,还提供只读手机视图以浏览决策依据。

主要功能

  1. 01记录和查询项目上下文
  2. 02基于 D1 的决策依据存储
  3. 03只读移动端项目视图
  4. 04自动迁移数据库架构

适用场景

  1. 01在 Claude 会话中查阅项目决策
  2. 02通过手机查看决策依据和约束

MCP 相关

它通过 Streamable HTTP 暴露 `record_entry`、`get_context` 和 `query_entries` 等 context-keeper 工具。Claude 可通过自定义连接器接入。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://context-keeper-remote.{account}.workers.dev/mcp/{token}
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

详细介绍

context-keeper-remote

部署到 Cloudflare

xylem 技术栈的一部分。

一个运行在 Cloudflare Workers 上的远程 MCP 服务,通过 Streamable HTTP 提供 context-keeper 的决策存储(决策、流水线、约束)。它可用作 claude.ai 自定义连接器,也支持移动设备, 因此你可以在任何 Claude 会话中访问项目的决策和约束——无需让电脑保持运行,也无需隧道。

它还提供一个**手机应用**,供你自行查看该 存储:只需将它安装到主屏幕一次,之后打开即可使用,无需登录,URL 中也没有令牌。应用包含最近活动、各项目计数、cambium 知识和存储状态等标签页;点击任意条目即可查看完整的决策依据, 而不只是标题。此功能可选、需主动启用,并使用独立的只读凭据。

只需点击上方按钮,即可自托管一份副本——Cloudflare 会将此仓库复制到你的 GitHub 账户,为你新建一个 D1 数据库,并 部署 Worker。然后添加一个密钥,再将 URL 粘贴到 Claude 中。下方提供完整步骤;每一步都只需点击,无需使用命令行。

维护者自己的实例运行于 https://context-keeper-remote.jarmstrong158.workers.dev。部署后,你的实例将位于你自己的 子域名下。

为什么采用这种构建方式
  • 使用 Worker,而非隧道——无需依赖“电脑必须开机”。
  • 使用 D1,而非 KV——支持按行写入和 WHERE 查询;两个写入方(桌面端 + 移动端)不会像对整个 JSON 文件进行读取-修改-写入那样互相覆盖。
  • 无状态处理程序,不使用 Durable Objects——这些工具是针对 D1 的无状态 RPC,因此 Worker 可在 Cloudflare 免费计划上运行。
  • 密钥路径身份验证——claude.ai 自定义连接器无法可靠地发送自定义 bearer 标头,因此令牌是 URL 的最后一个路径段。URL 本身就是 凭据。
  • 自动迁移——Worker 会在运行时创建自己的 D1 架构,因此全新的空数据库无需手动运行 SQL(已通过冷启动测试验证)。

自托管(单击部署,无需命令行)

第 1 步——点击“部署到 Cloudflare”

点击本页面顶部的部署到 Cloudflare按钮。Cloudflare 将会:

  1. 请求你授权 GitHub 并选择一个账户——它会将此仓库复制到 你的 GitHub 账户(你将拥有自己的仓库)。
  2. 自动在你的 Cloudflare 账户中创建一个新的 D1 数据库,并将其绑定到 Worker。(之所以可行,是因为 Worker 的配置声明了数据库 绑定,但没有硬编码的 id,因此 Cloudflare 会为你创建一个全新的数据库。)
  3. 设置 Workers Builds,让你每次推送到新仓库时都能自动重新部署。
  4. 构建并部署 Worker。

部署完成后,你的 Worker 将运行在 https://context-keeper-remote.<your-subdomain>.workers.dev。记下这个 URL——第 3 步会用到。 (你也可以随时在控制面板的 Workers & Pages 下找到它。)

无需配置仓库,也无需运行 SQL——数据库初始为空,Worker 会在收到第一个请求时创建数据表。

步骤 2 — 添加 AUTH_TOKEN 密钥(Cloudflare 控制面板)

在设置身份验证令牌之前,Worker 会拒绝所有请求,因此请先设置一个:

  1. Cloudflare 控制面板 → Workers & Pages → 你的 context-keeper-remote Worker。
  2. Settings → Variables and Secrets → Add。
  3. 类型:Secret。名称:AUTH_TOKEN。值:一串较长的随机字符串(32 个字符以上 — 请像密码一样妥善保管)。保存/部署。

该值就是连接器的密码。请妥善保存;下一步需要粘贴它。

还要部署配套的 agentsync-remote Worker 吗?

agentsync-remote 使用相同的 AUTH_TOKEN 方案,并且还需要在 它的 Worker 的 Variables and Secrets 中设置:

  • 一个名为 GH_PAT 的 Secret — GitHub 个人访问令牌,以及
  • 一个名为 REPO 的 Variable — 设置为它应同步的 owner/repo。

这两项不适用于 context-keeper-remote(本仓库)——它只需要 AUTH_TOKEN。具体信息请参阅 agentsync-remote README。

步骤 3 — 在 claude.ai 中添加自定义连接器
  1. claude.ai → Settings → Connectors → Add custom connector。

  2. 粘贴 Worker URL,并将令牌作为最后一个路径段:

    https://context-keeper-remote.<your-subdomain>.workers.dev/mcp/<AUTH_TOKEN>
    

    将 <your-subdomain> 替换为你的 Worker 子域名(步骤 1),并将 <AUTH_TOKEN> 替换为你设置的准确值(步骤 2)。

  3. 保存。现在,你可以在 Claude 会话中使用这些工具(record_entry、get_context、query_entries……)。

**检查是否正常:**让 Claude 调用 get_project_summary。如果它能给出回答,说明整条链路(部署 → 自动配置 D1 → 自动迁移 → 身份验证)均正常运行。

步骤 4 — 迁移现有本地数据(可选)

如果你已经在运行本地版 context-keeper,请在启用连接器的情况下,让 Claude 调用 import_entries,并粘贴每个文件的内容:

  • decisions.json → import_entries(project, kind="decision", entries=[...])
  • pipelines.json → import_entries(project, kind="pipeline", entries=[...])
  • constraints.json → import_entries(project, kind="constraint", entries=[...])

导入的 ID 会保留;已存在的 ID 会被报告,但绝不会被覆盖。

步骤 5 — 安装手机视图(可选)

以上内容介绍的是 MCP 连接器,用于让 Claude 读取数据。步骤 5 则是让你通过手机读取数据。此步骤需要克隆本仓库并安装 Node 22+,这是整个设置过程中唯一需要使用命令行的环节——连接器本身完全不需要使用命令行。

请参阅下文的手机视图。


手机视图

/view 是一个只读的服务端渲染页面,展示每个项目的决策和约束。将它添加到主屏幕后,打开时就像一个应用:无需登录,URL 中没有令牌,也没有任何需要记住的内容。

最近条目详情
最近 — 所有项目近期的变化任意条目 — 查看决策依据,而不只是标题
项目健康状况
项目 — 每个项目的计数,包括各规则集有多少内容可强制执行健康状况 — 乱码、依据过少、未标记、过时

合成数据。上方的所有项目和条目均为虚构内容 — 数据集及重新生成方法请参见 docs/screenshots。

它有四个标签页,与桌面仪表板一致:

标签页回答的问题
最近所有项目近期有哪些变化
项目每个项目的计数:条目、有效条目、约束、限定范围、替代关系链接、过时内容、乱码
知识cambium 的团队/组织计数(如果已接入,见下文)
健康状况乱码、依据过少、未标记、过时 — 按比例展示,并按项目排名

轻点任意行即可查看完整条目:问题、选择该方案的原因、最初尝试过的方法、权衡、备选方案及其被否决的原因;如果是约束,还会显示范围、强度和强制执行方式。搜索涵盖所有字段,包括决策依据,而答案通常就在其中。已被替代的条目仍可访问,每个条目都会链接到它替代的内容以及替代它的内容。

安装

1. 创建凭据。 双击 scripts/set-view-token.cmd (macOS/Linux:scripts/set-view-token.sh)。在终端中使用绝对路径 — 不要使用 npm run,因为它要求当前目录为仓库目录:

powershell -NoProfile -ExecutionPolicy Bypass -File "/full/path/to/context-keeper-remote/scripts/set-view-token.ps1"

运行一次即可生成令牌、安装令牌、等待路由返回 200、复制 URL、在浏览器中打开 URL,并打印二维码。

2. 用手机扫描二维码,然后安装:

  • Android / Chrome — 横幅会提供安装选项,也可以使用 ⋮ → 安装应用。 如果菜单中只有添加到主屏幕,说明清单未满足 Chrome 的安装条件;通常是缺少 192x192 图标,导致 Chrome 不提示地降级为普通快捷方式,并在浏览器标签页中打开。
  • iPhone — 必须使用 Safari(iOS 上的 Chrome 无法安装 Web 应用)。 分享 → 添加到主屏幕。

趁有网络时,依次打开“最近”“项目”“知识”和“健康状况”一次 — 离线缓存只会缓存你实际打开过的页面。

添加 -DryRun 可运行除安装之外的所有步骤,这是在进行任何更改前检查设置是否正确的最快方式。

离线可用,轻点即开

Service worker 会缓存你打开的每个页面,优先使用缓存,同时在后台重新验证。以下是在线实例上的实测数据:

从缓存提供1 ms
强制通过网络加载278–383 ms

因此,即使没有信号也能打开,切换标签页也是瞬间完成,而不必等待一次往返。决策日志不是实时动态流——立即显示昨天的答案,再过一会儿将其更正,总比等 300ms 什么都看不到好;页眉会标注“8h ago”,因此不会把过期数据显示成当前数据。

只缓存 200 响应。 对于未经身份验证或已轮换的凭据,此 Worker 会返回 404;如果缓存了这个响应,就意味着轮换令牌的设备会一直被告知已退出登录——响应来自本地磁盘,无需网络,也没有明显的方法清除它。已验证这两种情况。

令牌仍然永远不会传到 JavaScript。 Cookie 设置了 HttpOnly,因此 service worker 无法读取它;它只会发起同源请求,由浏览器附加 Cookie。放弃的是“完全不使用客户端 JS”,而不是凭据隔离。CSP 会添加 script-src 'self',并有意不添加 'unsafe-inline'——注册代码放在单独的文件中,因此不需要允许内联脚本;这种许可会作用于整个文档,包括任何通过转义器混入的记录条目。

如何保持登录状态

令牌 URL 是一个注册步骤,而非日常操作。访问该 URL 会设置一个长期有效的 HttpOnly Cookie;之后,该设备就可以直接访问 /view 路径——主屏幕图标打开的正是这个路径。

  • 不会扩大权限范围。 Cookie 携带的机密与路径中的相同,比较方式也相同,因此轮换 VIEW_TOKEN 仍会立即撤销所有设备的访问权限。只有一种撤销方式,没有会话表,也无需跟踪过期时间。
  • 使用独立凭据。 查看页面从不接受 AUTH_TOKEN,/mcp 也从不接受 VIEW_TOKEN。泄露查看 URL 会暴露决策摘要,但无法写入、弃用或删除内容。
  • 未设置即视为失效。 如果没有 VIEW_TOKEN,/view/<anything> 会返回纯 404,与从未部署过的路由无法区分。

之后运行 npm run view 可重新打开页面(URL 会保存到 .view-url,并由 git 忽略)。 运行 npm run view -- --qr 可为另一台设备注册,而不会轮换令牌——重新运行设置会生成一个新令牌,并悄无声息地移除所有已添加设备的访问权限。

将 Knowledge 标签页连接到 cambium-remote(可选)

仅当你也运行 cambium-remote 时才相关。

scripts/connect-cambium.cmd

它会生成一个仅用于状态的凭据,将其安装到 cambium-remote 并设为 STATUS_TOKEN,验证路由返回真实计数,然后才在此处设置 CAMBIUM_STATUS_URL。无需查找或粘贴任何内容。

**为什么要使用第二个凭据,而不是 cambium 的连接器 URL:**该 URL 是 cambium-remote 的 AUTH_TOKEN,它可以对所有已提升的项目执行 recall——其所在 Worker 的团队范围可触及 TEAM_OWNER 下的所有仓库, 包括私有仓库。将它复制到此处只为显示三个整数,意味着这个 Worker 一旦泄露, 就会暴露 cambium 的全部访问范围。STATUS_TOKEN 只能读取计数,不能做其他操作。 它还可以自动生成,这正是设置能够自动完成的原因;AUTH_TOKEN 只能手动 重新输入,因为 Cloudflare 以只写方式存储密钥。

**自托管用户必须添加服务绑定。**Worker 无法通过提取另一个 Worker 的 workers.dev 主机名来访问它——Cloudflare 边缘会返回 404, 目标 Worker 根本不会运行,这看起来就和令牌被拒绝完全一样。在你的 wrangler.toml 中添加:

[[services]]
binding = "CAMBIUM"
service = "cambium-remote"

本仓库仅在 [env.production] 下声明它,这是有意为之:服务绑定会指定其目标, 因此若在顶层声明,就会导致没有 cambium-remote 的用户无法一键部署。

面板会优雅地处理失败。如果 cambium 响应缓慢(预算为 10s)、宕机或未连接, 页面仍会渲染并说明情况。只有 Knowledge 标签页会发起该调用,因此其他标签页 不会受影响。

推送时部署,无需 API 令牌

git push 可以直接部署 Worker,使用你已有的 wrangler 登录状态——无需 Cloudflare API 令牌、GitHub 密钥或控制面板:

scripts/install-deploy-hook.cmd

它会安装一个 git pre-push 钩子。先部署,再推送:如果部署失败,推送就会中止, 因此 origin 永远不会收到无法部署的提交。这正好与它所替代的失败情况相反—— cambium-remote 的 CI 接受了每一次合并,却一次也没有部署,导致 main 超前于 正在运行的 Worker,而且没有任何迹象表明这一点。

仅针对 Main,跳过分支删除;git push --no-verify 可跳过一次,-Remove 可卸载。

如果仓库有命名环境,没有 -Env 就拒绝安装,这项限制事关安全,并非吹毛求疵。 不带参数的 wrangler deploy 会使用顶层配置——而本仓库的顶层配置是自托管配置, 它有意省略了 database_id,因此 Cloudflare 会创建一个全新的空数据库。 如果在此处不带 -Env 安装钩子,下一次推送时就会将线上 Worker 绑定到一个空 D1。 因此:

# cambium-remote -- no named environments, bare deploy is correct
scripts/install-deploy-hook.cmd

# a repo whose real deploy lives under [env.production]
scripts/install-deploy-hook.cmd -Env production

本仓库完全不需要这个钩子——它的 GitHub Actions 部署正常运行,而钩子会让每次推送 都部署两次。

**为什么不直接修复 CI?**因为这一步确实无法自动化。 GitHub Actions 需要 CLOUDFLARE_API_TOKEN,而通过 API 创建 Cloudflare API 令牌 需要已有一个具备 User API Tokens: Edit 权限的令牌。 Wrangler 的 OAuth 登录没有该权限——它的 29 个权限范围涉及 workers/d1/pages/ queues 操作以及 account:read,没有任何与令牌管理相关的权限。**你机器上的任何凭据 都无法创建这个凭据。**粘贴令牌是 Cloudflare 权限模型所要求的,并非工具存在缺陷。 在本地部署可以完全绕过这个问题。

如果你还是想使用 GitHub Actions CI

如果 connect-cambium 发现缺少状态路由,就会使用你已有的 wrangler 登录自行部署 cambium-remote,因此 Knowledge 标签页正常工作并不需要 GitHub Actions 部署成功。

只有在你希望 cambium-remote 每次推送时自动部署,才需要它。其工作流需要两个 Cloudflare 密钥,其中任意一个为空都会悄无声息地失败:每次合并看起来都是绿色,但不会部署任何内容。

scripts/fix-cambium-ci.cmd

CLOUDFLARE_ACCOUNT_ID 会从 wrangler whoami 读取并自动设置——它是标识符,不是凭据;每个仪表板 URL 中都有它。

CLOUDFLARE_API_TOKEN 需要由你粘贴一次,这一步确实无法省略:创建 Cloudflare API 令牌需要一个具有 User API Tokens: Edit 权限的现有令牌,而 wrangler 的 OAuth 登录不具备该权限。你机器上的任何凭据都无法创建这个凭据。除此之外,所有步骤都会自动完成——浏览器会打开正确的页面,读取令牌时不会回显,存储前会先通过 Cloudflare API 验证令牌,两个密钥都会通过 stdin 而非 argv 传递,并且会重新触发之前失败的运行,让你亲眼看到它变成绿色,而不是只听脚本保证。

设置 Worker URL(自托管用户)

没有任何 wrangler 命令会报告 workers.dev 主机名——whoami、deployments list、versions list 和 deployments status 都不会——因此它保存在 package.json 中:

node -e "const p=require('./package.json');p.contextKeeper.workerUrl='https://<worker>.<account>.workers.dev';require('fs').writeFileSync('package.json',JSON.stringify(p,null,2)+'
')"

设置脚本会在安装任何内容之前读取该值,如果没有 URL 就会拒绝运行。这个顺序是有意安排的:如果安装令牌时没有可写入的 URL,就无法恢复,因为 Cloudflare 不允许读取已保存的密钥。

坦诚说明平台支持情况
脚本WindowsmacOS / Linux
set-view-token.cmd / .ps1.sh
connect-cambium.cmd / .ps1尚未移植——见下文
install-deploy-hook.cmd / .ps1尚未移植——见下文
fix-cambium-ci.cmd / .ps1尚未移植——见下文

尚未移植的三个脚本只是对少量命令的简单封装,因此手动执行也很简单。连接 cambium:

TOKEN=$(head -c 32 /dev/urandom | base64 | tr '+/' '-_' | tr -d '=
')
printf '%s' "$TOKEN" | (cd ../cambium-remote && npx wrangler secret put STATUS_TOKEN)
# wait ~60s for the new version to roll out, then check it answers with counts:
curl -s "https://cambium-remote.<account>.workers.dev/status/$TOKEN" | head -c 200
printf '%s' "https://cambium-remote.<account>.workers.dev/status/$TOKEN"   | npx wrangler secret put CAMBIUM_STATUS_URL --env production

推送时部署——在目标仓库中编写 .git/hooks/pre-push,使用 LF 换行符,并运行 chmod +x 和 npx wrangler deploy(如果该仓库有命名环境,则添加 --env <name>——在这种情况下直接执行部署会指向 self-host 配置,并将线上 Worker 绑定到一个全新的空数据库)。

修复 CI——在仓库中执行 gh secret set CLOUDFLARE_ACCOUNT_ID 和 gh secret set CLOUDFLARE_API_TOKEN,并分别从 stdin 读取值。

编辑设置脚本

这些脚本面向 Windows PowerShell 5.1——也就是随 Windows 附带的版本,也是 .cmd 启动的版本。有五处关键设置看似可以现代化,但实际不能:

  • 使用 RNGCryptoServiceProvider,而不是 RandomNumberGenerator::Fill——后者仅适用于 .NET Core,会抛出异常。
  • 手动提取 WebException 状态,而不是使用 -SkipHttpErrorCheck——它仅适用于 PowerShell 7。
  • 不使用 ??、?. 或三元运算符——它们都仅适用于 PowerShell 7,在这里会导致解析错误。
  • 所有 wrangler 调用都通过 Invoke-Wrangler 执行。在 5.1 中,对原生命令使用 2>&1 会将每一行 stderr 包装为 ErrorRecord;在 $ErrorActionPreference = 'Stop' 的情况下,第一条就会成为终止错误——所以普通的 wrangler 通知也会中断运行。
  • 确认步骤使用 [Console]::IsInputRedirected 作为判断条件,绝不使用 [Environment]::UserInteractive(它始终为 true);并且会先将 Read-Host 转换为 [string] 再进行匹配——$null -notmatch '...' 的结果是 empty,而不是 $true,所以看似显而易见的保护条件会默认放行。

每次运行都会写入一份已清除敏感信息的日志(.view-setup.log、.cambium-setup.log),并遮蔽令牌,因此即使窗口关闭后,也能查看失败原因。

⚠️ 安全:连接器 URL 就是凭据

你粘贴到 Claude 中的 URL 会在最后一个路径段中嵌入 AUTH_TOKEN。 任何拿到完整 …/mcp/<AUTH_TOKEN> URL 的人,都可以读取和写入你的整个存储。 请像对待密码一样对待它:

  • 不要分享、截图,也不要粘贴到任何可能记录它的位置。
  • 请求任何其他路径或使用错误令牌的请求,都会得到不含任何详情的 404(有效令牌用于非 POST 方法时,会得到 405)。
  • 轮换令牌:在 Cloudflare 控制面板中更改 AUTH_TOKEN(第 2 步)。这会立即使所有旧 URL 失效——使用旧令牌的任何连接器都会开始收到 404,直到你在 claude.ai 中更新连接器(第 3 步),填入新值。

本节中的所有内容也适用于查看 URL,但有一点对你有利:VIEW_TOKEN 只能读取。泄露查看 URL 会暴露此实例中每个项目的所有决策摘要,这很可能是更敏感的一半——但它无法写入、弃用或删除任何内容。这就是两者使用不同凭据而非共用一个凭据的全部原因。

为什么令牌位于 URL 路径中,以及这样做的代价

这是经过深思熟虑的设计选择,并非疏忽。claude.ai 自定义连接器无法可靠地发送自定义标头,因此不能依赖 Authorization: 标头这一显而易见的替代方案。将凭据放入路径中,才能让连接器正常工作。

请清楚了解这样做的代价,因为它与使用标头不同:

  • URL 会被记录在请求正文永远不会出现的地方。浏览器历史记录、Shell 历史记录、代理和 CDN 访问日志、崩溃报告、错误报告、截图、“复制链接”按钮,以及Agent 会话记录。在生成本节内容的审计过程中,在一台机器上的 13 份本地会话记录中发现了约 54 处这些 Worker 的连接器 URL——没有一处是刻意粘贴的;它们只是 Agent 回显的工具配置的一部分。
  • **Worker 本身不会记录令牌。**每条日志都会将路由记录为 /mcp/***。泄露面是 Worker 周围的一切,而这些正是你无法审计的部分。
  • **令牌一旦泄露就意味着拥有完整访问权限,没有第二重验证,也没有逐个调用方的身份信息。**除了令牌本身,没有其他内容可以撤销;也没有日志能告诉你是谁使用了它。

实用建议:

  1. 按计划轮换令牌,不要等到怀疑令牌泄露时才轮换——假设 URL 已被记录在某个你无法控制的地方。轮换成本很低:更改 AUTH_TOKEN,然后更新连接器。
  2. 如果你分享过终端录屏、会话记录、屏幕截图,或来自已配置该连接器的机器的错误报告,请立即轮换令牌。
  3. 使用足够长的随机令牌(至少 32 字节,例如 openssl rand -hex 32)。无论内容还是长度,比较都采用恒定时间,因此无法通过观察获知长度——但熵仍然是你抵御猜测的唯一保障。
  4. 如果你有机会改用标头或 OAuth,就这么做。这是客户端迫使我们做出的权衡,而非首选方案。

工具

每个工具都接受可选的 project;如果省略,则使用已配置的 default_project(通过 config 设置一次:op='set',键为 default_project)。

统一工具(config、record_entry)是当前接口;旧的按操作划分的工具仍作为已弃用别名保留,以便现有调用方继续使用。新开发应优先使用统一工具。

工具用途
config读取或写入配置:op='get' 读取键,op='set' 写入键(需要 value)。使用键 default_project(全局范围,不带 project)来指定未提供 project 时调用所用的项目。
set_config / get_configconfig(op='set') / config(op='get') 的已弃用别名。
record_entry统一写入:记录 decision、constraint 或 pipeline。必填字段因类型而异——decision 需要 summary,constraint 需要 rule,pipeline 需要 name。
record_decisionrecord_entry(kind='decision') 的已弃用别名:summary、problem、why_chosen、what_we_tried、tradeoffs、tags。
record_constraintrecord_entry(kind='constraint') 的已弃用别名:必须遵守的规则——rule、reason、tags。
record_pipelinerecord_entry(kind='pipeline') 的已弃用别名:可复用流程——name、purpose、steps(额外字段会原样保留)。
get_context根据查询进行相关性排序检索(关键词评分;除非设置 include_deprecated,否则排除已弃用条目)。取代其他条目的记录会附带一行 predecessor——说明前一条记录的内容及其变更原因;此内容与本地服务中的字节完全一致,因此通过任一传输方式查看历史记录时都相同。
query_entries结构化筛选:id、kind、tags(必须全部匹配)、status(active/deprecated/all)、自由文本 text 和 limit。
get_project_summary一次调用即可了解项目概况:按类型和状态统计的条目数量、已有的 ID、当前生效的约束(精简版)以及最近的决策。
list_projects组织注册表:列出每个含有条目的项目,以及各项目当前生效条目的数量(decisions/constraints/pipelines)、当前生效/已弃用条目总数和最后更新时间。一次调用即可列举整个组织,查找准确、区分大小写的项目名称,无需猜测。
update_entry将 patch 字段合并到条目的载荷中;也可选择更改 status。
deprecate_entry将条目标记为已弃用;可选择关联 superseded_by 并记录 reason(前置条目行引用的就是此原因)。
reload_constraints当前生效约束的精简列表。
prune_stale删除较旧的已弃用条目(默认试运行;传入 dry_run=false)。
verify_quality标记缺少说明理由字段的条目。
export_markdown将条目渲染为 DECISIONS.md 风格的文档。
import_entries从本地 JSON 存储格式批量导入(保留 ID 和生命周期状态,包括 superseded;报告冲突,绝不覆盖)。
upsert_entries使用本地存储格式批量 upsert——用于镜像同步。插入新 ID;仅当传入的 updated_at 严格更新时才替换已有 ID(按时间戳采用最后写入者胜出),否则跳过。在镜像存储间传递编辑和弃用状态;绝不删除。
条目约定
  • 决策使用 summary、problem、why_chosen、what_we_tried、 tradeoffs、tags。输入中接受已弃用的 rationale 字段;若未提供 why_chosen,则将其映射到 why_chosen。
  • 约束使用 rule、reason、tags。
  • 流程使用 name、purpose、steps,以及你传入的任何额外字段。
  • ID按项目和类型划分:dec-001、pipe-003、con-012。由于不同项目中可能出现相同 ID,D1 主键采用复合键 (project, id)。

面向维护者 / 贡献者

以上内容面向可自托管用户。本节介绍如何参与代码本身的开发。

配置布局:一个仓库如何同时服务于按钮和 CI

wrangler.toml 有两个配置档:

  • 默认(顶层) — D1 绑定声明时不带 database_id。 部署按钮、wrangler dev 和本地测试套件都会使用此配置。没有 ID 时,Cloudflare 会为每个自托管用户自动配置一个全新的数据库。
  • [env.production] — 固定维护者的实际 database_id 和 Worker name。维护者的 CI 使用 wrangler deploy --env production 部署,因此始终连接到同一个数据库和同一个 URL。自托管用户绝不会使用此环境。

cambium 服务绑定仅存在于 [env.production] 中,这种拆分至关重要,而不只是为了整洁。服务绑定会指定目标 Worker,因此顶层的 [[services]] service = "cambium-remote" 会导致一键部署在没有此 Worker 的任何账户中失败——也就是除维护者账户之外的所有账户。出于同样的原因,任何指定其他 Worker、通过 ID 指定其他数据库或指定其他账户的配置,都应放在命名环境中。

命名环境不会继承任何配置。生产部署需要的每个绑定都必须在 [env.production.*] 下重复声明,包括 [observability]。只存在于顶层的绑定,在 CI 实际部署的环境中会被静默忽略。

部署流水线(仅限维护者)

.github/workflows/deploy.yml 会在推送到 main 时运行,并受 if: github.repository == 'jarmstrong158/context-keeper-remote' 条件限制,这样分支仓库(通过 Workers Builds 部署)就不会运行失败的 Actions。步骤:检出代码 → Node 22(Wrangler 需要 ≥ 22)→ npm ci → npm test → wrangler deploy --env production。测试通过后才会部署。它会读取两个 GitHub 仓库密钥: CLOUDFLARE_API_TOKEN(需要 Workers Scripts: Edit)和 CLOUDFLARE_ACCOUNT_ID ——这两个都不同于 Worker 自身的 AUTH_TOKEN。

本地开发

无需网络,也不需要 Cloudflare 凭据——测试通过 @cloudflare/vitest-pool-workers,在本地 workerd D1 上运行。需要 Node ≥ 22。

npm install
npm test          # vitest: migrations, cold-start, CRUD, id sequencing, auth, import, ...
npm run typecheck # tsc --noEmit
线上冒烟测试

部署后,可在任何能访问网络的机器上运行:

WORKER_URL="https://context-keeper-remote.<subdomain>.workers.dev/mcp/<AUTH_TOKEN>" \
  node scripts/smoke-test.mjs

它会针对线上 Worker 依次运行 initialize → tools/list → record_decision → query_entries。

目录结构
src/index.ts             fetch handler: token check -> MCP dispatch (schema ensured lazily on first tools/call, not on the handshake)
src/mcp.ts               stateless Streamable HTTP MCP server (createMcpHandler)
src/db.ts                D1 access + runtime migration runner + id generation
src/entries.ts           payload normalization, insert-with-retry, keyword scoring
src/tools/*.ts           one module per tool group
src/view.ts              the phone view: shell, tabs, knowledge panel, dispatch on ?e/?p/?q/?t
src/detail.ts            entry detail, project drill-down, search, supersession trail
src/health.ts            quality flags + the Projects and Health tables
src/install.ts           enrolment cookie, web app manifest, home-screen icon
src/icon-data.ts         GENERATED by scripts/make-icon.mjs -- do not hand-edit
schema.sql               reference copy of the DDL the migration runner embeds
wrangler.toml            default (auto-provision) + [env.production] (pinned) config
.github/workflows/deploy.yml   test-then-deploy on push to main (maintainer repo)
scripts/smoke-test.mjs   live JSON-RPC round-trip check
scripts/set-view-token.*  create VIEW_TOKEN, verify, QR, save the URL  (.cmd = double-click)
scripts/connect-cambium.* generate STATUS_TOKEN on cambium-remote and wire it here
scripts/make-icon.mjs     regenerate the home-screen PNG (npm run make-icon)
test/                    vitest suite (local workerd D1, no network)
维护者部署故障排查
Actions 日志中的症状原因修复方法
Wrangler requires at least Node.js v22.0.0Node < 22已在 deploy.yml 中设为 Node 22。
it's necessary to set a CLOUDFLARE_API_TOKEN environment variable缺少部署密钥添加两个 GitHub 仓库密钥。
No route for that URI [code: 7000] / object identifier is invalid [code: 7003]API token 缺少 Workers 权限,或 CLOUDFLARE_ACCOUNT_ID 错误使用“Edit Cloudflare Workers” token;确认账户 ID。
部署成功,但每次调用都返回 404未设置 Worker AUTH_TOKEN,或 URL 中的 token 与其不匹配在 Cloudflare 控制面板中设置/验证 AUTH_TOKEN。

相关项目

  • context-keeper — 此 Worker 以远程传输方式托管的本地 stdio 原版。
  • xylem — 此项目所属的技术栈。

评论

支持 Markdown

第一次接触 MCP?

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

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