Skip to main content
Glama
iceener

ElevenLabs MCP Server

by iceener
README.md
# ElevenLabs MCP Server

Fetch-native MCP server for ElevenLabs text-to-speech, speech-to-text, voices, and transcripts. It runs on Bun and Cloudflare Workers.

> This repository targets the prerelease `2026-07-28` MCP candidate with `@modelcontextprotocol/server@2.0.0-beta.5`. It does not claim final conformance until the dated specification and stable packages are published and verified.

## Tools

- `health`
- `text_to_speech` — returns generated audio as a base64 data-URI resource
- `speech_to_text` — accepts an HTTPS URL or base64 file content
- `list_voices`
- `get_voice`
- `get_transcript`
- `delete_transcript`

Tool names, inputs, annotations, audio behavior, and transcript behavior are shared across Bun and Workers. Tools that advertise output schemas return matching `structuredContent`.

## Configure

```bash
bun install
cp .env.example .env
```

Set the provider credential:

```env
ELEVENLABS_API_KEY=xi_your_elevenlabs_key
```

This is the only credential sent to `api.elevenlabs.io`.

Optional MCP caller authentication is separate:

```env
AUTH_STRATEGY=api_key
API_KEY=your_mcp_caller_key
API_KEY_HEADER=x-api-key
```

`API_KEY`, `BEARER_TOKEN`, custom caller headers, and OAuth resource tokens are never reused as ElevenLabs credentials. External JWT Resource Server mode is documented in `.env.example`.

## Run

```bash
bun run dev
# http://127.0.0.1:3000/mcp
```

Cloudflare Workers:

```bash
bun x wrangler secret put ELEVENLABS_API_KEY --config wrangler.jsonc
bun run deploy
```

Set a real `MCP_PUBLIC_URL`, Host/Origin allowlists, and binding IDs in `wrangler.jsonc` before deployment.

## Protocol and HTTP behavior

- One deployment-scoped fetch handler and a fresh `McpServer` per request
- Modern protocol pinned to candidate `2026-07-28`
- SDK stateless fallback for legacy `2025-11-25` clients
- `GET /mcp` and `DELETE /mcp` return `405`; no session capability is advertised
- Bounded MCP request bodies, strict Host/Origin checks, and allowlisted CORS headers
- Cancellation reaches ElevenLabs fetches through `ctx.mcpReq.signal`

Endpoints:

| Endpoint | Methods | Purpose |
|---|---|---|
| `/mcp` | `POST`, `OPTIONS` | MCP and CORS preflight |
| `/health` | `GET` | Runtime health |
| `/icon.svg` | `GET` | Server icon |

## Validate

```bash
bun test
bun run typecheck
bun run lint
bun run format:check
bun run build
bun run build:worker
bun run types:worker:check
```

Provider tests use mocks; real speech generation and transcription require a valid ElevenLabs API key and may incur usage charges.

## License

MIT