Start5 of 7
kotoba doctor
kotoba doctor is the command to run when something will not start. It checks this machine in the
order that decides whether she can run at all, and a check that cannot be answered because an earlier
one failed says which one to fix first rather than guessing.
It never prints a secret, and it never only says "not found" — every missing piece is reported with what its absence costs you.
kotoba doctor
Exit code 0 means she can run. Exit code 1 means something must be fixed first. --plain drops the
colour and --ascii folds the em dashes. The other two render flags are refused by name and exit 2:
$ kotoba doctor --calm
kotoba: --calm does nothing on `kotoba doctor`. Nothing on that report moves, and it has no face to leave out.
Here is a real report from a machine with no keys configured. Versions, paths and the platform string are that machine's; the long detail lines are trimmed here to fit the page:
kotoba doctor
what she needs
ok platform Linux 7.0.11 (x86_64), Python 3.14.5
ok terminal her interactive terminal can run here
ok python 3.14.5
ok soul /.../soul/default.md
ok database /.../kotoba.db — schema v4, created just now
ok encryption cryptography 50.0.1 — saved keys are encrypted at rest
ok permissions 0600 on the master key, the database and every atomic write
ok saved keys none stored yet
fail llm key no OpenAI key — run `kotoba setup`, or set $OPENAI_API_KEY in api/.env
ok reasoning low on a companion turn, medium in work mode — she narrates her own tool use in your language
warn voice key no ElevenLabs key, so no voice — set $ELEVENLABS_API_KEY or run `kotoba setup`. Text still works.
skip voice tags not asked — no voice to perform them
ok sandbox local — her commands run on this machine; a plain read inside her workdir runs unasked
ok web ui dev server — `kotoba serve` runs it with npm
optional extras
ok server installed
ok voice installed
ok mcp installed
ok web installed
ok cli installed
on this machine
ok node v26.2.0 — npx-launched MCP servers can run
ok browser /usr/bin/brave — report PDFs and browser automation
ok ripgrep ripgrep 15.1.0 — regex file search
mcp servers
ok servers none configured — she runs on her built-in tools
1 problem to fix before she runs.
That run was in a clone, which is why the key rows name api/.env as the file to edit. On a
pip install there is no such file and those rows say "the environment" instead — sending somebody to
a file they cannot find is a bug the report deliberately avoids.
What she needs
These are in the order they are asked, and the order matters: everything above the key check can stop her from running, so a failure there makes reading a key pointless.
platform — which machine this is. Never a failure. It is said first because it decides what the lines under it mean.
terminal — whether her interactive terminal can run here. It is built on the POSIX terminal layer
(termios, tty), which Windows does not ship. A warn there, not a fail: setup, doctor,
serve, discord and --once all still work, and bare kotoba starts the backend and the web UI
instead.
python — fail below 3.11. There is no fix but a newer Python.
soul — the path of the personality file she will load. fail means she has no personality to
load and nothing starts. Set SOUL_PATH, or reinstall.
database — opening it is the check: connecting runs the migrations, so a stale or broken schema fails here and nowhere else. The row names the exact file it will use, which is worth reading if you suspect you are looking at the wrong database. It also tells you when the file sits beside the package rather than in your home, where an upgrade would leave it behind.
encryption — fail means cryptography is missing, so no API key can be saved or read. It is a
required dependency, so this means the install itself is broken: reinstall with --force-reinstall.
permissions — whether the master key and the database are really kept to this account. Asked by doing it, not by reading the platform. Never fails the run: she works either way, and a filesystem with no ACLs would otherwise say so for ever.
saved keys — every secret the master key can still read. A fail here means the master key
changed or was lost, and it lists what is affected: the model key, the ElevenLabs key, the other
provider's key, MCP credentials. Each has to be entered again; none can be recovered.
llm key — the one row that usually decides the exit code. It runs the real startup, because a key
saved from the Settings panel or from first run lives encrypted in the database and only reaches the
client along that path — a doctor that read the environment would tell a configured user she has no
key. Fixes: kotoba setup, or set the provider's environment variable.
It also catches a pair nobody expects: a good key pointed at a model that provider does not serve.
provider and model are two settings and only one moves when a first run is abandoned between them,
so this is reachable by pressing Enter — and it used to report ok … Ready. while every turn came
back empty.
reasoning — one setting decides four unrelated things: how hard she thinks, who narrates her tool
use and in what language, whether the provider keeps her reasoning, and which system prompt she is
sent. The values are read off the wire rather than re-derived. A warn means the effort you asked for
is not one this provider takes, so it is being folded to a neighbour silently — set it to the value
named to say that is what you meant.
voice key — warn, never fail. Text is a complete way to use her. It says where the key came
from when there is one — saved in the app, or the environment variable.
voice tags — whether the [warmly]-style audio tags actually get performed. A warn here means
expressive is on while the fast engine strips every tag before synthesis: her face keeps emoting,
her words stay warm, and her voice is flat. Set tts_engine to expressive to hear them, or turn
expressive off to say the flat voice is meant.
sandbox — which execution backend is selected and what that means for you. On the default local
it says the commands run on this machine and that a plain read inside her workdir runs unasked. On
docker a fail means no daemon answers, so shell and execute_code are dead. On none it warns
that neither is offered at all.
web ui — whether there is a face to open, and from where. It is asked in the same order serve
decides, so the two can never disagree: the development server wins wherever it can run, otherwise the
packaged build. fail means the install carries no web UI or KOTOBA_FRONTEND_DIR points somewhere
with no app.html.
Optional extras
One row per extra, each naming what you lose and the exact command that adds it. A warn here never
fails the run.
On this machine
Three system tools, none required:
- node —
npx-launched MCP servers cannot start without it. Remote HTTP servers still can. - browser — a Chromium-family browser, for report PDFs and browser automation.
- ripgrep — without it,
search_filessilently drops to a literal, non-regex scan.
MCP servers
Connecting each saved server is the check, so a stdio server that dies on startup fails here and nowhere else. Never a hard failure — she runs without any of them. The last row names the log file holding what each of them printed while starting.
The verdict line
N problems to fix before she runs.— exit 1.Ready. N optional pieces missing; nothing above needs them.— exit 0.Ready. Everything she can use is here.— exit 0.
Next: Installing from a clone or Troubleshooting the first hour.
