Skip to Content
ReferenceProtocols

Protocol Compatibility

Relata speaks ten external wire protocols from one binary and one governed store. Any off-the-shelf client library that speaks one of them can use Relata as a drop-in backend — no Relata SDK required. Backed by ADR-163–ADR-170.

This is the fastest adoption path if you already have tooling that talks to S3, Postgres/pgvector, ClickHouse, Neo4j, Redis, or MongoDB: point it at Relata and the same governed, bi-temporal, ACL-enforced, audited store is underneath.

All doors are off by default unless their port env var is set, bind to 127.0.0.1, and share one credential: RELATA_BEARER_TOKEN. pgwire refuses to start without a token; the others default to open dev mode when unset.

At a glance

DoorADRPort env (default)Persisted in governed store?
S3164 / 170RELATA_S3_PORT (9191)YesS3Object / S3Bucket
Postgres + pgvector165RELATA_PG_PORT (5433)Yes — typed rows + _emb_text vectors
ClickHouse HTTP166RELATA_CLICKHOUSE_PORT (8123)Reads only (governed /query)
ClickHouse native TCPRELATA_CH_NATIVE_PORT (9000)Reads only
Neo4j HTTP Cypher167RELATA_NEO4J_PORT (7474)Reads only (Cypher→SQL)
Neo4j BoltRELATA_BOLT_PORT (7687)Reads only (Cypher→SQL)
Redis RESP168 / 170RELATA_REDIS_PORT (6379)YesKvEntry
MongoDB wire169 / 170RELATA_MONGO_PORT (27017)YesMongoDocument

The native Relata protocols are also always available:

DoorDefault portNotes
HTTP REST9090/query, /memory/*, /mcp, /health, /status, /audit/count, /cluster/nodes, /watch/stream, /sparql
gRPC50051Used by the Rust SDK (ADR-073)
Arrow Flight8815Zero-copy columnar streaming; enable with RELATA_FLIGHT_ENABLE=true (#958)
MCP/mcpModel Context Protocol on the HTTP door
SPARQL/sparqlSingle Basic Graph Pattern over KnowledgeTriple + optional LIMIT

Cross-protocol: write via S3/Redis/Mongo and read the same data back through any other surface, e.g. SELECT key, size FROM S3Object or SELECT value FROM KvEntry over SQL/psql. SmartIngest also runs on governed writes, so identities detected in an S3 object body link to identities in a Mongo doc via LOOKUP_IDENTITY.

Start the doors

export RELATA_BEARER_TOKEN=change-me RELATA_S3_PORT=9191 \ RELATA_PG_PORT=5433 \ RELATA_CLICKHOUSE_PORT=8123 \ RELATA_NEO4J_PORT=7474 \ RELATA_REDIS_PORT=6379 \ RELATA_MONGO_PORT=27017 \ relata serve

A single end-to-end smoke test for all six ecosystems lives at scripts/protocol_smoke_test.py.

S3 — boto3 / aws CLI / rclone / MinIO client

Nine core ops: ListBuckets, Create/Head/Delete Bucket, ListObjectsV2 + GetBucketLocation, Put/Get/Delete/Head Object, plus multipart upload.

import boto3 from botocore.config import Config s3 = boto3.client( "s3", endpoint_url="http://127.0.0.1:9191", aws_access_key_id="change-me", aws_secret_access_key="unused", config=Config(signature_version="s3v4", s3={"addressing_style": "path"}), ) s3.create_bucket(Bucket="cases") s3.put_object(Bucket="cases", Key="exhibit-1.txt", Body=b"hello") print(s3.get_object(Bucket="cases", Key="exhibit-1.txt")["Body"].read())

When RELATA_S3_SECRET_KEY is set, the door requires verified SigV4 and rejects plaintext bearer / unsigned access-key auth.

Read S3 objects back over SQL

SELECT key, size, content_hash FROM S3Object WHERE bucket = 'cases';

Postgres + pgvector — psql / psycopg2 / LangChain & LlamaIndex PGVector

psql -h 127.0.0.1 -p 5433 -U relata relata # password = RELATA_BEARER_TOKEN
CREATE EXTENSION vector; CREATE TABLE docs (id text PRIMARY KEY, embedding vector(3)); INSERT INTO docs (id, embedding) VALUES ('a','[1,0,0]'), ('b','[0.9,0.1,0]'); -- cosine KNN (auto-routed to Relata's HNSW index): SELECT id FROM docs ORDER BY embedding <=> '[0.9,0.1,0]' LIMIT 2;

INSERT/UPDATE/DELETE and ordinary SELECT work. TablePlus / DBeaver / pgAdmin / DataGrip connect and browse schema via the catalog intercept.

OperatorMetricNote
<=>cosine distancepreferred — ANN index is cosine-only
<->L2 distancemetric-correct via over-fetch + re-rank
<#>negative inner productmetric-correct via over-fetch + re-rank

ClickHouse — HTTP or native

# HTTP curl -X POST "http://127.0.0.1:8123/?query=SELECT+1" \ -H "X-ClickHouse-Key: change-me" curl -X POST http://127.0.0.1:8123/ --data-binary \ "SELECT name FROM Person FORMAT JSONEachRow" \ -H "X-ClickHouse-Key: change-me"
from clickhouse_driver import Client ch = Client(host="127.0.0.1", port=9000, password="change-me") print(ch.execute("SELECT name FROM Person LIMIT 5"))

Reads only — the door routes governed SELECTs through the planner.

Neo4j — HTTP or Bolt

# HTTP curl -X POST http://neo4j:change-me@127.0.0.1:7474/db/neo4j/tx/commit \ -H "Content-Type: application/json" \ -d '{"statements":[{"statement":"MATCH (n) RETURN n LIMIT 5"}]}'
from neo4j import GraphDatabase driver = GraphDatabase.driver("bolt://127.0.0.1:7687", auth=("neo4j", "change-me")) with driver.session() as s: print(s.run("MATCH (n) RETURN n LIMIT 5").data())

Cypher subset: relationship path patterns incl. bounded -[r*1..5]->, single-identifier RETURN [AS alias], whitelisted property predicates. Typed labels (n:Person) and typed edges [:KNOWS] are parsed but ignored. Read Cypher only.

Redis — any RESP client

redis-cli -h 127.0.0.1 -p 6379 -a change-me SET foo bar redis-cli -h 127.0.0.1 -p 6379 -a change-me GET foo

Governed keys persist as KvEntry rows; read back over SQL with SELECT key, value FROM KvEntry.

No MULTI/EXEC, BLPOP, scripting, or cluster commands. Pub/Sub is in-memory (zero persistence).

MongoDB — any Mongo wire client

// pymongo / mongoose / mongosh — all work const { MongoClient } = require("mongodb"); const c = new MongoClient("mongodb://localhost:27017", { auth: { username: "relata", password: "change-me" }, }); const db = c.db("cases"); await db.collection("exhibits").insertOne({ _id: "ex1", body: "hello" }); console.log(await db.collection("exhibits").findOne({ _id: "ex1" }));

Governed docs persist as MongoDocument rows; read back over SQL with SELECT * FROM MongoDocument.

LimitDetail
AuthSCRAM-SHA-256 only
maxWireVersion17
Transactions / change streamsnot supported
$push / $pull / $unsetnot supported
Nested equalityvia flattened columns only

Per-protocol security notes

  • All doors bind to 127.0.0.1 and share RELATA_BEARER_TOKEN.
  • pgwire is fail-closed — refuses to start without a token.
  • The other doors default to open dev mode when the token is unset.
  • Egress filtering (ADR-057) applies uniformly across every door.
  • /sparql GET+POST verify bearer auth (issue #563 fixed).

See also

Last updated on