CLI commands

Reference for every gno command, global option, retrieval mode, background service, and integration surface.

Compiled project context

Compile verified Capsules with gno context compiled preview, compile, check, and refresh. Read the compiled context guide for limits, indexed freshness, inclusion, and recovery.

The gno CLI indexes local folders into SQLite and runs BM25, vector, hybrid, and cited Ask against that index. Use it to connect folders, build the index, search and ask questions, keep the collection fresh in the background, and wire GNO into AI tools. It is useful from a terminal, but the same commands also power the Web UI, REST API, MCP server, and agent skills.

Quick chooser

Start here when you know what you want to do but not which command to reach for.

How the CLI thinks

  1. Collections point at folders on disk: notes, research, PDFs, project docs, client files, or a Karpathy-style personal knowledge base.
  2. Indexing reads files, extracts text, chunks documents, records links and tags, then embeds chunks for semantic search.
  3. Retrieval searches with keyword, vector, hybrid, default bounded graph expansion, and optional reranking.
  4. Surfaces expose the same index through the CLI, browser workspace, REST API, MCP, SDK, and installed skills.

Setup: verified first retrieval

gno setup

Creates or reuses a collection, indexes it, and succeeds only after an exact gno:// result. Semantic indexing then starts in the background and setup returns right away; --no-semantic skips it and records the skip.

gno setup ~/notes --name notes
gno setup ~/notes --name notes --exclude .env --exclude private
gno setup ~/notes --authorize-secret-risk
gno setup ~/notes --no-semantic
gno setup . --apply-profile --no-semantic
gno setup ~/notes --connector cursor-mcp --connector codex-skill

--exclude is one repeatable literal pattern, not a CSV. Secret-risk detection fails closed; only interactive confirmation or --authorize-secret-risk authorizes likely credentials. Safe-default --yes, JSON, non-TTY, decline, and EOF do not. Exit 0 means lexical proof completed, even when semantic or connector follow-up remains. Exit 1 is invalid or safely rejected input. Exit 2 is config, receipt, I/O, store, indexing, proof, or invariant failure.

Canonical private state lives under the configured data directory at setup-receipts/<index>/<folder-fingerprint>.json and setup-semantic/<index>/<folder-fingerprint>.json.

Only one background semantic job runs per folder and index. Rerunning setup while it runs leaves that job in place, even with different options. --no-semantic starts no job and leaves a running one alone. If semantic work is pending or failed, setup still exits 0 and prints the exact foreground gno ... embed <collection> command to finish it.

Setup checks for the nearest valid .gno/index.yml. By default it only prints an advisory and points to gno profile diff; it does not mutate profile-owned config. Pass --apply-profile to apply a valid profile before lexical setup. For a valid profile, that option cannot be combined with explicit --name or --exclude; conflicting input fails before config or index mutation. A missing or invalid profile never makes setup mandatory: normal setup continues, while an explicitly requested apply is reported as a truthful follow-up action. If the profile check or apply fails, setup stops before indexing and connector work. A failed apply can leave some resources created or updated; rerunning it resumes from there.

Without connectors or profile application, JSON is setup-command-result@1.0. Connector mode uses setup-activation-result@1.0 around the unchanged setup result. With --apply-profile, the closed setup-profile-result@1.0 records the profile check, optional apply, setup result, and any connector results. Supported connector IDs: claude-code-skill, claude-desktop-mcp, cursor-mcp, codex-skill, opencode-skill, openclaw-skill, and hermes-skill. Skill execution remains target_runtime_unverifiable; connector follow-up may be completed_with_actions with lexical success intact.

Web and Desktop onboarding run the same keyword-search check through the running server. They do not write the CLI setup receipts.

Project profiles: check, show, diff, apply

These commands discover the nearest repository-owned .gno/index.yml. Discovery stops at the first Git root, filesystem boundary, or filesystem root; a nearer nested profile shadows, rather than merges with, an ancestor profile. Passing a directory or its exact .gno/index.yml disables ancestor fallback.

gno profile check [path]
gno profile show [path]
gno profile diff [path]
gno profile apply [path]

