# Cypher Query Features Supported in the openCypher Subset of codebase-memory-mcp

> Discover supported Cypher query features in the openCypher subset of codebase-memory-mcp. Learn what MATCH, WHERE, RETURN, and more are available in this read-only implementation.

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

---

**The codebase-memory-mcp repository implements a read-only openCypher subset that supports `MATCH`, `OPTIONAL MATCH`, `WHERE`, `RETURN`, `WITH`, `ORDER BY`, `SKIP`, and `LIMIT`, along with label alternation, variable-length paths, logical operators, comparison predicates, scalar functions, and aggregations, while explicitly rejecting all write operations like `CREATE`, `DELETE`, `SET`, and `MERGE`.**

The `codebase-memory-mcp` project provides a Cypher-to-SQLite translation layer that exposes a carefully curated openCypher subset for querying codebases. This implementation focuses exclusively on read-only graph traversal and projection, translating Cypher statements into SQLite queries while strictly prohibiting any data modification or schema changes.

## Core Query Clauses

### MATCH Pattern Syntax

The parser in [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c) handles node patterns `(var:Label {props})` and relationship patterns `-[var:TYPE*min..max]->` through recursive-descent parsing. Supported pattern elements include:

- **Node labels**: Single labels `(n:Service)` or alternation `(n:A|B|C)` parsed in `parse_node`
- **Relationship direction**: `<`, `>`, or any direction
- **Variable-length hops**: `*min..max`, `*`, or `*..max` processed in `parse_hop_range` (lines 998-1012)
- **Property filters**: Inline property maps `(n {name: "value"})`

### OPTIONAL MATCH

The `TOK_OPTIONAL` token is recognized and processed in the query planner, compiling optional patterns to left-outer joins. This allows queries to return results even when the optional pattern matches no data.

### WHERE Clause Filtering

The `WHERE` clause supports a full logical expression grammar including:

- **Logical operators**: `AND`, `OR`, `XOR`, `NOT` with parentheses for precedence
- **Comparison operators**: `=`, `<>`, `=~`, `>`, `<`, `>=`, `<=`
- **String predicates**: `CONTAINS`, `STARTS WITH`, `ENDS WITH`
- **Collection operators**: `IN` for list membership
- **Null handling**: `IS NULL` and `IS NOT NULL`
- **Label tests**: `n:Label` syntax for runtime label checking
- **Existence**: Single-hop `EXISTS { (v)-[:TYPE]->() }` predicates

## Projection and Aggregation

### RETURN and WITH Clauses

Both clauses support:
- **Column aliasing**: `RETURN n.name AS serviceName`
- **DISTINCT**: `RETURN DISTINCT n.language`
- **Property access**: `n.prop` and `r.prop`
- **Wildcard**: `RETURN *` (expanded to all bound variables)

### Aggregation Functions

All standard openCypher aggregations are supported with `DISTINCT` modifiers:
- `COUNT`, `SUM`, `AVG`, `MIN`, `MAX`, `COLLECT`
- Usage: `COUNT(DISTINCT n.id)`, `COLLECT(r.name)`

### Scalar and Multi-Argument Functions

**Single-argument functions**:
- String: `toLower`, `toUpper`, `toString`, `trim`, `ltrim`, `rtrim`, `reverse`
- Numeric: `toInteger`, `toFloat`, `size`, `length`
- Graph: `labels`, `type`, `id`, `keys`, `properties`
- Boolean: `toBoolean`

**Multi-argument functions**:
- `coalesce`: `coalesce(n.doc, "undocumented")`
- `substring`: `substring(n.name, 0, 3)`
- `replace`, `left`, `right`

### CASE Expressions

Full conditional logic is supported:

```cypher
CASE 
  WHEN n.isPublic THEN "public" 
  ELSE "private" 
END

```

## Ordering and Pagination

- **ORDER BY**: Supports `ASC` (default) and `DESC` ordering on columns, aggregations, or function results
- **SKIP**: Integer offset for pagination
- **LIMIT**: Maximum result count

These translate directly to SQLite `OFFSET` and `LIMIT` clauses.

## Explicitly Unsupported Write Operations

The centralized `unsupported_clause_error` function (lines 808-831 in [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c)) explicitly rejects all graph-modifying operations:

- **Data modification**: `CREATE`, `DELETE`, `DETACH DELETE`, `SET`, `REMOVE`, `MERGE`
- **Control flow**: `FOREACH`
- **Schema operations**: `DROP`, `CONSTRAINT`, `INDEX`
- **Procedures**: `CALL`, `YIELD`
- **Variants**: `MANDATORY MATCH`

While tokens like `TOK_UNION` and `TOK_UNWIND` exist in the lexer, they are not implemented in the query planner and will raise parse errors.

## Code Examples

### Variable-length path with filtering

```cypher
MATCH (a:Service)-[r:CALLS*1..3]->(b:Service)
WHERE a.name CONTAINS "auth" AND b.language = "go"
RETURN a.name AS caller, b.name AS callee, COUNT(r) AS hops
ORDER BY hops DESC
LIMIT 10

```

### Optional match with label alternation

```cypher
MATCH (c:Component)
OPTIONAL MATCH (c)-[:USES|DEPENDS_ON]->(d)
RETURN c.id, d.id AS dependentId

```

### Scalar functions and CASE

```cypher
MATCH (f:Function)
WHERE toLower(f.name) STARTS WITH "get"
RETURN f.name,
       substring(f.name, 0, 3) AS prefix,
       coalesce(f.doc, "undocumented") AS documentation,
       CASE WHEN f.isPublic THEN "public" ELSE "private" END AS visibility
ORDER BY f.name ASC

```

## Summary

- **Supported**: Read-only traversal via `MATCH` and `OPTIONAL MATCH` with variable-length paths, label alternation, and complex `WHERE` filtering
- **Supported**: Rich projection with `RETURN`/`WITH`, including aggregation, scalar functions, and `CASE` expressions
- **Supported**: Result ordering and pagination via `ORDER BY`, `SKIP`, and `LIMIT`
- **Unsupported**: All write operations (`CREATE`, `DELETE`, `SET`, `MERGE`, etc.) and schema modifications
- **Implementation**: Parsed in [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c) with function declarations in [`src/cypher/cypher.h`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.h)

## Frequently Asked Questions

### Does codebase-memory-mcp support CREATE or DELETE clauses?

No. The engine explicitly rejects `CREATE`, `DELETE`, `DETACH DELETE`, `SET`, `REMOVE`, and `MERGE` clauses through the `unsupported_clause_error` handler in [`src/cypher/cypher.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cypher/cypher.c). The implementation is strictly read-only for safety and simplicity.

### What aggregation functions are available in the openCypher subset?

The subset supports `COUNT`, `SUM`, `AVG`, `MIN`, `MAX`, and `COLLECT`, each accepting an optional `DISTINCT` modifier. These are parsed in the `RETURN` and `WITH` clause handlers and translated to SQLite aggregation functions.

### Can I use variable-length path patterns in MATCH clauses?

Yes. The parser supports variable-length hops using `*min..max` syntax (e.g., `-[r:CALLS*1..3]->`), handled by the `parse_hop_range` function. You can also use unbounded ranges like `*` or `*..5`.

### Is the UNION clause supported for combining queries?

No. While the lexer defines a `TOK_UNION` token, the query planner does not implement `UNION` or `UNION ALL`. Attempting to use these constructs will result in a parse error indicating the feature is not supported.