使用说明
克劳德存储器MCP
为Claude提供跨会话、上下文压缩和机器的持久内存。
claude plugins install github:ViktorBarzin/claude-memory-mcp
就是这样。克劳德现在能记住东西了。
它的作用
You: "remember I prefer Svelte for all new frontend apps"
Claude: Stored. ✓
── 3 weeks later, new session, different machine ──
You: "build me a dashboard for this API"
Claude: I'll set up a SvelteKit project since that's your preference...
无需配置 适用于单机使用。内存通过全文搜索存储在本地SQLite数据库中。对于多机同步,请将其指向API服务器(详细信息如下)。
特性
Slash命令
/remember <fact>--存储事实、偏好、决定或个人详细信息/recall <query>--按主题搜索记忆
自动行为(通过钩子)
- 汽车召回 --在回应之前,克劳德会检查存储的记忆中的相关上下文(偏好、过去的更正、决定)。用户完全看不见。
- 自动学习 --每次回复后,背景过程都会分析对话中的更正、偏好和值得记住的决定。使用俳句作为保守提取的判断标准。
- 压实存活率 --当Claude的上下文窗口压缩时,关键内存会保存到标记文件中,并在下一个提示时重新注入。知识不会丢失。
- 自动审批 --内存工具调用会自动获得批准,没有权限提示。
MCP工具
Claude在对话中可以直接访问这些工具:
| 工具 | 说明 |
|---|---|
memory_store |
使用类别、标签、重要性和语义搜索关键字存储事实 |
memory_recall |
使用扩展查询词的全文搜索搜索内存 |
memory_list |
列出最近的记忆,可选择按类别筛选 |
memory_delete |
按ID删除内存 |
secret_get |
检索敏感内存的解密内容 |
memory_count |
按类别获取内存计数并同步状态诊断 |
memory_share |
与其他用户共享内存(读或写访问) |
memory_unshare |
撤销用户共享内存 |
memory_share_tag |
用标签分享所有回忆(实时规则——包括未来的回忆) |
memory_unshare_tag |
撤销基于标签的共享 |
memory_update |
更新现有内存的内容、标签或重要性 |
memory_shared_with_me |
列出他人与你分享的回忆 |
memory_my_shares |
列出您创建的所有共享规则 |
共享工具需要API连接(在SQLite-only模式下不可用)。
内存类别
记忆被组织成: facts, preferences, projects, people, decisions
敏感内存支持
将记忆标记为敏感 force_sensitive: true。配置Vault后,敏感内容在静止状态下加密,只能通过以下方式解密 secret_get.
有限记忆和类型链接
每 ADR-0007,内存是唯一存储的单元,其内容为 硬边界为1400个unicode字符 --大小使得召回的记忆总是在召回钩的注入预算内完整到达。API拒绝使用 HTTP 422;第一方客户端(MCP服务器、钩子、OpenClaw插件)使用相同的消息进行预验证。知识太大,无法容纳一个内存被分割 作者 分成几个 独立的 记忆——每一段都是可以理解的,从来不是“M的N部分”的片段。
记忆由以下元素连接 键入、定向链接 (四个封闭枚举),每个都有定义的回忆行为:
| 链接类型 | 方向 | 召回行为 |
|---|---|---|
supersedes 新→ 老 |
继任人已任职 代替 每当旧条目排名(重定向)时 | |
resolved-by |
症状→ 当前真相 | 目标是 自动连接 当源排名时,答案会在不进行第二次查找的情况下到达 |
part-of |
细节→ hub | 一个指向两个方向的直线指针;按需获取的内容 |
see-also |
相关 | 一行指针;无其他行为 |
GET /api/memories/{id} 返回一个完整的条目及其双向链接。链接是PostgreSQL/API的一项功能(ADR-0002 保持SQLite词法): 链接不同步到SQLite模式 --内存行与以前一样同步;链接边缘仅存在于服务器上。
建筑学
Claude Code Session
┌──────────────────────────────────────────────────────┐
│ Hooks MCP Server │
│ ┌──────────────────┐ ┌────────────────────┐ │
│ │ auto-recall │───────▶│ memory_store │ │
│ │ auto-learn │ │ memory_recall │ │
│ │ compaction │ │ memory_list │ │
│ │ auto-approve │ │ memory_delete │ │
│ └──────────────────┘ │ secret_get │ │
│ │ memory_count │ │
│ └─────────┬──────────┘ │
│ │ │
│ ┌─────────────────────────┼──────────┐ │
│ │ Local SQLite │ │ │
│ │ (cache + FTS5) SyncEngine │ │
│ │ ◄──── always ────(background, 60s) │ │
│ │ used push queued writes │ │
│ │ pull server changes│ │
│ │ pending_ops ──────────┘ │ │
│ │ (offline write queue) │ │
│ └────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
│
optional, for multi-machine sync
│
┌──────────▼───────────┐
│ API Server (FastAPI) │
│ Docker / Kubernetes │
└──────────┬───────────┘
│
┌──────────▼───────────┐
│ PostgreSQL │
│ (authoritative) │
└──────────────────────┘
同步弹性
SyncEngine旨在优雅地处理故障:
- 解耦推/拉 --推失败永远不会阻止拉。来自其他代理的远程更改总是会流入。
- 身份验证失败检测 --在401/403上,引擎设置了一个认证失败标志,记录了一个明确的警告,并降级为仅SQLite模式。定期健康检查检测身份验证何时恢复。
- 启动完全重新同步 --在MCP服务器启动时,会运行一个完整的缓存替换来捕获其他代理的漂移、删除的记录和模式更改。
- 定期完全重新同步 --每大约10分钟,一次完整的重新同步就会取代增量同步,以捕捉任何漂移。
- 重试盖子 --单个挂起的操作最多重试5次,然后永久跳过以防止队列堆积。
- 孤儿和解 --在推送之前,从未同步的本地记录会根据服务器内容进行重复数据消除。
搜索算法
内存调用根据操作模式使用两种不同的全文搜索后端。两者都遵循相同的查询构建模式: context 和 expanded_query 用户召回请求中的字段被连接成一个搜索字符串,然后被处理成特定于后端的查询。
查询构造
当 memory_recall 当被调用时,该工具接收到:
context--被问及的主题或问题expanded_query--必需,至少5个空格分隔的语义相关术语,由Claude生成
这些被连接起来: all_terms = f"{context} {expanded_query}",然后拆分成单个单词供搜索后端使用。
SQLite:带BM25的FTS5
本地SQLite数据库使用 FTS5虚拟桌 对于全文搜索,请使用 BM25 排名算法。
架构:
CREATE VIRTUAL TABLE memories_fts USING fts5(
content, category, tags, expanded_keywords,
content='memories', content_rowid='id'
);
这是一个 目录 由 memories 表--FTS5从中读取列数据 memories 按需而不是复制它。INSERT、UPDATE和DELETE上的触发器使FTS索引保持同步:
-- Insert trigger
CREATE TRIGGER memories_ai AFTER INSERT ON memories BEGIN
INSERT INTO memories_fts(rowid, content, category, tags, expanded_keywords)
VALUES (new.id, new.content, new.category, new.tags, new.expanded_keywords);
END;
-- Delete trigger (FTS5 special 'delete' command)
CREATE TRIGGER memories_ad AFTER DELETE ON memories BEGIN
INSERT INTO memories_fts(memories_fts, rowid, content, category, tags, expanded_keywords)
VALUES ('delete', old.id, old.content, old.category, old.tags, old.expanded_keywords);
END;
-- Update trigger (delete old + insert new)
CREATE TRIGGER memories_au AFTER UPDATE ON memories BEGIN
INSERT INTO memories_fts(memories_fts, rowid, ...)
VALUES ('delete', old.id, old.content, old.category, old.tags, old.expanded_keywords);
INSERT INTO memories_fts(rowid, content, category, tags, expanded_keywords)
VALUES (new.id, new.content, new.category, new.tags, new.expanded_keywords);
END;
查询建筑: 每个单词都被引用并与OR连接:
words = all_terms.split()
fts_query = " OR ".join(f'"{w}"' for w in words if w)
# Example: "kubernetes" OR "deployment" OR "pod" OR "scaling" OR "replicas"
排名: 两种排序模式(默认 relevance根据ADR-0005修正案):
sort_by="relevance"(默认)--ORDER BY (-bm25(memories_fts) * 0.7 + importance * 0.3) DESC--FTS5的内置BM25相关性得分占主导地位,其重要性与优先级相同sort_by="importance"—ORDER BY (-bm25(memories_fts) * 0.4 + importance * 0.6) DESC--用户分配的重要性占主导地位,相关性是决定性因素
退路: 如果FTS5 MATCH查询失败(例如特殊字符的语法错误),搜索将回退到 LIKE %query% 扫描 content 和 tags 柱。
PostgreSQL:带加权排名的tsvector
API服务器使用PostgreSQL的本机 全文检索 a生成 tsvector 列和加权排名。
模式 (来自移民 001):
CREATE TABLE memories (
id SERIAL PRIMARY KEY,
content TEXT NOT NULL,
category VARCHAR(50) DEFAULT 'facts',
tags TEXT DEFAULT '',
expanded_keywords TEXT DEFAULT '',
importance REAL DEFAULT 0.5,
-- ...
search_vector tsvector GENERATED ALWAYS AS (
setweight(to_tsvector('english', coalesce(content, '')), 'A') ||
setweight(to_tsvector('english', coalesce(expanded_keywords, '')), 'B') ||
setweight(to_tsvector('english', coalesce(tags, '')), 'C') ||
setweight(to_tsvector('english', coalesce(category, '')), 'D')
) STORED
);
CREATE INDEX idx_memories_search ON memories USING GIN(search_vector);
这 search_vector 是一个 生成列 PostgreSQL在每次插入/更新时都会自动维护——不需要触发器。它结合了四个权重不同的字段:
| 重量 | 场地 | 用途 |
|---|---|---|
| A. (最高) | content |
实际内存文本——对匹配最重要 |
| B | expanded_keywords |
Claude在商店时生成的语义搜索词 |
| C | tags |
用户提供的逗号分隔标签 |
| D (最低) | category |
类别名称(事实、偏好等) |
A. GIN指数 上 search_vector 无需顺序扫描即可快速查找。
查询执行:
SELECT id, content, category, tags, importance, is_sensitive,
ts_rank(search_vector, query) AS rank,
created_at, updated_at
FROM memories, plainto_tsquery('english', $2) query
WHERE user_id = $1
AND deleted_at IS NULL
AND (search_vector @@ query OR $2 = '')
ORDER BY (ts_rank(search_vector, query) * 0.7 + importance * 0.3) DESC
LIMIT $3
plainto_tsquery 通过PostgreSQL的英文文本搜索字典处理连接的查询文本——它处理词干(例如“running”)→ “run”)、停止单词删除和规范化。这 @@ 运算符匹配结果 tsquery 针对存储 tsvector.
ts_rank 根据比赛场地的权重对每场比赛进行评分—— content (权重A)得分高于比赛 tags (重量C)。
排序模式 (默认值 relevance,根据ADR-0005修正案——重要性明确可用):
sort_by="relevance"(默认)--ORDER BY (ts_rank(search_vector, query) * 0.7 + importance * 0.3) DESCsort_by="importance"—ORDER BY (ts_rank(search_vector, query) * 0.4 + importance * 0.6) DESCsort_by="recency"—ORDER BY created_at DESC
结果限制: limit 默认为 30 --recall返回一小部分前N个最相关的匹配项,而不是整个商店。对于明确选择加入更多的呼叫者,上限为10000。
或扩大回退范围: 上面的查询是AND匹配(plainto_tsquery 要求每个查询词都存在)。当返回值小于 limit 如果行和查询有多个单词,召回范围扩大到OR匹配(to_tsquery 将单词连接起来 |)以填充结果集。那些加宽的行是按顺序排列的 ts_rank 相关性(如 sort_by="relevance")并且必须清除最低等级(OR_BROADEN_MIN_RANK = 0.01)--只附带包含一个查询词的内存会作为噪声丢弃,而不是填充结果。
商店时间的语义扩展
当克劳德通过以下方式存储内存时 memory_store,它生成一个 expanded_keywords 字段——至少5个空格分隔的语义相关术语。例如,存储“用户更喜欢Svelte作为前端”可能会产生:
expanded_keywords: "svelte frontend framework ui web sveltekit javascript component reactive"
这些关键字与内存内容一起被索引。当未来 memory_recall 搜索“我应该为仪表板使用什么框架?”,扩展的关键字会创建纯内容匹配会错过的额外匹配表面。这是LLM在编写时执行的一种查询扩展形式。
SQLite与PostgreSQL的比较
| 功能 | SQLite(FTS5) | PostgreSQL(tsvector) |
|---|---|---|
| 标记化 | ICU/unicode61标记器 | 英文文本搜索词典 |
| 词干 | 否(精确单词匹配) | 是(波特词干分析器通过 english 配置) |
| 停用词 | 否 | 是(删除“the”、“is”、“at”等) |
| 排名 | BM25(词频+逆文档频率) | ts_rank (加权字段匹配) |
| 字段权重 | 否(所有FTS5列相等) | 是(每列A/B/C/D权重) |
| 索引类型 | FTS内容上的B树 | GIN(广义倒排索引) |
| 查询语法 | 引号或术语("word1" OR "word2") |
plainto_tsquery 隐式AND |
| 回退 | 失败时进行LIKE扫描 | 不需要(强大的解析器) |
| 维护 | 触发同步内容↔ FTS表 | 生成列,自动维护 |
| 键入链接(ADR-0007) | 否--链接不同步到SQLite模式 | 是(memory_links,随后召回) |
操作模式
| 模式 | 何时 | 发生什么 |
|---|---|---|
| 仅限SQLite | 没有设置环境变量 | 所有内容都是本地的。零配置。离线工作。 |
| 混合 | MEMORY_API_KEY 设置 |
本地SQLite用于读取+后台同步到API。若API关闭,则写入队列。 |
| 仅限HTTP | MEMORY_API_KEY + MEMORY_SYNC_DISABLE=1 |
直接调用API,无本地缓存。传统模式。 |
| 满的 | 任何模式+配置Vault | 以上+用于加密静止敏感内存的Vault |
设置
选项1:插件安装(推荐)
claude plugins install github:ViktorBarzin/claude-memory-mcp
立即适用于仅SQLite模式。要启用多机同步,请执行以下操作:
export MEMORY_API_URL="https://your-server.example.com"
export MEMORY_API_KEY="your-api-key"
选项2:手动MCP配置
添加到 ~/.claude.json 在...之下 mcpServers:
{
"mcpServers": {
"claude_memory": {
"type": "stdio",
"command": "python3",
"args": ["/path/to/claude-memory-mcp/src/claude_memory/mcp_server.py"],
"env": {
"PYTHONPATH": "/path/to/claude-memory-mcp/src",
"MEMORY_API_URL": "https://your-server.example.com",
"MEMORY_API_KEY": "your-api-key"
}
}
}
}
省略 MEMORY_API_URL 和 MEMORY_API_KEY 仅适用于SQLite模式。
验证
You: /remember "I prefer dark mode in all applications"
You: /recall "UI preferences"
运行API服务器
仅适用于多机同步。如果您使用的是仅SQLite模式,请跳过此步骤。
Docker Compose
cd docker
docker compose up -d
启动API服务器+PostgreSQL。(可选)添加Vault:
docker compose --profile vault up -d
手册
pip install claude-memory-mcp[api]
export DATABASE_URL="postgresql://user:pass@localhost:5432/claude_memory"
export API_KEY="your-secret-key"
alembic upgrade head
uvicorn claude_memory.api.app:app --host 0.0.0.0 --port 8000
Kubernetes
专为高可用性而设计:2个具有pod反亲和性、PodDisruptionBudget和启动探测的副本。
helm install claude-memory deploy/helm/claude-memory \
--set env.DATABASE_URL="postgresql://user:pass@host:5432/db" \
--set env.API_KEY="your-key" \
--set ingress.host="claude-memory.yourdomain.com"
或原始清单:
kubectl apply -f deploy/kubernetes/namespace.yaml
kubectl create secret generic claude-memory-secrets \
-n claude-memory \
--from-literal=database-url="postgresql://user:pass@host:5432/db" \
--from-literal=api-key="your-key"
kubectl apply -f deploy/kubernetes/
多用户设置
对于团队部署,请使用 API_KEYS 使用JSON映射:
export API_KEYS='{"alice": "key-alice-xxx", "bob": "key-bob-yyy"}'
默认情况下,每个用户都会获得隔离的内存存储。用户可以有选择地相互分享记忆。
存储器共享
用户可以与其他用户共享个人记忆或整个标签:
You: "share memory #42 with bob as read-only"
You: "share all memories tagged 'infra' with alice with write access"
个人股 授予对特定内存的访问权限。 标记共享 是实时规则——任何带有该标签的未来内存都会自动对目标用户可见。
权限级别:
read--可以在回忆结果中看到记忆write--还可以更新内存的内容、标签和重要性
即使其他人有写权限,也只有所有者可以删除内存。共享记忆出现在 memory_recall 结果与 shared_by 和 share_permission 领域。
添加用户:
- 生成密钥:
openssl rand -base64 32 - 添加到
API_KEYSJSON - 重新启动API服务器
- 与用户共享密钥
敏感记忆与秘密
敏感数据通过多层系统处理:
自动检测
credential_detector.py 使用具有置信度分数(0.5-0.95)的正则表达式模式扫描所有传入内容中的秘密:
| 置信度 | 模式类型 |
|---|---|
| 0.95 | 私钥(RSA/EC/DSA/OPENSSH)、AWS访问密钥(AKIA/ASIA),GitHub代币(ghp_/gho_/等等。) |
| 0.85–0.90 | 连接字符串(postgres/mysql/mongdb/redis/amqp)、基本身份验证标头、承载令牌 |
| 0.75–0.80 | api_key=, password=, token= 作业 |
| 0.60–0.65 | 通用 secret=/credential= 图案,十六进制键 |
检测到的内容为 已编辑 在主DB中(例如。, [REDACTED:private_key])原始文件存储在Vault或加密存储中。
静态加密
按顺序检查的三层:
- HashiCorp Vault (KV v2)——如果
VAULT_ADDR+VAULT_TOKEN集。秘密存储在claude-memory/{user_id}/mem-{id}支持Kubernetes服务帐户自动身份验证。 - AES-256-GCM --如果
MEMORY_ENCRYPTION_KEY集。密钥可以是十六进制编码的32字节或密码(通过SHA-256导出)。存储为nonce (12 bytes) + ciphertext + GCM tag (16 bytes)在encrypted_content列。 - 明文回退 --内容按原样存储(如果检测到敏感,仍会在主列中编辑)。
通过以下方式检索原件 secret_get(id=<memory_id>).
插件挂钩
| Hook | 事件 | 它的作用 |
|---|---|---|
pre-compact-backup.sh |
PreCompact | 在上下文压缩之前将前20个内存保存到标记文件中 |
post-compact-recovery.sh |
UserPromptSubmit | 压缩后重新注入保存的内存(一次性,然后删除标记) |
user-prompt-recall.py |
UserPromptSubmit | 告诉Claude检查 memory_recall 在回复每条消息之前 |
auto-learn.py |
Stop(async) | 在最后一次交换中运行俳句作为判断,以提取值得存储的持久事实 |
auto-allow-memory-tools.py |
权限请求 | 自动批准 memory_store, memory_recall, memory_list, memory_delete, secret_get |
自动学习详细信息
自动学习钩子在每次Claude响应后异步运行。它以两种模式运行:
- 单轮 (每一轮)——只分析最后一次用户/助理交换。便宜又快。提取更正、偏好、决定和事实。
- 深度多转弯 (每5轮)——将最后5次交易所作为一个窗口进行分析。还提取调试见解、解决方法和操作知识。
法官回退链: 克劳德CLI(俳句模式)→ 当地奥利玛(qwen2.5:3b/llama3.2:3b/gemma2:2b/phi3:mini)→ 启发式模式匹配(基于关键字从用户消息中提取)。
提取的事件通过SHA-256内容哈希进行重复数据消除。每个事件都存储在MCP内存数据库中。
调试
# See what hooks are doing
export DEBUG_CLAUDE_MEMORY_HOOKS=1
# Disable auto-approve to see permission prompts
export DISABLE_CLAUDE_MEMORY_AUTO_APPROVE=1
后台同步引擎
在混合动力模式下,a SyncEngine 在具有自己SQLite连接的守护进程线程中运行(通过 threading.Lock).
推送周期: 阅读 pending_ops 队列(SQLite表),并将每个操作发送到API。成功后,从队列中删除操作并更新本地 server_id 地图。如果失败,操作将排队等待下一个循环。
拉动周期: 呼叫 GET /api/memories/sync?since=<last_sync_ts> 对于增量更改。服务器在冲突中获胜——远程更新覆盖本地行(由匹配 server_id).服务器上的软删除行在本地被硬删除。只有内存行同步: 键入的链接(ADR-0007)不同步到SQLite模式 -它们是一个API/PostgreSQL特性,在服务器端调用时遵循。
永久性拒收: 用HTTP 422应答的推送(例如,超过1400个字符的内容)是确定的——操作会立即被丢弃,并记录服务器的详细信息,而不是消耗重试周期。客户端预验证 memory_store/memory_update 首先防止过大的行进入本地商店。
写入路径: 每 memory_store 首先写入本地SQLite(即时),然后尝试立即同步到API。如果立即同步失败,则写入被排队 pending_ops 用于下一个背景循环。
同步间隔: 可通过以下方式配置 MEMORY_SYNC_INTERVAL (默认值:60秒)。
API 参考
| 端点 | 方法 | 描述 |
|---|---|---|
/health |
GET | 健康检查(未经身份验证) |
/api/auth-check |
GET | 验证API密钥而不产生副作用 |
/api/memories |
POST | 存储内存(内容>1400个字符→ 422 分体式引导) |
/api/memories |
GET | 列出记忆(?category=facts&limit=20) |
/api/memories/recall |
POST | 按上下文和扩展查询搜索内存(默认 sort_by=relevance) |
/api/memories/{id} |
GET | 获取一个完整的内存,其中包含双向键入的链接 |
/api/memories/{id} |
PUT | 更新内存(所有者或写共享用户;相同的1400个字符绑定) |
/api/memories/{id} |
DELETE | 软删除内存(仅限所有者) |
/api/memories/{id}/share |
POST | 与用户共享内存 |
/api/memories/{id}/share/{user_id} |
DELETE | 撤销用户的共享 |
/api/memories/share-tag |
POST | 用标签分享所有回忆 |
/api/memories/share-tag |
DELETE | 撤销基于标签的共享 |
/api/memories/shared-with-me |
GET | 列出与当前用户共享的内存 |
/api/memories/my-shares |
GET | 列出当前用户创建的共享规则 |
/api/memories/sync |
GET | 增量同步(?since=ISO-timestamp) |
/api/memories/{id}/secret |
POST | 获取解密的敏感内存内容 |
/api/memories/migrate-secrets |
POST | 使用当前Vault配置重新加密现有机密 |
/api/memories/import |
POST | 批量导入内存(JSON数组) |
除以下端点外的所有端点 /health 需要 Authorization: Bearer <api-key>.
环境变量
MCP服务器(客户端)
| 变量 | 描述 | 默认值 |
|---|---|---|
MEMORY_API_URL |
API服务器URL | http://localhost:8080 |
MEMORY_API_KEY |
API密钥(启用混合模式) | 无 |
MEMORY_HOME |
本地存储目录 | ~/.claude/claude-memory |
MEMORY_DB |
SQLite数据库路径覆盖 | $MEMORY_HOME/memory/memory.db |
MEMORY_SYNC_INTERVAL |
后台同步间隔(秒) | 60 |
MEMORY_SYNC_DISABLE |
设置为 1 仅HTTP模式 |
无 |
别名 CLAUDE_MEMORY_API_URL 和 CLAUDE_MEMORY_API_KEY 也得到了支持。
API服务器
| 变量 | 描述 | 默认值 |
|---|---|---|
DATABASE_URL |
PostgreSQL连接字符串 | 必填 |
API_KEY |
单个用户API密钥 | 无 |
API_KEYS |
多用户JSON映射 {"user": "key"} |
没有 |
VAULT_ADDR |
Vault服务器地址 | 无 |
VAULT_TOKEN |
Vault身份验证令牌 | 无 |
VAULT_ROLE |
Kubernetes身份验证角色名称 | claude-memory |
MEMORY_ENCRYPTION_KEY |
用于非Vault加密的AES-256密钥 | 无 |
数据库迁移
PostgreSQL(API服务器)
迁移在API服务器启动时自动运行。要手动运行,请执行以下操作:
export DATABASE_URL="postgresql://user:pass@localhost:5432/claude_memory"
alembic upgrade head
四次迁移:
001--创建memories生成的表格tsvector列和GIN索引002--添加user_id(多用户),is_sensitive,vault_path,encrypted_content003--添加deleted_at(软删除)和updated_at增量同步索引004--添加memory_shares和tag_shares多用户共享表
所有迁移都是幂等的(在更改之前检查列/表是否存在)。
SQLite(MCP客户端)
SQLite模式通过以下方式进行版本控制 PRAGMA user_version 并在启动时自动迁移。当前版本: 2.
| 版本 | 迁移 |
|---|---|
| 1 | 添加 server_id 列到 memories 桌子 |
| 2 | 添加 retry_count 列到 pending_ops 桌子 |
发展
先决条件
- Python 3.11+
- 对于API服务器测试:
httpx,pytest-asyncio
快速开始
git clone https://github.com/ViktorBarzin/claude-memory-mcp.git
cd claude-memory-mcp
python -m venv .venv
source .venv/bin/activate
pip install -e ".[api,dev]"
运行测试
# All tests
pytest tests/ -v
# Individual test suites
pytest tests/test_sync.py -v # SyncEngine (client-side sync resilience)
pytest tests/test_mcp_server.py -v # MCP server (SQLite, tools, protocol)
pytest tests/test_api.py -v # API server (FastAPI endpoints)
# Linting
ruff check src/ tests/
mypy src/claude_memory/ --strict
MCP服务器本身(mcp_server.py 和 sync.py)用途 仅限stdlib --客户端不需要安装pip。这 [api] extra为服务器添加了FastAPI、asyncpg、uvicorn等。
测试结构
| 文件 | 测试 | 它涵盖了什么 |
|---|---|---|
test_sync.py |
SyncEngine单元测试 | 推/拉、身份验证失败处理、重试上限、完全重新同步、孤立协调、解耦推/拉和诊断 |
test_mcp_server.py |
MCP服务器单元测试 | SQLite CRUD、FTS搜索、工具调度、MCP协议、内存计数、模式迁移 |
test_api.py |
API服务器集成测试 | 所有REST端点、身份验证、用户隔离、软删除、同步、机密、导入 |
test_auth.py |
身份验证模块测试 | 单用户/多用户身份验证、密钥映射 |
test_credential_detector.py |
凭证检测 | 机密的模式匹配 |
test_crypto.py |
加密测试 | AES-256加密/解密 |
test_vault_client.py |
保险库集成 | 秘密存储/检索 |
项目结构
claude-memory-mcp/
├── src/claude_memory/
│ ├── mcp_server.py # MCP server entry point (stdio NDJSON)
│ ├── sync.py # Background sync engine (SQLite ↔ API)
│ ├── credential_detector.py # Sensitive content detection
│ └── api/
│ ├── app.py # FastAPI application
│ ├── auth.py # API key authentication
│ ├── database.py # asyncpg connection pool
│ ├── models.py # Pydantic models
│ ├── permissions.py # Sharing permission checks
│ └── vault_service.py # HashiCorp Vault integration
├── tests/ # pytest test suite
├── hooks/ # Claude Code hooks (auto-recall, auto-learn, etc.)
├── docker/ # Docker Compose for API server + PostgreSQL
├── deploy/ # Kubernetes manifests and Helm chart
└── pyproject.toml # Package config (hatchling)
关键设计决策
- 仅支持stdlib的MCP服务器:MCP服务器(
mcp_server.py,sync.py)仅使用Python stdlib,客户端不需要安装pip。这确保了它在任何没有依赖关系管理的Claude Code环境中都能工作。 - NDJSON传输:Claude Code对stdio MCP使用NDJSON(每行一个JSON),而不是Content-Length框架。
- 无阻塞启动:MCP服务器启动必须在~15秒内完成,否则克劳德代码超时。所有网络调用都被推迟到后台线程。
- 抑制stderr:MCP启动期间的任何stderr输出都会导致Claude Code拒绝服务器。
许可证
Apache许可证2.0。看 许可证 了解详情。