Add --json for deterministic, path-redacted closed contracts: project-profile-command@1.0 for check, show, and diff; project-profile-apply@1.0 for apply. Unknown output fields are not part of either contract. Apply is idempotent and safe to rerun after an interruption. Concurrent config writes, including writes through symlinked config paths, cannot overwrite each other, and repeating an unchanged apply leaves the config byte-identical. Public receipts identify the collection but redact the local profile path, and the apply receipt stays outside the project. Config, data, databases, cache, selected file-backed models, receipts, and locks may not overlap the project root. Apply fails before mutation when that runtime boundary is unsafe. It never writes the tracked profile or indexes documents.

Advanced setup: init, collection, index

gno init

Creates the first GNO config and points it at a folder. Use it for the first folder in a new index.

gno init ~/Documents/Knowledge --name knowledge
gno init ~/Notes --name notes --pattern "**/*.md"
gno init ~/Research --name research --exclude "**/archive/**"

gno collection

Adds, lists, renames, removes, or resets collection embeddings after the initial setup.

gno collection add ~/Downloads/Papers --name papers
gno collection list
gno collection rename papers reading
gno collection clear-embeddings notes
gno collection remove old-notes

remove deletes the collection's documents from the index at once; run gno cleanup afterwards to reclaim the space its content and embeddings used. After rename, run gno update to index the folder under its new name; the collection has no documents until then, and existing embeddings are reused. Deleting a collection from the config file by hand keeps its documents until you run gno cleanup or add it back; see collections not in the config.

gno index, update, embed

update scans files into SQLite. embed creates vectors for semantic search. index does both.

An optional chunking policy change also rechunks cached mirrors across the index. Sync receipts include rechunkedMirrors when this happens; file counters still describe source refresh. Sync-only work leaves changed chunks pending embedding.

gno update
gno update --git-pull
gno embed notes
gno index
gno index --models-pull
gno index --no-embed
gno index notes --path meeting.md projects/plan.md
gno index --lock-wait 5m

Restoring identical bytes at the same path reactivates an inactive document on the next successful update or index and records one reactivate event in the change journal. Repeated unchanged syncs add no further events. Unchanged chunks keep their vectors. Changed titles, text, or embedding model need re-embedding. A runtime change (backend, Bun version, threads) does not, as long as the new runtime reproduces the stored vectors.

gno embed resumes from completed checkpoints and rebuilds a missing vector index from stored vectors where it can. Backlog counts are document chunks waiting for vectors; identical text may share one embedding call. If stored vector data is missing or corrupt, semantic search reports a failure and hybrid search falls back to keyword results with that fallback reported. Run normal gno embed first; use --force for an intentional full refresh.

If the current runtime cannot reproduce the stored vectors, gno embed would build a separate vector partition. It states that, the full chunk count and an estimate, then asks for confirmation; non-interactive runs need gno embed --new-partition, and --yes alone never confirms. See Switching backend or Bun version.

Retrieve: search, vsearch, query, ask

gno search and gno vsearch

search is exact and fast. Use it for titles, names, quotes, filenames, error messages, and identifiers you already have verbatim. vsearch is semantic. Use it when the right documents may use different words than your query; for a question, start with gno query --fast.

search builds highlighted snippets only for the results it returns, so even a long natural-language input answers in about 0.2-0.4 seconds on a 2,300-document index. Each snippet, and its snippetRange line span, comes from the part of the document that best covers the query terms, with the terms marked.

gno search "spaced repetition" --collection notes
gno search "ERR_INVALID_STATE" --line-numbers
gno search --query-file /run/user/1000/gno-recall/q.XXXX --json
printf '%s' "auth" | gno search --query-file - --json
gno search "deploy" -c work -c ops --json
gno vsearch "notes about memory and learning loops" --limit 10

Structured --json results include results[].source.absPath when the hit is a resolvable file-backed document. There is no --source flag. If absPath is absent, show the URI tail and do not offer file-open for that row.

