-
Notifications
You must be signed in to change notification settings - Fork 18
First Steps for a New Kai User
This page is for someone who has just been added to a Kai instance and wants to get up and running. The admin has handed off; this walks you through what to do next. It assumes /help in Telegram already returns a response. If it doesn't, ask the admin to re-check Adding a User on macOS (or the cross-platform Multi-User Setup) before touching anything here.
This is a checklist, not a tutorial. Each phase takes a few minutes, and you can stop after any of them and come back later. The order reflects what most people find useful first, not what is strictly required.
The most important thing to understand up front is that you are not logging into a server. Kai lives on a host somewhere (the admin's machine, a Mac mini, a VPS) and you reach it through Telegram or the Workshop browser client; this page walks the Telegram path, and Workshop Collaboration Basics covers the browser one (your admin may have provisioned you for either or both; the two surfaces share the same conversations and settings). Every filesystem action, git operation, HTTP call, or scheduled job is executed by an agent subprocess (whichever backend the admin configured) running on the host under some OS user ID. You tell Kai what you want in chat; it does it. You never get a shell.
This matters for two recurring questions that come up once you try to do real work:
-
What UID is Kai running as when it acts for me? Either the shared service user (usually
kai) or a dedicatedos_userthe admin set up for process isolation. Anything Kai does is subject to that UID's filesystem permissions. - What credentials does that UID have? Fresh OS accounts have no GitHub auth, no SSH keys, nothing. If you want Kai to clone a private repo or push to one, the admin has to set those credentials up once for the UID you run as.
Those two questions explain every "why did Kai say it couldn't do that?" you will hit. Keep them in mind and the rest of this page makes sense.
Send /help in Telegram. You should see a list of slash commands. That confirms you are authorized, the bot is reachable, and the model is responding. If /help returns nothing, you are not actually authorized yet; go back to the admin.
Then ask Kai something trivial, e.g. "What time is it?" or "Say hello." A reply within a few seconds confirms the full round-trip: subprocess startup, model call, streaming back to Telegram. If the reply hangs for more than 30 seconds on your first message, that is usually a one-time cold-start cost; try a second message before worrying. If it still hangs, again, admin.
Finally, send /workspace with no arguments. Kai prints which directory it is currently operating in. That is your home_workspace (set by the admin in users.yaml), and it is where Kai will start every new session unless you switch.
If your home_workspace points at something like /opt/kai/home/, you are looking at a directory that ships with the Kai repo itself. By default every user on the install shares it. That is intentional, but it means anything already in there was put there by whoever set up this Kai instance, not auto-provisioned for you.
Three layers overlap inside home/, and it helps to keep them straight:
-
Kai convention. The
home/directory exists on every install and is the default workspace root.home/.claude/ships with the Kai repo and contains Kai-wide rules and skills that apply to every session rooted there. This layer is identical for all users. -
Developer convention. If the host you are on is also where someone develops Kai itself, you may see directories like
home/specs/(gitignored spec drafts) orhome/docs/(gitignored operator notes). These are conventions documented in the Kai repo's project-levelCLAUDE.mdfor people working on Kai's source. They are not part of what new users inherit; they belong to the developer, not to you. -
Personal practice. Anything else you or another user drops into
home/over time - notes, scratch files, a directory for a particular project. This layer is just whoever put it there.
The practical implication: if you want your own organized space, ask the admin to give you a dedicated home_workspace (for example /Users/you/kai-home/) rather than sharing the install's default. It also sidesteps the risk of your files mingling with another user's under the same directory.
How Kai remembers facts about you depends on the install. With semantic memory enabled (the usual production shape), telling Kai "remember this" writes a fact into the memory store, and relevant facts surface automatically in later conversations; browse them with /memory or the Workshop Memory Explorer. With semantic memory disabled, Kai instead keeps a personal file at DATA_DIR/memory/<your_principal_id>/MEMORY.md, injected at session start and writable at your instruction. Either way, your standing rules belong in /preferences (see Phase 3), which is always injected.
Seeding it is a conversational step, not a config form. Just tell Kai what you want it to remember. Useful things to establish on day one:
- Your name and how you would like Kai to address you
- Your timezone and rough location (affects scheduling, "today", weather queries, holiday awareness)
- Unit preferences (Celsius vs Fahrenheit, metric vs imperial)
- Preferred answer length and tone ("short unless I ask for depth", "direct, not apologetic")
- Standing rules ("never open a PR without asking first", "always run tests before saying a fix works")
You can also run /memory any time to browse, search, or delete what Kai has stored about you. That command is worth knowing now so you can audit your own memory as it grows.
Three commands cover most of what you will tune for yourself:
-
/modelslists the models available on your configured provider./model <name>switches to one; the choice persists to Kai's database and survives restarts. -
/settingsprints your resolved configuration (model, provider, timeout) with a source label on each line:user override,users.yaml, orglobal default. That last detail is the point; it tells you which tier is actually controlling each value right now. -
/statsshows the current session ID, model, started/last-used times, and whether the subprocess is alive.
Kai resolves each of these settings through a three-tier precedence: your personal override (DB, writable from chat) beats the admin's users.yaml entry for you, which beats the install-wide global default. You can change any of them at the top tier from Telegram:
-
/settings model <name>- switch your default model -
/settings timeout <n>- per-response timeout in seconds; the ceiling comes from your runtime profile -
/backendand/backends- switch among the backends the admin granted you -
/preferences set <text>- your standing guidance, injected every session (revisioned, restorable) -
/notifications- delivery controls: destinations, levels, quiet hours -
/project- which memory project the current workspace belongs to
Clear one override with /settings reset <field>; clear all of them with bare /settings reset. Both restart your session so the new values take effect immediately.
You only need the admin to (a) raise the ceiling on your runtime profile if your timeout setting bumped into it, or (b) seed a users.yaml default that outlives your personal overrides if you ever clear them.
This is the phase with the most moving parts. Work through it in order; skipping ahead usually produces the "why won't it clone" situation.
Every repo lives in a directory on the host. You cannot get to that directory directly, but Kai can, and Kai needs it to be writable by whatever UID Kai is running as for you. Two common patterns:
- Your
home_workspaceis a dedicated directory and you clone the repo as a subdirectory of it. - Your admin set
workspace_baseto something like/Users/you/Projects, and each repo lives as a subdirectory under that base.
If you are not sure which, ask Kai: "Where is my home workspace, and what workspace_base am I using?" It can read /settings and tell you.
In Telegram, something like:
"Clone https://github.com/bobsmith/their-repo into my workspace."
Kai runs git clone as its own UID. For a public repo over HTTPS this works with no setup. For a private repo, the UID needs GitHub credentials (see 4c).
If Kai reports a permission error on the target directory, that is a sign your workspace is not owned by the UID Kai is running as. Ask the admin to re-run sudo python -m kai install apply; it chowns per-user directories to the right user as part of the apply cycle.
For public repos, skip this. For private repos, the UID running your subprocess needs a GitHub credential. The admin handles this once, as that UID, one of two ways:
-
gh auth loginrun as the UID, which stores a token in that user's config and makesgh,git clone, and PR operations work transparently. - An SSH key in that UID's
~/.ssh/with the public half added to GitHub (deploy key per repo, or account-wide for the user).
Fresh os_user accounts have neither by default. If Kai tells you "authentication failed" when cloning a private repo, this is the reason. Hand the error back to the admin; this is not something you can fix from Telegram.
By default, Kai sends GitHub webhook events (pushes, PRs, issues) to admins. To have them come to you instead, add the repo to your subscription list. Easiest way, from Telegram:
/github add bobsmith/their-repo
Confirm with /github (no arguments) - it prints your current GitHub settings, including the repo list. Remove later with /github remove bobsmith/their-repo. These settings persist in Kai's database and survive restarts.
The full /github surface has a few more subcommands worth knowing: /github notify, /github reviews, /github triage, /github add, /github remove, /github token. See GitHub Notification Routing for what each one does.
The admin can also set github_repos in your users.yaml entry for a baseline that survives database resets. Most people just use the slash commands.
Adding the repo to your routing does nothing until GitHub is actually sending events to Kai. The admin usually does this once per repo; make sure it is done.
On the GitHub repo page:
- Settings → Webhooks → Add webhook
- Payload URL:
https://<your-kai-host>/webhook/github(the admin knows the exact host) - Content type:
application/json - Secret: the value of
WEBHOOK_SECRETfrom the host's/etc/kai/env(the admin has this; it is the same secret for every repo pointed at the same Kai install) - Which events: "Let me select individual events" and tick at least Pushes, Pull requests, Pull request reviews, Pull request review comments, Issues, Issue comments. Add Releases and Deployments if you care about them.
- Save.
Verify by pushing a trivial commit to the repo. Kai should message you within a few seconds with a summary of the push. If it doesn't, GitHub's webhook delivery log (Settings → Webhooks → your hook → Recent Deliveries) will show whether the request was even sent and what Kai returned.
See Exposing Kai to the Internet for how the host is reachable from GitHub's side, and GitHub Notification Routing for the full picture of actor-based routing.
Kai has two autonomous agents that act on repo events:
-
PR Review agent posts a code review on PRs that trigger it. Enable by asking the admin to set
pr_review: truein yourusers.yamlentry (there is no install-wide default), then toggle it yourself with/github reviewsor in Workshop Settings. See PR Review Agent. -
Issue Triage agent reads incoming issues, applies labels, and posts a summary. Enable with
issue_triage: trueinusers.yaml. See Issue Triage Agent.
Both are off-by-default per user. Both can be noisy on a busy repo; turn them on for a repo or two and see how it feels before flipping everything on.
Once your first repo is wired up, the automation surface is where Kai starts to pay for itself.
Scheduled jobs. You don't create jobs with a slash command; you ask Kai to create them in conversation, and Kai calls the scheduling API on your behalf. Start with something small, e.g. "Every Monday at 9am, summarize any PRs that landed in bobsmith/their-repo over the weekend." Once created, you manage jobs with slash commands:
-
/jobs(or bare/job) - list all your active jobs -
/job info <id>- show the full prompt and schedule for one job -
/job cancel <id>- delete a job
Files. Send any file as a Telegram attachment. Kai saves it to /var/lib/kai/files/<your_principal_id>/ and the file's path is attached to your message, so you can reference it in the same turn: "Look at the screenshot I just sent and tell me what is wrong."
Voice. There are two independent voice features, controlled by two different env vars:
-
Voice input (you send a voice message, Kai transcribes it with
whisper.cppand responds to the transcription). Enabled by the admin withVOICE_ENABLED=true. No slash command; just hold-to-record in Telegram. -
Voice output / TTS (Kai speaks replies aloud instead of or in addition to typing them). Enabled by the admin with
TTS_ENABLED=true. Controlled per-user from/voice(toggle mode) and/voices(pick a voice via inline keyboard).
Either feature can be on without the other. Check /settings to see what your current install has enabled.
See Scheduling and Conditional Jobs for the full job surface and Voice Setup for the voice side.
These are the commands you will reach for when something is going sideways:
-
/stopcancels a running response. Learn this before you need it. Long tool calls can run for a while;/stopis how you take your turn back. -
/newstarts a fresh session, discarding the current conversation's in-memory context. Useful when you feel Kai has "lost the thread" and a clean slate is cheaper than explaining. -
/statsshows current spend and session state. -
/settingsreminds you what the resolved configuration is. Nine times out of ten "why is Kai behaving strangely?" is explained by something in/settingsyou forgot was set.
The admin may have skills installed, which are markdown-based bundles of instructions that extend what the agent can do. Skills belong to the agent, not to Telegram: there is no /<skill-name> chat command (unknown slash commands just return "Unknown command"). You use a skill by asking for the task in plain language; the agent discovers and applies whatever skills its workspace carries. If playwright-cli is installed, "open this page headless and screenshot it" is how you drive it.
Skills are an optional layer; you do not need them to do real work. If you are curious what is installed, ask Kai: "What skills are available in this workspace?" See Browser Automation for the canonical skill example.
Things only the admin can do, bundled so you can send one message rather than pinging them six times:
- Confirm my
home_workspaceand that it is owned by my UID - Confirm my
os_user(or confirm I run as the shared service user) - Set up GitHub auth for my UID (
gh auth loginas that user, or an SSH key with access to the repos I care about) - Add the GitHub webhook on each repo I want Kai to hear from
- Enable
pr_reviewand/orissue_triageon me if I want the agents - Seed a
users.yamlbaseline formodelortimeoutif you want a default that outlives your own/settingsoverrides (otherwise, these are self-serve via/settings) - Raise the runtime-profile timeout ceiling if your self-serve setting bumped into it
None of these require the admin to give you shell access; they just require them to edit users.yaml, re-run install apply, and restart the service. A single pass usually covers it.
/help returns nothing.
You are not authorized yet. The admin has not restarted after adding you, or your telegram_id is mistyped. Back to the admin.
Kai says "permission denied" when cloning.
The workspace directory is not owned by the UID Kai is running as for you. Admin runs sudo python -m kai install apply to chown per-user directories.
Kai says "authentication failed" on a private repo.
GitHub credentials are not set up for your UID. Admin runs gh auth login as that UID, or installs an SSH key.
Pushes to my repo do not trigger a Telegram message.
Either the webhook on GitHub is not configured, or the repo is not in your /github list, or the event type you pushed is not subscribed. Check GitHub's Recent Deliveries first; if the delivery shows a 2xx response, the problem is on Kai's side (likely routing); if it shows 4xx, the problem is on GitHub's side (likely secret mismatch).
Everything is slow.
Cold-start on first message is real. If every message is slow, check /stats for model and timeout. Ask Kai if any tool calls are hanging; /stop and retry.
- Adding a User on macOS - the admin-side walkthrough this page hands off from
-
Multi-User Setup - cross-platform reference for the full
users.yamlschema - Slash Commands - full list of commands available in Telegram
-
Workspaces - workspace switching,
workspace_base, per-user configuration - GitHub Notification Routing - actor routing, per-user chat routing, agent scope
- PR Review Agent - enabling, scoping, re-triggering reviews
- Issue Triage Agent - enabling, label schemes, scope
-
Scheduling and Conditional Jobs -
/jobsurface and conditional triggers -
Voice Setup - voice messages via
whisper.cpp - Exposing Kai to the Internet - how the host is reachable from GitHub webhooks
- TOTP Authentication - optional second factor before a session unlocks
- Troubleshooting - general troubleshooting beyond first-user setup