Skip to content

Crystal CLI Reference

crystal-cli is a command-line client for interacting with a running Crystal Graph Engine server.

Installation

go build -o crystal-cli ./cmd/crystal-cli

Or from Docker:

docker cp crystal:/app/crystal-cli ./crystal-cli

Configuration

Set the server URL via environment variable:

export CRYSTAL_URL=http://localhost:7540

Defaults to http://localhost:7540 if not set.

Property Syntax

Properties are passed as key=value pairs after the command arguments.

  • key=value sets a string property
  • key:=value sets a JSON-typed property (numbers, booleans, arrays, objects)
crystal-cli vertex create Person name=Alice age:=30 active:=true
crystal-cli vertex create Config tags:='["web","prod"]'

Commands

Server

crystal-cli health                     # health check
crystal-cli stats                      # graph statistics
crystal-cli flush                      # flush to disk
crystal-cli version                    # CLI version

Vertices

List vertices:

crystal-cli vertex list
crystal-cli vertex list --type Person

Get a vertex:

crystal-cli vertex get <id>

Create a vertex:

crystal-cli vertex create Person name=Alice age:=30
crystal-cli vertex create Server ip=10.0.0.1 hostname=web01

The _labels property (with := JSON syntax) sets labels:

crystal-cli vertex create Person name=Alice _labels:='["suspect","witness"]'

Update a vertex:

crystal-cli vertex update <id> age:=31 city=Berlin

Use _type to change the vertex type:

crystal-cli vertex update <id> _type=Organization

Delete a vertex:

crystal-cli vertex delete <id>

This also deletes all connected edges.

List edges of a vertex:

crystal-cli vertex edges <id>
crystal-cli vertex edges <id> --dir out
crystal-cli vertex edges <id> --dir in
crystal-cli vertex edges <id> --dir both

List neighbors:

crystal-cli vertex neighbors <id>
crystal-cli vertex neighbors <id> --dir both

Edges

List edges:

crystal-cli edge list
crystal-cli edge list --type knows

Get an edge:

crystal-cli edge get <id>

Create an edge:

crystal-cli edge create <source_id> <target_id> knows since=2020
crystal-cli edge create <source_id> <target_id> accessed port:=443

Special properties: - _weight:=2.5 sets the edge weight - _directed:=false makes the edge undirected

Update an edge:

crystal-cli edge update <id> since=2019
crystal-cli edge update <id> _weight:=3.0

Delete an edge:

crystal-cli edge delete <id>

Queries

Query vertices:

crystal-cli query vertices
crystal-cli query vertices --type Person
crystal-cli query vertices --type Person --label suspect
crystal-cli query vertices --type Person --limit 10 --offset 20
crystal-cli query vertices --type Person city=Berlin

Query edges:

crystal-cli query edges
crystal-cli query edges --type knows
crystal-cli query edges --type knows --limit 50

Query neighbors (multi-hop):

crystal-cli query neighbors <vertex_id>
crystal-cli query neighbors <vertex_id> --type Server --depth 2
crystal-cli query neighbors <vertex_id> --dir both --depth 3 --limit 100

Traversal

BFS (breadth-first search):

crystal-cli bfs <vertex_id>
crystal-cli bfs <vertex_id> --depth 3
crystal-cli bfs <vertex_id> --depth 5 --dir both --edge-type knows

DFS (depth-first search):

crystal-cli dfs <vertex_id>
crystal-cli dfs <vertex_id> --depth 4 --edge-type accessed

Shortest path:

crystal-cli shortest-path <from_id> <to_id>
crystal-cli shortest-path <from_id> <to_id> --dir both
crystal-cli shortest-path <from_id> <to_id> --edge-type knows

All paths:

crystal-cli all-paths <from_id> <to_id>
crystal-cli all-paths <from_id> <to_id> --depth 4
crystal-cli all-paths <from_id> <to_id> --depth 3 --dir both

Import/Export

Export the entire graph to JSON:

crystal-cli export graph.json          # save to file
crystal-cli export                     # print to stdout
crystal-cli export > backup.json       # redirect to file

Import a graph from JSON:

crystal-cli import graph.json

The import creates new vertices and edges with new IDs. Edge source/target references are automatically remapped to the new vertex IDs.

Export format:

{
  "vertices": [
    {
      "id": "...",
      "type": "Person",
      "labels": ["suspect"],
      "properties": {"name": "Alice"},
      "created_at": "...",
      "updated_at": "..."
    }
  ],
  "edges": [
    {
      "id": "...",
      "source_id": "...",
      "target_id": "...",
      "type": "knows",
      "properties": {"since": "2020"},
      "directed": true,
      "weight": 1,
      "created_at": "...",
      "updated_at": "..."
    }
  ]
}

Examples

Investigation Workflow

# Create entities
crystal-cli vertex create Person name="John Doe" email=john@example.com
crystal-cli vertex create Domain fqdn=suspicious.com
crystal-cli vertex create IPAddress ip=203.0.113.42

# Get IDs from output, then link them
crystal-cli edge create $PERSON_ID $DOMAIN_ID registered_domain date=2025-01-15
crystal-cli edge create $DOMAIN_ID $IP_ID resolves_to first_seen=2025-02-01

# Explore connections
crystal-cli vertex neighbors $PERSON_ID --dir out
crystal-cli bfs $PERSON_ID --depth 3

# Find connection between two entities
crystal-cli shortest-path $PERSON_ID $IP_ID --dir both

# Export for reporting
crystal-cli export investigation.json

Dialogue Tree Workflow

# Create dialogue nodes
crystal-cli vertex create DialogueNode speaker=NPC text="Welcome, traveler."
crystal-cli vertex create DialogueNode speaker=Player text="Where is the temple?"
crystal-cli vertex create DialogueNode speaker=NPC text="North, past the river."

# Link with choices
crystal-cli edge create $NODE1 $NODE2 choice order:=1
crystal-cli edge create $NODE2 $NODE3 leads_to

# Walk the tree
crystal-cli vertex neighbors $NODE1 --dir out
crystal-cli dfs $NODE1 --depth 10 --edge-type choice