Skip to content

rohansx/ctxgraph

Repository files navigation

ctxgraph

Privacy-first knowledge graph engine for AI agents.

Extracts entities and relations from any text. Builds a temporal knowledge graph. Works locally with zero API keys — and when it does call an LLM, it makes one call per episode instead of Graphiti's six.

brew install rohansx/tap/ctxgraph
ctxgraph init && ctxgraph models download
ctxgraph log "Migrated auth from Redis sessions to JWT. Chose JWT for stateless scaling."
ctxgraph query "Why did we move away from Redis?"

Why ctxgraph?

Every knowledge graph engine requires an LLM for every operation. Graphiti makes 6 API calls per episode. Mem0 calls GPT-4 on every add/search. Microsoft GraphRAG is so expensive they put a cost warning in their README.

ctxgraph runs a tiered extraction pipeline: local ONNX models handle most episodes at zero cost, and only escalates to an LLM when local confidence is low. One call, not six. PII stripped before it leaves your machine.

Validated on 20 unseen episodes across 12 domains:

ctxgraph Graphiti Mem0 LightRAG
Combined F1 0.678 0.287 N/A (no KG eval) N/A (RAG, no KG)
Entity F1 0.854 0.468
Relation F1 0.502 0.106
LLM calls per episode 1 6 1-2 1+
Works without LLM? Yes No No No
Works offline? Yes No No Partial
Query latency <15ms ~300ms ~100ms ~200ms
Infrastructure SQLite Neo4j+Docker Vector DB Varies
Language Rust Python Python Python
Privacy (PII protection) CloakPipe (feature flag) None None None

How It Works

Text comes in
    |
    v
[Tier 1] GLiNER entities + GLiREL relations (local ONNX, FREE, ~10ms)
    |
    v
Confidence gate: good enough?
    |
    +-- YES (tech text, ~70%) --> Graph. Done. $0.
    |
    +-- NO (cross-domain)    --> [CloakPipe strips PII] --> LLM (1 call) --> Graph.
Tier What Cost Latency
Local ONNX GLiNER (entities) + GLiREL (relations) $0 ~10ms
LLM fallback One call for entities + relations when local isn't confident ~$0.0003/ep ~3-5s
Dedup Jaro-Winkler similarity + alias table (local) $0 <1ms
Search FTS5 + semantic + graph walk, fused via RRF (local) $0 <15ms

Graphiti does ALL of these via LLM: entity extraction, deduplication, relation extraction, contradiction detection, summarization, community detection. Six calls. Every episode.


Competitive Landscape

Knowledge Graph Engines

ctxgraph Graphiti Cognee WhyHow.AI
Extraction Local ONNX + LLM fallback LLM only (6 calls/ep) LLM only LLM only (OpenAI)
Graph DB SQLite (embedded) Neo4j/FalkorDB Neo4j/Kuzu MongoDB Atlas
Works offline? Yes No No No
Temporal queries Bi-temporal Bi-temporal No No
MCP support Yes Yes Yes No
Language Rust (single binary) Python Python Python
Schema-driven Yes (ctxgraph.toml) Yes (prescribed ontology) Yes Yes
Cost/1000 eps $0.30 $1.80 ~$1.50 ~$2+
Stars Early 24K 15K 900

Agent Memory Systems

ctxgraph Mem0 Basic Memory mcp-memory-service
Entity extraction Automated (ONNX+LLM) LLM-only None (manual) None (manual)
Relation extraction Automated (GLiREL+LLM) Limited None Manual typed edges
Knowledge graph Yes (temporal) Optional (Neptune) Semantic links Basic typed edges
Works without LLM? Yes No Yes Yes
Query latency <15ms ~100ms ~10ms ~5ms
Dedup Jaro-Winkler + aliases LLM-based None None
Cost $0 (local) / $0.30 (hybrid) LLM cost per op $0 $0
Stars Early 51K 2.7K 1.6K

Graph-Enhanced RAG

ctxgraph LightRAG Microsoft GraphRAG nano-graphrag
Purpose Knowledge graph engine RAG retrieval Document summarization Lightweight GraphRAG
Incremental updates Yes Yes No (batch only) No
Temporal awareness Yes (bi-temporal) No No No
LLM per query No Yes Yes Yes
Offline capable Yes Partial (Ollama) No Partial
Cost/1000 docs $0.30 ~$1-5 ~$10-50 ~$1-5
Stars Early 31K 32K 3.8K

What Makes ctxgraph Unique

