# Strana
Strana is a wire protocol for executing [Cypher](https://opencypher.org/) queries against embedded graph databases over WebSocket. `graphd` is the server that implements it.
Embedded graph databases like [LadybugDB](https://ladybugdb.com/) (formerly [Kuzu](https://kuzudb.com/)) are great for a lot of use cases, but sometimes you need to access your graph over the network. Think [sqld](https://github.com/tursodatabase/libsql/tree/main/libsql-server) for graph databases, inspired by the [Hrana](https://github.com/tursodatabase/libsql/tree/main/libsql-hrana) protocol.
- **strana** — the protocol ([PROTOCOL.md](PROTOCOL.md))
- **graphd** — the server daemon
## Quick start
```bash
cargo build --release
./target/release/graphd
```
`graphd` is now listening on `127.0.0.1:7688`. Connect any WebSocket client to `/ws` and start running Cypher queries.
## Usage
```
graphd [OPTIONS]
```
| `-p, --port` | `7688` | Port to listen on |
| `--host` | `127.0.0.1` | Bind address |
| `-d, --data-dir` | `./data` | Path to the database directory |
| `--token <TOKEN>` | — | Require clients to authenticate with this token |
| `--token-file <PATH>` | — | Load hashed tokens from a JSON file |
| `--generate-token` | — | Print a new token and its SHA-256 hash, then exit |
```bash
# Single token
graphd --token my-secret-token
# Multi-token (from file)
graphd --generate-token # grab the hash
graphd --token-file tokens.json # start with token file
```
The `--token` flag can also be set via the `STRANA_TOKEN` environment variable.
## Protocol
Strana uses a simple JSON-over-WebSocket protocol. See [PROTOCOL.md](PROTOCOL.md) for the full specification.
```
Client Server
|<--- hello_ok { version } --------|
| |
|---- execute { query } ---------->|
|<--- result { columns, rows } ----|
| |
|---- close ---------------------->|
|<--- close_ok --------------------|
```
### Example session (logical messages)
WebSocket uses protobuf binary frames (`proto/strana.proto`). HTTP uses JSON. The messages below show the logical structure:
```
→ hello { token: "my-secret-token" }
← hello_ok { version: "0.1.0" }
→ execute { query: "CREATE NODE TABLE Person(name STRING, age INT64, PRIMARY KEY(name))" }
← result { columns: [], rows: [], timing_ms: 1.2 }
→ execute { query: "CREATE (:Person {name: 'Alice', age: 30})" }
← result { columns: [], rows: [], timing_ms: 0.5 }
→ execute { query: "MATCH (p:Person) RETURN p.name, p.age" }
← result { columns: ["p.name", "p.age"], rows: [["Alice", 30]], timing_ms: 0.3 }
→ close
← close_ok
```
## Authentication
Strana supports three auth modes:
- **Open access** — no `--token` or `--token-file` flag. All clients accepted.
- **Single-token** — `--token <plaintext>`. Clients must send this token in `hello`.
- **Multi-token** — `--token-file <path>`. A JSON file of SHA-256 hashed tokens with labels.
Generate a token and its hash:
```bash
$ graphd --generate-token
Token: strana_a1b2c3d4e5f6...
Hash: e3b0c44298fc1c14...
```
Token file format:
```json
{
"tokens": [
{ "hash": "<sha256-hex>", "label": "my-app" },
{ "hash": "<sha256-hex>", "label": "ci-runner" }
]
}
```
## Tests
```bash
cargo test
```
## Client libraries
_Coming soon — Python and TypeScript clients are planned._
## License
MIT