Skip to content

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:

docker --version        # Should show 20.10.0 or later
docker compose version  # Should show 2.0.0 or later


Installation Steps

Step 1: Start Graphiti Services

Start the Neo4j graph database and Graphiti API server using Docker Compose:

# From your GuardKit project directory
docker compose -f docker/docker-compose.graphiti.yml up -d

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:

docker ps

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:

guardkit graphiti status

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:

Seed system knowledge now? (recommended for AutoBuild) [Y/n]:

Answering Y (the default) seeds system knowledge immediately. If you skip it, you can seed later:

guardkit graphiti seed-system

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:

guardkit graphiti seed-system --force

Multi-Project FalkorDB Environments

When multiple projects share a FalkorDB instance, use --copy-graphiti during init to inherit infrastructure settings from an existing project:

guardkit init --copy-graphiti

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:

guardkit init --copy-graphiti-from /path/to/parent/project

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:

guardkit graphiti verify --verbose

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

  • uv installed: pip install uv or brew 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 existing mcpServers object.

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:

Available tools: mcp__graphiti__search_nodes, mcp__graphiti__search_memory_facts, ...

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:

guardkit init fastapi-python
# Creates .guardkit/graphiti.yaml with default settings

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:

  1. Docker containers not running:

    # Check container status
    docker ps
    
    # Restart containers if stopped
    docker compose -f docker/docker-compose.graphiti.yml up -d
    

  2. Port conflicts (another service using 7474, 7687, or 8000):

    # Check what's using the ports
    lsof -i :7474
    lsof -i :7687
    lsof -i :8000
    
    # Change ports in docker-compose.graphiti.yml
    # Then restart containers
    docker compose -f docker/docker-compose.graphiti.yml down
    docker compose -f docker/docker-compose.graphiti.yml up -d
    

  3. Container health check failing:

    # View container logs
    docker compose -f docker/docker-compose.graphiti.yml logs -f
    
    # Look for error messages
    docker logs guardkit-graphiti
    docker logs guardkit-neo4j
    

  4. Network issues:

    # Recreate network
    docker compose -f docker/docker-compose.graphiti.yml down
    docker compose -f docker/docker-compose.graphiti.yml up -d
    


Seeding Errors

Symptom: guardkit graphiti seed fails with error

Common errors:

  1. "OPENAI_API_KEY not set":

    # Verify API key is set
    echo $OPENAI_API_KEY
    
    # If empty, export it
    export OPENAI_API_KEY="sk-your-api-key-here"
    

  2. "Connection timeout":

    # Increase timeout in config or via env var
    export GRAPHITI_TIMEOUT=60.0
    
    # Retry seeding
    guardkit graphiti seed --force
    

  3. "Already seeded":

    # Force re-seeding (overwrites existing data)
    guardkit graphiti seed --force
    

  4. "Permission denied" or "Cannot write to .guardkit/":

    # Check directory permissions
    ls -la .guardkit/
    
    # Fix permissions if needed
    chmod 755 .guardkit/
    


No Context in Sessions

Symptom: Queries return no results or Graphiti doesn't seem to provide context

Verification steps:

  1. Check seeding status:
    guardkit graphiti status
    

Should show "Seeded: Yes (version X.Y.Z)"

  1. Run verbose verification:
    guardkit graphiti verify --verbose
    

Should show query results with scores

  1. 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())
    

  2. Re-seed if necessary:

    guardkit graphiti seed --force
    


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:

  1. Run guardkit init (recommended):

    guardkit init
    # Creates .guardkit/graphiti.yaml with project_id from directory name
    

  2. Create manually:

    mkdir -p .guardkit
    cat > .guardkit/graphiti.yaml << 'EOF'
    enabled: true
    project_id: my-project-name
    host: localhost
    port: 8000
    timeout: 30.0
    embedding_model: text-embedding-3-small
    EOF
    

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:

docker compose -f docker/docker-compose.graphiti.yml logs -f
docker logs guardkit-neo4j -f

Stop services (preserves data):

docker compose -f docker/docker-compose.graphiti.yml down

Stop and remove volumes (clean slate):

docker compose -f docker/docker-compose.graphiti.yml down -v

Restart services:

docker compose -f docker/docker-compose.graphiti.yml restart


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

./scripts/graphiti-backup.sh list

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 verify after a restore or load operation
  • Volume backups require the same Neo4j version; use dump/load for 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:

./scripts/graphiti-backup.sh dump

2. Copy the dump file to the remote server:

scp backups/graphiti/neo4j-dump-*.dump user@remote-server:/path/to/guardkit/backups/graphiti/

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:

  1. Use in workflows: Graphiti automatically provides context during /task-work and /feature-build
  2. Enable MCP access: Add .mcp.json configuration (Step 6) for interactive Claude Code access
  3. Seed system knowledge: Run guardkit graphiti seed-system to load GuardKit workflow knowledge
  4. Capture project knowledge: Run guardkit graphiti capture --interactive to add project context
  5. Disable if needed: Set GRAPHITI_ENABLED=false to 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