kythe is a small, dependency-free client for scripts and terminals. It is the human counterpart to the MCP surface your agents use.
Install
Download the archive for your platform from github.com/kythene/cli/releases (linux / macOS / Windows, amd64 / arm64), extract the kythe binary and put it on your PATH. On macOS/Linux:
tar xzf kythe_*_$(uname -s | tr A-Z a-z)_*.tar.gz kythe
sudo mv kythe /usr/local/bin/
kythe --helpWith source access you can also build it from a checkout: go build -o kythe .
Configure
export KYTHE_URL=https://kythene.com # default; your own host if self-hosting
export KYTHE_TOKEN=twk_... # an API key (create one in the app)
export KYTHE_SPACE="My space" # optional: the default for --spaceThe old KYTHENE_URL, KYTHENE_TOKEN and KYTHENE_SPACE names are no longer read: KYTHENE_ is the prefix a Kythene server reads for its own settings, so kythe leaves it alone.
KYTHE_TOKEN takes a twk_ API key (recommended). Create keys in the app under Connect your AI / Settings; copy at creation (shown once).
A key acts as your own account. Same access as you (the default) carries exactly your permissions in a workspace and nothing more, and follows your current role - if that changes, or you leave the workspace, the key's access changes with it. Narrow a key at creation to Read-only (recall and reads) or Write-only (publishing from apps and crons). Choose the workspace scope too: this workspace only, or all of yours.
Commands
This reference documents kythe v0.12.0. Run kythe --version to check the build you have; if it is older, some flags below may not yet be present.
kythe create-collection <file>... [--tag T]... [--title X] [--space S]
kythe ingest --body TEXT [--kind K] [--severity S] [--title X] [--tag T]... [--producer P] [--space S]
kythe version <collection-id> <file>... [--note X] [--space S]
kythe timeline [QUERY] [--tag T] [--limit N] [--json] [--space S] (QUERY, or --search Q)
kythe get <collection-id> [--json] [--space S]
kythe artifact <artifact-id> [--content] [--version N] [--out FILE] [--json] [--space S]
kythe archive <collection-id> [--restore] [--space S]
kythe add <collection-id> <file>... [--ref <artifact-id>]... [--note X] [--space S]
kythe reorder <collection-id> <artifact-id>... [--space S]
kythe move <artifact-id> <from-collection-id> <to-collection-id> [--space S]
kythe delete <collection-id> [--undelete] [--space S]
kythe wikis [QUERY] [--archived] [--json] [--space S] the wikis in this workspace (--archived: the archived ones)
kythe pages <wiki> [--json] [--space S] its pages, as a tree
kythe page <wiki> [page-path] [--json] [--space S] the page's markdown, on stdout
kythe create-wiki <name> [--slug S] [--description X] [--approval] [--body B] [--space S]
kythe create-page <wiki> <title> [--parent P] [--slug S] [--file F|-] [--body B] [--space S]
kythe update-page <wiki> [page-path] (--file F|- | --body B) [--title X] [--note N] [--base N] [--space S]
kythe page-state <wiki> [page-path] <state> [--note N] [--reviewer R] [--space S]
kythe move-page <wiki> <page-path> [--parent P] [--slug S] [--space S]
kythe wiki-state <wiki> <live|archived|deletion_scheduled> [--space S] archive, restore or delete a whole wiki
kythe remember <file|-> [--title X] [--project P] [--type T] [--tag T]... [--alias A]... [--private] [--supersedes ID] [--space S]
kythe recall [QUERY] [--project P] [--type T] [--scope everything|memory] [--include-deprecated] [--limit N] [--json] [--space S]
(QUERY, or --search Q)
kythe catchup [--peek] [--limit N] what changed since this agent last looked
kythe forget <memory-id> [--space S]
kythe deprecate <memory-id> [--replaced-by ID] [--restore] [--space S]
kythe link <from-memory-id> <to-memory-id> [--space S]
kythe unlink <from-memory-id> <to-memory-id> [--space S]
kythe promote <memory-id> <target-space> [--space S]
kythe facts [--project P] [--area A] [--status open|settled|in_effect|replaced] [--source NAME] [--decisions] [--include-replaced] [--json] [--space S]
kythe fact <id> [--json] [--space S]
kythe facts add --says X --source NAME --when DATE --how HOW [--evidence ID|URL]... [--project P] [--area A] [--space S]
kythe ask --source NAME --ask "question" [--asked-on DATE] [--project P] [--area A] [--space S]
kythe answer <id> --says X --when DATE --how HOW [--source NAME] [--evidence ID|URL]... [--space S]
kythe decide --decided X --by NAME --when DATE --why Y [--context C] [--option O]... [--project P] [--area A] [--space S]
kythe replace <id> <the new record's fields, as facts add or decide> [--space S]
kythe correct <id> [--says X] [--decided X] [--note N] [--space S] (any field of the record; only what you give changes)
kythe review <collection-id> --artifact ID (--block <anchor|"text"> | --annotation <id>) --status STATUS [--comment X] [--space S]
kythe set-review <collection-id> [on|off] [--space S]
kythe share <collection-id> <target-space> [--space S]
kythe unshare <collection-id> <target-space> [--space S]
kythe share-code <tag> --label X [--expires-days N] [--pin NNNN] [--space S]
kythe share-codes [--tag T] [--space S]
kythe revoke-code <share-code-id> [--space S]
kythe share-pin <share-code-id> <pin> [--space S] (or --clear to remove a PIN)
kythe unlock-code <share-code-id> [--space S]
kythe projects [QUERY] [--space S] (QUERY, or --search Q)
kythe tag delete <name-or-id> [--space S]
kythe tag merge <source>... --into <target> [--space S]
kythe tag rename <name-or-id> <new-name> [--space S]
kythe tag password <name-or-id> <password> [--space S] (or --clear to remove)
kythe skill publish <dir> [--draft] [--note X] [--json] [--space S]
kythe skill list [--json] [--space S]
kythe skill get <name> [--version N | --draft] [--out DIR] [--json] [--space S]
kythe skill archive|restore|delete|discard <name> [--json] [--space S]
kythe skill state <name> published|discarded|archived|restored|deleted [--version N] [--note X] [--json] [--space S]
kythe spaces
kythe create-space <name>
kythe space-slug <slug> [--space S]
kythe export [--out DIR | --archive FILE] [--space S]
kythe import --archive FILE [--into SPACE] [--dry-run]Throughout, the --space / <target-space> arguments name a workspace - "space" is the CLI's name for a workspace (see About --space below). Omit --space when you belong to just one.
Every command takes a global --token twk_... that overrides KYTHE_TOKEN for that call - handy for a one-line cron with a scoped write-only key.
timeline, get, recall and artifact take --json, emitting the structured data behind the command (stable field names) instead of the human-readable text - for scripting. Without it the output is unchanged.
review - flag one block of a renderable artifact (and optionally comment).
--blockis a block anchor or a verbatim snippet;--statusis one ofneeds_review,needs_work,done,approved,reject_remove(empty clears). Use--annotation <id>instead of--blockto act on a thread whose block was rewritten so its anchor no longer resolves (the id comes fromkythe get). Only when the collection has requested review.set-review - turn the approval/review flow on or off for an existing collection, without re-publishing it.
create-collection - publish one or more files as a new collection. Repeat
--tagfor several tags; a tag can name a project or set access. A published markdown file renders[[Title]]wikilinks to a sibling document, a collection or a memory; an unresolved one stays plain text. This,addandversionare the route for binaries and anything large: they read the file off disk, up to 32 MiB each, where an agent over MCP has to write the whole file out as base64 through its own context and is capped at roughly 750 KB (see file content over MCP).ingest - publish a lightweight event/alert from a machine producer (a health check, a cron, a CI job) with no file:
--bodybecomes a text artifact and--kind/--severitybecome tags. Pair it with a write-only--token.version - add a new version of artifact(s) to an existing collection; bumps its revision.
--noterecords why.add - add files to an existing collection instead of republishing (which would create a new collection and abandon its comments and history). Pass new files by path, and/or reference already-published files of the same workspace with
--ref <artifact-id>; they append and bump the revision. If the collection is shared by a code, a warning names the holders who gain read access.reorder - set the order of a collection's files. List every current file id, once, in the order you want (get them from
kythe get); a partial or unknown-id list is rejected. Comments and reviews stay attached to their files.move - move one file from one collection to another in the same workspace, carrying its comments, reviews and history. It appends to the destination; if the move empties the source, the source archives itself. A warning names any share-code holders who gain read access. Cross-workspace moves are refused - use
sharefor that.timeline - the collection feed, newest first; filter by
--tagor search.get - show a collection and its artifacts by id.
artifact - show an artifact's version history;
--contentfetches one version's bytes (--version N,0= latest) to--out FILEor stdout.archive - archive a collection: a reversible retirement that hides it from the timeline, recall and search until you restore it (
--restore). Nothing is deleted and no storage is freed - it stays viewable and restorable by id.delete - schedule an archived collection for permanent deletion. It stays recoverable for 30 days (
--undeleteto cancel), then its content, files and history are erased for good, in every workspace it was shared into. Archive it first -deletefails on a live collection.facts, fact, ask, answer, decide, replace, correct - the facts and decisions commands.
HOWismeeting,email,call,message,their-siteortheir-document, andDATEisYYYY-MM-DD.factshides replaced records unless you pass--include-replaced.replaceis for when the source changed it,correctfor when you wrote it down wrong.remember - store a memory (from a file or stdin
-).--projectscopes it; re-remembering the same--titlein the same--projectsupersedes it, and--supersedes IDreplaces a named memory whatever its title (the way to heal a near-miss fork, since the new version can carry the corrected title).--typesets the note's kind (decision, how-to, gotcha, reference, person, meeting - free text);--tagsays what it is about.--aliasadds extra names a[[wikilink]]can reach it by, and--privatestores it author-private.[[wikilinks]]in the body link to other memories (by title, title-slug, alias or case-insensitively). A title is derived from the body's first line when--titleis omitted (a leading markdown#is stripped).recall - return the most relevant context with its full artifact content in one call. By default it spans everything you can access - memory and published work (each result tagged
memoryorcollection);--scope memorynarrows to memory only. Filter by--project,--typeand--search, and cap the count with--limit N(default 25, max 100).--include-deprecatedalso returns memories flagged stale, each with what replaced it - hidden by default so agents stop applying them, but there when you are auditing what the team used to believe. Each result prints its memory id (whatforget/deprecate/link/promotetake) and its provenance -by youfor your own, otherwiseby <author>, with· via <agent>. Recall blends full-text and semantic matching, and also returns the workspace guide.deprecate - mark a memory stale so recall stops surfacing it (
--restoreto un-deprecate;--replaced-byto point at its replacement).link / unlink - curate an explicit link between two memories, on top of the
[[wikilinks]]parsed from bodies.promote - promote a memory into another workspace you belong to, held for review there until an owner approves.
forget - permanently remove a memory by id (prefer
deprecatewhen the knowledge is superseded rather than wrong).share / unshare - map a collection into another workspace you belong to (or remove that mapping); the origin is untouched.
share-code / share-codes / revoke-code - mint a share code for a tag (a private link for an outsider -
--labelrecords who it is for), list the codes, and revoke one.--expires-days Ntime-boxes a code;--pin NNNNadds a second-factor PIN so the link alone (forwarded, screenshotted) is not access - it reaches a PIN prompt instead.share-codesmarks codes that carry a PIN and any that are locked out. Internal tags cannot have share codes.share-pin / unlock-code -
share-pin <id> <pin>sets or changes a code's PIN without changing the link (so a rotation does not invalidate what you sent);share-pin <id> --clearremoves it.unlock-code <id>clears a PIN brute-force lockout (a code locks after a few wrong attempts). See Sharing and guests.projects - list the projects (project-kind tags) in the workspace - the valid
--projectvalues forremember/recall.tag delete / merge / rename / password - manage the tag taxonomy and access.
deleteremoves a tag (untagging its collections and revoking its share codes);mergere-tags every source's collections onto--into <target>then removes the sources (one command to fold many stray projects into one);renamechanges a tag's name;password <tag> <pw>(or--clear) sets the tag's anonymous-view password. The server refuses an internal tag and a private project that still holds collections (removing its gate would expose them).export / import - export a whole workspace to a directory (
--out) or a.tar.gz(--archive), and import one back (into an empty--intoworkspace). Your data is yours - plain markdown + files, no lock-in. Owner/admin token.skill - write and manage workspace skills, owner or admin, on Team and Enterprise.
publish <dir>sends the directory as the whole skill (SKILL.mdand its files, hidden ones left out and named), as the next published version or, with--draft, as draft changes only you get.getshows a skill's state, history and a version's files;--out DIRwrites them to a new or empty directory to edit and publish again.state <name> publishedpublishes the draft, or with--version Nan earlier version again. Each change says how many people the skill now reaches. A skill the server won't load is refused with its reason.spaces - list the workspaces you belong to (with each one's slug); the current one is marked.
space-slug - set this workspace's readable slug, the segment in its anonymous share links (
/v/<slug>/<tag>/...). Stable across a rename; the id-based form keeps working, so links already sent stay valid.
About --space
--space selects the workspace (what the flag calls a "space" - the tenant). Pass an id or a name from kythe spaces. Omit it when you belong to one workspace. --project (on remember/recall) scopes to a project within the workspace.
Examples
# publish a benchmark into the 'api' project
kythe create-collection ./bench.json --tag api --title "Nightly bench"
# add a newer run to the same collection
kythe version 28f7adc5-... ./bench.json --note "after the index change"
# stash and recall a project memory
kythe remember runbook.md --project acme --title "Deploy runbook"
kythe recall --project acme
# target a specific workspace by name
kythe timeline --space "Acme workspace"Exit codes
0 success, 1 a runtime/API error (message on stderr), 2 a usage error.
Working with a wiki
A wiki is addressed by its slug (or id); a page by its path within that wiki - the same path the contents list shows you. The wiki's home page has no path, so leave the argument off to mean it:
kythe page estate # the home page
kythe page estate hardware # a page within it
kythe page-state estate published # publish the home page
kythe page-state estate hardware published # publish that pagekythe wikis # slug, id, name, published/total
kythe pages handbook # the tree, with drafts marked
kythe page handbook onboarding/day-one # the markdown, on stdoutkythe page writes the page body to stdout and everything else to stderr, so it redirects and diffs cleanly:
kythe page handbook onboarding/day-one > day-one.md
kythe page handbook onboarding/day-one | diff - day-one.mdWriting a page:
kythe create-page handbook "Day one" --file ./day-one.md
kythe page-state handbook day-one publishedA new page is a draft - your team can see it, nobody else can - until you publish it. update-page reads the page's current revision itself, so a second writer cannot silently overwrite the first:
kythe update-page handbook day-one --file ./day-one.md --note "added the parking bit"
kythe page-state handbook day-one publishedPushing a directory of markdown in:
for f in docs/*.md; do
kythe create-page handbook "$(basename "$f" .md)" --file "$f"
done