Default snippets skip a leading YAML frontmatter fence and prefer document prose. When the snippet window is frontmatter-dominated, GNO falls back to stripped chunk prose. line and snippetRange.startLine follow that trimmed display range. --full and --line-numbers still emit the raw source. This display cleaning applies to gno search, gno vsearch, and gno query.

Local CLI retrieval uses the canonical repository or worktree for the current directory as a bounded soft signal. When the nearest local .gno/index.yml is valid, its canonical root and affinity defaults replace that cwd-derived fallback for the request; the profile does not mutate the user’s global affinity config. A matching collection can receive at most +0.03. Pass repeatable --project-root <path> values to replace the profile or cwd-derived root. The user config’s projectAffinity.enabled setting controls only cwd fallback; explicit roots and valid profiles retain their higher precedence. Use --no-project-affinity to disable every source for one request. Invalid and missing profiles fall back normally. Roots never stack; collection, tag, date, exclude, and egress filters stay hard. Explain output exposes only redacted collection and root aliases. Local gno query diagnose returns schemaVersion: "1.1" with redacted affinity metadata, including project_profile as the source when the profile supplied the root, and whether anything matched. When affinity is off or absent, or the request is remote, diagnose returns the 1.0 shape; those responses omit affinity.

Search several collections at once

gno search, gno vsearch, and gno query search every collection by default. One -c (--collection) limits the search to that collection; repeat it to search several: gno query "rollout plan" -c work -c ops. The filter applies before the result limit, so documents from other collections never take result slots, graph neighbors, or rerank budget.

The MCP tools, REST API, and SDK take the same scope as a collections list; see MCP, REST API, and SDK.

Supported collection/path scope, tags, modified-date bounds, category, author, exclusions, visibility, and managed-memory filters select eligible owners before the corresponding candidate limit. Vector and hybrid retrieval also filter chunk language before their budgets; standalone lexical --lang remains reserved. Whole-document exclusions inspect all chunks, including other languages. Score thresholds, deduplication, and available evidence can still yield fewer than --limit results, including zero.

gno query

Hybrid retrieval for normal use. It combines keyword, vector, fusion, default bounded graph expansion, and optional reranking. Disable the graph stage only when you explicitly want a graph-free path.

Fusion works on documents: keyword search ranks whole documents and semantic search ranks passages, so each list counts a document once, at the rank of its best passage. A document both searches find first gets both votes.

gno query "what did I decide about backups?"
gno query --query-file /run/user/1000/gno-recall/q.XXXX --json
gno query "papers about retrieval evaluation" --tags-any research
gno query "pricing notes" --fast
gno query "architecture tradeoffs" --thorough --explain
gno query "linked context" --explain
gno query "pure vector/lexical" --no-graph
gno query "auth" -c work -c notes
gno query $'auth flow\nterm: "refresh token"\nintent: token rotation'

One configured contentTypes[].searchBoost may contribute at most ±0.05 and composes with trusted local project affinity under a shared ±0.08 cap. BM25 and vector only adjust candidates that already survived retrieval and minScore. In hybrid mode the boost applies before reranking, so the reranker and the top keyword hit keep precedence. The signal cannot create a candidate or bypass hard filters. --explain reports the base score, factor, bounded contribution, final score, rule source, and ranking fingerprint when active.

gno ask

Retrieves evidence and optionally asks a local model to synthesize a cited answer. Use it for questions over your notes, not for general chatbot use.

