whisper-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@whisper-mcpstart recording the meeting and show the transcript as it goes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
whisper-mcp
Local Whisper mic transcription, exposed as an MCP server.
Lets any MCP client — Claude Code, Claude Desktop, Cursor, etc. — start a mic recording, read the live transcript as it accumulates, and stop it. Everything runs locally. No audio leaves your machine.
Built on top of faster-whisper with VAD and incremental decoding. Packaged with uv — one command to install, including the right Python.
Why
Meeting-notes / interview / voice-memo workflows typically mean juggling two things: recording and the agent that's going to use the transcript. This bridges them. Your agent calls start_recording when a meeting begins, polls get_transcript for new content as the meeting progresses, and calls stop_recording at the end — all from the same conversation.
Related MCP server: MCP Audio Server
Tools
Tool | Purpose |
| Spawn the transcriber as a detached subprocess. Returns |
| SIGINT the subprocess so buffered audio flushes, wait up to 15s, return final text + duration. |
| Read the transcript. Safe mid-recording. |
| Is anything recording right now? Also reaps dead-but-registered sessions. |
| Recent sessions, newest first. |
Install
Prereqs:
macOS or Linux
uv—curl -LsSf https://astral.sh/uv/install.sh | shorbrew install uvmacOS:
brew install portaudio(sounddevice depends on it)
git clone https://github.com/SidU/whisper-mcp.git
cd whisper-mcp
uv sync
uv run whisper_mcp.py --print-configuv sync reads pyproject.toml + uv.lock, downloads a compatible Python (3.10–3.13) if you don't have one, creates .venv/, and installs the exact pinned deps.
--print-config prints a copy-pasteable mcpServers JSON blob with the absolute path to this clone already filled in — one version for empty config files, one inner-only version for existing configs.
Register with your MCP client
Run uv run whisper_mcp.py --print-config from the repo and paste the output into the right config file:
Client | Config path |
Claude Desktop |
|
Claude Code |
|
Cursor |
|
Then restart the client. uv run handles the venv activation and Python selection on every invocation — no need to point at .venv/bin/python yourself.
Claude Code shortcut — skip the JSON edit by running this from inside the repo:
claude mcp add whisper-local -- uv --directory "$(pwd)" run whisper_mcp.pyFirst run
The first call to start_recording downloads the Whisper model (~500 MB for small, the default) into ~/.cache/huggingface/. Takes about a minute. Later runs are instant.
Smoke-test the transcriber directly without MCP:
uv run transcribe_mic.py --model small --language en
# say something, then Ctrl+CIf that works, the MCP server will too.
State and files
By default everything lives under ~/.whisper-mcp/:
~/.whisper-mcp/
├── sessions.json # session registry (survives restarts)
├── transcripts/ # one .txt per session
└── logs/ # subprocess stderr, for debuggingSet WHISPER_MCP_STATE_DIR in the server's env (via your MCP client config) to put it elsewhere.
Design notes
One active session at a time. Deliberate: concurrent recordings make "the current session" ambiguous. Stop one before starting another.
Detached subprocess. The recorder runs in its own process group (
start_new_session=True). Restarting the MCP server doesn't kill an in-flight recording.Thin MCP layer. The server is just process management + file reads. All the audio / inference heavy lifting lives in
transcribe_mic.py, which also works standalone as a CLI.State persists across restarts.
sessions.jsonmeansget_status()works even after the MCP server restarts; the subprocess is identified by PID. Dead PIDs are reaped automatically.Why Whisper and not Parakeet. faster-whisper is reliable on CPU with int8. parakeet-mlx has crashed with MLX threading errors in my testing. YMMV.
Why Python ≤ 3.13. PyAV (a faster-whisper dep) has no 3.14 wheels yet.
pyproject.tomlcaps the version and uv will pick 3.13.
Model options
Pass to start_recording(model=...):
Model | Size | Latency on M-series CPU | Notes |
| 75 MB | fastest | fine for simple en speech |
| 142 MB | fast | ok |
| 466 MB | moderate | default — best balance for meetings |
| 1.5 GB | slow | marginal gain over small for most uses |
| 2.9 GB | slowest | best accuracy, needs patience on CPU |
Troubleshooting
transcribe_mic.py exited immediately — look at the log path in the error, usually ~/.whisper-mcp/logs/<session_id>.log. Common causes: PortAudio not installed, no mic permission granted to your terminal/MCP host.
Mic permission — on macOS, the first time you record, the OS prompts the parent process (your MCP client / terminal) for mic access. If you miss the prompt, grant it in System Settings → Privacy & Security → Microphone and restart.
get_status says my session is "stopped_unexpectedly" — the subprocess died. Check the log. Most often means the model download was interrupted or PortAudio broke.
License
MIT. See LICENSE.
Available Tools
5 toolsget_statusA
Return the currently-active recording session, if any.
Also reaps any session whose subprocess died (marks it 'stopped_unexpectedly'). Call this before start_recording if you want to confirm the slot is free.
Returns: {active: session dict or null, recent: last 3 sessions}
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well: it discloses an unexpected state-mutating side effect (reaping dead sessions and marking them 'stopped_unexpectedly') inside an otherwise read-shaped tool, and it describes the return payload shape. An agent would otherwise assume this is a pure read.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the primary purpose in the first sentence and appends the side effect and usage hint in tight follow-ups. The 'Returns' block is useful rather than filler, though the multi-line layout is slightly loose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-param tool with no annotations and no output schema, the description compensates by explaining both the mutation side effect and the return shape ({active, recent}). Nothing critical is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there are no parameter semantics to document; the baseline of 4 applies. The description correctly implies no inputs are needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Return the currently-active recording session') plus a secondary reaping behavior. It doesn't explicitly contrast itself with list_sessions, which also surfaces sessions, so the agent must infer the difference from 'currently-active' vs. a general list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete usage rule tied to a sibling: 'Call this before start_recording if you want to confirm the slot is free.' This is real when-to-use guidance, though it does not mention list_sessions as an alternative for broader session history.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_transcriptA
Read the transcript for the active (or named) session.
Safe to call mid-recording — the transcript file is line-buffered. Use
since_offset to poll incrementally (pass back the end_offset from the
prior call to fetch only new content).
Args: session_id: optional. Defaults to active session, else most recent. tail_lines: if set, return only the last N lines. since_offset: if set, return only bytes after this offset in the file. tail_lines takes precedence if both are provided.
Returns: {session_id, text, end_offset, line_count, is_recording, last_modified}
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | No | ||
| tail_lines | No | ||
| since_offset | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses that mid-recording reads are safe because the file is line-buffered, and that tail_lines takes precedence over since_offset. It does not mention auth/permission requirements or whether reads can block, so it is strong but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the purpose and the safety/polling guidance, then uses compact Args/Returns blocks. Every sentence — including the precedence rule and return field list — carries information an agent needs, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-param read tool with no annotations and no output schema, this covers the essentials: purpose, mid-recording safety, all parameter defaults and interactions, and the return object shape ({session_id, text, end_offset, line_count, is_recording, last_modified}). Nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate entirely, and it does: session_id (defaults to active, else most recent), tail_lines (last N lines), and since_offset (bytes after offset, with precedence rules) are all explained with behavior the schema cannot convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: 'Read the transcript for the active (or named) session.' The resource (transcript) is clearly distinct from the siblings get_status/list_sessions/start_recording/stop_recording, but the description never names or contrasts those siblings explicitly, which is what a 5 requires.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operating context: 'Safe to call mid-recording' and a concrete polling pattern ('pass back the end_offset from the prior call'). It stops short of saying when NOT to use it or pointing to an alternative sibling, so it is not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sessionsA
List recent recording sessions, newest first.
Args: limit: max number to return (default 10).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description carries the full behavioral burden. It usefully discloses ordering (newest first) and a default limit, and 'list' implies a read-only operation, but it does not mention permissions, max limits, or whether it returns metadata. The output schema covers return values, so that omission is acceptable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two front-loaded sentences with an args section, no filler, and the key scoping behavior ('newest first') is stated early. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple one-parameter schema and the presence of an output schema, the description is nearly complete. It could clarify the scope of sessions (e.g., all users or only the caller's), but otherwise an agent has enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and there is one parameter. The description adds meaning beyond the schema by explaining that limit is the 'max number to return' and states the default (10). This fully compensates for the undocumented schema parameter, though it does not mention minimum or maximum bounds.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'List recent recording sessions'. It is clear what the tool does, but it does not distinguish itself from siblings like get_status or get_transcript, which also relate to recording sessions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by saying it lists recent sessions, newest first, but gives no explicit when-to-use guidance or alternatives. An agent can infer it is for viewing past sessions, but there is no routing advice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_recordingA
Start a local Whisper mic transcription session.
Spawns transcribe_mic.py as a detached subprocess. Only one session can be active at a time — call stop_recording first.
Args: topic: short label (e.g. "1:1 with Ragini"). Used in the filename; defaults to "recording". Spaces/punctuation are kebab-cased. model: faster-whisper model name. Default "small". Options: tiny, base, small, medium, large-v3. "small" is a good balance for meetings. language: ISO code. Default "en".
Returns: {session_id, transcript_path, pid, started_at, topic}
| Name | Required | Description | Default |
|---|---|---|---|
| model | No | small | |
| topic | No | ||
| language | No | en |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses that the tool spawns transcribe_mic.py as a detached subprocess, that concurrency is limited to one active session, and it enumerates the return fields. It omits mic-permission requirements and failure modes, but the operational profile is substantially disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the one-line purpose, then structured Args/Returns blocks where each line earns its place. Slightly verbose in the model enumeration, but nothing is redundant or padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description supplies the return shape (session_id, transcript_path, pid, started_at, topic), documents all three parameters despite 0% schema coverage, and flags the single-session constraint. An agent has everything needed to invoke and interpret the call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: topic semantics (used in filename, kebab-cased, defaults to 'recording'), model options enumerated with a recommendation, and language as an ISO code with default 'en'. This is meaning the bare schema does not provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Start') plus resource ('local Whisper mic transcription session'), and the surrounding siblings (stop_recording, get_transcript) make the boundary unambiguous. An agent can immediately tell this initiates a capture session rather than reading or stopping one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the prerequisite alternative and the when-not condition: 'Only one session can be active at a time — call stop_recording first.' It also gives selection guidance for the model parameter ('small is a good balance for meetings'), which steers a reasonable default choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stop_recordingA
Stop the active (or named) recording and return the final transcript.
Sends SIGINT so transcribe_mic.py flushes its audio buffer before exiting (clean shutdown — the script traps SIGINT for this purpose). Waits up to 15s for the process to exit, then SIGTERMs as a backstop.
Args: session_id: optional. Defaults to the currently-active session.
Returns: {session_id, text, line_count, duration_sec, transcript_path, status}
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well: it discloses the shutdown mechanism (SIGINT for buffer flush, 15s wait, SIGTERM backstop) and the exact return payload. An agent knows this terminates a process, how long it may block, and what it gets back.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded purpose followed by compact Args/Returns blocks that are easy to scan. The parenthetical explaining that the script traps SIGINT is mildly redundant with the preceding clause, but nothing is wasted overall.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by enumerating every returned field (session_id, text, line_count, duration_sec, transcript_path, status). For a one-parameter, no-annotation tool, an agent has everything needed to invoke and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must supply the meaning of session_id, and it does: optional, defaulting to the active session. It stops short of describing the id's format or the failure behavior when no session is active.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Stop the active (or named) recording') plus the outcome ('return the final transcript'), which implicitly separates it from get_transcript and start_recording. It never names or contrasts a sibling explicitly, so it stops short of the top mark.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The default behavior ('session_id defaults to the currently-active session') implies the common usage context, so an agent can infer when to call it without arguments. However there is no explicit when-to-use/when-not guidance or pointer to alternatives such as get_transcript for peeking without stopping.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
get_status - First observed
get_transcript - First observed
list_sessions - First observed
start_recording - First observed
stop_recording
TDQS
Scored across 5 tools
Each tool targets a distinct action in the recording lifecycle (status, list, start, stop, read). get_status and list_sessions overlap somewhat since get_status also returns the last 3 sessions, but the primary intent of each (active slot check vs. historical list) is clear enough to distinguish.
All five tools follow a clean verb_noun snake_case pattern (get_status, list_sessions, start_recording, stop_recording, get_transcript) with no deviations or mixed conventions.
Five tools is well-scoped for a focused single-purpose recording server; each tool earns its place covering a distinct phase of the session lifecycle without redundancy.
The core lifecycle is covered: start, stop, status, list, and transcript retrieval, including clean shutdown and incremental polling. Minor gap is the absence of a delete/cleanup tool for old sessions or transcripts, but agents can work around this.
Maintenance
Related MCP Connectors
Memoket — access your recording transcripts, summaries, and key takeaways over MCP.
MCP server for Speech-to-Text
- VoibeOAuthcom.getvoibe
Transcribe recordings into a speaker-labelled transcript with timestamps and a summary.
FalaAI API MCP server: transcribe audio, diagnose conversations, audit compliance (ISO 18295-1).
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables recording audio from a microphone and transcribing it using OpenAI's Whisper model. Works as both a standalone MCP server and a Goose AI agent extension.6MIT
- AlicenseNot gradedqualityDmaintenanceEnables audio transcription, intelligent splitting, and meeting analysis for MCP-compatible clients like Claude Desktop.3MIT
- AlicenseAqualityDmaintenanceProvides voice transcription control and polling for MCP-compatible agents, enabling start/stop/pause/resume and retrieval of new text via tools.8MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to submit and manage durable long-form audio transcription jobs, and read or export structured transcripts via MCP tools.1MIT