LinuxToaster · docs

Documentation

One program, toast, and the tools around it. jam, ito and squawk for loops, undo and messaging; twenty-eight commands that put the Mac — Mail, Messages, Calendar, the camera, the screen — on the command line. They all read stdin and write stdout, so they work with everything else on your machine, and with each other. The first half of this page is a tutorial. The second half is the reference.

Get startedTutorialSunday · get acquaintedMonday · one-shotTuesday · collaboratorWednesday · reviewerThursday · approverFriday · audienceSaturday · farmerNext Sunday · a newsletterThe rule, and three questionstoastWhat the first word meansEvery flagSlicesProviders & BYOKLocal inferenceConfig filesChat mode & roomsTools, receipts, budgetsjamitosquawkThe Mac toolsRecipesGit hooksLog monitoringCI/CDcronAccount, credits, side hustleTroubleshootingFAQ

Get started

Create a free account at linuxtoaster.com. You enter an email address and receive a sign-in link; there is no password. The account page has the Mac installer. It puts toast, toastd and appled on your PATH. appled runs Apple's on-device model, so toast works immediately and offline. That model is a demonstration of the tools: its context window is about 4,000 tokens, which is too small for a log, a long file, or a conversation with tool results in it. For our models and the slices, add credits and run pkill appled.

FreePro · $49 onceCredits · from $20
binariestoast, toastd, appled+ jam, ito, squawk, emails, imessage, the tools—
modelsApple's on-device model (4K context), and your own API keystoasted: a local 30B modelour models and the slices, metered
the weekSunday–WednesdayThursday–Saturdayany day

On Linux and WSL, download the tarball for your platform from linuxtoaster.com/releases and put the binaries on your PATH. Keep them in the same directory: toast starts toastd by name.

What the free tier sends home. Once a day, toastd reports your version, the number of calls made, and the number of days active, so the account page can show your progress through the week. It never sends prompts, outputs, or file names. Set report = false in ~/.toast/config to disable it.

Tutorial

The tutorial is organised as a week. Each day adds one level of delegation, from a single question on Monday to an unattended loop on Saturday. What changes from day to day is how much of the output you read yourself. Use whichever day fits the task; the setup is the same for all of them.

Sunday · get acquainted

Start by piping things into toast and having the Mac read the result aloud. say is macOS's speech command. -v Daniel selects a better voice for anything longer than a sentence.

terminal
# nature documentary
$ log stream | head -200 | toast "narrate like a nature documentary" | say -v Daniel
# the front page, read for you
$ fetch https://news.ycombinator.com | toast "anything interesting?" | say
# the machine, as a starship
$ system_profiler SPHardwareDataType | toast "report like a star trek computer" | say
# who is it talking to
$ lsof -i -n -P | toast "who is my computer talking to and is it sketchy" | say
# the network, as a bar
$ arp -an | toast "introduce each device like you are in a bar"

If you record device names in .crumbs (for example - .4 is Toaster, the Mac mini), toast uses them. See config files.

Monday · one-shot

Level 1: one question, one answer. Anything that prints text can be piped in.

terminal
$ journalctl -p err -S today | toast "why did it crash? two lines"
$ emails unread | toast "what needs me before noon? three lines"
$ ito history | toast "what landed over the weekend, and who did it?"
$ cat config.yml | toast "explain this configuration"

Tuesday · collaborator

Level 2: a conversation. Run toast with no arguments. If the directory has a .tools file, toast can run the commands listed in it, and it prints each command on stderr before running it. If it needs a command that is not listed, it says which one and stops; you decide whether to add it.

terminal
$ printf 'ps\ndf\nls\ncat\ngrep\nlsof\narp\nmdfind\n' > .tools
$ toast
> what is going on
[toast] ps aux
[toast] df -h
Load is idle. Disk is 71% and the two big files are both installer images.
> most recently modified file in this folder
[toast] ls -lt | head -3
toastd.c, Apr 14 21:05.
> ssh to linuxtoaster.com and tell me the date
I'd need ssh. It isn't in .tools.
> /exit
$ echo ssh >> .tools

The [toast] lines are the record of what actually ran. If there is no such line, nothing ran. The conversation is saved in .chat and continues when you return.

