cf-memory-mcp
v3.67.0
Published
Cloudflare-hosted MCP server for code indexing, retrieval, and assistant memory with a direct remote MCP endpoint and local stdio bridge.
Maintainers
Readme
CF Memory MCP
Cloudflare-hosted MCP server for semantic code indexing, retrieval, and assistant memory.
Live at https://memcp.ai
Key Features
- 110+ language support - TypeScript, Python, Go, Rust, Java, C/C++, Ruby, PHP, Swift, Kotlin, Scala, and 100+ more including shaders (GLSL, HLSL, WGSL, Metal, CUDA)
- Hybrid retrieval - 3-lane RRF (semantic + keyword + name matching) with cross-encoder reranking
- 100% top-3 benchmark accuracy - 37 queries across behavioral, conceptual, identifier, and negation categories
- Code graph navigation - Track calls, imports, inheritance across 9 language families (TS/JS, Python, Go, Rust, Java/Kotlin/Scala, C/C++/C#, Ruby, PHP, Swift)
- 22 MCP tools - Indexing, retrieval, file exploration, code graph, freshness management, indexing status, and persistent memory
- Self-healing freshness - Results auto-flag stale chunks with a copy-pasteable
refresh_filescall;refresh_stalerebuilds the changed files in seconds; cache invalidates on write - Self-debugging errors -
retrieve_contextincludesempty_hinton 0-result queries;get_file_content/get_file_outlinereturn{error, hint}pointing to the next call instead of bare null; calling bridge-only tools server-side returnsbridge_requiredinstall instructions - Smart defaults - Bridge auto-detects project_id from cwd, returns chunks pre-enriched with file imports + citation + source classification
- Cross-chat resume -
end_session({handoff:{goal, status, next_steps, code_anchors, ...}})persists a structured ~600-1500 token resume packet; next chat callsget_context_bootstrap({resume:true})to pick up where the previous chat left off, withmatch_confidence, branch-mismatch downgrades, and stale-anchor markers + refresh hints. Bridge auto-fillsrepo_path/branch/project_idfrom cwd + git. - Contextual embeddings - Qwen3 8K-context model with Anthropic-style chunk headers
The active runtime is at src-simplified/index.ts. It exposes direct MCP over HTTP and a local stdio bridge for clients that want npx cf-memory-mcp.
What Works
- Direct remote MCP on
/mcp - Legacy compatibility on
/mcp/message - Code indexing with
index_projectandindex_github; local bridge indexing returns immediately with abridge_job_id, thenget_indexing_statusreports progress - Retrieval with
retrieve_context(3-lane hybrid + cross-encoder rerank, returnsfile_imports+source_kind+citation) - Code relationship graph with
get_related_code(calls, imports, extends, implements) - Project exploration with
list_files,list_projects,get_stats,get_file_outline,get_file_content(bridge reads local file byte-exact when resolvable; falls back to chunk-reconstruction withreconstruction_warning+missing_line_ranges) - Staleness handling:
find_stale_files,refresh_files,refresh_stale. Results auto-tag stale chunks with astale_refresh_hintshowing the exact call to fix them. SetCF_MEMORY_AUTO_REFRESH=true(or passauto_refresh:true) to have the bridge transparently refresh + re-query before returning. - Assistant memory tools (
store_memory,retrieve_memories,get_context_bootstrap,delete_memory) - Session tracking with
start_session,end_session - Structured entity storage with
store_entity - Async indexing with Queues
- Coordination and progress with Durable Objects
- Diagnostics:
health_checktool +npx cf-memory-mcp --diagnose+CF_MEMORY_TRACE=1
Resume Context (cross-chat handoff)
Beyond code retrieval, cf-memory-mcp persists structured "handoff" packets so one chat can hand work off to the next. The next agent calls get_context_bootstrap({resume:true}) (or the CLI cf-memory-mcp resume) and gets back the goal, status, next steps, code anchors with staleness markers, files touched, and a pre-rendered markdown prompt — without re-exploring the repo.
Measured impact (scripts/benchmark-cold-vs-warm.ts): warm resume is 82-85% faster with 3-4 fewer tool calls than cold-start exploration, and the warm path returns the exact next_action the cold agent would have eventually figured out.
$ npx cf-memory-mcp resume # print prior handoff for cwd
$ npx cf-memory-mcp list # all recent handoffs (with status counts)
$ npx cf-memory-mcp checkpoint # snapshot current state
$ npx cf-memory-mcp status # bridge + server health for cwd
$ npx cf-memory-mcp doctor # diagnose common setup issues
$ npx cf-memory-mcp export <id> # backup a handoff
$ npx cf-memory-mcp import <file> # cross-machine sync
$ npx cf-memory-mcp delete <id> # remove a session
$ cfm resume # short aliasResume context also surfaces via:
- MCP tools:
start_session,end_session(with structuredhandoff),get_context_bootstrap(withresume,session_id_hint,goal_contains,since,status_filter,max_age_minutes) - MCP resources:
cfm://resume/current,cfm://resume/recent,cfm://resume/session/<id> - MCP prompts:
/resume,/list_threads(for clients with slash-command UI)
New to resume context? Start with the 5-minute quick start. For version history, see CHANGELOG.md.
See docs/RESUME_CONTEXT_PLAN.md for design rationale, agents.md for the full agent-facing reference, and examples/ for copy-pasteable workflows (GitHub Actions, shell prompt, tmux status line, resume-or-checkpoint wrapper).
Active Infra
- Workers
- D1
- Vectorize
- Queues
- Durable Objects
This is the correct default stack for the current product. Queues fit per-file async indexing well, and Durable Objects fit progress and shared coordination.
Quick Start
Local MCP Bridge
CF_MEMORY_API_KEY="your-key" npx cf-memory-mcpTest connectivity:
CF_MEMORY_API_KEY="your-key" npx cf-memory-mcp --diagnoseUseful environment variables:
CF_MEMORY_BASE_URL— override the server URL (defaults tohttps://memcp.ai). Pre-migrationworkers.devURLs are auto-rewritten to memcp.ai.CF_MEMORY_TRACE=1— verbose request/response logging to/tmp/cf-memory-mcp.log(rotates at 5MB)CF_MEMORY_PROGRESS=true— stream per-file indexing progress via SSE to stderr duringindex_projectCF_MEMORY_AUTO_WATCH=true— watch the project directory and auto-reindex on file changeCF_MEMORY_AUTO_REFRESH=true— when retrieve_context returns stale chunks, transparently refresh the changed files and re-query before returning (new in v3.9.0). Removes the find_stale → refresh → re-query loop.CF_MEMORY_WATCH_PATH=/path/to/project— explicit project root (defaults to bridge'scwd)CF_MEMORY_PROJECT_NAME=my-project— display name when auto-watch indexes the project
Recommended workflow for active development
1. retrieve_context("how does X work") ← finds chunks with file_imports + citation
2. (if stale_count > 0): refresh_stale(project) ← re-embeds edited files
3. retrieve_context(...) ← fresh results
4. get_related_code(name=X) ← navigate the call graph
5. get_file_content(file_path) ← read whole file if neededThe bridge auto-detects the project from cwd so project_id is optional in step 1.
Direct Remote MCP
- Base URL: https://memcp.ai
- MCP endpoint: https://memcp.ai/mcp
- Health check: https://memcp.ai/health
curl -X POST https://memcp.ai/mcp \
-H 'content-type: application/json' \
-H 'x-api-key: your-key' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": { "name": "example", "version": "1.0.0" }
}
}'Incremental Local Indexing
CF_MEMORY_API_KEY="your-key" cf-memory-index /path/to/project
CF_MEMORY_API_KEY="your-key" cf-memory-watch /path/to/projectThe indexer keeps a local hash cache and uploads only changed files.
Local Validation
npm run validate:simplifiedThat runs strict TypeScript validation for src-simplified plus the simplified worker tests.
Deploy
./scripts/deploy.shThat deploys the active worker and applies the simplified D1 schema and required migrations.
Canonical Files
- src-simplified/index.ts
- src-simplified/services/IndexingService.ts
- src-simplified/services/RetrievalService.ts
- src-simplified/queue-consumer.ts
- wrangler.toml
- bin/cf-memory-mcp.js
- bin/cf-memory-mcp-indexer.js
Security
The bridge (bin/cf-memory-mcp.js) reads local files for several tools — get_file_content, refresh_files, find_stale_files, refresh_stale, and the staleness annotation pass on retrieve_context results. Every one of those code paths confines file access to the resolved project root via fs.realpathSync + relative-path check, so absolute paths, .. traversal, and in-root symlinks pointing outside are all rejected before any read. Locked in by the test suite under tests/bridge.test.ts.
If you find a path that escapes the project root despite this, please open an issue with a reproduction.
Notes
- The simplified worker is the active product path.
- Older material from previous architectures still exists in the repo; treat the simplified worker and
wrangler.tomlas canonical. - If repo-level long-running orchestration is needed later, add Workflows on top of the current stack rather than replacing Queues.
