Skip to main content
Glama
dcazman

Claude-Atlas-MCP

by dcazman

Claude-Atlas-MCP

自托管的 MCP 服务器,为 Claude 提供跨对话的持久记忆——实体、观察、历史、定时提醒,外加一个用于存放待处理事项的托盘和一个用于存放想法的搁板——全部运行在你自行管理的轻量级 Node/SQLite 后端中。

将其作为 MCP 连接器指向 Claude,它就能记住你在不同对话之间正在处理的内容:进行中的项目、决策及其依据、关于你和你的设置的事实,以及需要在未来某个日期重新浮现的事项。

为什么

Claude 在对话结束时会忘记一切。Atlas 是一个小巧、朴实、持久的记忆层,完全由你掌控——没有第三方服务,没有供应商锁定。它是一个由单个 SQLite 文件支持的 Node 进程。可以运行在家用服务器、VPS 或笔记本电脑上。

它故意从空白开始。没有预设你生活的模式,没有假定的工作,没有必需的问题跟踪器——只是一个随着你使用而逐渐填充的形状。

Related MCP server: memory-mcp

快速开始

git clone https://github.com/dcazman/Claude-Atlas-MCP.git
cd Claude-Atlas-MCP
docker compose up -d --build
docker compose logs atlas-mcp

无需 .env,无需令牌,无需配置。首次启动时,Atlas 会创建数据库,为每个作用域生成一个令牌,并打印出来:

    work     3f2a…   (caller "work-client")
    personal 9c41…   (caller "personal-client")
    shared   b7e0…   (caller "shared-client")

  Connect a client to:  http://localhost:7784/atlas-mcp?token=<one of the above>

令牌保存在数据库旁边,每次重启时重复使用。数据位于 ./data 中,是一个单独的 SQLite 文件。这就是全部设置。

检查是否生效:

curl -s localhost:7784/health
# {"ok":true,"service":"atlas-mcp","version":2,"port":"7784"}

TOKEN=<one of the tokens printed above>
curl -s -X POST localhost:7784/atlas-mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -H "x-atlas-token: $TOKEN" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":
       {"name":"add_observation","arguments":
        {"section":"work","entity":"Atlas","content":"Installed today."}}}'

如果返回了一个 observation_id,则整个堆栈正常工作:你的第一条记忆已写入磁盘,Claude 可以读取它。

CI 在每次推送到 main 时发布镜像,如果你不想自己构建:

docker run -d --name atlas -p 7784:7784 -v "$PWD/atlas-data:/app/data" \
  ghcr.io/dcazman/claude-atlas-mcp:latest
docker logs atlas

裸 Node——22.13+ 版本自带 node:sqlite。没有原生依赖,无需编译:

npm install
npm start

要使用自定义令牌、时区或整理时间而非默认值,请执行 cp .env.example .env 并取消注释你想要的部分。未经编辑地复制它不会改变任何内容——每一行都特意被注释掉了。

数据模型

概念

说明

实体

你希望 Claude 跟踪的主题或项目(例如“家庭网络”、“Q3 规划”)。包含名称和一行摘要。

观察

附加到实体上的单个事实(“于 2026-06-01 将路由器切换到 6E 频段”)。记忆的原子单位。可原地编辑,并可标记为受保护,以便可以更正但永远不会被删除。

历史事件

发生的重要事件,记录在时间线上供日后回顾。

提醒

带有 trigger_date 的笔记。一旦日期到达,它会在对话开始时自动浮现,并保持到被解除。添加 trigger_time 后,它变为定时提醒,旨在由轮询它的东西一次性投递。

托盘项

到达的需要处理但不应打断当前工作的事项。先捕获,稍后决定。

搁板项

你自己的一个想法。没有日期,没有压力,不会过期。

分区

顶层命名空间——work、personal 或 shared。每个工具调用都接受一个 section。shared 是一个交接通道,work 和 personal 作用域的令牌都可以访问;get_landscape 会将其合并到你拉取的分区中。

漏斗

三个层面,承诺程度递增:

  shelf  ──graduate──▶  tray  ──promote──▶  memory
 (ideas)              (triage)          (observations)
  • 搁板存放你想过的东西。一个想法在那里放了一年不是积压失败——而是搁板在正常工作。想法通过晋升到托盘或被有意终止(保留原因)而离开。

  • 托盘存放到达的东西。它是一个队列,而不是一堆:捕获,然后提升、合并或解除。

  • 记忆是 Claude 在对话开始时读取的部分。

没有任何东西在过程中被销毁。已解决的项目不再显示,但保留其历史记录,包括它们变成了什么。

你实际如何看到这些东西。 get_landscape 是 Claude 在对话开始时调用的唯一调用,因此任何需要你注意的事项都必须通过它返回:

层面

在概览中

原因

记忆

完整显示

它是对话运行的上下文

到期提醒

完整显示

整个目的就是无需询问而重新浮现

托盘

完整显示

未处理的捕获正在等待你的决定

搁板

仅计数

每次对话都复述所有想法会把无压力的搁板变成烦人的积压——计数表明“这里有东西”,research_list 在你询问时显示它们

因此,“先捕获,稍后决定”是可行的:无论你在对话中途往托盘里扔了什么,都会在下次对话开始时自动回来,无需你记住它的存在。

工具

31 个 MCP 工具。

读取

  • get_landscape — 一个分区中的所有内容(合并了 shared):所有实体及其观察、到期提醒、未处理的托盘项以及开放搁板想法的计数。在对话开始时调用以获取概览。

  • search — 跨实体、观察和历史进行关键词搜索。

  • get_entity — 按名称获取一个实体及其观察。

  • get_observation — 直接按 ID 获取最多 20 条观察。ID 是稳定的且永不重复,这使得它们成为在不同对话之间传递特定事实的廉价方式。

  • get_history — 已记录事件的时间线。

  • get_time — 当前时间加上自该令牌上次调用以来的时间。

写入

  • upsert_entity — 创建或更新实体的名称/摘要。

  • add_observation — 向实体附加一个事实。

  • update_observation — 原地编辑事实;ID 保持稳定。适用于受保护的行。

  • remove_observation — 删除过时或已完成的事实(如果受保护则拒绝)。

  • protect_observation / unprotect_observation — 将事实标记为不可删除,或取消该标记。

  • remove_entity — 删除实体及其观察(如果任何观察受保护则拒绝)。

  • log_event — 将重要事件记录到历史中。

提醒

  • create_reminder — 带有 trigger_date、可选 trigger_time 和可选实体链接的笔记。

  • list_reminders — 所有已安排的提醒,无论是否到期。

  • list_due_reminders — 当前到期的所有提醒。这是通知程序轮询的内容。

  • mark_reminder_fired — 将定时提醒标记为已投递,使其永远不会再次触发。

  • dismiss_reminder — 将提醒标记为已处理(它停止浮现)。

  • remove_reminder — 直接删除提醒。

托盘

  • pending_add — 捕获到达的事项。

  • pending_list — 仍需要处理的事项,按最早优先排序。

  • pending_promote — 将捕获转化为实体上的观察。

  • pending_merge — 将重复项合并到你保留的那个中。

  • pending_dismiss — 决定不需要任何操作,保留原因。

  • pending_reopen — 撤销上述任何操作。

搁板

  • research_add — 存放一个想法。

  • research_list — 开放的想法,按最早优先排序。

  • research_promote — 将想法晋升到托盘。

  • research_kill — 有意终止一个想法,保留原因。

  • research_reopen — 将其放回。

每个工具响应都带有一个小的时间页脚——你配置的时区中的当前服务器时间,加上自该令牌上次调用以来的经过时间——这样模型就不必从过时的心理时钟进行猜测或日期计算。

获取通知

Atlas 从不自行推送任何内容——它不知道你想在哪里被联系到。相反,list_due_reminders 是任何执行通知的组件的契约:

  1. 按你喜欢的任何间隔轮询 list_due_reminders。

  2. 投递那些带有 trigger_time 的行(被动的提醒只是在等待在概览中被看到)。

  3. 对你投递的每个提醒调用 mark_reminder_fired。

第 3 步使投递恰好一次:该标记在 SQL 中受到保护,因此两个重叠的轮询器无法重复发送。十几行由 cron 驱动的脚本就足以将其连接到电子邮件、聊天 webhook 或手机通知。

整理工作器

src/groom.js 在服务器进程内每晚运行(无需主机 cron),或者可以通过 npm run groom 按需运行。它有意只报告且机械执行——没有 LLM 调用,不会删除你的数据:

  • 标记实体内部可能接近重复的观察

  • 标记休眠实体(60 天以上未触碰)作为归档/压缩候选

  • 标记长期解除的提醒(90 天以上)作为删除候选

  • 轮转自己的 audit_log(90 天以上)——这是它唯一实际删除的内容

  • 跳过自上次运行以来未触碰的实体,因此重复运行成本很低

结果会放入每个分区的“整理报告”实体中,供你(或 Claude)处理。它在你的时区的 ATLAS_GROOM_HOUR(默认凌晨 4 点)运行,并且可以自我修复:如果因为容器关闭而错过了一个窗口,它会在下次检查时运行。

连接 Claude

Atlas 通过流式 HTTP 在 POST /atlas-mcp 上提供 MCP 服务。使用服务器的 URL 和你的令牌将其添加为连接器:

https://<your-host>/atlas-mcp?token=<your-secret>

令牌是 ATLAS_TOKEN 三元组的秘密部分(参见配置)。你也可以将其作为 X-Atlas-Token 标头或 Bearer 令牌传递,而不是查询字符串。

