tenbrains / commands
Agent-first CLI · X research · local SQLite

tenbrains

Analyze posts, track accounts, and recall research from your terminal. Every command prints one JSON object — branch on ok, then error.code. stdout is the result; stderr is chatter. Add --pretty for humans.

The output contract
successexit 0
{
  "ok": true,
  "command": "analyze",
  "data": { /* … the result … */ },
  "meta": { "id": "ana_…", "persisted": true }
}
failureexit 5
{
  "ok": false,
  "command": "takeaway refresh",
  "error": {
    "code": "PROVIDER_RATE_LIMITED",
    "message": "x api: rate limited (429).",
    "retryable": true
  }
}
0 ok 2 usage 3 not found 4 credentials 5 provider 6 validation 7 conflict 1 internal
Configure

setup — credentials, once

Collect and store your AI key (and optional X token) through the CLI. Written to a managed file at mode 0600 — never a hand-edited dotfile, never an env var.

$ tenbrains setup --provider anthropic --api-key sk-ant-… --x-bearer AAAA… --default

Store your Claude key and X Bearer token in one step. Run it with no flags to be prompted interactively. The key never leaves your machine.

setupexit 0
{
  "ok": true,
  "command": "setup",
  "data": {
    "provider": "anthropic",
    "model": "claude-sonnet-4-6",
    "default": true,
    "keyConfigured": true,
    "xConfigured": true
  },
  "meta": { "persisted": true }
}
Configure

config — read & write settings

Manage the config directly by dot-path: default provider, per-provider models and keys, the X token. Secrets are redacted unless you pass --reveal.

$ tenbrains config set <key> <value>

Set any value. The value may be inline, @file, or - (stdin) so a secret stays out of shell history.

config setexit 0
{ "ok": true, "command": "config set",
  "data": { "key": "x.bearerToken", "value": "********wXY2" },
  "meta": { "persisted": true } }
$ tenbrains config list --reveal

See everything you've configured. config get <key> reads one value; config unset <key> removes it.

config listexit 0
{ "ok": true, "command": "config list",
  "data": { "entries": [
    { "key": "defaultProvider", "value": "anthropic" },
    { "key": "providers.anthropic.apiKey", "value": "********pgAA" },
    { "key": "x.bearerToken", "value": "********wXY2" }
  ] } }
$ tenbrains config path

Show exactly where the config file and database live on disk.

config pathexit 0
{ "ok": true, "command": "config path",
  "data": {
    "configPath": "~/.config/tenbrains/config.json",
    "dbPath": "~/.local/share/tenbrains/tenbrains.db"
  } }
Research

analyze — a post → topic, summary, intent, 5 concepts

Give it text you paste, or a tweet URL to fetch. Single tweets fetch free via oEmbed; add --fetch api for the official API, or --learn to also build a study track.

$ tenbrains analyze --url https://x.com/jack/status/20

Fetch a tweet and analyze it with Claude. No X credits needed — the free oEmbed path pulls the text and author.

analyze · real outputexit 0
{
  "ok": true,
  "command": "analyze",
  "data": {
    "post": { "id": "post_0mq…", "authorUsername": "jack",
              "text": "just setting up my twttr" },
    "analysis": {
      "topic": "Social media platform launch",
      "intent": "To publicly inaugurate the platform with its first message.",
      "novelConcepts": [
        { "name": "First tweet",
          "whyItMattersInTweet": "The first message ever published on the platform." }
        /* …four more concepts… */
      ]
    }
  },
  "meta": { "analysisId": "ana_0mq…", "provider": "anthropic",
            "model": "claude-sonnet-4-6", "mock": false,
            "source": "x:oembed", "persisted": true }
}
$ tenbrains analyze --text "…" --author levelsio --learn

Analyze content you already have (--text, @file, or stdin) and optionally generate a learning track in the same call.

analyze --learnexit 0
{ "ok": true, "command": "analyze",
  "data": { "analysis": { "id": "ana_0mq…", "topic": "…" },
            "track": { "id": "trk_0mq…", "minutesPerDay": 10 } },
  "meta": { "source": "text", "mock": false, "persisted": true } }
$ tenbrains analyze list --limit 5 · analyze get <id>

Read your stored analyses back — the full list, or one by id with its post.

