Skip to content
All docs

AI and automation

bitty CLI

Install the bitty command line, sign in with an access token, and use its commands, output modes and exit codes from a terminal, scripts and AI agents.

View as Markdown

bitty is the Bitty Course command line. It talks to your workspace's MCP server, the same tools an AI assistant uses, so permissions, plan limits and validation all come from the server. Use it to check courses, links, stats and discounts from a terminal, a script or an agent.

Install

bitty is a single Ruby script that uses only Ruby's standard library. It needs Ruby 3.2 or newer and nothing else.

To install it:

  1. Download it from your Bitty Course app address at /cli/bitty, for example curl -fsSLo bitty <your Bitty Course app address>/cli/bitty. The Docs link in the studio sidebar is on the same address.
  2. Make it executable: chmod +x bitty.
  3. Put it on your PATH, for example with a link: ln -s "$PWD/bitty" /usr/local/bin/bitty.
  4. Check it runs: bitty --version prints bitty 0.1.0.

Sign in

You sign in with a personal access token. See Create a token.

To sign in:

  1. Create a token in Settings → AI assistant. Choose the access level you want the CLI to have.
  2. Run bitty auth login --url <your Bitty Course app address>. Use the address only, without /mcp; bitty adds that itself.
  3. Paste the token when asked. The input is hidden.

bitty checks the token with the server before saving it. If the token is refused, nothing is saved and it exits with code 3.

To sign in without a prompt (in a script), pass the token on standard input:

bitty auth login --url <address> --with-token < token.txt

Without --with-token, auth login needs a terminal to prompt in.

Auth commands

Command What it does
bitty auth login [--url URL] [--with-token] Check a token and save it with the address.
bitty auth status Whether you're signed in, to which workspace, your role, the token's access level, and where the token came from. bitty auth alone does the same. Exits with code 3 when you're not signed in.
bitty auth logout Forget the token on this computer.
bitty auth token Print the saved token.

bitty auth logout only removes the token from this computer. It keeps working until you revoke it in Settings → AI assistant.

Config and environment variables

The address and token are saved to ~/.config/bitty/config.json, readable only by you (file mode 600).

