The client is
the same binary
Nothing else to install. The binary you downloaded is the server, the MCP endpoint and this REPL, and it connects to http://localhost:9480 unless told otherwise.
./cameodb client -i # another node, over TLS ./cameodb client -i --connect https://cameodb.example.com # a self-signed certificate, development only ./cameodb client -i --connect https://localhost:9480 --insecure
--insecure trusts the node’s certificate. For a schema or data file on a self-signed host, --insecure-source trusts that source, and the connection to your node keeps its own settings.
Tab knows what
the node holds
The session caches index metadata on startup and refreshes it after connect and either list command, so completion answers from the live schema rather than from whatever was true when the REPL opened.
healthCluster health, pretty-printed.list indexesEvery index with document counts and field names.list index <name>One index in full: stats and schema.search books <TAB>Field names with type hints: title: [text], year: [numeric], active: [true/false].connect <host[:port]>Switch to another node without leaving the session.key file <path>Load an API key while keeping it out of your history. Keys travel over HTTPS, or to this machine.A completed field arrives as title: with the colon already typed, ready for a value. A word the command continues past brings its own space, so one Tab settles it and the next moves on, and the +, − and ! modifiers survive completion rather than being eaten by it.
Point it at a file
or at a URL
CSV, TSV, JSON, JSONL and NDJSON, local or over HTTP(S). Gzip and Zip archives are decompressed in flight, so a public dataset loads without being downloaded and unpacked first.
schema detect <file>Read a file and report the schema it implies, without applying it.schema detect <file> --reportHow each column was read and why it became the field it did.schema load <index> <file>The same detection, applied to an index.data load <index> <file>Batched ingest. 4,000 documents per batch unless --batch-size says otherwise.data load <index> <file> --id <col>The column that identifies a row; several, comma-separated, combine into one id.delete <index>At the prompt it asks Delete index "<name>"? [yes/NO] first. From the shell it runs straight through, ready for scripts.delete <index> --id <id[,id]>Delete those documents and keep the index. --ids-file reads them from a file, one per line.cameodb@localhost ▶ data load hugdata https://huggingface.co/datasets/.../data.jsonl.gz
Run it once
or leave it open
Every command at the prompt also runs straight from the shell, and each one answers --help. That makes the same binary a scripting tool for loads, cleanups and maintenance.
./cameodb search books 'title:rust' --limit 10 --offset 10
./cameodb list indexes --extended
./cameodb data load books ./books.csv.gz --parallel 4
./cameodb delete books --id b1,b2
./cameodb admin index books merge
--parallel keeps up to 16 batches in flight; four loaded 2.4× faster than one on a three-node cluster. admin index <name> merge folds each shard’s segments into one and hands back the space deleted documents held.
The same grammar
the agent uses
Queries typed here and queries an agent sends over MCP go to the same parser. The client passes the modifier run straight through. The server owns where one may appear, so the REPL cannot disagree with the engine about it.
cameodb@localhost ▶ search books title:"Harry Potter" limit 7 cameodb@localhost ▶ search books +title:rust +year:[2020 TO *] return title,author,year limit 10 sort year:desc
At the prompt, a limit is part of the query, limit 10, and offset 20 pages on. From the shell the one-shot form takes flags too: ./cameodb search books 'author:doe' --limit 10 -o 20. The full grammar covers the rest.
Built to be left
open all day
The details that decide whether a tool gets used twice.
History that survives
Sessions persist to ~/.cameodb/client_history, with Ctrl-R reverse search, arrow keys, Home and End: Rustyline navigation, not a bare read line.
Readable, and pipeable
Colorized JSON by default, in the manner of jq, with a plain fallback so a pipe or a CI log gets text rather than escape codes.
The editor never blocks
The line editor runs under spawn_blocking while requests stay async, so a slow query does not freeze the prompt you are typing at.
Hints in your language
Common types are shown as [text], [numeric], [decimal] and [true/false]; dates, addresses and the rest keep their own names.