agentsclimarketplace

Gcyphrq

Skill plelevier/gcyphrq/skills/gcyphrq

Use for querying graph data with Cypher — service dependencies, infrastructure topology, blast radius analysis, path tracing, graph mutations. Runs against JSON graph files with an in-memory Cypher engine.From its SKILL.md

Install
npx -y skills add plelevier/gcyphrq --skill gcyphrq

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

11.7 KB, ~3.7k tokens by cl100k_base, as published. Nobody here has run it

gcyphrq

Execute Cypher queries against JSON graph files. Outputs raw JSON to stdout.

Workflow

  1. Find the graph file (.json with {nodes, edges}) or let the user name it
  2. Build Cypher query from patterns below or references/queries.md
  3. Run: gcyphrq -g <graph.json> -e '<cypher>'

CLI

gcyphrq -g <file|-> -e '<cypher>'. -e query (required), -g file/stdin (required), -nl label prop (default "label"), -et edge type (default "type"), --format graph|rows. Chain via -g -.

Extensions

gcyphrq supports pluggable extensions for non-JSON input formats and custom functions. Extensions are npm packages named gcyphrq-ext-*. Both local (node_modules/ near cwd) and global (npm root -g) packages are discovered; local takes precedence.

  • Discover installed extensions: gcyphrq --list-extensions (run first to see what's available)
  • Graph-input extensions: gcyphrq -g <file> --ext <name> -e '<cypher>' (e.g., --ext gexf for GEXF files)
  • Function extensions: gcyphrq -g <file> --ext-fn <name> -e '<cypher>' (repeatable, e.g., --ext-fn apoc-commons)
  • Combined: gcyphrq -g data.gexf --ext gexf --ext-fn apoc-commons -e '<cypher>'
  • Function syntax: <namespace>.<name>() (e.g., RETURN apoc.text.join(", ", ["a","b"]))

When a non-JSON graph file is provided, check --list-extensions for a matching --ext handler.

Graph File Format

{ "nodes": [{ "key": "id1", "attributes": { "label": "Service", "name": "api" } }],
  "edges": [{ "source": "id1", "target": "id2", "attributes": { "type": "TCP" } }] }
  • attributes.label → Cypher label (:Service). String or array (["Service","Infra"]). Override with -nl.
  • attributes.type on edges → relationship type ([:TCP]). Override with -et.
  • All other attributes → filterable properties ({name: "X"}).
  • Optional options.type: "directed"|"undirected"|"mixed" (default "directed"). options.allowSelfLoops: true / options.multi: true (parallel edges).

Supported Cypher

  • Matching: MATCH, OPTIONAL MATCH, chained (cartesian), labels :A:B (AND), :A|B (OR), :!A (NOT), variable-length *min..max, directional edges (->, <-, -). Unbounded patterns ([*1..]) default to max depth 10 and path limit 100K per start node; explicit bounds ([*1..N]) always take precedence and avoid the warning
  • Filtering: WHERE with =, <>, >, >=, <, <=, CONTAINS, STARTS WITH, ENDS WITH, IN, IS NULL, AND/OR/NOT, map comparison
  • Pipelining: WITH + aggregations (count, count(*), sum, avg, min, max, collect, all with DISTINCT)
  • CASE: general (CASE WHEN cond THEN result) and simple (CASE expr WHEN val THEN result). Nested. In RETURN/WHERE/WITH/ORDER BY/SET
  • Reduce: reduce(init, var IN list | body). Triggers grouping only when sub-expressions contain aggregations
  • List comprehensions: [var IN list [WHERE pred] | expr]
  • Pattern comprehensions: [(pattern) [WHERE pred] | expr]. From bound anchor. Supports directional edges, typed rels, variable-length. In RETURN/WHERE/WITH; nest in size(), head(), list comps
  • Quantifiers: ALL/ANY/SINGLE/NONE(x IN list WHERE pred). Empty list: ALL/NONE → true, ANY/SINGLE → false
  • EXISTS: EXISTS(expr) — true if not null/undefined. Use with NOT in WHERE
  • UNWIND with WHERE: UNWIND list AS x WHERE x > 0. Combine with WITH for multi-stage filtering
  • ORDER BY NULLS FIRST/LAST: default NULLS LAST for ASC, NULLS FIRST for DESC
  • UNION/UNION ALL: each branch must end with RETURN. ORDER BY/SKIP/LIMIT on combined result
  • Arithmetic: +, -, *, /, %, ^, unary +/-. + concatenates strings. Null propagation, div/mod by zero → null
  • List/Map literals: dynamic values, list slicing [start..end] with negative indices
  • Strings as char lists: for head(), last(), tail(), reverse(), slicing, comprehensions, quantifiers, reduce(), UNWIND, FOREACH, IN. tail()/reverse()/slicing → string; others → char list
  • Scalar functions: 40+ (toLower, substring, split, coalesce, size, random, labels (RETURN only), labelsOf (everywhere), nodes/relationships (RETURN only), etc.). random() → 0..1 float; use ORDER BY random() to shuffle
  • Graph statistics: numNodes(), numRelationships(), density(), averageDegree(), diameter() (-1 if disconnected, bidirectional)
  • Centrality: pagerank() (power iteration, damping=0.85), degreeCentrality() (normalized unique neighbors), betweennessCentrality() (Brandes'). All support global (no args → {nodeId: score}) and per-node (node arg → score). Betweenness: bidirectional
  • Subgraph extraction: subgraph(nodeList) (induced subgraph from collect()), egoGraph(node, k) (k-hop ego network, default k=1), connectedComponent(node) (connected component). All return { nodes: [...], edges: [...] }. All treat edges as bidirectional for traversal
  • Temporal: Constructors: timestamp(), datetime(), date(), time(), localdatetime(), localtime(), datetimewithtimezone(), timewithzone(), duration(). Extractors: year(), month(), day(), hour(), minute(), second(), millisecond(), timezone(), epochseconds(), epochmillisecond(), totalSeconds(), totalMinutes(). WHERE/ORDER BY: chronological, timezone-aware
  • Path expressions: shortestPath((a)-[*]->(b)) (single BFS); allShortestPaths((a)-[*]->(b)) (all min-length). Supports type filtering, direction, depth bounds. Variables must be bound
  • CALL { ... } subqueries: Inline (refs outer vars), YIELD filtering, nested, CREATE/SET/DELETE inside, ORDER BY inside. No stored procedures
  • LOAD CSV: LOAD CSV [WITH HEADERS] FROM 'source' AS var. Local/HTTP/HTTPS. FIELDS TERMINATED BY, OPTIONALLY ENCLOSED BY. Works in CALL
  • Mutations: CREATE (single node or chain), SET, DELETE, DETACH DELETE, REMOVE, MERGE (WHERE filter, ON CREATE/ON MATCH with SET/DELETE/DETACH DELETE/REMOVE)
  • Not supported: stored procedures, APOC, regex in WHERE
  • Notes: startnode()/endnode() return string IDs; avg()/min()/max() return null on empty sets

Cypher Patterns

Full command: gcyphrq -g <graph> -e '<cypher>'

TaskCypher
By labelMATCH (n:Service) RETURN n
By propertyMATCH (n:Service {type: "RPC"}) RETURN n
Multi-label ANDMATCH (n:Service:Infrastructure) RETURN n
Label OR`MATCH (n:Service
Label NOTMATCH (n:!Database) RETURN n
IncomingMATCH (s)-[:TCP]->(db:Database {name: "PostgreSQL"}) RETURN s
OutgoingMATCH (db:Database)-[]->(t) RETURN db, t
PathMATCH (a {name: "X"})-[r*1..3]->(b {name: "Y"}) RETURN a, r, b
Blast radiusMATCH (root {name: "X"})-[r*1..2]-(affected) RETURN root, r, affected
Unbounded pathMATCH (a {name: "X"})-[r*1..]->(b) RETURN a, r, b (max depth 10, 100K paths; use [*1..N] for more)
DegreeMATCH (n)-[]->(t) WITH n, count(t) AS deg RETURN n, deg
Group byMATCH (n:Service) WITH n.type AS t, count(n) AS c RETURN t, c
CREATECREATE (n:Service {name: "X", type: "RPC"}) RETURN n
CREATE chainMATCH (a {name: "X"}) MATCH (b {name: "Y"}) CREATE (a)-[r:DEPENDS_ON]->(b) RETURN r
SETMATCH (n {name: "X"}) SET n.status = "updated" RETURN n
SET multiMATCH (n) SET n:Label, n.prop = val, n.count = 5 RETURN n
FOREACH`MATCH (u) FOREACH (x IN u.items
FOREACH WHERE`MATCH (u) FOREACH (x IN u.items WHERE x.val > 0
FOREACH multi`MATCH (u) FOREACH (x IN u.items
DELETEMATCH (n {name: "X"}) DELETE n or DETACH DELETE n
REMOVEMATCH (n) REMOVE n:Label, n.prop RETURN n
MERGEMERGE (n:User {name: "Alice"}) ON CREATE SET n.createdAt = 0 RETURN n
UNION ALLMATCH (u:User) RETURN u.name UNION ALL MATCH (u:Admin) RETURN u.name
ArithmeticMATCH (n) RETURN n.price * n.qty AS total, n.price * 2 + n.shipping AS cost
CASEMATCH (n) RETURN n.name, CASE WHEN n.type = "RPC" THEN "svc" ELSE "other" END AS cat
CASE (ORDER BY)MATCH (n) RETURN n.name ORDER BY CASE n.type WHEN "RPC" THEN 0 ELSE 1 END
Path varMATCH path=(a)-[r]->(b) RETURN path, nodes(path), relationships(path)
labels()MATCH (n) RETURN labels(n)
CALLCALL { MATCH (n:Person) RETURN n.name AS name }
CALL (outer)MATCH (a:Person) CALL { MATCH (a)-[:FRIEND]->(b) RETURN b.name AS friend } RETURN a.name, friend
CALL (YIELD)CALL { MATCH (n:Person) RETURN n.name AS name, n.age AS age } YIELD name WHERE name <> "Bob" RETURN name
CALL (nested)CALL { CALL { MATCH (n:Person) RETURN n.name AS name } RETURN name }
shortestPath()MATCH (a {name: "X"}) MATCH (b {name: "Y"}) RETURN shortestPath((a)-[*]->(b)) AS path
shortestPath (typed)RETURN shortestPath((a)-[:TCP*]->(b)) or allShortestPaths((a)-[*]-(b))
count(*)MATCH (n) RETURN count(*) AS total
collectMATCH (u:User) RETURN collect(u.name) AS names, collect(DISTINCT u.dept) AS depts
reduce`RETURN reduce(total = 0, x IN [1,2,3]
reduce (collect)`MATCH (u:User) RETURN reduce(total = 0, x IN collect(u.age)
quantifiersMATCH (n) WHERE ALL/ANY/SINGLE/NONE(x IN n.tags WHERE x = "a") RETURN n
Pattern comp`MATCH (a:Person) RETURN [(a)-->(b:Person)
Pattern comp (in/WHERE)`MATCH (a:Person) RETURN [(a)<--(b:Person) WHERE b.age > 30
Pattern comp (size)`MATCH (a:Person) RETURN a.name, size([(a)-->(b:Person)
EXISTSMATCH (n) WHERE EXISTS(n.prop) OR NOT EXISTS(n.prop) RETURN n
UNWINDUNWIND [1,2,3,4,5] AS x WHERE x > 1 WITH x WHERE x < 5 RETURN x
NULLSMATCH (n) RETURN n.name, n.score ORDER BY n.score NULLS FIRST
LOAD CSVLOAD CSV [WITH HEADERS] FROM 'file.csv' AS row RETURN row.name, row.age
LOAD CSV (MATCH)LOAD CSV WITH HEADERS FROM 'users.csv' AS row MATCH (u:User {name: row.name}) RETURN row.name, u
LOAD CSV (delim)LOAD CSV FROM 'data.tsv' AS row FIELDS TERMINATED BY '\t' RETURN row
EXPLAINgcyphrq --explain -e 'MATCH (u:User) RETURN u'
timestamp()RETURN timestamp() AS ts, datetime(2023,6,15,14,30,45) AS dt, date(2023,6,15) AS d
duration/extractorsRETURN time(14,30,45) AS t, duration({hours:1,minutes:30}) AS dur, year(n.createdAt) AS y, epochseconds(n.createdAt) AS epoch
temporal WHEREMATCH (n) WHERE n.createdAt > '2023-01-01T00:00:00.000Z' RETURN n.name ORDER BY n.createdAt DESC
Graph statsRETURN numNodes() AS n, numRelationships() AS e, density() AS d, averageDegree() AS avgDeg, diameter() AS diam
PageRankRETURN pagerank() AS scores
PageRank (node)MATCH (n) RETURN n.name, pagerank(n) AS pr ORDER BY pr DESC
CentralityMATCH (n) RETURN n.name, degreeCentrality(n) AS dc, betweennessCentrality(n) AS bc ORDER BY dc DESC
Top-NMATCH (n) RETURN n.name, pagerank(n) AS pr ORDER BY pr DESC LIMIT 5
SubgraphMATCH (n) WHERE n.type = "RPC" WITH collect(n) AS nodes RETURN subgraph(nodes) AS sg
Ego / componentMATCH (n {name: "X"}) RETURN egoGraph(n, 2) AS sg, connectedComponent(n) AS cc

See references/queries.md for more patterns.

References

  • references/example-graph.json — 8-node bundled test graph (services, DBs, infra, monitoring)
  • references/queries.md — Use-case query examples. Load for infrastructure questions needing concrete patterns.

What ships with it: 2 files

12.5 KB alongside SKILL.md

references/

Keep looking

Skills are one crate of 326,144. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.