持久记忆插件

为Claude提供跨会话的持久记忆功能,支持本地SQLite存储和多机器同步。

  • by ViktorBarzin
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 ViktorBarzin/claude-memory-mcp

使用说明

克劳德存储器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) DESC
  • sort_by="importance" — ORDER BY (ts_rank(search_vector, query) * 0.4 + importance * 0.6) DESC
  • sort_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 领域。

添加用户:

  1. 生成密钥: openssl rand -base64 32
  2. 添加到 API_KEYS JSON
  3. 重新启动API服务器
  4. 与用户共享密钥

敏感记忆与秘密

敏感数据通过多层系统处理:

自动检测

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或加密存储中。

静态加密

按顺序检查的三层:

  1. HashiCorp Vault (KV v2)——如果 VAULT_ADDR + VAULT_TOKEN 集。秘密存储在 claude-memory/{user_id}/mem-{id}支持Kubernetes服务帐户自动身份验证。
  2. AES-256-GCM --如果 MEMORY_ENCRYPTION_KEY 集。密钥可以是十六进制编码的32字节或密码(通过SHA-256导出)。存储为 nonce (12 bytes) + ciphertext + GCM tag (16 bytes) 在 encrypted_content 列。
  3. 明文回退 --内容按原样存储(如果检测到敏感,仍会在主列中编辑)。

通过以下方式检索原件 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

四次迁移:

  1. 001 --创建 memories 生成的表格 tsvector 列和GIN索引
  2. 002 --添加 user_id (多用户), is_sensitive, vault_path, encrypted_content
  3. 003 --添加 deleted_at (软删除)和 updated_at 增量同步索引
  4. 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。看 许可证 了解详情。