关于 Scratchpad Mcp
Scratchpad Mcp 是为 AI Agent 提供持久化版本存储的 MCP 服务,可保存文件和只追加日志。它支持按 Agent 隔离数据、逐行差异比较,以及长文件摘要缓存。
主要功能
- 01文件版本存储与差异比较
- 02支持游标分页的只追加日志
- 03按 Agent 隔离数据
- 04按需生成并缓存文件摘要
- 05文件、日志与用量管理
适用场景
- 01跟踪 Agent 工作文件的变更
- 02记录并回放 Agent 操作历史
- 03为后续 Agent 轮次保存上下文
- 04按需概括长文件
MCP 相关
该服务向 MCP 客户端提供 8 个工具,用于文件和日志操作、摘要生成及用量统计。工具调用按 agent_id 隔离;README 指出该参数未经身份验证。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
scratchpad-mcp
为 AI Agent 提供持久化且节省 token 的存储。一个 MCP 服务,可避免 Agent 每轮都重新读取相同文件、重新加载相同上下文。
agent: "what changed in this file since I last read it?"
server: { diff: [...], current_version: 14 } ← not the whole file
为什么需要
Agent 会浪费 token。它们会重新读取已经看过的文件,重新总结已经处理过的文档,还会重新发现已经计算出的状态。这个服务为它们提供一个存放这些成果的地方,之后还能以模型可以低成本推理的方式继续使用。
具体来说:
- 带版本的写入,让 Agent 可以存储工作文档,并询问“自上次查看以来有哪些变化?”——服务会返回结构化差异,而不是完整内容。
- 仅追加日志,支持基于游标的分页,让 Agent 可以记录自身操作历史并高效重放。
- 按需生成摘要,针对较长文件(估算超过 2000 个 token),由 Claude Haiku 生成摘要,并按文件版本缓存,因此重复调用摘要不产生费用。
- 按 Agent 命名空间隔离,让一个服务实例可以服务多个 Agent,同时避免彼此间的状态泄露。
工具
所有工具都将 agent_id 作为第一个参数。操作仅限于对应 Agent 的范围——Agent 不能读取其他 Agent 的文件或日志。
| 工具 | 功能 |
|---|---|
write_file(agent_id, path, content) | 将内容存储到指定路径。每次写入都会自动创建新版本。保留最近的 10 个版本。 |
read_file(agent_id, path, since_version?) | 读取完整内容,或读取与较早版本相比的 JSON 行级差异。如果 since_version 对应的版本已被清理,则返回完整内容并附带 version_too_old: true。 |
append_log(agent_id, path, entry) | 向仅追加日志中追加一条记录。返回新记录的 ID。 |
read_log(agent_id, path, since_entry?) | 使用游标分页读取日志记录。每页 100 条记录,返回 has_more 标记和 last_entry_id 游标。 |
list_files(agent_id, prefix?) | 列出文件(仅包含元数据),可按路径前缀筛选。 |
delete_file(agent_id, path) | 删除文件及其所有版本和任何缓存的摘要。 |
summarize_file(agent_id, path) | 使用大模型总结较长文件(超过 8000 个字符)。按版本缓存,因此未更改文件的重复调用不产生费用。 |
get_usage_stats(agent_id) | 返回该 Agent 的总字节数、文件数、日志数和总操作数。 |
差异格式
read_file 配合 since_version 会返回一个由以下内容组成的 JSON 数组:
{
"diff": [
{ "op": "equal", "lines": ["line that didn't change"] },
{ "op": "remove", "lines": ["line that was deleted"] },
{ "op": "add", "lines": ["line that was added"] }
]
}
有意采用行级差异——这是 Agent 最容易可靠处理的格式,也让 Agent 可以推理发生了哪些变化,而不是重新处理整个文件。
路径规则
路径必须符合 [a-zA-Z0-9/_.-]+,最长 255 个字符,不能以 / 开头,也不能包含 .. 序列。错误信息会指出违反的规则。
限制
- 每次文件写入最大 1 MB
- 每条日志记录最大 64 KB
- 每个文件保留 10 个版本(较旧的版本会自动清理)
- 每页
read_log最多 100 条日志记录
安装
需要 Node 20+ 和 Anthropic API 密钥(仅 summarize_file 需要)。
git clone <this repo>
cd scratchpad-mcp
npm install
npm run build
这会生成可运行的服务 dist/index.js。
配置 Claude Desktop
添加到 %APPDATA%\Claude\claude_desktop_config.json(Windows)或
~/Library/Application Support/Claude/claude_desktop_config.json(macOS):
{
"mcpServers": {
"scratchpad": {
"command": "node",
"args": ["C:\\path\\to\\scratchpad-mcp\\dist\\index.js"],
"env": {
"ANTHROPIC_API_KEY": "sk-ant-..."
}
}
}
}
只有在打算调用 summarize_file 时才需要 ANTHROPIC_API_KEY。
其他七个工具无需该密钥即可使用。
可选:设置 SCRATCHPAD_DB_PATH 以覆盖 SQLite 文件位置。默认位于项目根目录下的 scratchpad.db。
重启 Claude Desktop。该服务应会出现在 MCP 服务列表中,并提供 8 个工具。
安全模型——托管前请先阅读
agent_id 是明文工具参数。这里没有身份验证:调用方可以声称自己是任意 agent_id,而服务器会信任它。这是 V1 的有意设计,适用于预期的部署方式:
- 每个服务器进程对应一位用户。 Agent 与 SQLite 文件处于同一信任边界内。例如:Claude Desktop 安装、本地安装 Smithery、每位用户单独运行的 Apify Actor(Apify 默认会为每次运行启动一个全新的容器,并使用一个全新的数据库文件)。
以下情况并不安全:
- 多租户待机模式,即一个服务器进程为多个不受信任的调用方提供服务,并由他们读写同一个 SQLite 文件。任何人都可以传入另一位调用方的
agent_id,读取或覆盖其数据。
如果需要多租户,请在包装层中根据调用方的 API 密钥生成 agent_id(这是 V2 计划),或为每个租户运行一个进程。
已实施的纵深防御
- 所有 SQL 都使用参数化查询——无法通过路径、agent_id 或前缀进行注入。
- 路径验证会拒绝
..、开头的/、空格,以及任何不在[a-zA-Z0-9/_.-]范围内的字符。 list_files前缀匹配使用SUBSTR相等判断(而非LIKE),因此 SQL 通配符_和%不会生效,且匹配区分大小写。- 单次调用的大小上限(每个文件 1 MB/每条日志 64 KB)。
- 每个 Agent 的配额(1000 个文件、10 万条日志、总计 100 MB),防止失控的 Agent 在托管部署中耗尽共享磁盘空间。
- 错误仅返回
err.message——不包含堆栈跟踪、SQLite 路径或 API 密钥。
summarize_file 的费用由谁支付?
始终由调用方支付。
- 本地安装(Smithery、Claude Desktop、mcp.so): 用户在配置中提供自己的
ANTHROPIC_API_KEY。用自己的机器、密钥,也由自己付费。 - Apify 托管: 每次 Actor 运行都会从该次运行的输入中读取
anthropicApiKey。.actor/entrypoint.sh启动脚本会在启动服务器前将其映射到环境变量中。每位调用方自行向 Anthropic 支付摘要费用;Actor 发布者只收取 Apify 的按次调用费用。
如果你 Fork 此项目并打算托管它,不要将 API 密钥硬编码到 Dockerfile、Apify Actor 环境中,或任何会公开发布的配置中。其他七个工具无需密钥,因此不设置密钥是安全的默认选择。
不同部署方式的持久性
这点很重要——不同的服务器运行方式有不同的持久性保障。请选择与工作负载相匹配的方式。
| 部署方式 | 持久性 | 数据丢失时机 |
|---|---|---|
| Claude Desktop/本地 Smithery/直接使用 stdio | 在本地磁盘上完全持久。 SQLite 文件位于项目旁边的 scratchpad.db。除非你删除文件,否则状态在重启、崩溃等情况下都会保留。 | 你删除文件时。 |
| Apify 托管(待机模式) | 仅限会话范围。 状态会在一个热运行的 Actor 实例内跨请求保留。冷启动时丢失。 | Actor 实例回收时:空闲超过 Idle timeout 秒、达到 Max requests per run 配额,或重新部署时。 |
| Smithery 托管(计划中) | 待定——等待 Smithery 支持持久卷。 |
Apify 这种部署方式非常适合单任务 Agent 会话(Agent 运行几分钟,调用数十次工具,便签数据在所有调用期间都会保留)。但它并不适合跨会话的长期记忆(Agent 希望读回自己昨天写入的内容)。针对这种需求,现阶段请使用本地安装,或等待 v0.2.0——下方路线图会跟踪这项工作。
存储的工作方式
所有内容都存储在一个 SQLite 文件中:
files— 每个(agent_id, path)对应一行,跟踪当前版本。file_versions— 每个版本的完整内容,每个文件最多保留最近 10 个版本。每次write_file时都会进行清理。log_entries— 仅追加条目,不会修改。summaries— 每个文件的摘要缓存,版本不匹配时失效。agent_usage— 每个 Agent 的操作计数器,供get_usage_stats使用。
版本控制会存储每个版本的完整内容(而非增量),因为写入需要快速,读取结果也必须明确。读取时会对两个版本进行逐行差异比较来计算差异 — 成本由请求差异的调用方承担,而不是由每个写入方承担。
路线图
- 为按调用付费计费提供 Apify 打包支持。
- 为托管部署提供 HTTP/SSE 传输方式。
- 在 Apify 上实现跨冷启动持久化。 写入时/关机时将 SQLite 文件同步到 Apify 的键值存储,以便状态在实例回收后仍能保留。计划在 v0.2.0 推出。
- 托管后端选项。 接入 libSQL/Turso(兼容 SQLite 的托管服务),作为本地 SQLite 的替代方案 — 无需繁琐的键值存储操作,即可在托管部署中实现长期持久化。
- 从 API 密钥派生
agent_id,而不是将其作为参数传入。 - 按 Agent 限流。
- 添加结构化日志,以便运维监控。
许可证
MIT — 详见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。