DEV Community

kaz
kaz

Posted on

Building a Lightweight Remote MCP Knowledge Base on Cloudflare Workers

Every time I start a new conversation with Claude, I re-explain my project context. What we decided, what the architecture looks like, what we tried and rejected. The AI has no memory.

I built edgenote-ai to fix this — a lightweight shared knowledge base on Cloudflare Workers that both humans and LLMs can read and write through MCP (Model Context Protocol).

Claude Desktop using edgenote-ai

The Problem

LLMs are stateless. They process your input, generate a response, and forget everything. Memory features like ChatGPT's are limited and proprietary — you can't control what gets remembered, search it, or share it across tools.

What I wanted:

  • A place to store project notes, decisions, and context
  • Accessible to any LLM via standard protocols (MCP)
  • Searchable
  • Also usable by humans through a web UI
  • Self-hosted, open source, under my control

The Architecture

edgenote-ai provides three interfaces to the same data:

Human (browser)  → Web UI      →
                                  Cloudflare Workers + D1
LLM (Claude)     → MCP tools   →
                                  (+ Rust/WASM planned for search)
Scripts          → REST API   →
Enter fullscreen mode Exit fullscreen mode

MCP Tools (9 total)

The MCP endpoint uses Streamable HTTP transport via the official @modelcontextprotocol/sdk. When connected to Claude Desktop (via mcp-remote), the LLM gets these tools:

Tool Description
note_create Create a note
note_read Read by ID or title
note_update Update or append content
note_search Search notes (currently D1 LIKE-based)
note_list List all notes
note_delete Delete a note
note_export Bulk export for loading full context
context_briefing Comprehensive overview of your knowledge base
note_summarize Summarize one or more notes

The context_briefing tool is what makes this useful in practice — at the start of a conversation, the LLM calls it and immediately understands what's in your knowledge base.

Dynamic Server Instructions

When a new MCP session starts, the server returns dynamic instructions in the initialize response:

"instructions": "This is edgenote-ai, a shared knowledge base with 9 notes.
Last updated: 2026-05-25. Recent notes: Architecture Overview, Sprint 3 Retro...
Use context_briefing for a full overview before starting work."
Enter fullscreen mode Exit fullscreen mode

This tells the LLM what exists before it even calls a tool.

Zero-Friction Setup

  1. Sign in with Google at edgenote.0xkaz.com
  2. Copy the MCP config from your dashboard
  3. Add to Claude Desktop config (uses mcp-remote for the remote connection)
  4. Done — Claude can read and write your notes
{
  "mcpServers": {
    "edgenote": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://edgenote.0xkaz.com/mcp",
        "--header",
        "Authorization: Bearer YOUR_API_KEY"
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Note created by Claude appears in Web UI

Technical Decisions

Why Cloudflare Workers?

A remote MCP server needs global accessibility with low latency. Workers gives:

  • Edge deployment in 300+ locations
  • D1 for SQL storage (SQLite-compatible)
  • R2 for object storage
  • $5/mo paid tier covers everything

Search: Honest About the Current State

Currently, search is D1 LIKE '%query%' — basic but functional. I have a Rust/WASM core built with pulldown-cmark (Markdown parsing) and an in-memory search index, but it's not yet integrated into the Workers runtime.

The plan is to add tantivy (a Rust full-text search library) compiled to WASM for ranked results, fuzzy matching, and CJK tokenization. This is on the roadmap, not shipped.

I'm being upfront about this because I've seen too many projects claim features they haven't built yet.

Auth Design

Dual auth from day one:

  • API key (enai_* prefix) — for MCP clients and REST API
  • Google OAuth — for the web UI, with CSRF state parameter

Both resolve to the same user ID. Sign up via Google → get an API key automatically → copy ready-made MCP config from dashboard.

Security

  • Markdown rendering uses DOMPurify + script context XSS prevention (< escaping)
  • OAuth includes state parameter for CSRF protection
  • R2 image serving has path traversal protection
  • All note queries are scoped by user_id

What I Learned

MCP is powerful but remote servers are rare

The protocol is well-designed. Claude Desktop connects via mcp-remote (an npm proxy that translates Streamable HTTP to stdio). Most MCP servers are local — remote ones are still uncommon.

LLMs are surprisingly good at using structured tools

When you give Claude note_search and context_briefing, it knows when to use them without explicit prompting. "Check my notes about the deployment plan" just works.

The "context briefing" pattern is essential

Individual note reads are useful, but the real value comes from the LLM understanding your entire knowledge base at a glance. The context_briefing tool gives a structured overview — note count, titles, summaries — so the LLM can make informed decisions about which notes to read.

Dynamic instructions make remote MCP servers feel intelligent

The MCP spec's instructions field in the initialize response is underutilized. Making it dynamic (querying D1 for the user's actual note state) makes the server feel like it knows you.

What's Next

  • [ ] tantivy WASM search (replacing D1 LIKE queries)
  • [ ] CRDT-based real-time sync (Automerge)
  • [ ] Shared spaces for team collaboration
  • [ ] Semantic search (Vectorize + Workers AI)
  • [ ] MCP-native OAuth (eliminate copy-paste API keys)

Try It

This is an early-stage side project — feedback and contributions welcome.

I'd love feedback on the MCP tool design. What tools would be most useful for your AI workflow? What would you want your AI assistant to remember?

Top comments (0)