mcp-http-diary-server
Provides tools for writing and retrieving diary entries, using Supabase as the persistent storage backend.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-http-diary-serverwrite a diary entry about my day and set mood to happy"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
🧠 AI 长期记忆系统 —— 自动化维护实施方案
基于 MCP Streamable HTTP 的 AI 长期记忆系统,支持「日志提炼 → 长期记忆管理 → 自动化维护」生产级方案。 AI 助手可认识用户、记住信息、理解偏好、学习人格、保存共同经历,并通过定时提炼工作流把每日聊天沉淀为可复用的长期记忆, 同时保证幂等(重复运行不产生重复数据)、可重试(失败日志保留并重跑)、可清理(超期日志自动清理)。
核心流程:聊天 → 每日日志 → AI 分类/打标签 → 定时提炼 → memory_key 定位 → insert/update → 验证 → processed → 保留 14 天 → 清理。
技术栈(禁止更换)
Node.js + TypeScript
Express(HTTP 服务)
MCP SDK(Streamable HTTP,
@modelcontextprotocol/sdk)Supabase(
@supabase/supabase-js,anon 发布密钥)Zod(参数校验)
Related MCP server: ppdiary
系统架构
┌──────────────┐ chat ┌──────────────────────────┐
│ AI 助手/客户端 │ ─────────▶ │ save_daily_log │
└──────────────┘ │ (companion_daily_logs) │
│ processing_status=pending │
└────────────┬───────────────┘
│ get_unprocessed_logs
▼
┌──────────────────────────┐
│ 定时提炼工作流(weekly) │
│ AI 分类 + importance 标签 │
└────────────┬───────────────┘
memory_key 匹配 │
┌─────────────────────────────┼─────────────────────────────┐
▼ ▼ ▼
┌─────────────────┐ ┌────────────────────┐ ┌──────────────────┐
│ get_memory_by_key│ │ save_memory │ │ save_shared_memory│
│ 命中→update_memory│ │ (memory_key, 插入) │ │ (幂等 upsert) │
└────────┬────────┘ └─────────┬──────────┘ └─────────┬────────┘
│ │ │
▼ ▼ ▼
companion_memories companion_memories shared_memories
│ │
└──────────── record_extraction_task ───────────────┘
(memory_extraction_logs 仅元数据)
失败:update_log_status(failed, error_reason) → 下一轮重试
成功:update_log_status(processed) → 保留 14 天 → delete_logs 清理表名约定:方案中
memories/daily_logs/shared_memories在本仓库对应既有表companion_memories/companion_daily_logs/shared_memories(沿用历史命名以兼容线上数据与旧接口)。
项目结构
mcp-http-diary-server/
├── package.json
├── tsconfig.json
├── .env.example # 环境变量模板(复制为 .env 填写)
├── Dockerfile # 已支持公网部署(Render / Railway / 云服务器)
├── README.md
├── docs/
│ └── AI-memory-workflow.md # 自动化维护工作流说明(流程/幂等/删除策略)
├── src/
│ └── index.ts # MCP HTTP Server 主入口(全部逻辑)
├── scripts/
│ ├── setup-db.mjs # 按顺序应用 supabase/migrations 下所有迁移
│ ├── check-schema.mjs # 检查 diaries.content 列
│ └── test_new_tools.mjs # 走真实 HTTP 链路的自检脚本
├── tests/
│ └── memory-workflow.test.mjs # 自动化维护工作流测试(幂等/失败/去重)
├── supabase/
│ └── migrations/
│ ├── 001_add_content_column.sql
│ ├── 002_companion_memory_columns.sql
│ └── 003_memory_automation.sql # 本次升级:memory_key/处理状态/提炼任务表
└── test-*.js # 旧版手写测试(可选)快速开始
1. 安装
cd mcp-http-diary-server
npm install2. 配置环境变量
cp .env.example .env编辑 .env(必填 SUPABASE_URL / SUPABASE_KEY):
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your_supabase_anon_key
PORT=3000
HOST=0.0.0.0
USER_ID=test_couple
LOG_RETENTION_DAYS=14 # 可选,提炼成功后日志保留天数
# DATABASE_URL=postgresql://... # 仅 db:setup 需要3. 应用数据库迁移(必须)
npm run db:setup或直接在 Supabase SQL Editor 依次执行 supabase/migrations/ 下所有 .sql
(重点是新增的 003_memory_automation.sql,它会为 companion_memories 增加 memory_key、
为 companion_daily_logs 增加 processing_status / error_reason / updated_at / mood、
为 shared_memories 增加 created_at 与 importance NOT NULL、并新建 memory_extraction_logs)。
4. 编译运行
npm run build
npm start # 生产:node dist/index.js
# 或开发模式(热重载源码)
npm run dev # tsx src/index.ts健康检查:
curl http://localhost:3000/healthMCP 接口说明
共 18 个工具,全部服务于长期记忆与自动化维护(含 V1.1 生命周期闭环 8 个新工具)。
工具瘦身说明:
write_diary/get_diaries两个「用户主动写日记 / 查看日记」的旧兼容接口已于 V1.2 下线。 本服务是 AI 长期记忆系统,不是日记应用;聊天记录统一由save_daily_log写入companion_daily_logs后进入提炼流水线。 注:仅移除 MCP 工具注册,diaries表与其历史数据保留不动。
工具 | 写入/读取表 | 说明 |
|
| 保存长期记忆(可选 memory_key 幂等定位) |
|
| 按 user_id + memory_key 查询已有记忆 |
|
| 按分类/关键词召回历史记忆 |
|
| 保存每日总结(入队 pending) |
|
| 保存共同经历(幂等 upsert) |
|
| 更新已有记忆(支持 id 或 memory_key) |
|
| 拉取 pending / failed 日志 |
|
| 更新日志处理状态 |
|
| 删除超期 processed 日志 |
|
| 记录/更新提炼任务(仅元数据) |
|
| V1.1 原子领取 pending→processing,retry_count 自增(防并发重复消费) |
|
| V1.1 标记成功 processed,retry_count 归零,写 processed_at / extract_task_id |
|
| V1.1 失败:retry_count<3 回滚 pending,≥3 标记 failed |
|
| V1.1 超时恢复:stuck processing 按 retry_count 回滚/失败 |
|
| V1.1 历史修复:无 extraction_results 的 processed 回滚 pending |
|
| V1.1 写日志↔memory 关联(log,task 唯一,先删后插幂等) |
|
| V1.1 读取共同经历(title 精确 / keyword 模糊,返回含 event) |
|
| V1.1 查询提炼任务(task_id/log_ids/status/时间) |
save_memory(category, content, importance?, confidence?, source?, memory_key?)
category(必填,枚举):user_profile/preference/personality/goal/skill/relationship/emotional_pattern/conversation_stylecontent(必填):记忆正文(≤ 4000 字符)importance(可选,1–5,默认 3)confidence(可选,0–1,默认 0.8)source(可选,默认conversation)memory_key(可选,namespace.topic):省略时自动生成。命名空间必须由 category 推导(见下表),禁止自由创建。
memory_key 命名规范
格式 namespace.topic,命名空间与 category 强制绑定:
category | namespace |
user_profile | profile |
preference | preference |
personality | personality |
goal | goal |
skill | skill |
relationship | relationship |
emotional_pattern | emotional_pattern |
conversation_style | conversation_style |
示例:profile.basic_info、preference.food、relationship.first_meet、skill.design。
get_memory_by_key(memory_key, user_id?)
按
user_id+memory_key查询;返回{ success, found, memory }。幂等定位记忆的核心接口,提炼工作流先查后写。
recall_memory(category?, keyword?, limit?)
category:按分类过滤;keyword:对content做ILIKE模糊匹配;limit(1–100,默认 20)。
save_daily_log(log_date?, events?, user_state?, mood_changes?, topics?, relationship_state?, mood?)
写入
companion_daily_logs并令processing_status = 'pending'(进入提炼队列)。mood(可选,整数 -2~2):当日心情。同日重复保存仅更新结构化字段,不重置
processing_status(已 processed 的不会被重新入队)。
save_shared_memory(title, event, importance?)
按
(user_id, title)幂等 upsert:同一标题重复保存更新而非新增。
update_memory(id? / memory_key?, category?, content?, importance?, confidence?, source?)
兼容旧方式:传
id直接更新。新方式:传
memory_key,内部先get_memory_by_key取 id 再更新。用于修正过期记忆(如「喜欢猫」→「喜欢狗」),避免无限累积重复记忆。
get_unprocessed_logs(limit?, include_failed?)
默认返回
pending+failed(可重试)日志;include_failed=false仅返回pending。供自动化提炼工作流拉取待处理日志。
update_log_status(id, processing_status, error_reason?)
processing_status:pending/processing/processed/failed(四态状态机)。守卫:存在
error_reason时拒绝标记为processed(失败不能标记成功)。
delete_logs(retention_days?, older_than?)
仅删除
processing_status = 'processed'且updated_at早于截止日的日志(failed保留以便重试)。retention_days默认取LOG_RETENTION_DAYS(14);older_than可覆盖截止日。
record_extraction_task(id?, task_id?, log_ids?, status?)
写入/更新
memory_extraction_logs(pending/running/success/failed)。只保存任务元数据,不保存 AI 提炼全文。
数据库设计
表 | 关键列 | 说明 |
|
| 长期记忆; |
|
| 每日日志;四态状态机驱动提炼闭环(见 V1.1) |
|
| 共同经历;按标题幂等 |
|
| 提炼任务记录(仅元数据) |
|
| V1.1 日志↔memory 关联;保证提炼幂等(不删 memory 本身) |
|
| 旧版日志本;V1.2 起无 MCP 工具读写,仅保留历史数据 |
时间统一以 UTC 存储(
TIMESTAMPTZ/ Supabase 默认时区)。companion_daily_logs的扩展列由迁移002添加;003新增processing_status/error_reason/updated_at/mood与memory_key等。
自动提炼流程
详见 docs/AI-memory-workflow.md。要点:
日志入队:
save_daily_log写入,processing_status = pending。定时提炼:工作流
get_unprocessed_logs拉取pending/failed日志。AI 分类 + 打标签:归入
category、importance。memory_key 定位:按
category → namespace生成namespace.topic。insert / update:先
get_memory_by_key,命中则update_memory,未命中则save_memory。验证成功 →
processed;失败 →failed+error_reason,下一轮重试。删除策略:
processed日志保留LOG_RETENTION_DAYS(默认 14)天后由delete_logs清理;failed不删除。幂等:重复运行不产生重复
memory/shared_memory(依赖memory_key与唯一约束)。
部署方式
服务支持 HOST / PORT / LOG_RETENTION_DAYS 环境变量,MCP 端点为 https://你的域名/mcp。
方式一:Render(推荐,详细步骤)
项目根目录已提供 render.yaml(Blueprint),可一键部署;也可在 Dashboard 手动创建。
把本项目推到 GitHub(
.env已被.gitignore忽略,密钥不会上传)。Render Dashboard → New → Blueprint → 连接该 GitHub 仓库 → Apply。
在创建的服务里,给
SUPABASE_URL/SUPABASE_KEY填入真实值(标记为sync:false,需手动填);其余变量已带默认值。部署完成后,公网 MCP 端点即
https://<你的服务名>.onrender.com/mcp。
Health Check Path:
/health。免费版有冷启动(约 30–50s),首次调用可能超时属正常。
方式二:云服务器(VPS)
上传项目,安装依赖并构建后运行 npm start,确保 HOST=0.0.0.0、PORT 对外开放。
通过 http://你的公网IP:3000/mcp 访问。
方式三:Docker
docker build -t ai-memory-mcp .
docker run -d -p 3000:3000 \
-e SUPABASE_URL=... -e SUPABASE_KEY=... \
-e HOST=0.0.0.0 -e LOG_RETENTION_DAYS=14 \
ai-memory-mcp方式四:Cloudflare Tunnel / ngrok(临时域名)
cloudflared tunnel --url http://localhost:3000 # 得到 https://xxx.trycloudflare.com/mcp
# 或
ngrok http 3000 # 得到 https://xxx.ngrok.io/mcp本地自检
# 先启动服务(另开终端)
npm run dev
# 全部新工具写读自检(真实链路)
node scripts/test_new_tools.mjs
# 自动化维护工作流测试(幂等/失败/去重,需已应用 003 迁移)
npm run test:workflow
# V1.1 生命周期闭环测试(tools/list + 共享记忆 + 状态流转 + 任务查询,需已应用 004 迁移)
npm run test:v11环境变量说明
变量 | 必填 | 说明 | 默认值 |
| ✅ | Supabase 项目 URL | - |
| ✅ | Supabase anon key | - |
| 否 | HTTP 监听端口 | 3000 |
| 否 | 监听地址 | 0.0.0.0 |
| 否 | 记忆归属用户 | test_couple |
| 否 | 提炼成功后每日日志保留天数 | 14 |
| 仅 db:setup | Supabase 数据库连接串 | - |
| 否 | CORS 来源( | true |
MCP 协议支持
✅ initialize / ping / tools/list / tools/call / notifications/
✅ 兼容
POST /与POST /mcp两个入口
技术栈
Express.js + TypeScript
Supabase JS Client
MCP Streamable HTTP(无状态,每次请求新建 Server 实例)
Zod 参数校验
V1.1 变更(记忆生命周期闭环)
迁移文件:
supabase/migrations/004_lifecycle_v1.1.sql(幂等,可重复执行)。
修复目标(不改整体架构,仅闭环)
daily_logs 状态机升级为四态:
pending → processing → processed,异常processing → pending(failed 可重试)/processing → failed(retry 耗尽)。并发防重:
claim_daily_log走UPDATE ... WHERE processing_status='pending'(原子条件更新)+retry_count自增,多个 worker 不会重复消费同一条日志。retry 阈值:
mark_log_failed读取retry_count,<3回滚pending(可重试),≥3标记failed并记录error_reason。超时恢复:
recover_stuck_logs(timeout_minutes=30)将卡在processing超过阈值的日志按retry_count回滚/失败。日志↔memory 关联 + 提炼幂等(新表
memory_extraction_results):record_extraction_result按(log_id, task_id)唯一约束 + 先删后插,保证重复提炼不产生重复结果;不删除companion_memories中的 memory 本身(被其他任务引用则保留)。历史数据修复:
reconcile_log_statuses()不盲目"summary 存在即 processed"——仅将processed但无任何memory_extraction_results关联的日志回滚为pending,交由真实提炼生成结果。新增查询工具:
get_shared_memories(title 精确 / keyword 模糊,返回含event)、get_extraction_tasks(按 user_id / status / task_id 过滤)。
V1.1 新增 8 个工具
claim_daily_log · mark_log_processed · mark_log_failed · recover_stuck_logs · reconcile_log_statuses · record_extraction_result · get_shared_memories · get_extraction_tasks
状态机
claim (retry_count+1)
pending ─────────────────────► processing
▲ │ ├─ mark_log_processed ─► processed (retry_count=0, processed_at)
│ │ └─ mark_log_failed
│ retry_count<3 │ │
└─────────────────────────────┘ └─ retry_count>=3 ─► failed
(recover: processing 超时 → <3 pending / >=3 failed)This server cannot be deployed
Maintenance
Related MCP Connectors
Private journal MCP server to search, analyze, and create Dabble Me entries securely via OAuth.
MCP-native open-source Notion alternative: read & write pages, databases and kanban boards.
One memory, every AI. A shared, user-owned markdown memory your AI clients read and write over MCP.
Persistent memory for AI agents — log and recall conversation context over MCP.
Related MCP Servers
- AlicenseAqualityDmaintenanceMCP server for JournalOwl that enables AI-powered journaling integration, allowing users to create, search, and browse journal entries, access weekly reviews, and get personalized suggestions directly from their AI assistant.78MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI-assisted diary management through natural language, allowing you to create, read, update, delete, and search diary entries stored locally in SQLite.-
- AlicenseNot gradedqualityCmaintenanceEnables humans and AI to collaboratively write a diary with time-ordered entries, replies, and participant-based access control via MCP tools.23MIT
- AlicenseNot gradedqualityBmaintenanceProvides a SQLite-backed off-context diary for Letta agents with MCP tools for journaling and retrieval, keeping core memory uncluttered. Supports embedding summaries and FTS fallback for semantic search.1AGPL 3.0