Wednesday · reviewer

Level 3: one model writes, and others check the result without seeing the original prompt. The names after toast are slices; see slices. The prompt here is 🍞 because these commands are run in jam, which does not expand $ or interpret quotes.

terminal
🍞 toast coder deploy.sh "add a rollback: if the health check fails, put the old build back"
[toast] Updated deploy.sh
[toast] ito log "rollback on failed health check; keeps last build in ./prev"
🍞 ./test deploy.sh
12 passed, 0 failed
🍞 cat deploy.sh | toast paranoid "what breaks in production?"
The health check is a curl with no timeout. When the new build hangs instead of
failing, curl waits forever and the rollback never runs. Add -m 10.
🍞 cat deploy.sh | toast security "anything I'd be embarrassed by?"
Line 41 echoes $DATABASE_URL into the deploy log, password included.
🍞 toast coder deploy.sh "curl -m 10 on the health check; stop logging DATABASE_URL"
🍞 ./test deploy.sh
12 passed, 0 failed

The tests passed both times; the two review passes found problems the tests could not. Because the reviewers are different models and did not see the coder's instructions, their mistakes are unlikely to coincide with its mistakes. You still read the final diff, with the reviewers' notes beside it.

Thursday · approver

Level 4: a loop that runs until the model says it is finished. This is the first day that needs Pro, because it uses ito to save a restore point and jam to run the loop. Instead of reading the diff, you read the history of what each pass changed.

terminal
$ toast ch4.tex "what's slack in this chapter? one paragraph"
The inn scene restates what the ledger already showed. Cut it, or move the reveal there.
🍞 ito log "ch4 before the editor"
🍞 20 while toast editor ch4.tex "cut until nothing is left to cut"
[editor] pass 1 · dropped the inn restatement · −212 words
[editor] pass 2 · merged two dialogue beats · −88 words
[editor] pass 3 · DONE
🍞 ito history

The loop stopped after three passes because the editor printed DONE. If the result is worse, ito undo reverts one pass at a time; each entry carries the editor's own description of the change. 20 while limits the loop to twenty passes regardless.

Friday · audience

Level 5: toast runs on a schedule and sends the result somewhere you will see it. Nobody is at the terminal.

