Seahorse
Seahorse
面向 LLM 代理的持久化、双时态记忆 —— 本地优先、MCP 原生、可在 Obsidian 中阅读。
pip install seahorse-memory
seahorse init myvault && seahorse remember "Sergio lives in Madrid"
seahorse recall "where does Sergio live?"为什么
LLM 代理每次会话都从零开始。上下文窗口并不是记忆:它是一张会重置的草稿纸,而且太小,根本放不下一个代理在未来数周工作中积累的东西。那些试图弥补这个缺点的工具,却各有各的问题:
遗忘得让人无法接受。 大多数记忆系统只会无限累积事实,从不厘清矛盾,于是代理会"记住"用户同时住在马德里和巴塞罗那,却无法判断哪个是真的。
它们并不透明。 记忆被锁在人类无法读取、编辑或审计的专有数据库里。如果代理错了,根本没有任何办法可以修正它。
投喂的成本相当高。 每一条 episode 都要过一遍 LLM 的闸门,于是动辄上千条小事实累积起来,花费是真金白银。
它们会锁定你。 你采用一套记忆系统,往往就会被迫采用它的运行时、它的供应商、它的生态系统。
它们的基准测试极其不可靠。 这个领域内的数字令人难以复现:LOCOMO 基准有 6.4% 的错误黄金答案,Mem0 的复现实现已经损坏(issue #2800),而 MTEB 上的嵌入并不代表并发于记忆-召回任务的性能(该结论见 LMEB,arXiv 2603.12572)。
Seahorse 是一套不同的方案:一个开放、可移植、双时态的记忆标准。它既能被 agent 写入、也可由 agent 读取,且人类可以直接阅读与修改;同时,它并不把你们绑定到任何运行时或服务供应商上。
Related MCP server: agentcairn
2. 它适合谁
想让自己的 agent 在会话之间记住决策与上下文的开发者们(无论你用 Claude Code、Cursor、Codex,还是自研 agent)。
Obsidian 高级用户,但你需要的不是 一张静态存档笔记,而是一个能交给 agent 去查询和维护的知识库。
希望记忆本身是可轮换(portable)的团队,这是一种不依赖的历史回放便能迁移的结构化格式。
可落地的示例:用 Claude Code 拥有永续记忆
最轻松的入手 Seahorse 的方式,是给 Claude Code 装上一块不跨会话丢失的记忆。只有三个小步骤:
捕捉会话。
seahorse setup可把观察者钩子装到~/.claude/settings.json;再运行seahorse observe start启动采集进程。之后,每一个会话都会被记录为 episodes —— 采用 skip-first 机制(接近零成本),做过去标识清理,并生成确定性摘要。
seahorse setup
seahorse observe start在会话之外召回。
SessionStart钩子会把seahorse context投递到下一次会话里,这样新会话开始时可以直接叠加之前学到的内容。如果想直接搜素,可以使用seahorse recall命令:
seahorse context
seahorse recall "what did we decide about the API design?"带上你已有的记忆。 如果你已经正在用 claude-mem 管理记忆,
seahorse import便能够把全部行为观测倒入标准 episodes —— 不需要重放历史,也不会被任何东西锁定。
seahorse import --mode commit这与传统的做法根本不同之处在于:代理写入的是同一套 vault,正是你会在 Obsidian 里编辑到的地方。这就是很大一部分亮点所在——每一条 episode 都是一个带 YamL frontmatter 的 Markdown 文件:人可读、可编辑、git 中可以 diff、人也经得起审计。代理的回忆起笔不是黑箱,而是自己真实的笔记。
合规:从代理侧连接(MCP)
为代理创造条件本就是 Seahorse 的出发点:其记忆被暴露为一个 stdio MCP 服务(编号 io.seahorse.memory/v1),任何支持 MCP 的代理都能接进来。CLI 专为人类和脚本而准备;代理们只要透过 seahorse-mcp 即可对话。
在 Claude Code 里注册服务器(本机作用域,这是默认值):
claude mcp add seahorse-mcp -- uvx --from seahorse-memory seahorse-mcp --vault "${HOME}/myvault"-- 是守住不可少的内容——它用于隔开 Claude 自身的 flag 与随后的服务器命令。还可用 --scope project 让另由项目内 .mcp.json (已纳入 git)的团队共享。再用 claude mcp list 检查(应当显示 ✔ Connected),以及 claude mcp get seahorse-mcp。
或则在项目根的 .mcp.json 也做同样配置(适配任意 MCP 客户端原则:
{
"mcpServers": {
"seahorse-mcp": {
"type": "stdio",
"command": "uvx",
"args": ["--from", "seahorse-memory", "seahorse-mcp", "--vault", "${HOME}/myvault"]
}
}
}这里强调:.mcp.json 中的 ~ 不可展开,请用 ${HOME} 或者绝对路径。(而 settings.json 中的 mcpServers 是对的日期——其实 MCP server真实的位置是:user/local 作用域位于 ~/.claude.json 里,project 作用域应当在 .mcp.json。)
一旦连接成功,这个代理就可以看到 14 个工具——也就是 remember、recall、recall_timeline、recall_full、improve、forget、build_pit、skill_add、skill_show、skill_list、skill_search、freshness_view、audit_log、follow_supersedes_chain(见 The agent surface)。
seahorse setup 观察器则是另一个独立组件:它负责把 Claude Code 整个会话清洗成可导入的 episodes。MCP 服务器才是代理可以随时 读&写 记忆的真正入口。它们两个互相补全:先从会话取信息,再在这些会话之间召回。
执行机制
graph LR
A[Claude Code / any MCP agent] -- stdio MCP io.seahorse.memory/v1 --> S[seahorse-mcp]
S --> E[Bi-temporal engine]
E --> DB[(sqlite3 + sqlite-vec + FTS5)]
E --> V[Obsidian vault: markdown + F3.1 frontmatter]
H[Human in Obsidian] --> V一个 agent 把有两个端和 seahorse-mcp 在一起。引擎对每一条 episode 做二次存储:一份进到单体 SQLite 库(sqlite-vec 负责向量检索,FTS5 做全文检索);另一份则作为带 F3.1 frontmatter 的 markdown 文件写入 vault 内。人类编辑的就是同一份 markdown。这种格式已有限定的版本并记录在 docs/f3.1-format.md。
快速开始
# Install (PyPI):
pip install seahorse-memory
# …or with uv:
uv tool install seahorse-memory
# For hybrid semantic retrieval (FastEmbed ONNX, downloads mE5-small on first
# embed): pip install "seahorse-memory[embeddings]"
# For the multi-LLM extraction path (LiteLLM): pip install "seahorse-memory[llm]"
# Create a vault and write your first episode:
seahorse init myvault
seahorse remember "Sergio lives in Madrid" --title home
seahorse recall "madrid"
# Improve and forget (append-only; history is preserved):
seahorse improve <ep_id> "Sergio lives in Barcelona" --reason correction
seahorse forget <ep_id> --reason done
# Session capture, context, and consolidation:
# Install the observer (writes [observe] + merges the Claude Code hooks into
# ~/.claude/settings.json):
seahorse setup
# Start the observer (unix socket + worker), then the next session is captured
# automatically (skip-first, redacted, deterministic summary):
seahorse observe start
seahorse observe status
# Bootstrap context by recency (the SessionStart hook injects this):
seahorse context
# Distill recurrent episodes into semantic knowledge notes (N≥3, idempotent):
seahorse consolidate
# Remove the observer:
seahorse setup --uninstall
# Serve an agent over stdio MCP (io.seahorse.memory/v1):
seahorse-mcp --vault myvault
# …equivalently:
seahorse mcp --vault myvaultseahorse 控制台为面向人和 script;seahorse-mcp 为 agent 准备。 seahorse mcp 这个子命令会最终拉起海与 seahorse-mcp 原理相同的 stdio server ,所以两个入口对 agent 来说完全等同。连接方法如上节所述(点 从代理端使用 去看)。
前置条件
Python ≥ 3.11(任何稳定的 3.11/3.12/3.13 都行)。注意,当前解释器的
sqlite3必须曼enable_load_extension( sqlite-vec 需要它);大多数标准构建都没问题,如果哪套碰是没有,seahorse doctor会诚然显示为 FAIL。Observer额外选装 Obsidian, 完全可以不用。 Seahorse 可以在任意 Markdown 目录文件夹下运行——
seahorse init会建一个.seahorse/的普通文件夹作为边车。Obsidian 只是你处理这个日常文件夹的人类作业界面;其中的.obsidian/目录被 Seahorse 忽略,且从未被放在输入依赖里。
迁移一个旧版 Obsidian vault
如果你手上已有大量 Obsidian 笔记(没有 frontmatter,只有旧式 tags/created 元数据),那么它还不是我们现在的正式规范格式,seahorse index rebuild 对这些笔记会直接失败,不会忽悠。用 seahorse frontmatter migrate 可以完成这个转换:
# Preview: classify every note, write nothing (always exit 0):
seahorse frontmatter migrate --vault myvault --dry-run
# Apply: convert legacy notes, leave canonical notes untouched, refuse
# incompatible notes:
seahorse frontmatter migrate --vault myvault
# Rebuild the sidecar index from the converted notes:
seahorse index rebuild --vault myvault当遇到无法兼容的笔记,导致不能完成整段过程时,apply 会退出编码 97——但先干了一件事:把 manifest 汇总打完整打印给你,操作员一眼敲定哪几条必须手工处置
我需要 LLM 吗? 不需要。对于大部分写入,默认走确定性跳过路径(成本接近于零)。LLM 提取是可选的(seahorse-memory[llm]),只保留给少数值得这么做的记忆片段。
它免费吗? 免费。Apache-2.0,本地优先,零基础设施。托管 SaaS 和企业级版本计划在将来推出(见项目策略说明)。
如何贡献? 开发环境、测试/lint 命令和拉取请求相关工作流,请参阅 CONTRIBUTING.md。
路线图
已构建的内容、下一步计划以及项目方向,请参阅 ROADMAP.md。发布历史记录在 CHANGELOG.md。
智能体接口 —— 7 个记忆原生原语 + 7 个程序式/只读工具
通过 stdio MCP(io.seahorse.memory/v1,协议固定为 2025-11-25)暴露,并在 CLI 上同步提供。这些是记忆原语,而不是泛型 CRUD:智能体会像人类谈论记忆一样,调用 remember / recall / improve / forget。
7 个记忆原语(写入 + 检索):
原语 | 作用 |
| 记录一个记忆片段(正文、来源、可选标题/主题)。 |
| INDEX 层级——当前状态列表,按 |
| TIMELINE 层级——围绕锚点记忆片段的取代链。 |
| FULL 层级——带全部来源信息的完整记忆片段。 |
| 用更正后的记忆片段取代原记忆片段(仅追加)。 |
| 软删除一个记忆片段(仅追加;保留历史)。 |
| 构建一个时点投影(全 None → 当前状态)。 |
另有 7 个程序式/只读工具(技能 + 门面自省):
工具 | 作用 |
| 创建一个程序式技能(确定性,成本几乎为零)。 |
| 展示技能的门控正文(信任门)。 |
| 列出程序式技能(Discovery 层级)。 |
| 搜索程序式技能(混合召回,程序式过滤)。 |
| 某个记忆片段的新鲜度快照(age、stale、pending_ingest)。 |
| 某个记忆片段的审计事件(写入路径历史)。 |
| 某个记忆片段的取代闭包(版本历史)。 |
三个检索层级提供渐进式披露:先做廉价的列表(INDEX),按需提供链条(TIMELINE),只有真正需要时才给出完整记录(FULL)。这让常见路径保持低成本。
已实现功能
基于标准库
sqlite3+ sqlite-vec 的双时态、仅追加记忆片段存储(FTS5vec0)。 schema 自动迁移。
7 个记忆原生原语,以及 7 个程序式/只读工具,在 CLI 和 stdio MCP 上都能用(共 14 个工具)。
渐进式披露(INDEX / TIMELINE / FULL)和时点投影。
混合语义检索:
recall按相关性排序 —— sqlite-vec kNN + FTS5 BM25 使用 Reciprocal Rank Fusion 融合;接入真实嵌入器时支持时点路由(state_at/known_at)。写入路径和seahorse index rebuild会填充vec0/FTS(尽力而为 —— 嵌入器失败绝不会导致记忆片段写入失败)。诚实的降级:没有安装
embeddings扩展(或没有填充向量)时,recall回退到当前状态列表(分数 0.0,不排序),并拒绝时点召回 —— 引擎在不具备排序能力的情况下仍正常工作。可选衰减排序(默认关闭):类似 Ebbinghaus 遗忘曲线的机制,按年龄降低旧知识的权重(
score' = score · 2^(-age/half_life)),并有各类型半衰期先验。默认关闭:纯 RRF 的指纹仍保持比特级可比。LLM 提取:真正的多 LLM 路径(ollama / gemini / groq / openrouter / openai / anthropic / deepseek / vllm,本地优先),带严格 schema 校验器 + 修复循环、重试/回退链,以及可操作的成本上限(本地和免费层模型定价为 $0)。
seahorse init --llm引导启动它;跳过路径仍是大部分写入的默认策略(成本接近零)。本地优先 CI 门禁:真实提取路径会在 CI 中针对该序列中最弱的模型(
ollama/qwen3:0.6b)运行,所以校验器 + 修复必须承担主要工作 —— 该路径不会静默依赖原生结构化输出或强大模型。取代(
improve)和软删除(forget)会完整保留全部历史。批量蒸馏(
seahorse consolidate):将许多记忆片段蒸馏成一条合并笔记 —— 默认确定性;可选择 LLM 合成(--synthesis llm)和取代(--supersede),使合并笔记取代其来源。为 Obsidian vault 层提供 frontmatter 导入/导出(markdown 作为人类可读、可移植的磁盘契约)。
旧 vault 迁移:
seahorse frontmatter migrate可转换旧版 Obsidian 笔记;支持--dry-run预览、--resume,并在不兼容笔记阻塞完整迁移时诚实地返回退出码97。诚实的退出码和 stderr 上的结构化
{"error": {...}}封装,让智能体和脚本能够通过seahorse_code/cli_code进行确定性分支。
少数 CLI 命令已经触发,却刻意以退出码 75 结束并附上原因(参数 expire、revalidate、index verify),从而诚实地暴露尚未实现的部分,而不是默默 no-op。llm_partial 保持完全保留。
技术栈
Python ≥ 3.11。std-standard-library
sqlite3+ sqlite-vec 用于存储(零基础设施的单文件;vec0虚拟表和 FTS5)。numpy 用于嵌入向量的形状。
Pydantic v2 用于定义规范性的
Episode契约(核心类型系统)。Typer 用于 CLI 表面(供人和脚本使用)。局限在
seahorse.cli。stdio JSON-RPC 2.0 用于 MCP 智能体表面(hand-rolled framing,跨平台 stdlib-only
seahorse.mcp包 —— 引入seahorse.mcp不会加载 Typer)。ruamel.yaml+python-frontmatter,只用在 frontmatter 适配器。FastEmbed ONNX + onnxruntime(
embeddings扩展,不在默认安装中):mE5-small bundle 默认model_O4.onnx(fp32,约 235MB)——没有一个 int8/fp16 产物能移植到 Apple Silicon,且开放标准必须能在 Windows/Linux/macOS 上运行。可移植的 int8 bundle 是突破口。LiteLLM(
llm扩展,不在默认安装中):统一 100+ 提供商,用于 LLM 提取路径。即使没有该扩展,seahorse.llm仍可导入(契约 +StubLLMClient),真实路径会从 LLM 降级为跳过,并给出一种安装提示。FastAPI / SQLAlchemy / Postgres 有望用作后续的多智能体层级(Postgres + pgvector)。README 只描述当前交付的内容,而不是目标架构闭环。
测试
单元 + 集成:
uv run pytest(覆盖率 ≥ 80% 门禁)。真实用户端到端:
scripts/e2e-fresh-user.sh—— 在干净的、隔离的 HOME 中完整走一遍 安装 → 初始化 → 核心 CLI → embeddings → LLM → 导入 → MCP 流程(绝不会触碰真实的~/.claude/~/.claude-mem)。环境矩阵:
scripts/e2e-matrix.sh—— 跨环境组合的真实用户流程(安装方法 × 额外依赖 × Obsidian × Ollama × 在线/离线 × vault 状态 × 并发组合)。--ci-subset运行 CI 安全组合(core_min+uv_sync_dev);--list列出所有组合。核心压测:
scripts/stress-core.sh—— 摄入 1000+ 条记录,recall --top-k 100p95 ≤ 250ms(进程内 INDEX 预算),并发单写者、reindex、幂等导入、improve/forget 链。
主要贡献
欢迎贡献。开发环境、测试/lint 命令和 PR 工作流的进一步说明见 CONTRIBUTING.md。发布历史记录在 CHANGELOG.md。
许可证
Apache-2.0。见 LICENSE。
当前状态
v0.10.0。 记忆引擎在全新安装后即能端到端运行:写入记忆,用混合语义检索进行参与,用真正的多 LLM 路径(本地优先、CI 门禁)抽取、改进和遗忘,并通过 stdio MCP 服务智能体。当向量已填充向量并且嵌入器可用时,recall 按相关性排序;否则它就诚实地降级为当前状态列表。可选的衰减排序偏差(默认关闭)会按年龄降低过期知识的权重。seahorse import 将 claude-mem 的 observations 迁移到 episodes;同时,批量蒸馏功能(seahorse consolidate)会把许多 episodes 变成一条合并完成笔记,带有可选的 LLM 合成与取代。基准测试工具已包含在仓库中,相关说明和重现命令在 docs/benchmark.md 中。更多关于“下一步”的内容参见 What works 和 ROADMAP.md。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceLocal-first, file-based memory layer for AI agents — one shared Markdown vault across Claude, Codex, Gemini, Cursor and any MCP client. Provides read/write memory tools with an audit trail, per-agent trust levels, and Git sync; no cloud and no lock-in.2MIT
- AlicenseBqualityAmaintenanceagentcairn is a local-first memory MCP server: your agent's memories live as Markdown in an Obsidian vault you own — the source of truth — with a rebuildable DuckDB index providing fast hybrid BM25 + vector + graph recall. It exposes tools to capture, recall, and manage those memories (non-lossy, with secret redaction) and works the same across Claude Code, Codex, Cursor, and any MCP host.546Apache 2.0
- AlicenseNot gradedqualityDmaintenanceLocal-first AI memory layer with hybrid retrieval and brain-inspired namespaces. Enables agents to save, search, and manage memories directly via MCP tools.5MIT
- AlicenseNot gradedqualityAmaintenanceLocal-first, source-grounded memory for AI agents, with citations, bitemporal history, review-gated corrections, and MCP tools for search and recall.3Apache 2.0
Related MCP Connectors
Token-efficient MCP memory for Markdown vaults. Tiered search, GraphRAG, AI memories.
Persistent memory and knowledge graphs for AI agents. Hybrid search, context checkpoints, and more.
Universal memory for AI agents and tools. Save, organize and search context anywhere.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/ssanvi-builds/seahorse'
If you have feedback or need assistance with the MCP directory API, please join our Discord server