Skip to content

alcheng10/handy_opencode_mcp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

handy-opencode-mcp

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.


How it works

  1. Watches Handy's history.db SQLite database for new transcription rows (mtime polling, no writes).
  2. On each new entry, discovers the active OpenCode HTTP port via process inspection.
  3. POSTs the transcription text to OpenCode's /tui/append-prompt endpoint.
  4. 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.


Requirements

  • Python 3.11+
  • Handy installed and running
  • OpenCode v0.1+ (requires TUI HTTP API)

Supported platforms:

  • Windows 10/11
  • macOS (Intel and Apple Silicon)
  • Linux (x64)

Installation

Install with pip (outside any virtualenv):

pip install --user -e "path/to/handy-opencode-mcp"

Confirm the executable is available:

handy-opencode-mcp --help

If handy-opencode-mcp is not found, add the user Scripts/bin directory to your PATH:

  • Windows: %APPDATA%\Python\Python3xx\Scripts
  • macOS / Linux: ~/.local/bin

Usage

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

Standalone

handy-opencode-mcp --directory /path/to/your/project --no-submit

As an OpenCode MCP plugin (recommended)

Add 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 --port so the bridge can discover it:

opencode --port 4096

Without --port, port discovery fails and transcriptions are silently dropped.


State

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.


Troubleshooting

Transcriptions not appearing in OpenCode

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 4096

Or any free port. The bridge will find it automatically.


Transcription appears twice in the same tab

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:

  1. Check for multiple instances:
    pgrep -af "handy-opencode-mcp"
  2. If two processes are listed, kill the stale one (lower PID = older instance):
    kill <old-pid>
  3. 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.


Transcription appears once then doubles on next speech

Same root cause as above — two MCP processes. Check with pgrep -af handy-opencode-mcp and kill the duplicate.


Licence

MIT — see LICENSE.


Attribution

Built with assistance from Claude (Anthropic) via OpenCode.

About

MCP to allow Handy to interact with the OpenCode TUI. Cross-platform (Windows, Mac, Linux)

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages