Docs
View as markdown

API reference

Every relate surface, from the CLI and the language clients to the served protocols, with the capability matrix and each surface's reference page.

clirustcpythonnodebrowserjavagoswiftbolthttpmcp

relate is one engine with several front doors, and each front door is a surface Any front door to the relate engine: the CLI, a language client, the C ABI, the WebAssembly build, or a server that relate serve hosts. Read more in the glossary. The Rust crate is the engine. The C library, librelate_ffi, exposes it through a C application binary interface (C ABI), which the Node.js, Java, Go and Swift client A language package that runs the relate engine inside a program's process: the Python, Node.js, Rust, Java, Go and Swift clients. Read more in the glossary call; the Python client and the WebAssembly (WASM) browser build carry the engine themselves. The relate CLI links the engine too, and relate serve hosts Bolt Neo4j's binary client protocol; relate serve --bolt <port> speaks it, so Neo4j's drivers and Neo4j Browser can run statements against a relate store. Read more in the glossary, the HTTP Query API and MCP The Model Context Protocol, which agent hosts use to call tools; relate serve --mcp exposes a store as read_cypher, get_schema and write_cypher. Read more in the glossary over one store A relate database: a directory, a single .rl file, or :memory:, opened with --database. Read more in the glossary. Every surface runs the same engine, so a statement means the same thing on each; the surfaces differ in what they expose around it, which the matrix on this page records.

Synopsis

SurfacePackage or commandAn in-memory store
CLIrelate--database :memory:, the default
Pythonrelate-dbrelate.connect(":memory:")
Node.js@relate/relateDatabase.open(":memory:")
Browser@relate/relate-wasmnew RelateDb()
Rustthe relate crateDatabase::open(":memory:")
Clibrelate_ffi, relate.hrelate_database_open(":memory:", …)
Javacom.relate:relateDatabase.open(":memory:")
Gogithub.com/relatedb/relate/clients/gorelate.Open(":memory:")
SwiftRelateDatabase.inMemory()
Bolt, HTTP, MCPrelate serverelate serve --database :memory: --http <port>; at least one of --http, --bolt or --mcp is required

Package names are launch-day targets; Project lists the platforms each one ships for.

Capability matrix

