# Traverse - Full LLM Reference > Traverse is Truespar's in-memory graph database with disk persistence. It supports Cypher and ISO GQL queries, the Bolt protocol (Neo4j driver compatible), an HTTP REST API, gRPC, a built-in MCP server for AI assistants, 36+ graph algorithms, APOC compatibility, ML pipelines, and a WebAssembly build that runs in the browser. ## Overview - **Version:** 0.8.2 - **Bolt protocol:** port 7690 (configurable via `--listen`) - **HTTP API + Studio:** port 7691 (configurable via `--http-listen`) - **gRPC:** port 50051 (configurable via `--grpc-listen`) - **Auth:** API key with `tvs_` prefix. Methods: `Authorization: Bearer tvs_...` or `X-API-Key: tvs_...` header or `?token=tvs_...` query param - **Cypher:** openCypher compatible (99.95% TCK compliance) plus the Cypher 25 surface (quantified path patterns, SEARCH, COLLECT{}, CALL{} IN TRANSACTIONS, dynamic labels, composable SHOW) - **GQL:** 100% ISO/IEC 39075 conformance - select with `X-Query-Dialect: gql` header or client dialect options - **APOC:** built-in compatibility layer, 246 functions + 190 procedures, no plugin - **GDS:** 36+ algorithms via `traverse.*` plus `gds.*` compatibility (graph catalog, mutate mode) - **ML:** `traverse.ml.pipeline.nodeClassification.*` - GNN training (GCN, GraphSAGE) and prediction from Cypher, `.tvmodel` persistence - **Indexes:** range, composite, relationship-property, vector (HNSW), full-text (BM25), text (trigram), point (spatial) - **Durability:** snapshot by default; `TRAVERSE_DURABILITY=wal` for per-commit write-ahead logging - **Bolt versions:** 5.1 through 6.0 - **Persistence:** in-memory with `.tvdb` file persistence. Auto-saved on graceful shutdown. Manual: `POST /api/save`. - **MCP endpoint:** `POST /api/mcp` (JSON-RPC 2.0, protocol version 2025-11-25) ## Installation The download endpoints below are **version-agnostic** - they always resolve to the current release, so no version needs to be pinned. Valid `platform` values are `linux-x64` and `windows-x64`. To try Traverse with no install at all, the full engine also runs in the browser via WebAssembly at https://traverse.truespar.com/ **Linux (x86-64):** ``` curl -L "https://truespar.com/api/versions/traverse/latest/download?platform=linux-x64" -o traverse.tar.gz tar xzf traverse.tar.gz ./traverse-server --data ./data --api-key tvs_your_key --license-key tskey_your_license ``` The Linux tarball contains `traverse-server`, `traverse-cli`, `traverse-admin`, and `traverse-bench`. **Windows (x86-64):** download `https://truespar.com/api/versions/traverse/latest/download?platform=windows-x64` (a `.zip` with Authenticode-signed `.exe` binaries), extract, then run `traverse-server.exe --data ./data --api-key tvs_your_key --license-key tskey_your_license`. **Docker:** `docker pull truespar/traverse` - expose ports 7690, 7691. ### Version discovery (for automation) `GET https://truespar.com/api/versions/traverse/latest?platform=linux-x64` returns JSON: `{"version": "0.8.2", "releaseNotes": "...", "publishedAt": "...", "downloadAvailable": true}`. Use `platform=windows-x64` for the Windows build. Human-readable install guide: https://truespar.com/traverse/docs/v1/getting-started ## HTTP API Endpoints Base URL: `http://localhost:7691` ### Health & Status (no auth required) - `GET /api/health` - server status, uptime, memory, database stats, license - `GET /api/ready` - readiness probe (200 when ready) - `GET /metrics` - Prometheus-format metrics - `GET /api/docs` - interactive Scalar API reference - `GET /api/openapi.json` - OpenAPI 3.1.0 specification ### Query Execution - `POST /api/query` - execute Cypher (or GQL) query - Body: `{"query": "MATCH (n) RETURN n LIMIT 10", "database": "mydb", "parameters": {}}` - GQL dialect: add header `X-Query-Dialect: gql` (or body field `"dialect": "gql"`) - Response: columns, rows (max 10,000), total_rows, query_type, timing - Async: `?async=true` returns task ID for polling ### Database Management - `GET /api/databases` - list all databases (name, node/edge counts, aliases, memory) - `POST /api/databases` - create database: `{"name": "mydb"}` - `DELETE /api/databases/{name}` - drop database (requires `--allow-drop-database`) - `POST /api/databases/{name}/rename` - rename: `{"name": "newname"}` - `POST /api/databases/{name}/unload` - unload from memory (keeps .tvdb file) - `POST /api/databases/load` - load .tvdb from disk: `{"path": "file.tvdb"}` ### Schema - `GET /api/schema` - labels, relationship types, property keys, indexes, constraints - Optional: `?database=name` ### Data Import - `POST /api/import` - Cypher statements (one per line, async) - `POST /api/import/csv` - CSV as nodes (columns: string, integer, float, boolean) - `POST /api/import/csv/edges` - CSV as relationships (requires `:START_ID`, `:END_ID`) ### File Management - `GET /api/files` - list .tvdb files - `GET /api/files/{name}` - download .tvdb (streamed) - `PUT /api/files/{name}` - upload .tvdb - `DELETE /api/files/{name}` - delete .tvdb file ### Database Aliases - `GET /api/aliases` - list aliases - `POST /api/aliases` - create: `{"name": "alias", "database": "target"}` - `PUT /api/aliases/{name}` - update target - `DELETE /api/aliases/{name}` - delete alias ### User Management - `GET /api/users` - list users - `POST /api/users` - create: `{"username": "...", "password": "...", "role": "EDITOR"}` - `PUT /api/users/{username}` - update password or role - `DELETE /api/users/{username}` - delete user - Roles: ADMIN (full), EDITOR (queries/writes), READER (read-only) ### Async Tasks - `GET /api/tasks/{id}` - poll status of async operations - Returns: id, operation, status (running/completed/failed), result, timing ### Persistence - `POST /api/save` - save all databases immediately (async) ### License - `POST /api/license/activate` - start activation - `POST /api/license/activate/poll/{id}` - poll activation - `POST /api/license/devices` - list devices - `DELETE /api/license/devices/{id}` - remove device - `POST /api/license/deactivate` - deactivate license - `GET /api/update/download` - download latest binary ## Cypher Query Language ### Clauses `MATCH`, `OPTIONAL MATCH`, `CREATE`, `MERGE` (with `ON CREATE SET` / `ON MATCH SET`), `DELETE`, `DETACH DELETE`, `SET`, `REMOVE`, `WITH`, `RETURN`, `WHERE`, `ORDER BY`, `LIMIT`, `SKIP`, `UNION`, `UNION ALL`, `UNWIND`, `CALL` (with `YIELD`), `FOREACH`, `LOAD CSV`, `EXPLAIN`, `PROFILE` ### Pattern Syntax ``` (n) -- anonymous node (n:Person) -- labeled node (n:Person {name: "Alice"}) -- node with properties (a)-[r:KNOWS]->(b) -- directed relationship (a)-[r:KNOWS|LIKES]->(b) -- multiple types (a)-[*1..3]->(b) -- variable-length path p = (a)-[:TYPE]->(b) -- named path ``` ### Data Types `NULL`, `BOOLEAN`, `INTEGER` (64-bit), `FLOAT` (64-bit), `STRING` (UTF-8), `LIST`, `MAP`, `NODE`, `RELATIONSHIP`, `PATH`, `DATE`, `LOCAL_TIME`, `TIME`, `LOCAL_DATE_TIME`, `DATE_TIME`, `DURATION`, `POINT` (spatial), `BYTEARRAY` (binary) ### Operators - Comparison: `=`, `<>`, `<`, `>`, `<=`, `>=` - Boolean: `AND`, `OR`, `XOR`, `NOT` - String: `STARTS WITH`, `ENDS WITH`, `CONTAINS`, `=~` (regex) - Null: `IS NULL`, `IS NOT NULL` - List: `IN`, `list[index]`, `list[start..end]` - Math: `+`, `-`, `*`, `/`, `%`, `^` ### Functions **String:** `toUpper()`, `toLower()`, `trim()`, `replace()`, `substring()`, `split()`, `reverse()`, `left()`, `right()` **Math:** `abs()`, `ceil()`, `floor()`, `round()`, `sqrt()`, `log()`, `exp()`, `rand()` **Aggregation:** `count()`, `sum()`, `avg()`, `min()`, `max()`, `collect()`, `percentileDisc()`, `stDev()` **List:** `size()`, `head()`, `last()`, `tail()`, `range()`, `coalesce()` **Predicate:** `exists()`, `all()`, `any()`, `none()`, `single()` **Type:** `toString()`, `toInteger()`, `toFloat()`, `toBoolean()`, `typeName()` **Graph:** `id()`, `labels()`, `type()`, `keys()`, `properties()`, `startNode()`, `endNode()` **Path:** `nodes()`, `relationships()`, `length()` **Temporal:** `date()`, `datetime()`, `time()`, `duration()`, `timestamp()` ### Schema Commands ```cypher CREATE INDEX FOR (n:Person) ON (n.name); CREATE INDEX rel_idx FOR ()-[r:KNOWS]-() ON (r.since); CREATE EDGE INDEX ON :KNOWS(since); CREATE VECTOR INDEX v FOR (m:Movie) ON m.embedding OPTIONS { indexConfig: {'vector.dimensions': 128, 'vector.similarity_function': 'cosine'}}; CREATE FULLTEXT INDEX docs FOR (d:Doc) ON EACH [d.title, d.body]; CREATE TEXT INDEX emails FOR (u:User) ON (u.email); CREATE POINT INDEX cities FOR (c:City) ON (c.loc); CREATE CONSTRAINT FOR (n:Person) REQUIRE n.email IS UNIQUE; CREATE CONSTRAINT FOR (n:Person) REQUIRE n.age IS :: INTEGER; CREATE CONSTRAINT FOR (p:Person) REQUIRE (p.first, p.last) IS NODE KEY; SHOW INDEXES; SHOW CONSTRAINTS; SHOW SETTINGS; ANALYZE GRAPH; ``` ### Shortest Path ```cypher MATCH p = shortestPath((a)-[*..15]->(b)) WHERE id(a) = 1 AND id(b) = 99 RETURN p MATCH p = allShortestPaths((a)-[*..5]->(b)) WHERE ... RETURN p ``` ### Parameters ```cypher MATCH (p:Person) WHERE p.age > $minAge RETURN p -- Pass: {"parameters": {"minAge": 30}} ``` ### Expressions - CASE: `CASE WHEN x > 0 THEN 'pos' ELSE 'neg' END` - List comprehension: `[x IN range(1,10) WHERE x % 2 = 0 | x * x]` - Pattern comprehension: `[(p)-[:KNOWS]->(f) | f.name]` - Existential: `EXISTS { (p)-[:KNOWS]->(:Person) }` - Count subquery: `COUNT { (p)-[:KNOWS]->() } > 5` ## GQL Dialect (ISO/IEC 39075) - 100% conformance (40/40 mandatory, 60/60 optional features) - Available on: HTTP API (`X-Query-Dialect: gql`), all embedded SDKs and HTTP clients (dialect option), Studio dialect picker, browser WASM build - Not available on: Bolt, gRPC, CLI (openCypher only) - Server capability advertised in `GET /api/health` → `features.gql` ## APOC Built-in APOC core catalog (246 functions, 190 procedures). Highlights: - `apoc.load.json/csv/xml/jsonParams/jdbc` (jdbc: `jdbc:sqlite:`, `jdbc:postgresql:///`) - `apoc.export.*` / `apoc.import.*` - JSON, CSV, GraphML, Cypher script, Arrow IPC - `apoc.periodic.iterate(outer, inner, {batchSize, parallel})` - batched updates - `apoc.trigger.add(name, statement, {phase})` - graph event triggers - `apoc.coll.*`, `apoc.map.*`, `apoc.text.*`, `apoc.agg.*`, `apoc.refactor.*`, `apoc.meta.*`, `apoc.create.*` ## Graph Data Science - 36+ algorithms: `CALL traverse..(config)` - modes: stream / stats / write - Categories: centrality (pageRank, betweenness, ...), community (louvain, leiden, wcc, ...), paths (dijkstra, astar, yens, ...), similarity, link prediction, embeddings (fastRP, node2vec, graphSage, hashGNN) - `gds.*` compatibility: `gds.graph.project` catalog, algorithm execution on projections, `.mutate` mode ## ML Pipelines - `traverse.ml.pipeline.nodeClassification.create/addNodeProperty/selectFeatures/addGcn/addGraphSage` - `...train(graph, {pipeline, targetProperty, modelName, epochs, learningRate})` → async, YIELD jobId; poll `...trainStatus(jobId)` - `...predict.stream(graph, {modelName})` YIELD nodeId, predictedClass, predictedProbabilities; `...predict.write` writes back - `traverse.ml.model.list/drop/export/setMetadata` - models persist as `.tvmodel` next to the `.tvdb` - Requires server built with the `ml` feature (`features.ml` in health); in-browser inference via `@truespar/traverse-ml-wasm` ## Browser (WASM) - Full engine in a browser tab: https://traverse.truespar.com (Cypher, GQL, GDS, Studio, OPFS persistence) - Embeddable npm package: `@truespar/traverse-wasm` (~2.5 MB gz) - `db.query(text, params, {dialect: 'gql'})` - `.tvdb` files are interchangeable between browser and server ## Bolt Protocol - **Port:** 7690 (default) - **Versions:** 5.1 through 6.0 - **TLS:** `bolt+s://` scheme with `--tls-cert` and `--tls-key` - **Compatible drivers:** Neo4j drivers for Python, JavaScript, Java, Go, .NET, Rust - **0.8.0:** Bolt 5.7+ failure metadata (GQLSTATUS), transient-error retry classification, mid-stream FAILURE delivery Connection URI: `bolt://localhost:7690` ## gRPC API - **Port:** 50051 (default) - **Service:** `TraverseService` (package `traverse.v1`) - **21 RPCs:** ExecuteQuery, QueryChannel, CreateNode, GetNode, DeleteNode, BatchCreateNodes, CreateEdge, GetEdge, DeleteEdge, BatchCreateEdges, UpdateProperties, BeginTransaction, CommitTransaction, RollbackTransaction, CreateIndex, DropIndex, GetLabels, GetRelationshipTypes, GetPropertyKeys, GetNodeCount, GetEdgeCount ## MCP Server Endpoint: `POST /api/mcp` - JSON-RPC 2.0, Streamable HTTP transport, protocol version 2025-11-25. Auth: same API key as HTTP API via `Authorization: Bearer tvs_...` or `X-API-Key: tvs_...`. ### Available Tools | Tool | Required Args | Description | |------|---------------|-------------| | `query` | `cypher` | Run Cypher query (read/write, parameterized, max 500 rows) | | `schema` | - | Get labels, types, properties, indexes, constraints | | `databases` | - | List databases with node/edge counts and status | | `search_nodes` | `label` | Find nodes by label and optional property filter (max 100) | | `shortest_path` | `from_id`, `to_id` | Find shortest path between two nodes | | `neighbors` | `node_id` | Get neighbors with optional direction/type filter (max 50) | All tools accept optional `database` argument. ### Claude Desktop Configuration ```json { "mcpServers": { "traverse": { "url": "http://localhost:7691/api/mcp", "headers": { "Authorization": "Bearer tvs_your_api_key" } } } } ``` ## CLI (traverse-cli) ``` traverse-cli # Interactive REPL traverse-cli "MATCH (n) RETURN n LIMIT 5" # Single query traverse-cli -s queries.cypher # Script file traverse-cli -f database.tvdb # Embedded mode (no server) ``` Options: `--bolt URI`, `--format table|json|csv`, `--user`, `--password`, `--database` Meta-commands: `:help`, `:quit`, `:format`, `:param key => value`, `:source file`, `:use database` ## Admin Tool (traverse-admin) ``` traverse-admin import --nodes Person=people.csv --edges KNOWS=knows.csv -o output.tvdb traverse-admin cypher-import -i data.cypher -o output.tvdb traverse-admin update --download ``` ## Client SDKs & Drivers | Language | Package | Protocol | |----------|---------|----------| | .NET | `Traverse.Bolt`, `Traverse.Http`, `Traverse.Grpc`, `Traverse.Embedded` | Bolt, HTTP, gRPC, Embedded | | Python | `traverse-embedded` (pip, native PyO3), `traverse-http` (pip), Neo4j driver | Embedded, HTTP, Bolt | | Java | `com.truespar:traverse-http`, `com.truespar:traverse-java`, Neo4j driver | HTTP, Embedded, Bolt | | Node.js | `@truespar/traverse-http`, Neo4j driver | HTTP, Bolt | | Go | `traverse-sdk-go` (download from truespar.com), Neo4j driver | HTTP, Embedded, Bolt | Bolt-compatible: any Neo4j driver works with `bolt://localhost:7690`. ## Server Configuration | Flag | Default | Description | |------|---------|-------------| | `--listen` | `0.0.0.0:7690` | Bolt listen address | | `--http-listen` | `0.0.0.0:7691` | HTTP API + Studio | | `--grpc-listen` | `0.0.0.0:50051` | gRPC listen address | | `--data` | - | .tvdb file or directory | | `--default-db` | `traverse` | Default database name | | `--memory-limit` | 90% RAM | Memory limit (e.g., `32GB`) | | `--api-key` | auto-generated | HTTP API key (`tvs_` prefix) | | `--auth` | - | Seed admin credentials (`user:pass`) | | `--query-timeout` | unlimited | Query timeout (ms) | | `--slow-query-threshold` | - | Slow query log threshold (ms) | | `--allowed-ips` | all | CIDR allowlist | | `--allow-drop-database` | true | Database deletion via HTTP/Studio (set env/TOML to `false` to lock down) | | `--tls-cert` | - | TLS certificate | | `--tls-key` | - | TLS private key | | `--license-key` | - | License key (`tskey_` prefix) | | `--durability` | `snapshot` | `snapshot` or `wal` (per-commit crash durability) | | `--server-agent` | `Traverse/` | Bolt agent string; set to `Neo4j/5.26.0` for clients that require a genuine Neo4j instance (G.V(), py2neo) | | `--log-level` | `info` | trace/debug/info/warn/error | | `--log-dir` | stdout | Daily-rotated log file directory | Environment variables use `TRAVERSE_` prefix. TOML config: `traverse.toml`. Priority: CLI > environment > TOML > defaults. ## User Roles | Role | Query | Write | Schema | Users | Admin | |------|-------|-------|--------|-------|-------| | READER | Yes | No | No | No | No | | EDITOR | Yes | Yes | Yes | No | No | | ADMIN | Yes | Yes | Yes | Yes | Yes | ## Error Response Format ```json {"error": "error description"} ``` Status codes: 200 (success), 202 (async task created), 400 (invalid input), 401 (missing/invalid key), 403 (forbidden), 404 (not found), 409 (conflict), 500 (server error).