Agent Speak is a local Windows, macOS, and Linux Model Context Protocol (MCP) server that lets an agent speak and play audio. You decide which voices, sounds, files, and output devices are available.
MCP host → Agent Speak → optional UtterPipe provider → TTS engine or service
Agent Speak is pre-release software.
- Requirements
- Install
- Quick start
- Configuration
- Playback and safety
- Troubleshooting
- More documentation
- Windows with speech services, macOS 15 or later, or Linux with ALSA-compatible audio
- On Linux, an independently installed UtterPipe TTS provider;
utterpipe-espeak-ngis the quick-profile default - An audio output device and an MCP host that can run a local stdio server
- A prebuilt release, or Rust 1.89+ to build from source
The installers download the latest release, verify its checksum, and install it for the current user. The same one-line command handles initial installation, reinstallation, and updates: run it again to replace the executable with the current latest release. Profiles and provider assets are left untouched. Stop running Agent Speak instances first, especially on Windows where an active executable may be locked.
irm https://raw.githubusercontent.com/4piu/agent-speak/master/install.ps1 | iexThe default destination is
%LOCALAPPDATA%\Programs\UtterPipe\bin\agent-speak.exe; the installer adds that
directory to the user PATH. Open a new terminal, then verify it:
(Get-Command agent-speak).SourceThis removes the executable while preserving profiles and provider assets:
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/4piu/agent-speak/master/install.ps1))) -Uninstallcurl -fsSL https://raw.githubusercontent.com/4piu/agent-speak/master/install.sh | sh && command -v agent-speakThe default destination is ${XDG_BIN_HOME:-$HOME/.local/bin}/agent-speak. Add
that directory to PATH if the installer asks you to. Releases are not yet
signed or notarized; after verifying the download, macOS may require explicit
approval in System Settings > Privacy & Security.
This removes the executable while preserving profiles and provider assets:
curl -fsSL https://raw.githubusercontent.com/4piu/agent-speak/master/install.sh | sh -s -- --uninstallcurl -fsSL https://raw.githubusercontent.com/4piu/agent-speak/master/install.sh | sh && command -v agent-speakThe default destination is ${XDG_BIN_HOME:-$HOME/.local/bin}/agent-speak.
Agent Speak uses ALSA for playback. On Arch/Manjaro and Debian-based systems
(including Ubuntu), the installer verifies the ALSA runtime and, when PipeWire
is active, pipewire-alsa. If anything is missing, an interactive install
offers to run the appropriate pacman or apt-get command; it never changes
packages without confirmation. A non-interactive run prints the command
instead. Other distributions receive a warning when active PipeWire lacks a
detectable ALSA bridge.
Package managers and intentionally custom audio setups can bypass the check:
curl -fsSL https://raw.githubusercontent.com/4piu/agent-speak/master/install.sh | sh -s -- --skip-audio-checkText to speech also needs a provider. The self-contained
utterpipe-espeak-ng executable needs no system eSpeak installation; put it
beside agent-speak or on PATH.
curl -fsSL https://raw.githubusercontent.com/4piu/agent-speak/master/install.sh | sh -s -- --uninstallPrebuilt archives and matching .sha256 files are available from
GitHub Releases. To build from
source, clone the repository and run cargo build --release --locked; Linux
also needs its distribution's ALSA development package.
With no discovered config file, Agent Speak uses a safe quick profile:
arbitrary speech is enabled, while audio files, audio cues, and history are
disabled. Windows and macOS use their public system TTS APIs; Linux discovers
utterpipe-espeak-ng beside Agent Speak or on PATH.
| Command | Purpose | Example |
|---|---|---|
devices |
List active output devices and stable IDs | agent-speak devices |
voices |
List native Windows/macOS voices | agent-speak voices |
serve |
Run MCP with discovered layers or the quick fallback | agent-speak serve |
Quick-profile settings are command-line options, not TOML fields. Supplying any of these options explicitly selects the quick profile and bypasses config-file discovery:
| Goal | Example |
|---|---|
| Choose a voice | agent-speak serve --voice-id <ID> |
| Change the gain policy | agent-speak serve --maximum-gain 0.9 --default-gain 0.5 |
| Change the text limit and diagnostics | agent-speak serve --maximum-text-characters 500 --log-level info |
Run agent-speak serve --help for the complete quick-profile option list.
Configuration covers MCP host registration and Agent Speak TOML profiles. A profile is required for audio cues, arbitrary local audio, history, fixed output routing, or a non-default TTS provider.
Register the executable's absolute path and the serve argument:
{
"mcpServers": {
"agent-speak": {
"command": "/absolute/path/to/agent-speak",
"args": ["serve"]
}
}
}Typical installer paths are:
| Platform | Command path |
|---|---|
| Windows | %LOCALAPPDATA%\Programs\UtterPipe\bin\agent-speak.exe |
| macOS | /Users/you/.local/bin/agent-speak |
| Linux | /home/you/.local/bin/agent-speak |
Resolve environment-variable and home-directory shorthand before copying the path into a host that requires a literal absolute path. Restart or reload the host before trying it.
Agent Speak has no per-call approval prompt. Unattended alerts therefore need
an MCP host that can persist approval after you review the startup profile. For
Codex, register the command with codex mcp add, then keep approval scoped to
the reviewed tools in ~/.codex/config.toml:
[mcp_servers.agent-speak]
command = "/absolute/path/to/agent-speak"
args = ["serve"]
enabled_tools = ["cancel_playback", "get_audio_capabilities", "get_playback_status", "speak_text"]
default_tools_approval_mode = "prompt"
[mcp_servers.agent-speak.tools.cancel_playback]
approval_mode = "prompt"
[mcp_servers.agent-speak.tools.get_audio_capabilities]
approval_mode = "approve"
[mcp_servers.agent-speak.tools.get_playback_status]
approval_mode = "approve"
[mcp_servers.agent-speak.tools.speak_text]
approval_mode = "approve"This keeps tools exposed by a later, broader profile unavailable until you explicitly review and add them. See the Codex MCP configuration reference for the registration and approval options.
Talk to the agent naturally; Agent Speak's MCP metadata teaches it the tool workflow. For the quick profile, try:
Say “Agent Speak is ready” out loud.When you finish reviewing this file, speak a one-sentence summary.
With configured audio cues, try What audio cues are available? or Use the completion audio cue when this task is done. Installing the MCP makes audible
tools available, but the agent should use them only when requested or when an
approved audio cue description clearly applies.
To register one complete, isolated profile, add its absolute path to the arguments:
"args": ["serve", "--config", "/absolute/path/to/agent-speak.toml"]| Command | Purpose | Example |
|---|---|---|
init |
Generate a complete profile for the current machine | agent-speak init --output ./agent-speak.toml |
validate [--config] |
Check the discovered or explicit profile and report its source | agent-speak validate |
serve [--config] [--control-file] |
Run MCP, optionally with a private local-UI control descriptor | agent-speak serve |
| `devices [--format table | toml | json]` |
| `voices [--format table | json]` | List native Windows/macOS voices for people or integrations |
init never overwrites an existing file. Profile parsing is strict: unknown
fields and invalid combinations are rejected.
The JSON device and voice inventories are versioned with
"schema_version": 1 and are intended for local UI integrations. Device JSON
contains stable IDs, display names, and default status; voice JSON contains the
same voice metadata shown by the human-readable table. These read-only commands
inspect the current host and do not load or merge a profile.
When a config-consuming command omits --config, Agent Speak starts with its
built-in quick-profile defaults and loads each existing file in this order:
| Layer | Windows | macOS/Linux |
|---|---|---|
| System | %ProgramData%\Agent Speak\agent-speak.toml |
/etc/agent-speak.toml |
| User | %USERPROFILE%\.agent-speak.toml |
$HOME/.agent-speak.toml |
| Working directory | .\.agent-speak.toml |
./.agent-speak.toml |
Later layers have higher priority. Tables merge recursively; later scalars and
arrays replace earlier values wholesale. A changed tts.backend also discards
fields belonging to the previous backend, so provider options or credentials
cannot accidentally carry into a different provider. This makes a complete
user profile plus a small project permission layer natural, and also permits
smaller layers that inherit built-in defaults:
# ~/.agent-speak.toml
[tts]
backend = "utterpipe-pocket-tts"
[tts.provider_options]
voice = "alba"# project/.agent-speak.toml
[permissions]
arbitrary_text = true
arbitrary_local_audio = falseKnown relative logging.history_path and audio-cue source paths resolve from
the layer that declared them. Provider options are opaque; relative strings
inside provider_options are passed literally, so use absolute paths when a
provider option represents a file. Any present but unreadable, malformed, or
invalid layer fails the command—Agent Speak never falls back to a partial
policy. agent-speak validate prints the loaded sources from lowest to highest
priority.
An explicit --config PATH always loads that one complete file with no
defaults, discovery, or merging. This is how the VS Code extension keeps its
managed instance isolated. Working-directory discovery uses the process working
directory chosen by the shell or MCP host; use an explicit path when that
directory is not stable.
Start from one of these complete examples:
| Section | Purpose |
|---|---|
[permissions] |
Allow arbitrary text or arbitrary local audio |
[playback] |
Set gain, queueing, concurrency, and duration limits |
[outputs] |
Name allowed default or fixed output devices |
[tts] |
Select the backend, audio policy, provider permissions, and text limit |
[logging] |
Configure diagnostics and optional history |
[[audio_cues]] |
Define approved speech or audio-file actions |
Relative audio-file cue sources and history paths are resolved from the profile's directory.
Audio-file cues do not require arbitrary_local_audio = true; that permission
controls the separate play_audio_source MCP tool. The examples demonstrate
both speech and audio-file cues.
A provider is an independently installed executable. Select its portable
command name without Windows' .exe; there is no registry or separate
provider field:
schema_version = 1
# Selects the speech backend and host-side synthesis policy.
[tts]
enabled = true
backend = "utterpipe-espeak-ng"
maximum_characters = 300
agent_utterance_options = ["rate_wpm", "pitch"]
# Sets per-request provider defaults that authorized agent values may override.
[tts.utterance_options]
voice = "default"
rate_wpm = 175
pitch = 50Agent Speak checks its own executable directory and then each absolute PATH
directory for that exact backend. It starts one reusable provider process for
serve, owns its lifecycle, and keeps playback and decoding in Agent Speak.
| Provider | Use | Options and setup |
|---|---|---|
utterpipe-espeak-ng |
Embedded, offline eSpeak NG | voice, rate, pitch, and amplitude |
utterpipe-pocket-tts |
Local neural TTS | model/voice setup and request controls |
utterpipe-openai-http |
Local or remote OpenAI-compatible service | endpoint/model setup and request controls |
provider_options is a provider-defined TOML table passed as JSON and fixed for
the process; expensive model loading and endpoint or credential settings belong
there. utterance_options contains configured defaults sent on every synthesis,
such as a cheap voice, speed, or tone choice. A provider assigns each key to
exactly one of those lifecycles.
Credentials such as provider_options.api_key remain plaintext in the profile;
protect the file and do not commit it.
agent_utterance_options is a simple permission allowlist. At startup, the
provider supplies the exact type, range, choices, and agent-facing explanation
for each available per-utterance control. Agent Speak exposes only the named
controls beneath speak_text.utterance_options, validates every value locally,
and overlays it onto configured utterance_options without assigning
engine-specific meaning. A request never changes later speech.
Optional audio_deliveries is the host's ordered format policy. When omitted,
Agent Speak automatically prefers low-latency compressed delivery, then its
other decodable pairs; every synthesis explicitly selects one initialized pair.
provider_environment remains available for providers that explicitly require
allowlisted environment variables. See the
provider configuration reference for exact
environment, discovery, storage, and lifecycle behavior.
Provider catalogs and assets change only through explicit human CLI commands,
never during MCP startup or a tool call. Catalog IDs and import kinds come from
provider info; names such as models or voices are provider conventions,
not hard-coded Agent Speak concepts.
| Command | Purpose |
|---|---|
agent-speak provider info |
Show the resolved executable and provider capabilities |
agent-speak provider catalog --catalog voices |
List one provider-declared catalog |
agent-speak prepare |
Plan, confirm, and install required assets |
agent-speak provider import --kind voice --source /absolute/reference.wav --id my-voice --consent-confirmed |
Import a file using a provider-declared kind |
agent-speak provider remove --artifact voice:my-voice |
Plan and remove an exact provider asset |
These commands use discovered layers by default and accept --config PATH for
one complete explicit profile.
Agent Speak negotiates PCM16 WAV, raw PCM16, MP3, or Ogg Opus. A provider may support more formats for other hosts; Agent Speak does not negotiate a format it cannot decode.
| MCP tool | Purpose |
|---|---|
cancel_playback |
Stop an active item or remove a queued item by playback ID |
get_audio_capabilities |
Show the effective profile and available tools |
get_playback_status |
Inspect the current or retained terminal state of an accepted playback ID |
list_audio_cues |
List configured audio cue IDs and descriptions |
play_audio_cue |
Play a configured speech or audio-file cue |
speak_text |
Speak arbitrary text when enabled |
play_audio_source |
Play an arbitrary local audio file when enabled |
Calls are fire-and-forget: acceptance means the item entered the playback
queue, not that it finished or was audible. enqueue adds to the FIFO queue;
interrupt stops every active item, starts the replacement, and retains queued
items. When startup policy allows mix, it starts beside active playback until
maximum_mix_streams is reached, then waits in the same FIFO. An earlier
enqueued item remains a barrier, so later mix requests cannot skip it. On each
physical output, requested gains are unchanged while their sum is at most 1.0;
above that, Agent Speak scales all active gains proportionally to preserve
relative levels and headroom. Use the returned playback_id with
get_playback_status when terminal confirmation matters. States are
accepted, playing, completed,
interrupted, and failed; completed is backend playback completion, not
human acknowledgement. cancel_playback stops an active item or removes a
queued item; repeating it for a terminal ID is a successful no-op with
cancelled = false. All in-flight states and the newest 256 terminal states are
retained for the life of that server process. Status and cancellation results
never include spoken text, cue text, or source paths. WAV, MP3, FLAC, and Ogg
Vorbis files are supported.
Local human-facing integrations can opt into a separate control channel with
agent-speak serve --control-file /absolute/private/control.json. Agent Speak
binds an ephemeral IPv4 loopback listener and creates that new descriptor with
a random session ID and bearer token; on POSIX the descriptor mode is 0600.
The channel provides a sanitized newest-first lifecycle snapshot, targeted
cancellation, and an emergency stop that discards queued work and stops the
active item. It is never exposed as an MCP tool and returns no spoken text,
source paths, output identities, or provider diagnostics. Treat the descriptor
as a same-user secret and let the launching integration choose and protect its
path. Agent Speak removes it on orderly shutdown.
Enabling arbitrary_local_audio lets the agent try any absolute local regular
file readable by the Agent Speak process. Playback history is disabled by
default. Selecting a provider authorizes that native executable to run with
your user privileges; process separation is not a sandbox, and a remote
provider may receive every spoken text. Review SECURITY.md.
- Run
agent-speak validatefor discovered layers oragent-speak validate --config <PATH>for one explicit profile before registration. - Run
agent-speak devicesagain if a fixed endpoint is unavailable. - On Linux, confirm the selected
utterpipe-*executable is beside Agent Speak or in an absolutePATHdirectory, and confirmaplay -lworks. PipeWire normally needspipewire-alsa; PulseAudio needs its ALSA plugin. - Diagnostics go to stderr; stdout is reserved for MCP messages while serving.
Apple and Microsoft, in their infinite wisdom, keep their best built-in voices behind Narrator and Siri instead of exposing them through supported application TTS APIs. Agent Speak lists only voices the public APIs actually allow, avoiding brittle private-API hacks.
- Provider configuration — discovery, environment, options, storage, and lifecycle
- Linux containers — edge-case ALSA/udev setup
- UtterPipe integration contract — host and provider protocol details for developers
- Security — trust boundaries and deployment guidance
- Third-party notices — distributable dependency licenses and source obligations
- Release integrity — checksum, signing, and notarization status
Licensed under the Apache License 2.0.