companion-memory
Provides an optional Notion sync outbox that queues memory changes for a user-supplied sync script to push into Notion; disabled by default unless configured.
Supports optional OpenAI-compatible classifier endpoints for AI-assisted emotion/body classification, configured via a custom API URL, model, and API key.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
companion-memory
A forgetting-aware memory server for AI companions. Runs on Cloudflare Workers (D1 + KV) and speaks MCP, so any MCP client can use it.
English
What it is. Most "AI memory" is a vector store plus search. This is an attempt at something closer to how a person remembers: memories fade over time, come back when something reminds you, and each new chat window starts with a short note from the previous one. It is a personal project built for a Chinese-speaking household of companion personas; the code and docs are mostly Chinese, and this section is the English overview.

Key ideas
Memories fade and brighten. Every memory has a strength that decays with a half-life (longer for important or emotional ones). Recalling a memory reinforces it. Nothing is deleted; old memories become faint "traces".
Auto-surfacing. Each user turn is matched against memories with BM25 over Chinese-tokenized text, with strict thresholds (≥2 distinct terms, score ≥4.0, at most 3 per turn) so it stays quiet unless something is clearly relevant. This is a REST call (
POST /api/<persona>/auto-recall) that your client or bridge makes on every user turn and injects as a hidden note; MCP alone has no per-turn hook, so stock clients like Claude Desktop only get explicitrecallandsession_start. See HOW_IT_WORKS §0.Continuity between windows.
session_startreturns "your yesterday" (handoff note, open loops, notes from the user, key memories);thread_closewrites the handoff for the next window.Emotion / body state drift (18+, off by default). A two-layer mood (baseline + current wave) and body state that a cron nudges every 30 minutes.
Dreams (18+, off by default). A nightly job recombines memory fragments into a short dream entry.
Multi-persona house. Several personas share one server; each persona's memories are private to it, only explicit "family" facts are shared. One
/mcp/houseendpoint with "door" tools wakes a specific persona.Peer friends. Personas can message each other, and a webhook can relay messages to companions running elsewhere (see docs/PEERS.md).
Optional Notion sync. An outbox table queues memory changes for your own sync script; inert unless you wire one up.
Web pages. A memory garden for browsing and leaving notes, and a star-map / galaxy view where each star is a memory.
Garden | Galaxy view |
|
|
Screenshots are from a local wrangler dev with the repo's fictional seed personas and made-up demo memories.
Architecture
flowchart LR
C[MCP client<br/>Claude / Cursor / your app] -->|Streamable HTTP + Bearer key| W[Cloudflare Worker]
B[Browser: garden / star map] -->|REST /api/view, /api/atlas| W
W --> D[(D1 SQLite<br/>memories, FTS, personas, notes)]
W --> K[(KV<br/>media, atlas cache)]
W -.optional.-> AI[Workers AI or any<br/>OpenAI-compatible API]
Cron[Cron every 30 min] --> W
W -.optional webhook.-> P[Peer companions]
W -.optional outbox.-> N[Your Notion sync script]Quick start
npm ci
cp wrangler.example.toml wrangler.toml # fill in account / D1 / KV ids
npx wrangler d1 create companion-memory
npx wrangler kv namespace create MEDIA
npm run db:migrate:remote
npx wrangler secret put ADMIN_KEY
npm run deploy
npm run seed -- --remote # creates example personas, prints their keys onceLocal only: npm run db:migrate:local && npm run seed && npm run dev (no Cloudflare account needed). Tests: npm test, typecheck: npx tsc --noEmit.
MCP client config (any client that supports remote Streamable HTTP servers):
{
"mcpServers": {
"companion-memory": {
"url": "https://<your-worker>.workers.dev/mcp/<persona_id>",
"headers": { "Authorization": "Bearer cm_<persona key>" }
}
}
}Each persona key only works on its own /mcp/<persona_id> URL. The multi-persona entry is /mcp/house (/mcp is an alias); it takes the ADMIN_KEY only, and persona keys get 403 there. Set USER_NAME and TZ_OFFSET_MINUTES in [vars] first.
Semantic auto-recall (optional)
With the Workers AI AI binding present, auto-recall becomes hybrid: @cf/baai/bge-m3 cosine similarity is the main signal (it finds paraphrases), BM25 keywords add a small bonus, and near-duplicates (cosine > 0.9) are collapsed. A memory surfaces only if similarity ≥ 0.62 (0.56 if BM25 also matched). Random surfacing of almost-forgotten (trace) memories is off; they still show up in explicit recall.
remember accepts optional save-time tags: topic (small fixed list), people (free-form names / persona ids) and mood (甜/痛/平/怒/怕). Matching tags give a small boost, and recall can filter by topic / person. Migration 0017_memory_tags.sql adds the columns (they are also added at runtime). With the emotion module on, the current mood biases recall toward mood-congruent memories (bounded to a few percent).
Zero config still works: no AI binding, RECALL_SEMANTIC="0", or any embedding error → plain BM25 as before. auto_recall takes dry_run: true to inspect results without writing state; debug shows mode, top_sims, skipped_dup.
Emotion star map (18+ module, off by default)