Variable Effect
BITTY_URL Bitty Course address to use instead of the saved one.
BITTY_TOKEN Token to use instead of the saved one.
BITTY_CONFIG_DIR Folder for config.json instead of ~/.config/bitty.
XDG_CONFIG_HOME If set (and BITTY_CONFIG_DIR isn't), the config goes in $XDG_CONFIG_HOME/bitty.

The address is taken from --url, then BITTY_URL, then the saved config. If none is set, bitty can't reach your workspace, so always sign in with --url.

Commands

The shape is bitty <command> [action] [args] [flags]. bitty --help lists everything, and bitty <command> --help shows one command's usage.

Command Description
auth Sign in with a token and check the connection
workspace Your workspace: plan, limits and courses
courses List courses, see one, get its links, stats or publish it
discounts Coupon codes and timed sales for a course
stats Workspace totals over a date range
tools List the MCP tools this token can use
call Call any MCP tool with JSON or key=value arguments
commands Every command and action, as JSON

workspace

bitty workspace

Your workspace's name, plan, limits, video storage, whether payments are set up, the token's access level and your courses.

courses

bitty courses                                    # list: id, title, status, access, price, lessons
bitty courses show <course>                      # details, sections and what still blocks publishing
bitty courses link <course> [--url-only]         # public, preview and studio links, plus coupon links
bitty courses stats <course> [--range 7d|30d|90d|12m|all]
bitty courses publish <course>

<course> is an id, a slug, or part of the title when it matches exactly one course. If a name matches several courses, bitty lists them and exits with code 8; use the id.

--url-only prints just the public link. Until the course is published, the public link shows "not available".

courses publish needs a Build and publish token. If something blocks publishing, the error lists what.

bitty course works the same as bitty courses.

discounts

bitty discounts <course>                         # coupons and sales
bitty discounts show <course> <id|CODE>          # uses, revenue, savings (no student names)
bitty discounts create <course> --code CODE (--percent N | --amount N) [--name NAME] [--starts TIME] [--ends TIME] [--limit N]
bitty discounts sale <course> --name NAME (--percent N | --amount N) --ends TIME [--starts TIME]
bitty discounts off <course> <id|CODE>
bitty discounts on <course> <id|CODE>
  • Times are ISO 8601 with a zone, for example 2026-12-01T09:00:00-05:00.
  • --limit is how many students can use a coupon. Leave it out for no limit.
  • Only workspace owners create or switch discounts. A published course also needs a Build and publish token.
  • Amounts and dates can't be edited. Turn the discount off and make another.

bitty discount and bitty coupons work the same as bitty discounts. See Coupons and sales.

stats

bitty stats [--range 7d|30d|90d|12m|all]

Workspace totals and a row per course: students, new students, revenue and average progress. The default range is 30 days. Stats never include student names or emails. See Analytics.

tools and call

bitty tools                                      # the MCP tools this token can call
bitty call get_transcript lesson_id=12           # key=value arguments
bitty call get_course '{"course_id": 1}'         # or one JSON object

call reaches every tool the token can use, including ones without their own command, such as building outlines or adding captions. Values in key=value are read as JSON when they parse (numbers, true, arrays), otherwise as text. See MCP tool reference for each tool's arguments.

commands

bitty commands

Every command, its description and its actions, as JSON. Useful for an agent to discover what's available.

Output modes

Flag Output
(none, in a terminal) Readable text: a summary line, a table or fields, then suggested next commands.
(none, piped) The JSON envelope, as with --json.
-j, --json JSON envelope.
-q, --quiet The data only, as JSON, no envelope.
--agent Same as --quiet, for scripts and assistants.
-m, --md Markdown: a bold summary, then a table or a list.

The JSON envelope on success:

{
  "ok": true,
  "data": { },
  "summary": "One line saying what happened",
  "breadcrumbs": [ { "action": "Show a course", "cmd": "bitty courses show <id>" } ]
}

breadcrumbs suggest next commands and are left out when there are none.

On failure, in JSON, quiet and agent modes, the error is printed to standard output:

{ "ok": false, "error": "Not signed in.", "code": "auth", "retryable": false, "hint": "Run: bitty auth login" }

In text and Markdown modes, the error and hint go to standard error instead.

retryable is true for rate limits and network trouble.

Exit codes

Exit code Meaning
0 OK
1 usage, invalid Usage or invalid input
2 not_found Not found
3 auth Not signed in, or the token was refused
4 forbidden Forbidden (role or token permission)
5 rate_limit Rate limited (retryable)
6 network Network trouble or a server error (retryable)
7 api Other server error
8 ambiguous A name matched several courses

Examples

For a script:

# Stop if not signed in (auth status exits 3 when there's no token)
bitty auth status -q || exit 1

# The public link of course 1
url=$(bitty courses link 1 --url-only)

# Course ids and titles, with jq
bitty courses --agent | jq -r '.[] | "\(.id)\t\(.title)"'

# Retry once after a minute on a retryable failure (exit 5 or 6)
bitty stats --range 7d --json > stats.json
status=$?
if [ $status -eq 5 ] || [ $status -eq 6 ]; then
  sleep 60
  bitty stats --range 7d --json > stats.json
fi

For an AI agent, in an agent's instructions:

Use the bitty CLI with --agent for Bitty Course. Start with `bitty commands` and `bitty workspace`.
Exit code 8 means the course name was ambiguous: use the id. Exit 4 means the token or role doesn't allow it.
Only run `bitty courses publish` or create discounts when I ask.

Owner examples:

bitty discounts create 1 --code FRIENDS --percent 20 --limit 50
bitty discounts sale 1 --name "Launch week" --percent 30 --ends 2026-12-01T00:00:00Z
bitty discounts show 1 FRIENDS --json
bitty discounts off 1 FRIENDS

Good to know

  • The token's access level applies: Read only can look, Build drafts can't touch published courses, and discounts need a workspace owner's token. See MCP server.
  • Changes made through bitty appear in the Activity list under Settings → AI assistant, under the token's name.
  • The server's rate limit applies to bitty too. Looking up a course by name or slug takes extra requests; ids are fastest.