mcpField
M
memharness

memharness

本地服务
github.com/las7记忆与知识618 周前更新

关于 memharness

memharness 是面向 AI Agent 的 SQLite 长期记忆存储层,以双时态事实和来源记录保留信念变化及其依据。它通过 MCP 提供记忆操作,不在存储层调用 LLM 或网络。

主要功能

  1. 01按事实存储双时态记忆
  2. 02记录每条事实的来源
  3. 03修订时保留旧信念链
  4. 04按时间查询与比较变化
  5. 05支持按来源撤销记忆
  6. 06可选本地语义检索

适用场景

  1. 01追溯 Agent 某时点的信念
  2. 02检查记忆变化及其来源
  3. 03清除指定会话或来源的记忆
  4. 04管理超出上下文窗口的长期事实

MCP 相关

MCP 服务通过 stdio 向 MCP 客户端提供七种工具,用于记忆、检索、修订、比较、溯源、撤销和统计。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"las7-memharness": {
"command": "npx",
"args": [
"-y",
"@memharness/mcp"
],
"env": {
"MEMHARNESS_DB": "<MEMHARNESS_DB>"
}
}
}
}
启动命令npx -y @memharness/mcp
需要配置的环境变量
MEMHARNESS_DBPath to the SQLite memory file. Defaults to a per-user data path; set to override.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@memharness/mcp0.1.2

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

memharness

面向 AI Agent 的双时态、携带来源信息的记忆原语。 一个 SQLite 文件。存储层不调用大模型或网络。可通过 MCP 提供给任何 Agent。

大多数 Agent 的记忆只是一堆字符串。memharness 存储的是事实,并结合了现有方案往往各自拆分处理的三种语义:

  1. 双时态:每条事实分别记录它在现实中开始成立的时间(valid_from/valid_to)和Agent 得知它的时间(tx_at)。因此,你可以询问:“你在 3 月 1 日时相信什么?”
  2. 只取代,不删除:更正会关闭旧事实,并将它链接到后续事实。*“你在我更正你之前是怎么想的?”*这个问题有答案。
  3. 每条事实都有来源信息:每条记忆都会注明是谁、在何处、何时说的。*“你为什么相信这个?”有答案。“忘掉那个会话里的所有内容。”*也有答案。

存储层是确定性的:没有大模型、没有网络、没有后台守护进程。 它就是普通的 SQLite,因此你可以用任何客户端打开该文件。

Agent 学会了一个部署目标,用户在几周后更正了它,而 recall / as_of / why / diff 会解释当时相信的内容。

亲自运行:cd examples && npm install && npm run demo

适用场景(以及不适用的场景)

memharness 不是提升准确率的灵丹妙药,也对此坦诚以待。如果 Agent 的记忆量很小、内容固定,而且能轻松放进上下文窗口,那么使用 CLAUDE.md 文件(或者直接把历史记录塞进提示词)会更简单;对于较短的历史记录,完整上下文的表现也会胜过任何外部记忆系统,或至少与之相当。

以下情况可以考虑使用 memharness:

  • 历史记录超出窗口容量:数月的事实、众多主题,内容多到你不想(或无法)在每个提示词里都粘贴一遍。
  • 需要审计线索:“Agent 做出这项决策时相信什么?”(as_of)、“自周一以来有什么变化?”(diff)、“它为什么相信这个?”(why)。这些问题不是一堆字符串能回答的。
  • 需要按来源范围删除:一次调用即可*“忘掉那个会话/文件/来源中的所有内容”*(契合 GDPR 式需求,而不是字符串搜索)。
  • 信念会随时间变化:更正应该取代旧内容,而不是悄然覆盖,这样旧的推理过程仍然可以解释。

对比

坦诚而言,memharness 的独特之处在于它是一个确定性、可审计的存储层,而不是提取服务。

存储方式写入时的大模型调用as_of / diff / why可嵌入 / 可自托管
memharness一个 SQLite 文件无支持:双时态 + 来源信息支持,它是一个库
mem0托管 / OSS 服务有(提取流水线)部分支持 / 不支持部分支持
Zep / Graphiti托管图数据库有(大模型摄取)支持双时态,但由大模型构建部分支持
Letta / MemGPTAgent 框架 + DB有(由 Agent 管理)不支持支持
Anthropic memory tool客户端文件模型编辑文件不支持(由模型决定)支持
普通 CLAUDE.md / 文件文本文件无不支持支持

