kglite-bolt-server
Bolt v5.x protocol server for kglite
knowledge graphs. A pure-Rust single binary speaking the Bolt wire protocol.
The official Python, JavaScript, and Java drivers are regression-tested in
CI — session and explicit-transaction lifecycle, managed executeWrite retry,
PackStream type round-trips, Node/Relationship/Path values, Neo.* error
codes, and OCC conflict detection (tests/conformance/js,
tests/conformance/java, driven by
tests/test_bolt_driver_conformance.py). Other Bolt v5 clients may connect but
can rely on features outside KGLite's documented wire and Cypher contracts.
Then point a Bolt v5 client at bolt://localhost:7687 and run KGLite's
documented Cypher dialect against the loaded .kgl graph.
Features
- Bolt v5.x handshake + PackStream framing (handshake versions 5.0 / 5.1 / 5.2 / 5.3 / 5.4 advertised).
neo4j://routing URIs via single-server routing table (--advertise-addrfor reverse-proxy deployments).- TLS via
--tls-cert+--tls-key(drivers connect withbolt+s://orneo4j+s://). db.labels()/db.relationshipTypes()yield Neo4j-conventional column names (label,relationshipType).- Optimistic concurrency control on commit — concurrent
writers whose snapshots become stale see
Neo.ClientError.Transaction.ConflictDetected. Retry on the client side. - Cross-process writer lease — a writable server takes the
graph's exclusive writer lease before it reads the path and holds
it until shutdown, so a second writer (server, CLI, MCP server or
kglite.open()) is refused at startup by name instead of overwriting its work at save time.--readonlytakes no lease. - Zero PyO3 in the binary — no libpython link, no Python
runtime required.
cargo tree -p kglite-bolt-server | rg pyo3returns empty.
Transaction metadata (write_scope / git_sha / modified_by)
KGLite's write-scope and write-provenance options ride on Bolt transaction metadata, at parity with the CLI and MCP surfaces:
=
Drivers send this under the tx_metadata key of BEGIN's extra
dict (auto-commit runs: RUN's extra); hand-rolled Bolt clients may
also place the same keys at the top level of extra. A CREATE/SET
touching a node type outside write_scope fails the query; git_sha /
modified_by are stamped on writes to auto_timestamp types. All
three are ignored by reads. Malformed values (non-list write_scope,
non-string git_sha) fail the BEGIN/RUN with a client error.
CLI
kglite-bolt-server [OPTIONS] --graph <PATH>
Options:
--graph <PATH> .kgl graph file to serve
--bind <ADDR> Bind address [default: 127.0.0.1]
--port <PORT> Port [default: 7687]
--readonly Reject mutations
--neo4j-compat Report a Neo4j-compatible agent in the handshake
--auth <USER:PASS> Basic auth credentials
--idle-timeout <SECS> Per-session idle timeout
--max-sessions <N> Max concurrent sessions
--advertise-addr <HOST:PORT> Address advertised in routing table (for neo4j:// URIs)
--tls-cert <PATH> PEM-encoded TLS certificate chain
--tls-key <PATH> PEM-encoded TLS private key
Driver identity and --neo4j-compat
By default the server identifies honestly in the Bolt handshake:
kglite-bolt-server/0.14.5
The official Python and JavaScript drivers accept this — they do not
inspect the server agent. The official Java driver does: it requires the
agent to begin with Neo4j/ and otherwise aborts the connection before running
a single query.
UntrustedServerException: Server does not identify as a genuine Neo4j
instance: 'kglite-bolt-server/0.14.5'
Compatibility mode makes the server present an agent that satisfies that check, while keeping the real product in the string:
Neo4j/5.26.0 (kglite-bolt-server/0.14.5)
Two equivalent ways to turn it on — the flag wins if both are set:
KGLITE_BOLT_NEO4J_COMPAT=1
The environment variable accepts 1, true, yes or on (any case), for
Docker, systemd and CI where editing an argv is awkward.
Why it is off by default. Claiming to be Neo4j is a claim about a different product, so it is the operator's decision, not the server's. When a client whose driver enforces the check connects while compatibility mode is off, the server logs a warning naming both activation routes — so the fix is discoverable from your own log rather than only from a client stack trace. Detection is a hint only: the identity is never switched automatically on the strength of a client-supplied string.
Compatibility mode changes only the handshake's server field. The bolt_agent
metadata keeps reporting kglite-bolt-server/<version> either way, because no
driver gates on it and the claim should not travel further than it must.
Documentation
- Bolt server operator guide — deployment patterns, driver compatibility, OCC retry shape.
- kglite Rust API — for embedders who want the engine directly without the Bolt frontend.
License
MIT — see LICENSE.