Desktop voice input tool — Node sidecar MCP server for speech-to-text transcription, text injection, and AI text polishing with Tauri 2 shell
Vocium defines 10 tools with explicit Zod schemas and descriptions. All tools have names starting with action verbs (get_, toggle, start_, stop_, cancel, submit_, transcribe_, inject_, probe_, polish_). Descriptions are present and reasonably detailed (avg ~100 chars), explaining WHAT each tool does and WHEN to use it. However, several critical gaps reduce the score: (1) Parameters lack descriptions in the schema definitions, Zod objects define types but no descriptions are visible in mcp-tools.ts; (2) Output schemas are not documented, responses are wrapped in a generic `ok()` helper returning JSON text without field-level documentation; (3) No error handling guidance, tools return success/failure but do not guide LLMs on recovery steps; (4) No pagination or result limits documented for tools that could return large data; (5) Tool composition is reasonable (each does one thing) but some tools like submit_audio and transcribe_clip are very similar and could benefit from clearer differentiation in descriptions.
Cancel the current operation and return to idle state without processing audio
Get the current state of the voice session (idle, listening, transcribing, injecting, or error)
Inject text into the active application using system keyboard/clipboard mechanisms
Polish/refine transcribed text using AI. Supports light correction, full polishing, or custom prompt styles. The act of calling this tool is opt-in regardless of the polishEnabled config setting.
Probe the system to verify text injection capability (e.g., check macOS Accessibility permissions)
Start listening for audio input. If already listening, does nothing. Transitions to listening state.
Parameter descriptions missing in Zod schemas. Zod objects define types (z.string(), z.enum()) but no descriptions are attached. LLMs cannot infer parameter meaning from type alone, a 'language' param needs context (e.g., 'ISO 639-1 language code like zh, en').
Output schemas not documented. Tools return responses via ok() helper wrapping JSON text, but no field-level schema is declared. LLMs cannot plan downstream calls or extract structured data without knowing response fields.
No error handling guidance. Tools do not document what errors can occur, whether they are retryable, or what the LLM should do next. E.g., submit_audio could fail if audio is invalid or STT service is unavailable, but no recovery guidance is provided.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 54 | 2026-07-28+ | v2 |
Stop listening for audio input. If not listening, does nothing. Transitions from listening state.
Submit audio blob for transcription and text injection. Accepts base64-encoded audio with MIME type and optional language.
Toggle the listening state (start listening if idle, stop if listening)
Transcribe an audio clip without injecting the text. Returns transcribed text only.
submit_audio and transcribe_clip are nearly identical in signature and purpose. Descriptions should clarify the key difference: submit_audio injects text into the active app after transcription, while transcribe_clip returns text only. This distinction is buried in descriptions and could confuse LLM tool selection.
No permission or scope declarations. Tools like inject_text and probe_inject require system-level permissions (macOS Accessibility, Windows clipboard access) but do not declare what permissions they need or how to handle permission denial.