@ontrove/cli
v0.8.0
Published
The Trove command-line tool — a scriptable GraphQL client for your personal knowledge base, and the toolchain for authoring sources and building & deploying toolkits.
Maintainers
Readme
@ontrove/cli — the Trove command-line tool
trove is a single, scriptable command-line tool for all of Trove: building and
deploying the tools you give Claude (your own toolkits, hosted on Trove's cloud),
capturing documents, authoring sources, and querying everything — all over the
one GraphQL API at api.ontrove.sh/graphql.
GraphQL is the API. The CLI is a convenience layer. Every
trovecommand is a thin wrapper over a documented GraphQL operation. The CLI has no privileged access and no private endpoint — it is just another client of the same Open Host Service the MCP tools and the web app use.
Install
trove ships as a self-contained single binary (bun build --compile) — the Bun
runtime and the @ontrove/* packages are embedded, so the binary installs need
nothing else on your machine: no Node, no Bun, no toolchain.
Homebrew (macOS/Linux):
brew install hollyburnanalytics/tap/troveShell script (macOS/Linux):
curl -fsSL https://ontrove.sh/install.sh | shWindows (x64):
irm https://ontrove.sh/install.ps1 | iexBun / npm — if you already have Bun, skip the binary and run the package directly (npm works too, but the CLI runs on Bun, so you need Bun on your PATH):
bunx @ontrove/cli # run without installing
bun add --global @ontrove/cli # install it globally
npm i -g @ontrove/cli # or from npm (requires Bun on PATH)The binary channels cover macOS (arm64 + x64), Linux (x64 + arm64), and Windows x64; each download's checksum is verified against the release
SHA256SUMS. Windows on ARM has no native binary — usebunx @ontrove/clithere.
Quickstart
# Authenticate. `trove login` opens your browser (loopback OAuth + PKCE) and
# stores the token in the OS keychain when available, else ~/.trove/config.toml
# (chmod 600). Prefer the non-interactive path for CI:
trove login --token "$CLERK_JWT" --email [email protected]
# ...or set TROVE_TOKEN and skip login entirely.
trove whoami # verify the token + print corpus size
trove search "database indexing" # semantic search (top-K)
trove list --source "The Guardian" --json | jq '.totalCount'
trove get d_123 | $EDITOR - # full text to stdout for piping
trove get d_123 --offset-words 0 --max-words 800 # page a long transcript
trove save --url https://example.com/post --tag readingSource & toolkit authoring
The CLI is the local SDK toolchain for @ontrove/sdk (sources) and @ontrove/mcp
(your own toolkits): scaffold, run locally, then push.
# Sources (client-side execution → ingestDocuments)
trove source init my-blog # scaffold manifest.json + index.ts
cd my-blog
trove source dev --json | jq '.[].title' # run sync(ctx) locally, no upload
trove source test --fixtures fixtures.json # assert document shape offline
trove source validate # lint manifest (credential-key check)
trove source sync --source "My Blog" --feed default --create # → ingestDocuments
# Toolkits (@ontrove/mcp)
trove mcp init my-server # scaffold manifest.json + server.ts
cd my-server
trove mcp dev --port 8788 # bundle + serve over http://127.0.0.1:8788
trove mcp deploy # mutation deployServer (PROPOSED runtime)Output & scripting
- Human by default at a TTY — aligned tables,
[doc:ID]handles, color. --json/--jsonl— the GraphQLdatashape forjq/fzfpipelines. When stdout is not a TTY, the CLI auto-selects--json.- Data → stdout, diagnostics → stderr.
trove search … --json | jqis never polluted by progress/chrome. - Honors
NO_COLOR,--no-color,--quiet.
trove search "distributed systems" --jsonl \
| jq -r '[.relevanceScore, .document.title] | @tsv' | sort -rn | fzfExit codes
| Code | Meaning |
|------|---------|
| 0 | Success |
| 2 | Usage / validation error |
| 4 | Auth error (not logged in, expired token, or access not granted for this account) |
| 5 | Not found (document/source returned null) |
| 7 | Transport / server error |
| 8 | Retryable conflict — ingest cursor CAS rejection (re-read the cursor and retry) |
Profiles
~/.trove/config.toml holds named profiles (an environment + identity each):
default_profile = "prod"
[profiles.prod]
api_url = "https://api.ontrove.sh"
issuer = "https://accounts.ontrove.sh"
token = "…"
email = "[email protected]"
[profiles.dev]
api_url = "http://localhost:8787"Select with --profile <name>, TROVE_PROFILE, or default_profile.
TROVE_TOKEN overrides any stored token (the CI path). --endpoint <url>
overrides a profile's api_url.
Commands → GraphQL operations
| Command | GraphQL operation | Kind |
|---|---|---|
| login / logout / whoami | — (Clerk; whoami calls query stats) | Auth |
| search <query> | query search | Read |
| discover <topic> | query discover | Read |
| recent | query recent | Read |
| get <id…> | query document(id) | Read |
| list | query documents | Read |
| sources | query sources | Read |
| source <id\|name> | query source(id) | Read |
| stats | query stats | Read |
| save | mutation saveDocument | Write |
| ingest | mutation ingestDocuments (cursor CAS) | Write |
| source init | — (scaffold @ontrove/sdk project) | Local |
| source dev | — (local sync(ctx) on Bun) | Local |
| source test | — (local fixtures assertion) | Local |
| source validate | — (validateSourceManifest) | Local |
| source sync | mutation ingestDocuments (+ createSource/addFeed w/ --create) | Write |
| mcp init | — (scaffold @ontrove/mcp project) | Local |
| mcp dev | — (local server over 127.0.0.1) | Local |
| mcp logs | — (explains the deployed runtime log gap) | Info |
| mcp ls | query mcpServers | Read |
| mcp deploy / deploy | mutation deployServer | Write |
| mcp pause / resume / rm | pauseServer / resumeServer / deleteServer | Write |
| mcp rollback | mutation rollbackServer | Write |
| secret set | mutation setServerSecret | Write |
| secret ls | query mcpServers (secrets — names only) | Read |
| gql <file\|-> | arbitrary, user-supplied | Escape hatch |
The toolkit management commands (mcp deploy/pause/resume/rollback/rm,
secret set/ls) wrap the corresponding GraphQL mutations; the deployed
runtime (where each request runs in an isolated sandbox) is still PROPOSED,
so mcp logs has no GraphQL operation to call —
it explains that per-script logs come from the deployed runtime and points there
rather than inventing a fake op. Everything else — the source init/dev/test/
validate/sync and mcp init/dev local toolchain, login's loopback OAuth flow,
keychain token storage, get word-paging, and secret ls — is implemented here.
Development
bun install # from the packages/ workspace root (links @ontrove/mcp + @ontrove/sdk)
bun run typecheck # tsc --noEmit (strict)
bun run lint # biome check
bun run test # vitest (mocked fetch — no network, no credentials)
bun run build # tsc → dist/ (the `trove` bin)
@ontrove/clilives in thepackages/bun workspace alongside@ontrove/mcpand@ontrove/sdk, which it depends on via published semver. A singlebun installatpackages/links all three locally; building@ontrove/mcpand@ontrove/sdkfirst (bun run buildin each) makes theirdist/available to the CLI.
All tests run against a mocked GraphQL endpoint and a temp $HOME; none touch the
network. The OAuth browser/loopback and OS-keychain seams are injected and mocked
in tests (the one genuinely-unrunnable wiring lives in src/commands/login-live.ts,
which is excluded from coverage). Branch coverage is gated at 90%.
Support
Guides and the full reference live at docs.ontrove.sh.
Report bugs or security issues to [email protected].
License
Released under the MIT License. © 2026 Hollyburn Analytics Inc.
