Python SDK.
Connect Python to a running local Code server, iterate one turn or follow a session, answer specific permissions, and cancel work with the correct lifecycle.
KaitoiCodeClient is a synchronous client for an already running local Code
server. It does not start that server or act as a hosted model SDK. The import
comes from the Python package kaitoi-code; installing a bundled CLI executable
alone does not make it importable in every Python environment. This guide
describes the 0.9.0 package API.
Connect and send a turn
Start kaitoi code serve in another terminal. Then, in your project:
from kaitoi_code.sdk import KaitoiCodeClient
with KaitoiCodeClient.from_running_server() as client:
with client.create_session(".", trust="read", mode="plan") as session:
for event in session.send("Explain this project"):
print(event.kind)
This example submits a real model request when executed. The SDK resolves the
relative workspace path. create_session defaults to trust="none"; choose
read or edits explicitly for the intended access. Other options include
provider, model, mode, resume, and command availability.
from_running_server() selects the newest compatible running discovery record;
pass pid=... to select a specific server. When serve uses --token-file, it
does not write a discovery record: construct KaitoiCodeClient(base_url, token)
with your protected local values. The client accepts loopback URLs and disables
environment proxies and redirects.
Distinguish watching from stopping
The client owns HTTP connections; a served session owns ongoing work; a Turn iterator follows one submitted turn until turn.end. Closing or leaving that iterator stops following events only. Session.cancel requests cancellation. Session.close stops and closes the served session while preserving its log. Client.close releases the client's connections.
The four controls act on different tracks: turn.close and client.close disconnect observation; session.cancel requests the running work to stop; session.close stops and closes the served session. Retained log evidence remains separate from open connections.
session.send(...) starts work immediately and returns a Turn. Iteration and
turn.wait() drain through its turn.end. Events expose kind, data,
sequence, and id. By contrast, session.events(after=...) follows the
session-wide stream and can span multiple turns.
Breaking iteration or calling turn.close() does not cancel work. Call
session.cancel() to request cancellation, then inspect progress before sending
another turn. session.close() stops and closes the served session; its saved
log remains. client.close() only releases HTTP connections. Context managers
apply those respective close operations on exit.
Answer concrete permission requests
send can take an on_permission callback. It receives a PendingPermission
with id, action, operation, summary, details, and decisions. Present
that request to the responsible operator and return one of its advertised
decisions. Returning None leaves it pending for an explicit answer.
With no callback, requests can remain pending until answered or timed out. Do not implement a callback that blindly approves every action, and do not assume every request supports session-wide approval. The HTTP guide explains trust, decisions, timeouts, and the one-turn-at-a-time constraint.
For Python execution of local recipes, use the distinct Runtime API in
kaitoi_runtime. It has a different purpose and lifecycle from Code sessions.
Last reviewed against Kaitoi on 24 October 2026. View this page as Markdown