Skip to content

Commands

Every command is a thin wrapper over one named GraphQL operation. This page documents each command exactly as the package implements it: synopsis, flags, the operation it maps to, and output examples.

These apply to every command and may appear before or after the command path:

FlagEffect
--jsonEmit the GraphQL data payload, pretty-printed.
--jsonlEmit one JSON object per line (for the streamable list of a result).
--humanForce the human table/record view (e.g. into a pipe).
--no-colorDisable ANSI color.
--quietSuppress non-error stderr chrome.
--profile <name>Select the config profile.
--endpoint <url>Override the profile’s api_url.
--help, -hPrint top-level usage.
--version, -vPrint the CLI version.

Format precedence is --jsonl > --json > --human; with none given, the CLI emits human at a TTY and json when piped. See Scripting.


Covered in full on Install & Authentication. In brief: login stores a token (verifying it via query stats), logout forgets it, and whoami prints identity + corpus size (also via query stats). None maps to a dedicated GraphQL auth operation — auth is Clerk; whoami reuses stats.


The highest-leverage group. Each is --json-capable, and the human view echoes the [doc:ID] handle convention the Core tools use, so output reads like what an agent sees.

trove search <query…> [--source <name|id>] [--source-type <t>]
[--author <a>] [--after <date>] [--before <date>] [--type <ct>]
[--tag <t>]… [--feed <id>] [--limit <n> | -l <n>]

Semantic top-K search → query search. Positional words are joined into the query string. --source accepts a name or id; a name is resolved to its id client-side via sources (an id-shaped value, src_…, is used as-is). --tag is repeatable. --type is upper-cased to the ContentType enum.

$ trove search "database indexing" --source "arXiv Papers" --limit 5
SCORE TITLE SOURCE HANDLE
0.847 Learned Indexes for Range Queries arXiv Papers [doc:d_8f2a]
0.812 B-Tree vs LSM under Write Amplification arXiv Papers [doc:d_31c0]
2 match(es) in 41ms

--json emits the SearchResults object ({ totalMatches, queryTimeMs, results[] }); --jsonl emits one results[] entry per line.

trove discover <topic…> [--source <name|id>] [--source-type <t>]
[--feed <id>] [--limit <n> | -l <n>]

Broad thematic browse → query discover. Only source/feed filters take effect — the wider search filters (--author, --after, --type, --tag) are accepted but ignored. Output shape matches search.

trove recent [--source <name|id>] [--author <a>] [--since <date>]
[--limit <n> | -l <n>]

Chronological by indexedAtquery recent. Renders a TITLE / AUTHOR / SOURCE / HANDLE table. --json/--jsonl emit the document array.

trove get <doc-id…> [--offset-words <n>] [--max-words <n>]

Fetch one or more documents with full text → query document(id), once per id. A missing document fails with exit code 5. The human view prints a record header (title, author, source, url, handle) followed by the full text — built for piping into $EDITOR/less:

Terminal window
trove get d_8f2a | $EDITOR -

In --json, a single id emits one document object; multiple ids emit an array. In --jsonl, each document is one line.

Word paging. --offset-words / --max-words page a long transcript client-side: the CLI fetches the document’s fullText, slices it by words, and prints just that window. The human view writes the slice to stdout plus a continuation hint (the next offset) to stderr; --json returns { id, offsetWords, returnedWords, totalWords, nextOffset, text }. Paging applies to a single document id at a time.

Terminal window
trove get d_8f2a --offset-words 0 --max-words 800 # first 800 words
trove get d_8f2a --offset-words 800 --max-words 800 # next page (use nextOffset)
trove list [--source <name|id>] [--type <ct>] [--tag <t>]… [--search <text>]
[--sort <field>] [--order <asc|desc>] [--limit <n> | -l <n>] [--offset <n>]

The exhaustive lister with an authoritative totalCountquery documents. This is the right tool for “all X”, counts, and pagination — search is semantic top-K. --sort maps to DocumentSortField and --order to SortOrder (both upper-cased); --type upper-cases to ContentType.

$ trove list --source "The Guardian" --json | jq '.totalCount'
675

The human view appends a <N> total footer (with (more available) when hasMore). --jsonl emits the nodes[] one per line.

trove sources [--type <t>] [--status <s>]

List your sources → query sources. --status upper-cases to SourceStatus. Renders an ID / NAME / TYPE / STATUS / DOCS table.

trove source <id|name> [--feeds] [--sync-runs]

One source with feeds, top authors, date range, and recent sync runs → query source(id). The name/id argument is resolved via sources. A missing source fails with exit code 5. (--feeds/--sync-runs are accepted; the operation already requests feeds and sync runs.)

trove stats

Corpus aggregates → query stats: total documents, total/active sources, breakdowns by source type and content type, and recent sync runs.


trove save (--text <text> | --text - | --url <url>) [--title <t>]
[--tag <t>]… [--source <s>]

Manual capture of free text or a URL into the Manual Saves source → mutation saveDocument. One of --text or --url is required. --text - reads the body from stdin, so:

Terminal window
cat notes.md | trove save --text - --title "Meeting notes"
trove save --url https://example.com/post --tag reading --tag ai

Here --source is free-form attribution text (e.g. "conversation with Claude"), not a source id. On success the human view writes ✓ saved [doc:…] to stderr and the record (id, title, url, tags) to stdout. --json/--jsonl emit the saved Document.

trove ingest --source <id> --feed <id> --documents <file.jsonl|->
[--cursor <new>] [--cursor-before <expected>]

The lower-level ingest boundary for source-adapter authors and bulk scripts → mutation ingestDocuments. --documents accepts a JSONL stream or a JSON array of IngestDocumentInput; - reads from stdin.

It honors the cursor compare-and-swap: pass --cursor (the new cursor) and --cursor-before (the expected current value). On a CAS rejection the CLI exits with code 8 (retryable) so a script can re-read IngestResult.cursor and retry. Re-sent documents are reported as documentsSkipped, not errors.

Terminal window
generate-docs | trove ingest --source src_123 --feed feed_456 --documents -

The human view prints indexed, skipped, transcriptions queued, cursor, and errors. --json emits the full IngestResult; --jsonl emits the per-document errors[] one per line.


The CLI is the local dev toolchain for source adapters. A source adapter is a folder with extension.ts — one defineSource({ sync }) export against @ontrove/extend/source — plus the manifest.json generated from it. Locally, the CLI runs the adapter on your machine — dev/test run sync(ctx) and never upload; sync runs it then pushes via ingestDocuments. In production, most sources run in Trove’s cloud; the ones that need a browser or local files run on the Mac app.

trove source init <name>

Scaffold <name>/extension.ts (a defineSource stub with a sample sync) and the manifest.json generated from it. No GraphQL.

trove source dev [path] [--config <file.json>] [--cursor <json>]

Load the source adapter’s extension.ts and hand it to @ontrove/extend/source’s runSource, run sync(ctx), and print the produced documents (human table or --json/--jsonl). --config supplies the source’s preference values; --cursor supplies the starting cursor. Nothing is uploaded.

trove source test [path] [--fixtures <file.json>] [--config <file.json>]

Run sync(ctx) against a fixtures file (a JSON map of request URL → canned response body, default fixtures/responses.json) so the run is deterministic and offline, then assert the document shape. Exits 2 if assertions fail.

trove source validate [path]

Validate the manifest half of your defineSource declaration with @ontrove/extend/source’s validateSourceManifest — required fields, the id/version patterns, and the credential-key lint (a source’s config must hold preferences only, never credentials). Exits 2 on an invalid manifest.

trove source sync [path] [--source <name|id>] [--feed <key>] [--create] [--config <file.json>]

The real upload: run sync(ctx) locally, then push the documents via mutation ingestDocuments with cursor compare-and-swap. The CLI reads the target feed’s current cursor as cursorBefore and advances it with the cursor sync returns. --source (defaults to the manifest name) and --feed (defaults to default) select the target; --create creates the source/feed (via createSource/addFeed) if they don’t exist yet.


Toolkit authoring & deployment (@ontrove/extend/toolkit)

Section titled “Toolkit authoring & deployment (@ontrove/extend/toolkit)”

toolkit init/toolkit dev are the local toolchain for toolkits. A toolkit is a folder with extension.ts — one defineToolkit({ …, tools }) export against @ontrove/extend/toolkit — plus the manifest.json generated from it, and every toolkit runs as a full MCP server on Trove’s cloud. The remaining commands wrap the toolkit control-plane operations. A toolkit argument is a slug or id, resolved via mcpServers.

trove toolkit init <name>

Scaffold <name>/extension.ts (a defineToolkit stub with a sample tool, annotations, and an output schema) and the manifest.json generated from the same declaration. No GraphQL.

trove toolkit dev [path] [--port <n>] [--once]

Load extension.ts, wrap it in @ontrove/extend/toolkit’s runtime fetch handler, and serve it over http://127.0.0.1:<port> (default 8788) so a client can connect: GET returns tools/list, POST runs a tool. Prints the local URL and the tool list; ctx.secret/ctx.trove resolve against the configured endpoint. Runs until interrupted (--once serves and returns, used in tests).

trove toolkit ls

List your toolkits → query mcpServers. Renders a SLUG / NAME / STATUS / VIS / TOOLS / ACTIVE table (ACTIVE is the active deployment’s version).

trove toolkit deploy [--dir <path>] [--name <name>] [--slug <slug>]
trove deploy [--dir …] [--name …] [--slug …]

Register/version a toolkit → mutation deployServer. Reads manifest.json from --dir (default .), derives name/slug from it (slug falls back to the manifest id) unless overridden by --name/--slug, bundles extension.ts locally (a Bundling extension.ts… line is written to stderr), and registers the deployment. The manifest’s egress, scopes and secrets are read from the file, not from the bundle, and become the deployed toolkit’s policy. On success it prints the namespaced tool names ({slug}__{tool}) to stdout and a ✓ deployed … line to stderr. --json emits the deployment. Missing manifest.json is a usage error (exit 2). See Toolkits — Deploying.

toolkit pause / toolkit resume / toolkit rm

Section titled “toolkit pause / toolkit resume / toolkit rm”
trove toolkit pause <toolkit>
trove toolkit resume <toolkit>
trove toolkit rm <toolkit>

Lifecycle, each over a single id → mutation pauseServer, mutation resumeServer, mutation deleteServer (a soft-delete). The human view writes ✓ paused|resumed|deleted <name> to stderr; --json emits the returned McpServer.

trove toolkit rollback <toolkit> <deploymentId>

Repoint a toolkit to a prior deployment → mutation rollbackServer. Both positionals are required. The human view writes ✓ rolled back <name> → <version> to stderr.

trove toolkit logs <toolkit>

There is no logs GraphQL operation: per-script logs are produced by the deployed toolkit runtime, not the GraphQL API. Rather than invent a fake op, this command explains where logs live (the deployed endpoint, once the runtime ships) and exits 0. --json returns { server, available: false, reason }.

trove secret set <toolkit> <name> (--value <v> | --from-file <path> | --from-stdin)

Seal a secret into the encrypted vault → mutation setServerSecret. The value comes from --value, --from-file <path>, or --from-stdin so it need never land in argv history; it is stored server-side in the vault, never in D1. The human view writes ✓ secret '<name>' sealed for <toolkit> to stderr.

trove secret ls <toolkit>

List a toolkit’s declared secret names → backed by query mcpServers (the secrets field). Values are unreadable by design — only the names are ever returned. The human view prints one name per line (or notes when the toolkit declares none); --json emits { server, secrets } and --jsonl emits one name per line.


trove gql <file|-> [--variables <json|->]

Run a raw, user-supplied GraphQL document over the same endpoint with the same token. The document is read from a file path or stdin (-); --variables takes inline JSON or stdin. Unlike the wrapped commands, gql emits the full { data, errors } envelope (so scripts can branch on .errors) and exits 7 if errors[] is non-empty, 0 otherwise. It is the same authz the server enforces for every client — there is nothing reachable here that the token could not do with curl.

Terminal window
echo '{ stats { totalDocuments } }' | trove gql -
trove gql query.graphql --variables '{"id":"d_8f2a"}'

This table is the contract: every command resolves to a named operation in schema.graphql (or a marked local step). It is a strict subset of the published GraphQL surface — the CLI never exceeds the API, it only makes a slice of it ergonomic.

CommandGraphQL operationKind
login / logout / whoami— (Clerk; whoami calls query stats)Auth
search <query>query searchRead
discover <topic>query discoverRead
recentquery recentRead
get <id…>query document(id) (once per id)Read
listquery documentsRead
sourcesquery sourcesRead
source <id|name>query source(id)Read
statsquery statsRead
savemutation saveDocumentWrite
ingestmutation ingestDocuments (cursor CAS)Write
source init— (scaffold @ontrove/extend/source project)Local
source dev— (local sync(ctx))Local
source test— (local fixtures assertion)Local
source validate— (validateSourceManifest)Local
source syncmutation ingestDocuments (+ createSource/addFeed w/ --create)Write
toolkit init— (scaffold @ontrove/extend/toolkit project)Local
toolkit dev— (local server over 127.0.0.1)Local
toolkit logs— (no log op; explains the deployed-runtime gap)Info
toolkit lsquery mcpServersRead · PROPOSED
toolkit deploy / deploymutation deployServerWrite · PROPOSED
toolkit pausemutation pauseServerWrite · PROPOSED
toolkit resumemutation resumeServerWrite · PROPOSED
toolkit rollbackmutation rollbackServerWrite · PROPOSED
toolkit rmmutation deleteServer (soft-delete)Write · PROPOSED
secret setmutation setServerSecretWrite · PROPOSED
secret lsquery mcpServers (secrets — names only)Read · PROPOSED
gql <file|->arbitrary, user-suppliedEscape hatch