Skip to content
 
 

Repository files navigation

SpeechLab MCP Server

Give Claude the ability to dub, transcribe, and globalize any media — just by talking to it. The SpeechLab MCP server connects Claude (and any MCP-compatible AI client) directly to the SpeechLab Translate/Dub API, so you can say "dub this YouTube video into Spanish and Japanese" and get back download-ready dubbed audio, without writing a single line of code.


Table of Contents


Install

Claude Code (one command):

claude mcp add speechlab npx speechlab-mcp

Then set your credentials:

claude mcp add speechlab npx speechlab-mcp \
  -e SPEECHLAB_EMAIL=you@example.com \
  -e SPEECHLAB_PASSWORD=yourpassword \
  -e SPEECHLAB_API_URL=https://translate-api.speechlab.ai/v1

Claude Desktop Configuration

Add this block to your claude_desktop_config.json (usually at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "speechlab": {
      "command": "npx",
      "args": ["-y", "speechlab-mcp"],
      "env": {
        "SPEECHLAB_EMAIL": "you@example.com",
        "SPEECHLAB_PASSWORD": "yourpassword",
        "SPEECHLAB_API_URL": "https://translate-api.speechlab.ai/v1"
      }
    }
  }
}

Restart Claude Desktop after saving. The server starts on-demand via npx — no global install needed.


Tools

All tools are prefixed speechlab_. Authentication is handled automatically using the credentials in your environment — you rarely need to call speechlab_login directly.

Tool What it does Endpoint
speechlab_login Authenticate and obtain a JWT. Called automatically by other tools when credentials are in env. JWT is at tokens.accessToken.jwtToken in the response. POST /auth/login
speechlab_create_project_and_dub Primary dub tool. Creates a project and starts dubbing media into one or more target languages. Accepts a URL or media reference, source language, and array of target language codes. Returns a flat object { projectId, jobId, dubStatus }. POST /projects/createProjectAndDub
speechlab_create_project_and_transcribe Creates a project and starts transcription. Returns a project ID and transcription ID to poll. POST /projects/createProjectAndTranscribe
speechlab_get_projects Lists projects with pagination. Filterable by status; sortable by any field (e.g. createdAt:desc). Use this to poll dub completion — check translations[0].dub[0].status. GET /projects
speechlab_get_project Returns project metadata. Note: does not populate dub status — use speechlab_get_projects to poll dub and merge progress. GET /projects/{projectId}
speechlab_export_project Triggers export of a completed project to generate downloadable output files. POST /projects/exportProject/{projectId}
speechlab_get_dubs Fetches status and metadata for a specific dub by ID. Poll this to check whether mergeStatus is complete. GET /dubs/{dubId}
speechlab_get_transcription Returns transcription content (segments, timestamps, speaker IDs) for a given transcription ID. GET /transcriptions/{transcriptionId}
speechlab_get_translation Returns translated segments for a given translation ID. The dub array is at the dub field (singular). GET /translations/{translationId}
speechlab_get_media_url Returns a short-lived presigned URL to download a media file (dubbed audio/video, transcription export, etc.). POST /medias/getMediaPresignedURL
speechlab_get_languages Returns the full list of supported source and target language codes. Use this to discover valid values before dubbing. GET /languages
speechlab_get_voices Lists available TTS voices, optionally filtered by language. GET /voices
speechlab_get_user_balance Returns the account's remaining dubbing credit balance (flat { credits }). 1 credit ≈ 1 minute of media. GET /users/{userId}/balance
speechlab_check_upload_billing Estimates the credit cost to upload and process media before committing (credits = minutes rounded up; first 2 projects under 30 min are free). POST /dubs/check-upload-billing
speechlab_check_export_billing Estimates the credit cost to export a project before committing. POST /dubs/check-export-billing
speechlab_import_youtube Starts an import job for a YouTube URL, making the video available as a media reference for dubbing or transcription. POST /imports/youtube
speechlab_get_youtube_import_status Polls the status of a YouTube import job by import ID. GET /imports/youtube/{importId}
speechlab_merge_dub Merges separately dubbed audio tracks back into the original video container. Returns a merged media reference. POST /dubs/{dubId}/merge
speechlab_regenerate_dub Queues a dub for regeneration (e.g., after editing transcription or translation). POST /dubs/{dubId}/regenerate
speechlab_generate_sharing_link Creates a shareable review link for a project that can be sent to stakeholders. POST /projects/{projectId}/share
speechlab_update_project Updates project metadata (name, description, settings) for an existing project. PATCH /projects/{projectId}

Typical Dub Workflow

  1. Check your balance — call speechlab_get_user_balance to confirm you have credits.
  2. Discover languages — call speechlab_get_languages to find the exact language codes you need. Language codes use underscore format: es_la, es_es, fr, fr_ca, pt_pt, pt_br, ar_sa. Bare codes like es return HTTP 400.
  3. Import from YouTube (optional) — call speechlab_import_youtube with the video URL, then poll speechlab_get_youtube_import_status until status is complete. Use the returned media reference in step 4.
  4. Start dubbing — call speechlab_create_project_and_dub with your media URL or reference, source language, and an array of target language codes. The response is a flat object: { projectId, jobId, dubStatus }.
  5. Poll project status — call speechlab_get_projects every 15–30 seconds and check translations[0].dub[0].status for COMPLETE. For merge progress, poll speechlab_get_dubs and watch mergeStatus until it reads complete.
  6. Export — call speechlab_export_project to package the output files.
  7. Download — call speechlab_get_media_url with the project or media ID to get a presigned download URL. The URL is temporary — fetch the file before it expires.

