Graphiti Setup Guide¶
Purpose: Set up the Graphiti temporal knowledge graph to provide persistent memory and context across GuardKit sessions.
Technology: Graphiti + Neo4j (temporal knowledge graph with semantic search)
Overview¶
Graphiti is a temporal knowledge graph that gives GuardKit persistent memory across sessions. Instead of re-learning your project's architecture and patterns every time, GuardKit can recall previous decisions, patterns, and context from the knowledge graph.
Key Benefits:
- Persistent Memory: Context survives across sessions and restarts
- Semantic Search: Find related decisions, patterns, and architecture
- Temporal Tracking: See how decisions evolved over time
- Automatic Integration: Works transparently during /task-work and /feature-build
What Gets Stored: - Product knowledge (GuardKit concepts, entities, relationships) - Command workflows (usage patterns, best practices) - Quality gate phases (testing, review processes) - Technology stack information (templates, agents, patterns) - Architecture Decision Records (ADRs for feature-build workflow)
Prerequisites¶
Before installing, ensure you have:
- Docker Desktop (or Docker Engine + Docker Compose) (download here)
- Python 3.10+ with async support
- OpenAI API Key for embeddings (get one here)
- Recommended: 4GB RAM, SSD storage for graph database
Verify Docker installation:
Installation Steps¶
Step 1: Start Graphiti Services¶
Start the Neo4j graph database and Graphiti API server using Docker Compose:
Expected output:
[+] Running 3/3
✔ Network guardkit-knowledge Created
✔ Container guardkit-neo4j Started
✔ Container guardkit-graphiti Started
What this does:
- Creates guardkit-knowledge network for service communication
- Starts guardkit-neo4j on ports 7474 (HTTP) and 7687 (Bolt) (graph database backend)
- Starts guardkit-graphiti on port 8000 (API server)
- Creates persistent volumes for data storage
Verify services are running:
You should see:
CONTAINER ID IMAGE STATUS PORTS
abc123def456 zepai/graphiti:latest Up 30 seconds 0.0.0.0:8000->8000/tcp
def456ghi789 neo4j:5.26.0 Up 31 seconds 0.0.0.0:7474->7474/tcp, 0.0.0.0:7687->7687/tcp
Step 2: Configure Environment¶
Set your OpenAI API key for embeddings:
# Option 1: Export in shell (temporary)
export OPENAI_API_KEY="sk-your-api-key-here"
# Option 2: Add to ~/.bashrc or ~/.zshrc (permanent)
echo 'export OPENAI_API_KEY="sk-your-api-key-here"' >> ~/.bashrc
source ~/.bashrc
# Option 3: Use .env file (project-specific)
echo "OPENAI_API_KEY=sk-your-api-key-here" > .env
Optional Configuration Overrides:
Graphiti uses .guardkit/graphiti.yaml for configuration. Override any setting via environment variables:
# Disable Graphiti temporarily
export GRAPHITI_ENABLED=false
# Change host/port (if running remotely)
export GRAPHITI_HOST=192.168.1.100
export GRAPHITI_PORT=8080
# Increase timeout for slow connections
export GRAPHITI_TIMEOUT=60.0
# Change config directory location
export GUARDKIT_CONFIG_DIR=/path/to/custom/config
Step 3: Verify Connection¶
Check that GuardKit can connect to Graphiti:
Expected output:
Graphiti Status
Enabled Yes
Host localhost
Port 8000
Timeout 30.0s
Checking connection...
Connection: OK
Health: OK
Seeded: No
Run 'guardkit graphiti seed' to seed system context.
If connection fails, see Troubleshooting: Connection Failed.
Step 4: Seed Knowledge¶
Graphiti knowledge seeding uses a two-phase architecture, each targeting a different scope:
Phase 1: Project Knowledge (automatic during guardkit init)¶
Project-specific knowledge is seeded automatically when you run guardkit init. This includes:
- Project overview extracted from
CLAUDE.md/README.md - Project name, purpose, and structure
This gives Graphiti enough context to assist with project-level tasks immediately after init.
Phase 2: System Knowledge (via guardkit graphiti seed-system or auto-offer)¶
System-scoped knowledge is shared across all GuardKit projects and includes:
- Templates, rules, and implementation patterns
- Role constraints (Player/Coach behaviors)
- Implementation modes and workflow definitions
- Agent definitions and command specifications
During guardkit init, after project knowledge is seeded, you will be prompted:
Answering Y (the default) seeds system knowledge immediately. If you skip it, you can seed later:
System knowledge is larger and takes longer to seed, which is why it runs as a separate phase. It only needs to be seeded once per FalkorDB instance — all projects sharing the same instance benefit from a single system seed.
Note: Use --force to re-seed:
Multi-Project FalkorDB Environments¶
When multiple projects share a FalkorDB instance, use --copy-graphiti during init to inherit infrastructure settings from an existing project:
This auto-discovers a parent project's .guardkit/graphiti.yaml and copies all connection and embedding settings, replacing only the project_id. This prevents embedding dimension mismatches when the shared FalkorDB was seeded with a specific embedding model.
For explicit source selection:
Without --copy-graphiti, projects fall back to defaults (neo4j graph store, OpenAI embeddings). If the actual infrastructure uses FalkorDB with a different embedding model, this causes dimension mismatches. --copy-graphiti is the recommended default for any multi-project environment sharing FalkorDB.
Step 5: Verify Seeding¶
Run test queries to verify knowledge was seeded correctly:
Expected output:
Graphiti Verification
Connecting to Graphiti at localhost:8000...
Connected
Running verification queries...
✓ What is GuardKit?
-> guardkit_product (score: 0.92)
-> quality_gates (score: 0.87)
✓ How to invoke task-work?
-> task-work_command (score: 0.94)
-> workflow_phases (score: 0.86)
✓ What are the quality phases?
-> phase_2_planning (score: 0.91)
-> phase_4_testing (score: 0.89)
✓ What is the Player-Coach pattern?
-> player_agent (score: 0.93)
-> coach_agent (score: 0.90)
✓ How to use SDK vs subprocess?
-> adr-fb-001 (score: 0.95)
-> sdk_usage (score: 0.88)
Results: 5 passed, 0 failed
Verification complete!
If queries fail, see Troubleshooting: No Context in Sessions.
Step 6 (Optional): Enable MCP Access for Claude Code Sessions¶
To make Graphiti directly accessible during Claude Code sessions (via mcp__graphiti__* tools),
add the Graphiti MCP server to your project's .mcp.json.
Prerequisites¶
uvinstalled:pip install uvorbrew install uv- FalkorDB reachable (see Step 3)
Add the MCP Server Block¶
Create or update .mcp.json in your project root:
{
"mcpServers": {
"graphiti": {
"command": "uvx",
"args": [
"--from", "graphiti-core[falkordb]",
"graphiti-service",
"--transport", "stdio",
"--group-id", "your-project-id"
],
"env": {
"FALKORDB_HOST": "whitestocks",
"FALKORDB_PORT": "6379",
"OPENAI_API_KEY": "not-used",
"LLM_BASE_URL": "http://promaxgb10-41b1:8000/v1",
"LLM_MODEL": "neuralmagic/Qwen2.5-14B-Instruct-FP8-dynamic",
"EMBEDDER_BASE_URL": "http://promaxgb10-41b1:8001/v1",
"EMBEDDER_MODEL": "nomic-embed-text-v1.5"
}
}
}
}
Replace your-project-id with your project_id from .guardkit/graphiti.yaml.
Replace FALKORDB_HOST, LLM_BASE_URL, EMBEDDER_BASE_URL, and EMBEDDER_MODEL to
match your infrastructure.
If you already have a
.mcp.json(for Context7, Design Patterns, etc.), add only the"graphiti"key to the existingmcpServersobject.
Restart Claude Code¶
After saving .mcp.json, restart Claude Code. If the MCP server starts successfully, you
will see mcp__graphiti__search_nodes and related tools in your session.
Verify MCP Access¶
In a Claude Code session, the tools should appear:
If the tools don't appear, check Claude Code's MCP output panel (View → Output → MCP Logs) for startup errors.
Important: Embedding Model Must Match¶
The EMBEDDER_MODEL in .mcp.json must match the embedding_model in
.guardkit/graphiti.yaml. Mismatched models cause vector dimension errors when writing
new knowledge via MCP.
See: Graphiti Claude Code Integration Guide for complete MCP setup, group ID reference, and troubleshooting.
Configuration File Reference¶
Automatic Creation¶
The .guardkit/graphiti.yaml file is automatically created when you run guardkit init:
The file includes a project_id field that is auto-generated from the current directory name. This ID is used for project namespace prefixing to isolate knowledge between projects sharing a Graphiti instance.
Configuration Reference¶
The complete .guardkit/graphiti.yaml configuration file:
# Graphiti Knowledge Graph Configuration
#
# All settings can be overridden via environment variables:
# - GRAPHITI_ENABLED: Enable/disable integration
# - GRAPHITI_HOST: Server hostname
# - GRAPHITI_PORT: Server port
# - GRAPHITI_TIMEOUT: Connection timeout in seconds
# - GUARDKIT_PROJECT_ID: Override project_id
#
# To start Graphiti services:
# docker compose -f docker/docker-compose.graphiti.yml up -d
# Enable Graphiti integration (set to false to disable)
enabled: true
# Project identifier for namespace prefixing
# Auto-generated from directory name during 'guardkit init'
# Used to isolate project knowledge in shared Graphiti instances
project_id: my-project
# Graphiti server connection settings
host: localhost
port: 8000
timeout: 30.0
# OpenAI embedding model for semantic search
# Requires OPENAI_API_KEY environment variable
embedding_model: text-embedding-3-small
# Group IDs for organizing knowledge
# These create separate namespaces in the knowledge graph
group_ids:
- product_knowledge # Domain concepts, entities, relationships
- command_workflows # GuardKit command patterns and usage
- architecture_decisions # ADRs and design rationale
Alternative LLM Providers (vLLM, Ollama)¶
You can use vLLM or Ollama instead of OpenAI. When using alternative providers, OPENAI_API_KEY is not required — GuardKit injects custom LLM/embedding clients that bypass the OpenAI constructor.
# .guardkit/graphiti.yaml - vLLM example
llm_provider: vllm
llm_base_url: http://your-vllm-host:8000/v1
llm_model: your-model-name
embedding_provider: vllm
embedding_base_url: http://your-vllm-host:8001/v1
embedding_model: your-embedding-model
Group ID Scoping¶
Knowledge groups have two scopes. See Project Namespaces for details.
- System groups (shared, unprefixed):
role_constraints,quality_gate_configs,implementation_modes,guardkit_templates,guardkit_patterns - Project groups (auto-prefixed with
{project_id}__):project_overview,project_architecture,feature_specs,project_decisions,project_constraints,domain_knowledge
When querying, use unprefixed group names — the client applies the correct prefix automatically.
Configuration Priority (highest to lowest):
1. Environment variables (GRAPHITI_ENABLED, GRAPHITI_HOST, etc.)
2. YAML configuration file (.guardkit/graphiti.yaml)
3. Default values (enabled, localhost:8000, 30s timeout)
Environment Variable Override Patterns:
| Setting | Environment Variable | Type | Example |
|---|---|---|---|
enabled |
GRAPHITI_ENABLED |
bool | true, false, 1, 0 |
host |
GRAPHITI_HOST |
string | localhost, 192.168.1.100 |
port |
GRAPHITI_PORT |
int | 8000, 9000 |
timeout |
GRAPHITI_TIMEOUT |
float | 30.0, 60.0 |
Troubleshooting¶
Connection Failed¶
Symptom: guardkit graphiti status shows "Connection: Failed"
Causes & Solutions:
-
Docker containers not running:
-
Port conflicts (another service using 7474, 7687, or 8000):
-
Container health check failing:
-
Network issues:
Seeding Errors¶
Symptom: guardkit graphiti seed fails with error
Common errors:
-
"OPENAI_API_KEY not set":
-
"Connection timeout":
-
"Already seeded":
-
"Permission denied" or "Cannot write to .guardkit/":
No Context in Sessions¶
Symptom: Queries return no results or Graphiti doesn't seem to provide context
Verification steps:
- Check seeding status:
Should show "Seeded: Yes (version X.Y.Z)"
- Run verbose verification:
Should show query results with scores
-
Manually test search:
from guardkit.knowledge.graphiti_client import GraphitiClient, GraphitiConfig from guardkit.knowledge.config import load_graphiti_config import asyncio async def test_search(): settings = load_graphiti_config() config = GraphitiConfig( enabled=settings.enabled, host=settings.host, port=settings.port, timeout=settings.timeout ) client = GraphitiClient(config) await client.initialize() results = await client.search( "What is GuardKit?", group_ids=["product_knowledge"], num_results=5 ) print(f"Found {len(results)} results") for r in results: print(f" - {r.get('name', 'unknown')}: {r.get('score', 0):.2f}") asyncio.run(test_search()) -
Re-seed if necessary:
Missing .guardkit/graphiti.yaml¶
Symptom: Graphiti commands fail or use defaults because configuration file is missing.
Cause: The .guardkit/graphiti.yaml file is created by guardkit init. If you set up your project manually or used an older version of GuardKit, this file may not exist.
Solution:
-
Run
guardkit init(recommended): -
Create manually:
Project ID: The project_id is auto-generated from the directory name (e.g., directory my-app produces project_id: my-app). This ID prefixes project-specific group IDs in Graphiti to enable multi-project isolation.
Common Error Messages¶
| Error | Meaning | Solution |
|---|---|---|
Connection refused |
Graphiti API not running | Start containers with docker compose up -d |
Name or service not known |
DNS resolution failed | Check host setting in config |
Timeout waiting for response |
Connection too slow | Increase timeout in config |
API key not found |
OPENAI_API_KEY not set | Export API key to environment |
Permission denied |
Cannot access config directory | Fix file permissions with chmod |
Invalid port number |
Port out of range (1-65535) | Check port setting in config |
Docker Compose Reference¶
Services Started¶
The docker-compose.graphiti.yml file starts one service:
Neo4j (Graph Database):
- Image: neo4j:5.26.0
- Container: guardkit-neo4j
- Ports: 7474 (HTTP/Browser), 7687 (Bolt protocol)
- Volumes: neo4j_data:/data, neo4j_logs:/logs (persistent storage)
- Plugins: APOC (utility procedures)
- Health Check: Cypher shell check every 10s
- Browser: http://localhost:7474
Note: The zepai/graphiti Docker REST API has been removed. GuardKit now uses the graphiti-core Python library directly for better error handling, full control over LLM token limits, and direct Neo4j communication without middleware.
Port Mappings¶
| Service | Container Port | Host Port | Purpose |
|---|---|---|---|
| Neo4j | 7474 | 7474 | HTTP/Browser interface |
| Neo4j | 7687 | 7687 | Bolt protocol (graphiti-core connection) |
Volume Persistence¶
Data is persisted in Docker named volumes, which survive container stops and restarts:
# View volumes
docker volume ls | grep neo4j
# Inspect Neo4j data volume
docker volume inspect docker_neo4j_data
Volume names: Docker Compose prefixes volume names with the project directory name (e.g., docker_neo4j_data when run from the docker/ directory). Use docker volume ls | grep neo4j to find the exact name.
For backup and restore procedures, see Backup & Restore below.
Container Management¶
View logs:
Stop services (preserves data):
Stop and remove volumes (clean slate):
Restart services:
Backup & Restore¶
GuardKit includes a backup script for Neo4j data at scripts/graphiti-backup.sh.
Backup Methods¶
| Method | Command | Best For | Cross-Version |
|---|---|---|---|
| Volume backup | backup / restore |
Local backups, same-machine restore | No (same Neo4j version) |
| Database dump | dump / load |
Migration to another server | Yes (across Neo4j 5.x) |
Quick Backup¶
# Volume backup (fast, for local use)
./scripts/graphiti-backup.sh backup
# Portable dump (for migration)
./scripts/graphiti-backup.sh dump
Backups are saved to ./backups/graphiti/ by default. Override with --output DIR or the BACKUP_DIR environment variable.
Restore¶
# Restore from volume backup
./scripts/graphiti-backup.sh restore backups/graphiti/neo4j-backup-20250205_120000.tar.gz
# Load from portable dump
./scripts/graphiti-backup.sh load backups/graphiti/neo4j-dump-20250205_120000.dump
# Verify after restore
./scripts/graphiti-backup.sh verify
List Backups¶
Verify Database¶
# Check Neo4j connectivity and node count
./scripts/graphiti-backup.sh verify
# Full GuardKit verification
guardkit graphiti status
guardkit graphiti verify --verbose
Important Notes¶
- The script automatically stops and restarts Neo4j as needed for consistent backups
- Always run
verifyafter a restore or load operation - Volume backups require the same Neo4j version; use
dump/loadfor cross-version migration - After restoring on a new machine, you may need to re-seed system knowledge:
guardkit graphiti seed --force
Migration Guide¶
Local to Remote Server (AWS, etc.)¶
To migrate your Neo4j knowledge graph to a remote server:
1. Create a portable dump on your local machine:
2. Copy the dump file to the remote server:
3. On the remote server, set up Neo4j:
# Clone/copy the GuardKit project
git clone <repo-url> guardkit
cd guardkit
# Start Neo4j
docker compose -f docker/docker-compose.graphiti.yml up -d
# Load the dump
./scripts/graphiti-backup.sh load backups/graphiti/neo4j-dump-*.dump
# Verify
./scripts/graphiti-backup.sh verify
4. Update GuardKit configuration on the remote server:
Edit .guardkit/graphiti.yaml or set environment variables:
export GRAPHITI_HOST=localhost # Or the server's address if connecting remotely
export GRAPHITI_PORT=8000 # Not applicable if using graphiti-core directly
Alternative: Re-seed Instead of Migrate¶
For system knowledge (GuardKit workflows, patterns, etc.), re-seeding is often simpler than migrating:
# On the new server
docker compose -f docker/docker-compose.graphiti.yml up -d
guardkit graphiti seed
guardkit graphiti verify
Re-seeding only recreates system knowledge. Project-specific context (ADRs, feature specs) would need to be re-added:
# Re-add project documentation
guardkit graphiti add-context CLAUDE.md
guardkit graphiti add-context docs/architecture/ --pattern "ADR-*.md"
guardkit graphiti add-context docs/features/ --pattern "FEATURE-SPEC-*.md"
Production Considerations¶
Security:
- Change the default Neo4j password (password123) in docker-compose.graphiti.yml
- Update the password in .guardkit/graphiti.yaml or via NEO4J_PASSWORD environment variable
- Restrict Neo4j ports (7474, 7687) to trusted networks using firewall rules
- Consider using Neo4j's built-in SSL/TLS for encrypted connections
Neo4j Aura (Managed Service):
For production deployments, consider Neo4j Aura instead of self-hosted Docker:
- Managed backups and scaling
- No Docker management overhead
- Update neo4j_uri in config to point to your Aura instance
Automated Backups:
# Add to crontab for daily backups at 2am
# crontab -e
0 2 * * * cd /path/to/guardkit && ./scripts/graphiti-backup.sh dump --output /path/to/backup/dir
Next Steps¶
Once Graphiti is set up and verified:
- Use in workflows: Graphiti automatically provides context during
/task-workand/feature-build - Enable MCP access: Add
.mcp.jsonconfiguration (Step 6) for interactive Claude Code access - Seed system knowledge: Run
guardkit graphiti seed-systemto load GuardKit workflow knowledge - Capture project knowledge: Run
guardkit graphiti capture --interactiveto add project context - Disable if needed: Set
GRAPHITI_ENABLED=falseto temporarily disable
Related Documentation: - Graphiti Claude Code Integration - MCP access setup and configuration - Graphiti Integration Guide - Full integration overview - Graphiti Shared Infrastructure - Multi-project FalkorDB setup - Graphiti Project Namespaces - Project isolation deep-dive