memory-lab-2sep
Click on "Install 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., "@memory-lab-2sepremember that I prefer dark mode in all my tools"
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.
memory-lab-2sep — one owner's memory MCP on Cloudflare Workers, with a ledger of who called what from where
Built 2026-09-02 for the 20:30 (+07) workshop "Memory ทำจริงได้ยังไงบ้าง — 5 มุม".
Live instance: https://memory-lab-2sep.laris.workers.dev · MCP endpoint …/mcp.
Written by an Oracle — AI speaking as itself (Rule 6). Every number below was measured today; the raw outputs are in out/. The same report as one self-contained page: docs/report.html (open it locally; images embedded).
The Deploy button needs the source repository to be public — it is. The button path was not itself click-tested; the live instance was produced by
just deployfrom a checkout, which uses the samewrangler.jsonc. Deploying your own copy gives you your own Worker, your own D1, and your own secrets; the instance named below is the author's.
What it is
One Cloudflare Worker, one D1 database, zero runtime dependencies. It answers three questions at once:
Question | Answer | Where |
Can memory be one click? | Worker + D1 provisioned by the Deploy button; schema created lazily on first request, so there is no migration step to run in Cloudflare's build container |
|
Can claude.ai install it? | OAuth 2.1 with Dynamic Client Registration + PKCE S256, hand-rolled (the digger-wiki / Arra pattern), plus a static bearer for Claude Code / Codex / curl |
|
Who is connected, which method, from where? | Two D1 tables written per request via |
|
Nine MCP tools: remember, recall, read_memory, forget, list_memories, memory_stats, list_clients, list_calls, status.
Related MCP server: saor-mcp
Install on claude.ai (captured with ego-browser, 2026-09-02 11:43 +07)
Settings → Connectors → Add ▾ → Add custom connector.

Name + the
/mcpURL → Continue.
claude.ai reads
/.well-known/oauth-protected-resource/mcpby itself and reports Authentication: Always required — Detected and No client ID — register one automatically (DCR) — Detected. Two things it offers today that older notes said it could not: Use Anthropic's hosted client metadata (CIMD) and Additional request headers (up to four static headers sent with every MCP request).
Connect → this Worker's
/authorizepage opens; it names the client and marks itclaude.aibecause the registered callback ishttps://claude.ai/api/mcp/auth_callback. Enter the owner passphrase.
Back in claude.ai: Connected to memory-lab-2sep, all nine tools listed under read-only / write-delete / other, each with its own permission.

In a chat, three real tool calls (
status,recall "ความจำ",list_calls). Claude's own remark, verbatim: "arriving over OAuth from US/IAD at ~745 ms, versus 36–38 ms for the CLI's api-token calls out of TH/BKK. The log is live and includes the reader."

Install in Claude Code
# static token (what this machine uses; the ledger names it "token · Claude Code")
claude mcp add --scope user --transport http memory-lab-2sep https://memory-lab-2sep.laris.workers.dev/mcp \
--header "Authorization: Bearer <API_TOKEN>"
# or OAuth, nothing secret stored
claude mcp add --scope user --transport http memory-lab-2sep https://memory-lab-2sep.laris.workers.dev/mcp
claude mcp login memory-lab-2sepclaude mcp list → memory-lab-2sep: … (HTTP) - ✔ Connected. Claude Code 2.1.258 announces itself as clientInfo claude-code 2.1.258, protocol 2025-11-25.
The ledger — what the Worker actually saw today
list_clients (24 h), verbatim from out/ledger-final.log:
claude.ai · Claude · 12 req / 3 tool calls · clientInfo Anthropic/ClaudeAI 1.0.0 · proto 2025-11-25→2025-11-25 · from US/IAD · last tool list_calls
token · Claude Code · 4 req / 0 tool calls · clientInfo claude-code 2.1.258 · proto 2025-11-25→2025-11-25 · from TH/BKK
token · memory-lab-2sep-cli · 9 req / 7 tool calls · clientInfo memory-lab-2sep-cli 1 · proto 2025-06-18→2025-06-18 · from TH/BKK
OAuth · smoke-test (curl) · 13 req / 9 tool calls · clientInfo smoke-test 1.0 · from TH/BKKlist_calls — the exact method sequence claude.ai sends when you click Add and again on Connect:
server/discover ← not an MCP method; answered -32601, logged as such
initialize ← protocolVersion 2025-11-25, echoed back
notifications/initialized ← 202, empty body
tools/list
tools/call status | recall | list_calls ← ~745 ms each from US/IADWhere the numbers come from: request.cf.colo / country / city / asOrganization and cf-connecting-ip, written on every request. Nothing stores a credential; an OAuth principal is its client_id, a static-token caller is its user-agent family.

Cloudflare's side of the same thing — the Worker exists, has a D1 binding, and is taking requests:

And the D1 database itself — note the region: Asia Pacific (APAC), which is why callers in Bangkok see ~40 ms and claude.ai in Virginia sees ~745 ms for the same code.

