Cypher Query Patterns for Graph Traversal in Codebase-Memory-MCP: A Complete Reference
Codebase-Memory-MCP implements a full-featured Cypher engine that supports directed and undirected relationships, variable-length path traversal, label alternation, existential sub-queries, and complex filtering, with every pattern validated in tests/test_cypher.c.
The DeusData/codebase-memory-mcp repository provides a graph-based memory system for analyzing codebases using Cypher as its native query language. Developers can traverse code relationships—such as function calls, module dependencies, and data flow—using standard Cypher syntax. The implementation covers simple node matching through advanced existential sub-queries, with the test suite serving as the authoritative specification of supported Cypher query patterns for graph traversal.
Node and Relationship Matching
Simple Node Labels
The engine supports matching nodes by single labels or label combinations. This pattern forms the foundation for all graph traversals in the codebase memory system.
MATCH (n:Function)
This basic pattern is proven in tests/test_cypher.c at line 22, demonstrating that the parser correctly handles label-based node identification.
Directed Relationships
Codebase-Memory-MCP handles both outbound and inbound edge directions explicitly. The outbound pattern follows the standard arrow syntax:
MATCH (f:Function)-[:CALLS]->(g:Function)
This directed traversal is tested at lines 44-46 in tests/test_cypher.c. For inbound relationships, the reverse arrow syntax retrieves callers of a specific function:
MATCH (f:Function)<-[:CALLS]-(g:Function)
The inbound pattern validation appears at lines 27-30 of the test file.
Undirected Traversal
When direction is irrelevant, the engine accepts undirected relationship patterns using a dash without arrows:
MATCH (f:Function)-[:CALLS]-(g:Function)
This bidirectional matching is confirmed in tests/test_cypher.c at lines 40-44, enabling queries that discover relationships regardless of call direction.
Variable-Length Path Traversal
Bounded and Unbounded Hops
The Cypher engine supports variable-length paths using the Kleene star syntax. For bounded traversals, explicit minimum and maximum hop counts control the search depth:
MATCH (f)-[:CALLS*1..3]->(g)
This pattern, tested at lines 53-56, restricts traversal to between one and three hops. For unbounded deep traversal, the wildcard syntax searches all reachable nodes:
MATCH (f)-[:CALLS*]->(g)
The unbounded pattern appears in tests/test_cypher.c at lines 67-70.
Maximum Depth Enforcement
While unbounded queries use the * syntax, the execution engine enforces a safety limit through the cbm_cypher_max_depth() function, which defaults to 10 hops. This prevents runaway queries on deeply connected code graphs while still allowing comprehensive reachability analysis.
Advanced Pattern Composition
Multiple Edge Types
The pipe operator enables matching against several relationship types within a single pattern, useful when tracing both direct calls and HTTP requests:
MATCH (f)-[:CALLS|HTTP_CALLS]->(g)
This alternation syntax is validated in tests/test_cypher.c at lines 82-86, allowing flexible traversal across different connection semantics.
Label Alternation
Nodes can match multiple possible labels using the same pipe syntax, enabling polymorphic queries across code entities:
MATCH (n:Function|Module)
This label alternation pattern appears at lines 1245-1252 in the test suite, supporting queries that treat functions and modules uniformly when appropriate.
Property Filtering and WHERE Clauses
Inline Property Constraints
Properties can be filtered directly within the node pattern for concise queries:
MATCH (f:Function {name: "SubmitOrder"})
This inline filtering is tested at lines 97-100 in tests/test_cypher.c, providing a shorthand for exact property matching.
String Matching and Regular Expressions
The WHERE clause supports rich string predicates including regular expressions:
WHERE f.name =~ ".*Order.*"
This regex capability is confirmed at lines 117-122. For substring matching without regex overhead, the engine supports CONTAINS and STARTS WITH:
WHERE f.name CONTAINS "Order"
These substring predicates appear in tests/test_cypher.c at lines 67-73.
Null-Safe Operations
The COALESCE function provides null-safe defaults when handling optional properties:
WHERE coalesce(f.transitive_loop_depth, 0) >= 2
This pattern, tested at lines 27-33, ensures queries handle missing properties gracefully by substituting default values.
Numeric Comparisons
The engine converts string properties to numeric values for comparison operations:
WHERE f.start_line > "8"
This numeric comparison capability is validated at lines 92-96 in the test suite, enabling range queries on line numbers and other numeric metadata stored as strings.
Sub-Queries and Aggregation
Existential Sub-Queries
The EXISTS and NOT EXISTS predicates test for pattern presence within the graph, supporting complex filtering based on graph topology:
WHERE EXISTS { (f)-[:CALLS]->() }
This sub-query syntax is proven at lines 55-62 in tests/test_cypher.c, allowing queries to find functions that make calls to any target.
Distinct and Aggregation
Result sets can be deduplicated using DISTINCT:
RETURN DISTINCT f.label
This aggregation support appears at lines 86-94 in the test file, essential for summarizing code properties without repetition.
Sorting and Pagination
The engine supports result ordering and limitation for manageable result sets:
RETURN f.name ORDER BY f.name DESC LIMIT 5
This pagination pattern is tested at lines 76-81, enabling top-N queries for code analysis results.
Implementation Architecture
According to the source code in cypher/cypher.h and cypher/cypher.c, the parser and execution engine implement the grammar recognized in the test suite. The underlying graph storage layer in store/store.h and store/store.c provides traversal primitives such as cbm_store_bfs, which the Cypher engine invokes to execute variable-length path queries. The graph-ui frontend component utilizes this same Cypher grammar to render interactive visualizations of code relationships.
Summary
- Directionality – The engine supports outbound (
->), inbound (<-), and undirected (-) relationship traversal equally. - Path Control – Variable-length paths support bounded ranges (
*1..3), unbounded wildcards (*), and depth limiting viacbm_cypher_max_depth(). - Pattern Flexibility – Label alternation (
:A|B) and edge-type alternation ([:CALLS|HTTP]) enable polymorphic matching. - Rich Filtering – WHERE clauses support regex, substring functions (
CONTAINS,STARTS WITH), null-safeCOALESCE, and numeric comparisons. - Existence Testing –
EXISTS { ... }sub-queries validate pattern presence for topology-based filtering. - Result Processing – Full support for
DISTINCT,ORDER BY, andLIMITenables precise result control.
Frequently Asked Questions
What is the maximum traversal depth for unbounded path queries?
The engine caps unbounded variable-length paths at 10 hops by default through the cbm_cypher_max_depth() function defined in the Cypher execution layer. This prevents excessive resource consumption when traversing densely connected code graphs while still supporting comprehensive reachability analysis.
How does Codebase-Memory-MCP handle optional or missing node properties?
The implementation supports the COALESCE function within WHERE clauses, allowing queries to provide default values for missing properties. For example, WHERE coalesce(f.transitive_loop_depth, 0) >= 2 safely handles nodes lacking the transitive_loop_depth property by substituting zero, as demonstrated in tests/test_cypher.c at lines 27-33.
Can I query for relationships of multiple types in a single pattern?
Yes, the pipe operator (|) enables matching multiple edge types within one pattern, such as MATCH (f)-[:CALLS|HTTP_CALLS]->(g). This alternation is validated in the test suite at lines 82-86 and allows flexible traversal across different connection types without requiring separate queries.
Does the engine support regular expression matching on code identifiers?
Yes, the WHERE clause supports regex matching using the =~ operator, such as WHERE f.name =~ ".*Order.*". This capability, confirmed at lines 117-122 in tests/test_cypher.c, enables flexible searching of function names, module names, and other string properties using standard regular expression syntax.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →