ArcFlow
Company
Managed Services
Markets
  • News
  • LOG IN
  • GET STARTED

OZ brings Visual Intelligence to physical venues, a managed edge layer that lets real-world environments see, understand, and act in real time.

Talk to us

ArcFlow

  • World Models
  • Sensors

Managed Services

  • OZ VI Venue 1
  • Case Studies

Markets

  • Sports
  • Broadcasting
  • Robotics

Company

  • About
  • Technology
  • Careers
  • Contact

Ready to see it live?

Talk to the OZ team about deploying at your venues, from a single pilot match to a full regional rollout.

Schedule a deployment review

© 2026 OZ. All rights reserved.

LinkedIn
ArcFlow Docs
Get Started
  • Get Started
  • Quickstart
  • Installation
  • Project Setup
  • Platforms
  • Bindings
  • Licensing
  • Pricing
Capabilities
  • Vector Search
  • Graph Algorithms
  • Sync
  • MCP Server (AI Agents)
  • Live Queries
  • Programs
  • Temporal
  • Spatial
  • Trusted RAG
  • Behavior Graph
  • Agent-Native
  • Event Sourcing
  • GPU Acceleration
  • Intent Relay
Concepts
  • World Model
  • Graph Model
  • Query Language (GQL)
  • Graph Patterns
  • SQL vs GQL
  • Parameters
  • Query Results
  • Persistence & WAL
  • Error Handling
  • Observations & Evidence
  • Confidence & Provenance
  • Proof Artifacts & Gates
  • Skills
GQL / WorldCypher
  • Overview
  • MATCH
  • WHERE
  • RETURN
  • OPTIONAL MATCH
  • CREATE
  • SET
  • MERGE
  • DELETE
  • REMOVE
  • WITH
  • UNION
  • UNWIND
  • CASE
  • Spatial Queries
  • Temporal Queries
  • Algorithms Reference
  • Triggers
Schema
  • Overview
  • Indexes
  • Constraints
  • Data Types
Functions
  • Built-in Functions
  • Aggregations
  • Procedures
  • Shortest Path
  • EXPLAIN
  • PROFILE
Skills
  • Overview
  • CREATE SKILL
  • PROCESS NODE
  • REPROCESS EDGES
Operations
  • CLI
  • REPL Commands
  • Snapshot & Restore
  • Server Modes & PG Wire
  • Persistence
  • Import & Export
  • Docker
  • Architecture
  • Cloud Architecture
  • Sync Protocol (Deep Dive)
Guides
  • Agent Integration
  • World Model
  • Graph Model Fundamentals
  • Trusted RAG
  • Using Skills
  • Behavior Graphs
  • Swarm & Multi-Agent
  • Migration Guide
  • Filesystem Workspace
  • From SQL to GQL
  • ArcFlow for Coding Agents
  • Data Quality & Pipeline Integrity
  • Code Intelligence
Tutorials
  • Knowledge Graph
  • Entity Linking
  • Vector Search
  • Graph Algorithms
Recipes
  • CRUD
  • Multi-MATCH
  • MERGE (Upsert)
  • Full-Text Search
  • Temporal Queries
  • Batch Projection
  • GraphRAG
Use Cases
  • Agent Tooling
  • Knowledge Management
  • RAG Pipeline
  • Fraud Detection
  • Sports Analytics
  • Grounded Neural Objects
  • Behavior Graphs
  • Autonomous Systems
  • Digital Twins
  • Robotics & Perception
Reference
  • TypeScript API
  • GQL Conformance
  • Compatibility Matrix
  • Glossary
  • Data Types
  • Operators
  • Error Codes
  • Known Issues

Server & Access Layers

ArcFlow adapts to how you deploy. In-process by default. Add --pg for PostgreSQL clients. Add --http for REST. Add --serve for TCP. The engine is the same; the access layer changes.

arcflow                              # In-process REPL (default)
arcflow --pg 5432                    # PostgreSQL wire protocol
arcflow --http 8080                  # HTTP API
arcflow --serve 7687                 # TCP server
arcflow-mcp --data-dir ./graph       # MCP server for cloud chat UIs (ChatGPT, Claude.ai)

Run multiple servers concurrently on the same graph store:

arcflow --pg 5432 --serve 7687 --http 8080 --data-dir ./data

All access layers share the same engine, the same query compiler, the same storage. There are no "modes" to configure. The engine auto-detects available resources (CPU cores, memory) and adapts regardless of which access layer you use.

In-Process (default)#

No flags needed. When used as a Rust library, import arcflow and call functions directly. Zero serialization. Zero network latency. This is the fastest path.

use arcflow::GraphStore;
 
let mut store = GraphStore::new();
// Direct function calls — no serialization, no network
store.create_node(vec![Label::new("Person")], props);

As a CLI, launch the interactive REPL:

arcflow
arcflow --data-dir ./mydb        # persistent storage
arcflow --playground             # preloaded demo data

For non-interactive single-query execution:

arcflow query "MATCH (n:Person) RETURN n.name" --json
{"columns":["n.name"],"rows":[{"n.name":"Alice"},{"n.name":"Bob"}]}

See REPL Reference for all meta-commands and agent usage patterns.

PostgreSQL Wire Protocol#

Start a PostgreSQL-compatible server:

arcflow --pg 5432
arcflow --pg 5432 --data-dir ./mydb
arcflow --pg 5432 --pg-password my-secret --pg-log-queries

Connect with any PostgreSQL client:

psql -h localhost -p 5432
stadium=# MATCH (p:Player)-[:NEAR {distance: 2.0}]->(b:Ball)
          RETURN p.name, p.speed;
 name    | speed
---------+-------
 Salah   | 32.1
 Haaland | 28.7
(2 rows)

Protocol Details#

Full PostgreSQL wire protocol v3 implementation:

  • Startup handshake: SSL rejection, protocol negotiation, authentication, parameter status, backend key data
  • Simple Query protocol: RowDescription + DataRow + CommandComplete
  • Extended Query protocol: Parse/Bind/Describe/Execute/Sync/Close
  • Error mapping: ArcFlow TypedError maps to PG ErrorResponse with SQLSTATE codes (42000 syntax, 40001 serialization, 57014 timeout, etc.)
  • Type inference: columns auto-typed as bool/int8/float8/text based on data sampling

SQL Shims#

SQL compatibility shims handle common PostgreSQL client expectations:

SQL StatementArcFlow Response
SET ...Acknowledged silently
BEGIN / COMMIT / ROLLBACKAcknowledged (single-node, no distributed transactions)
SHOW SERVER_VERSIONReturns ArcFlow version
SELECT VERSION()Returns ArcFlow build info
SELECT CURRENT_SCHEMA()Returns "public"
DISCARD ALLAcknowledged (psql compatibility)
pg_catalog / information_schema queriesEmpty result set

This means ORMs, connection poolers (PgBouncer), and visualization tools (Grafana) connect without modification. WorldCypher queries run transparently underneath.

Authentication#

arcflow --pg 5432 --pg-password my-secret

When --pg-password is set, the server requires cleartext password authentication. Clients that don't provide the correct password receive SQLSTATE 28P01 (invalid_password).

Query Logging#

arcflow --pg 5432 --pg-log-queries

Logs every query to stderr with the client's address, useful for debugging and audit trails.

Compatible Clients#

Tested with: psql, pgAdmin, Grafana, Python psycopg2, Go pgx, Node.js node-postgres, Rust sqlx. Any client that speaks PostgreSQL wire protocol v3 should work.

The queries sent over this connection are WorldCypher (ISO GQL), not SQL. See From SQL to GQL for the full adoption path — from psql connection to native SDK to full GQL features.

HTTP API#

Start the HTTP server on any port:

arcflow --http 8080
arcflow --http 8080 --data-dir ./mydb
arcflow --http 8080 --data-dir ./mydb --api-key my-secret-token

The server prints its configuration to stderr on startup:

WorldCypher HTTP API listening on http://0.0.0.0:8080
  GET  /query?q=MATCH+(n)+RETURN+n
  POST /query  (body = query string)
  GET  /status
  GET  /health    (liveness probe)
  GET  /ready     (readiness probe)
  Auth: API key required (Authorization: Bearer <key>)
  Data dir: ./mydb

POST /query#

Execute a WorldCypher query. The request body is the raw query string (not JSON-wrapped).

curl -X POST http://localhost:8080/query \
  -d "MATCH (n:Person) RETURN n.name, n.age"

Response (200 OK):

{
  "columns": ["n.name", "n.age"],
  "rows": [
    {"n.name": "Alice", "n.age": "30"},
    {"n.name": "Bob", "n.age": "25"}
  ]
}

Error response (400 Bad Request):

{"error": true, "code": "COMPILE_ERR", "message": "Unexpected token at position 12"}

Mutation example:

curl -X POST http://localhost:8080/query \
  -d "CREATE (n:Person {name: 'Charlie', age: 35}) RETURN n"

Algorithm example:

curl -X POST http://localhost:8080/query \
  -d "CALL algo.pageRank()"

GET /query?q=...#

Execute a query via URL parameter. URL-encode the query string.

curl "http://localhost:8080/query?q=MATCH+(n:Person)+RETURN+n.name"

Response format is identical to POST /query.

GET /status#

Returns engine metadata: version, node count, relationship count, skill count.

curl http://localhost:8080/status
{
  "name": "worldcypher",
  "version": "1.5.0",
  "nodes": 12,
  "relationships": 15,
  "skills": 3
}

GET /health#

Kubernetes liveness probe. Always returns 200 if the process is running. Does not require authentication.

curl http://localhost:8080/health
{"status": "healthy"}

GET /ready#

Kubernetes readiness probe. Returns 200 with current node/relationship counts. Does not require authentication.

curl http://localhost:8080/ready
{"status": "ready", "nodes": 12, "relationships": 15}

Authentication#

Pass --api-key to require a Bearer token on all requests except /health and /ready.

# Start with auth
arcflow --http 8080 --api-key my-secret-token
 
# Authenticated request
curl -X POST http://localhost:8080/query \
  -H "Authorization: Bearer my-secret-token" \
  -d "MATCH (n) RETURN count(*)"
 
# Unauthenticated request (returns 401)
curl -X POST http://localhost:8080/query \
  -d "MATCH (n) RETURN count(*)"

401 response:

{"error": "unauthorized", "message": "Invalid or missing API key. Use Authorization: Bearer <key>"}

CORS#

The HTTP server sets Access-Control-Allow-Origin: * on all responses. OPTIONS preflight requests return 204 with appropriate CORS headers.

TCP Server#

Start the TCP server:

arcflow --serve 7687
arcflow --serve 7687 --data-dir ./mydb

Startup output:

WorldCypher server listening on 0.0.0.0:7687
Protocol: one query per line, JSON response per line
Data dir: ./mydb

Protocol#

Line-delimited text protocol. Send one WorldCypher query per line. Receive one JSON response per line. No framing, no headers — raw TCP.

Example session#

# Connect
nc localhost 7687
 
# Send a query (you type this)
CREATE (n:Person {name: 'Alice', age: 30}) RETURN n
 
# Receive JSON response (server returns this)
{"columns":["n"],"rows":[{"n":"{name: Alice, age: 30}"}]}
 
# Send another query
MATCH (n:Person) RETURN n.name, n.age
 
# Response
{"columns":["n.name","n.age"],"rows":[{"n.name":"Alice","n.age":"30"}]}

Error response#

{"error": true, "code": "COMPILE_ERR", "message": "Unexpected token at position 5"}

Scripting with TCP#

# Single query
echo "MATCH (n) RETURN count(*)" | nc localhost 7687
 
# Multiple queries
printf "CREATE (n:A {x: 1})\nMATCH (n) RETURN count(*)\n" | nc localhost 7687

Concurrency#

Each TCP client gets its own thread. Multiple clients can connect simultaneously. The server engine is thread-safe: multiple concurrent readers, single writer with exclusive access.

MCP Server#

The MCP (Model Context Protocol) server is the bridge for cloud chat interfaces — ChatGPT, Claude.ai, Gemini web, and other environments with no local shell or filesystem access. These interfaces cannot run arcflow query as a binary, so MCP is the only way to give them graph tool access.

For local environments (CLI agents, application code), use arcflow query "..." --json instead — it is faster and requires no protocol overhead.

arcflow-mcp                        # in-memory
arcflow-mcp --data-dir ./mydb      # persistent

Protocol#

Stdio JSON-RPC 2.0. Send one JSON object per line to stdin. Receive one JSON object per line from stdout. Notifications (no id field) do not produce responses.

Initialization#

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}

Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {"tools": {}},
    "serverInfo": {"name": "arcflow-mcp", "version": "1.5.0"}
  }
}

Tools#

The MCP server exposes 5 tools. Call them via tools/call:

{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"TOOL_NAME","arguments":{...}}}

get_schema

Returns labels, relationship types, property keys, indexes, constraints, node/relationship counts, and per-label schema detail. No arguments.

{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_schema","arguments":{}}}

Response text:

Labels: Person, Company
Relationship types: WORKS_AT, KNOWS
Property keys: name, age, domain
Indexes: :Person.name
Constraints: UNIQUE :Person.email
Nodes: 8, Relationships: 5
Schema detail:
  :Person (5 nodes) — properties: name, age, email
  :Company (3 nodes) — properties: name, domain

get_capabilities

Returns available algorithms, procedures, built-in functions, observation classes, and query features. No arguments.

{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_capabilities","arguments":{}}}

Response includes: 27 graph algorithms (pageRank, louvain, dijkstra, graphRAG, etc.), 100+ procedures, 83 built-in functions, observation classes (observed, inferred, predicted), and all supported query clauses.

read_query

Execute a read-only WorldCypher query. Rejects CREATE, SET, DELETE, MERGE, REMOVE — use write_query for mutations.

Input schema:

ParameterTypeRequiredDescription
cypherstringyesWorldCypher query (read-only)
{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"read_query","arguments":{"cypher":"MATCH (n:Person) RETURN n.name, n.age"}}}

Response text (JSON-formatted string):

{
  "columns": ["n.name", "n.age"],
  "row_count": 2,
  "rows": [
    {"n.name": "Alice", "n.age": "30"},
    {"n.name": "Bob", "n.age": "25"}
  ]
}

If a mutation is attempted, the response has isError: true:

{
  "content": [{"type": "text", "text": "read_query rejects mutating queries (CREATE, SET, DELETE, MERGE, REMOVE). Use write_query instead."}],
  "isError": true
}

write_query

Execute a mutating WorldCypher query. Supports CREATE, SET, DELETE, MERGE, REMOVE, DETACH DELETE.

Input schema:

ParameterTypeRequiredDescription
cypherstringyesWorldCypher mutation query
{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"write_query","arguments":{"cypher":"CREATE (n:Person {name: 'Alice', age: 30})"}}}

Response format is identical to read_query.

graph_rag

Run the trusted GraphRAG pipeline — combines graph traversal, vector search, and confidence-weighted ranking to answer a natural language question.

Input schema:

ParameterTypeRequiredDescription
querystringyesNatural language question for the world model
{"jsonrpc":"2.0","id":6,"method":"tools/call","params":{"name":"graph_rag","arguments":{"query":"What do we know about water on Mars?"}}}

Response text (JSON-formatted string):

{
  "query": "What do we know about water on Mars?",
  "results": [
    {"name": "Water ice", "confidence": "0.95", "observation_class": "observed", "note": "Spectral analysis confirmed"},
    {"name": "Subsurface lake", "confidence": "0.7", "observation_class": "inferred", "note": "Radar echo pattern"}
  ],
  "result_count": 2
}

Listing available tools#

{"jsonrpc":"2.0","id":7,"method":"tools/list","params":{}}

Returns all 5 tool definitions with input schemas.

Thread Safety#

All server access layers (HTTP, TCP, MCP) share one graph engine with read/write isolation:

  • Multiple concurrent readers: MATCH queries run in parallel across threads.
  • Single writer with exclusive access: CREATE/SET/DELETE acquire a write lock. Other queries wait.
  • Automatic persistence: After mutations, the snapshot is written to disk if --data-dir is set.

The REPL runs single-threaded (no locking overhead).

Persistence#

All access layers support --data-dir for durable storage:

arcflow --data-dir ./production-db                # REPL
arcflow --http 8080 --data-dir ./production-db    # HTTP
arcflow --serve 7687 --data-dir ./production-db   # TCP
arcflow-mcp --data-dir ./production-db                # MCP

Storage uses two files in the data directory:

FilePurpose
worldcypher.snapshot.jsonFull graph state, written on checkpoint/exit
worldcypher.walAppend-only write-ahead log for crash recovery

On startup, the engine restores from the snapshot, then replays any WAL entries written after the last snapshot.

Auto-Detection#

The engine detects available resources and adapts regardless of access layer:

  • CPU cores: Thread pool scales to available cores for parallel query execution.
  • Memory: Graph storage is in-process — no external database, no network serialization.
  • GPU: When compiled with GPU support, CUDA kernels accelerate graph algorithms automatically. The access layer (HTTP, TCP, etc.) is unaffected.

For AI Agents#

Choose the access layer based on your environment:

EnvironmentRecommended access layer
Local filesystem accessarcflow query "..." --json
Existing PostgreSQL toolingarcflow --pg 5432 + psql/pgAdmin/Grafana
Long-running session, many queriesarcflow --http 8080 + curl
Cloud IDE, no filesystemarcflow-mcp --data-dir ./graph
Rust applicationarcflow crate (napi-rs for Node.js, or Rust crate direct)

For single queries, always prefer arcflow query "..." --json. It starts, executes, prints JSON, and exits. No server process to manage.

For batch operations, start the HTTP server once and issue requests:

# Terminal 1: start server
arcflow --http 8080 --data-dir ./mydb &
 
# Terminal 2: issue queries
curl -s -X POST http://localhost:8080/query -d "CREATE (n:Person {name: 'Alice'})"
curl -s -X POST http://localhost:8080/query -d "MATCH (n) RETURN count(*)"
curl -s http://localhost:8080/status

See Also#

  • REPL Reference — all meta-commands and agent usage
  • Persistence — WAL-backed durable storage
Try it
Open ↗⌘↵ to run
Loading engine…
← PreviousSnapshot & RestoreNext →Persistence