FeatureCLIPythonNode.jsBrowser (WASM)RustCJavaGoSwiftBoltHTTPMCP
In-memory storeA store that lives only in the process.yes--database :memory:, the defaultyesrelate.connect(":memory:")yesDatabase.open(":memory:")yesnew RelateDb()yesDatabase::open(":memory:")yesrelate_database_open(":memory:", …)yesDatabase.open(":memory:")yesrelate.Open(":memory:")yesDatabase.inMemory()yesrelate serve --database :memory: --bolt <port>yesrelate serve --database :memory: --http <port>yesrelate serve --database :memory: --mcp stdio
Directory storeA store in a directory on disk.yes--database ./diryesrelate.connect(path)yesDatabase.open(path)nono filesystem paths; RelateDb.open("opfs://<name>") is the durable browser store, in a dedicated workeryesDatabase::open(path)yesrelate_database_open(path, …)yesDatabase.open(path)yesrelate.Open(path)yesDatabase(path:)yesrelate serve on a directory storeyesrelate serve on a directory storeyesrelate serve on a directory store
Single-file .rl storeA store in one .rl file.yes--database ./graph.rlyesrelate.connect("graph.rl")yesDatabase.open("graph.rl")noopens :memory: and opfs:// onlyyesDatabase::open("graph.rl")yesa *.rl URIyesDatabase.open("graph.rl")yesrelate.Open("graph.rl")yesDatabase(path: "graph.rl")yesrelate serve on a .rl storeyesrelate serve on a .rl storeyesrelate serve on a .rl store
Read-only openAn open that loads the store once and refuses every write.yes--read-only; a write exits 6yesread_only=TrueyesDatabase.open(uri, { readOnly: true })yesnew RelateDb(true)yesOpenMode::ReadOnlyyesrelate_database_open_read_onlyyesDatabase.openReadOnly(uri)yesrelate.OpenReadOnly(uri)yesDatabase(readOnlyPath:)yesrelate serve --read-onlyyesrelate serve --read-onlyyesrelate serve --mcp stdio --read-only; only read_cypher and get_schema are listed
Explicit transactionsSeveral statements committed or rolled back together.yes.begin, .commit, .rollback in a script on stdin or the shellyesautocommit = False, then commit() or rollback()yesbegin(), commit(), rollback()noeach statement commits on its own; BEGIN is a syntax erroryesbegin(), commit(), rollback()yesrelate_conn_begin, relate_conn_commit, relate_conn_rollbackyesbegin(), commit(), rollback()yesBegin(), Commit(), Rollback()yesbegin(), commit(), rollback(), transaction { }yesBEGIN, COMMIT, ROLLBACKyesPOST /db/<name>/query/v2/tx, then …/tx/<id>/commitnoeach tools/call runs one statement
Parameters$name values passed beside the statement.yes--param name=valueyesexecute(statement, {"x": 3})yesquery(statement, { x: 3 })yesexecute(statement, paramsJson)yesquery_with_paramsyesthe params builderyesquery(statement, Map)yesQueryParams(statement, map)yesquery(statement, [String: CypherValue])yesthe RUN message's parameter mapyes"parameters" in the request bodyyesthe tools' parameters argument
Column types, counters and timingsMetadata returned with each result.partialthe envelope has columnTypes, timings (elapsed and its phase split) and planCache, and the plan on EXPLAIN; no countersyesQueryResult (column_types, stats, query_type, elapsed_ms and its phase split) and the result summarypartialcounters, query type, elapsed and its phase split; no per-column type list (each value carries its type)yescolumnTypes, stats, elapsed_ms and its phase split, plan_cache in the envelopeyesQueryResult: header.column_types, header.query_type, stats, elapsed_ms() and its phase split, plan_cache()partialcounters, timings and column names; no column-type call (read each value's kind with relate_value_kind)partialquery type (a typed QueryType), namespace, bookmark, notifications and plan; no column types, counters or timingspartialStats, QueryType, Plan; no column types or timingspartialstats, elapsedMs and its phase split, queryType; no column typesyesthe SUCCESS summaries: columnTypes, t_first, t_last, the phase times, plan_cache, type, statspartialcounters on a write, queryPlan, timings (elapsed and its phase split) and planCache; no column types in the JSON responseyescolumnTypes, stats, elapsed_ms and its phase split, plan_cache in the tool result
NotificationsThe engine's query notifications (for example a Cartesian product), each with a remedy.yesnotifications in the envelope; filled on EXPLAIN and PROFILEyesQueryResult.notificationsyesresult.notificationsyesnotifications in the envelope; filled on EXPLAIN and PROFILEyeswith the plan, on EXPLAIN and PROFILEyesrelate_result_notificationsyesgetNotifications()yesNotificationsyesnotificationsyesin the ending SUCCESS summary on EXPLAIN and PROFILE; a plain run carries noneyesnotifications in the response on EXPLAIN and PROFILE only; the remedy is appended to descriptionyeson every call, from the EXPLAIN that classifies the statement
Arrow outputResults as Apache Arrow.nono Arrow output modeyescursor.to_arrow() (the relate-db[arrow] extra), Database.execute_arrow()nono Arrow call in the clientnono Arrow call in the packageyesthe relate-arrow cratenono Arrow call in the clientnono Arrow call in the clientnono Arrow call in the clientnono Arrow call in the clientnono Arrow output on this surfacenono Arrow output on this surfacenono Arrow output on this surface
Change data captureReading committed changes from a slot.nono CDC command; CALL db.cdc.current() is ProcedureNotFoundnono change-data-capture call in the clientnono change-data-capture call in the clientnoCALL db.cdc.current() is ProcedureNotFoundyesregister_cdc_slot, cdc_records_after, ack_cdc_slotnono change-data-capture call in the clientnono change-data-capture call in the clientnono change-data-capture call in the clientnono change-data-capture call in the clientnono change-data-capture feed on this surface; CALL db.cdc.current() is ProcedureNotFoundnono change-data-capture feed on this surface; CALL db.cdc.current() is ProcedureNotFoundnono change-data-capture feed on this surface; CALL db.cdc.current() is ProcedureNotFound
Full-text searchFull-text indexes and their queries.yesCREATE FULLTEXT INDEX and full-text SEARCH, with the index's query syntax (AND, NOT)yesCREATE FULLTEXT INDEX and full-text SEARCHyesCREATE FULLTEXT INDEX and full-text SEARCHyesCREATE FULLTEXT INDEX and full-text SEARCHyesCREATE FULLTEXT INDEX and full-text SEARCH; the engine crate the other surfaces build onyesCREATE FULLTEXT INDEX and full-text SEARCH through the C ABIyesCREATE FULLTEXT INDEX and full-text SEARCH through the C ABIyesCREATE FULLTEXT INDEX and full-text SEARCH through the C ABIyesCREATE FULLTEXT INDEX and full-text SEARCH through the C ABIyesCREATE FULLTEXT INDEX and full-text SEARCH as statementsyesCREATE FULLTEXT INDEX and full-text SEARCHyesCREATE FULLTEXT INDEX and full-text SEARCH as statements
LOAD CSV from local filesLocal LOAD CSV under a configured directory (denied unless one is set).yes--load-csv-dir PATH or RELATE_LOAD_CSV_DIRyesRELATE_LOAD_CSV_DIR; connect takes no CSV optionyesRELATE_LOAD_CSV_DIRnono CSV directory can be set; a local file is LOAD CSV file unavailableyesOpenOptions.load_csv_diryesRELATE_LOAD_CSV_DIR, read by the C ABI's openyesRELATE_LOAD_CSV_DIR, read by the C ABI's openyesRELATE_LOAD_CSV_DIR, read by the C ABI's openyesRELATE_LOAD_CSV_DIR, read by the C ABI's openyesRELATE_LOAD_CSV_DIR for relate serve, one store for every served surfaceyesRELATE_LOAD_CSV_DIR for relate serve, which has no flag for ityesRELATE_LOAD_CSV_DIR for relate serve; only through write_cypher, which returns no rows (read_cypher refuses LOAD CSV)
Load a store from a URLOpening a .rl store fetched over https.yes--load with an https URL to a .rl filenono open from a URL in the clientnono open from a URL in the clientnoopens :memory: and opfs:// onlynoDatabase::open takes :memory:, a path or file://nono open from a URL in the clientnono open from a URL in the clientnono open from a URL in the clientnono open from a URL in the clientyesrelate serve --database :memory: --load with an https URL; the loaded store is read-onlyyesrelate serve --database :memory: --load with an https URL; the loaded store is read-onlyyesrelate serve --database :memory: --load with an https URL; the loaded store is read-only
Agent modeThe CLI's agent defaults: the 100-row cap and the piped toon output.yes--agent-mode, RELATE_AGENT_MODE, or a detected agent harnessnoA CLI settingnoA CLI settingnoA CLI settingnoA CLI settingnoA CLI settingnoA CLI settingnoA CLI settingnoA CLI settingnoA CLI settingnoA CLI settingnoA CLI setting

Each cell is yes, no, partial or unknown, with the call, flag or reason. Checked on 2026-11-09 against relate 0.1.2: runs of the CLI binary and relate serve (Bolt, HTTP and MCP), the WebAssembly build this site ships, and the Python, Node.js, C, Java, Go, Swift and Rust clients, and each surface's upstream reference. The C, Java, Go and Swift clients load the same C ABI library as the Node.js client.

Each row is a feature and each column a surface; every row has a stable anchor, #matrix-<feature>, such as #matrix-read-only. A cell holds one of four values, then a note:

ValueMeaning
yesThe surface has the feature; the note names the call, flag, or field
noThe surface lacks it; the note says why, or what it offers instead
partialThe surface has part of it; the note names the part
unknownNobody has checked the cell; the matrix never guesses

A cell is checked against a run of the surface or its upstream reference, and the note says what the surface does, not how the cell was checked. The C, Java, Go and Swift clients load the same C library as the Node.js client, so a statement-level cell such as vector search is checked once through that library; the Bolt and MCP cells of statement-level features are checked on the store all three served surfaces share. The reference page of each language client shows its own column alone.

Surfaces

See also