Generate
Read text from an argument or stdin. Choose voice, speed, language, model variant, output path, and WAV, MP3, Opus, or M4A.
A self-contained, offline-first text-to-speech product for people and agents. Generate a recording, validate its metadata, optionally play it, and return a concrete file—not a promise.
-Read text from an argument or stdin. Choose voice, speed, language, model variant, output path, and WAV, MP3, Opus, or M4A.
Optionally play completed audio through afplay or ffplay. Success is reported only after the player exits successfully. Windows playback is experimental because CI cannot prove audible output.
Emit a proof-carrying JSON receipt with an absolute path, audio metadata, backend, and playback state. A localhost OpenAI-shaped HTTP endpoint supports long-lived agent workflows.
List installed voices. Model artifacts are downloaded under a cross-platform OS process lock, written atomically, and checked against pinned sizes and SHA-256 hashes.
kokoro doctor is the product-health contract for runtime, model, codecs, playback, writable output, and optional service state.
Public CLI and HTTP contracts are deliberately small so other products can create speech without importing Kokoro internals.
# Install the stable release globally from PyPI
-uv tool install kokoro-cli
-
-# Prepare and inspect
-kokoro setup
-kokoro doctor
-kokoro voices
-
-# Generate locally or through a healthy optional service
-kokoro speak "The build is ready." --format mp3 --json
-printf '%s' "$VISIBLE_TEXT" | kokoro speak --play --json
-kokoro speak "Strict local run." --service off --json
-kokoro speak "Strict service run." --service required --json
-
-# Long-lived localhost service
-kokoro serve
-curl http://127.0.0.1:8765/health
- The installed kokoro command works from any directory. Contributors can use ./kokoro inside a macOS/Linux checkout or uv run --frozen kokoro on Windows.
Provides only visible, user-facing text to the CLI or HTTP contract.
CLI checks the optional localhost service, with explicit required/off modes and embedded fallback.
Serialized Kokoro ONNX inference, atomic encoding, file/HTTP delivery, optional playback.
| Surface | Contract | Guarantee |
|---|---|---|
| CLI result | Final stdout line is JSON with absolute path, format, voice, speed, timings, backend, and played. | Non-zero exit on generation, validation, required-service, or playback failure. Auto fallback is explicit in JSON. |
| Health | GET /health | Reports service identity, version, active model variant, and readiness. |
| Speech | POST /v1/audio/speech | Accepts input, voice, speed, response_format, plus local lang and play. |
| Voices | GET /voices | Returns voices exposed by the loaded model bundle. |
35 tests cover atomic audio and service output, persistent defaults, model selection and concurrent downloads, Windows data paths and playback messaging, payload validation, localhost binding, live health and speech requests, service fallback, required-service failure, and honest playback receipts. CI runs Ruff and pytest on macOS and Linux, plus Windows on every supported Python version.
The Windows release gate builds and installs the wheel into clean Python 3.11, 3.12, and 3.13 environments; downloads and verifies the real int8 assets; synthesizes and decodes 24 kHz mono WAV audio with embedded inference; and repeats synthesis through a live required localhost service. Playback is deliberately excluded from that claim.
No remote binding, authentication layer, cloud TTS, speech-to-text, hidden reasoning narration, or HTML Drop implementation. This repository only exposes contracts another product can compose with.
Streaming synthesis, sentence chunking for very long narration, richer install/uninstall helpers, audible Windows playback verification, and measured model-quality or latency comparisons.
JSON recordings now include browser-friendly localhost links. They open as + rendered audio controls even when a local file link would open as code in an IDE.
+ +browser_url opens the branded player document with the
+ recording name, audio controls, and response text; audio_url
+ serves the recording directly.--output remains the exact requested destination. When it is
+ outside the managed recordings directory, a private copy is made for HTTP
+ delivery; no symlink is created.127.0.0.1, prefers port
+ 8779, falls back to a free port when needed, and serves only
+ the managed recordings directory.agent-voice viewer start --json
+agent-voice viewer stop --json
+
+agent-voice speak "Viewer smoke test." \
+ --label viewer-smoke --service off
+ The receipt contains the generated path, plus:
delivery.browser_url
+delivery.audio_url
+delivery.recording_path
+ Routes normally use port 8779; use the reported port after a
+ collision:
http://127.0.0.1:<port>/player/<recording>.html
+http://127.0.0.1:<port>/recordings/<recording.ext>
+
+ browser_url from both an IDE terminal and a normal terminal.
+ Both should show the branded document, audio controls, and response text.audio_url. It should play or download the real audio file.--format wav.--output /tmp/my-recording.mp3. Confirm that exact file
+ exists and the HTTP copy in delivery.recording_path also works.viewer stop; old links should stop. The next JSON recording
+ should restart the viewer on port 8779 unless it is occupied.recording-delivery.md template using the receipt's
+ top-level path and file_uri, omitting the
+ unavailable viewer links.Deliberate limit: links remain stable while
+ port 8779 is available. A collision forces a temporary free
+ port. Range requests and seeking optimizations are not added until needed.
$RESPONSE_TEXT+