Grapha
Blazingly fast code intelligence that gives AI agents compiler-grade understanding of your codebase.
Grapha builds a symbol-level dependency graph from source code — not by guessing with regex, but by reading the compiler's own index. For Swift, it taps directly into Xcode's pre-built index store via binary FFI for 100% type-resolved symbols, then enriches with tree-sitter for view structure, docs, and localization. For Rust, it uses tree-sitter with Cargo workspace awareness. The result is a queryable graph with confidence-scored edges, dataflow tracing, impact analysis, and code smell detection — available as both a CLI and an MCP server for AI agent integration.
1,991 Swift files — 131K nodes — 784K edges — 8.7 seconds. Zero-copy binary FFI. Lock-free parallel extraction. No serde on the hot path.
Why Grapha
| Grapha | |
|---|---|
| Parsing | Compiler index store (confidence 1.0) + tree-sitter fallback |
| Relationship types | 10 (calls, reads, writes, publishes, subscribes, inherits, implements, contains, type_ref, uses) |
| Dataflow tracing | Forward (entry → terminals) + reverse (symbol → entries) |
| Code quality | Complexity analysis, smell detection, module coupling metrics |
| Confidence scores | Per-edge 0.0–1.0 |
| Terminal classification | Auto-detects network, persistence, cache, event, keychain, search |
| MCP tools | 11 |
| Watch mode | File watcher with debounced incremental re-index |
| Recall | Session disambiguation — ambiguous symbols auto-resolve after first use |
Performance
Benchmarked on a production iOS app (1,991 Swift files, ~300K lines):
| Phase | Time |
|---|---|
| Extraction (index store + tree-sitter enrichment) | 3.5s |
| Merge (module-aware cross-file resolution) | 0.3s |
| Classification (entry points + terminals) | 1.7s |
| SQLite persistence (deferred indexing) | 2.0s |
| Search index (BM25 via tantivy) | 1.0s |
| Total | 8.7s |
Graph: 131,185 nodes · 783,793 edges · 2,983 entry points · 11,149 terminal operations
Why it's fast: zero-copy index store FFI via pointer arithmetic (no serde), lock-free rayon extraction, single shared tree-sitter parse, marker-based enrichment skip, deferred SQLite indexing, USR-scoped edge resolution. Run grapha index --timing for a per-phase breakdown.
Install
Quick Start
# Index a project (incremental by default)
# Search symbols
# 360° context — callers, callees, reads, implements
# Impact analysis — what breaks if this changes?
# Complexity analysis — structural health of a type
# Dataflow: entry point → terminal operations
# Reverse: which entry points reach this symbol?
# Code smell detection
# Module metrics — symbol counts, coupling ratios
# MCP server for AI agents (with auto-refresh)
MCP Server — 11 Tools for AI Agents
Add to .mcp.json:
| Tool | What it does |
|---|---|
search_symbols |
BM25 search with kind/module/role/fuzzy filters |
get_symbol_context |
360° view: callers, callees, reads, implements, contains tree |
get_impact |
BFS blast radius at configurable depth |
trace |
Forward dataflow to terminals, or reverse to entry points |
get_file_symbols |
All declarations in a file, by source position |
batch_context |
Context for up to 20 symbols in one call |
analyze_complexity |
Structural metrics + severity rating for any type |
detect_smells |
Code smell scan scoped to the repo, a module, a file, or a symbol |
get_module_summary |
Per-module metrics with cross-module coupling ratio |
get_file_map |
File/symbol map organized by module and directory |
reload |
Hot-reload graph from disk without restarting the server |
Recall: The MCP server remembers symbol resolutions within a session. If helper is ambiguous the first time, after you disambiguate with File.swift::helper, future bare helper queries resolve automatically.
Commands
Symbols
Dataflow
Repository
Indexing & Serving
Localization & Assets
Configuration
Optional grapha.toml at project root:
[]
= true # false → tree-sitter only
[]
= ["file", "module"]
[[]]
= "FrameUI"
= "/path/to/local/frameui" # include in cross-repo analysis
[[]]
= "FirebaseFirestore.*setData"
= "persistence"
= "write"
= "set"
Architecture
grapha-core/ Shared types (Node, Edge, Graph, ExtractionResult)
grapha-swift/ Swift: index store → SwiftSyntax → tree-sitter waterfall
grapha/ CLI, Rust extractor, query engines, MCP server, web UI
nodus/ Agent tooling package (skills, rules, commands)
Extraction Waterfall (Swift)
Xcode Index Store (binary FFI) → compiler-resolved USRs, confidence 1.0
↓ fallback
SwiftSyntax (JSON FFI) → accurate parse, no type resolution, confidence 0.9
↓ fallback
tree-sitter-swift (bundled) → fast, limited accuracy, confidence 0.6–0.8
After index store extraction, tree-sitter enriches doc comments, SwiftUI view hierarchy, and localization metadata in a single shared parse.
Graph Model
14 node kinds: function, struct, enum, trait, protocol, extension, property, field, variant, constant, type_alias, impl, module, view, branch
10 edge kinds: calls, implements, inherits, contains, type_ref, uses, reads, writes, publishes, subscribes
Dataflow annotations: direction (read/write/pure), operation (fetch/save/publish), condition, async_boundary, provenance (source file + span)
Node roles: entry_point (SwiftUI View, @Observable, fn main, #[test]) · terminal (network, persistence, cache, event, keychain, search)
Nodus Package
Installs skills, rules, and slash commands (/index, /search, /impact, /complexity, /smells) for grapha-aware AI workflows.
Supported Languages
| Language | Extraction | Type Resolution |
|---|---|---|
| Swift | Index store + tree-sitter | Compiler-grade (USR) |
| Rust | tree-sitter | Name-based |
The per-language crate architecture supports adding new languages with the same waterfall pattern: compiler index → syntax parser → tree-sitter fallback.
Development
&&
License
MIT