The model is told today's date and each source's content date (its frontmatter or record date, never the file's modification time), so it can answer questions about when something happened or which source is newer.

gno ask "what are my open migration risks?" --answer
gno ask "who owns the launch decision?" --verify
gno ask "summarize my latest meeting notes" --since "last week"
gno ask "what did I save about local-first apps?" --show-sources

A source hit is not proof that all answer-bearing passages were retained. For multi-source questions, inspect each required passage with gno get and preserve its citation. Diagnose a known missing target with gno query diagnose; keep omissions, gaps, and unanswered parts explicit. See document hits and complete evidence.

Context Capsules and saved freshness

Compile one deterministic, token-budgeted evidence bundle, verify a saved bundle without rebuilding it, or explicitly register a caller-owned Capsule file for resident freshness checks:

gno context build "compare launch proposals" --budget 12000 --json --output capsule.json
gno context verify capsule.json --json
gno context watch capsule.json --question "Who owns launch?" --notify --json
gno context watches --json
gno context reverify <registration-id> --json
gno context unwatch <registration-id>

Watch lifecycle commands are CLI-only and scoped to the Capsule's canonical index. GNO stores bounded metadata and evidence hashes, never Capsule or passage text, and never rewrites the saved file. A completed check stores a verification receipt and runs no answer model. A failed check stores no receipt; gno context reverify prints its error code and message and exits nonzero. Local notifications contain only registration/Capsule identity, operation status, affected-question state, and timestamp.

Knowledge Delta

Read bounded metadata-only change history, one retained structural diff, or explainable inbound dependency paths:

gno changes --since 2026-07-20T00:00:00Z --json
gno diff gno://notes/plan.md --json
gno impact gno://notes/plan.md --max-depth 3 --max-edges 250 --json
gno impact gno://notes/plan.md --collection notes --json

Change IDs and cursors are opaque. Journal retention can expire old cursors; GNO reports partial, expired, or unavailable history instead of reconstructing source bodies. Impact traversal always enforces depth, node, edge, frontier, and visited-row bounds. Without --collection it covers every collection; repeat --collection to keep the traversal, and every step of each evidence path, inside those collections.

Private retrieval receipts

With retrievalTraces.enabled: true, successful search, query, ask, get, and Context Capsule calls print Trace: <traceId> to stderr. Stdout and structured payloads remain unchanged. Continue a retrieval-only receipt by passing the ID to an exact read:

gno query "deployment decision"
gno get gno://work/decisions/deploy.md --from 40 --limit 20 --trace-id <traceId>

Terminal replay-mode receipts with explicit labels can become content-free qrels and a verified local replay baseline:

gno trace export <traceId> --format qrels --output qrels.json
gno trace replay <qrels-export-id> --candidate hybrid --md

Replay checks the aggregate manifest and immutable evidence hashes, then compares rank, coverage, capability fallbacks, and source freshness. It can recommend promotion but always returns applied: false; it never edits ranking configuration, models, prompts, traces, or source files.

Read: get, multi-get, ls, tags

gno get and gno multi-get

Search results return gno:// URIs, paths, doc IDs, and line anchors. Use the read commands to pull the exact source into a terminal, script, or AI prompt after retrieval.

Structured search, vector, query, and ask results may also include context: user-configured guidance resolved for that exact uri and docid. Matching guidance composes global first, collection second, then path prefixes from broadest to most specific. It guides interpretation without changing ranking.

gno get gno://notes/learning.md
gno get gno://notes/learning.md --from 40 --limit 30
gno multi-get gno://notes/a.md gno://notes/b.md --max-bytes 12000

gno convert

Print the Markdown GNO would index for one file, without adding it to a collection. The output is exactly what indexing stores for that file, and nothing is written: no config, index, or cache is needed.

gno convert report.pdf
gno convert report.pdf > report.md
gno convert slides.pptx --json

gno ls, tags, status, doctor

Use these when results look wrong. First check whether the document is indexed, then inspect tags and health.

Status JSON includes chunking.configured, applied, state, pendingDocuments, and pendingMirrors. Layout states are empty, legacy-default, current, pending, or mixed. Applied parameters are null for empty/mixed layouts. These counts describe cached chunks; source errors and embedding backlog remain separate.

Embedding status reports coverage for the vectors that search actually reads, so a half-built replacement never shows up as lost embeddings. Pending counts are per document chunk: identical text in documents with different titles needs separate embeddings. Collection chunk totals count shared text once, and a shared chunk counts as embedded only when every document using it in that collection is covered. Status does not load a model. You do not need gno embed --force to fix a status count.

When more than one partition exists, status prints a Vector partitions: block (JSON: vectorRuntime and vectorPartitions): first what this runtime's queries read, selected by the same rule retrieval uses (a partition, lexical retrieval only with the reason, or not resolved until its first query or embed), then each partition's state, chunk count, provenance such as CUDA, Bun 1.4.2, and the runtimes that read or cannot read it. Status prints a gno vec drop <id-prefix> hint for exactly the partitions drop accepts: abandoned shadow or legacy partitions this runtime does not read. Activated partitions are refused because another runtime may read them.

Status checks each configured collection's folder every time it runs. A folder that is missing or unreadable (an unmounted drive, an offline sync folder, a renamed directory) is named under its collection with a Root unavailable: line and the error; its documents stay indexed and counted. JSON output adds rootError (code, message) to that collection and sets healthy to false. The report clears as soon as the folder is back, without an update. For sourceAvailability: local collections the check confirms the folder exists and is readable without listing it, so it never downloads a cloud folder's listing.

Status lists configured collections only. Indexed collections the config does not list appear under Collections not in this config (JSON: staleCollections); other commands refuse to open that index until you add them back, use a separate --index, or run gno cleanup. See Troubleshooting.

gno ls --collection notes
gno tags
gno metadata --collection notes
gno status --json
gno doctor

gno doctor includes an embedding-fingerprint check. In JSON output, that check carries an embeddingFingerprint object with currentFingerprint, pendingChunks, legacyChunks, mixedGroups, and groups. Warnings mean BM25 still works, but semantic results may need gno embed or gno embed --force. A vector-partitions check reports the partition retrieval uses and warns about shadow or legacy partitions and incompatible runtimes. A collection-roots warning names each collection whose folder is missing or unreadable right now, with the folder and the error; it counts as a warning for the exit code but makes the structured doctor result non-healthy. The documents stay indexed.

Doctor and status also expose collection-scoped retrieval activation. Lexical readiness comes from a corpus-derived local search that must return the expected indexed document; it does not wait for semantic models. Semantic state is reported independently and may remain pending or skipped. Connector rows appear only after you run the connector check in the Web UI, and only while that result still matches the current setup. Only the first 64 target/collection checks are listed, but every check counts: the listing says how many of the rest passed, failed or are pending, and overall connector health is decided from all of them.

gno peek

Cheap read-only snapshot of index counts, backlog, recent files, and whether detached serve is up. One invocation; no model or embedding initialization. Use it instead of composing gno status + gno ls + gno changes. Keep gno status for activation, onboarding, and the full health payload. Status bars and desktop widgets can poll it on a coarse interval. GNO Recall (omarchy plugin add https://github.com/gmickel/omarchy-gno-recall) uses this snapshot from the Omarchy bar.

gno peek
gno peek --json

Uninitialized is success: --json returns initialized: false with pinned nulls and recent: [], exit 0. JSON is peek@1.0. recent is at most 10 files, newest first. recent[].absPath is the path to open a recent file without gno get. serve.running is pid-file based and is true only for gno serve --detach. A foreground gno serve is not detected. A stale pid reports not running. There is no HTTP probe. If any part of the snapshot fails, peek returns one RUNTIME error (exit 2) and no partial snapshot.

{
  "schemaVersion": "peek@1.0",
  "initialized": true,
  "counts": { "documents": 1234, "collections": 5 },
  "backlog": { "pending": 0, "failed": 0 },
  "lastIndexedAt": "2026-08-29T09:00:00Z",
  "recent": [
    {
      "docid": "#abc123",
      "uri": "gno://notes/inbox.md",
      "title": "Inbox",
      "collection": "notes",
      "absPath": "/home/user/notes/inbox.md",
      "modifiedAt": "2026-08-29T08:55:00Z"
    }
  ],
  "serve": { "running": true, "url": "http://localhost:3000" }
}

When serve.running is true, open a document in the Web UI with the stable template {serveUrl}/doc?uri=<encodeURIComponent(uri)> (serve.url plus document URI; optional #anchor). See document deep links.

gno capture

Capture writes a note into an editable collection. Inline content,--stdin, and --file are mutually exclusive. Capture accepts text only; binary-like file or stdin content is rejected before writing. With no path, folder, or title, captures land under inbox/YYYY-MM-DD/capture-<body-hash>.md using UTC time.

gno capture "thought to remember"
gno capture --stdin --collection notes --preset source-summary --tags inbox,gno
gno capture --file ./clip.md --source-url https://example.com --source-kind web --json
gno capture --preset person --title "Jane Doe" --folder people/
gno capture --preset meeting --title "Weekly sync" --folder meetings/
gno capture "meeting note" --quiet

Preset IDs include blank, project-note, research-note, decision-note, prompt-pattern, source-summary, idea-original, person, company-project, and meeting. The typed second-brain presets keep current synthesis above ## Timeline and dated evidence below it.

JSON output returns a receipt with separate write, sync, and embed status. Capture writes and syncs the note into text search before it returns; it does not imply embedding unless embed.status is completed. If lexical sync fails, the command still exits 0 with sync.status failed; run gno update to index the note. Capture writes fail instead of replacing a late-arriving file.

Retry-safe writes and gno request-status

gno capture and gno remember (with --add or --supersede) accept --request-id <id>; check one with gno request-status <id> [--json] before retrying. See Retry-safe writes.

Relationships: links, backlinks, similar, graph

These commands answer “what does this note point to?”, “what points back?”, and “what is semantically nearby?”.

gno links gno://notes/llm-memory.md
gno backlinks gno://notes/llm-memory.md
gno similar gno://notes/llm-memory.md --limit 8

Links resolve across the collections of one link workspace, so backlinks can come from a sibling collection. JSON names the other collection (resolvedCollection on links, sourceCollection on backlinks); gno backlinks --collection limits the linking documents.

gno graph

Builds a document graph from wiki links, markdown links, backlinks, unresolved links, and optional similarity edges. Use it to find hubs, isolated notes, communities, nearest neighbors, and paths between ideas.

gno graph --collection notes --json
gno graph --neighbors gno://notes/llm-memory.md
gno graph --from gno://notes/a.md --to gno://notes/b.md
gno graph --include-similar --threshold 0.78
gno graph --dot > graph.dot
gno graph --mermaid

Sync repairs affected incoming graph references across collections, including changed target identities and ambiguous names. Unchanged syncs skip the graph work, and after an interrupted sync the next run rebuilds the graph in full. No separate graph-rebuild command is needed.

Services: serve and daemon

gno serve

Starts the local browser workspace and REST API. Use it when you want visual search, browsing, graph exploration, editing, or API access. Default serve is the production bundle; --dev enables the development bundle with HMR.

gno serve
gno serve --dev
gno serve --port 8080
gno serve --detach
gno serve --status --json
gno serve --stop

gno daemon

Runs the headless watch/sync/embed loop plus the resident MCP gateway at /mcp. Use it when your CLI and AI tools need fresh search results but you do not need the browser open.

The daemon picks up edits, editor atomic saves, renames, and folder deletions, and retries failed syncs. A change that keeps failing to sync is retried after 0.5 seconds at first, then twice as long each time up to 5 minutes, until a sync succeeds; new edits are still picked up right away. A file GNO cannot read at all (locked, password-protected, too large) is recorded once, the way gno update does, and tried again when the file changes, so it never causes repeated rescans. When it cannot tell exactly what changed, it resyncs the whole collection. This applies to supported local filesystems; some network and removable volumes are not covered.

The daemon also rechecks watched Context Capsules when documents they cite change, and after a restart it resumes without repeating work. Rechecks write no source or Capsule files and run no answer model.

gno daemon --detach
gno daemon --no-sync-on-start
gno daemon --status
gno daemon --stop

Lifecycle flags for both commands: --detach, --status, --stop, --pid-file, --log-file. --json is for --status. Serve and daemon are alternative owners of one resident index: a second process against the same data directory is rejected.

Background syncs and embedding wait while a CLI command is writing. A CLI write that overlaps a busy server or daemon reports BUSY (exit 4) at worst, never a raw database is locked error. A failing background embed pass backs off and parks after 5 failures in a row. gno status, gno serve --status, and gno daemon --status list these as background issues, together with an overrunning pass or a resident that does not answer within 500ms. See resident background issues.

Reindex requests sent to a running server or daemon (MCP gno_sync and gno_index, or POST /api/sync) wait in a queue while another job runs instead of being refused. Requests for the same collection merge into one waiting pass, and a request can name just the files that changed. See reindexing over MCP and POST /api/sync.

Started on a session archive config and index with automation profiles enabled, the daemon also runs due session schedules and pending imports (from schedules, the Claude Code SessionEnd hook, or an interrupted run) at startup and every 30 seconds through the ordinary sessions import path. sessions automation enable and disable take effect without a restart. A daemon on a config without automation profiles does nothing here, and gno serve never runs these imports. The daemon keeps answering MCP and status requests during a long import. If the archive is busy, the run is recorded as failed with reason busy and retried with backoff. Logs contain no session content. Check automation with gno sessions status; gno daemon --status does not show it. GNO never installs or starts the daemon for you.

CLI commands load their own models and do not use a running server or daemon. Serve and daemon load models on first use and keep them loaded during the idle grace. The first request, and the first after an idle period, is slower because it loads the model. If model loading fails, GNO reports the error and does not retry on its own; send the request again. Hybrid fallback reports whether vector retrieval actually succeeded.

Stopping serve or daemon waits up to about 11 seconds for running work to finish or cancel. Completed checkpoints survive; unfinished embeddings resume on the next start. See shutdown behavior for limits.

Agents, models, publishing, and maintenance

gno mcp and gno skill

Use MCP when you want AI clients to call GNO tools automatically. Use skills when you want explicit /gno lookups with low context overhead.

gno mcp install --target claude-desktop
gno mcp install --target cursor --scope project
gno skill install --target all --scope user --force
gno skill paths

At user scope, the Claude target follows CLAUDE_CONFIG_DIR and the Codex target follows CODEX_HOME when they are set, as gno agents does: the skill goes to $CLAUDE_CONFIG_DIR/skills/gno or $CODEX_HOME/skills/gno. gno skill uninstall and gno skill paths resolve the same directories. A blank value counts as unset.

gno agents

Install a versioned GNO protocol block into each detected harness's global instruction file (Claude Code, Codex, Cursor, OpenCode, Hermes, OpenClaw; Grok is covered via Claude) so agents know the retrieval ladder before they reach for the skill. Backup-first, idempotent, symlink-aware; --dry-run shows the diff and --extra-dir handles nonstandard layouts. Exit 1 on malformed markers or an outdated block, 2 when a file cannot be read or written; on failure the complete block is printed for manual use. update refreshes only files that already contain the block: a file without one is reported absent with a hint to run gno agents install, and is never written or created.

gno agents install
gno agents install --target claude --dry-run
gno agents install --extra-dir ~/.claude-instances/work-cli
gno agents verify --json
gno agents update
gno agents uninstall

models, publish, bench, vec, cleanup

These are supporting commands for model files, shared artifacts, retrieval evaluation, vector index maintenance, and housekeeping.

gno models list
gno models use balanced
gno models pull
gno publish export atlas --out ~/Downloads/atlas.json
gno bench fixture.json --modes bm25,hybrid --json
gno vec sync
gno vec drop 9a8b7c6d5e4f
gno cleanup
gno completion zsh

gno vec sync repairs drift in the vector index after failed inserts, and gno vec rebuild rebuilds it in full. Run gno vec sync when gno similar returns nothing although embeddings exist. gno vec drop removes an abandoned shadow vector partition and its vectors, named by an id prefix of at least 8 characters from gno status. Status prints a drop hint for exactly the partitions drop accepts: shadow or legacy partitions this runtime does not read. Active partitions are refused, because another runtime may read them. See Switching backend or Bun version.

gno cleanup deletes the documents of indexed collections the config does not list, then orphaned content, chunks, and vectors. Before deleting, it names each of those collections on stderr (Deleting collections not in this config:). It deletes whatever the config you pass omits, so run it with the config that owns the index. With --json, the announcement is {"deleting": [...]} on stderr and the result carries droppedCollections and the orphan counts.

Global options and output flags

Global options work before the command name. Output flags are repeated on retrieval and read commands where they make sense.

Long terminal output honors $PAGER. Without an override, GNO uses less -R on Unix and a built-in less-compatible pager on Windows, including backward scrolling and search. Use --no-pager for automation or direct output.

The CLI flushes stdout and stderr before it exits, so large piped output such as gno search --json | jq arrives complete. A consumer that closes the pipe early, such as | head, still lets the command exit promptly with its own exit code. Structured errors follow the error output schema, which lists every CLI error code, including BUSY (exit 4).

Typed metadata filters

Pass --filter JSON to search, vsearch, query, query diagnose, ask, and context build. Custom predicates intersect existing scope and fixed filters before candidate limits.

Read the metadata guide: examples, operators, missing fields, limits, and recovery.

Agent session archive

gno sessions discover previews local Codex, Claude Code, OpenClaw, and Hermes session roots and never imports. On a dedicated archive config/index pair, sessions init, source add and remove, import (with --dry-run and --limit), status, and prune manage a manual, redacted archive. Nothing imports, watches, or schedules on its own unless you explicitly enable automation for a profile.

gno sessions discover
gno --config ~/gno-sessions/archive.yml --index sessions sessions init --archive ~/gno-sessions/archive --collection sessions-work
gno --config ~/gno-sessions/archive.yml --index sessions sessions source add codex --harness codex --path ~/.codex/sessions --collection sessions-work
gno --config ~/gno-sessions/archive.yml --index sessions sessions import --source codex --dry-run
gno --config ~/gno-sessions/archive.yml --index sessions sessions import --source codex --json
gno --config ~/gno-sessions/archive.yml --index sessions sessions status

Exit codes: 1 validation (including a selection with no supported session format), 4 busy, 2 for an unavailable source, a failed import or automation run, or a hook that was not accepted; the error-code table and troubleshooting live in the session archive guide, with the config/index binding, receipts, and redaction limits.

gno sessions automation

Opt-in hooks and daemon schedules for registered sources. Every trigger is off until you enable it; the imports always go through sessions import. Full behaviour: Automation.

A="gno --config ~/gno-sessions/archive.yml --index sessions"
$A sessions automation set claude --source claude-code [--cadence 30m] [--limit 200] [--retries 3]
$A sessions automation preview claude [--settings <file>]
$A sessions automation enable claude --hook claude-code [--settings <file>]
$A sessions automation enable claude --schedule --cadence 30m
$A sessions automation run claude
$A sessions automation disable claude [--hook] [--schedule]
$A sessions automation remove claude
SubcommandDescription
set <profile>Create or reconfigure a profile: --source <id> (repeatable), --cadence, --limit, --retries. Enables nothing.
preview <profile>Sources with paths, destinations, the exact hook command and settings file, schedule, budget, daemon prerequisite.
enable <profile>--hook claude-code installs the owned SessionEnd entry; --schedule --cadence <n>s|m|h|d (min 1m) turns on ticks.
run <profile>Run the profile now through the importer (exit 4 SESSIONS_BUSY when the archive is busy, and the busy run is recorded; exit 2 when the run failed otherwise).
disable <profile>Pause: switch triggers off (all, or --hook / --schedule), remove the owned entry, clear pending work.
remove <profile>Uninstall owned integrations and delete the profile; archives are kept.

All subcommands accept --json. run --json prints the sessions-automation-run object. sessions status includes an automation block with daemon availability and, per profile, state, hook and schedule switches, pending and running work, last run, last success, next due time (only with a running daemon), and a recovery action; text output shows times in your local timezone.

gno sessions hook

gno --config ~/gno-sessions/archive.yml --index sessions sessions hook claude-code --profile claude

The command a Claude Code SessionEnd hook runs; automation enable --hook installs it. It reads the event on stdin, durably marks the profile pending and prints one line: accepted (… pending, not yet archived …), skipped (…), or not accepted (…) with exit 2. It never imports. Set GNO_SESSIONS_HOOKS=off to make every installed hook return immediately. An unknown profile is reported as skipped (… unknown_profile), a profile whose hook is off as skipped (… hook_disabled). An explicit --settings other than the default location must name an existing file (VALIDATION).