Kotoba

Where to start

What Kotoba isWho she is and where she runs, in one page
InstallingOne package, two commands
First runA key, a model, her first words
The approval gateHow she asks before she acts
The two voice modesLocal voice, or the agent tunnel
The soul fileChange who she is
RoadmapWhat grows next, and what was cut on purpose

Or a section

↑↓ move openesc close124 pages
All pages

Security8 of 10

What leaves your machine

About 5 minutes to read

On this page

Kotoba runs locally and talks outward. Nothing reaches in unless you deliberately configure it to (the ElevenLabs agent voice path is the one such case, and it is not the default).

There is no telemetry

There is no analytics, no crash reporting, no usage ping, and no version check. This was verified by searching the whole tree — Python, TypeScript and the frontend — for every common name in that category. The only match is the packaged build explicitly setting NEXT_TELEMETRY_DISABLED=1 to turn off the web framework's own default.

There is no route that returns a saved key, and nothing writes a key to a log.

The services she talks to

Every one of these is a service you configured or a tool you asked her to use.

The model provider — always

The conversation goes to whichever provider is active. Two are built in:

ProviderEndpointKey
openai (default)the OpenAI SDK default endpointOPENAI_API_KEY
xaihttps://api.x.ai/v1XAI_API_KEY

KOTOBA_LLM_BASE_URL can point either at an OpenAI-compatible gateway of your own.

What goes with a turn is what an LLM assistant sends: the conversation, her system prompt and soul file, the facts in her long-term memory that are selected for the prompt, tool definitions, and the results of the tools she ran — which includes the contents of any file she read and the text of any page she fetched. If she reads a file, that file's contents reach the provider.

By default, reasoning state is stateless: encrypted reasoning is re-fed each turn rather than retained by the provider. KOTOBA_LLM_STORE=true changes that, and is only needed for models that reject encrypted reasoning.

ElevenLabs — when voice is on

Required for voice in the web app. Two modes:

  • local (default) — everything is outbound. Your backend sends captured audio to ElevenLabs for transcription and sends text for synthesis. No public URL, no tunnel.
  • agent — you delegate turn-taking to their Conversational-AI platform, which means their cloud calls into your /v1/chat/completions. That needs a publicly reachable URL and a bearer. This is the one inbound path in the product and it is opt-in.

The terminal does not need ElevenLabs.

Web search — when she searches

Web search is the model provider's own server-side tool. The search query goes to the provider, which runs the search; there is no separate search-engine key and no separate service. On the default provider, searching means the query reaches OpenAI.

Page reading — when she opens a page

web_extract fetches the URL directly from your machine first, so the site sees your address. If the direct fetch fails or the site serves a block page, it falls back to a public reader service (r.jina.ai), which means that service sees the URL she opened.

Installing the optional extractor (pip install kotoba-companion[web]) makes the direct path succeed far more often; without it, the fallback is reached routinely. kotoba doctor says so when the extra is missing.

MCP servers — when you install one

Finding a server queries public registries (registry.modelcontextprotocol.io, the npm registry, PyPI). Connecting a remote MCP server sends your requests to whoever runs it. Connecting a stdio server runs a process on your machine.

Whatever you hand a server, that server has. A token you give it is a token it holds.

The Live2D sample model — only if you install it

No model ships with Kotoba; they cannot be redistributed. If you install the default sample, the archive is downloaded from the Live2D sample-data host. Nothing else downloads a model, and KOTOBA_DEFAULT_MODEL_URL can point elsewhere.

The browser — when she uses it

She drives a real Chromium-family browser on a dedicated profile. Pages she opens are ordinary browsing traffic from your machine. If you point KOTOBA_BROWSER_CDP at a browser you are already logged into, she is browsing as you, in your sessions.

What stays

  • Conversations and the audit trail live in a local SQLite database. They are never uploaded anywhere; they reach the model provider only as the prompt for a turn you are having.
  • What she remembers about you is markdown you can open — ~/.kotoba/memory/USER.md and the topic files beside it — not a table.
  • Files she works with stay in ~/.kotoba/files (or KOTOBA_WORKSPACE_DIR). Nothing syncs.
  • Saved keys stay encrypted in that database. No route returns one.
  • Visual keepsakes stay in ~/.kotoba/visual-memory. The screenshots she takes while working are ordinary files, under ~/.kotoba/files/screenshots/.
  • Logs stay in ~/.kotoba/, with the query-string token redacted.

Reading the audit trail yourself

Every tool call that changes something — risk write, exec or network — is recorded locally with what was asked and what happened. Read it through the audit_log_read view rather than the raw table, because the view answers the question you actually have:

bash
sqlite3 ~/.kotoba/kotoba.db \
  "select created_at, action, risk_kind, approved, authority, detail
     from audit_log_read order by created_at desc limit 20"

Two kinds of row exist and the view tells them apart. detail = 'decision' is the approval gate recording an answer. detail = 'executed' (or executed:failed) is the loop recording that a tool ran.

The authority column names who permitted it, in words rather than codes:

authorityMeaning
useryou decided — yes or no
saved-family / saved-exact-commanda standing grant you gave earlier
auto-safe / allowlistit never needed asking
nobody — the card was shown and expired unanswered, deniedyou never saw it in time
nobody — the card never reached the user (channel failed), deniedno screen could draw it
none — the loop ran it, nobody was askeda write or a network call that carries no card

That last one is the honest label on write_file, patch and the tools that reach a service — they are recorded, not gated.

Be clear about the other gap: read-risk tools are not recorded at all. Searching, fetching a page, opening a link and reading a file leave no row. What she read is in the conversation, not in the log.