使用说明
召回
注: 这是一个个人学习项目。我用它来学习C#。NET构建我每天实际使用的东西。工作在 Linux、macOS和Windows.PR受欢迎,但预计会有粗糙的边缘。
一个具有持久内存、语义搜索、健康跟踪和杂货集成的个人日记MCP服务器。
Recall允许Claude(或任何兼容MCP的AI)访问您过去的对话。每一次新的对话都是从自动检索到的相关上下文开始的,因此人工智能总是知道你之前讨论过什么。
运作原理
召回是 MCP服务器 它将日记条目存储在SQLite中,并带有用于语义搜索的向量嵌入(通过ONNX Runtime的全MiniLM-L6-v2)。工具使用动作参数模式来保持工具数量低:
| 工具 | 行动 | 目的 |
|---|---|---|
diary |
写、更新、获取、固定 | 创建、编辑、获取或固定日记条目 |
diary_search |
上下文、查询、列表 | 查找条目:对话开始上下文、关键字搜索、最近列表 |
diary_day |
查看、计划、总结 | 日视图、设置计划、存储每日总结 |
diary_time |
-- | 当前日期/时间(以便AI知道它是什么时候) |
health |
最近、查询、log_migraine、log_period | 健康/健身数据、偏头痛和周期跟踪 |
rohlik_search |
搜索,最后一分钟 | 搜索Rohlik.cz杂货产品 |
rohlik_cart |
查看、添加、删除、更新、检查 | 购物车管理 |
rohlik_orders |
历史记录、详细信息、即将发布 | 订单历史记录和跟踪 |
rohlik_delivery |
信息、时隙、预留 | 交货时隙 |
rohlik_account |
溢价、公告、包、结账、购物列表 | 帐户信息 |
rohlik_checkout |
提交、付款 | 订单提交和付款(TOTP保护) |
快速启动
先决条件
安装并连接到Claude Code
git clone https://github.com/anicka-net/recall.git
cd recall
dotnet build
# Register with Claude Code
claude mcp add --transport stdio --scope user recall -- \
dotnet run --project /path/to/recall/src/Recall.Server/Recall.Server.csproj
日记工具现在可以在您的Claude Code对话中使用。
配置
配置文件: ~/.recall/config.json
{
"databasePath": "~/.recall/recall.db",
"systemPrompt": "Custom instructions for the AI",
"promptFile": "~/.recall/prompt.txt",
"autoContextLimit": 5,
"searchResultLimit": 10,
"tools": ["diary", "health"],
"rohlikUsername": "user@example.com",
"rohlikPassword": "password",
"rohlikBaseUrl": "https://www.rohlik.cz"
}
所有字段都是可选的。默认值开箱即用。
这 tools 数组控制注册哪些工具模块。有效模块: diary, health, rohlik。当省略或为空时,所有模块都将启用。Rohlik还要求出示证件。
数据存储
所有数据都存储在本地 ~/.recall/recall.db (SQLite)。除非您配置远程传输,否则任何东西都不会离开您的机器。
语义搜索模型
召回用途 全迷你LM-L6-v2 用于语义搜索。下载模型文件:
mkdir -p ~/.recall/models/all-MiniLM-L6-v2
curl -L -o ~/.recall/models/all-MiniLM-L6-v2/model.onnx \
https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2/resolve/main/onnx/model.onnx
curl -L -o ~/.recall/models/all-MiniLM-L6-v2/vocab.txt \
https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2/resolve/main/vocab.txt
如果没有模型文件,Recall将退回到子字符串(LIKE)搜索。
身份验证和访问控制
Recall有两层身份验证: 传输层 (谁可以连接)和 刀具水平仪 (他们所看到的)。
传输:本地与远程
本地(stdio): Claude Code通过stdio连接,无需传输身份验证。
远程(HTTP): 具有PKCE或API密钥的OAuth 2.1控制谁可以连接。
# OAuth setup (for claude.ai)
dotnet run -- oauth setup
# Prompts for a passphrase and your server's public URL
# API keys (for other clients)
dotnet run -- key create "my-client" # Generate a key (shown once)
dotnet run -- key list # List all keys
dotnet run -- key revoke 3 # Revoke by ID
这两种方法同时起作用。如果没有任何配置,服务器将打开运行。
工具级别:四层访问
每次日记/健康工具调用(除 diary_time)需要a secret 参数。服务器对其进行哈希运算,并与配置的哈希值进行比较,以确定访问级别。当根本没有配置身份验证哈希时,服务器默认为特权访问(仅供本地使用)。Rohlik工具没有访问控制(它们由是否配置凭据来控制)。
| 级别 | 日记 | 健康 | 固定/基础 | 写限制 |
|---|---|---|---|---|
| 享有特权的 | 所有未分类的条目,所有层级 | 是 | 是 | 有 |
| 编程 | 无限制+仅无范围 | 否 | 否 | |
| 作用域的 | 仅限自己的范围 | 否 | 否 | |
| 无 (无/坏秘密) | 拒绝 | 拒绝 |
在中配置 ~/.recall/config.json:
{
"guardianSecretHash": "<sha256 of privileged passphrase>",
"codingSecretHash": "<sha256 of coding passphrase>"
}
使用以下方法生成哈希值: echo -n "your-passphrase" | sha256sum
将秘密注入克劳德密码 --使用a PreTool使用挂钩 它将编码秘密添加到每个Recall工具调用中。示例 ~/.claude/hooks/recall-secret.sh:
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
# diary_time needs no secret
if [ "$TOOL_NAME" = "mcp__claude_ai_Recall__diary_time" ]; then
exit 0
fi
TOOL_INPUT=$(echo "$INPUT" | jq -r '.tool_input')
UPDATED=$(echo "$TOOL_INPUT" | jq '. + {"secret": "YOUR_CODING_SECRET"}')
jq -n --argjson updated "$UPDATED" '{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"updatedInput": $updated
}
}'
在中注册 ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [{
"matcher": "mcp__claude_ai_Recall__.*",
"hooks": [{"type": "command", "command": "/path/to/recall-secret.sh"}]
}]
}
}
对于claude.ai(特权),在系统提示符中包含特权秘密,并指示将其作为 secret 每个工具调用中的参数。
范围用户(独立项目)
多个用户或项目可以共享一个完全隔离的Recall实例。每个作用域用户都有自己的日记空间——他们只能查看和写入标记有其作用域的条目。管理员(特权用户)默认情况下会看到全局条目,并可以选择查看任何范围。
| 级别 | 看到 | 写入 | 健康 |
|---|---|---|---|
| 享有特权的 | 全局条目(根据请求提供所有范围) | 任何范围 | 是 |
| 编程 | 仅全局无限制 | 全局无限制 | no |
| 作用域的 | 只有范围 | 只有范围 | 没有 |
设置范围:
# Generate credentials
PASSPHRASE=$(openssl rand -base64 24)
HASH=$(echo -n "$PASSPHRASE" | sha256sum | cut -d' ' -f1)
echo "Passphrase: $PASSPHRASE"
echo "Hash: $HASH"
添加 ~/.recall/config.json 在服务器上:
{
"Scopes": [
{ "Name": "project-name", "SecretHash": "<hash from above>" }
]
}
重新启动服务。将密码提供给用户——请参阅 ONBOARDING.md 对于他们的设置步骤。
范围隔离是如何工作的:
- 条目有
scope列(NULL=全局,“项目名称”=范围) - 作用域用户的写入会自动标记其作用域
- 查询在SQL级别按作用域过滤——ONNX矢量搜索仅扫描匹配的条目,而不是整个数据库
- 现有条目(作用域=NULL)对特权和编码仍然可见,对作用域用户不可见
重要提示:PreToolUse挂钩 updatedInput 替换,而不是合并。 钩子脚本必须读取原始脚本 tool_input 从stdin中,将秘密合并到其中 jq,并返回完整的组合对象。如果你只回来 {secret: "..."},所有其他参数(如 content)丢失,工具调用失败。看 ONBOARDING.md 以获取正确的钩子脚本。
分层老化
随着条目的积累,较旧的条目会自动降低优先级,因此最近的上下文仍然具有相关性。参赛作品分为三个层次:
| 级别 | 姓名 | 年龄 | diary_search 上下文 |
diary_search 查询 |
diary_search 列表 |
|---|---|---|---|---|---|
| 0 | 热门 | <7天 | 最近+搜索 | 是 | 是 |
| 1 | 温暖 | 7-90天 | 仅搜索 | 是 | 否 |
| 2 | 寒冷 | >90天 | 否 | 是 | 否 |
衰老在每个开始时都很缓慢 diary_search action=上下文调用。阈值是可配置的:
{
"tierHotDays": 7,
"tierWarmDays": 90
}
固定和基础条目
置顶 条目(diary action=pin id=42)免于自动老化——它们永远保持在当前级别。
基础的 条目(diary action=pin id=42 basical=true)被固定,并且始终显示在顶部 diary_search action=特权用户的上下文。它们显示为紧凑的索引(ID+第一行) diary action=获取完整内容。对于应始终与上下文相关的参考材料很有用。
这两个功能都是特权。
日历
日历提供日记的日视图:计划、摘要和链接条目。
运作原理
每个日期都可以有一个包含两个字段的日历条目:
- 计划 --你打算做什么(可以为未来的日期设置)
- 摘要 --对所发生事情的简明记录(事后写成)
日记条目根据其创建日期自动链接到日历日。呼叫 diary_day action=带日期的视图,在一个视图中查看所有内容。
访问控制
日历条目遵循与日记条目相同的访问模型:
| 级别 | 看到 | 可以创建 |
|---|---|---|
| 享有特权的 | 所有日历条目(任何范围,无论是否受限) | 受限和不受限 |
| 编程 | 无范围,仅无限制 | 仅无限制 |
| 作用域的 | 仅限自己的范围 |
一个日期可以有多个具有不同访问级别的日历条目。例如,特权用户可能会在同一天同时编写受限摘要(包含私人详细信息)和非受限摘要(对编码会话安全)。这 restricted 日历条目上的标记控制可见性的方式与日记条目相同。
生成摘要
摘要是存储的文本,不是自动生成的。预期的工作流程:
- 呼叫
diary_dayaction=查看查看条目的日期 - 写一个简明的总结
- 呼叫
diary_dayaction=总结以存储它
这可以手动完成,也可以作为跨历史日期的批处理操作编写脚本。
健康数据集成
Recall可以存储Fitbit的每日健康摘要(睡眠、心率、活动、SpO2)、天气数据、月经周期跟踪和偏头痛跟踪。这 tools/ 目录包含:
| 脚本 | 目的 |
|---|---|
tools/fitbit-sync.py |
通过API获取Fitbit数据,丰富天气(Open-Meteo),写入recall.db |
tools/fitbit-cron.sh |
每小时定时任务:同步+推送到远程+偏头痛风险预测 |
tools/cycle.py |
月经周期跟踪与预测 |
tools/migraine.py |
偏头痛记录、历史与天气/周期背景、7天风险预测 |
健康数据通过 health MCP工具(操作:最近,查询)。偏头痛和月经开始可以直接通过 health 工具(操作:log_migraine、log_period)或通过CLI脚本。
偏头痛预测
migraine.py predict 获取7天的天气预报,每天根据以下因素对偏头痛风险进行评分:
- 大气压下降(>5 hPa=中等,>10 hPa=高风险)
- 月经周期阶段(月经=高,排卵=中等)
- 温度波动(每日范围>12°C)
风险预测会写入日历表,以便显示在 diary_day 意见。
部署
本地(stdio)
只需按照快速入门中的说明使用Claude Code注册即可。不需要服务器进程。
远程(HTTP)
发布a 独立的 二进制文件,并将其作为服务运行。除非准确无误,否则依赖框架的构建将无法工作。NET运行时已安装在服务器上。
# Build (self-contained for Linux x64)
dotnet publish src/Recall.Server/Recall.Server.csproj \
-c Release --self-contained -r linux-x64 -o publish/
# Copy to server
rsync -av publish/ server:~/recall-server/
# Run
./publish/Recall.Server --http --port 3000
systemd服务 (/etc/systemd/system/recall.service):
[Unit]
Description=Recall MCP Server
After=network.target
[Service]
Type=exec
User=recall
WorkingDirectory=/opt/recall
ExecStart=/opt/recall/Recall.Server --http --port 3000
Restart=on-failure
RestartSec=5
Environment=DOTNET_ENVIRONMENT=Production
[Install]
WantedBy=multi-user.target
sudo systemctl enable --now recall
在TLS前面放置一个反向代理(Apache/nnginx/Caddy)。Claude.ai需要HTTPS。
更新正在运行的服务器
dotnet publish src/Recall.Server/Recall.Server.csproj \
-c Release --self-contained -r linux-x64 -o publish/
rsync -av publish/ server:~/recall-server/
# On the server:
sudo systemctl restart recall
SQLite数据库在重新启动时保留。架构迁移在启动时自动运行。
代理外部MCP服务器
Recall可以作为其他MCP服务器的OAuth网关。任何基于stdio的MCP服务器都封装在 超级通道 可以通过Recall的现有身份验证进行代理,无需额外的OAuth设置。(注意:Rohlik杂货工具现在直接集成到召回服务器二进制文件中,而不是代理。)
它是如何工作的:
claude.ai ──HTTPS──▶ reverse proxy ──▶ Recall ──▶ supergateway ──▶ stdio MCP server
(OAuth gate) (Streamable HTTP)
步骤1:使用supergateway设置外部MCP服务器
# Install on the server
mkdir -p ~/my-mcp && cd ~/my-mcp
npm init -y
npm install supergateway @some/mcp-server
# Create credentials file (if needed)
cat > ~/.config/my-mcp.env << 'EOF'
MY_USERNAME=user@example.com
MY_PASSWORD=secret
EOF
chmod 600 ~/.config/my-mcp.env
步骤2:创建systemd用户单元
# ~/.config/systemd/user/my-mcp.service
[Unit]
Description=My MCP Server (supergateway)
After=network.target
[Service]
Type=exec
EnvironmentFile=%h/.config/my-mcp.env
ExecStart=/usr/bin/npx --prefix %h/my-mcp supergateway \
--stdio "node %h/my-mcp/node_modules/@some/mcp-server/dist/index.js" \
--port 8385 \
--outputTransport streamableHttp \
--streamableHttpPath /mcp \
--logLevel info
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user enable --now my-mcp
loginctl enable-linger # persist after logout
步骤3:将代理添加到Recall的配置中
在 ~/.recall/config.json:
{
"mcpProxies": [
{ "prefix": "my-mcp", "target": "http://127.0.0.1:8385" }
]
}
重新启动召回。工具现在可以在 https://your-server/recall/my-mcp/mcp 使用相同的OAuth令牌。
步骤4:添加claude.ai连接器
在claude.ai设置中,添加一个MCP连接器,URL为:
https://your-server/recall/my-mcp/mcp
它使用与Recall相同的OAuth密码,没有单独的身份验证设置。
重要提示:
- 使用
--outputTransport streamableHttp在supergateway中,claude.ai更喜欢流式HTTP而不是SSE - Apache/nnginx中不需要代理配置——现有
/recall/代理规则覆盖所有子路径 - 当
mcpProxies不存在或为空,零代理代码运行——对Recall没有影响 - 外部服务的凭据放在env文件中,从不放在Recall的配置或仓库中
建筑
┌─────────────────────────────────────────────┐
│ Recall MCP Server │
│ SQLite + vector search + OAuth 2.1 │
│ │
│ /sse, /message → diary, health, rohlik │
│ /{prefix}/* → proxy to backend (opt) │
└──────┬──────────────────┬───────────────────┘
│ │
MCP protocol reverse proxy (opt)
│ │
┌────┴────────┐ ┌─────┴──────────┐
│ Claude Code │ │ supergateway │
│ claude.ai │ │ (external │
│ any client │ │ MCP servers) │
└─────────────┘ └────────────────┘
建筑
dotnet build # Build
dotnet test src/Recall.Tests # Run tests
许可证
麻省理工学院