CodeGraph by FalkorDB

repository·staging·Indexed 43 days ago

https://github.com/falkordb/code-graph

A knowledge graph visualization tool that transforms codebases into searchable graphs to analyze dependencies, detect bottlenecks, and optimize projects using GraphRAG and LLMs. It features a FastAPI backend, a cgraph CLI for indexing and querying, and an MCP (Model Context Protocol) server for AI agent integration. Currently supports Python (.py), Java (.java), and C# (.cs) file extensions.

Tokens
16.2K
Snippets
59
Records
76
Agent score
55%

What's inside CodeGraph

  1. Overview of Code Graph MCP Server capabilities

    staging

    The Code Graph MCP (Model Context Protocol) server provides AI coding agents with two primary types of capabilities for interacting with a codebase:

    1. Structural tools (Deterministic, no LLM required): These tools allow agents to perform precise graph traversals and repository analysis without the overhead or unpredictability of an LLM. Tools include:

      • get_callers: Find upstream callers of a component.
      • get_callees: Find downstream dependencies/calls.
      • get_dependencies: Query multiple relationship types.
      • impact_analysis: Perform variable-depth traversals to see what breaks if a change is made.
      • find_path: Locate paths between entities.
      • search_code: Perform code searches.
      • index_repo: Build/update the graph index.
    2. Ask tool (GraphRAG-powered, requires LLM): A natural language interface that converts questions into Cypher queries to provide grounded answers about the codebase. It returns the answer, the generated Cypher query (for transparency), and the context nodes used.

  2. Code Graph MCP Server Roadmap

    staging

    The development of the Code Graph MCP server is organized into several phases:

    Phase 1: Core MCP Server

    • Tools: 8 tools available.
    • Language Support: 11 languages (Python, JS, Kotlin, Go, Rust, TypeScript, Ruby, C, C++ via tree-sitter; Java, C# via multilspy).
    • Transport: stdio.
    • Features: Auto-init, agent guidance, per-branch graph identity, and default-on incremental indexing.

    Phase 1.5: Transport & Prompting

    • Transport: HTTP/SSE support.
    • Features: Real-LLM nightly E2E with secret-managed API keys and prompt iteration for the ask tool.

    Phase 2: Advanced Querying & Indexing

    • Features: Cross-branch query tools (e.g., "what changed between branches"), per-file second-pass LSP optimization, and rename detection in incremental indexing.
    • Language Support: Expansion of tree-sitter coverage toward 60+ languages.

    Phase 3: Deep Integration

    • Features: Dedicated TS/Go analyzers with deeper LSP integration, Copilot extension, FalkorDB Cloud integration, and branch garbage collection/TTL.

    Future

    • Integration into a unified @falkordb/code-intelligence package alongside Graphiti and mcpserver.
  3. Manage multi-branch graph identity

    staging

    To prevent different git branches from overwriting each other's indices, CodeGraph uses a unique naming convention: code:{project_name}:{branch}.

    • Automatic Detection: When using Project.from_git_repository() or Project.from_local_directory(), the branch parameter is optional. If None, it auto-detects the current branch via git rev-parse --abbrev-ref HEAD.
    • CLI Usage: Use the --branch <name> flag with commands like cgraph index, cgraph list, cgraph info, and cgraph search to target a specific branch.
    • API Usage: REST endpoints such as /api/list_repos, /api/graph_entities, /api/repo_info, /api/get_neighbors, /api/find_paths, and /api/auto_complete accept an optional branch query parameter.
    • MCP Server: The index_repo tool accepts an optional branch and returns the detected branch in its response.
    • Migration: If you are upgrading from a version that used a single global index, run cgraph migrate to rename existing code:{project} graphs to code:{project}:_default and migrate metadata to {repo}:_default_info.
    # Index a specific branch
    cgraph index . --branch feature-xyz
    
    # Search within a specific branch
    cgraph search "my function" --branch feature-xyz
  4. How to find callers of a function

    staging

    The graph uses directed edges: (caller)-[:CALLS]->(callee).

    Because the cgraph neighbors command follows outgoing edges (from caller to callee), it cannot directly find callers by querying a callee's neighbors. To find who calls a specific function, you must either:

    1. Use cgraph paths to trace connections.
    2. Search for potential callers and inspect their CALLS neighbors to see if they point to your target function.
  5. Use incremental indexing for faster updates

    staging

    CodeGraph supports incremental indexing to avoid re-parsing every file in a repository. This is particularly useful for agents that call index_repo frequently.

    • How it works: The system maintains a Redis hash {repo}:{branch}_files mapping file_path to its SHA256(content). During indexing, it diffs the current file tree against this store.
    • Behavior:
      • Unchanged files: Skipped.
      • Modified files: Old graph entities are removed via delete_files([path]), and the file is re-analyzed.
      • Deleted files: Removed from the graph.
      • New files: Analyzed normally.
    • CLI Control: cgraph index . defaults to incremental mode if a graph already exists. Use the --full flag to force a complete re-index.
    • MCP Server: The index_repo tool defaults to incremental mode and returns a response containing mode ("full" or "incremental") and a list of files_changed.
    # Force a full re-index
    cgraph index . --full
  6. Best practices for using code-graph tools

    staging

    Follow these rules of thumb when interacting with the code-graph MCP server:

    1. Resolve names to IDs first: Most tools require a symbol_id. Start with search_code or find_symbol to obtain the ID for a name.
    2. Navigate relationships with direction: When using get_neighbors, use direction="IN" to find callers and direction="OUT" to find callees. Use the relation parameter for specific edge types like IMPORTS or DEFINES.
    3. Perform impact analysis before refactoring: Use impact_analysis to discover the transitive closure of callers; the results often reveal dependencies you might have missed.
    4. Specify branches: While branch is optional, provide it when working on feature branches to ensure you are querying the correct per-branch index.
    5. Understand the response format: For tools returning collections (search_code, find_symbol, get_neighbors, get_file_neighbors, find_path, impact_analysis), the array is located in structuredContent.result per the MCP specification. index_repo returns a single object.
  7. Multi-branch graph identity and isolation

    staging

    To support multi-tenant environments (e.g., multiple agents working on different branches of the same repository simultaneously), Code Graph uses a specific naming convention for graph identities. This prevents concurrent agents from corrupting each other's views.

    • Graph Name Format: code:{project}:{branch}
    • Default Branch: Existing single-graph deployments use code:{project}:_default.
    • Branch Detection: The index_repo tool automatically detects the current branch using git rev-parse --abbrev-ref HEAD in the target path. You can provide an optional override parameter if needed.
    • Non-Git Paths: For paths not managed by Git, the _default branch identifier is used.
  8. How the MCP `ask` tool works via GraphRAG

    staging

    The ask tool uses a GraphRAG (Graph Retrieval-Augmented Generation) pattern to answer natural language questions about a codebase. To ensure scalability on large codebases, the graph itself is never sent to the LLM. Instead, the process follows a two-step LLM round-trip bracketing a Cypher query:

    1. NL-to-Cypher: The LLM receives the user's question and the graph ontology to generate a precise Cypher query.
    2. Execution: The generated Cypher query is executed against the FalkorDB graph.
    3. NL-to-Answer: The LLM receives the original question and the raw rows returned from the database to synthesize a natural-language answer.

    This pattern is implemented by retrieving a cached KnowledgeGraph instance and calling its .ask() method.

    # api/mcp/tools/ask.py — the tool itself
    async def ask(question: str) -> dict:
        kg = get_or_create_kg(current_project_name())
        response = await asyncio.get_event_loop().run_in_executor(None, kg.ask, question)
        return {
            "answer": response.answer,
            "cypher_query": response.cypher_query,   # exposed for transparency
            "context_nodes": response.context_nodes,
        }
  9. Incremental indexing with file-hash skipping

    staging

    Code Graph supports incremental indexing to allow agents to call index_repo frequently and cheaply.

    • Mechanism: It uses file-hash-based skipping. The system tracks per-file SHA256 hashes in Redis under the key {repo}:{branch}_files.
    • Behavior: Once a (project, branch) graph exists, incremental indexing is enabled by default. The system only processes files that have changed.
    • Full Re-indexing: To force a complete re-index, use the --full flag in the CLI or set incremental=False when calling the MCP tool.
  10. Understand Code Graph JSON structures

    staging

    The Code Graph represents code entities as Nodes and their relationships as Edges.

    • Node: Represents an entity like a Function or Class. It contains a unique id, labels, and properties (e.g., name, path, src_start, src_end).
    • Edge: Represents a relationship (e.g., CALLS, DEFINES) between a src_node and a dest_node.
    • Neighbors response: Returns a collection of nodes and edges connected to a specific node.
    • Paths response: Returns an array of paths, where each path is an alternating array of [node, edge, node, edge, node].
    ### Node
    ```json
    {
      "id": 42,
      "labels": ["Function"],
      "properties": {
        "name": "analyze_sources",
        "path": "api/project.py",
        "src_start": 79,
        "src_end": 94,
        "doc": "..."
      }
    }

    Edge

    {
      "id": 10,
      "relation": "CALLS",
      "src_node": 42,
      "dest_node": 55,
      "properties": {
        "pos": 83
      }
    }
  11. Authentication and Authorization behavior

    staging

    CodeGraph uses token-based authentication for its API endpoints.

    • Mutating Endpoints: /api/analyze_folder, /api/analyze_repo, and /api/switch_commit require the token_required dependency. You must provide Authorization: Bearer <SECRET_TOKEN>.
    • Read Endpoints: Use the public_or_auth dependency.
    • Public Access: If CODE_GRAPH_PUBLIC=1 is set in environment variables, read-only endpoints become public even if a SECRET_TOKEN is configured.
    • Unset Token: If SECRET_TOKEN is not configured, the current implementation accepts requests without an Authorization header.
  12. Use the Code Graph CLI for common queries

    staging

    The cgraph CLI allows you to navigate the code graph using node IDs obtained from search results.

    • Find what a function calls: Search for the function name, get its ID, then use neighbors with the --rel CALLS flag.
    • Find what a class defines: Search for the class name, get its ID, then use neighbors with the --rel DEFINES flag.
    • Trace a path between two entities: Search for both entities to get their IDs, then use paths with both IDs.
    • Get repository statistics: Use the info command with the --repo flag.
    # What does function X call?
    cgraph search X
    cgraph neighbors <id> --rel CALLS
    
    # What does class Y define?
    cgraph search Y
    cgraph neighbors <id> --rel DEFINES
    
    # Trace path from function A to function B
    cgraph search A
    cgraph search B
    cgraph paths <id_A> <id_B>
    
    # What are the stats for this repo?
    cgraph info --repo my-project