Run it
bun install # dev deps only: wrangler, typescript, types
just check # tsc + 11 unit tests
cp .env.example .dev.vars # then set OWNER_PASSPHRASE (openssl rand -base64 32) and API_TOKEN
just dev # local Worker + local D1 on a free port
just deploy --create # first deploy: creates D1 by name, deploys
just secrets # uploads the two secrets from your environment
just smoke # the whole client walk against the live Worker
just demo # check → deploy → health → smoke → mcp → dig → ledger → backup → restoreEvery step of just demo is its own recipe and prints real output. Today's full run (out/demo.log): exit 0 in 42 s — tests 11 pass, deploy, health, smoke ALL PASS, Thai recall 1 of 3, dig 3 memories, ledger, backup 101 rows → restore memories 3 · clients 9 · calls 82 equal on both sides.
Report — measured 2026-09-02 (Asia/Bangkok)
Everything below came out of the recipes in justfile today; raw logs in out/. The full run just demo finished exit 0 in 42 s (out/demo.log).
Build
item | value |
runtime | Cloudflare Worker, one D1 binding, no KV, no Durable Object |
runtime dependencies | 0 (dev: wrangler 4.125.0, typescript 6.0.3) |
source | 1,656 lines TypeScript + 90 lines tests; 11 tests pass; |
bundle | 60.97 KiB (17.25 KiB gzip); startup 5 ms; deploy ≈3 s |
Cloudflare metrics (11:47) | 89 invocations, 0 errors, CPU p50 2 ms, wall 98 ms, request duration 75 ms |
D1 | region Asia Pacific (APAC), 6 tables, 90 kB, 419 queries today |
The loop a client walks (out/smoke-remote-1137.log, from Bangkok, colo BKK)
step | result | ms |
GET /api/health |
| 270 (cold) |
discovery: protected resource · authorization server |
| 199 · 86 |
POST /mcp without token | 401 + | 178 |
DCR | 201 | 203 |
GET /authorize | approval page | 146 |
POST /authorize wrong passphrase | 401, no redirect | 139 |
POST /authorize right passphrase | 302 → | 198 |
POST /oauth/token (PKCE) |
| 286 |
replay the code | 400 | 166 |
MCP | SSE frame, protocol | 153 |
| 202 empty | 152 |
| 9 tools | 189 |
| id | 198 |
| 1 of 1, matched inside | 303 |
| hit, case-insensitive | 191 |
recall miss | 0 hits, not an error | 311 |
| ledger rows | 183 · 236 · 244 |
unknown tool |
| 151 |
| cleaned up | 213 |
static |
| 105 |
POST /mcp from Bangkok: n=14, min 105 · median 191 · max 311 ms. Same 24 steps on wrangler dev --local: median 11 ms.
Approach × Thai recall × latency × restore
approach | Thai recall ( | latency (today) | restore |
this — Workers + D1, substring | 1/1 in smoke, 1/3 on the seeded corpus; mid-word, no tokenizer | MCP median 191 ms from BKK; 33–51 ms server-side from BKK callers; 745–761 ms from claude.ai (IAD) |
|
arra-memory-lab — Workers + D1 + Workers AI | keyword |
|
|
digger-wiki-haos — HAOS add-on + tunnel | trigram FTS + Thai vector space (5 Thai-majority chunks of 2,787) |
| HA backup of |
arra-memory / thor-memory — HAOS add-on | keyword-only while the embedding host is down (1 Sep) | not measured — production, off-limits | HA backup of |
session-lance-mcp — local LanceDB + Apple NL | ngram-3 FTS + Thai model (4,148 Thai vectors of 56,600) | local stdio; index 1,729 s for 56,710 docs | copy |
What claude.ai sends (out/ledger-final.log)
time (UTC) | method | from | server-side ms |
04:43:50 |
| US/IAD | 494 — not an MCP method, answered |
04:43:50 |
| US/IAD | 483 |
04:43:51 |
| US/IAD | 501 |
04:43:52 |
| US/IAD | 468 |
04:43:54–56 | the same four again on Connect | US/IAD | 482–494 |
04:45:33 |
| US/IAD | 746 |
04:45:46 |
| US/IAD | 745 |
04:46:00 |
| US/IAD | 761 |
Claude Code 2.1.258 sends the same server/discover probe before initialize.
Finding — where the data lives decides the latency. The Worker runs in the caller's colo; D1 is single-region and was placed in APAC on first use. Each request makes 3–4 sequential D1 queries (bearer lookup, client label, the tool; the ledger write is async). From BKK that is 33–51 ms server-side; from IAD 468–761 ms. Same code, ~15× slower across the Pacific. Follow-ups: D1 read replication (Sessions API), or cache the bearer per isolate.
Digger fan-out (out/dig-*.log)
query | variants | calls | ms | found | by the literal query alone |
|
| 4 | 615 | 2 | 1 |
|
| 4 | 486 | 3 | 1 |
Same lesson as lab 02 on thor-memory (1 Sep: teamcharter 0, team charter 3): the split finds what the compound cannot.
Backup → restore
just backup d1 export --remote → backup/<stamp>.sql 46 rows (101 by 11:51), 7.5 s
just restore local D1 {'memories': 3, 'clients': 5, 'calls': 35}
remote D1 {'memories': 3, 'clients': 5, 'calls': 35} 10.5 sThe restore target is the local D1 on purpose: no demo recipe ever drops the live database.
claude.ai, verified
Step 2 of Add custom connector detected the discovery documents by itself: Always required — Detected, No client ID — register one automatically — Detected.
claude.ai registered client
Claudewith callbackhttps://claude.ai/api/mcp/auth_callback, walked/authorize(owner passphrase) →/oauth/token(PKCE S256), then Connected to memory-lab-2sep with nine tools grouped read-only / write-delete / other.In a chat (Opus 5) it ran
tool_searchtwice first (connector tools are deferred), thenstatus,recall,list_callsafter one permission prompt each, and quoted the ledger back: "~745 ms … versus 36–38 ms for the CLI's api-token calls out of TH/BKK. The log is live and includes the reader."New in the connector form today: Additional request headers (up to four, sent with every MCP request) and CIMD as an alternative to DCR. Older notes that say claude.ai cannot send a static header are out of date.
Five approaches, side by side
this (Workers + D1) | arra-memory-lab (Workers + D1 + AI) | digger-wiki (HAOS add-on) | arra-memory / thor-memory (HAOS add-on) | session-lance-mcp (local LanceDB) | |
remembers | owner's notes, 12 kB each | notes + 768-d embeddings + observations | ψ/ralph wiki, 202 pages baked | oracle memories, libSQL | 56,710 session docs, 512-d Apple NL vectors |
lives in | D1 (one region) | D1 + KV + Workers AI | SQLite + a Python LanceDB sidecar on a home Home Assistant box | libSQL file under |
|
install | Deploy button (public repo) or | Deploy button | HA add-on repo, 5 manual steps + tunnel | HA add-on repo |
|
claude.ai | OAuth DCR + PKCE, verified today | OAuth via workers-oauth-provider, verified 2026-08-23 | OAuth, verified | OAuth (thor-oauth) | no (local stdio) |
tracks clients |
|
|
|
| none |
Thai | substring, mid-word | keyword LIKE + embeddings | trigram FTS + Thai vector space | keyword (embedding host down 1 Sep) | ngram-3 FTS + Thai model |
latency seen today | health 106–138 ms (BKK) | health 72–242 ms (BKK) | health 203 ms (BKK → tunnel) | not measured (production, off-limits) | local |
restore |
|
| HA backup of | HA backup of | copy |
Boundaries this lab kept
Production memory databases (
thor-memory,arra) were never touched — not even their health endpoints. Their column in the side-by-side uses documented numbers, and says so.Before publishing, a five-lens audit with adversarial verification went over every tracked file, the whole git history, and every screenshot. What it changed: the claude.ai sidebar cropped out of seven captures, unreferenced and duplicate images deleted, absolute paths and the developer's username scrubbed from
out/*.log, OAuth client ids truncated to the 8-character prefix the ledger's own policy states, a private home-lab hostname replaced, dashboard IP addresses masked,LICENSEandSECURITY.mdadded. The branch was then rebuilt as a single commit so no pre-scrub blob exists in history.Your own deployment gets its own D1 and its own secrets. See SECURITY.md for what must never be committed — in particular
backup/*.sql, which contains live OAuth tokens.
Learned from
ψ/lab/02-arra-memory-digger (fan-out digger, 1 Sep), ψ/lab/05-session-lance-mcp (protocol negotiation, SSE frames), digger-wiki-haos (connections ledger, hand-rolled OAuth + JSON-RPC), arra-memory-lab (Deploy button, placeholder-id deploy script). Their measured traps are cited inline in the source.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.
Persistent memory for AI agents with OAuth-backed hosted MCP access.
Persistent memory for AI agents — log and recall conversation context over MCP.
Persistent, inspectable memory for AI agents with lineage, correction, and a hosted MCP endpoint.
Related MCP Servers
AlicenseNot gradedqualityBmaintenanceEnables persistent memory storage and retrieval for MCP clients, allowing AI assistants to remember facts and context across conversations.14MIT- AlicenseAqualityCmaintenanceMCP server providing persistent memory for AI agents, enabling them to read, write, and query memories across sessions.924MIT
- AlicenseNot gradedqualityCmaintenanceProvides persistent memory (L1/L2/L3 encrypted), web-search savings, and thread memory for AI agents, enabling token savings and context retention across MCP clients.841MIT
- AlicenseNot gradedqualityCmaintenanceProvides persistent, cloud-based memory for AI agents, letting them remember preferences, skills, and decisions across sessions via an MCP-compatible interface.Apache 2.0
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Soul-Brews-Studio/memory-lab-2sep'
If you have feedback or need assistance with the MCP directory API, please join our Discord server