关于 stateark
stateark 是面向使用本地 MCP 客户端的项目状态版本管理服务,可在不同聊天间保存和恢复工作。它将状态与文件存为可读的普通文件,并提供版本差异和完整性检查。
主要功能
- 01保存并恢复项目状态
- 02保存点版本历史与差异
- 03未变文件自动沿用
- 04文件哈希与完整性警告
- 05记录保存点间的关键事件
适用场景
- 01在新聊天中继续已有项目
- 02检查两个保存点之间的变化
- 03避免项目文件在交接中丢失
MCP 相关
提供 MCP 服务,供本地 MCP 客户端调用保存、恢复、历史、差异及文件相关工具。默认只在本机运行,数据保存在本地文件夹。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
StateArk
永远不必向 AI 重复解释你的项目。
你的聊天是工作空间,而不是档案库。StateArk 会将工作会话转化为有版本记录、可移植的项目状态,任何新的聊天都能接续使用。打开终端并输入:
npx stateark
然后彻底退出 Claude Desktop(Cmd+Q)并重新打开。安装就这么简单。
(更愿意从源代码安装?npm install && npm run build && npm run setup —
参见 INSTALL.md。随时可以用 npx stateark remove 撤销。)
这是我们开发 StateArk 时的初衷——我们要解决数百万用户面临的问题……
You: ...three hours of work...
You: Savepoint
-> my-project v0.3 written to ~/StateArk
(next day, new chat, empty context)
You: Resume my-project
-> decisions, constraints, rejected approaches, open questions,
and the actual files - all current, none of the detours
默认本地运行。 存档点是由 Markdown、JSON 和你的真实文件组成的普通文件夹。不会上传任何内容。即使 StateArk 明天消失,你仍然拥有一切。
~/StateArk/projects/my-project/v0.3/
state.md <- the canonical state, readable in any editor
state.json
manifest.json <- every artifact with its SHA-256
artifacts/
app.py
schema.sql
命令
| 在聊天中 | 会发生什么 |
|---|---|
Savepoint | 将会话整理汇总为一个新版本 |
Resume <project> | 将最新状态载入新的聊天 |
History <project> | 列出各个版本 |
Diff <project> | 查看两个存档点之间的实际变更 |
| 在终端中 | |
|---|---|
npx stateark | 在 Claude Desktop 中注册 |
npx stateark report | 仅为你生成并打印匿名化的本地使用情况摘要 |
npx stateark remove | 取消注册;保留存档点 |
不止是摘要
- 延续内容。 未重新提交的文件会连同原始哈希一起复制到新版本中,因此健忘的模型无法悄悄丢失你的架构。
- 完整性检查。 StateArk 无法查看你的聊天,因此会检查它能检查的内容:截断标记(
// ... rest unchanged)、大小缩减的文件、状态中有所描述但从未交付的文件,以及与前一版本完全相同的存档点。 它会发出警告,但绝不会阻止操作:存档点始终会写入。 - 日志。 在存档点之间,模型会静默记录关键转折,因此漫长会话结束时创建的存档点不会依赖已经退化的上下文。 仅适用于之前已保存过的项目——不会触及临时对话。
要求
Node 20+。Claude Desktop 或 Claude Code(claude mcp add --transport http ...)。
它也可运行于其他本地 MCP 宿主——用户已成功将 Codex 和 Hermes 与同一个存储配合使用。
通过供应商云端连接到你的服务的托管客户端(Claude 网页版、ChatGPT 网页版)无法访问 localhost。请参见 INSTALL.md。
同时运行多个 Agent
支持同时运行多个 Agent。这里值得明确说明,因为这是最先出问题的配置。 项目写入操作会跨进程串行化,因此两个 Agent 不会占用同一个版本号。如果存档点提示另一个进程正在忙碌,稍等片刻后重试即可——不会丢失任何内容。进程若在写入期间意外终止,其锁会自动释放。
如果你的存储位于 Dropbox、OneDrive 或 iCloud Drive:同一台机器上运行多个 Agent 没问题。两台机器同时写入同一个存储会产生同步冲突,由同步客户端解决,StateArk 无法处理。
| 变量 | 默认值 | |
|---|---|---|
STATEARK_LOCK_WAIT_MS | 60000 | 放弃前等待另一个进程的时长 |
STATEARK_LOCK_STALE_MS | 120000 | 将锁视为属于已终止进程的等待时间 |
STATEARK_FS_RETRIES | 6 | 同步客户端占用文件时的重试次数 |
许可协议
Elastic License 2.0。可将其用于任何用途,包括商业用途;可阅读和修改源代码,也可分享此软件包。不得将其作为托管或管理服务提供给第三方。你的存档点归你所有,不受此许可协议约束。
架构
ChatGPT / Claude / Gemini-capable MCP client
|
v
StateArk Local Agent <- 127.0.0.1 only, by default
|
v
~/StateArk/projects <- SOURCE OF TRUTH
|
| optional
v
Supabase <- mirror / backup / transport
存档点是一个普通目录,而非专有数据库:
StateArk/projects/my-project/
journal.ndjson # entries recorded since the last savepoint
project.json # index (self-healing: rebuilt from disk if corrupt)
v0.3/
state.md # human- and LLM-readable canonical state + integrity warnings
state.json # the same state, structured
meta.json # version, lineage, platform, sync status, warnings
manifest.json # artifacts with SHA-256, stored/pending, carried_forward_from
journal.ndjson # the entries this savepoint consolidated
artifacts/
app.py
schema.sql
prototype.zip
即使 StateArk 消失,这些文件仍可使用。
安装
需要 Node 20+。
npm install
npm run typecheck
npm test # 97 checks against a throwaway store — run this first
npm start
仅本地模式无需 .env。只有在要更改端口、存储位置或启用 Supabase 镜像时,才需要将 .env.example 复制为 .env。
首次运行时,StateArk 会生成一个随机访问密钥,并将其存储在
~/StateArk/.access-key 中(模式为 0600)。启动横幅会显示你的端点:
MCP: http://localhost:8787/mcp/<key>
Upload page: http://localhost:8787/upload/<key>
Health: http://localhost:8787/health
安全模型
HTTP 入口是在你自己的计算机上运行的本地服务,因此 StateArk 假定你访问的任何网页都具有恶意:
| 控制项 | 默认值 |
|---|---|
| 绑定地址 | 127.0.0.1(可通过 STATEARK_BIND 更改) |
| 访问密钥 | 每次安装随机生成,存储在 <root>/.access-key 中,使用恒定时间比较 |
Origin 标头 | 仅允许环回地址,以及 STATEARK_ALLOWED_ORIGINS |
Host 标头 | 仅允许环回地址,以及 STATEARK_ALLOWED_HOSTS(防止 DNS 重绑定) |
| CORS | 回显通过验证的来源,绝不使用 * |
| 上传表单 | 一次性 CSRF 令牌,限制请求体大小 |
| 非环回绑定 | 除非访问密钥至少有 24 个字符,否则拒绝启动 |
通过 HTTPS 暴露 Agent 之前:设置较长的 STATEARK_ACCESS_KEY,将 STATEARK_ALLOWED_HOSTS 设为你的隧道主机名,并在前面配置一个真正的反向代理。
平台现状
本地优先环境与托管大模型环境的网络条件不同。Claude Desktop/Code 和其他本地 MCP 客户端可以直接连接本地 Agent。托管的 ChatGPT/Gemini 客户端通常无法访问你计算机上的 localhost。这些客户端需要通过安全的 HTTPS 路由访问正在运行的本地 Agent;远程访问仍在路线图中,目前尚不存在。
如果你正在进行设置,请按以下顺序操作:
- 在本地运行 StateArk;
- 使用本地 MCP 客户端测试 Savepoint 和 Resume;
- 仅在确实需要镜像时启用 Supabase 同步;
- 只有在以上三步都正常后,才通过 HTTPS 暴露 Agent。
仅本地模式 — 默认模式
将 SUPABASE_URL、SUPABASE_SECRET_KEY 和 STATEARK_OWNER_ID 留空。云同步将保持关闭,文件不会离开本机。默认存储位置:~/StateArk
(可通过 STATEARK_LOCAL_ROOT 覆盖)。
开箱即用的就是这种模式。下方的 Supabase 部分为可选配置。
本地 + Supabase 同步
按顺序在 Supabase SQL 编辑器中运行迁移:
supabase/migrations/001_stateark.sqlsupabase/migrations/002_artifacts.sqlsupabase/migrations/003_hardening.sql
然后设置 SUPABASE_URL、SUPABASE_SECRET_KEY(服务端 Secret 密钥,绝不能使用 publishable 密钥)、STATEARK_OWNER_ID 和 STATEARK_STORAGE_BUCKET。
云端是镜像,而非主存储:
- 本地保存点会先提交,云端故障不会导致其失效;
- 删除云端数据不会删除本地数据;
- 同步状态记录在
meta.json中(disabled/pending/synced/failed); - 使用
sync_savepoint工具重试失败的推送。
大小不超过 2 MB 的文本/代码制品会以内联方式镜像到 Postgres;其他内容则存入私有 Storage 存储桶。该镜像并未采用端到端加密——Supabase 项目可以读取其中存储的内容。同步默认关闭,正是出于这个原因;只有当你愿意将数据存入任何托管数据库时,才启用它。
Savepoint 行为
当你说 Savepoint 时,宿主大模型应:
- 重建最新的有效状态,而非概述时间顺序;
- 保留起主导作用的决策、要求和约束;
- 仅在原因重要时保留已否决的方案;
- 将准确的文本/代码作为
transfer=text发送; - 仅在确实可获取二进制字节时,将其作为
transfer=base64发送; - 否则,将制品标记为
transfer=pending,而不是编造内容; - 省略未发生变化的文件——这些文件会自动沿用;
- 绝不使用
... rest unchanged缩略文件内容。
本地创建采用原子操作:StateArk 会先写入临时包,仅在写入完成后才重命名。制品名称会经过清理;如果名称必须更改,manifest.json 会在 original_name 下记录原始名称。
完整性检查
每个保存点都会与前一个保存点进行比较。检查结果会在工具
结果中返回,并显示在 state.md 顶部。保存点始终会写入——检查不会让你损失任何工作,只会提醒模型如实说明。
| 代码 | 含义 |
|---|---|
artifact_carried_forward | 文件未重新提交,也未声明为已删除,因此从上一版本复制而来 |
artifact_became_pending | 已存储的内容现在仅处于待处理状态 |
artifact_shrank | 文件大小缩减至先前版本的 50% 以下 |
truncation_marker | 存储的文本包含 ... rest unchanged、[...]、… gekürzt 等内容 |
no_change | 此保存点与前一个保存点完全相同 |
journal_not_reflected | 已将决策记录到日志中,但提交的状态中未列出任何决策 |
artifacts_mentioned_but_missing | 状态文本提到了某个文件(schema.sql、app.py、……),但从未将其作为工件提交 |
最后一项在实际使用中最为重要。StateArk 无法读取你的聊天记录,因此文本中出现文件名,是它唯一能据此判断模型是在描述文件而非保留文件的线索。警告会以问题的形式措辞,因为提及的文件也可能只是计划中的文件,或存在于对话之外。
日志
note_event 会在每个转折点静默记录一行,而且只适用于 StateArk 中已有的项目。未跟踪的项目会返回 tracked: false,不会写入任何内容——这是用来排除临时对话的过滤机制。
在下一个保存点中,日志会合并到新版本并清空。只有在保存点已可靠写入磁盘后,日志才会清空。
使用 journal 工具查看待处理条目。提醒基于条目数量(STATEARK_JOURNAL_NUDGE_AT,默认值为 20),绝不基于计时器。
差异
不带版本参数调用 diff_savepoints,会将最新保存点与前一个保存点进行比较:对文本字段执行 LCS 行级差异比较,对列表执行集合差异比较,对工件进行 SHA-256 比较,并为任何看似静默丢失的内容添加 attention 区块。
工件
每个已存储的工件都有一个 SHA-256。待处理文件会明确列在 manifest.json 和 resume_project 输出中,因此 LLM 无法悄悄假装文件存在。
如果二进制文件无法通过 MCP 传输,请打开启动时显示的本地上传页面,并将其附加到现有项目/版本。这会解决清单中的待处理条目。
恢复项目
Resume My Project 会返回 state.md 和工件清单。只有在需要时,LLM 才会调用 get_artifact 获取确切文本。对于二进制文件,它会获取经验证的本地路径和哈希,而不是编造内容。
MCP 客户端
- Claude Desktop —
npx stateark会为你注册 stdio 入口点。 - Claude Code — 将其指向本地 Streamable HTTP 端点:
claude mcp add --transport http ... - Codex、Hermes 和其他本地 MCP 宿主 — 将它们指向同一个存储根目录,即可共享保存点。每个客户端都需要单独配置;设置不会共享。StateArk 会在存储目录中写入
README.md说明目录结构,大多数编码 Agent 会自行读取。 - ChatGPT 网页版/移动版、Gemini 和其他托管客户端 — 它们会从供应商的云端连接你的服务,无法访问你电脑上的
localhost。这是网络机制所限,并非缺少功能。要从托管客户端访问你的保存点,需要通过经过身份验证的 HTTPS 路由连接到你自己的机器;此功能已列入路线图,但目前尚不存在。
路线图
目前还没有实现以下功能。大致按此顺序推进:
- 可选云存储 — 将保存点同步到云端,这样笔记本电脑损坏也不会导致项目丢失。默认关闭,并且始终只保存副本:磁盘上的数据仍是原件。
- 远程访问 — 不再局限于存储状态的那台设备上的桌面应用,还能通过 Web 和移动客户端访问状态。
- 分支 — 目前,两个聊天同时处理同一个项目,只会生成一条线性的版本链。问题已记录,尚未解决。
- 状态裁剪 — 保存点积累多了,
state.md会无限增长。需要设置大小上限,并制定淘汰旧内容的规则。
StateArk 可免费使用,包括商业用途。有关唯一不允许的事项,请参阅上文的许可证。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。