Local daemon that bridges Handy speech-to-text transcriptions into the OpenCode TUI prompt via MCP.
Speak into Handy. Your words appear in the OpenCode input box, ready to edit before you press Enter.
- Watches Handy's
history.dbSQLite database for new transcription rows (mtime polling, no writes). - On each new entry, discovers the active OpenCode HTTP port via process inspection.
- POSTs the transcription text to OpenCode's
/tui/append-promptendpoint. - Optionally auto-submits via
/tui/submit-prompt(disabled by default — see--no-submit).
All traffic is 127.0.0.1 only. No internet access, no external dependencies, stdlib Python only.
Supported platforms:
- Windows 10/11
- macOS (Intel and Apple Silicon)
- Linux (x64)
Install with pip (outside any virtualenv):
pip install --user -e "path/to/handy-opencode-mcp"Confirm the executable is available:
handy-opencode-mcp --helpIf handy-opencode-mcp is not found, add the user Scripts/bin directory to your PATH:
- Windows:
%APPDATA%\Python\Python3xx\Scripts - macOS / Linux:
~/.local/bin
handy-opencode-mcp [options]
Options:
-d, --directory DIR OpenCode project directory for session routing
(default: current working directory)
--db PATH Path to Handy history.db (default: platform-specific)
--poll-interval SECS Seconds between mtime checks (default: 1.0, min: 0.5)
--no-submit Append text to prompt but do not auto-submit;
press Enter yourself to send
--mcp Run as MCP stdio server (auto-started by OpenCode)
-v, --verbose Enable debug logging
handy-opencode-mcp --directory /path/to/your/project --no-submitAdd to ~/.config/opencode/opencode.json:
{
"mcp": {
"handy-opencode-mcp": {
"type": "local",
"command": ["handy-opencode-mcp", "--mcp", "--no-submit",
"--directory", "/path/to/your/project"]
}
}
}If handy-opencode-mcp is not on your PATH, use the full absolute path to the executable.
OpenCode will start the daemon automatically on launch and stop it on exit.
Important: Start OpenCode with
--portso the bridge can discover it:opencode --port 4096Without
--port, port discovery fails and transcriptions are silently dropped.
Last-seen transcription ID is persisted to a platform-specific location:
- Windows:
%APPDATA%\handy-opencode-mcp\state.json - macOS:
~/Library/Application Support/handy-opencode-mcp/state.json - Linux:
~/.config/handy-opencode-mcp/state.json
Delete this file to replay all existing transcriptions on next start.
Symptom: Handy records speech, but nothing appears in the OpenCode prompt.
Cause: Port discovery fails. The bridge finds OpenCode by scanning for --port <N> in the process command line. If OpenCode was started without --port, discovery returns nothing and all dispatches are silently skipped.
Fix: Always start OpenCode with an explicit port:
opencode --port 4096Or any free port. The bridge will find it automatically.
Symptom: Every voice input is duplicated in the prompt box.
Most likely cause: two OpenCode instances are running. Each instance spawns its own copy of the MCP bridge, and both watch the same Handy database. Every new transcription is dispatched by both processes to the same TUI.
Fix:
- Check for multiple instances:
pgrep -af "handy-opencode-mcp" - If two processes are listed, kill the stale one (lower PID = older instance):
kill <old-pid>
- Close the extra OpenCode tab/window so only one instance runs.
Secondary cause: If you recently fixed a broken port (transcriptions were queued but not sent), the old MCP process may still be alive and retry-dispatching the backlog at the same time as the new one. Killing the old process resolves it.
Same root cause as above — two MCP processes. Check with pgrep -af handy-opencode-mcp and kill the duplicate.
MIT — see LICENSE.
Built with assistance from Claude (Anthropic) via OpenCode.