terminal
# the morning letter, 7am
0 7 * * *  { fetch https://news.ycombinator.com; emails unread; weather; } | toast "my morning newsletter: five lines, what needs me first" | imessage
# friday: what did I actually do
0 17 * * 5  ito history | toast "what did I actually do this week?" | imessage
# the watchdog: says something only when there is something to say
*/30 * * * *  df -h / | toast "if usage is over 85% say so, else print nothing" | imessage
# bots: answer the phone, answer the mail
$ imessage bot toast "you are Dirk's assistant; short answers; if unsure say you'll check"
$ email bot toast support "answer from docs.html; anything about billing, forward to sales@ and say so"

Under cron, stdin is empty. toast notices and answers the prompt as a single question. The disk-space line shows the pattern for alerts: the prompt tells the model to print nothing unless there is something to report, so most runs send nothing.

Saturday · farmer

Level 6: a long unattended job from an outline. The model keeps its own working notes in .crumbs. You read the result.

terminal
$ vim outline.tex .persona
$ printf 'toast\nSTRINGAPPEND\nito log\n' > .tools
$ ito init && ito log "outline"
🍞 12 times toast outline.tex "draft the next chapter into its own .tex file; note continuity in .crumbs"
🍞 20 while toast editor book.tex "polish for publishing"
🍞 latexmk -pdf book.tex
🍞 detex ch*.tex | wc -w
84312
🍞 cat .crumbs

The outline and the persona were yours. Every pass was logged by ito, so any of them can be undone.

Next Sunday · a newsletter

A weekly newsletter that uses every level. Each pass reads one source and writes its figures, with source and date, to notes.md. When all sources are read, the issue is written from the notes only. A small script, numcheck, checks that every number in the issue appears in the notes; the model may not finish until it prints nothing. cron runs the whole thing and mails the result.

terminal
$ cat .tools
fetch
search
numcheck
cat
STRINGAPPEND
STRINGREPLACE
ito log
🍞 20 while toast issue-001.md
[toast] fetch https://aventis-advisors.com/ai-valuation-multiples/
[toast] Appended to notes.md
[toast] Appended to issue-001.md
[toast] numcheck issue-001.md
not in notes: $62.3B
[toast] Updated issue-001.md
[toast] ito log "Removed the $62.3B exit total: no source in notes.md"
DONE
$ crontab -l
0 7 * * 5  ~/ai-letter/weekly.sh

A second slice then reads the notes and the issue together and reports claims the notes do not support, which a number check cannot catch. The issue ends with a list of figures the sources disagree on. The full setup, including the cron script, is in the blog.

The rule, and three questions

Each level delegates more and asks you to read less. This table summarizes what toast does at each level and what remains yours to check:

DayLevelWhat toast doesStill yours
Monday1 · one-shotanswersreading the answer
Tuesday2 · collaboratorruns what you allowevery answer, every command
Wednesday3 · reviewerwrites; others checkthe summary and the diff
Thursday4 · approverworks in a loopthe history; the undo
Friday5 · audienceruns on a schedulereading a text
Saturday6 · farmerplants and harveststhe outline; the harvest

Before moving up a level, check three things. Can you read it? Every prompt, tool list and memory file is plain text. Can you limit it? 20 while, a cron window, and the byte budget all cap how much a loop can do. Can you undo it? ito log before a loop and ito undo after. If the answer to any of these is no, stay at the current level.

toast

What the first word means

toast has no subcommands. It works out what you meant from whether stdin is a terminal, whether there are arguments, and what the first argument looks like. The first argument is treated as a slice name unless it is a file or a prompt:

You typedFirst word isBecause
toast— (chat)stdin is a tty, no arguments
toast "hello there"prompthas a space
toast hellopromptalone, nothing on stdin
cat log | toast explainslicea word, with input
toast editor ch4.tex "cut"slice, then filea word, then more
toast ch4.tex "cut"filehas a period
toast README "summarize"fileexists
toast explain READMEslice, then filea word, then a file that exists

toast does not keep a list of slice names. It sends the word to the server, which either answers or replies that no such slice exists. -m overrides this rule. ai is the same program under another name.

Every flag

FlagWhat it does
-p, --provider PPick the provider: toast (hosted), openai, anthropic, ollama, mlx, and the rest. Default is appled or toasted if one is running locally, otherwise toast.
-m, --model MChoose the model by id. For the toast provider this is the slice name; -m beats the first-word rule.
-l, --listList what the provider offers. For toast: every slice, with the model behind it this week and the rate.
--add <name>Make <name> a one-word command (a symlink to toast). Optional: toast editor works without it.
--drop <name>Remove that symlink.
--balanceAccount balance and plan.
--statsToken usage: input, output, requests, latency, per provider.
--accountOpen your account page in a browser, signed in.
--addfundsTop up credits.
--room P,P,…Start a chat room with several personas in it at once.
--color MODEColouring for --room: name (default), full, or off.
--telegramLink Telegram so you can talk to toast via @linuxtoasterbot.
--sidehustleOffer your idle local capacity to the pool and earn credits. --nosidehustle turns it off.
-w, --wait MSIn batch mode, how long stdin may pause before toast sends what it has. Default 500.
-r, --rawPrint the raw JSON from the daemon instead of the message text.
-d, --debugDebug output on stderr: what it decided, the request, the response.
-v, --versionVersion and build time.
-h, --helpThis list, from the binary itself.

Exit status. 0 answered. 1 the model printed DONE. 2 an error. That is what lets while toast … stop when the work is finished, and lets a script tell finished from broken.

Slices

A slice is a named configuration on our servers: a model, the host that serves it, and the settings for a particular job. You select one by putting its name after toast. When a better model appears, we change what the name points to; your commands do not change.

What you wantThe jobThe lab, by nickname
best (also sota), fast, cheap, long, localexplain, coder, reviewer, paranoid, security, editor, translator, supportanth, gpt, gemi, xai, kimi, dpro, dflash, ali, glm, mistral
terminal
# what each name resolves to this week, with the lab and the price
$ toast -l
# a job
$ cat deploy.sh | toast reviewer
# a mind
$ toast kimi "what is in notes.md"
# a specific model, by its real id
$ toast -m k3-256k "what is in notes.md"
# one word, if you like
$ toast --add editor
$ editor ch4.tex "cut"

A lab nickname selects that lab's current best model. Note that a model name only identifies the weights; the provider serving them determines speed, price, data retention, and often quality (a quantized copy of the same model is a different thing). A slice fixes all of these together. local is the one slice resolved on your machine: it means whatever appled or toasted is running.

Slices are separate from .persona, which is your own system prompt for plain toast; only one of the two is used for any call. Slices still read your .tools and .crumbs; only the system prompt comes from the server.

Providers & BYOK

toast can use your own API keys. It reads the key from the provider's usual environment variable and connects to the provider directly; nothing passes through our servers.

terminal
$ export OPENAI_API_KEY=sk-...
$ export ANTHROPIC_API_KEY=...
$ toast -p openai "explain this"
$ toast -p anthropic -m claude-opus-5 "explain this"
# what models does that key give you?
$ toast -p openai -l

The variable name follows the provider: OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, GROQ_API_KEY, CEREBRAS_API_KEY, MISTRAL_API_KEY, XAI_API_KEY, DEEPSEEK_API_KEY, KIMI_API_KEY. Any name works if its variable is set and the daemon knows the host.

Each stage of a pipeline is a separate process with its own -p, so one command can use several providers, for example a local model for the first draft and a hosted one for the review:

terminal
$ cat auth.py | toast "draft a fix" | toast -p openai "what did that miss?"

Local inference

Start either local daemon and toast will use it in preference to the hosted service, without any configuration. -p overrides this.

terminal
# Apple Intelligence, on-device, no API key — the free tier
$ appled
# toasted: MLX on Apple Silicon (Pro)
$ toasted
# from here plain `toast` is local and spends no credits
$ toast "explain this"
# stop preferring local
$ pkill appled
# or point at something else you already run
$ toast -p ollama -l
$ toast -p ollama -m qwen2.5-coder "explain this"

Precedence. When -p is not given, toast uses appled if it is running, otherwise toasted, otherwise linuxtoaster. The cheapest available option is always the default; pkill appled when you want our models, which need credits.

Config files

toast reads four plain-text files. It looks for each in the current directory, then in each parent directory up to /, then in $HOME.

FileWhat it isWho writes it
.personaYour system prompt for plain toast: voice, method, what to keep in mind.you
.crumbsMemory. Read into every call; the model may append to it when STRINGAPPEND is allowed — what it learned that will still be true next week. You prune it.you and the model
.toolsAllowlist of commands the model may run, one per line. STRINGAPPEND and STRINGREPLACE here allow file writes. No file means no tools.you only
.chatChat transcript, written in the current directory; resumed next time.toast
terminal
$ echo "You are terse. If the answer is a command, print the command." > .persona
$ cat >> .crumbs
- Python 3.11, FastAPI, PostgreSQL. Sessions moved to JWT so the mobile client works offline.
- Toaster is the Mac mini at .4. Do not add a build system.
^D
$ printf 'df\njournalctl\nsystemctl\nito log\nSTRINGAPPEND\n' > .tools

The model can never write to .tools or .persona, regardless of what .tools allows. A two-word line such as ito log allows only that subcommand. A comment after a name is the tool's description, and the model sees it:

.tools with descriptions
battery      # charge, charging state, time remaining
kal          # calendar: kal [days]; kal add "…"
rem          # reminders: list, add, done
search       # web search: search "terms"
ls
ito log      # save with a reason

A tool documents itself with -h; a directory documents its tools with these comments. The instructions the model needs for calling tools, writing files, and using .crumbs are generated from .tools on every call, so .persona only needs to describe how the model should behave.

The notebook is opt-in. A directory without a .crumbs file has no notebook, and the model is never told about one. touch .crumbs is how you say "remember things here"; TOAST_NO_CRUMBS=1 switches it off for one job even where it exists.

A directory is a slice. A hosted slice such as toast reviewer is a voice, a tool policy and a memory chosen together with a model. A directory with a .persona, a .tools and a .crumbs is the same thing, made by you: cd into it and toast is that specialist. Rules go in .crumbs; lists the model only needs to look up go in a file it can grep, because the notebook rides along on every call.

Chat mode & rooms

Run toast with no arguments and a terminal on stdin. The transcript is saved in .chat and reloaded next time, with the persona and tools reapplied. Leave with /exit, /quit, or Ctrl+D.

terminal
# several personas in one chat session
$ toast --room coder,paranoid,security
$ toast --room coder,paranoid --color full

Tools, receipts, budgets

toast can run commands, but only those listed in .tools, and only through jam. Every stage of a pipeline is checked against the list: ls | sh is refused because sh is not listed, even though ls is. Every command is printed on stderr before it runs.

terminal
$ printf 'df\njournalctl\n' > .tools
$ toast "is this box running out of disk, and if so what is eating it?"
[toast] df -h
[toast] journalctl --disk-usage
71% used. The journal is 9.3 GB; `journalctl --vacuum-size=1G` gets most of it back.

Models request tools either as structured calls, where the provider supports them, or as a line of text. toast accepts both, and the allowlist applies to both. A command repeated within a turn returns its cached result instead of running again. A command that produces no output returns [ok: exit 0, no output]. A command that fails the allowlist returns the name of the refused word, so the model can ask for it.

EnvironmentMeaningDefault
TOAST_TOOL_ROUNDStool rounds per turn before toast asks for an answer8
TOAST_TOOL_BYTEStool output kept in full per turn; beyond it, older results are compacted256000
TOAST_TOOL_TIMEOUTseconds before a command is killed; 0 never60
TOAST_TOOL_OUTPUT_MAXbytes of one command's output passed to the modelnone

.tools restricts which commands run, not what they do. It is an allowlist, not a sandbox. Keep tool scripts outside the directory the model can write to; otherwise the model could edit them. Tool calls require jam on the PATH.

jam

jam is a shell with no expansion. Quotes group words; nothing inside them is interpreted; $ and \ are ordinary characters. This is why toast runs tools through jam: a model cannot get the quoting wrong, and a command cannot smuggle in a substitution.

Commands jam does not recognise are sent to toastd as a prompt. A typo therefore gets an answer from the model instead of an error, and costs a call.

FormMeaning
while <command>Repeat until the command exits nonzero. No do, no done.
N while <command>Same, capped at N iterations.
N times <command>Run it exactly N times.
send KEY VALUEUDP multicast to every jam on the LAN.
listen [KEY]Receive from the bus. With a KEY, returns after the first match.
set NAME VALUE / get NAMEEnvironment variables.
source FILE / . FILERun a script.
cd, pwd, exit, historyAs expected.
numbers and + - * / mod dup drop swap over . .sA small Forth. ? pushes the last exit status.
terminal
# improve until toast says DONE and exits 1
🍞 while toast server.c "improve until production ready"
# same, but stop after 20 passes whatever happens
🍞 20 while toast server.c "keep improving"
# tell the other machines something
🍞 send status "build green on arm64"
🍞 listen status
# pipes and redirects work
🍞 cat auth.py | toast reviewer > review.md

; and && both just separate commands. jam runs the next command regardless of the previous exit status, so 20 while toast x ; ito log pass never stops. To save after each pass, put ito log in .tools and have the model call it, rather than appending it to the loop.

jam keeps its own history in .history, found by walking up from the current directory, and sends the last 50 lines as context when a line falls through to the model.

ito

ito is version control organised around reasons. Each entry records what changed and why. Nothing is ever deleted.

terminal
$ ito log "hardened parse_header — unbounded copy on malformed input"
logged 9c4f1a2  hardened parse_header — unbounded copy on malformed input
$ ito history
4a91c07  2026-07-21T09:14:22Z  (dirk)
         switched sessions to JWT
9c4f1a2  2026-07-22T16:02:55Z  (dirk)
         hardened parse_header — unbounded copy on malformed input
$ ito search jwt
$ ito undo
undone  9c4f1a2  "hardened parse_header — unbounded copy on malformed input"
✓ your files are back — nothing is ever deleted
$ ito restore 4a91c07

undo goes back one entry. restore <hash> goes to any entry. Set AUTHOR to record who made a change; this is how a slice or a cron job signs its work:

terminal
$ AUTHOR=editor ito log "cut chapter 4"

Before using restore. It restores the whole directory, so any file that did not exist at that point is removed; keep copies you want to compare outside the directory. It does not touch dotfiles, so .crumbs is unchanged; edit it by hand if the model's notes need correcting.

The history is plain text, so it can be piped:

terminal
$ ito history | toast "what did we actually change this week"

squawk

squawk is a message bus reachable three ways: a Unix socket on the local machine, TCP through an SSH tunnel from anywhere, and UDP multicast on the LAN. A message arriving by any route is delivered to all of them.

The client picks its mode from whether stdin and stdout are terminals, so there are no flags for it:

You typedMode
squawkinteractive chat
echo hi | squawksend one message
squawk | grep "dave>"receive
squawk bot <cmd>feed the last 20 messages to <cmd> and post its output back
squawk map <cmd>pipe every message through <cmd>
terminal
# once per machine
$ squawkd &
# put a model in the room; USER sets the nick it posts under
$ USER=paranoid squawk bot toast paranoid
# join from your laptop on the same LAN
$ squawk
# or across the internet, through your existing ssh access
$ squawk linuxtoaster.com
# notify the room from a script
$ echo "deploy finished" | squawk

Remote hosts are reached through ssh -W, so no inbound port is opened and no firewall change is needed. LAN addresses connect over plain TCP.

The Mac tools

Twenty-eight commands, one word each, stdin and stdout, in the style of the tools already on the Mac. Piped, each prints plain lines a script or a model can parse; at a terminal, something easier on the eye. Every one documents itself with -h, and a directory names the ones a model may run, with a comment, in .tools. Sold as macli; the ones that are plain C (emails, email) run on Linux too.

mailMail.app, read from its own index: unread, search, a message as text; archive, flag, move; rules that sort on arrival; send
imessagechats, a thread, unread, everything since you last looked; search inside messages; send. Names from Contacts
emailsIMAP on any account: list, filter, search; move, flag or delete a set in one command; index a Maildir into grep-able lines
emailone message: read, reply from stdin, send stdin to an address, watch for new mail
kalcalendar: today, the next N days, add from a sentence, remove
remreminders: open ones soonest first, add from a sentence, done, remove
concontacts: look someone up, add, birthdays, export
notenotes: recent, read, search, add from stdin
photophotos: recent, by date, favorites, albums; export an original
fetcha web page as text; PDFs too; --links for where it goes next
searchweb search results, with a distinct exit code when the engine is blocking
ocrthe text in an image, a PDF page, or the screen
snapone picture from the camera
hearlisten, and print what was said
locplace name and coordinates
wifithe network, signal, nearby networks; on, off, join
btBluetooth devices and their batteries
batterylevel and state; --lid; --power
lightambient light, lux
noisehow loud the room is
thermalnominal, fair, serious, critical
idleseconds since the last key or mouse; --over N for scripts
volvolume: show, set, mute, toggle
notifya banner from any script
timera countdown that notifies you
stopwatchstart, lap, stop
tuneMusic: now playing, play, pause, next, a playlist by name
tagFinder tags: see, set, find files by them

Where these earn their place: ocr --screen | toast "what's this error?", photo 2026-09-06 | toast "where was I yesterday?", imessage new | toast "anything that needs me?", and a .tools file that lists kal, rem, mail and notify so that a persona in that directory can run your day. The mail ledger in the recipes is built from mail and emails.

Recipes

Git hooks

Do not use toast's exit code to block a commit. It exits 1 when the answer contains DONE and 2 on error, not when a problem is found. Write the review out for a person to read, or block on a marker word you specify in the prompt.

terminal
# .git/hooks/prepare-commit-msg
#!/bin/sh
git diff --cached | toast fast "write a commit message, one line, imperative" > "$1"

# .git/hooks/pre-commit — advisory, never blocks
#!/bin/sh
git diff --cached | toast reviewer | tee /dev/stderr > /dev/null
exit 0

# .git/hooks/pre-commit — blocking, on a marker you control
#!/bin/sh
git diff --cached | toast reviewer "print BLOCK on the last line if anything is serious" | tee /dev/stderr | grep -q BLOCK && exit 1
exit 0

Log monitoring

Batch mode sends a request per pause. When stdin is a pipe, toast sends what it has each time input pauses for -w milliseconds (500 by default). Piping tail -f directly into toast therefore sends many requests. Collect a window of input first, or raise -w.

terminal
# a minute of errors, one question, local model
$ timeout 60 tail -f app.log | grep --line-buffered ERROR | toast -w 60000 "diagnose and suggest fixes"
# or once, from the last hour
$ journalctl -p err -S -1h | toast "what's wrong, in three lines"

CI/CD

terminal
# GitHub Actions
- name: Review the diff
  env:
    TOAST_API_KEY: ${{ secrets.TOAST_API_KEY }}
  run: |
    git diff origin/main | toast reviewer | tee review.md
- name: Generate API docs
  env:
    TOAST_API_KEY: ${{ secrets.TOAST_API_KEY }}
  run: |
    find src -name '*.py' -print0 | xargs -0 cat | toast "generate API docs" > docs/API.md

Use -print0 and xargs -0 so that paths with spaces are handled correctly. TOAST_API_KEY is your account token; set it on machines that are not your own.

cron

terminal
# monday 9am: your standup, written from what you actually did
0 9 * * 1  cd /srv/app && ito history | toast "write my standup, first person, modest" | mail -s standup you@example.com
# a prompt with no input is fine under cron too
0 7 * * *  cd ~/jarvis && toast "morning briefing" | imessage

Under cron, stdin is /dev/null. toast reads nothing and answers the prompt as a single question. Change to the right directory first so that toast finds the intended .persona, .tools and .crumbs.

Account, credits, side hustle

terminal
$ toast --balance
$ toast --stats
$ toast --addfunds
$ toast --account
# sell idle local capacity, earn credits
$ toast --sidehustle
$ toast --nosidehustle
# buy from the pool when your own machine is not enough
$ toast -p peers "explain this"

The account is free, with Apple's on-device model. Pro, the toolkit, is $49 once. Credits, from $20, pay for our models and the slices; usage is metered by token at the provider's rate plus our margin, and unused credits roll over and expire a year after purchase. Pro is the toolkit — toasted with a local 30B model, jam, ito, squawk, messaging — sold as its own package. Local providers and your own keys never send anything to our servers.

--sidehustle runs a command sent by the server. The server replies with an autossh command that opens a reverse tunnel, and toast runs it in the background. Use -d to see the command before it runs.

Set TOAST_API_KEY to use an explicit token instead of the one derived from your machine — this is what you want in CI.

Troubleshooting

Debugging

terminal
$ toast -d "test"          # what it decided, the request, the response — on stderr
$ toast -r "test"          # raw JSON from the daemon
$ toastd -d                # run the daemon in the foreground and watch both sides

FAQ

Is my data private?

With a local provider or your own API key, nothing passes through our servers: toastd connects to the provider directly, and local inference stays on the machine. With hosted slices, the request goes to our server and on to the model provider under our account; you are our customer, not theirs. The free tier's daily report contains counts only, never content.

Can I work offline?

Yes, with appled, toasted, Ollama or MLX. No network needed once the model is on disk.

How does billing work?

The account is free. Pro, the toolkit, is $49 once. Credits start at $20 and are metered by the token; toast -l shows the rate beside each slice and toast --balance shows what is left.

Why does toast exit 1 on success?

It exits 1 when the answer contains DONE and 2 on an error. This lets while toast … stop when the model says the work is finished, and lets a script distinguish a finished loop from a failed one.

Can I use my own models?

Yes: through Ollama or MLX for anything local, or your own API key for anything with an API.

Is there an API?

Yes — the same daemon protocol toast speaks, over a socket, from Python or anything else. Ask us.

What is the difference between a slice and .persona?

A slice is a hosted configuration selected by the first word after toast. .persona is a local file containing your own system prompt, used by plain toast. Only one of the two applies to any call.

Keep me in the loop

Product updates, new features, the occasional blog post. No spam.

Unsubscribe anytime.

Launchpadly Startup Directory Featured on tools.cafe