URL 中没有 section——每个工具都接受一个 section 参数,而特定对话应默认使用哪个分区最好在你的 Claude 项目自定义指令中设置(例如 “你的 Atlas 分区是 personal”)。GET /health 端点可用于存活检查。

对于实际使用,你希望它位于 HTTPS 后面——在容器前面放置反向代理或隧道(Cloudflare Tunnel、Tailscale、nginx 等)。令牌是唯一的身份验证,因此不要在没有 TLS 的情况下公开暴露端口。

连接后,一个好的习惯是让 Claude 在每次对话开始时调用 get_landscape,并在事情变化时保持条目更新。服务器附带了明确说明这一点的指令,因此大多数客户端无需你编写任何内容就能自动执行。

保护它

Atlas 的内置身份验证是一个共享令牌——在私有网络或隧道后面没问题,但如果暴露在互联网上则很薄弱。对于真正的访问控制,请在前面放置专用的身份验证网关,而不是自己加固此服务器。

mcp-auth-proxy 是一个即插即用的 OAuth 2.1 / OIDC 网关,适用于 MCP 服务器——无需对 Atlas 进行任何代码修改:

  • 针对您自己的身份提供商(Google、GitHub、Okta、Auth0、Azure AD、Keycloak 或任何 OIDC 提供商)进行身份验证,并可选择使用密码。

  • 通过精确匹配或通配符(例如 *@yourcompany.com)对用户进行授权。

  • 终止 TLS 并原样代理 HTTP 传输,已在 Claude、Claude Code、ChatGPT、Copilot 和 Cursor 上验证通过。

大致来说,您只需将其指向 Atlas 的 HTTP 端点:

./mcp-auth-proxy \
  --external-url https://<your-domain> \
  --tls-accept-tos \
  -- http://localhost:7784/atlas-mcp

有关身份提供商的设置和配置,请参阅其文档。(非关联项目——只是恰好非常适合此类自托管 MCP 服务器。)

配置

所有配置均为可选。通过 .env(参见 .env.example)或环境变量进行设置:

变量

用途

ATLAS_TOKEN

一个或多个 调用者:密钥:作用域 三元组,以逗号分隔。作用域为必填项——work(可访问 work+shared)、personal(可访问 personal+shared)或 shared(仅可访问 shared)。在每次调用时在服务端强制执行;超出作用域的请求将返回 403 并被记录。如果未设置,Atlas 会在首次启动时为每个作用域生成一个令牌,并将其保存到数据目录中的 first-run-tokens.txt 文件中。

ATLAS_TZ

用于提醒、时间页脚和整理窗口的 IANA 时区(例如 America/Chicago、Europe/Berlin)。默认为主机时区,若无效则使用 UTC。

ATLAS_GROOM_HOUR

夜间整理可能开始的本地时间小时(0–23,默认为 4)。

PORT

监听端口(默认为 7784)。

ATLAS_DB_PATH

SQLite 文件的路径(相对于 src/ 默认为 ../data/atlas.db;Docker 镜像使用 /app/data/atlas.db)。

自定义

设计刻意保持小巧,以便您可以轻松扩展而无需费力。

  • 添加工具。 所有内容都位于 src/tools.js 中,通过一个 guarded() 包装器注册,该包装器负责作用域检查和审计写入。一个新工具就是一个 guarded(name, {description, inputSchema}, handler) 块,外加 src/db.js 中的一个函数。描述比代码更重要——Claude 会根据描述来决定何时使用该工具。

  • 添加表。 迁移是 src/db.js 中的一个 PRAGMA user_version 阶梯:增加版本号,编写由它保护的附加 SQL,完成。每次迁移都是幂等的,并在启动时运行,因此升级只需重启即可。

  • 将规则推入数据库。 这里的风格是,需要记住的规则就是会被打破的规则——因此 resolved_at 由触发器打上时间戳,作用域在服务端强制执行,受保护的行在 SQL 层面受到保护。遵循此模式,您的添加内容将继承这些特性。

  • 更改分区。 work/personal/shared 在模式的 CHECK 约束和 src/server.js 的作用域映射中是固定的。重命名它们只需进行一次迁移和两行映射编辑——如果这些词汇不符合您的生活习惯,值得一试。

测试

npm test

每次运行都从一个空数据库开始,因此测试套件也充当了空白状态检查:模式从无到有构建,令牌作用域矩阵保持有效(包括超出作用域的 ID 与不存在的 ID 无法区分),定时提醒恰好触发一次,漏斗按预期方式移动项目。

安全

请参阅 SECURITY.md 了解威胁模型、部署加固说明以及如何报告漏洞。

变更

请参阅 CHANGELOG.md。简要说明:v3 版本新增了托盘、搁架、定时提醒、观察 ID 寻址以及零配置启动功能。

许可证

MIT 许可证——请参阅 LICENSE。

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers