关于 Subconscious
Subconscious 是面向 MCP Agent 的本地语义记忆服务,可保存任务与答案并按语义检索。它使用本机嵌入模型和持久化存储,支持回声探测与漂移分析,数据不会离开设备。
主要功能
- 01按语义检索已记录任务
- 02保存、删除记忆并设置有效期
- 03回声查询相近记忆但不返回答案
- 04分析召回记录中的语义漂移
- 05查看记忆统计并捕获会话片段
适用场景
- 01重复任务前查找既有答案
- 02检查任务是否接近已有记忆
- 03识别可能涵盖过宽问题的记忆
- 04在 Claude Code 会话间保留项目上下文
MCP 相关
作为通过 stdio 运行的 MCP 服务,它向 Agent 提供六种记忆工具。Claude Code hooks 还可捕获会话片段,并在后续启动时导入。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
subconscious-mcp
面向 MCP Agent 的本地优先语义记忆。通过标准输入/输出实现回忆、记忆、遗忘、回声、漂移检测和统计。
该服务以 MCP 标准输入/输出进程的形式在你的机器上运行。它提供六个工具,让 Agent 能询问“我以前处理过这个任务吗?”,如果处理过,就能在几毫秒内取回之前的答案,无需重新执行工作。其灵感来自蝙蝠的回声定位:即使未能回忆到内容,也会报告最近记忆与查询的接近程度;echo 工具会感知附近的记忆而不检索答案;每次回忆结果都会被记录,因此 drift_report 可以标记那些缓存答案逐渐覆盖过多查询类型的情况(首次填充语义漂移)。
嵌入向量由 sentence-transformers/all-MiniLM-L6-v2 提供(384 维,可在 CPU 上运行)。存储使用持久化的本地 ChromaDB 集合。数据不会离开你的机器。
安装
# From PyPI:
pip install subconscious-mcp
# Local development:
git clone https://github.com/vishaltorc/subconscious-mcp
cd subconscious-mcp
pip install -e ".[dev]"
安装后,你可以在任意位置运行该服务:
subconscious-mcp --help
首次调用工具时,嵌入模型(约 80MB)会下载到本地 Hugging Face 缓存中。之后启动会很快。
配置 MCP 客户端
Claude Desktop
编辑配置文件:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
添加一个 mcpServers 条目:
{
"mcpServers": {
"subconscious-mcp": {
"command": "subconscious-mcp",
"args": []
}
}
}
如果 subconscious-mcp 不在 Claude Desktop 的 PATH 中,请使用 which subconscious-mcp 输出的绝对路径,例如 "command": "/Users/you/.local/bin/subconscious-mcp"。
然后退出并重启 Claude Desktop。新工具会显示在 🔌 指示器下。
Claude Code
选项 A:通过 CLI 注册(推荐):
claude mcp add subconscious-mcp -- subconscious-mcp
选项 B:编辑 ~/.claude.json(或项目的 .mcp.json)并添加:
{
"mcpServers": {
"subconscious-mcp": {
"command": "subconscious-mcp",
"args": [],
"type": "stdio"
}
}
}
重新加载 Claude Code 会话后,即可使用这六个工具。
可直接复制粘贴的配置文件见 examples/claude_desktop_config.json 和 examples/claude_code_config.json。
环境记忆
除了显式调用工具外,subconscious-mcp 还可以通过 Claude Code 钩子自动记录你的工作。只需运行以下三个命令:
pip install subconscious-mcp
claude mcp add subconscious-mcp -- subconscious-mcp
subconscious-mcp install-hooks
install-hooks 会编辑 Claude Code 的 settings.json(默认为 ~/.claude/settings.json),注册两个钩子:SessionStart 钩子和 Stop 钩子。它会先备份现有文件(settings.json.bak.<timestamp>),再以原子方式写入,并且是幂等的:如果两个钩子都已存在,再次运行时不会执行任何操作。传入 --dry-run 可打印计划进行的更改而不写入,传入 --settings <path> 可指定其他设置文件。
捕获内容:会话结束时,Stop 钩子会读取转录内容的末尾,提取最后一组用户请求与助手结果的对话,尽力对敏感信息进行脱敏(详见隐私),并将每个会话的内容写入 ~/.subconscious-mcp/data/context.db(一个普通的 SQLite 收件箱)。这些钩子不会加载嵌入模型或 ChromaDB;待处理内容会在 MCP 服务下次启动时由其进行嵌入和导入。
SessionStart 注入的内容:会话开始时,它会打印本项目最近的记录(最多 3 条),并附上一行提示,建议在开始非简单任务前调用 recall。Claude Code 会将这些文本作为上下文。
系统会自动按项目捕获内容。命名空间取自 Git 仓库根目录的文件夹名称(若无法获取,则使用当前目录的基本名称),因此无需任何配置,各项目的记录和整理后的记忆也会彼此隔离。在配置中显式设置 namespace 可覆盖此行为。
隐私
所有数据都会保留在你的设备上。环境钩子捕获的记录存储在 ~/.subconscious-mcp/data/context.db 中,这是一个普通的 SQLite 文件,你可以使用任何 SQL 客户端检查:
sqlite3 ~/.subconscious-mcp/data/context.db 'SELECT ts, namespace, substr(content,1,80) FROM episodes ORDER BY ts DESC LIMIT 10'
写入记录前,捕获的文本会经过尽力而为的脱敏处理。目前会屏蔽以下形式的内容:
- OpenAI / Anthropic
sk-密钥(包括sk-ant-、sk-proj-) - PyPI 令牌(
pypi-) - GitHub 经典令牌(
ghp_、gho_、ghu_、ghs_、ghr_)和细粒度令牌(github_pat_) - Slack 令牌(
xoxb-、xoxa-、xoxp-、xoxr-、xoxs-) - AWS 访问密钥 ID(
AKIA...) Bearer授权令牌- PEM 私钥标头(
-----BEGIN ... PRIVATE KEY-----) KEY=value环境变量赋值,其中名称以KEY/TOKEN/SECRET/PASSWORD/PASSWD结尾(值会被屏蔽,名称会保留)
脱敏只能尽力而为,并不能保证万无一失。目前已知无法捕获的内容包括:AWS 秘密访问密钥(不带前缀的 40 字符字符串)、Bearer 前缀之外的裸 JWT、连接字符串中的密码(postgres://user:pass@host)、Stripe 秘密密钥(sk_live_ / sk_test_ 下划线形式)以及 npm 令牌。请将记录功能视为便利工具,而非保险库。
如需完全关闭捕获功能,请在配置中设置 capture_enabled=false,或在环境中设置 SUBCONSCIOUS_CAPTURE_ENABLED=false。此时 Stop 钩子不会捕获任何内容。
如需一行命令清除 subconscious-mcp 存储的所有内容(整理后的记忆、记录、回声日志和服务日志):
rm -rf ~/.subconscious-mcp
工具
recall(task, threshold=0.85, top_k=1)
语义搜索之前记住的任务。
| 参数 | 类型 | 默认值 | 含义 |
|---|---|---|---|
task | str | (必填) | 要查找的任务描述 |
threshold | float | 0.85 | 命中所需的最低余弦相似度 |
top_k | int | 1 | 要考虑的候选项数量 |
tags | list[str] | null | 可选;候选项必须至少共享一个标签 |
返回:
{
"hit": true,
"similarity": 0.91,
"answer": "...",
"task_text": "...",
"entry_id": "uuid",
"stored_at": 1731000000.0,
"tags": ["..."]
}
未命中时,hit 为 false,answer 为 null,而 similarity 是 在 top_k 个候选项中观察到的最高相似度。调用方可以据此了解匹配程度。
提供 tags 时,未命中结果中的 similarity 表示在已获取的候选范围与标签筛选条件交集内的最佳匹配;即使范围之外存在符合标签条件的条目,该值也可能为 0.0(增大 top_k 可扩大候选范围)。
remember(task, answer, tags=[], ttl_seconds=null, skip_if_duplicate=false)
持久化一个 (task, answer) 对。返回 {stored, entry_id, embedding_dim}。
ttl_seconds=null 表示永不过期。传入一个整数后,经过相应秒数,该条目将不再出现在后续召回中。
存储前,会探测最近的精选条目。如果其余弦相似度落在近重复区间 [0.75, 0.92],结果还会包含 warning="near_duplicate",以及 nearest_task、nearest_similarity 和 nearest_entry_id(这是一种写入时的首次填充漂移防护,与 drift_report 相辅相成)。该条目仍会被存储。传入 skip_if_duplicate=true 可跳过写入,此时结果为 {stored: false, ...},并包含相同的警告字段。环境采集片段不会触发警告。
区间 [0.75, 0.92] 特意独立于 default_threshold(0.85),因此它跨越了召回阈值:对于警告涉及的邻近条目,召回可能会返回,也可能不会返回。高于 0.92 的相似度会被视为更新范围(基本上是相同的任务),因此有意不发出警告。若要处理警告,请通过 recall 查询 nearest_entry_id(或查找该条目)以检查现有条目,然后决定是合并、更新还是继续操作。
echo(task, top_k=5)
声纳探测:返回最近的未过期条目,不包含其答案。
| arg | type | default | meaning |
|---|---|---|---|
task | str | (required) | 用于探测的任务描述 |
top_k | int | 5 | 返回的最近条目数量 |
tags | list[str] | null | 可选;候选项必须至少共享一个标签 |
返回:
{
"count": 47,
"echoes": [
{"entry_id": "uuid", "similarity": 0.91, "task_text": "...", "stored_at": 1731000000.0, "tags": ["..."], "kind": "memory"}
]
}
在进行召回前,可用它感知任务是否属于已知范围。由于不会返回答案,echo 永远不会传播过时或错误的缓存答案。echo 调用不计入命中率,也不会写入 echo 日志。
每次 echo 都带有一个 kind:精选 remember 条目的值为 "memory",导入的环境采集片段的值为 "episode"。片段会出现在 echo 中,但绝不会出现在 recall 的答案中。
drift_report(min_hits=3, min_spread=0.08)
分析 echo 日志,找出首次填充语义漂移候选项:这些条目的召回命中会因不同的查询措辞而分布在较宽的相似度区间内。较宽的区间意味着某个缓存答案正在吸收一大类查询,而这些查询可能带有细微不同的解释(请参阅 validation/results.md,了解此功能检测的问题模式)。
| arg | type | default | meaning |
|---|---|---|---|
min_hits | int | 3 | 将条目纳入考量所需的最少已记录命中数 |
min_spread | float | 0.08 | 触发标记所需的最小命中相似度区间(最大值 - 最小值) |
返回:
{
"analyzed_recalls": 412,
"entries_with_hits": 38,
"candidates": [
{
"entry_id": "uuid",
"task_text": "Pull out all digits...",
"still_stored": true,
"hits": 5,
"distinct_queries": 4,
"similarity_min": 0.82,
"similarity_max": 0.94,
"similarity_spread": 0.12
}
]
}
被标记的条目是待审核候选项:可用 forget 删除,将其拆分为更具体的条目,或提高该类别的召回阈值。
forget(entry_id)
删除具有此 ID 的条目。如果条目存在,返回 {"forgotten": true},否则返回 false。
stats()
返回 {"total_entries", "last_hit_at", "hit_rate_last_100"}。hit_rate_last_100 是最近 100 次召回调用的滑动窗口统计值。可用于查看记忆是否确实发挥了作用。
配置
配置按以下优先级解析:
- 环境变量(最高)
~/.subconscious-mcp/config.json- 内置默认值
| 键 | 默认值 | 环境变量 |
|---|---|---|
storage_dir | ~/.subconscious-mcp/data | SUBCONSCIOUS_STORAGE_DIR |
embedding_model | all-MiniLM-L6-v2 | SUBCONSCIOUS_EMBEDDING_MODEL |
default_threshold | 0.85 | SUBCONSCIOUS_DEFAULT_THRESHOLD |
default_ttl_seconds | null | |
log_level | INFO | SUBCONSCIOUS_LOG_LEVEL |
echo_log_enabled | true | SUBCONSCIOUS_ECHO_LOG_ENABLED |
echo_log_max_bytes | 5000000 | SUBCONSCIOUS_ECHO_LOG_MAX_BYTES |
namespace | default | SUBCONSCIOUS_NAMESPACE |
capture_enabled | true | SUBCONSCIOUS_CAPTURE_ENABLED |
无需启动服务即可查看解析后的配置:
subconscious-mcp --print-config
写入磁盘的文件
~/.subconscious-mcp/
├── config.json (optional, user-edited)
├── data/ ChromaDB collection (sqlite + parquet)
│ ├── echo_log.jsonl one line per recall: query, nearest entry, similarity, hit
│ └── context.db SQLite inbox for ambient-capture episodes (shared across namespaces)
└── logs/server.log rotating, 2MB x 3 backups
上面的目录树对应默认命名空间。使用非默认的 namespace 时,回声日志会改为命名为 echo_log_{namespace}.jsonl,而 context.db 会在各命名空间间共享(每个 episode 都有自己的 namespace 列)。
回声日志会自动压缩:超过 echo_log_max_bytes(默认 5MB)时,会删除最旧的一半内容。设置 SUBCONSCIOUS_ECHO_LOG_ENABLED=0 可完全禁用此功能(这也会禁用 drift_report)。
要清除记忆(包括回声日志):rm -rf ~/.subconscious-mcp/data。
演示会话
请参阅 examples/demo_session.md,了解一个 Agent 调用 recall(未命中,然后调用 remember),并在之后的轮次中使用改述再次调用 recall 且成功命中的完整示例。
架构
请参阅 docs/architecture.md,了解分层设计(服务 / 工具 / 记忆 / 配置)、选择 ChromaDB + 余弦相似度的原因,以及 TTL 策略。
故障排除
安装后出现 subconscious-mcp: command not found
你的 shell 的 PATH 未包含安装位置。尝试运行 python -m subconscious_mcp.server --help 确认软件包可用,然后在 MCP 客户端配置中使用绝对路径。
Claude Desktop 显示“Server disconnected”
检查 ~/.subconscious-mcp/logs/server.log 中的回溯信息。最常见的原因:
- 模型下载失败(首次启动时处于离线状态)。恢复网络连接后重新运行。
storage_dir位于只读卷上。
首次 recall 速度较慢 首次调用时会延迟加载 sentence-transformer 模型(在普通 CPU 上约需 5 秒)。后续调用会复用已加载的模型,并在几毫秒内响应。
drift_report 未返回候选项
原因可能是记录的 recall 次数过少(每个候选项需要至少两种不同表述,各自达到 min_hits 次命中),也可能是回声日志已禁用(SUBCONSCIOUS_ECHO_LOG_ENABLED=0)。检查 ~/.subconscious-mcp/data/echo_log.jsonl 是否存在且持续增长。
对明显的改述进行 Recall 时仍不断未命中
降低阈值(recall(task=..., threshold=0.7)),或提高 top_k 以查看候选项。all-MiniLM-L6-v2 体积小、速度快。若要获得更高质量的匹配,请设置 SUBCONSCIOUS_EMBEDDING_MODEL=all-mpnet-base-v2。
测试因 sentence-transformers 下载错误而失败
你处于离线状态或使用了代理。预先下载模型后,设置 HF_HUB_OFFLINE=1;也可以在网络连接正常时运行一次 python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('all-MiniLM-L6-v2')"。
许可证
MIT © 2026 Vishal Jayaprakash
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。