坦率地说,其他方案的优势在于:mem0 和 Zep 能够从原始对话中自动提取事实,而 memharness 有意不这样做(写入路径不依赖模型;由客户端或技能决定哪些内容值得记忆)。普通的 CLAUDE.md 完全不需要安装。只有在你需要其他方案不提供的时序和来源查询时,memharness 才能体现其价值。

软件包

软件包内容
@memharness/coreTypeScript 库:架构、迁移、写入路径、回忆排序。不使用模型,不访问网络。
@memharness/mcpMCP 服务(stdio),向任何 MCP 客户端提供七种工具。
@memharness/embed可选。本地嵌入模型,用于混合式(语义)回忆。默认不安装。

快速开始(MCP)

默认安装内容精简(SQLite 加 MCP SDK);嵌入模型为可选项,参见混合检索。

Claude Code:

claude mcp add memharness -- npx -y @memharness/mcp

Claude Desktop(~/Library/Application Support/Claude/claude_desktop_config.json) 和 Cursor(~/.cursor/mcp.json)使用相同的 JSON 格式:

{
  "mcpServers": {
    "memharness": { "command": "npx", "args": ["-y", "@memharness/mcp"] }
  }
}

Codex(~/.codex/config.toml)使用 TOML,而不是 JSON:

[mcp_servers.memharness]
command = "npx"
args = ["-y", "@memharness/mcp"]

数据库位于 ~/.memharness/memory.db(可通过 MEMHARNESS_DB 覆盖; 在 Linux 上会遵循 XDG_DATA_HOME)。除非启用可选的调试日志,否则不会写入其他内容。

首次运行
  1. 使用上述任一命令添加服务,然后重启客户端,使其加载新的 MCP 服务。
  2. 在对话中向 Agent 提供一条持久事实,例如 “记住,我用 Fly.io 部署这个项目。” 它会调用 remember。
  3. 稍后(或在新会话中)询问 “你知道我是如何部署的吗?” 它会调用 recall 并根据记忆作答。纠正它后,它会调用 revise;旧信念会成为历史记录,可通过 as_of / why / diff 查询。

无需 API 密钥,无需注册,无需联网。首次调用 remember 时会创建 SQLite 文件,设置就全部完成了。如需在没有 Agent 的情况下端到端查看工具运行情况,请运行演示:cd examples && npm install && npm run demo。

可选:让检索自动进行

默认情况下,由 Agent 决定何时调用 recall。若要在每个会话开始时主动注入相关记忆(比寄希望于模型记得去查更可靠),请添加一个 Claude Code SessionStart hook,运行随附的 memharness-context 工具,该工具的标准输出会注入上下文:

{
  "hooks": {
    "SessionStart": [
      { "hooks": [ { "type": "command",
        "command": "npx -y -p @memharness/mcp memharness-context --subject user" } ] }
    ]
  }
}

它会输出最相关的当前信念的精简内容(如果尚无内容,则会静默退出),让 Agent 在每个会话开始时就已了解持久事实。多次传入 --subject 可注入多个实体。

七个工具

工具功能验证的论点
remember存储带有置信度和来源信息的原子事实事实 > 大块内容
recall按排名返回当前信念;as_of 返回过去某个时刻的信念双时态
revise替代某条信念,并保留历史记录替代 > 删除
diff查看自某日期以来的变更(学习/修订/撤回)审计演示
why查看某条事实的来源信息和完整修订链信任/审计
forget按 ID 或来源(基于来源信息删除)添加墓碑符合 GDPR 要求
stats计数、主体、架构版本—

库的使用

import { Memharness } from "@memharness/core";

const mem = Memharness.open(); // ~/.memharness/memory.db

// Learn something now, then learn it was actually true earlier.
const { id } = mem.remember({
  subject: "user",
  fact: "lives in Osaka",
  sourceRef: "session-2026-06-09",
});
mem.revise({ oldFactId: id, newFact: "lives in Tokyo", validFrom: "2026-05-01" });

mem.recall({ query: "lives" }).facts[0].fact;   // "lives in Tokyo" (current belief)
mem.diff({ since: "2026-06-01" });               // { learned, revised, retracted }
mem.why(id);                                     // { fact, ancestors, descendants }

recall 返回的是 RecallResult({ facts: ScoredFact[]; asOf; truncated; usedFallback }),而不是普通字符串。asOf 支持时间回溯:mem.recall({ query: "lives", asOf: "2026-04-15" }) 会返回在该日期当时被视为真实的内容。 这会遵循事务时间,因此今天学到的事实不会出现在对过去的查询中。

