A polyglot memory server built on the Model Context Protocol. Intelligently routes knowledge across Neo4j, Mem0, and MongoDB, surfaces it through semantic search with sub-100ms FACT caching, and exposes everything as MCP tools for Claude Desktop, Claude Code, and any MCP-compatible client.
Different knowledge has different shapes:
| Layer | Store | Strength |
|---|---|---|
| Knowledge graph | Neo4j | Entities, typed edges, traversal queries — who worked where, what connects to what |
| Semantic / episodic | Mem0 | Natural language recall, personal context, "do I know anything about X?" |
| Structured documents | MongoDB | Config, procedures, technical specs — exact field queries |
The routing rule is simple: Neo4j + Mem0 always (graph + semantic layer). MongoDB added only for procedural or technical content. You don't choose — the router chooses.
Input
│
▼
┌─────────────────────────────────┐
│ Content Inference │ Detects type, source, tags
│ (ContentInference.ts) │
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ Storage Router │ LLM (Ollama) → regex fallback
│ OllamaStorageRouter │
│ IntelligentStorageRouter │
└─────────────────────────────────┘
│
├──────────────────────┬─────────────────────────┐
▼ ▼ ▼
Neo4j Mem0 (always) MongoDB (if technical/
(always) Semantic + episodic procedural content)
Knowledge graph memory layer
│
▼
┌─────────────────────────────────┐
│ EnrichmentQueue (async) │ Entity extraction, graph linking
│ EntityLinker + OllamaInference │ via local Ollama (optional)
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ FACT Cache │ L1 (in-memory) → L2 (Redis) → L3
│ 3-layer, sub-100ms │
└─────────────────────────────────┘
│
▼
MCP Tools / HTTP API / CLI
Four cloud services. All have free tiers.
| Service | Purpose | Get it |
|---|---|---|
| Mem0 | Semantic / episodic memory | Free tier, API key from dashboard |
| Neo4j Aura | Knowledge graph | Free tier, 50k nodes |
| MongoDB Atlas | Structured documents | Free 512MB cluster |
| Redis Cloud or Upstash | L2 cache (optional) | Free tiers available |
Optional: Ollama running locally for LLM-powered routing. Falls back gracefully to regex routing if unavailable.
git clone https://github.com/ryaker/KMSmcp
cd KMSmcp
npm install
npm run build# Storage
MEM0_API_KEY=your_mem0_api_key
MONGODB_URI=mongodb+srv://user:pass@cluster.mongodb.net/kms
NEO4J_URI=neo4j+s://xxxx.databases.neo4j.io
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=your_password
REDIS_URI=redis://... # Optional — L2 cache
# Identity
KMS_DEFAULT_USER_ID=your_user_id # e.g. "alice" — stored with all knowledge
# Transport
TRANSPORT_MODE=http # stdio | http | dual
HTTP_PORT=8180
HTTP_HOST=0.0.0.0
# LLM routing (optional — improves routing quality)
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=qwen3:8b
# OAuth (optional)
OAUTH_ENABLED=false
OAUTH_ISSUER=https://your-auth-server.com
OAUTH_JWKS_URI=https://your-auth-server.com/.well-known/jwks.json# Development
npm run dev
# Production
npm start
# With Doppler (recommended for secret management)
doppler run -- npm start{
"mcpServers": {
"kms": {
"type": "http",
"url": "https://your-kms-server/mcp"
}
}
}For local use:
{
"mcpServers": {
"kms": {
"type": "http",
"url": "http://localhost:8180/mcp"
}
}
}Settings → MCP Connectors → Add custom connector → enter your server URL.
| Mode | Use case |
|---|---|
stdio |
Local Claude Desktop, no network |
http |
Remote access via Cloudflare Tunnel, Railway, etc. |
dual |
Both simultaneously |
{
"content": "Resolved OAuth loop by pinning jwks-rsa to 3.1.0 — later versions break with Auth0",
"contentType": "procedure",
"source": "technical",
"confidence": 0.95
}{
"content": "I work best with async-first communication — real-time meetings drain focus",
"contentType": "memory",
"source": "personal"
}contentType: memory | insight | pattern | relationship | fact | procedure
source: personal | technical | cross_domain
The router always targets Neo4j + Mem0. MongoDB is added automatically for procedure, technical source, or config-pattern content.
{
"query": "OAuth authentication issues",
"filters": {
"contentType": ["procedure", "fact"],
"minConfidence": 0.7
},
"options": {
"maxResults": 10,
"cacheStrategy": "conservative"
}
}Results are merged, deduplicated, and ranked across Neo4j, Mem0, and MongoDB. Entity relationships surfaced from the graph layer.
{
"content": "Deploy via GitHub Actions to Azure Static Web App on push to main"
}Returns the routing decision (primary + secondary stores, cache strategy, reasoning) without writing anything.
Returns status of all three storage systems and the cache layer. Use to verify connectivity before storing.
{
"timeRange": "24h",
"includeCache": true
}{
"pattern": "user:alice",
"level": "all"
}Returns the KMS CLAUDE.md instructions as a tool response — useful for grounding agents at the start of a session.
For Claude Code agents and shell scripts that don't have an MCP client. Mirrors the MCP tools exactly.
# Install globally after build
npm link
# Store knowledge
doppler run -- kms store "Resolved the Neo4j timeout by setting connection pool to 50" \
--type procedure --source technical
# Search
doppler run -- kms search "Neo4j connection issues" --limit 5
# Preview routing (no secrets needed)
kms route "npm install --save-dev typescript" --type procedure
# Health check all three stores
doppler run -- kms pingCommands: store | search | ping | route
- Ollama LLM (if available, confidence ≥ 0.6) — best signal, understands semantics
- Regex fallback — pattern matching on content + contentType + source
| Content | Neo4j | Mem0 | MongoDB |
|---|---|---|---|
| Any knowledge | ✅ always | ✅ always | — |
contentType: procedure |
✅ | ✅ | ✅ |
source: technical |
✅ | ✅ | ✅ |
| Config / deploy / API patterns | ✅ | ✅ | ✅ |
| Source | Level | TTL |
|---|---|---|
personal |
L1 | 5 min (in-memory) |
memory / insight contentType |
L2 | 30 min (Redis) |
| High confidence (>0.8) | L2 | 30 min |
technical / procedure |
L3 | 1 hour (Redis) |
After storing, the EnrichmentQueue runs asynchronously if Ollama is available:
- Extracts entity mentions from stored content
- Matches against existing Neo4j nodes via
EntityLinker - Creates typed relationships in the graph automatically
This builds the knowledge graph incrementally without blocking the store operation. If Ollama is unavailable, enrichment is skipped silently.
POST /mcp MCP JSON-RPC endpoint
GET /mcp SSE stream (resumable sessions)
DELETE /mcp Close session
GET /health Health check
GET /.well-known/oauth-protected-resource/mcp OAuth metadata (if enabled)
GET /.well-known/oauth-authorization-server OAuth metadata (if enabled)
# Health
curl http://localhost:8180/health
# Tool call
curl -X POST http://localhost:8180/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unified_store",
"arguments": {
"content": "Always add connection timeout to Neo4j driver config",
"contentType": "procedure",
"source": "technical"
}
},
"id": 1
}'OAUTH_ENABLED=true
OAUTH_ISSUER=https://your-auth-server.com
OAUTH_AUDIENCE=https://your-kms-server.com
OAUTH_JWKS_URI=https://your-auth-server.com/.well-known/jwks.json
# Or token introspection
OAUTH_TOKEN_INTROSPECTION_ENDPOINT=https://your-auth-server.com/oauth/introspect
OAUTH_CLIENT_ID=your-client-id
OAUTH_CLIENT_SECRET=your-client-secretMCP discovery methods (initialize, tools/list) are allowed without authentication for protocol compatibility.
KMS supports SparrowDB as a local, zero-latency alternative to Neo4j Aura.
- SparrowDB cloned locally (default:
~/Dev/SparrowDB) - Rust stable toolchain
# From KMSmcp root:
npm run build:sparrowdb
# Or directly:
bash scripts/build-sparrowdb-node.sh [/path/to/SparrowDB]SPARROWDB_PATH=~/.kms-sparrowdb \
doppler run --project ry-local --config dev_personal -- \
node scripts/import-neo4j-to-sparrowdb.mjsSPARROWDB_PATH=~/.kms-sparrowdb \
KMS_STORAGE_BACKEND=sparrowdb \
doppler run --project ry-local --config dev_personal -- npm run devKMS_SHADOW_MODE=true \
SPARROWDB_PATH=~/.kms-sparrowdb \
doppler run --project ry-local --config dev_personal -- npm run devnpm test
npm run test:coverage
npm test -- --testPathPattern=OAuth2Authenticator
npm test -- --testPathPattern=HttpTransportMIT