# How the Cypher Query Engine Works in codebase-memory-mcp: OpenCypher Support Explained

> Explore the Cypher query engine in codebase-memory-mcp. Learn how it translates OpenCypher to SQLite SQL through lexing, parsing, planning, and execution for efficient knowledge-graph queries.

- Repository: [Martin Vogel/codebase-memory-mcp](https://github.com/DeusData/codebase-memory-mcp)
- Tags: internals
- Published: 2026-07-16

---

**The Cypher query engine in codebase-memory-mcp is a read-only interpreter that translates a subset of OpenCypher into SQLite SQL, executing it against the internal knowledge-graph store through a four-stage pipeline of lexing, parsing, planning, and execution.**

The **cypher query engine** provides a lightweight, self-contained query layer for the `cbm_store` knowledge graph in the DeusData/codebase-memory-mcp repository. Unlike full Neo4j implementations, this engine deliberately restricts operations to read-only graph analysis, converting pattern matching and aggregation expressions into executable SQL statements.

## Four-Stage Query Processing Pipeline

The engine processes queries through a strict pipeline implemented primarily in [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c).

### Lexer: Tokenizing the Input

The **lexer** scans input strings and produces a token stream containing identifiers, literals, operators, and punctuation. It handles string escaping, numeric literals, comments, and two-character tokens such as `!=`, `<=`, and `..`.

Key implementation resides in [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c) at lines 68-124.

### Parser: Building the Abstract Syntax Tree

A recursive-descent **parser** constructs an **abstract syntax tree (AST)** for `MATCH` patterns, `WHERE` clauses, and `RETURN` specifications. The parser detects unsupported clauses early and validates syntax against the read-only subset.

Implementation spans lines 329-782 in [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c).

### Planner: Generating SQL

The **planner** walks the AST and produces equivalent **SQL SELECT** statements. It maps node variables to columns (`name`, `qn`, `label`, `file`) and edge variables to columns (`name`, `qn`, `label`), generating necessary joins and filters for the SQLite backend.

### Executor: Running Against SQLite

The **executor** sends generated SQL to the SQLite-backed `cbm_store` via `cbm_exec_query` in [`src/store/store.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/store/store.c), returning result sets to the caller.

## Supported OpenCypher Features

The cypher query engine supports a practical read-only subset of OpenCypher optimized for code analysis.

### MATCH Patterns

- **Node syntax**: `(n:Label)` with optional variable names
- **Relationship syntax**: `-[:TYPE*min..max]->` with hop ranges
- **Label alternation**: `:A|B|C` parsed as pipe-separated lists (stored as `"A|B|C"` and split during matching; see `parse_node()` around line 560)
- **Hop ranges**: `*2..5` for specific depths; `*` alone translates to `1..0` (where `0` signals no upper bound)

Example:

```c
const char *cypher = "MATCH (n:Class|Interface)-[:CALLS*1..3]->(m) "
                     "WHERE n.name CONTAINS \"Get\" "
                     "RETURN n.name, COUNT(m) AS calls "
                     "ORDER BY calls DESC LIMIT 10";

```

### WHERE Filters

Supported operators include:

- Logical: `AND`, `OR`, `XOR`, `NOT`
- Comparison: `=`, `<>`, `>`, `<`, `>=`, `<=`
- String: `CONTAINS`, `STARTS WITH`, `ENDS WITH`
- Null checking: `IS NULL`, `IS NOT NULL`
- List membership: `IN`
- Label tests: `n:Label`

### RETURN Clause

Supports scalar expressions, **aggregate functions** (`COUNT`, `SUM`, `AVG`, `MIN`, `MAX`, `COLLECT`), `DISTINCT`, and **string functions** (`toLower`, `toUpper`, `toString`). Multi-argument scalar functions include `coalesce`, `substring`, `replace`, `left`, and `right`.

Function handling distinguishes three groups via `is_aggregate_tok()`, `is_string_func_tok()`, and `is_multiarg_func_call()` around lines 1292-1302.

### Ordering and Pagination

Full support for `ORDER BY ... ASC|DESC`, `SKIP`, and `LIMIT`.

### EXISTS Predicate

Limited to single-hop patterns: `(var)-[:TYPE]->()`.

Example:

```c
const char *cypher2 = "MATCH (e) "
                      "WHERE EXISTS { (e)-[:EXTENDS]->() } "
                      "RETURN e.name, "
                      "       CASE WHEN e.is_public THEN \"public\" ELSE \"private\" END AS visibility, "
                      "       toUpper(e.name) AS upper_name";

```

### Property Access and CASE Expressions

Standard `node.prop` syntax for stored properties and simple `CASE ... END` expressions.

### Variable Limits

Hard-coded constants in [`src/foundation/limits.h`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/foundation/limits.h) define **CYP_MAX_VARS = 16** for node variables and 8 edge variables maximum per query.

## Explicitly Unsupported Features

The engine rejects write and schema-altering operations through `unsupported_clause_error()` (lines 815-838 in [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c)):

- `CREATE`, `DELETE`, `DETACH`, `SET`, `REMOVE`, `MERGE`
- `YIELD`, `CALL` (stored procedures)
- `FOREACH`, `MANDATORY MATCH`
- `DROP`, `CONSTRAINT`

These generate clear error messages such as *"unsupported Cypher feature: CREATE clause (write operations not supported)"*.

## Architectural Implementation Details

The **expression tree** (`cbm_expr_t`) is built recursively in [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c), allowing straightforward evaluation or SQL translation. Label alternation is stored as a single string `"A|B|C"` and split during pattern matching.

The engine maintains strict boundaries through constants defined in [`src/foundation/limits.h`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/foundation/limits.h), ensuring predictable memory usage during query processing.

## Practical Code Examples

Multi-hop analysis with label alternation:

```c
const char *cypher = "MATCH (n:Class|Interface)-[:CALLS*1..3]->(m) "
                     "WHERE n.name CONTAINS \"Get\" "
                     "RETURN n.name, COUNT(m) AS calls "
                     "ORDER BY calls DESC LIMIT 10";

```

Using scalar functions and CASE expressions:

```c
const char *cypher2 = "MATCH (e) "
                      "WHERE EXISTS { (e)-[:EXTENDS]->() } "
                      "RETURN e.name, "
                      "       CASE WHEN e.is_public THEN \"public\" ELSE \"private\" END AS visibility, "
                      "       toUpper(e.name) AS upper_name";

```

Filtering with IN lists and IS NULL:

```c
const char *cypher3 = "MATCH (c) "
                      "WHERE c.type IN [\"class\", \"enum\"] AND c.deprecated IS NULL "
                      "RETURN c.name, c.type";

```

## Key Source Files

| File | Role |
|------|------|
| [`src/cypher/cypher.h`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.h) | Public API for lexing, parsing, and execution |
| [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c) | Full lexer, parser, AST construction, and query planning |
| [`src/store/store.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/store/store.c) | SQLite-backed store receiving generated SQL via `cbm_exec_query` |
| [`src/foundation/limits.h`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/foundation/limits.h) | Engine constants including `CYP_MAX_VARS` |
| [`src/cli/cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/cli.c) | CLI wrapper exposing the `query_graph` command |

## Summary

- The **cypher query engine** implements a four-stage pipeline: lexer, parser, planner, and executor.
- It translates **OpenCypher** into **SQLite SQL** for read-only graph queries against `cbm_store`.
- Supports **MATCH** patterns with label alternation and hop ranges, **WHERE** filters, **RETURN** with aggregates, and **ORDER BY/LIMIT**.
- Explicitly blocks all write operations (`CREATE`, `DELETE`, `SET`, etc.) via `unsupported_clause_error()`.
- Hard limits include **16 node variables** and **8 edge variables** per query.
- Core implementation resides in [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c) with storage delegation to [`src/store/store.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/store/store.c).

## Frequently Asked Questions

### Does the codebase-memory-mcp Cypher engine support write operations?

No. The engine is explicitly read-only and rejects `CREATE`, `DELETE`, `SET`, `REMOVE`, `MERGE`, and `DETACH` clauses. The `unsupported_clause_error()` function in [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c) (lines 815-838) detects these constructs and returns clear error messages indicating that write operations are not supported.

### What is the maximum depth for relationship hop ranges?

The engine supports arbitrary hop ranges using syntax like `*2..5`. The unbounded `*` operator translates to `1..0` internally, where `0` signals no upper bound. However, practical limits depend on the underlying SQLite performance and the `cbm_store` indexing.

### How does the engine handle multiple labels in MATCH patterns?

Label alternation such as `:Class|Interface` is parsed into a single pipe-separated string (e.g., `"Class|Interface"`) and stored as such. During execution, this string is split and evaluated as a label test. This implementation is found in `parse_node()` around line 560 of [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c).

### Which aggregate functions are available in RETURN clauses?

The engine supports `COUNT`, `SUM`, `AVG`, `MIN`, `MAX`, and `COLLECT`. These are identified by `is_aggregate_tok()` around line 1292 in [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c), alongside string functions like `toLower` and `toUpper`, and multi-argument functions such as `coalesce` and `substring`.