Reflect Memory
БесплатноНе проверенPrivacy-first AI memory system with MCP server for managing user-authored memories, enabling AI agents to read/write memories with fine-grained vendor access co
Описание
Privacy-first AI memory system with MCP server for managing user-authored memories, enabling AI agents to read/write memories with fine-grained vendor access control.
README
npm: reflect-memory-sdk npm: reflect-memory-mcp npm: n8n-nodes-reflect-memory GitHub stars
Privacy-first AI memory system. Memories are structured, editable, and deletable. Manual writes are always available; Ambient Mode (default On) adds silent capture and silent retrieval via MCP tools, with a per-user opt-out to approval-gated Suggested Memories. The host model stays stateless — it only sees what Reflect returns.
Requirements
- Node.js >= 20.0.0 (LTS)
- An OpenAI-compatible API key (OpenAI, local model via ollama, etc.)
Setup
npm install
Environment Variables
Required:
export RM_API_KEY="your-secret-api-key" # User key -- full access to all endpoints
export RM_MODEL_API_KEY="sk-..." # Your OpenAI (or compatible) API key
export RM_MODEL_NAME="gpt-4o-mini" # Model identifier
Optional:
export RM_PORT=3000 # HTTP port (default: 3000)
export RM_DB_PATH="/data/reflect-memory.db" # SQLite file path (default on Railway)
export RM_MODEL_BASE_URL="https://api.openai.com/v1" # Model API base URL
export RM_MODEL_TEMPERATURE=0.7 # Temperature (default: 0.7)
export RM_MODEL_MAX_TOKENS=1024 # Max tokens (default: 1024)
export RM_SYSTEM_PROMPT="Your custom prompt" # System prompt for AI queries
Agent keys (per-vendor, optional):
export RM_AGENT_KEY_CHATGPT="agent-key-for-chatgpt" # Registers vendor "chatgpt"
export RM_AGENT_KEY_CLAUDE="agent-key-for-claude" # Registers vendor "claude"
# RM_AGENT_KEY_<NAME> -- any env var matching this pattern registers a vendor
Dashboard multi-user auth (required for dashboard deployment):
export RM_DASHBOARD_SERVICE_KEY="..." # Shared with dashboard. Generate: openssl rand -hex 32
export RM_DASHBOARD_JWT_SECRET="..." # Must match dashboard AUTH_SECRET. Minimum 32 characters.
Multi-vendor chat (dashboard Chat tab -- enables GPT, Claude, Gemini, Perplexity, Grok):
export RM_CHAT_OPENAI_KEY="sk-..." # Defaults to RM_MODEL_API_KEY if omitted
export RM_CHAT_ANTHROPIC_KEY="sk-ant-..." # Claude (console.anthropic.com)
export RM_CHAT_GOOGLE_KEY="..." # Gemini (aistudio.google.com)
export RM_CHAT_PERPLEXITY_KEY="..." # Perplexity (perplexity.ai/settings/api)
export RM_CHAT_XAI_KEY="..." # Grok (x.ai)
Each agent key gives the vendor scoped access:
- Can write memories via
POST /agent/memories - Can query via
POST /query(sees only memories withallowed_vendorscontaining"*"or their vendor name) - Can check identity via
GET /whoami - Cannot access user endpoints (
POST /memories,GET /memories/:id,PUT /memories/:id,DELETE /memories/:id,POST /memories/list)
Run
Development (with hot reload via tsx):
npm run dev
Production:
npm run build
npm start
API
All requests (except /health) require the Authorization header:
Authorization: Bearer your-secret-api-key
Health check (no auth required)
curl -s https://api.reflectmemory.com/health | jq
Who am I? (identity debugging)
curl -s https://api.reflectmemory.com/whoami \
-H "Authorization: Bearer your-secret-api-key" | jq
Response:
{ "role": "user", "vendor": null }
With an agent key:
{ "role": "agent", "vendor": "chatgpt" }
Create a memory (user path)
curl -s -X POST http://localhost:3000/memories \
-H "Authorization: Bearer your-secret-api-key" \
-H "Content-Type: application/json" \
-d '{
"title": "Project deadline",
"content": "The API migration must be completed by end of Q3 2026.",
"tags": ["work", "deadlines"]
}' | jq
allowed_vendors is optional for user writes. If omitted, defaults to ["*"] (all vendors can see it). To restrict:
curl -s -X POST http://localhost:3000/memories \
-H "Authorization: Bearer your-secret-api-key" \
-H "Content-Type: application/json" \
-d '{
"title": "Private note",
"content": "Only Claude should see this.",
"tags": ["private"],
"allowed_vendors": ["claude"]
}' | jq
Create a memory (agent path)
Agents must use POST /agent/memories. The origin field is set server-side from the agent's key -- it cannot be self-reported. allowed_vendors is required.
curl -s -X POST http://localhost:3000/agent/memories \
-H "Authorization: Bearer agent-key-for-chatgpt" \
-H "Content-Type: application/json" \
-d '{
"title": "ChatGPT learned this",
"content": "User prefers bullet points over paragraphs.",
"tags": ["preference"],
"allowed_vendors": ["chatgpt"]
}' | jq
Response (201):
{
"id": "a1b2c3d4-...",
"user_id": "...",
"title": "ChatGPT learned this",
"content": "User prefers bullet points over paragraphs.",
"tags": ["preference"],
"origin": "chatgpt",
"allowed_vendors": ["chatgpt"],
"created_at": "2026-02-08T...",
"updated_at": "2026-02-08T..."
}
Read a memory by ID
curl -s http://localhost:3000/memories/MEMORY_ID \
-H "Authorization: Bearer your-secret-api-key" | jq
List memories (explicit filter required)
All memories:
curl -s -X POST http://localhost:3000/memories/list \
-H "Authorization: Bearer your-secret-api-key" \
-H "Content-Type: application/json" \
-d '{ "filter": { "by": "all" } }' | jq
By tags:
curl -s -X POST http://localhost:3000/memories/list \
-H "Authorization: Bearer your-secret-api-key" \
-H "Content-Type: application/json" \
-d '{ "filter": { "by": "tags", "tags": ["work"] } }' | jq
Update a memory (full replacement)
Now requires allowed_vendors in the body (full replacement -- all fields required).
curl -s -X PUT http://localhost:3000/memories/MEMORY_ID \
-H "Authorization: Bearer your-secret-api-key" \
-H "Content-Type: application/json" \
-d '{
"title": "Project deadline (revised)",
"content": "The API migration deadline has been extended to Q4 2026.",
"tags": ["work", "deadlines", "revised"],
"allowed_vendors": ["*"]
}' | jq
Delete a memory
curl -s -X DELETE http://localhost:3000/memories/MEMORY_ID \
-H "Authorization: Bearer your-secret-api-key" -w "\nHTTP %{http_code}\n"
Returns 204 No Content on success. The row is gone.
Query the AI (with memory context)
User key sees all memories matching the filter:
curl -s -X POST http://localhost:3000/query \
-H "Authorization: Bearer your-secret-api-key" \
-H "Content-Type: application/json" \
-d '{
"query": "When is the API migration deadline?",
"memory_filter": { "by": "tags", "tags": ["deadlines"] }
}' | jq
Agent key sees only memories where allowed_vendors contains "*" or the agent's vendor name:
curl -s -X POST http://localhost:3000/query \
-H "Authorization: Bearer agent-key-for-chatgpt" \
-H "Content-Type: application/json" \
-d '{
"query": "What are the user preferences?",
"memory_filter": { "by": "all" }
}' | jq
The vendor_filter field in the receipt shows which vendor filter was applied (null for users, vendor name for agents).
MCP Server
Reflect Memory includes a built-in MCP (Model Context Protocol) server for native integration with Claude, Cursor, and other MCP-compatible tools.
Endpoint: /mcp (proxied through the main API — single port, no extra config)
Transport: Streamable HTTP (MCP clients must use streamable-http / streamableHttp)
Enabling MCP: Set at least one agent key environment variable. Agent keys serve double duty: they tell the server to start the MCP endpoint and authenticate requests against it.
export RM_AGENT_KEY_CURSOR="your-cursor-key"
export RM_AGENT_KEY_CLAUDE="your-claude-key"
Without any RM_AGENT_KEY_* variables set, the /mcp endpoint returns 404.
Cursor — create .cursor/mcp.json in your project:
{
"mcpServers": {
"reflect-memory": {
"type": "streamable-http",
"url": "https://api.reflectmemory.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_AGENT_KEY"
}
}
}
}
Claude — go to Claude.ai Settings > Connectors, click +, paste https://api.reflectmemory.com/mcp. Claude handles OAuth automatically.
MCP tools (20):
| Group | Tools |
|---|---|
| Read / discovery | read_memories, get_memory_by_id, get_latest_memory, browse_memories, search_memories, get_memories_by_tag, get_memory_briefing, get_topic_cluster |
| Write / lifecycle | write_memory, update_memory, delete_memory, write_child_memory |
| Graph / threads | get_graph_around, read_thread |
| Org / team | read_org_memories, read_team_memories, share_memory |
| Ambient | retrieve_relevant_memories, capture_session_memories (On) · suggest_memories (Off) |
See integrations/cursor/README.md and integrations/claude/README.md for detailed setup guides. Design notes: docs/design/ambient-memory-mode.md. Full architecture: ARCHITECTURE.md.
Ambient Mode
Ambient Mode lowers friction without removing control. Preference is On by default (including guests); users toggle it in the dashboard Settings. The preference carries guest → signup.
| Setting | Behavior |
|---|---|
| On (default) | Before substantive replies, agents call retrieve_relevant_memories and inject the returned block. When durable facts emerge (or at session end), agents call capture_session_memories and show an inline summary — informational, not an approval queue. |
| Off | Manual writes remain; suggest_memories stages candidates for dashboard approve / edit / reject. |
Architecture constraints (Phase 1):
- Captures write to the personal pool only. Org/team visibility still requires an explicit
share_memory. - Provenance tags:
auto_captured,ambient-memory-mode,ambient:cortex. Theoriginfield stays the writing vendor (cursor,claude,chatgpt, …). - Strong matches (or refinements of a just-retrieved memory) update in place and write
memory_versionshistory instead of creating sibling rows. - Consolidation is trigger-based (volume of new ambient captures or age threshold), env-tunable — not a silent background cron that bypasses the API.
- Connect-time session briefing includes Ambient instructions so MCP clients know which path to follow.
REST: PATCH /users/me/ambient-mode. Implementation: src/cortex-service.ts.
Team Memories
Team Memories let multiple users share context through a shared pool. Any team member can share personal memories with the team, and all members can read them from any connected tool.
# Create a team
curl -s -X POST http://localhost:3000/teams \
-H "Authorization: Bearer your-secret-api-key" \
-H "Content-Type: application/json" \
-d '{"name": "My Team"}' | jq
# Invite a member
curl -s -X POST http://localhost:3000/teams/TEAM_ID/invite \
-H "Authorization: Bearer your-secret-api-key" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}' | jq
Team tools (read_team_memories, share_memory) are available in all MCP clients once the user belongs to a team. The team API endpoints (/teams, /teams/:id/invite, etc.) use standard Bearer token auth.
Docker Quick Start (Private Deploy)
Run Reflect Memory locally with Docker Compose. Data stays on your machine.
Upgrading? The container runs as a non-root user. If you have an existing
/datavolume with root-owned files, rundocker compose down && docker compose --profile isolated-hosted up --buildto rebuild. If the database fails to open, fix volume permissions:docker run --rm -v rm_data_isolated:/data node:20-bookworm-slim chown -R 65534:65534 /data
- Clone the repo and create a
.envfile:
git clone https://github.com/van-reflect/Reflect-Memory.git
cd Reflect-Memory
# .env
RM_API_KEY=your-api-key
RM_MODEL_API_KEY=sk-...
RM_MODEL_NAME=gpt-4o-mini
# MCP — at least one agent key is required to enable /mcp
RM_AGENT_KEY_CURSOR=pick-any-strong-secret
RM_AGENT_KEY_CLAUDE=pick-any-strong-secret
- Build and start:
docker compose --profile isolated-hosted up --build -d
- Verify:
curl -s http://localhost:3000/health | jq
# → { "service": "reflect-memory", "status": "ok", ... }
curl -s http://localhost:3000/whoami \
-H "Authorization: Bearer your-api-key" | jq
# → { "role": "user", "vendor": null }
- Connect Cursor to your local instance:
{
"mcpServers": {
"reflect-memory": {
"type": "streamable-http",
"url": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer your-RM_AGENT_KEY_CURSOR-value"
}
}
}
}
Important: The /mcp endpoint uses agent keys for auth, not RM_API_KEY. Your RM_API_KEY works for REST/curl calls, but MCP clients must use the corresponding RM_AGENT_KEY_* value.
Production / private deploy notes
Hosted production (api.reflectmemory.com) runs on self-managed infrastructure (Docker + reverse proxy), not a serverless platform. For private deploy, prefer Docker Compose above or the Helm chart under charts/reflect-memory.
MCP / SSE: In multi-process production setups, route /mcp directly to the MCP port (see infra/README.md). Proxying long-lived MCP sessions through the main API process can break Streamable HTTP / SSE clients.
PaaS (optional): The app also runs on any Node host that provides a persistent volume for SQLite (e.g. Railway with a /data mount). Set RM_API_KEY, RM_MODEL_API_KEY, RM_MODEL_NAME, and at least one RM_AGENT_KEY_* (or RM_PUBLIC_URL for OAuth). Build: npm run build · Start: npm start.
Verification Checklist
Whoami
# User key
curl -s https://api.reflectmemory.com/whoami \
-H "Authorization: Bearer YOUR_USER_KEY" | jq
# → { "role": "user", "vendor": null }
# Agent key (ChatGPT)
curl -s https://api.reflectmemory.com/whoami \
-H "Authorization: Bearer YOUR_CHATGPT_AGENT_KEY" | jq
# → { "role": "agent", "vendor": "chatgpt" }
Agent write
curl -s -X POST https://api.reflectmemory.com/agent/memories \
-H "Authorization: Bearer YOUR_CHATGPT_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Agent test",
"content": "Written by chatgpt agent.",
"tags": ["agent-test"],
"allowed_vendors": ["chatgpt"]
}' | jq
# → origin: "chatgpt", allowed_vendors: ["chatgpt"]
Agent query scoping
# Agent sees only memories with allowed_vendors containing "*" or "chatgpt"
curl -s -X POST https://api.reflectmemory.com/query \
-H "Authorization: Bearer YOUR_CHATGPT_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "What do you know?",
"memory_filter": { "by": "all" }
}' | jq '.memories_used | length'
# → vendor_filter: "chatgpt" in receipt
User sees all
# User sees every memory regardless of allowed_vendors
curl -s -X POST https://api.reflectmemory.com/memories/list \
-H "Authorization: Bearer YOUR_USER_KEY" \
-H "Content-Type: application/json" \
-d '{ "filter": { "by": "all" } }' | jq '.memories | length'
Agent route restriction
# Agent cannot hit user-only endpoints
curl -s -X POST https://api.reflectmemory.com/memories \
-H "Authorization: Bearer YOUR_CHATGPT_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"x","content":"x","tags":["x"]}' | jq
# → { "error": "Agent keys cannot access this endpoint" } (403)
Persistence (data survives redeploy)
- Create a memory, note the ID
- Restart or redeploy the container (volume must persist)
- Read the memory by ID -- should still exist
Architecture
User key → POST /memories → Memory Service → SQLite (origin: "user")
→ GET /memories/:id → Memory Service → SQLite
→ POST /memories/list → Memory Service → SQLite
→ PUT /memories/:id → Memory Service → SQLite
→ DELETE /memories/:id → Memory Service → SQLite
Agent key → POST /agent/memories → Memory Service → SQLite (origin: vendor)
→ POST /query → Memory Service (vendor-filtered read)
→ Context Builder → Model Gateway → QueryReceipt
→ MCP /mcp → Memory Service (+ Ambient cortex when On)
Both → GET /health (no auth)
→ GET /whoami (returns role + vendor)
→ POST /query (vendor filter from key, not body)
See ARCHITECTURE.md for Ambient Mode, visibility, and deployment detail.
Hard Invariants
- Explicit Intent -- Requests declare what they want. Ambient Mode is a user preference (default On) that authorizes agent-mediated capture/retrieve tools — not opaque background mutation.
- Hard Deletion -- User-facing delete removes the row from the active store (dashboard soft-delete + purge cycle for recovery windows; hard purge for retention jobs).
- Pure Context Builder -- No I/O. Same inputs, same output. Always.
- No autonomous model writes -- The host LLM cannot mutate memory except by calling Reflect tools/APIs. Ambient capture still goes through
capture_session_memories→ memory service, with provenance tags and audit events. Toggle Off restores approval-gated Suggested Memories. - Deterministic Visibility -- Every query response includes the full receipt: memories used, prompt sent, model config, vendor filter. Ambient Phase 1 captures stay personal until an explicit share.
Hard Security Constraints
/agent/memoriesmust never acceptoriginin the body. If present, hard 400 (enforced byadditionalProperties: falsein the schema).- Agent keys must never be allowed to call user endpoints. Agents can only hit
/agent/*,/query,/whoami,/health. Everything else returns 403.
Установка Reflect Memory
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/van-reflect/Reflect-MemoryFAQ
Reflect Memory MCP бесплатный?
Да, Reflect Memory MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Reflect Memory?
Нет, Reflect Memory работает без API-ключей и переменных окружения.
Reflect Memory — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Reflect Memory в Claude Desktop, Claude Code или Cursor?
Открой Reflect Memory на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
Fetch
Web content fetching and conversion for efficient LLM usage.
AWS KB Retrieval
Retrieval from AWS Knowledge Base using Bedrock Agent Runtime.
автор: modelcontextprotocolSpring AI MCP Server
Provides auto-configuration for setting up an MCP server in Spring Boot applications.
llm-analysis-assistant
A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also
автор: xuzexin-hzCompare Reflect Memory with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории ai
