scratchpad-mcp
scratchpad-mcp
为 AI 代理提供持久化、Token 高效的存储。这是一个 MCP 服务器,可以防止你的代理在每一轮对话中重复读取相同的文件和重新加载相同的上下文。
agent: "what changed in this file since I last read it?"
server: { diff: [...], current_version: 14 } ← not the whole file为什么
代理会浪费 Token。它们会重复读取已经看过的文件,重新总结已经处理过的文档,并重新发现已经计算出的状态。该服务器为它们提供了一个存储这些工作成果的地方,以便后续以模型能够低成本推理的方式获取。
具体来说:
版本化写入:代理可以存储工作文档并询问“自上次查看以来发生了什么变化?”——服务器会返回结构化差异,而不是完整内容。
仅追加日志:支持基于游标的分页,代理可以记录自己的操作历史并高效地重放。
按需摘要:针对长文件(预估 >2000 Token)生成摘要,由 Claude Haiku 生成并按文件版本缓存,因此重复调用摘要是免费的。
按代理命名空间隔离:一个服务器实例可以服务多个代理,而不会在它们之间泄露状态。
工具
所有工具都将 agent_id 作为第一个参数。操作仅限于该代理——代理无法读取彼此的文件或日志。
工具 | 功能 |
| 在路径处存储内容。每次写入自动版本化。保留最近的 10 个版本。 |
| 读取完整内容,或针对先前版本的 JSON 行差异。如果 |
| 向仅追加日志添加一条记录。返回新的条目 ID。 |
| 使用游标分页读取日志条目。每页 100 条,包含 |
| 列出文件(仅元数据),可选择按路径前缀过滤。 |
| 删除文件及其所有版本和任何缓存的摘要。 |
| 对长文件(>8000 字符)进行 LLM 摘要。按版本缓存,因此对未更改的文件重复调用无需成本。 |
| 返回代理的总字节数、文件数、日志数和总操作数。 |
差异格式
带有 since_version 的 read_file 返回一个 JSON 块数组:
{
"diff": [
{ "op": "equal", "lines": ["line that didn't change"] },
{ "op": "remove", "lines": ["line that was deleted"] },
{ "op": "add", "lines": ["line that was added"] }
]
}行级差异是刻意设计的——这是代理处理最可靠的格式,它让代理能够推理出发生了什么变化,而不是重新处理整个文件。
路径规则
路径必须匹配 [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 版本的刻意设计,对于预期的部署形态工作良好,即:
每个服务器进程一个用户。 代理和 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/日志条目)。
每个代理的配额(1000 个文件,10 万条日志条目,100 MB 总量),防止失控的代理在托管部署中耗尽共享磁盘。
错误仅返回
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 环境或任何公开分发的配置中。其他七个工具无需密钥即可工作,因此将其留空是一个安全的默认设置。
存储工作原理
单个 SQLite 文件保存所有内容:
files— 每个(agent_id, path)一行,跟踪当前版本。file_versions— 每个版本的完整内容,每个文件最多保留 10 个最新版本。修剪发生在每次write_file时。log_entries— 仅追加条目,从不修改。summaries— 每个文件的摘要缓存,因版本不匹配而失效。agent_usage— 用于get_usage_stats的每个代理操作计数器。
版本控制存储每个版本的完整内容(而非增量),因为写入需要快速,读取需要明确。差异是在读取时通过对两个版本进行行级差异对比计算出来的——成本由请求差异的调用者承担,而不是由每个写入者承担。
路线图
[ ] 用于按次付费结算的 Apify 打包。
[ ] 从 API 密钥派生
agent_id,而不是将其作为参数。[ ] Postgres 后端(SQLite 模式是可移植的;这是一个连接交换,而不是重写)。
[ ] 每个代理的速率限制。
[ ] 用于操作可见性的结构化日志记录。
许可证
MIT — 参见 LICENSE。
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/MikePressure/scratchpad-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server