Summary
There is no way to express "nodes with no incoming edge" in query_graph. The form the README documents is rejected, and the natural workaround returns zero rows without an error.
The documented example does not work
README, Supported Cypher section:
EXISTS { (n)-[:TYPE]->() } (single-hop existence — great for dead-code, e.g. WHERE NOT EXISTS { (f)<-[:CALLS]-() })
That exact expression is rejected:
WHERE NOT EXISTS { MATCH (f)<-[:CALLS]-() }
-> unsupported EXISTS pattern — only the single-hop form '(var)-[:TYPE]->()' is supported
All three inbound syntaxes rejected
| Query fragment |
Error |
WHERE NOT (f)<-[:CALLS]-() |
unexpected operator at pos 31 |
WHERE NOT EXISTS((f)<-[:CALLS]-()) |
expected '{' after EXISTS |
WHERE NOT EXISTS { MATCH (f)<-[:CALLS]-() } |
unsupported EXISTS pattern … |
The outbound direction works as documented: WHERE NOT EXISTS { (f)-[:CALLS]->() } -> 2,949 leaf functions.
Silent-failure workaround
MATCH (f:Function)
OPTIONAL MATCH (f)<-[:CALLS]-(c)
WITH f, count(c) AS fan_in
WHERE fan_in = 0
RETURN f.name
-> 0 rows, no error
Expected: the ~291 zero-fan-in functions that search_graph(max_degree=0, exclude_entry_points=true) does return.
Impact
Dead-code detection is a headline feature. It is reachable via search_graph(max_degree=0) but not via Cypher, while the README advertises the Cypher form. Three possible fixes, in descending preference: support the inbound single-hop form; or make the OPTIONAL MATCH + WITH count() = 0 path work; or at minimum make that path fail loudly and correct the README example.
Environment
- Version: codebase-memory-mcp 0.9.0 (release binary, darwin-arm64)
- OS: macOS 26.5.2, Apple Silicon
- Repo under test: DeusData/codebase-memory-mcp @ af3ffbd (21,143 nodes / 123,103 edges)
- Verified identically through both the MCP server and
cli mode (outputs byte-identical)
Summary
There is no way to express "nodes with no incoming edge" in
query_graph. The form the README documents is rejected, and the natural workaround returns zero rows without an error.The documented example does not work
README, Supported Cypher section:
That exact expression is rejected:
All three inbound syntaxes rejected
WHERE NOT (f)<-[:CALLS]-()unexpected operator at pos 31WHERE NOT EXISTS((f)<-[:CALLS]-())expected '{' after EXISTSWHERE NOT EXISTS { MATCH (f)<-[:CALLS]-() }unsupported EXISTS pattern …The outbound direction works as documented:
WHERE NOT EXISTS { (f)-[:CALLS]->() }-> 2,949 leaf functions.Silent-failure workaround
Expected: the ~291 zero-fan-in functions that
search_graph(max_degree=0, exclude_entry_points=true)does return.Impact
Dead-code detection is a headline feature. It is reachable via
search_graph(max_degree=0)but not via Cypher, while the README advertises the Cypher form. Three possible fixes, in descending preference: support the inbound single-hop form; or make theOPTIONAL MATCH+WITH count() = 0path work; or at minimum make that path fail loudly and correct the README example.Environment
climode (outputs byte-identical)