Sign In to MCP With OAuth
Clients that connect by URL, such as ChatGPT, claude.ai and Claude Desktop, now sign in to a CameoDB node without a header to paste. Turn on [security.oauth] and the node becomes the OAuth 2.1 authorization server for its own /mcp: discovery, dynamic client registration, PKCE and token refresh are all built in.
The person approving pastes the API key they already hold, and the token acts as that key with read access on /mcp. Revoke the key and the token stops working. Nothing is stored on the node: registrations, codes and tokens are signed with one secret from cameodb keygen --oauth-secret-out, the same on every node.
Keys Minted Through the Node
A new provisioner role holds one capability, managing keys. With it, an automation mints and revokes writer and reader keys over HTTP with POST /_keys and DELETE /_keys/{key_id}, and manages companies as tenants through /_tenants. The key appears once, in the minting response. The file on disk holds only its digest, readable by the service alone, and the node reloads it at once.
Scope stays in your hands at every level:
allowed_indexestakes prefixes, so["logs-*", "audit"]coverslogs-2026and any index created under the prefix later.- A tenant can bound all of its keys, and a key narrows within that.
PATCH /_keys/{key_id}changes a key's indexes in place while its holder keeps the key.- A provisioner with its own list grants only within it.
The bundled client has client keys and client tenants for all of it, and include = ["keys.d/*.toml"] pulls key and tenant files in beside the config and reloads the key ring when they change.
Ghost Fields: One Text, a Column per Analyzer
A multilingual corpus used to mean a copy of the text per language. A ghost field is a search column filled from a source field, only for the documents whose condition matches, analyzed by its own tokenizer and never stored:
"ghost": {"source": "text", "when": {"field": "lang", "in": ["en"]}}
Pair an in list with a not_in list and every document lands in exactly one column. The document store keeps the text once, however many columns search it: a stemmed column per language beside the text as written.
Analyzers for More Languages
pt_stem brings Portuguese: plurals reduce to the singular and feminines to the masculine before the Snowball stemmer runs, so decisões finds decisão and portuguesa finds português. On the UD Portuguese treebank 99.3% of plural nouns reach their singular's term, against 80.9% for Snowball alone.
Accent-insensitive _fold variants now cover Spanish, French, Portuguese and German, so informacion finds información and Haeuser finds Häuser. Italian gets sharper too: plurals reaching their lemma rise from 90.7% to 95.5% and feminines from 89.3% to 98.0%. The Croatian analyzers read Serbian Cyrillic, so камен and kamen reach one term and a query in either script finds both.
Hits That Show Why They Matched
A clause can match an element deep inside a long array. A cut array now leads with the elements the query matched, in stored order, and the hit names their positions, such as "_matched_elements": {"string_ipv4": [1834]}. It works across terms, phrases, prefixes, ranges, sets and CIDR blocks. It is on by default, and "matches": false returns each array's head instead.
Delete by Query
POST /api/{index}/delete with a query removes the matching documents on every shard of every node. Clauses are exact: values, IN and ranges on string, numeric, date and IP fields, booleans, document keys and quoted phrases on text fields. dry_run counts first, and a match above delete_max_docs asks for "confirm": true before it deletes. The SDK has delete_by_query, and the client has cameodb client delete <index> --query '…'.
Steadier on Windows, Safer on Shared Disks
Writes on Windows now ride out antivirus scans of fresh index files, and cameodb compact runs there. Every node claims its data directories before reading them, so two processes can never open one directory, even across a container's bind mount. If a node meets a damaged metadata.redb, it checks it at startup and a single node rebuilds it from its shards.
Upgrading
A node starts on your existing config, and every new section is off until you set it. On a cluster, upgrade every node first so ghost fields and matched elements work mesh-wide. Fields under it_stem, it_stem_fold, or Croatian analyzers that hold Cyrillic text pick up the new terms as their documents are written again.
Get It
CameoDB 0.3.9 is the current release: one binary, nothing else to install, signed and checksummed for macOS, Linux and Windows, with deb, rpm and msi packages. The v0.3.8 post covers the certificate rotation and signed releases it builds on.