DEV Community

Cover image for Graphify: AST-Based Knowledge Graphs for Agent Code Navigation
mech.app
mech.app

Posted on Originally published at mech.app

Graphify: AST-Based Knowledge Graphs for Agent Code Navigation

Agents need to navigate codebases, SQL schemas, and documentation to answer questions like "which functions call this API endpoint?" or "what tables does this migration touch?" Vector embeddings give you semantic proximity. AST-based knowledge graphs give you structural certainty.

Graphify parses code into a queryable graph using tree-sitter, stores relationships as explicit edges, and partitions large codebases with community detection algorithms. No vector store. No cloud dependency. Every edge is deterministic and explainable.

The project has 132K stars and is trending as a /graphify skill for Claude Code, Cursor, Codex, and Gemini CLI. It positions itself as infrastructure for agents that need to understand code structure, not just semantic similarity.

Why AST Graphs Beat Vector Search for Code

Vector embeddings collapse code into a latent space. You get approximate neighbors, but you lose the call graph, import chains, and type hierarchies. AST-based graphs preserve the structure:

  • Deterministic edges: A function call is a directed edge from caller to callee. No probabilistic retrieval.
  • Multi-hop queries: "Find all functions that transitively depend on this database table" is a graph traversal, not a similarity search.
  • Reproducibility: Same codebase, same graph. No embedding model drift or retraining.

Tree-sitter parses source files into concrete syntax trees. Graphify walks those trees, extracts entities (functions, classes, variables, imports), and creates typed edges (calls, inherits, imports, references). The result is a property graph where nodes are code entities and edges are relationships.

Architecture: Parse, Extract, Partition, Query

Graphify runs locally. The pipeline is:

  1. Parse: Tree-sitter generates ASTs for each file. Supports 40+ languages with consistent grammar.
  2. Extract: Walk the AST, identify entities (functions, classes, modules), and relationships (calls, imports, type references).
  3. Store: Build a graph in memory or persist to a graph database (Neo4j, NetworkX, or custom backend).
  4. Partition: Use community detection to split large codebases into subgraphs (modules, packages, feature areas). The repository topics include "leiden," suggesting Leiden-based clustering.
  5. Query: Agents issue graph queries via MCP tools to retrieve context.

Community detection is key for large codebases. It clusters nodes based on edge density, so related code (a module and its tests, a service and its database layer) ends up in the same community. Agents can load one community at a time to fit context windows.

MCP Integration and Agent Workflow

Graphify exposes an MCP server. Agents call tools like:

  • graphify.query(pattern): Run a graph query to find relationships.
  • graphify.community(entity): Retrieve the subgraph containing an entity.
  • graphify.explain_edge(source, target): Return the AST node that created the edge.

The workflow for an agent answering "what does this function depend on?":

  1. Agent calls graphify.query() with a pattern to find all functions called by process_payment.
  2. Graphify returns a list of called functions with file locations.
  3. Agent calls graphify.community(dep) to load the subgraph for each dependency.
  4. Agent synthesizes an answer with full context.

Because edges are deterministic, the agent can trust the graph. No hallucinated dependencies, no missed transitive calls.

Failure Modes and Limitations

AST parsing is not magic. It breaks down in predictable ways:

Scenario Impact Mitigation
Dynamic languages eval(), getattr(), runtime imports create invisible edges Hybrid approach: AST + runtime tracing
Metaprogramming Decorators, macros, code generation confuse static analysis Manual annotations or plugin hooks
Incomplete parses Syntax errors, unsupported language features leave gaps Graceful degradation: mark nodes as uncertain
Large monorepos Graph size explodes, query latency increases Community detection + lazy loading
Cross-language calls FFI, RPC, microservices span graphs Explicit edge annotations or service mesh metadata

The "every edge explained" promise means you can inspect the AST node that created each relationship. If a parse fails, you know which edges are missing. This is better than vector search, where you never know what you missed.

Trade-Offs: Graph Topology vs. Semantic Search

Dimension AST Graph Vector Embeddings
Precision High (structural ground truth) Medium (semantic proximity)
Recall Medium (misses dynamic behavior) High (finds conceptually similar code)
Explainability Full (every edge traceable) Low (latent space is opaque)
Query complexity Multi-hop traversals, pattern matching K-nearest neighbors, cosine similarity
Latency Low (graph index lookup) Medium (embedding inference + search)
Dependency Local tree-sitter binaries Embedding model + vector store

For agent code navigation, you want both. Use the AST graph for structural queries ("what calls this?"), and embeddings for semantic search ("find similar error handling patterns"). Graphify focuses on the structural layer.

Example: Querying a Codebase Graph

Assume you have a Python codebase with a users.py module and a database.py module. After parsing, an agent might query the graph through the MCP interface:

# Hypothetical Graphify MCP tool call
result = graphify.query({
    "entity": "create_user",
    "relationship": "CALLS",
    "filter": {"module": "database"}
})

# Returns:
# [
#   {"name": "insert_user", "file_path": "src/database.py", "line": 45}
# ]
Enter fullscreen mode Exit fullscreen mode

The agent can now load database.py:45, understand the SQL schema, and trace the full data flow. The edge from create_user to insert_user is backed by an AST node (the function call expression), so you can inspect the exact line of code.

Note: The exact query API depends on Graphify's MCP implementation. The repository documentation should specify whether queries use Cypher-like syntax, custom JSON patterns, or graph traversal methods.

When to Use Graphify

Use it when:

  • Agents need to navigate code structure (call graphs, import chains, type hierarchies).
  • You want deterministic, reproducible results.
  • You are building local-first tools (no cloud dependency).
  • You need to explain every relationship to a human or auditor.
  • Your codebase is statically analyzable (typed languages, minimal metaprogramming).

Avoid it when:

  • You need semantic search ("find code that does X").
  • Your codebase is heavily dynamic (lots of eval, runtime code generation).
  • You want a turnkey solution with no graph query language learning curve.
  • You need cross-service dependency tracking without manual annotations.

Technical Verdict

Graphify is infrastructure for agents that need structural code understanding. Use it for call graph analysis, dependency tracing, and refactoring tasks in well-typed, statically analyzable codebases. The deterministic AST approach gives you precision and explainability at the cost of missing dynamic behavior.

Avoid it if your primary need is semantic search or if your codebase relies heavily on runtime metaprogramming. The MCP integration is the right abstraction: agents call graph queries as tools, and the server handles parsing and traversal. The local-first architecture means no API keys, no rate limits, no vendor lock-in.

The project is actively maintained and trending on GitHub with 132K stars, but verify MCP integration stability for your specific agent framework. Pair Graphify with vector search for semantic queries, and you have a complete code understanding stack.

Source Links

Top comments (0)