Aletheia: Weekend Sprint Report¶
Period: February 6-8, 2026 Author: David Morales
Executive Summary¶
Over a three-day sprint, we transformed Aletheia's LLM-accessible interface from a basic search tool into a full analytics platform. We forked our core dependency (Graphiti) to gain control over release cadence and quality, integrated 16 community bug fixes and features, built a Cypher query engine for direct graph analytics, and made every connector self-describing so that LLMs understand each domain's data without manual prompting.
What Changed and Why It Matters¶
1. Independence from upstream release cycles¶
We created and maintain our own fork of Graphiti. Previously, bug fixes required waiting for the upstream maintainer's release schedule (weeks to months). We now control when fixes ship. We also built a repeatable process (codified as a Claude Code skill) for pulling future upstream improvements.
2. LLMs can now do analytics, not just search¶
Before this sprint, LLMs connected to our knowledge graphs could only perform semantic search -- "find entities similar to X." Now they can run structured Cypher queries against the graph ("count all sanctions by jurisdiction," "find the shortest path between two entities"), inspect the graph schema, and combine search with analytics in multi-step workflows. A four-stage security pipeline ensures all queries are read-only.
3. Connectors describe themselves¶
Each MCP connector now introspects its own graph at startup and generates domain-specific tool descriptions, entity catalogs, and example queries. An LLM connecting to the Aviation Safety graph sees aviation-specific guidance; the same code connecting to Terrorist Organizations sees sanctions-specific guidance. This eliminates the need for manual prompt engineering per domain.
4. Quality hardened across multiple domains¶
We ran the full pipeline against our richest dataset (Operation Tango: 491 records, 18 entity schemas, 3 sanctions jurisdictions) and fixed 12 issues in entity extraction, deduplication, and edge resolution. These fixes benefit all current and future use cases.
Delivery Metrics¶
| Before | After | |
|---|---|---|
| LLM-accessible tools per connector | 3 | 13 |
| Query capabilities | Semantic search only | Search + Cypher analytics + schema introspection |
| Test coverage (MCP server) | ~40 tests | 175 tests |
| Upstream dependency | PyPI releases (uncontrolled) | Maintained fork (controlled) |
| Connector setup per domain | Manual prompt engineering | Automatic self-description |
| Documentation | None for MCP | Landing page + 2,500-word reference |
Risks and Next Steps¶
- Fork maintenance: We now own the merge burden. The upstream-fork-sync skill mitigates this but periodic syncs require attention.
- Cypher security: The whitelist-based security gate is conservative by design. Edge cases from production LLM queries will grow the regression test suite organically.
- Integration testing: Cypher tools have unit tests and stubs but no live FalkorDB integration tests yet. These should be added before any production deployment.
Full Technical Report¶
Context¶
Coming into Friday, Aletheia was running on upstream graphiti-core from PyPI and had 6 use cases (anticorruption, terrorist_orgs, aviation_safety, safety_recommendations, airworthiness_directives, operation_tango). The MCP server was the stock Graphiti one with minimal search tools. Schema inference had grown to include Phase 4 consolidation but was still hitting LLM non-determinism issues.
1. Create the Aletheia-Graphiti Fork¶
Why: Upstream Graphiti had 20+ open PRs with fixes we needed, plus we had our own fixes that couldn't go upstream (prompt changes, FalkorDB-specific edge type handling). Running on PyPI releases meant waiting months for bug fixes.
What we did: - Forked getzep/graphiti to david-morales/aletheia-graphiti (branch: aletheia) - Pointed aletheia's dependency at the fork with force-reinstall workflow - Versioned as 0.27.0rc2 to stay ahead of upstream releases
2. Analyze Open PRs and Cherry-Pick the Best¶
What we did: Analyzed all ~25 open PRs on getzep/graphiti, triaged for relevance, and cherry-picked 16 upstream PRs into our fork:
| Category | PRs | Examples |
|---|---|---|
| Bug fixes | 7 | FalkorDB driver clone (#1170), community flatten (#1085), label propagation cap (#1086), empty group_ids guard (#816), max_tokens respect (#764), GC task refs (#1176), edge signature preservation (#1197) |
| Features | 5 | Inline attribute extraction (#1131), edge dedup prompt (#1102), orphan node cleanup (#1130), summary embedding search (#1163), entity summary from episode (#1196) |
| Performance | 2 | Batch community projection (N+1 fix), deduplicate BFS results |
| Infra | 2 | Exponential backoff for rate limiting, FalkorDB fulltext sanitization (#1183, #1175) |
Created the upstream-fork-sync skill (~/.claude/skills/upstream-fork-sync/) to systematize this process for future syncs: discover new PRs, triage what's integrated, plan cherry-picks with human approval, execute with TDD.
3. Revamp the MCP Server (Complete Overhaul)¶
Before: Stock Graphiti MCP with search_nodes, search_memory_facts, get_entity_edge -- three narrow tools with no ontology awareness, no Cypher, no schema introspection.
After: 6 main tools + 7 secondary tools, fully self-describing per domain. ~80 commits on the fork.
3a. Tool Surface Redesign (Feb 7)¶
- Unified
searchtool replacing 3 separate ones -- supports node, edge, and community search in one call with configurablesearch_mode,reranker,source,depth explore_node-- entity-centric graph exploration with BFS traversalget_episode_contextandbuild_communities-- new tools- Bulk episode ingestion added to
add_memory - Tightened schemas with
Literaltypes, added YAML-configurable search defaults - 40+ unit tests for the new tools
3b. Ontology Graph Integration (Feb 8)¶
search_ontology+explore_ontology-- same patterns as KG tools but against a companion ontology graph- Config field
ontology_graphconnects each KG server to its ontology - Dynamic server naming:
mcp._mcp_server.name = f'Graphiti - {group_id}'
3c. Self-Describing Connectors via DomainProfile (Feb 8)¶
DomainProfiledataclass auto-discovers entity types, edge types, counts, and samples from the graph at startup- Enriches descriptions from ontology graph if configured
- 3 MCP resources:
graphiti://domain_summary,graphiti://entity_catalog,graphiti://relationship_types - Dynamic tool descriptions generated from profile (each domain gets custom search examples, entity type lists)
- Graceful fallback: static docstrings if introspection fails
- Reasoning-style "When to use / When NOT to use" docstrings for all tools
3d. Layered Config (Feb 8)¶
base:key in YAML overlay loads and deep-merges a shared config- Shared base config (
mcp-base-config.yaml) in aletheia with LLM, embedder, database, transport - 4 domain-specific overlays in aletheia
use_cases/<name>/mcp_config.yaml
3e. Cypher Analytics Pipeline (Feb 8) -- 13-task plan executed with subagent-driven development¶
get_schema-- structural schema discovery with dirty-flag cache (invalidated on all data-modifying operations)run_cypher-- read-only Cypher viaGRAPH.RO_QUERYwith 4-stage validation pipeline:- Stage 1: LLM syntax fixups (smart quotes, code blocks, identifier quoting, RETURN injection)
- Stage 2: FalkorDB dialect (reject APOC/pattern comprehensions/EXISTS{}, auto-fix date→string/toLower)
- Stage 3: Security whitelist (fail-safe, only known read-only keywords allowed)
- Stage 4: Safety injection (LIMIT N+1 for truncation detection)
- Typed result envelopes (scalar, tabular, graph, path formats)
format_error()with stage/reason/explanation/suggestion/doc_hint- 95 unit tests + 3 integration stubs + 1 regression fixture = 175 total MCP tests
4. Debug and Harden the Fork Across Use Cases¶
Ran operation_tango (491 records, 18 FTM schemas) and aviation_safety use cases against the fork. Found and fixed 12 issues in graphiti-core:
| Area | Fix | Impact |
|---|---|---|
| Node dedup | Exact name match before entropy gate | Prevented false merges of similar entity names |
| Node dedup | Containment matching for duplicate_name | Fixed partial name resolution failures |
| Node dedup | Same-batch cross-referencing | Entities in same batch now reference each other |
| Node dedup | Case-insensitive matching | "SPAIN" = "Spain" during dedup |
| Edge extraction | Removed pair pre-assignment | Stopped silently dropping valid edges |
| Edge extraction | Case-insensitive name resolution | Entity lookup no longer case-sensitive |
| Edge extraction | Constrain to schema-defined types | Eliminated non-deterministic type naming (HAS_OPERATOR vs OPERATED_BY) |
| Entity extraction | Reverted attributes field | Inline attributes broke downstream processing |
| Entity extraction | Disabled content chunking | Chunking split context needed for entity naming |
| Entity extraction | Entity type descriptions in dedup | Consistent metadata context across pipeline |
| Custom edge types | FalkorDB support in BFS, fulltext, entity queries | Custom edge types actually work now |
| Prompt engineering | Reverted "canonical names" experiment | Too aggressive, stripped ICAO codes |
5. Schema Inference Improvements (Aletheia-side)¶
| Feature | What |
|---|---|
| Non-reified relationship extraction | Object properties in ontology now extracted as relationship types |
| Hyphenated type sanitization | Auto-strips hyphens for Cypher compatibility |
| Data-driven pruning | Removes types not in parser's schema_distribution |
| Phase 4 consolidation | Directive hints for committed relationships + LLM-based type consolidation |
| CoerciveBaseModel | Fixes LLM scalar/list type mismatches in schemas |
| Enriched entity type docstrings | Property summaries from ontology flow to extraction AND dedup prompts |
6. Update Documentation¶
- MCP landing page (
docs/mcp/index.md) -- connector table, overview - MCP connectors reference (
docs/mcp/connectors.md, ~2500 words) -- comparison tables (Graphiti stock vs Aletheia), capability matrix, self-describing connector architecture, tool reference, Cypher pipeline with Mermaid diagram, FalkorDB dialect cheatsheet, cross-graph workflow patterns, performance data - GraphRAG-SDK comparison (
docs/comparisons/graphrag-sdk.md) -- functional comparison of ontology approaches - Updated
mkdocs.ymlnav anddocs/index.mdfeature table - Build verified with
mkdocs build --strict, deployed to Netlify
By the Numbers¶
| Metric | Count |
|---|---|
| Commits (graphiti fork) | ~80 |
| Commits (aletheia) | 14 |
| Upstream PRs cherry-picked | 16 |
| MCP tools (before → after) | 3 → 13 |
| MCP tests (before → after) | ~40 → 175 |
| Core bug fixes | 12 |
| New skills created | 1 (upstream-fork-sync) |
| Documentation pages | 3 new + 2 updated |