No other tool has all of these:

  1. Automated extraction that works offline — GLiNER + GLiREL via ONNX. Mem0 and Basic Memory have no extraction. Graphiti/Cognee/LightRAG always need an LLM.
  2. Typed relations, not free-form — Graphiti produces SWITCHED_TO, CAUSED_OOM_KILLS. ctxgraph produces replaced, caused — queryable by type.
  3. Bi-temporal history — Only ctxgraph and Graphiti have this. Every other tool is current-state only.
  4. PII protection — CloakPipe strips PII before LLM calls (--features cloakpipe). No competitor offers this.
  5. Single Rust binary — Every competitor is Python with pip/Docker/Neo4j. ctxgraph is cargo install.
  6. 6x fewer LLM calls — 1 call vs Graphiti's 6. Same model, better results.

Validated Benchmark

Tested on 20 completely new episodes across 12 domains. Both systems use GPT-4o-mini. Neither system has seen this data before.

Overall Results

Graphiti ctxgraph
Entity F1 0.468 0.854
Relation F1 0.106 0.502
Combined F1 0.287 0.678
Time/episode 18.2s 5.1s
LLM calls (20 eps) ~120 20

Per-Domain (ctxgraph scores)

Domain Entity F1 Relation F1 Combined
Tech (Slack, PRs, ADRs, incidents) 0.877 0.530 0.703
Finance 0.769 0.600 0.685
Healthcare 0.909 0.286 0.598
Legal 0.857 0.500 0.679
Manufacturing 0.667 0.333 0.500
Education 0.667 0.286 0.477
Real Estate 1.000 0.667 0.834
E-commerce 0.800 0.500 0.650
Logistics 0.889 0.667 0.778
Gaming 1.000 1.000 1.000
Government 0.909 0.000 0.455

LLM Model Comparison (cross-domain)

LLM Hostable locally? Cross-domain F1 Cost/1000 eps
None (local only) N/A 0.325 $0
Llama 3.2 3B (Ollama) Yes (8GB) 0.472 $0
Qwen 2.5 7B (Ollama) Yes (16GB) 0.508 $0
GPT-4o-mini Cloud 0.650 $0.30
Claude 3.5 Haiku Cloud 0.611 $0.09
Gemini 2.0 Flash Cloud 0.552 $0.05

Query Performance

ctxgraph Graphiti
Full-text search <1ms ~50ms
Semantic search 3-5ms ~100ms
Graph traversal (2-3 hops) <5ms 5-50ms
Fused search (RRF) <15ms ~300ms

Key Features

  • Tiered extraction — Local ONNX first, LLM only when needed
  • Privacy — CloakPipe strips PII before cloud LLM calls (enable with --features cloakpipe)
  • Zero infrastructure — One binary, one SQLite file
  • Any LLM — Ollama, NVIDIA NIM (free), OpenRouter, OpenAI, Anthropic
  • Bi-temporal — Time-travel queries, fact invalidation
  • Schema-driven — Entity/relation types via ctxgraph.toml
  • MCP server — Claude Code, Cursor, Cline, any MCP client
  • Embeddable — Rust library, CLI, or MCP server
  • Entity dedup — Jaro-Winkler + alias table across episodes

Installation

# Homebrew
brew install rohansx/tap/ctxgraph

# Or build from source (Rust 1.85+)
cargo install ctxgraph-cli

Quick Start

ctxgraph models download              # one-time ONNX model download
ctxgraph init                         # initialize graph in current dir
ctxgraph log "Alice chose PostgreSQL"  # extract + store
ctxgraph query "why PostgreSQL?"       # search the graph

Optional: LLM for cross-domain quality

# ctxgraph.toml
[llm]
provider = "openrouter"
[llm.openrouter]
model = "openai/gpt-4o-mini"
api_key_env = "OPENROUTER_API_KEY"

[privacy]
# Enable PII stripping: cargo install ctxgraph-cli --features cloakpipe

Without this, everything runs locally at 0.846 F1 on tech text.


MCP Server

{
  "mcpServers": {
    "ctxgraph": { "command": "ctxgraph-mcp" }
  }
}
Tool Description
ctxgraph_add_episode Record a decision or event
ctxgraph_search Fused FTS5 + semantic + graph search
ctxgraph_traverse Walk the graph from an entity
ctxgraph_find_precedents Find similar past events
ctxgraph_list_entities List entities with filters
ctxgraph_export_graph Export entities and edges

Rust SDK

let graph = ctxgraph::Graph::init(".ctxgraph")?;
graph.add_episode(Episode::builder("Chose Postgres for billing").build())?;
let results = graph.search("why Postgres?", 10)?;

Project Structure

crates/
+-- ctxgraph-core/       Types, storage, query, temporal
+-- ctxgraph-extract/    Tiered extraction (ONNX + LLM)
+-- ctxgraph-embed/      Local embeddings
+-- ctxgraph-cli/        CLI binary
+-- ctxgraph-mcp/        MCP server
+-- ctxgraph-sdk/        Rust SDK

Contributing

See CONTRIBUTING.md.

License

MIT