Example Claude Prompts

Dub this video into Spanish (es_la) and French (fr):
https://example.com/product-launch.mp4
Source language is English.
Transcribe this podcast episode and show me the full transcript:
https://example.com/episode-42.mp3
What languages does SpeechLab support for dubbing?
Import this YouTube video and dub it into Brazilian Portuguese (pt_br):
https://www.youtube.com/watch?v=dQw4w9WgXcQ
How many dubbing credits do I have left, and what would it cost
to export my last project in MP4 format?
Show me all my projects from the past week, sorted by most recent,
and give me a download link for the Spanish dub on the first one.

Supported Languages

The full list of supported source and target language codes is dynamic and served by the API. Call speechlab_get_languages to get the current list:

What languages can I dub into?

Language codes use underscore format — not BCP-47 hyphenated codes. Common examples: es_la (Spanish Latin America), es_es (Spanish Spain), fr (French), fr_ca (French Canada), pt_br (Portuguese Brazil), pt_pt (Portuguese Portugal), ar_sa (Arabic Saudi Arabia). Passing a bare code like es returns HTTP 400.


Environment Variables

Variable Required Description Example
SPEECHLAB_EMAIL Yes SpeechLab account email you@example.com
SPEECHLAB_PASSWORD Yes SpeechLab account password hunter2
SPEECHLAB_API_URL No API base URL. Defaults to the production endpoint if omitted. https://translate-api.speechlab.ai/v1
MCP_TRANSPORT No Transport type. stdio is correct for Claude Desktop and Claude Code. stdio
LOG_LEVEL No Logging verbosity info (default), debug, warn, error
LOG_FORMAT No Log format json (default), simple
API_TIMEOUT No HTTP request timeout in milliseconds 60000
API_MAX_RETRIES No Number of retries on 429/5xx errors 3

Troubleshooting

"Authentication failed" or 401 errors

The server authenticates using SPEECHLAB_EMAIL and SPEECHLAB_PASSWORD from the environment. If those are missing or wrong, every tool call will fail with an auth error.

  • Confirm the variables are set in your MCP config's env block — they are not inherited from your shell when launched by Claude Desktop.
  • The server stores a JWT in memory and refreshes it automatically before expiry. If you see repeated 401s mid-session, the refresh token may have expired — restart the MCP server.
  • The JWT is never written to disk.

"Tool not found: speechlab_get_dubs" or similar

The tool name is speechlab_get_dubs (plural), not speechlab_get_dub. All tools that return a single record by ID still use the plural form to match the underlying API resource paths (GET /dubs/{dubId}).

Dub is taking a long time / mergeStatus never becomes complete

Dubbing is an async pipeline. Processing time scales with media length — a 10-minute video may take several minutes. Poll speechlab_get_dubs on the dubId returned from speechlab_create_project_and_dub:

  • mergeStatus: pending — queued, not yet started
  • mergeStatus: processing — pipeline is running
  • mergeStatus: complete — ready to export and download
  • mergeStatus: failed — pipeline error; check the error field in the response

If mergeStatus stays pending for more than 10 minutes, check your account balance with speechlab_get_user_balance.

Language code returns HTTP 400

The API requires locale-specific underscore codes, not bare ISO codes. Use es_la not es, pt_br not pt, fr_ca not fr-CA. Call speechlab_get_languages to see the full accepted enum.

Polling dub status via GET /projects/{id} returns incomplete data

GET /projects/{projectId} does not populate dub status. To check whether a dub is complete, use speechlab_get_projects (list endpoint) and read translations[0].dub[0].status. For merge completion, poll speechlab_get_dubs and watch mergeStatus.


Development

# Clone and install
git clone https://github.com/speechlabinc/speechlab-mcp.git
cd speechlab-mcp
npm ci

# Copy and fill in credentials
cp .env.example .env

# Run in watch mode (restarts on save)
npm run dev

# Build
npm run build

# Type check
npm run typecheck

# Run all tests
npm test

# Unit tests only
npm run test:unit

# With coverage
npm run test:coverage

Tests live in tests/unit/ and tests/integration/. Integration tests require valid credentials in .env.


Companion Resources

  • speechlab-platform-skill — Claude Code skill that teaches your agent every API quirk documented here, so it gets every task right without you correcting it. Install via the Claude Code plugin marketplace or manually into .claude/skills/: github.com/speechlabinc/speechlab-platform-skill

  • Remotion globalization example — End-to-end example combining SpeechLab dubbing with a Remotion video composition. Scaffold with npx create-video@latest --yes --blank --no-tailwind <name>, render with npx remotion render, parametrize compositions via Zod schema + calculateMetadata, add audio via <Audio> from @remotion/media, and burn captions via @remotion/captions. See examples/remotion-globalization in this repository.

  • SpeechLab platform — translate.speechlab.ai — manage credits, review projects, and access the web UI.

  • API reference — https://translate-api.speechlab.ai/v1/docs (Swagger UI). Append /docs.json for the raw OpenAPI JSON.


License

MIT — see LICENSE.

About

The Speechlab MCP server

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages