#22186: feat(talk): add baseUrl support for custom TTS servers
app: android
app: ios
app: macos
app: web-ui
gateway
extensions: talk-voice
size: S
Cluster:
Voice Call and TTS Improvements
## Summary
- Adds `baseUrl` field to the Talk Mode config, allowing users to point Talk Mode at any ElevenLabs-compatible TTS server instead of the hardcoded `https://api.elevenlabs.io`
- When `baseUrl` is unset, all behavior is unchanged — clients default to ElevenLabs
- Changes span all platforms: gateway TypeScript, macOS Swift, iOS Swift, Android Kotlin, and the talk-voice extension
## Motivation
Local/self-hosted TTS servers that implement the ElevenLabs streaming API (e.g. [Sesame CSM-1B](https://github.com/bautrey/sesame-tts), Piper, Coqui) cannot be used with Talk Mode today because the API URL is hardcoded. This is the only thing blocking local TTS integration.
The `ElevenLabsTTSClient` (from ElevenLabsKit) already accepts a `baseUrl` parameter — this PR just threads it through the config layer.
## Config example
```json
{
"talk": {
"baseUrl": "http://localhost:8880",
"voiceId": "conversationalB",
"modelId": "csm1b",
"outputFormat": "pcm_24000",
"apiKey": "local"
}
}
```
## Changes
| File | Change |
|------|--------|
| `src/config/types.gateway.ts` | Add `baseUrl?: string` to `TalkConfig` type |
| `src/gateway/protocol/schema/channels.ts` | Add `baseUrl` to `TalkConfigResultSchema` |
| `src/gateway/server-methods/talk.ts` | Forward `baseUrl` in `normalizeTalkConfigSection` |
| `extensions/talk-voice/index.ts` | Accept optional `baseUrl` in `listVoices()` |
| `apps/macos/.../TalkModeRuntime.swift` | Parse `baseUrl`, pass to `ElevenLabsTTSClient` |
| `apps/ios/.../TalkModeManager.swift` | Parse `baseUrl`, pass to `ElevenLabsTTSClient` |
| `apps/android/.../TalkModeManager.kt` | Parse `baseUrl`, use in TTS + voice list URLs |
## Test plan
- [ ] Verify Talk Mode works normally without `baseUrl` set (defaults to ElevenLabs)
- [ ] Set `baseUrl` to a local ElevenLabs-compatible server and verify TTS streams correctly
- [ ] Verify config reload picks up `baseUrl` changes without restart
- [ ] Test on macOS, iOS, and Android
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Added `baseUrl` support to Talk Mode configuration, allowing users to point TTS requests at custom ElevenLabs-compatible servers instead of the hardcoded ElevenLabs API.
**Changes:**
- Added optional `baseUrl` field to `TalkConfig` type and protocol schema
- Updated gateway to forward `baseUrl` in config normalization
- Modified all platform TTS clients (iOS, macOS, Android) to accept and use custom `baseUrl`
- Updated `talk-voice` extension's `listVoices` function signature to accept `baseUrl` parameter
**Issue found:**
- The `talk-voice` extension's `/voice list` and `/voice set` commands don't pass the configured `baseUrl` to `listVoices()`, so they will always query the default ElevenLabs API instead of the custom server (lines 110, 119)
<h3>Confidence Score: 3/5</h3>
- Safe to merge after fixing the extension bug; otherwise TTS will work but voice management commands won't respect custom baseUrl
- The implementation is mostly correct across all platforms (TypeScript, Swift, Kotlin), with proper config parsing, URL construction, and fallback handling. However, the extension has a logical bug where the `/voice` commands won't use the configured `baseUrl`, breaking the voice list/set functionality for custom TTS servers. This is a functional issue but not critical since core TTS streaming works correctly.
- extensions/talk-voice/index.ts requires a fix to pass `baseUrl` from config to `listVoices()` calls
<sub>Last reviewed commit: 9cd9562</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#9736: feat(tts): add baseUrl option to OpenAI TTS config (#9709)
by divol89 · 2026-02-05
83.0%
#8339: fix(tts): validate ElevenLabs base URL against allowlist
by yubrew · 2026-02-03
76.2%
#11704: feat(tts): OpenAI TTS baseUrl support for local servers (Chatterbox...
by mateusz-michalik · 2026-02-08
74.0%
#9456: feat(mac): add enhanced Siri neural voice support for Talk mode
by teknomage8 · 2026-02-05
73.3%
#8922: feat(voice-call): Add ElevenLabs WebSocket streaming TTS
by mikiships · 2026-02-04
72.5%
#22889: feat(talk): add provider-agnostic talk config contract
by ngutman · 2026-02-21
71.0%
#11745: ui: add server-side TTS for web chat via gateway endpoint
by wjlgatech · 2026-02-08
70.9%
#16274: feat(voice): Fix persistent speech errors, silent playback, and feedb…
by ryotsukuda333 · 2026-02-14
70.9%
#7965: feat(tts): add Speechify as TTS provider
by chaerla · 2026-02-03
70.7%
#18167: feat(web-search): add baseUrl support for Brave Search provider
by jkoprax · 2026-02-16
70.3%