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.
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:
- Download it from your Bitty Course app address at
/cli/bitty, for examplecurl -fsSLo bitty <your Bitty Course app address>/cli/bitty. The Docs link in the studio sidebar is on the same address. - Make it executable:
chmod +x bitty. - Put it on your
PATH, for example with a link:ln -s "$PWD/bitty" /usr/local/bin/bitty. - Check it runs:
bitty --versionprintsbitty 0.1.0.
Sign in
You sign in with a personal access token. See Create a token.
To sign in:
- Create a token in Settings → AI assistant. Choose the access level you want the CLI to have.
- Run
bitty auth login --url <your Bitty Course app address>. Use the address only, without/mcp;bittyadds that itself. - 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. --limitis 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
bittyappear in the Activity list under Settings → AI assistant, under the token's name. - The server's rate limit applies to
bittytoo. Looking up a course by name or slug takes extra requests; ids are fastest.