Neo4j Knowledge Graph MCP Server
Provides scalable knowledge graph memory storage using Neo4j, enabling semantic retrieval, contextual recall, and temporal awareness of entities and relations.
Uses OpenAI embedding models to generate vector embeddings for semantic search of entities, supporting multi-model compatibility and configurable similarity thresholds.
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., "@Neo4j Knowledge Graph MCP ServerRemember that John Smith works at Anthropic and is fluent in Spanish."
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.
Quick Start
Get up and running in ~10 minutes:
Install Node.js (v24+) and start Neo4j (Docker or Desktop)
Configure your MCP client (Claude Desktop, Claude Code, Cursor, etc.)
Test the setup by creating your first entity
Sections:
Installation - npm/npx setup
Neo4j Setup - Docker or local database
Configuration - Environment variables
Claude Desktop - MCP client setup
Claude Code - CLI client setup
Testing - Verification steps
Related MCP server: KnowledgeGraph MCP Server
Installation
Global Installation with npx (Recommended)
You can run this Neo4j Knowledge Graph MCP server directly using npx:
npx @henrychong-ai/mcp-neo4j-knowledge-graphThis method is recommended for use with Claude Desktop and other MCP-compatible clients.
npm Installation
For local use or development:
# Install the package
pnpm install -g @henrychong-ai/mcp-neo4j-knowledge-graph
# Or use locally in your project
pnpm install @henrychong-ai/mcp-neo4j-knowledge-graphNote: This package is maintained in a private GitHub repository but published publicly to npm. The compiled code, documentation, and full functionality are available through npm installation.
Core Concepts
Entities
Entities are the primary nodes in the knowledge graph. Each entity has:
A unique name (identifier)
An entity type (e.g., "person", "organization", "event")
A list of observations
Vector embeddings (for semantic search)
Complete version history
Example:
{
"name": "John_Smith",
"entityType": "person",
"observations": ["Speaks fluent Spanish"]
}EntityType Convention: Use lowercase-kebab-case for entityType values (e.g., person, medical-condition, claude-code-skill). Avoid uppercase, spaces, or underscores.
Relations
Relations define directed connections between entities with enhanced properties:
Strength indicators (0.0-1.0)
Confidence levels (0.0-1.0)
Rich metadata (source, timestamps, tags)
Temporal awareness with version history
Time-based confidence decay
Example:
{
"from": "John_Smith",
"to": "Anthropic",
"relationType": "works_at",
"strength": 0.9,
"confidence": 0.95,
"metadata": {
"source": "linkedin_profile",
"last_verified": "2025-03-21"
}
}Storage Backend
This MCP server uses Neo4j as its storage backend, providing a unified solution for both graph storage and vector search capabilities.
Why Neo4j?
Unified Storage: Consolidates both graph and vector storage into a single database
Native Graph Operations: Built specifically for graph traversal and queries
Integrated Vector Search: Vector similarity search for embeddings built directly into Neo4j
Scalability: Better performance with large knowledge graphs
Simplified Architecture: Clean design with a single database for all operations
Prerequisites
Neo4j 5.13+ (required for vector search capabilities)
Neo4j Desktop Setup (Recommended)
The easiest way to get started with Neo4j is to use Neo4j Desktop:
Download and install Neo4j Desktop from https://neo4j.com/download/
Create a new project
Add a new database
Set password to
memento_password(or your preferred password)Start the database
The Neo4j database will be available at:
Bolt URI:
bolt://127.0.0.1:7687(for driver connections)HTTP:
http://127.0.0.1:7474(for Neo4j Browser UI)Default credentials: username:
neo4j, password:your_password(or whatever you configured)
Neo4j Setup with Docker (Alternative)
Alternatively, you can use Docker to run Neo4j:
# Start Neo4j container
docker run -d \
--name neo4j-kg \
--restart unless-stopped \
-p 7474:7474 \
-p 7687:7687 \
-v neo4j-kg_data:/data \
-v neo4j-kg_logs:/logs \
-e NEO4J_AUTH=neo4j/your_password \
neo4j:5.26-community
# Stop Neo4j container
docker stop neo4j-kg
# Start existing container
docker start neo4j-kg
# Remove Neo4j container (preserves data in volumes)
docker rm neo4j-kgWhen using Docker, the Neo4j database will be available at:
Bolt URI:
bolt://127.0.0.1:7687(for driver connections)HTTP:
http://127.0.0.1:7474(for Neo4j Browser UI)Default credentials: username:
neo4j, password:your_password
Data Persistence and Management
Neo4j data persists across container restarts and even version upgrades due to Docker named volumes:
neo4j-kg_data- Database filesneo4j-kg_logs- Log files
To backup your data:
# Create a backup of the data volume
docker run --rm -v neo4j-kg_data:/data -v $(pwd):/backup alpine tar czf /backup/neo4j-backup-$(date +%Y%m%d).tar.gz -C /data .To restore from backup:
# Restore data from backup
docker run --rm -v neo4j-kg_data:/data -v $(pwd):/backup alpine tar xzf /backup/neo4j-backup-YYYYMMDD.tar.gz -C /dataUpgrading Neo4j Version
For comprehensive Neo4j upgrade procedures, see docs/UPGRADE.md.
This guide covers:
When and why to upgrade (LTS vs Latest)
Complete 5-phase upgrade procedure with go/no-go checkpoints
Configuration management (deprecated settings)
Troubleshooting and rollback procedures
Real-world upgrade examples with verified commands
48-hour monitoring schedule
Quick Reference for Docker:
# Basic upgrade (for development/testing)
1. Stop current container: docker stop neo4j-kg
2. Remove container: docker rm neo4j-kg
3. Start new version: docker run -d --name neo4j-kg ... neo4j:5.XX-community
4. Reinitialize schema: pnpm run neo4j:initProduction Warning: For production deployments with valuable data, always follow the complete procedure in docs/UPGRADE.md, which includes backup verification, data integrity checks, and rollback procedures.
Complete Database Reset
If you need to completely reset your Neo4j database:
# Stop and remove the container
docker stop neo4j-kg
docker rm neo4j-kg
# Remove the data volume
docker volume rm neo4j-kg_data
# Restart with fresh container
docker run -d \
--name neo4j-kg \
--restart unless-stopped \
-p 7474:7474 \
-p 7687:7687 \
-v neo4j-kg_data:/data \
-v neo4j-kg_logs:/logs \
-e NEO4J_AUTH=neo4j/your_password \
neo4j:5.26-community
# Reinitialize the schema
pnpm run neo4j:initNeo4j CLI Utilities
This MCP server includes command-line utilities for managing Neo4j operations:
Testing Connection
Test the connection to your Neo4j database:
# Test with default settings
pnpm run neo4j:test
# Test with custom settings
pnpm run neo4j:test -- --uri bolt://127.0.0.1:7687 --username myuser --password mypass --database neo4jInitializing Schema
For normal operation, Neo4j schema initialization happens automatically when the MCP server connects to the database. You don't need to run any manual commands for regular usage.
The following commands are only necessary for development, testing, or advanced customization scenarios:
# Initialize with default settings (only needed for development or troubleshooting)
pnpm run neo4j:init
# Initialize with custom vector dimensions
pnpm run neo4j:init -- --dimensions 768 --similarity euclidean
# Force recreation of all constraints and indexes
pnpm run neo4j:init -- --recreate
# Combine multiple options
pnpm run neo4j:init -- --vector-index custom_index --dimensions 384 --recreateAdvanced Features
Semantic Search
Find semantically related entities based on meaning rather than just keywords:
Vector Embeddings: Entities are automatically encoded into high-dimensional vector space using OpenAI's embedding models
Cosine Similarity: Find related concepts even when they use different terminology
Configurable Thresholds: Set minimum similarity scores to control result relevance
Cross-Modal Search: Query with text to find relevant entities regardless of how they were described
Multi-Model Support: Compatible with multiple embedding models (OpenAI text-embedding-3-small/large)
Contextual Retrieval: Retrieve information based on semantic meaning rather than exact keyword matches
Optimized Defaults: Tuned parameters for balance between precision and recall (0.6 similarity threshold, hybrid search enabled)
Hybrid Search: Combines semantic and keyword search for more comprehensive results
Adaptive Search: System intelligently chooses between vector-only, keyword-only, or hybrid search based on query characteristics and available data
Performance Optimization: Prioritizes vector search for semantic understanding while maintaining fallback mechanisms for resilience
Query-Aware Processing: Adjusts search strategy based on query complexity and available entity embeddings
Temporal Awareness
Track complete history of entities and relations with point-in-time graph retrieval:
Full Version History: Every change to an entity or relation is preserved with timestamps
Point-in-Time Queries: Retrieve the exact state of the knowledge graph at any moment in the past
Change Tracking: Automatically records createdAt, updatedAt, validFrom, and validTo timestamps
Temporal Consistency: Maintain a historically accurate view of how knowledge evolved
Non-Destructive Updates: Updates create new versions rather than overwriting existing data
Time-Based Filtering: Filter graph elements based on temporal criteria
History Exploration: Investigate how specific information changed over time
Confidence Decay
Relations automatically decay in confidence over time based on configurable half-life:
Time-Based Decay: Confidence in relations naturally decreases over time if not reinforced
Configurable Half-Life: Define how quickly information becomes less certain (default: 30 days)
Minimum Confidence Floors: Set thresholds to prevent over-decay of important information
Decay Metadata: Each relation includes detailed decay calculation information
Non-Destructive: Original confidence values are preserved alongside decayed values
Reinforcement Learning: Relations regain confidence when reinforced by new observations
Reference Time Flexibility: Calculate decay based on arbitrary reference times for historical analysis
Advanced Metadata
Rich metadata support for both entities and relations with custom fields:
Source Tracking: Record where information originated (user input, analysis, external sources)
Confidence Levels: Assign confidence scores (0.0-1.0) to relations based on certainty
Relation Strength: Indicate importance or strength of relationships (0.0-1.0)
Temporal Metadata: Track when information was added, modified, or verified
Custom Tags: Add arbitrary tags for classification and filtering
Structured Data: Store complex structured data within metadata fields
Query Support: Search and filter based on metadata properties
Extensible Schema: Add custom fields as needed without modifying the core data model
Batch Operations
Optimized bulk operations providing 10-50x performance improvement over individual operations:
High-Performance Bulk Processing: Batch operations use Neo4j's UNWIND clause for dramatic performance gains
Automatic Chunking: Large batches are automatically split into optimal chunk sizes (default: 100 items)
Parallel Processing: Independent operations (like embedding generation) can run concurrently
Progress Tracking: Optional callbacks provide real-time progress updates for long-running operations
Partial Failure Handling: Continue processing on failures with detailed error reports per item
Performance Metrics: Each batch operation returns total time and per-item average timing
Transaction Safety: Automatic rollback on failures ensures data consistency
Available Batch Tools:
create_entities_batch: Create multiple entities in single operationcreate_relations_batch: Create multiple relations in single operationadd_observations_batch: Add observations to multiple entities in single operationupdate_entities_batch: Update multiple entities in single operation
Performance Comparison:
// Individual operations: ~50 seconds for 100 entities
for (const entity of entities) {
await createEntities([entity]);
}
// Batch operation: ~1.5 seconds for 100 entities (33x faster)
await createEntitiesBatch(entities, {
maxBatchSize: 100,
enableParallel: true,
});Configuration Options:
maxBatchSize: Control chunk size (default: 100)enableParallel: Reserved for future parallel chunk processing (embeddings always generated if service available)onProgress: Callback for progress tracking
Cost Management:
Incremental approach minimizes API calls
Only processes entities without embeddings
Typical cost: ~$0.02 per 1M tokens
Production cost: ~$0.0025 per daily run (for typical workloads)
This automation ensures semantic search remains highly effective as your knowledge graph grows, without requiring manual embedding regeneration.
Query Result Caching (v1.5.0+)
Semantic search queries are automatically cached for improved performance:
Cache Configuration:
LRU (Least Recently Used) Strategy: Automatically evicts oldest entries when full
Capacity: 500 unique queries cached simultaneously
TTL (Time-To-Live): 5 minutes per cache entry
Size Limit: 10,000 entities maximum across all cached results
Size Calculation: Entity count + relation count
Cache Behavior:
Cache Hits: Sub-millisecond response for repeated queries
Automatic Invalidation: Cache cleared on mutations (create_entities, add_observations, delete_entities, etc.)
Intelligent Keying: Considers query text, limit, similarity threshold, entity types, and hybrid config
Metrics Integration: Cache hits/misses tracked via Prometheus (when enabled)
Performance Impact:
First Query: Normal latency (~100-500ms depending on graph size)
Cached Query: <1ms response time
Memory Usage: Minimal - automatically bounded by size limits
Cache Miss Rate: Typically <10% for conversational workloads
Example Scenarios:
User asks "What programming languages do you know?" → Cache miss (~300ms)
User asks "What programming languages do you know?" again → Cache hit (<1ms)
User creates new entity → Cache cleared for consistency
User asks "What programming languages do you know?" → Cache miss (~300ms, fresh results)
This caching layer provides significant performance improvements for repeated or similar queries without any configuration needed.
MCP API Tools
The following tools are available to LLM client hosts through the Model Context Protocol:
Entity Management
create_entities
Create multiple new entities in the knowledge graph
Input:
entities(array of objects)Each object contains:
name(string): Entity identifierentityType(string): Type classificationdomain(string, optional): User-defined namespace for organization. Default:null(uncategorized)observations(string[]): Associated observations
add_observations
Add new observations to existing entities
Input:
observations(array of objects)Each object contains:
entityName(string): Target entitycontents(string[]): New observations to add
delete_entities
Remove entities and their relations
Input:
entityNames(string[])
delete_observations
Remove specific observations from entities
Input:
deletions(array of objects)Each object contains:
entityName(string): Target entityobservations(string[]): Observations to remove
Relation Management
create_relations
Create multiple new relations between entities with enhanced properties
Input:
relations(array of objects)Each object contains:
from(string): Source entity nameto(string): Target entity namerelationType(string): Relationship typestrength(number, optional): Relation strength (0.0-1.0)confidence(number, optional): Confidence level (0.0-1.0)metadata(object, optional): Custom metadata fields
get_relation
Get a specific relation with its enhanced properties
Input:
from(string): Source entity nameto(string): Target entity namerelationType(string): Relationship type
update_relation
Update an existing relation with enhanced properties
Input:
relation(object):Contains:
from(string): Source entity nameto(string): Target entity namerelationType(string): Relationship typestrength(number, optional): Relation strength (0.0-1.0)confidence(number, optional): Confidence level (0.0-1.0)metadata(object, optional): Custom metadata fields
delete_relations
Remove specific relations from the graph
Input:
relations(array of objects)Each object contains:
from(string): Source entity nameto(string): Target entity namerelationType(string): Relationship type
Graph Operations
read_graph
Read the entire knowledge graph
No input required
search_nodes
Search for nodes based on query
Input:
query(string): Search querydomain(string, optional): Filter by user-defined domain. Omit to search all domains
open_nodes
Retrieve specific nodes by name
Input:
names(string[])
Semantic Search
semantic_search
Search for entities semantically using vector embeddings and similarity
Input:
query(string): The text query to search for semanticallylimit(number, optional): Maximum results to return (default: 10; with a reranker configured, default: 5 reranked best-first — an explicitlimitis always honoured exactly)min_similarity(number, optional): Minimum similarity threshold on Neo4j's normalised cosine scale (0.0-1.0, where 0.5 ≈ unrelated; default: 0 = disabled — see Result counts, ordering &min_similarity)entity_types(string[], optional): Filter results by entity typesdomain(string, optional): Filter by user-defined domain. Omit to search all domainshybrid_search(boolean, optional): Combine keyword and semantic search (default: true)semantic_weight(number, optional): Weight of semantic results in hybrid search (0.0-1.0, default: 0.6)
Features:
Intelligently selects optimal search method (vector, keyword, or hybrid) based on query context
Gracefully handles queries with no semantic matches through fallback mechanisms
Maintains high performance with automatic optimization decisions
get_entity_embedding
Get the vector embedding for a specific entity
Input:
entity_name(string): The name of the entity to get the embedding for
Temporal Features
get_entity_history
Get complete version history of an entity
Input:
entityName(string)
get_relation_history
Get complete version history of a relation
Input:
from(string): Source entity nameto(string): Target entity namerelationType(string): Relationship type
get_graph_at_time
Get the state of the graph at a specific timestamp
Input:
timestamp(number): Unix timestamp (milliseconds since epoch)
get_decayed_graph
Get graph with time-decayed confidence values
Input:
options(object, optional):reference_time(number): Reference timestamp for decay calculation (milliseconds since epoch)decay_factor(number): Optional decay factor override
Embeddings & Reranking Setup
Semantic search needs an embedding provider. The server speaks the OpenAI-compatible /embeddings API, so it works with OpenAI, Cloudflare Workers AI, or any self-hosted OpenAI-compatible endpoint (Ollama, LM Studio, vLLM). An optional cross-encoder reranker re-scores semantic search candidates for better precision.
The one rule that matters: dimensions must match
EMBEDDING_DIMENSIONS == NEO4J_VECTOR_DIMENSIONS == the model's NATIVE output dimensionThe Neo4j vector index is created at a fixed dimension. A vector of any other length can never be indexed — and as of v2.6.0 the server refuses to write it (see Graceful degradation). The dimension is a property of the model, so pick the model first, then set both variables to its native output size.
Option A — OpenAI (default)
OPENAI_API_KEY=sk-...
OPENAI_EMBEDDING_MODEL=text-embedding-3-small # 1536 dimensions (default)
NEO4J_VECTOR_DIMENSIONS=1536Nothing else needed — the OpenAI endpoint is the built-in default.
Option B — Cloudflare Workers AI (free plan works)
Cloudflare's free Workers AI allocation (10,000 neurons/day) comfortably covers a personal knowledge graph — a full re-embed of ~2,000 entities fits inside a single day's free quota, and steady-state usage (query embeddings + incremental backfill) is a tiny fraction of that.
Create a token: Cloudflare dashboard → My Profile → API Tokens → Create Token → use the Workers AI template (or a custom token with
Account → Workers AI → Read). This single permission covers both embeddings and the reranker.Find your account ID: dashboard → any zone → right sidebar, or Workers & Pages overview.
Configure:
EMBEDDING_API_KEY=<your-cf-workers-ai-token>
EMBEDDING_API_ENDPOINT=https://api.cloudflare.com/client/v4/accounts/<your-account-id>/ai/v1/embeddings
EMBEDDING_MODEL=@cf/qwen/qwen3-embedding-0.6b # native 1024 dimensions
EMBEDDING_DIMENSIONS=1024
NEO4J_VECTOR_DIMENSIONS=1024
# Optional but recommended: cross-encoder reranker (same token)
RERANK_ENABLED=true
RERANK_ACCOUNT_ID=<your-account-id>
RERANK_MODEL=@cf/baai/bge-reranker-base
RERANK_API_KEY=<your-cf-workers-ai-token>Option C — Any OpenAI-compatible endpoint (Ollama, LM Studio, vLLM)
EMBEDDING_API_KEY=anything-non-empty # some local servers ignore auth but the key must be set
EMBEDDING_API_BASE_URL=http://localhost:11434/v1 # /embeddings is appended automatically
EMBEDDING_MODEL=nomic-embed-text # check your model's native dimension!
EMBEDDING_DIMENSIONS=768
NEO4J_VECTOR_DIMENSIONS=768Result counts, ordering & min_similarity
Defaults are reranker-aware (v2.7.0+). Vector recall is always limit ?? 10; the reranker only re-orders within that recalled set and trims the default return:
Scenario | Vector recall | Returned | Final order |
No reranker, default | 10 | 10 | hybrid score, best-first |
Reranker configured, default | 10 | 5 ( | cross-encoder, best-first |
Explicit | N | N (always honoured exactly) | as above |
Reranker fails → fail-open | 10 / N | 5 / N | hybrid score, sliced to the return count |
Two env knobs govern the reranker, and they mean different things:
RERANK_TOP_K(default 5) — the default return count when a reranker is configured. Only applies when no explicitlimitis given.RERANK_TOP_N(default 20) — the scoring-payload cap: how many recall candidates are sent to the cross-encoder for scoring. It is not a return count. With an explicitlimitlarger thanRERANK_TOP_N, the firstRERANK_TOP_Ncandidates are cross-encoder-ordered and the unscored remainder is appended in recall order, so thelimitcontract always holds.
Ordering guarantees: with a reranker, results are cross-encoder best-first (the response is defensively score-sorted server-side). Without a reranker — and on any reranker failure (fail-open) — results follow the hybrid-score order, which is preserved through entity hydration on both search paths (v2.7.0+).
min_similarity: the threshold applies to Neo4j's normalised cosine score — (cosine + 1) / 2, so 0.5 ≈ unrelated and 1.0 = identical. The default is 0 (disabled). Absolute floors are not meaningful on this scale for typical embedding models: measured with qwen3 embeddings, top-20 scores cluster around 0.71–0.90 for relevant and irrelevant queries alike, so any floor that blocks junk also blocks real queries. The parameter is retained per-call for power users (an explicit 0 works).
Switching models (dimension migration)
Changing to a model with a different native dimension requires rebuilding the vector index and re-embedding — vectors of the old dimension cannot coexist with the new index. With the server stopped:
DROP INDEX entity_embeddings IF EXISTS;
MATCH (e:Entity) WHERE e.embedding IS NOT NULL
SET e.embedding = NULL, e.embeddingModel = NULL, e.embeddingGeneratedAt = NULL;
CREATE VECTOR INDEX entity_embeddings IF NOT EXISTS
FOR (n:Entity) ON (n.embedding)
OPTIONS { indexConfig: {
`vector.dimensions`: 1024, // the NEW dimension
`vector.similarity_function`: 'cosine'
} };Then update the EMBEDDING_* / NEO4J_VECTOR_DIMENSIONS variables and restart. The backfill cron (EMBEDDING_BACKFILL_CRON) re-embeds every entity automatically — tighten it to */1 * * * * for the duration of the migration if you want it done in minutes rather than at the next daily tick.
Graceful degradation / failure behaviour
The embedding pipeline is designed to fail loudly into a safe state, never silently corrupt:
Condition | Behaviour |
No provider configured (no | Server runs in keyword-only mode: BM25/keyword search works, |
Embedding API call fails on entity write | Entity is persisted with |
Reranker errors (timeout, bad response, quota) | Fail-open: |
Vector length ≠ | Write is rejected with a loud error — a mismatched vector can never be indexed, so persisting it would silently corrupt search. The startup log also warns if |
| Embedding writes are refused (keyword-only mode + hard error log). |
Multi-Surface MCP Client Setup
When several MCP clients (Claude Code, Claude Desktop, Codex, etc.) share one knowledge graph, use a hub-and-spoke topology:
One server-side instance owns all embedding writes:
WRITE_EMBEDDINGS_LOCALLY=true(the default) plus a tight backfill cron (EMBEDDING_BACKFILL_CRON='*/1 * * * *').Every interactive client runs as a thin client:
WRITE_EMBEDDINGS_LOCALLY=false. Thin clients embed queries (sosemantic_searchworks) but never write embeddings — a misconfigured laptop can therefore never pollute the shared store.
The canonical thin-client environment (substitute your own values):
NEO4J_URI=bolt://<your-neo4j-host>:7687
NEO4J_USERNAME=neo4j # NOTE: NEO4J_USERNAME — "NEO4J_USER" is silently ignored
NEO4J_PASSWORD=<password>
NEO4J_DATABASE=neo4j
NEO4J_VECTOR_DIMENSIONS=1024
EMBEDDING_API_KEY=<token>
EMBEDDING_API_ENDPOINT=https://api.cloudflare.com/client/v4/accounts/<account-id>/ai/v1/embeddings
EMBEDDING_MODEL=@cf/qwen/qwen3-embedding-0.6b
EMBEDDING_DIMENSIONS=1024
RERANK_ENABLED=true
RERANK_ACCOUNT_ID=<account-id>
RERANK_MODEL=@cf/baai/bge-reranker-base
RERANK_API_KEY=<token>
WRITE_EMBEDDINGS_LOCALLY=falseClaude Code (user scope, all projects):
claude mcp add-json kg -s user '{
"command": "npx",
"args": ["-y", "@henrychong-ai/mcp-neo4j-knowledge-graph"],
"env": { /* canonical thin-client env above */ }
}'Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"kg": {
"command": "npx",
"args": ["-y", "@henrychong-ai/mcp-neo4j-knowledge-graph"],
"env": { "...": "canonical thin-client env above" }
}
}
}Codex (~/.codex/config.toml):
[mcp_servers.kg]
command = "npx"
args = ["-y", "@henrychong-ai/mcp-neo4j-knowledge-graph"]
[mcp_servers.kg.env]
NEO4J_URI = "bolt://<your-neo4j-host>:7687"
# ... canonical thin-client env above, TOML syntaxTips:
Secrets: prefer a secret-manager wrapper (e.g. 1Password:
command: "op",args: ["run", "--", "npx", "-y", "@henrychong-ai/mcp-neo4j-knowledge-graph"]withop://references inenv) over literal tokens in config files.Query embeddings must match the index: every client embeds its own queries, so all clients must use the same model/dimension as the server's index. A client on a different model returns no semantic hits.
After upgrading: clear the npx cache so clients pick up the new version —
rm -rf ~/.npm/_npx/*/node_modules/@henrychong-ai— then restart the client app. Long-lived apps (Claude Desktop) keep old server processes alive until restarted.
Configuration
Environment Variables
Configure the MCP server with these environment variables:
# Neo4j Connection Settings
NEO4J_URI=bolt://127.0.0.1:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=your_password
NEO4J_DATABASE=neo4j
# Vector Search Configuration
NEO4J_VECTOR_INDEX=entity_embeddings
NEO4J_VECTOR_DIMENSIONS=1536
NEO4J_SIMILARITY_FUNCTION=cosine
# Embedding Service Configuration
OPENAI_API_KEY=your-openai-api-key
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
# Provider-neutral embedding config (v2.5.0+) — ANY OpenAI-compatible endpoint.
# These fall back to the OPENAI_* names above, so existing setups are unaffected.
# Example: Cloudflare Workers AI qwen3-embedding-0.6b (1024-dim):
# EMBEDDING_API_KEY=<cf-workers-ai-token>
# EMBEDDING_API_BASE_URL=https://api.cloudflare.com/client/v4/accounts/<id>/ai/v1
# EMBEDDING_MODEL=@cf/qwen/qwen3-embedding-0.6b
# EMBEDDING_DIMENSIONS=1024 # MUST match NEO4J_VECTOR_DIMENSIONS and the model's NATIVE output
# # dim. Sets the reported/index dimension only — it is NOT sent in
# # the embeddings request (not all OpenAI-compatible endpoints accept
# # a `dimensions` param), so it cannot truncate an OpenAI vector;
# # choose a model whose native output dim already matches.
# With NO provider configured (and MOCK_EMBEDDINGS unset) the server runs keyword-only
# (no random-vector mock). Set MOCK_EMBEDDINGS=true for deterministic test vectors.
# Optional cross-encoder reranker (v2.5.0+) — re-scores semantic_search candidates.
# Disabled unless RERANK_ENABLED=true AND an endpoint + key resolve. Fail-open on any error
# (v2.7.0+: fail-open returns the hybrid-ordered recall sliced to the return count).
RERANK_ENABLED=false
# RERANK_MODEL=@cf/baai/bge-reranker-base
# RERANK_ENDPOINT=https://api.cloudflare.com/client/v4/accounts/<id>/ai/run/@cf/baai/bge-reranker-base
# RERANK_ACCOUNT_ID=<id> # alternative to RERANK_ENDPOINT (derives the URL from model)
# RERANK_API_KEY=<token> # falls back to EMBEDDING_API_KEY
# RERANK_TOP_N=20 # scoring-payload cap (candidates sent to the cross-encoder) — NOT a return count
# RERANK_TOP_K=5 # default return count with a reranker (explicit `limit` always wins; v2.7.0: was 10)
# RERANK_MAX_PASSAGE_CHARS=2000 RERANK_TIMEOUT_MS=5000
# Embedding Pipeline Topology (v2.3.0+)
WRITE_EMBEDDINGS_LOCALLY=true # Default true. Set to "false" on thin-client hosts (e.g. laptops)
# to skip queueing embedding jobs on entity writes; entities are
# persisted with embedding=NULL and a server-side instance is
# responsible for backfilling. Read paths still use the embedding
# service for query embeddings, so OPENAI_API_KEY is still
# required for semantic_search unless you accept BM25-only fallback.
EMBEDDING_BACKFILL_CRON='0 19 * * *' # Cron schedule for scheduleIncrementalRegeneration. Default
# 19:00 UTC daily (= 03:00 SGT). Server-side instances may
# tighten to '*/1 * * * *' for ~1-minute backfill latency.
EMBEDDING_STALE_CLAIM_MS=300000 # (v2.4.0+) Claims older than this age are auto-released back
# to 'pending' on the next processJobs tick. Default 5 minutes.
# Increase if your worker's batch processing time can exceed
# this; decrease for faster recovery from worker crashes.
# Logging Configuration
LOG_LEVEL=warn # Log level: debug, info, warn, error, silent (default: warn)
DEBUG=true # Enable debug mode (enables additional diagnostic tools)
# Prometheus Metrics (Optional - Production Monitoring)
ENABLE_PROMETHEUS_METRICS=true # Enable metrics collection and HTTP endpointPrometheus Metrics
The MCP server includes built-in Prometheus metrics for production observability. Metrics are disabled by default to minimize local machine overhead and only enabled when explicitly configured.
Enabling Metrics
Set the environment variable to enable metrics collection:
export ENABLE_PROMETHEUS_METRICS=trueWhen enabled, the metrics server starts on port 9091 and exposes a /metrics endpoint in Prometheus exposition format.
Available Metrics
Query Performance:
mcp_query_duration_seconds- Histogram tracking query execution timeLabels:
operation(loadGraph, searchNodes, openNodes, semanticSearch),cache_status(hit, miss, disabled)Buckets: 1ms, 5ms, 10ms, 50ms, 100ms, 500ms, 1s, 5s
Cache Performance (ready for future cache integration):
mcp_cache_hits_total- Counter for cache hitsmcp_cache_misses_total- Counter for cache missesmcp_cache_invalidations_total- Counter for cache invalidationsmcp_cache_size_current- Gauge for current cache size
Process Metrics:
Default Node.js process metrics (CPU, memory, event loop, garbage collection)
Accessing Metrics
Once enabled, metrics are available at:
curl http://localhost:9091/metricsProduction Deployment
For production deployments, configure Prometheus to scrape the metrics endpoint:
scrape_configs:
- job_name: 'mcp-kg-server'
scrape_interval: 30s
static_configs:
- targets: ['localhost:9091']
labels:
instance: 'mcp-neo4j-knowledge-graph'
environment: 'production'Metrics can then be visualized in Grafana with custom dashboards showing:
Query performance trends
Cache hit/miss ratios
System resource utilization
Operation latency distributions
Port Selection
Port 9091 is chosen to avoid conflicts with common Prometheus exporters:
9090: Prometheus server
9099: neo4j-exporter
9100: node-exporter
Command Line Options
The Neo4j CLI tools support the following options:
--uri <uri> Neo4j server URI (default: bolt://127.0.0.1:7687)
--username <username> Neo4j username (default: neo4j)
--password <password> Neo4j password (default: memento_password)
--database <n> Neo4j database name (default: neo4j)
--vector-index <n> Vector index name (default: entity_embeddings)
--dimensions <number> Vector dimensions (default: 1536)
--similarity <function> Similarity function (cosine|euclidean) (default: cosine)
--recreate Force recreation of constraints and indexes
--no-debug Disable detailed output (debug is ON by default)Embedding Models
Available OpenAI embedding models:
text-embedding-3-small: Efficient, cost-effective (1536 dimensions)text-embedding-3-large: Higher accuracy, more expensive (3072 dimensions)text-embedding-ada-002: Legacy model (1536 dimensions)
OpenAI API Configuration
To use semantic search, you'll need to configure OpenAI API credentials:
Obtain an API key from OpenAI
Configure your environment with:
# OpenAI API Key for embeddings
OPENAI_API_KEY=your-openai-api-key
# Default embedding model
OPENAI_EMBEDDING_MODEL=text-embedding-3-smallNote: For testing environments, the system will mock embedding generation if no API key is provided. However, using real embeddings is recommended for integration testing.
Integration with Claude Desktop
Configuration
Add this to your claude_desktop_config.json:
{
"mcpServers": {
"neo4j-kg": {
"command": "npx",
"args": ["-y", "@henrychong-ai/mcp-neo4j-knowledge-graph"],
"env": {
"NEO4J_URI": "bolt://127.0.0.1:7687",
"NEO4J_USERNAME": "neo4j",
"NEO4J_PASSWORD": "your_password",
"NEO4J_DATABASE": "neo4j",
"NEO4J_VECTOR_INDEX": "entity_embeddings",
"NEO4J_VECTOR_DIMENSIONS": "1536",
"NEO4J_SIMILARITY_FUNCTION": "cosine",
"OPENAI_API_KEY": "your-openai-api-key",
"OPENAI_EMBEDDING_MODEL": "text-embedding-3-small",
"DEBUG": "true"
}
}
}
}Alternatively, for local development, you can use:
{
"mcpServers": {
"neo4j-kg": {
"command": "/path/to/node",
"args": ["/path/to/mcp-neo4j-knowledge-graph/dist/index.js"],
"env": {
"NEO4J_URI": "bolt://127.0.0.1:7687",
"NEO4J_USERNAME": "neo4j",
"NEO4J_PASSWORD": "your_password",
"NEO4J_DATABASE": "neo4j",
"NEO4J_VECTOR_INDEX": "entity_embeddings",
"NEO4J_VECTOR_DIMENSIONS": "1536",
"NEO4J_SIMILARITY_FUNCTION": "cosine",
"OPENAI_API_KEY": "your-openai-api-key",
"OPENAI_EMBEDDING_MODEL": "text-embedding-3-small",
"DEBUG": "true"
}
}
}
}Important: Always explicitly specify the embedding model in your Claude Desktop configuration to ensure consistent behavior.
Recommended System Prompts
For optimal integration with Claude, add these statements to your system prompt:
You have access to a Neo4j knowledge graph memory system, which provides you with persistent memory capabilities.
Your memory tools are provided by a sophisticated knowledge graph implementation.
When asked about past conversations or user information, always check the knowledge graph first.
You should use semantic_search to find relevant information in your memory when answering questions.Testing Semantic Search
Once configured, Claude can access the semantic search capabilities through natural language:
To create entities with semantic embeddings:
User: "Remember that Python is a high-level programming language known for its readability and JavaScript is primarily used for web development."To search semantically:
User: "What programming languages do you know about that are good for web development?"To retrieve specific information:
User: "Tell me everything you know about Python."
The power of this approach is that users can interact naturally, while the LLM handles the complexity of selecting and using the appropriate memory tools.
Real-World Applications
The adaptive search capabilities provide practical benefits:
Query Versatility: Users don't need to worry about how to phrase questions - the system adapts to different query types automatically
Failure Resilience: Even when semantic matches aren't available, the system can fall back to alternative methods without user intervention
Performance Efficiency: By intelligently selecting the optimal search method, the system balances performance and relevance for each query
Improved Context Retrieval: LLM conversations benefit from better context retrieval as the system can find relevant information across complex knowledge graphs
For example, when a user asks "What do you know about machine learning?", the system can retrieve conceptually related entities even if they don't explicitly mention "machine learning" - perhaps entities about neural networks, data science, or specific algorithms. But if semantic search yields insufficient results, the system automatically adjusts its approach to ensure useful information is still returned.
Integration with Claude Code
Configuration
Add this to your ~/.claude.json:
{
"mcpServers": {
"neo4j-kg": {
"command": "npx",
"args": ["-y", "@henrychong-ai/mcp-neo4j-knowledge-graph"],
"env": {
"NEO4J_URI": "bolt://127.0.0.1:7687",
"NEO4J_USERNAME": "neo4j",
"NEO4J_PASSWORD": "your_password",
"NEO4J_DATABASE": "neo4j",
"NEO4J_VECTOR_INDEX": "entity_embeddings",
"NEO4J_VECTOR_DIMENSIONS": "1536",
"NEO4J_SIMILARITY_FUNCTION": "cosine",
"OPENAI_API_KEY": "your-openai-api-key",
"OPENAI_EMBEDDING_MODEL": "text-embedding-3-small"
}
}
}
}Verify MCP Tools Available
In a Claude Code session, the MCP tools will be automatically available. You can verify by asking:
Show me the available MCP tools for the knowledge graphYou should see tools like:
mcp__kg__create_entitiesmcp__kg__create_relationsmcp__kg__add_observationsmcp__kg__search_nodesmcp__kg__semantic_searchAnd more...
Testing Your Setup
Step 1: Create Your First Entity
In Claude Desktop or Claude Code, say:
Use the knowledge graph to create an entity named "Python"
of type "Programming Language" with the observation
"General-purpose, high-level programming language known for readability"Step 2: Search for the Entity
Search the knowledge graph for "Python"Claude should find your entity using the mcp__kg__search_nodes tool.
Step 3: Add More Observations
Add these observations to the Python entity:
- Created by Guido van Rossum in 1991
- Popular for data science, web development, and automation
- Dynamic typing with interpreted executionStep 4: Verify in Neo4j Browser
Open http://localhost:7474 and run:
MATCH (e:Entity {name: "Python"})
WHERE e.validTo IS NULL
RETURN eYou should see your entity with all observations.
Step 5: Test Semantic Search (If OpenAI API Key Configured)
Perform a semantic search for "programming languages for beginners"The Python entity should appear in results based on semantic similarity.
Troubleshooting
Schema Constraint Configuration
Temporal versioning requires a composite uniqueness constraint in your Neo4j database:
CREATE CONSTRAINT entity_name
FOR (e:Entity)
REQUIRE (e.name, e.validTo) IS UNIQUE;If you see Node already exists errors, your database has an old single-field constraint. See docs/SCHEMA_CONSTRAINT_FIX.md for diagnosis and fix instructions.
Vector Search Diagnostics
The MCP server includes built-in diagnostic capabilities to help troubleshoot vector search issues:
Embedding Verification: The system checks if entities have valid embeddings and automatically generates them if missing
Vector Index Status: Verifies that the vector index exists and is in the ONLINE state
Fallback Search: If vector search fails, the system falls back to text-based search
Detailed Logging: Comprehensive logging of vector search operations for troubleshooting
Debug Tools (when DEBUG=true)
Additional diagnostic tools become available when debug mode is enabled:
diagnose_vector_search: Information about the Neo4j vector index, embedding counts, and search functionality
force_generate_embedding: Forces the generation of an embedding for a specific entity
debug_embedding_config: Information about the current embedding service configuration
Developer Reset
To completely reset your Neo4j database during development:
# Stop the container (if using Docker)
docker stop neo4j-kg
# Remove the container (if using Docker)
docker rm neo4j-kg
# Delete the data volume (if using Docker)
docker volume rm neo4j-kg_data
# For Neo4j Desktop, right-click your database and select "Drop database"
# Restart the database
# For Docker:
docker run -d \
--name neo4j-kg \
--restart unless-stopped \
-p 7474:7474 \
-p 7687:7687 \
-v neo4j-kg_data:/data \
-v neo4j-kg_logs:/logs \
-e NEO4J_AUTH=neo4j/your_password \
neo4j:5.26-community
# For Neo4j Desktop:
# Click the "Start" button for your database
# Reinitialize the schema
pnpm run neo4j:initContributing
Contributions are welcome! See CONTRIBUTING.md for guidelines.
License
MIT - See the LICENSE file for details.
Acknowledgments
Built on foundational work by Gannon Hall. For the original implementation, see @gannonh/memento-mcp.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
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/henrychong-ai/mcp-neo4j-knowledge-graph'
If you have feedback or need assistance with the MCP directory API, please join our Discord server