analyze listexit 0
{ "ok": true, "command": "analyze list",
  "data": { "count": 3, "analyses": [
    { "id": "ana_0mq…", "topic": "Social media platform launch" }
  ] }, "meta": { "limit": 5, "offset": 0 } }
Research

takeaway — follow an account, summarize its posts

Follow accounts, then distill their recent posts into a summary plus bullet takeaways. Supply posts with --posts, or fetch a timeline from X with --count. History is kept per account.

$ tenbrains takeaway refresh mattpocockuk --count 10

Pull an account's recent posts from X and summarize them with Claude. Saved as a snapshot you can revisit.

takeaway refresh · real outputexit 0
{
  "ok": true,
  "command": "takeaway refresh",
  "data": {
    "account": { "username": "mattpocockuk" },
    "snapshot": {
      "summary": "mattpocockuk is actively building Claude Code slash-command skills to orchestrate AI agents for planning and research.",
      "takeaways": [
        "Building a /wayfinder skill to plan large chunks of work.",
        "Tip: claude --bg --name to spin up named background agents.",
        "Renamed /to-prd to /to-spec and /to-issues to /to-tickets."
        /* …two more… */
      ],
      "postCount": 10
    }
  },
  "meta": { "snapshotId": "snap_0mr…", "source": "x:api",
            "mock": false, "postCount": 10, "persisted": true }
}
$ tenbrains takeaway follow mattpocockuk

Start tracking an account. takeaway unfollow stops and removes its snapshots; takeaway list shows every account with its latest takeaway.

takeaway followexit 0
{ "ok": true, "command": "takeaway follow",
  "data": { "account": { "id": "acc_0mr…", "username": "mattpocockuk" } },
  "meta": { "accountId": "acc_0mr…", "persisted": true } }
$ tenbrains takeaway show mattpocockuk --history

Show the latest takeaway with its source posts, or --history for every snapshot over time.

takeaway showexit 0
{ "ok": true, "command": "takeaway show",
  "data": { "account": { "username": "mattpocockuk" },
    "snapshot": { "summary": "…", "takeaways": [ "…" ] },
    "sourcePosts": [ { "text": "Building a /wayfinder skill…" } ] } }
Curate

suggest — ranked recommendations with feedback

Rank analyzed-but-unsaved posts against your saved signal (bookmark tags + takeaway themes). Save or dismiss to teach the next round.

$ tenbrains suggest generate

Build a ranked list of posts worth revisiting, each with a reason. suggest list filters by status.

suggest generateexit 0
{ "ok": true, "command": "suggest generate",
  "data": { "created": 2, "profileEmpty": false, "suggestions": [
    { "id": "sug_0mr…", "score": 7,
      "reason": "Matches your saved interest in embeddings, vector, retrieval." }
  ] }, "meta": { "created": 2, "persisted": true } }
$ tenbrains suggest save <id> · suggest dismiss <id>

Saving turns a suggestion into a bookmark; dismissing hides it from future ranking. suggest add injects your own candidate.

suggest saveexit 0
{ "ok": true, "command": "suggest save",
  "data": { "suggestion": { "id": "sug_0mr…", "status": "saved" },
            "bookmark": { "id": "bm_0mr…" } },
  "meta": { "bookmarkId": "bm_0mr…", "persisted": true } }
Curate

bookmark — save posts with tags & notes

Save any post; if it's been analyzed, tags are suggested automatically. Filter, retag, and prune your collection. Aliased as bm.

$ tenbrains bookmark add --post-id <id>

Save a post — auto-tagged from its analysis unless you pass --tags. Add --note for context.

bookmark addexit 0
{ "ok": true, "command": "bookmark add",
  "data": { "bookmark": { "id": "bm_0mr…",
    "tags": [ "twttr", "first-tweet", "microblogging" ], "source": "cli" } },
  "meta": { "bookmarkId": "bm_0mr…", "autoTagged": true, "persisted": true } }
$ tenbrains bookmark tag <id> --add rag,agents --remove draft

Retag a bookmark. bookmark list --tag rag filters; bookmark show <id> opens it with post + analysis; bookmark remove deletes.

