Claude is great at reasoning, but it forgets. A knowledge graph gives it a memory it can query: entities, relationships, the connective tissue between facts. This is the smallest setup I could find that hands Claude a real Neo4j graph to explore over the Model Context Protocol (MCP) - one Docker Compose service, a .env for credentials, and a .mcp.json that wires the Neo4j MCP server into Claude Code.

Docker Compose

One container, two ports. The Browser UI on 7474 lets you eyeball the graph; Bolt on 7687 is the wire Claude actually talks over. Persistent volumes mean your graph survives a restart, and APOC ships the procedures you'll inevitably want.

docker-compose.yaml
services:
neo4j:
image: neo4j:5
ports:
- "7474:7474" # Browser UI
- "7687:7687" # Bolt protocol
volumes:
- neo4j_data:/data
- neo4j_logs:/logs
environment:
- NEO4J_AUTH=${NEO4J_AUTH:-neo4j/changeme}
- NEO4J_server_memory_heap_initial__size=512m
- NEO4J_server_memory_heap_max__size=1G
- NEO4J_server_memory_pagecache_size=512m
- NEO4J_PLUGINS=["apoc"]
restart: unless-stopped
volumes:
neo4j_data:
neo4j_logs:

Environment file

Neo4j wants credentials as a single username/password string, not two fields. Easy to trip on. Keep it in .env and out of git.

Terminal window
# Neo4j credentials (format: username/password)
NEO4J_AUTH=neo4j/changeme

MCP configuration

This is the wiring. .mcp.json tells Claude Code to spawn the Neo4j MCP server, which turns Claude's requests into Cypher and runs them against the graph over Bolt. Change changeme to match your .env, or nothing connects.

.mcp.json
{
"mcpServers": {
"neo4j": {
"type": "stdio",
"command": "neo4j-mcp",
"env": {
"NEO4J_URI": "bolt://localhost:7687",
"NEO4J_USERNAME": "neo4j",
"NEO4J_PASSWORD": "changeme",
"NEO4J_DATABASE": "neo4j"
}
}
}
}

Run it

  1. Run docker compose up -d to start Neo4j.
  2. Open the Browser UI at http://localhost:7474.
  3. Seed a few nodes to populate the graph.
  4. Launch Claude Code in the project directory and query the graph via MCP.

That's the whole thing. No cloud account, no API keys to rotate, no schema migrations. Just a graph database on localhost that Claude can walk with Cypher - ask it how two nodes connect and watch it write the query itself.