Skip to main content
Glama

dottie-talk

Local voice: STT + koko TTS (:1314) + HTTP façade (:1320).

Standalone. No gateway. No Dottie.app.

npm install
npm start

Bins ship in bin/ (macOS). Models download on first boot (~/.cache/parakeet.cpp, ~/.cache/dottie-talk or ~/.dottie).

Platform

STT

TTS

Apple Silicon (darwin)

parakeet-server :1315 (bundled)

koko :1314

Omarchy / Linux

voxtype (PATH, else fetched AVX2 binary + base.en)

koko :1314 (ELF fetched on first start as bin/koko-linux-x86_64)

Command

What

npm start

HTTP :1320 (starts STT+TTS)

npm run mcp

MCP stdio

npm run tts

TTS only (:1314)

dottie-talk speak "hi" / speak "hi"

TTS → speech.wav (or -o / stdout)

dottie-talk transcribe a.wav / transcribe a.wav

STT → text on stdout

dottie-talk start

same as npm start

dottie-talk health

STT/TTS readiness JSON

dottie-talk keys on

enable talk-keys-style hotkeys (off by default)

dottie-talk keys off

disable hotkeys

dottie-talk keys status

enabled / armed / chords

dottie-talk bar on

Omarchy menubar icon (hidden until start)

dottie-talk stop

stop the HTTP server

npx speak "hello" -o hello.wav
speak "hello" -o hello.wav   # after dottie-talk bar on (~/.local/bin/speak)
npx transcribe hello.wav

Node ≥22. Override STT with DOTTIE_STT=voxtype or DOTTIE_STT=parakeet.

Linux: if voxtype is already on PATH, talk uses it. If not, first start downloads the x86_64 AVX2 binary into ~/.cache/dottie-talk/bin and base.en (no sudo, no pacman). npm start skips the Darwin bin/koko and downloads the linux-bins ELF the same way. Streaming/multipart STT needs parakeet — buffered JSON /v1/audio/transcriptions works on both.

MCP

npm run mcp (stdio). Audio stays on disk or goes to the speakers, so agent context never fills with base64.

Tool

Args

Returns

transcribe

path (or wavBase64 for apps)

text

speak

text, voice?

streams PCM to the speakers; starts in ~20 ms, not after the whole clip

speak

out

saves the file; play: true also plays it

speak

returnAudio: true

base64 too (old behavior, for apps)

Streaming needs a player that reads stdin: pw-cat, pacat, aplay, or ffplay. The first one on PATH wins (pw-cat runs with --raw).

Add to Claude Code:

claude mcp add dottie-talk -s user -- node ~/Projects/dottie-talk/mcp.js

Related MCP server: io.github.chicogong/ffvoice

Talk-back (Claude Code)

Read Claude's replies aloud through koko. talk-back.js runs as two Claude Code hooks, and skills/ has the /talk and /talk-toggle skills.

Command

What

/talk

speak this session's last reply, one time

/talk on / off / toggle

talk-back mode: read every reply aloud

/talk-toggle

same as /talk toggle

/talk stop

stop playback

/talk status

on or off

Stop it: type anything (the next prompt cuts playback off), /talk stop, or /talk off. On Linux with dottie-talk keys on, Escape stops it too.

What is read: only the final reply. Never thinking, tool calls, or notes written between tool calls. Code blocks, tables, URLs, and markdown marks are dropped.

State: ~/.config/dottie-talk/talk-back/. The saved last reply is per session (last-<session>.txt), so two windows never read each other's reply. The on/off mode is global.

Setup

  1. Start dottie-talk (npm start), so koko answers on :1314

  2. Link the skills:

    ln -s ~/Projects/dottie-talk/skills/talk ~/.claude/skills/talk
    ln -s ~/Projects/dottie-talk/skills/talk-toggle ~/.claude/skills/talk-toggle
  3. Add the hooks to ~/.claude/settings.json:

    {
      "hooks": {
        "Stop": [{ "hooks": [{ "type": "command", "command": "node ~/Projects/dottie-talk/talk-back.js hook", "timeout": 5 }] }],
        "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "node ~/Projects/dottie-talk/talk-back.js interrupt", "timeout": 5 }] }]
      }
    }
  4. Restart Claude Code, then /talk on

The Stop hook saves every reply and speaks it only when the mode is on. It returns at once; playback runs in a detached child. The interrupt hook prints nothing, because UserPromptSubmit output goes into the model's context.

Keys (Linux)

Talk-keys analog. Off by default. Enable, then keep npm start running so binds arm:

dottie-talk keys on
npm start

Chord

Action

Omarchy

Alt+S

Speak selection if present, else clipboard. Second tap stops.

Steals app Alt+S menu accelerators while armed

Alt+D

Hold to dictate (voxtype push-to-talk)

Steals browser Alt+D address bar while armed; leaves Super+Ctrl+X / F9 alone

Escape

Stop speak

Only consumed while playback is active

Config: ~/.config/dottie-talk/config.json

{
  "keys": {
    "enabled": false,
    "speak": "ALT + S",
    "stop": "ESCAPE",
    "dictate": "ALT + D",
    "voice": ""
  }
}

DOTTIE_TALK_KEYS=on / off overrides enabled. Hotkeys no-op when the HTTP server is down. macOS: use talk-keys.

Bar (Omarchy)

Menubar icon only while npm start is running. Click: keys toggle, speak selection, stop, quit. Middle-click quits.

dottie-talk bar on
dottie-talk start

start on Linux also installs the plugin (sd.dottie-talk) next to Dottie if the bar does not already have it.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    A local voice interface providing high-performance speech recognition and natural text-to-speech with voice cloning capabilities. It enables AI assistants to speak, listen, and engage in character-based voice conversations through integrated MCP tools.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Local-first speech-to-text and text-to-speech MCP server. Hot-swappable engines via config.yaml — no code changes, no API keys required.
    2
    MIT