MCP tools for a VocaGateway you run. The server lets an MCP client inspect gateway readiness and models, then send a completed local audio file to that explicitly configured gateway for transcription.
This is not the speech engine and it is not on-device dictation. Audio leaves the machine running the MCP server and goes only to the VocaGateway URL the user configured. There is no Voca account, hosted Voca relay, or cloud transcription service.
The v0.1 milestone is a local stdio MCP server. A self-hosted Streamable HTTP transport may reuse the same client core later, but is not implemented yet.
| Tool | Purpose | Gateway access |
|---|---|---|
get_gateway_status |
Show the configured destination, readiness, engine, streaming capability, and languages | Public health endpoints |
list_models |
List available and installed models without changing gateway state | Bearer-authenticated |
transcribe_file |
Upload one completed local audio file and return its transcript | Bearer-authenticated |
transcribe_file requires confirm_gateway_url to match the configured
destination before it opens the file. This gives the MCP host a chance to show
where audio will be sent and prevents an unnoticed destination change.
Not included in v0.1: live transcription streaming, token administration, model download/delete/select, transcript history, arbitrary URL ingestion, or a Voca cloud relay.
- Python 3.12 or newer
uv- A reachable VocaGateway with an existing bearer token
- Node.js/
npxonly for the optional MCP Inspector - Docker only for the container build
git clone https://github.com/VocaHQ/vocagateway-mcp.git
cd vocagateway-mcp
uv sync --locked --all-groupsConfigure the gateway destination and token in the MCP host environment. Do not put either value in source control:
export VOCAGATEWAY_URL=http://127.0.0.1:8765
export VOCAGATEWAY_TOKEN='your-existing-gateway-token'
uv run vocagateway-mcpAn stdio server waits silently for an MCP host on stdin. Use Ctrl+C to stop a
manual launch.
| Variable | Required | Purpose |
|---|---|---|
VOCAGATEWAY_URL |
Yes | Absolute http or https gateway URL; credentials in the URL are rejected |
VOCAGATEWAY_TOKEN |
Yes | Existing gateway bearer token; never included in returned errors |
With a local VocaGateway running at 127.0.0.1:8765, use the included wrapper:
npx @modelcontextprotocol/inspector bash \
/absolute/path/to/vocagateway-mcp/scripts/inspect-local.shThe wrapper defaults to the loopback gateway and reads
~/.config/vocagateway/token without printing it. Explicit environment values
still take precedence.
In the Inspector:
- Connect and open Tools.
- Call
get_gateway_status; confirm the displayedgateway_url. - Call
list_models. - Call
transcribe_filewith raw form values—do not include quote characters:
{
"audio_file_path": "/absolute/path/to/recording.wav",
"confirm_gateway_url": "http://127.0.0.1:8765"
}The audio path is local to the machine running this stdio MCP server. A hosted server will need a different, remote-safe audio input contract.
The MCP returns remediation-oriented errors without echoing gateway response bodies:
| Error | What to check |
|---|---|
confirm_gateway_url contains quote characters |
In Inspector form mode, paste the raw URL without " characters |
Gateway destination mismatch |
Call get_gateway_status and confirm that exact gateway_url |
Could not connect to VocaGateway |
Start the gateway and verify its hostname and port |
HTTP 401 |
Verify VOCAGATEWAY_TOKEN matches the running gateway |
HTTP 404 |
Verify the base URL and upgrade to a gateway with /v1/audio/transcriptions |
HTTP 413 / 415 / 422 |
Check the upload size, supported audio type, duration, and whether the file is decodable |
HTTP 503 |
Call get_gateway_status; the selected speech engine is not ready |
Configured and confirmed gateway URLs must be absolute http or https URLs
pointing at the gateway root. Credentials, paths, query strings, fragments,
whitespace, invalid ports, and surrounding quotes are rejected explicitly.
uv sync --locked --all-groups
uv run ruff check .
uv run ruff format --check .
uv run pytestBuild a wheel, then exercise the current environment's MCP initialization and tool discovery:
uv build --wheel
uv run python scripts/smoke_stdio.py .venv/bin/vocagateway-mcpTests use httpx.MockTransport; they do not require a live gateway, speech
engine, recording, or network connection. GitHub Actions repeats lint, format,
unit, clean-wheel install, stdio protocol smoke, and container-build checks.
The image currently exposes the same stdio server. Pass secrets at runtime, not at build time:
docker build --tag vocagateway-mcp:dev .
docker run --rm -i \
-e VOCAGATEWAY_URL \
-e VOCAGATEWAY_TOKEN \
vocagateway-mcp:devFor a gateway running on the macOS host, remember that 127.0.0.1 inside Docker
is the container itself. Use an explicitly configured host address such as
host.docker.internal only when that network path is intended and protected.
MCP host
└── stdio → vocagateway-mcp
└── HTTP + bearer token → user-operated VocaGateway
└── selected local speech engine
GatewayClient contains configuration, validation, and redacted errors. It owns
one reusable httpx.AsyncClient, so status checks, model discovery, and uploads
share connection pooling and one request/error path. The FastMCP lifespan closes
that client cleanly when the server exits.
The FastMCP tool layer is deliberately thin so a future authenticated Streamable HTTP transport can reuse the same gateway behavior without duplicating it.
- The server does not log bearer tokens, audio bytes, or transcript content.
- Gateway response bodies are not echoed in HTTP errors.
- Audio is not opened until its destination URL is confirmed.
- URL credentials and empty tokens are rejected during configuration.
- Tests contain no real recordings, transcripts, tokens, or private hostnames.
- A local HTTP deployment should bind to
127.0.0.1; a future remote MCP mode must require authentication, TLS or a private network, and Origin/Host checks.
See AGENTS.md for contributor and coding-agent rules.
This repository was opened from
VocaGateway issue #38. The
transcription tool uses the OpenAI-compatible
POST /v1/audio/transcriptions endpoint introduced by
VocaGateway PR #37.
License: AGPL-3.0.