检索排名通过对 FTS5 BM25(以及启用混合检索时的向量排名)进行倒数排名融合,再乘以置信度和近期性衰减(半衰期为 90 天,可配置),并在 SQL 中评分。可选的 maxTokens 预算会限制输出,以适应上下文窗口。FTS-only 和混合模式均会使用子串回退,以匹配部分词语和拼写错误。

可选:混合召回

默认情况下,召回使用 FTS5 关键词搜索,并按近期程度和置信度排序:不需要模型,完全离线。混合召回通过本地嵌入模型(BGE-small,约 130MB)增加语义检索:从 HuggingFace Hub 下载一次后即可完全离线运行,不需要 API 密钥,也不会在每次查询时联网。分两步启用:

  1. 在服务旁安装可选的嵌入包。使用 npx:

    npx -y -p @memharness/mcp -p @memharness/embed memharness-mcp
    

    (也可以使用 npm i -g @memharness/embed 进行全局安装)。

  2. 在服务的环境中设置 MEMHARNESS_HYBRID=1。

此后,服务会自动为已存储的事实生成嵌入:你通过 remember 记录的事实会在下一次 recall 时支持语义搜索,无需单独执行回填。如果尚未加载模型,首次混合召回时会将下载进度输出到 stderr。如果未安装该包,服务会提示这一点并继续仅使用 FTS;它绝不会因无法使用混合召回而直接失败。

在库层面,召回与嵌入提供方无关:可以将自己的查询向量传给 recall({ queryVector }),并使用 setEmbedding(...) 添加文档向量,模型不限。

一个完整示例

两个相隔数周的会话。Agent 学到一项偏好,用户之后又对其进行更正,下游问题则询问 Agent 当时相信的是什么:

// June 9: the agent learns a deploy target and acts on it.
const { id } = mem.remember({
  subject: "project:acme",
  fact: "deploys via Heroku",
  sourceRef: "session-2026-06-09",
});

// June 16: turns out the team moved to Fly back on June 1.
mem.revise({
  oldFactId: id,
  newFact: "deploys via Fly.io",
  validFrom: "2026-06-01",
  sourceRef: "session-2026-06-16",
});

mem.recall({ subject: "project:acme" }).facts[0].fact; // "deploys via Fly.io"

// "Why did the CI config you wrote on June 9 target Heroku?"
mem.recall({ subject: "project:acme", asOf: "2026-06-09" }).facts[0].fact;
//   "deploys via Heroku": what the agent honestly believed that day.

mem.why(id);   // the full chain: Heroku, superseded by Fly.io, with sources.
mem.diff({ since: "2026-06-15" });  // surfaces the Heroku -> Fly.io revision.

基于字符串集合的记忆无法回答 as_of 问题,因为它在得知 Fly.io 后就覆盖了 Heroku。

正确性

属性测试套件是本项目的核心:对于随机生成的 remember/revise/forget 序列,recall({asOf: T}) 必须与不使用 SQL 对事件日志进行朴素重放所得的信念集合一致,并在每个事件时间戳的 ±1ms 处进行探测。每次推送到 main 时都会运行 10,000 个测试用例。

在一台开发笔记本电脑(Apple Silicon)上,以 100k 条事实(10% 修订链、2% 撤回)进行基准测试:四种查询形式(双词关键词、关键词 + 主体、仅主体,以及 as_of + 关键词)的整体召回 p95 约为 1.3ms,低于 10ms 的预算。pnpm bench 会填充数据库并验证预算,因此这个数值可复现,而非仅作宣称。

与最初原型的一项刻意差异:撤回会存储时间戳(retracted_at),而不是标志,因此在撤回之前进行的 as_of 查询仍能看到历史记录。这正是原型文档承诺的行为,但其 SQL 并未实现。

开发

pnpm install
pnpm test            # unit + behavior suites (property tests at 200 runs)
pnpm test:property   # 10k randomized property cases
pnpm bench           # seed 100k facts, assert recall p95 < 10ms

Schema 迁移只向前进行,由 PRAGMA user_version 驱动。行永不删除(forget 使用墓碑标记),因此 facts.id 同时充当插入顺序。所有时间戳均为规范的定宽 UTC ISO 8601 格式,因此可以按字典顺序进行时间比较。

可选:本地使用日志

如需调试或衡量自己的使用情况,可设置 MEMHARNESS_DEBUG=1。服务会在数据库旁的 usage.log 中追加操作名称和时间戳(绝不记录事实内容)。此功能默认关闭,完全在本地运行,绝不会联网。

许可证

Apache-2.0

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。