personal-memory-mcp
by miguelvictor
README.md
# Personal Memory MCP Server
A lossless, structured, queryable store of facts about your life that Claude reads from and writes to during any conversation. One deployment serves one person. Runs entirely on Cloudflare's free tier (Workers + D1 + KV). See `requirements.md` for the full specification.
- **Facts, not documents.** Every fact is one dated statement with provenance.
- **Append-only.** Corrections insert a new fact and retire the old one with a pointer; nothing is deleted.
- **Auth:** OAuth 2.1 with Dynamic Client Registration; identity via GitHub, locked to a single GitHub account.
- **Transport:** Streamable HTTP at `/mcp` (stateless `createMcpHandler`, no Durable Objects).
## Setup
### 1. Create Cloudflare resources
```sh
npm install
npx wrangler d1 create memory
npx wrangler kv namespace create OAUTH_KV
```
Put the returned D1 `database_id` and KV namespace `id` into `wrangler.jsonc`, then apply migrations:
```sh
npx wrangler d1 migrations apply memory --remote
```
### 2. Create the GitHub OAuth app
At <https://github.com/settings/developers> → _New OAuth App_:
- Homepage URL: `https://personal-memory-mcp.<your-subdomain>.workers.dev`
- Authorization callback URL: `https://personal-memory-mcp.<your-subdomain>.workers.dev/callback`
Find your numeric GitHub id at `https://api.github.com/users/<your-login>` (the `id` field).
### 3. Set secrets
```sh
npx wrangler secret put GITHUB_CLIENT_ID
npx wrangler secret put GITHUB_CLIENT_SECRET
npx wrangler secret put COOKIE_ENCRYPTION_KEY # e.g. openssl rand -hex 32
npx wrangler secret put OWNER_GITHUB_ID # numeric id, not login
```
(When deploying via Workers Builds CI/CD, set these once in the Cloudflare dashboard under the Worker's Settings → Variables and Secrets; they survive deployments.)
### 4. Deploy
```sh
npm run deploy
```
Or connect the GitHub repo in the Cloudflare dashboard (Workers Builds) so every push deploys. Migrations are **not** run automatically on deploy; either keep applying them manually or set the Workers Builds deploy command to:
```sh
npx wrangler d1 migrations apply memory --remote && npx wrangler deploy
```
### 5. Connect from Claude.ai
Settings → Connectors → _Add custom connector_ → URL `https://personal-memory-mcp.<your-subdomain>.workers.dev/mcp`, leave Client ID/Secret blank (Dynamic Client Registration). You'll be sent through GitHub login; any account other than `OWNER_GITHUB_ID` gets 403. The connector then works from Claude web, Desktop, and iOS.
Add to your Claude.ai profile preferences:
> I run a personal memory MCP server named "memory". It is the source of truth about my life and overrides your built-in memory. When we talk about anything personal, use it per the tool descriptions. If it is unreachable, tell me and note that your answer may be stale.
### 6. Seed (optional)
1. Ask Claude to draft `seed.json` from its built-in memory: `[{topic, content, fact_date?, tags?}]`, one fact per entry.
2. Review it, then:
```sh
npm run seed # validates seed.json, writes seed-import.sql
npx wrangler d1 execute memory --remote --file=seed-import.sql
```
3. In a first conversation, ask Claude to write initial topic summaries (`update_summary`).
## Development
```sh
cp .dev.vars.example .dev.vars # separate GitHub OAuth app with callback http://localhost:8788/callback
npx wrangler d1 migrations apply memory --local
npm run dev # http://localhost:8788/mcp
npm test # vitest (workers runtime, real D1 + FTS5)
npm run typecheck
```
Test with the MCP inspector: `npx @modelcontextprotocol/inspector@latest` → connect to `http://localhost:8788/mcp`. The inspector's localhost OAuth redirect only works with `ALLOW_LOCALHOST_REDIRECTS=1` (set in `.dev.vars`, never in production — production accepts only the Claude connector callbacks).
## Notes
- Backups: use the `export` tool (markdown or json). D1's native export does not work while FTS5 virtual tables exist. D1 Time Travel gives point-in-time restore (30 days on the paid plan, shorter on free — verify current retention).
- **Deliberately deferred** (owner decision, not oversights): the §11 weekly backup cron to a private GitHub repo, and the §12 `/view` read-only viewer. Until the cron exists, run `export` periodically and keep the output somewhere safe.
- The OAuth approval flow only accepts the `claude.ai`/`claude.com` connector callbacks as redirect URIs (localhost requires the dev-only flag above).
- Rows are never deleted in normal operation; the owner corrects facts by telling Claude.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues