Global push-to-talk speech-to-text for Windows 11. Hold a key, speak, release, and the transcript is typed into whatever has focus, including fullscreen games.
Overview
Hold to talk (works while the app is minimized or unfocused). On release, audio is sent to Fish Audio STT, then typed into whichever window has focus—including fullscreen games. Optionally run as an so Claude Desktop, Claude Code, OpenClaw, and similar tools can read your STT history. - Windows 11 (designed for; other Windows versions may work) - Python - A Fish Audio API key 1. Press , search for , open . 2. → under → 3. Name: FISH_AUDIO_API_KEY Value: your key from https://fish.audio/app/api-keys 4. OK out of all dialogs. the terminal (and this app) so the variable is visible. Session-only (PowerShell, not permanent): , Windows hides keyboard state from other programs. If Right Ctrl does nothing while the game is focused, start elevated (optional): Edit config.ini in this folder and save. Most settings — including — apply immediately; you do not need to restart the program. A fully commented template is in config.example.ini.
README
Elo STT Passive v1.0
Global push-to-talk speech-to-text for Windows 11.
Hold Right Ctrl to talk (works while the app is minimized or unfocused). On release, audio is sent to Fish Audio STT, then typed into whichever window has focus—including fullscreen games. Optionally run as an MCP server so Claude Desktop, Claude Code, OpenClaw, and similar tools can read your STT history.
Features
| Feature | Details |
|---|---|
| Global hotkey | Right Ctrl hold-to-talk; Right Shift cancels |
| Rolling buffer | Configurable pre/post roll (default 0.5 s) so words are not clipped |
| Speech gate | Skips the API when only ambient noise is present (distinct soft cue) |
| Audio prep | Normalizes quiet speech, then boosts all speech (~+30% default, dB-aware) |
| Game-friendly typing | SendInput Unicode key-down / key-up with configurable delay & hold |
| Parallel jobs | Start a new hold while a previous clip is still processing |
| Soft cues | Distinct low-volume sounds for error, cancel, and no-speech |
| API key safety | Reads FISH_AUDIO_API_KEY from the environment only — never saved to disk |
| MCP | Query recent results, time windows, ranges, search; timestamps on hold start/end |
| Config | All knobs in config.ini next to the program |
Requirements
- Windows 11 (designed for; other Windows versions may work)
- Python 3.10+
- A Fish Audio API key
Install
cd "C:\Projects\Elo STT Passive\repo"
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
Set the API key (Windows 11)
- Press Win, search for environment variables, open Edit the system environment variables.
- Environment Variables… → under User variables → New…
- Name:
FISH_AUDIO_API_KEY
Value: your key from https://fish.audio/app/api-keys - OK out of all dialogs. Restart the terminal (and this app) so the variable is visible.
Session-only (PowerShell, not permanent):
$env:FISH_AUDIO_API_KEY = "your_key_here"
Run
Desktop (Notepad and other unelevated apps):
python elo_stt_passive.py
In some fullscreen games, Windows hides keyboard state from other programs. If Right Ctrl does nothing while the game is focused, start elevated (optional):
python elo_stt_passive.py --elevate
| Action | Result |
|---|---|
| Hold Right Ctrl | Record (includes buffer before the press) |
| Release Right Ctrl | Transcribe → type into the focused app |
| Right Shift while holding Right Ctrl | Cancel; soft cancel sound |
| Ctrl+C in the console | Quit |
Configuration
Edit config.ini in this folder and save. Most settings — including capture mode — apply immediately; you do not need to restart the program. A fully commented template is in config.example.ini. Defaults and limits are also documented in the header of elo_stt_passive.py.
Useful keys:
[audio] capture_mode—microphone(default),system(what you hear), orboth(switch live)[recording] buffer_seconds— pre/post roll (default0.5)[audio_processing] speech_boost_percent— default30(×1.30 ≈ +2.28 dB)[keystrokes] inter_key_delay/key_hold_duration[stt] timeout_seconds— default8[speech_detection] *— ambient / speech gate
MCP server
Start capture and expose tools to MCP clients:
python elo_stt_passive.py --mcp
Claude Desktop (example)
Add to your Claude Desktop MCP config (path may vary):
{
"mcpServers": {
"elo-stt-passive": {
"command": "C:\\Projects\\Elo STT Passive\\repo\\.venv\\Scripts\\python.exe",
"args": [
"C:\\Projects\\Elo STT Passive\\repo\\elo_stt_passive.py",
"--mcp",
"--skip-api-key-check"
]
}
}
}
Set FISH_AUDIO_API_KEY in your user environment rather than putting it in the JSON file.
Tools
| Tool | Purpose |
|---|---|
get_recent_stt_results |
Last N transcripts |
get_latest_stt_result |
Single newest result |
get_stt_results_past_seconds |
Everything in the last N seconds |
get_stt_results_in_range |
Overlap with Unix timestamp range |
get_stt_results_since_iso |
Since an ISO-8601 time |
search_stt_results |
Substring search |
get_stt_result_by_id |
Lookup by id |
get_stt_stats / get_elo_stt_status |
Counts and runtime status |
clear_stt_history |
Wipe in-memory history |
Each success record includes hold_start_utc / hold_end_utc (and Unix equivalents) with millisecond precision, plus the transcript text.
Optional SSE transport for a long-running windowed app:
python elo_stt_passive.py --mcp-sse
Tests
python -m pytest tests -q
Project layout
elo_stt_passive.py # Entry point + documented defaults
config.ini # Your settings
config.example.ini # Template
elo_stt/ # Modular package
tests/
Privacy & security
- The Fish Audio API key is read from the environment only when needed.
- This program does not write API keys to
config.inior any other file. - Audio is sent to Fish Audio over HTTPS for transcription; review their terms for data handling.
- STT history is in-memory only (lost when the process exits), sized by
mcp.max_history.
License
MIT. See LICENSE. Fish Audio, Claude, and other trademarks belong to their respective owners.
Install
This server does not publish a one-line install command.
Open the repository installation guideConfiguration
{
"mcpServers": {
"elo-stt-passive": {
"command": "C:\\Projects\\Elo STT Passive\\repo\\.venv\\Scripts\\python.exe",
"args": [
"C:\\Projects\\Elo STT Passive\\repo\\elo_stt_passive.py",
"--mcp",
"--skip-api-key-check"
]
}
}
}