🧠context-kernel
Self-hostable LLM context memory. Keep your context, preferences, and knowledge in sync across Claude—without re-pasting or semantic drift.
You curate a set of Markdown files about yourself and your work. A Cloudflare Worker serves them to Claude (Claude Code, Desktop, chat) via authenticated remote MCP. Your agents extend the memory through an append-only journal—but only you decide what becomes permanent. The curation gate prevents the memory from rotting.
Not: a website, resume renderer, CMS, or chatbot. No public access, no unauthenticated reads.
Why Not Vector-Memory Tools?
context-kernel
- Hand-curated Markdown
- Append-only journal
- Manual promotion gate
- Stale content removed by you
- Trustworthy (you control it)
Vector-Memory (mem0, etc.)
- Auto-extracted facts
- Often direct edits
- Automatic ranking
- Relies on decay heuristics
- Semantic drift risk
The gap: Vector tools excel at semantic search but have a known failure mode. When facts change (e.g., "Prod: Postgres 14" → "Postgres 16"), both sit in the index. Similarity search hands back whichever scores higher—usually the older, reinforced one. Result: outdated info looks authoritative.
Status
Deployment
Cloudflare Workers, running live with real curated content.
Tests
100/100 passing. Full coverage: auth, KV, journal, promotion.
Connect via
Claude Code CLI (bearer token) or claude.ai connector UI (OAuth) — both verified live.
OAuth
DCR + single-field login page gated on READ_TOKEN. Issues read-only tokens only.
Built with
- Models: Claude Sonnet 5 (main build), Claude Haiku 4.5 (final polish). 170k+ tokens across implementation, testing, deployment.
- Runtime: Cloudflare Workers (V8 isolate), minimal deps (agents SDK, MCP TypeScript SDK, Zod).
- Storage: Cloudflare KV (curated context + journal buffer, separate namespaces).
- Language: TypeScript. Strict mode, comprehensive tests via vitest.
- Protocol: Remote MCP over HTTP. Bearer token (Claude Code CLI) and OAuth via
@cloudflare/workers-oauth-provider(claude.ai connector UI) — both auth paths converge on/mcp.
Architecture
content/*.md (hand-edited source of truth)
|
v
scripts/generate-artifacts.ts (build KV bulk payload)
|
v
Cloudflare KV (CONTEXT_KV namespace)
|
v
src/worker.ts (MCP server handler + OAuthProvider)
|
+-- src/mcp/auth.ts (constant-time bearer validation)
+-- src/mcp/oauth.ts (OAuth provider, DCR, /authorize login page)
+-- src/mcp/tools.ts (MCP tool handlers)
+-- src/kv.ts (read-only KV helpers)
|
v
/mcp (apiRoute) — validates bearer OR OAuth token, dispatches by resolved scope
(read: get_context, list_sections, get_meta)
(write: append_journal, list_journal — bearer WRITE_TOKEN only)
|
+-- OAuth-issued tokens: always read-only
+-- Journal: append-only, ULID keys, manual promotion gate
Key Design Decisions
- Hand-curated Markdown, not vector search. Nothing becomes memory without explicit human approval. Avoids the semantic-drift problem of vector-store memory when facts change over time.
- Append-only journal, manual promotion. Agents can leave notes but cannot corrupt curated context. The promotion step is where the owner filters signal from noise.
- Two token scopes, separate secrets. Read token for sessions, write token for servers. Write leak is contained (notes only), read leak is the primary risk (context exposure).
- Constant-time token comparison. No timing attacks. Uses crypto.subtle.digest (SHA-256 + XOR accumulate), portable across workerd and Node.
- OAuth login gated on READ_TOKEN, not open registration. The OAuth library reports an
/authorizeURL but doesn't implement it — without a real handler, anyone completing DCR could mint a token with zero credential check. The login page closes that gap by requiring the owner's READ_TOKEN before issuing any OAuth grant.
Development Metrics
| Phase | Deliverable | Status |
|---|---|---|
| 1 | Scaffold + tooling | ✓ package.json, tsconfig, wrangler example, tests |
| 2 | Artifact generator | ✓ content/*.md → KV bulk JSON + metadata |
| 3 | Auth gate | ✓ Constant-time token comparison, scope isolation |
| 4 | MCP server + read tools | ✓ get_context, list_sections, get_meta |
| 5 | Write tools + journal | ✓ append_journal, list_journal (ULID-keyed) |
| 6 | Promotion script | ✓ npm run promote (CLI journal review) |
| 7 | Personal skill | ✓ Auto-pull context at session start |
| 8 | Docs + hygiene | ✓ README, SECURITY.md, wiki, landing site |
Quick Start
Deploy to Cloudflare
npm install
cp wrangler.toml.example wrangler.toml
wrangler kv namespace create CONTEXT_KV
wrangler kv namespace create OAUTH_KV
wrangler secret put READ_TOKEN
wrangler secret put WRITE_TOKEN
cp -r content.example content
npm run build
wrangler kv bulk put artifacts/kv-bulk.json --binding CONTEXT_KV
wrangler deploy
Connect Claude Code
claude mcp add --transport http context-kernel \\
https://my-context-kernel.myname.workers.dev/mcp \\
--header "Authorization: Bearer <READ_TOKEN>"
The skill .claude/skills/context-kernel/SKILL.md auto-loads your context on every session start.
Append via Agents (write-token)
Agents and servers use WRITE_TOKEN to append journal entries. You review via npm run promote and hand-promote what becomes permanent.
Connect claude.ai Chat (OAuth)
Add a custom connector in claude.ai pointing at your Worker's /mcp endpoint. Claude self-registers via Dynamic Client Registration, then redirects to a one-field login page — enter your READ_TOKEN once to authorize. Every OAuth-issued token is read-only; write access stays on the bearer-token path only.
Repository
Token Usage & Cost (All Sessions)
Aggregated across every local Claude Code session on this repo, scaffold through the deployed OAuth fix.
| Model | Output tokens | Cache-read tokens | Cache-creation tokens |
|---|---|---|---|
| Claude Sonnet 5 | 239,096 | 73,379,771 | 1,841,956 |
| Claude Haiku 4.5 | 113,515 | 29,514,258 | 757,289 |
| Total | 352,611 | 102,894,029 | 2,599,245 |
Estimated total cost: ~$26 (Sonnet 5 intro pricing $2/$10 per MTok in/out through 2026-08-31, plus 5-min cache-write premium; Haiku 4.5 at standard $1/$5 per MTok). Covers scaffolding, all six build phases, docs, the two reverted OAuth attempts, this session's OAuth fix (missing apiRoute config, /authorize login page, WRITE_TOKEN rotation), and end-to-end verification. Caveman-compressed communication mode kept output tokens low relative to cache-read volume.