bookmark tagexit 0
{ "ok": true, "command": "bookmark tag",
  "data": { "bookmark": { "id": "bm_0mr…", "tags": [ "rag", "agents" ] } },
  "meta": { "persisted": true } }
Curate

learn — a 7-day Feynman track from any analysis

Turn an analysis' concepts into a paced study plan: each day pairs a concept with Learn / Explain / Check steps. Rate concepts to prioritize what you care about.

$ tenbrains learn generate --analysis <id> --minutes 10

Generate a 7-day study track. learn show <id> re-opens one; learn list shows all.

learn generateexit 0
{ "ok": true, "command": "learn generate",
  "data": { "track": { "id": "trk_0mr…", "minutesPerDay": 10, "days": [
    { "day": 1, "concept": "First tweet",
      "learn": "4 min: Read a primer on \"First tweet\".",
      "explain": "4 min: Explain it to a beginner, no jargon.",
      "check": "2 min: Note one question to resolve tomorrow." }
    /* …six more days… */
  ] } }, "meta": { "trackId": "trk_0mr…", "persisted": true } }
Recall

search & record — find and resolve anything

Keyword-search everything you've stored, grouped by type. Or jump straight to any record by its prefixed id.

$ tenbrains search "vector databases" --type analysis,bookmark

Search across analyses, takeaways, and bookmarks at once — results grouped by source and ranked by overlap.

searchexit 0
{ "ok": true, "command": "search",
  "data": { "query": "vector databases", "total": 2, "groups": {
    "analysis": [ { "id": "ana_0mq…", "score": 0.83, "title": "Vector & databases" } ],
    "takeaway": [],
    "bookmark": [ { "id": "bm_0mr…", "score": 0.5, "title": "#embeddings" } ]
  } }, "meta": { "total": 2 } }
$ tenbrains record get ana_0mq…

Resolve any idpost_ · ana_ · acc_ · snap_ · bm_ · sug_ · trk_ — to its record, without knowing which table it's in.

record getexit 0
{ "ok": true, "command": "record get",
  "data": { "type": "analysis",
    "record": { "id": "ana_0mq…", "topic": "Social media platform launch" } } }
Operate

db — inspect & maintain the store

Everything lands in one local SQLite file. Check what's in it, compact it, migrate the schema, or wipe it clean.

$ tenbrains db stats

See row counts and schema version at a glance.

db statsexit 0
{ "ok": true, "command": "db stats",
  "data": { "path": "…/tenbrains.db", "schemaVersion": 1, "total": 21,
    "tables": { "posts": 12, "analyses": 3, "accounts": 1,
      "takeaway_snapshots": 1, "bookmarks": 2,
      "suggestions": 1, "learning_tracks": 1 } } }
$ tenbrains db reset --yes · db migrate · db vacuum

Wipe all data (guarded by --yes), apply pending migrations, or compact the file. Isolate a throwaway workspace anytime with --db ./scratch.db.

db resetexit 0
{ "ok": true, "command": "db reset",
  "data": { "path": "…/tenbrains.db", "schemaVersion": 1, "reset": true },
  "meta": { "persisted": true } }
Operate

manifest — the whole CLI, as JSON

One call returns the entire command tree, every flag, the provider catalog, and the error/exit-code tables. This is how an agent discovers the tool.

$ tenbrains manifest

Self-describe the entire CLI so an agent never has to guess a command or flag.

manifestexit 0
{ "ok": true, "command": "manifest",
  "data": {
    "name": "tenbrains", "version": "2.0.0",
    "commands": [ /* the full tree with args + options */ ],
    "providers": [ "anthropic", "openai", "google", "xai", "mock" ],
    "errorCodes": [ /* … */ ],
    "exitCodes": { "USAGE": 2, "NOT_FOUND": 3, "MISSING_CREDENTIALS": 4 /* … */ },
    "database": { "engine": "sqlite", "schemaVersion": 1 }
  } }
Everywhere

global flags — valid on any command

Output defaults to JSON so agents can parse it. These work in any position, on any command.

--jsonThe JSON envelope (default).
--prettyHuman-readable output instead.
--quietSilence progress on stderr.
--db <path>Point at a specific database.
--config-dir <path>Use a specific config directory.
-h · -vHelp and version.
anthropic · default openai google xai mock · offline