内容
# mneo
**用于 AI 代理的持久性内存。无需向量数据库,无需守护进程。只需 git。**
> mneo 存在的原因及其拒绝成为什么:[MANIFESTO.md](MANIFESTO.md)。
你的编码代理忘记了昨天在 `feat/auth` 中发现的内容。互联网的答案是向量数据库、嵌入式管道、守护进程和每月 20 美元的 SaaS。
git 已经可以做到这一点。
```bash
$ git show refs/agent-memory/feat-auth/oauth-flow:note.md
拒绝 JWT — 用于 SSR 的会话 cookie。不要重新提议。
```
分支是作用域。引用是存储。`push` 和 `fetch` 是同步。五个动词,零基础设施。
```ts
record({ body }) // 保存有效的内容
list({}) // 当前分支的标题
read({ slug }) // 展开一个标题
copy({ from, to, slug }) // 推广过去的合并
forget({ slug }) // 过时
```
作为 [MCP 服务器](https://modelcontextprotocol.io) 与 Claude Code 一起发布,或用于任何代理的 TypeScript SDK。约 1500 行 TypeScript 代码。SDK 中没有运行时依赖。笔记在卸载后仍然存在。
---
## 存储方式
```
refs/agent-memory/feat-auth/oauth-flow
refs/agent-memory/main/architecture
refs/agent-memory/main/db-schema
```
每个笔记一个 git 引用。分支名称中的斜杠变为破折号(`feat/auth` → `feat-auth`)。笔记的第一行成为提交主题 — 这就是 `list` 返回的标题。
像代码一样检查:
```bash
git log refs/agent-memory/feat-auth/oauth-flow
git show refs/agent-memory/feat-auth/oauth-flow:note.md
```
像代码一样同步:
```bash
git push origin 'refs/agent-memory/*:refs/agent-memory/*'
git fetch origin '+refs/agent-memory/*:refs/agent-memory/*'
```
---
## 安装
```bash
npm install -g mneo mneo-mcp
# 或零安装:
npx -y mneo <子命令>
```
需要 Node `>=18` 和 `git >= 2.31`。
---
## 连接到 Claude Code
一条命令:
```bash
cd your-project
npx -y mneo install
```
三个部分位于 `.claude/` 中:
1. **会话启动钩子**,在 `startup | resume | clear | compact` 时自动注入最近的标题。失败退出 0 — 损坏的内存永远不会阻止代理。
2. **MCP 服务器**,公开 `record`、`list`、`read`、`forget`、`copy`、`push`、`fetch`。
3. **技能文件**,位于 `.claude/skills/mneo/SKILL.md`,告诉模型何时调用哪个动词。
原子且幂等。重新运行 `mneo install` 会将每个部分报告为 `unchanged`;不相关的 `settings.json` 键会被保留。
<details>
<summary>手动安装(无编排器)</summary>
```bash
npx -y mneo init-hook # 1. 仅会话启动钩子
```
```jsonc
// 2. .claude/settings.json — MCP 服务器条目
{
"mcpServers": {
"mneo": { "command": "npx", "args": ["-y", "mneo-mcp"] }
}
}
```
```bash
# 3. 技能文件
mkdir -p .claude/skills/mneo
ln -s "$(pwd)/SKILL.md" .claude/skills/mneo/SKILL.md
```
</details>
---
## 从任何语言使用
用于 bash、Python、Rust 的代理 — 任何可以启动进程的语言。机器使用 `--json`,默认情况下人类使用单行命令。`MneoError` 时退出 `1`(代码在 stderr 上),`2` 在使用时。
```bash
echo "决策主体" | mneo record --slug oauth/flow --json
mneo list --prefix oauth/ --limit 5 --json
mneo read --slug oauth/flow --json
mneo copy --from feat-x --to main --slug oauth/flow --json
mneo forget --slug oauth/flow --json
```
`record` 通过 `--body` 或 stdin 读取主体。所有动词都接受 `--scope` 以覆盖自动检测的分支。`copy` 需要 `--from` 和 `--to`,以及 `--slug`(单个)或 `--prefix`(批量);省略两者以复制整个源范围。
---
## 信任边界
笔记主体成为每个代理回合的受信任提示上下文。**作用域是信任边界。** 任何具有 `refs/agent-memory/<scope>/*` 写访问权限的人都可以植入一个笔记,您的代理将在下一个会话中读取并视为指令。
`refs/agent-memory/*` 默认不会被推送 — 同步是可选的。如果您连接它,请像对待代码推送一样对待内存推送。
防御措施:
- 会话启动钩子将包裹在 `<mneo-memory>` 标签中,告诉模型将内容视为数据,而不是指令。始终开启。
- 设置 `MNEO_REQUIRE_SIGNED=1` 以控制 `list` 和 `read` 的 `git verify-commit`。建议在从您不完全控制的远程获取 `refs/agent-memory/*` 时使用。
完整的威胁模型:[SECURITY.md](SECURITY.md)。
---
## 配置
| 变量 | 默认值 | 用途 |
|---|---|---|
| `MNEO_REPO` | 从 cwd 向上查找 | 仓库路径覆盖 |
| `MNEO_SCOPE` | 当前分支 | CI / 分离的 HEAD / 分支冲突消歧义 |
| `MNEO_AUTHOR` | `mneo <agent@mneo>` | 用代理的身份标记提交 |
| `MNEO_REQUIRE_SIGNED` | 未设置 | `1` 或 `true` → 拒绝未签名的笔记(`UntrustedError`) |
每次调用作者覆盖:向 `record` 传递 `by`。
---
## 为什么不是向量数据库?
- LLM 在提示上下文检索方面优于任何嵌入模型。`list → read` 足够了。
- 向量数据库需要守护进程、索引和嵌入 API。git 已经在每个开发人员的机器上。
- 分支免费提供作用域。RAG 用元数据过滤器重新实现此功能。
- 标签、重要性、方面 — 在 slug 中编码它们。约定胜过分类法。
- 没有 TTL。`git gc` 在 `gc.pruneExpire` 后回收无法访问的对象(默认为 `forget` 后 14 天)。
API 的形状适用于 LLM 调用者:工具描述是模型指令,错误是恢复提示,哨兵(`*`)位于一个与有效输入不相交的命名空间中。没有针对优化的 UI。
---
## 限制
| | |
|---|---|
| 正文 | 5000 个字符 |
| slug | `^[a-z0-9][a-z0-9-/]*$`,≤80 个字符 |
| 作用域 | `^[a-z0-9][a-z0-9-]*$`,≤80 个字符 |
| 标题 | 正文的前 80 个字符 |
`record` 是幂等的:相同的 `(scope, slug, body)` 返回 `{ unchanged: true }` 并且不会创建新的提交。
`list({})` 默认情况下默认为最近 30 天,最多 50 条记录。结果带有 `hidden` / `untrusted` / `skewed` / `more` 计数器,以便调用者可以检测到过滤器丢弃的数据 — 通过增加 `maxAgeDays` 或 `limit` 来显示它。
`forget({ scope: "*" })` 从每个作用域中删除 slug。要立即清除泄漏的秘密:
```bash
git reflog expire --expire=now --all && git gc --prune=now
```
---
## 贡献
```bash
git clone git@github.com:HugoLopes45/mneo.git
cd mneo
bun install
bun test
bun run lint
```
Bun `>=1.3.0`。`bun.lock` 是规范的。分支:`feat/<short-name>` 来自 `main`。参见 [CONTRIBUTING.md](CONTRIBUTING.md)。
---
## 致谢
灵感来自 [Mourad Ghafiri 的 `git-notes-memory`](https://github.com/mourad-ghafiri/git-notes-memory)。
## 许可证
[MIT](LICENSE)。