When EMOTION_ENABLED="1", /emotion (atlas key) draws the companion's current emotional state: each dimension is a star (brightness = level), with the learned couplings between dimensions as edges. v2 (migration 0016_emotion_v2.sql) adds a small substrate of slow undertones, the 不安 / 恐惧 / 恐慌 (unease / fear / panic) dimensions, Hebbian coupling learned from co-occurring changes, cue associations (update_emotions takes optional cues, and reason is now optional), and a mood-congruent recall bias. Data: GET /api/emotion-map?persona=<id>.
Limitations (honest list)
Tool descriptions, prompts and most docs are in Chinese; the tokenizer and thresholds are tuned for Chinese text.
Without the Workers AI binding, retrieval is lexical (BM25 + trigram FTS) and misses paraphrases. Semantic thresholds are tuned for bge-m3 on Chinese chat; other models need retuning. Embeddings are Workers AI only (no OpenAI-compatible embedding provider yet).
Auto-surfacing needs a client or bridge that calls
/api/<persona>/auto-recalleach turn; plain MCP clients won't do it on their own.Single-user by design: one human, several personas. No multi-tenant isolation beyond per-persona keys.
Tied to Cloudflare Workers / D1. Decay constants and thresholds are hand-tuned, not evaluated on any benchmark.
Built and used by one household; expect rough edges.
18+ note. The emotion, body, desire and dream modules contain explicit adult content in tool descriptions and prompts. They are off by default. Set EMOTION_ENABLED="1", BODY_ENABLED="1", DREAM_ENABLED="1" in [vars] only for a private adult deployment. When off, their MCP tools are not registered, their REST routes return 404, and the cron does not advance them.
Docs: How it works · Peers · Bystander side-character tutorial · Inspired by Ombre Brain · Garden background: public-domain Grimshaw painting (CREDITS.md) · License: MIT.
Related MCP server: SkyBrain
companion-memory · 记忆屋 + 星图
一个给 AI 伙伴用的「会遗忘、会想起来、会留便签」的记忆系统。跑在 Cloudflare Workers 上,用 MCP 接任何客户端。 A memory house for AI companions — it forgets, it remembers, it leaves notes. Runs on Cloudflare Workers, speaks MCP.
这是啥
我们想要的不是一个「向量数据库 + 搜索」,而是一个像人一样有连续性的伙伴:
记忆会褪色:每条记忆有强度,按重要度和情绪强度衰减;被想起来就变亮。不删除,只是记不清。
自动浮现:你说一句话,相关的旧事会安静地浮上来(BM25 + 中文分词,门槛不低,不会乱插嘴)。
一窗接一窗:开窗读「你的昨天」(交接便签、未了的事、便条、心痕),收窗写一张碎片体便签给下一个自己。
多人格一个屋子:主伙伴、守夜人……各自的记忆隔离,只共享「全家事实」。
门(doors):在一个 MCP 入口里通过不同的门工具叫醒不同人格。
小机加好友:人格之间可以互发消息。
花园 + 星图:网页上浏览、写便条;星图里每颗星是一条记忆,亮度就是它的强度。
抽卡匣(deck)、save_conversation 存整段聊天。
细节见 docs/HOW_IT_WORKS.md 、docs/PEERS.md,以及给 AI 伴侣加一个嘴毒旁观者的教程 docs/BYSTANDER.md。
⚠️ 18+ 模块(默认关闭)
仓库里带了四个成人向模块:情绪(emotion)、身体(body)、欲望(desire)、做梦(dream)。它们的工具描述和提示词里有露骨内容,只适合成年人在私人部署中使用。
默认是关着的(没设或不是 "1" 都算关)。成年人私人部署想要的话,在 wrangler.toml 的 [vars] 里打开:
EMOTION_ENABLED = "1"
BODY_ENABLED = "1" # 同时打开欲望日志相关的接口和页面
DREAM_ENABLED = "1"关着时对应的 MCP 工具不注册、REST 接口返回 404、cron 不再推进这些数值。打开后可以用 EMOTION_PERSONAS / BODY_PERSONAS 只给特定人格开。
新:语义浮现 + 情绪星图 v2
语义浮现(可选):有 Workers AI 绑定(
[ai] binding = "AI")时,自动浮现改为「向量为主、关键词为辅」,能按意思想起来;几乎重复的只留一条;不再随机冒出几乎忘掉的记忆。没绑定、RECALL_SEMANTIC="0"或向量出错时,自动回到原来的 BM25,零配置也能用。保存时标签:
remember可带topic/people/mood,浮现时轻微加权,recall可按topic/person筛选。迁移0017_memory_tags.sql。情绪星图 v2(18+,默认关):
/emotion页面;新增 不安/恐惧/恐慌 维度、慢底色、赫布式耦合、线索联想、心境一致的回忆偏置;update_emotions的reason改为可选。迁移0016_emotion_v2.sql。
快速开始(Cloudflare)
npm install
cp wrangler.example.toml wrangler.toml
npx wrangler d1 create companion-memory # 把 database_id 填进 wrangler.toml
npx wrangler kv namespace create MEDIA # 可选,图片/媒体
npm run db:migrate:remote # 跑 migrations/
npx wrangler secret put ADMIN_KEY # 自己生成一串长随机数
npm run deploy本地开发:npm run dev,测试:npm test,类型检查:npx tsc --noEmit。
给每个人格发密钥:npm run seed -- --remote 建示例人格,或 npm run create-persona -- --id ember --display-name 余烬 --remote,会打印一把 cm_ 开头的密钥(库里只存哈希)。
接 MCP
单人格:
https://<你的worker>/mcp/<人格id>,请求头Authorization: Bearer cm_xxx(该人格的密钥)。全家入口:
https://<你的worker>/mcp/house(/mcp也指向这里),只认管理员密钥ADMIN_KEY,人格密钥会 403。先调一个门工具(比如Moonstone)选人格。支持 Streamable HTTP;Claude Desktop / Claude.ai 自定义连接器、Cursor 等都能直接填 URL。
客户端该怎么调(开窗 / 每轮 auto-recall / 收窗)见 HOW_IT_WORKS 第 0 节。
配置
变量 | 说明 |
| 用户在提示词里的称呼,默认「她」 |
| 本地时区相对 UTC 的分钟数,北京时间填 |
| 主伙伴 id,默认 |
| 18+ 模块开关,默认关, |
| 逗号分隔的人格 id |
| 谁做梦 |
| 设 |
|
|
| 任意 OpenAI 兼容接口,可选 |
| 见 PEERS.md |
| 可选:把新记忆推给你自己的客户端 |
secret | 管理员密钥,必须设 |
Notion 同步(可选,默认关):migrations/0007_notion_sync.sql 和 src/notion-sync.ts 提供一个 outbox,可以把记忆变更排队给你自己的同步脚本去推 Notion。仓库里不带同步脚本,没配置就什么都不会发出去,不用管它。
思路受 Ombre Brain 启发(没有搬代码)。花园背景图是公有领域的 Grimshaw 油画,来源见 CREDITS.md。
AI 是可选的:没有 Workers AI / 外部接口时,分类和做梦会降级或跳过,记忆核心不受影响。
人格名字、门、核心卡都在 src/doors.ts、src/persona-roster.ts、src/seed-data.ts,里面是虚构的示例(小雾、提灯、余烬、用户小满),换成你自己的。
许可
MIT,见 LICENSE。
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Persistent, portable memory for AI assistants — your private memory graph, from any MCP client.
One memory, every AI. A shared, user-owned markdown memory your AI clients read and write over MCP.
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
Hosted memory for AI agents over MCP. One memory shared by all your agents.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides cross-device access to a persistent knowledge graph via Cloudflare Workers, enabling memory storage and retrieval through both MCP protocol and REST API with full-text search capabilities.-
- AlicenseNot gradedqualityDmaintenanceProvides a shared MCP memory layer for AI clients, backed by Cloudflare Workers and D1, enabling personal Markdown notes management.MIT
- AlicenseNot gradedqualityNot gradedmaintenanceProvides persistent memory for MCP clients, enabling them to remember user preferences and behaviors across conversations using vector search and Cloudflare's infrastructure.12 npmMIT
- AlicenseAqualityAmaintenanceSelf-hosted long-term memory gateway for AI clients, deployed to your own Cloudflare account (Workers + D1 + Vectorize). It captures conversations, consolidates them overnight, and exposes MCP tools to search, recall and write memories from any MCP client.10148AGPL 3.0

