Skip to main content
Glama
Social Whisper Transcript MCP

Social Whisper Transcript MCP

Social Whisper Transcript MCP

Turn any YouTube, Instagram, TikTok, X (Twitter), Facebook, Vimeo or podcast link into a full transcript, on your own server, with OpenAI Whisper. Built for AI agents.

A self-hosted MCP server + REST API in one Docker container. Give it a video URL. It downloads the audio with yt-dlp, transcribes it with faster-whisper (Whisper large-v3-turbo / large-v3), and hands back the text, timestamps, subtitles or a ready-to-download file. Works with Claude Code, Claude Desktop, Cursor, VS Code, OpenClaw and any other MCP client.

CI License: MIT

You:    "Summarise this: https://www.instagram.com/reel/..."
Agent:  transcribe_url(url) -> full Whisper transcript -> summary

Why this instead of a YouTube-transcript tool?

Most transcript MCP servers just fetch YouTube's own captions. That breaks when:

  • the video has no captions, or only bad auto-captions (common for Hindi and other non-English videos, music, accents, names)

  • the link is Instagram, TikTok, X, Facebook, Vimeo, a podcast, or any of yt-dlp's ~1800 other sites

  • you need timestamps, subtitles (SRT/VTT) or a file to hand over

This server transcribes the actual audio with Whisper. It runs on hardware you already have (a NAS, homelab box or VPS, no GPU needed), so there are no per-minute API costs and the audio never leaves your network.

Related MCP server: TubePull – AI YouTube Downloader

Features

  • Any link: YouTube, Shorts, Instagram Reels, TikTok, X/Twitter, Facebook, Vimeo, SoundCloud, podcasts… (yt-dlp updates itself on every start)

  • Whisper large-v3-turbo by default (fast), large-v3 for best accuracy; 99 languages with auto-detection

  • MCP over Streamable HTTP with 4 tools, plus a plain REST API with Swagger docs at /docs

  • Job queue: long videos (up to 4 h) run in the background; agents wait or check back, nothing times out

  • Readable output: paragraphs with [m:ss] timestamps, Markdown, SRT, VTT or JSON with every segment

  • File downloads: a 24-hour signed link an agent can pass on or curl without the API token

  • Reuse: asking for the same URL again returns the earlier transcript instantly

  • Light when idle: models load on the first job and unload after 10 minutes (~50 MB RAM idle)

  • Music / singing: falls back to full-audio transcription when voice detection finds nothing

  • Bearer-token auth, refuses links into your own network (SSRF guard), runs as non-root

Quick start (Docker Compose)

mkdir social-whisper-transcript && cd social-whisper-transcript
curl -fsSLO https://raw.githubusercontent.com/vireshmahajan/social-whisper-transcript-mcp/main/docker-compose.yml
echo "API_TOKEN=$(openssl rand -hex 24)" > .env
docker compose up -d
curl http://localhost:8000/health

The first transcription downloads the Whisper model (~1.6 GB for turbo) into the transcript-data volume.

Your API token

Every install has its own secret token, so only you (and the agents you give it to) can use your server:

  • Create it once, as above: echo "API_TOKEN=$(openssl rand -hex 24)" > .env. Compose refuses to start without one.

  • Use it everywhere as the header Authorization: Bearer <API_TOKEN>: REST calls, and the MCP config of each agent (examples below).

  • Read it back later: grep API_TOKEN .env.

  • Change it (e.g. if it leaked): put a new value in .env, run docker compose up -d, and update your agents. Old download links stop working too.

  • Keep it out of git and chats. Agents such as OpenClaw can read it from an environment variable instead of storing it in their config.

/health is the only endpoint that works without the token. Download links from get_transcript_file carry their own 24-hour signature instead, so you can share a single file without sharing the token.

docker run -d --name social-whisper-transcript --restart unless-stopped \
  -p 8000:8000 -e API_TOKEN=$(openssl rand -hex 24) \
  -v transcript-data:/data \
  ghcr.io/vireshmahajan/social-whisper-transcript-mcp:latest

Try it:

TOKEN=$(grep API_TOKEN .env | cut -d= -f2)
curl -s -X POST http://localhost:8000/transcribe \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"url": "https://www.youtube.com/watch?v=jNQXAC9IVRw", "wait": true}' | jq -r .text

Connect your AI agent

The MCP endpoint is http://<your-server>:8000/mcp (Streamable HTTP) with the header Authorization: Bearer <API_TOKEN>.

Claude Code

claude mcp add --scope user --transport http transcript http://your-server:8000/mcp \
  --header "Authorization: Bearer YOUR_TOKEN"

Cursor (~/.cursor/mcp.json)

{
  "mcpServers": {
    "transcript": {
      "url": "http://your-server:8000/mcp",
      "headers": { "Authorization": "Bearer YOUR_TOKEN" }
    }
  }
}

VS Code (.vscode/mcp.json)

{
  "servers": {
    "transcript": {
      "type": "http",
      "url": "http://your-server:8000/mcp",
      "headers": { "Authorization": "Bearer YOUR_TOKEN" }
    }
  }
}

Claude Desktop (via mcp-remote, claude_desktop_config.json)

{
  "mcpServers": {
    "transcript": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "http://your-server:8000/mcp", "--allow-http",
               "--header", "Authorization: Bearer YOUR_TOKEN"]
    }
  }
}

OpenClaw

echo 'TRANSCRIPT_TOKEN=YOUR_TOKEN' >> ~/.openclaw/.env
openclaw mcp set transcript '{"url":"http://your-server:8000/mcp","transport":"streamable-http",
  "headers":{"Authorization":"Bearer ${TRANSCRIPT_TOKEN}"}}'

Set "transport": "streamable-http" explicitly (OpenClaw defaults to SSE). The optional skill tells the agent when and how to use the tools.

MCP tools

Tool

What it does

transcribe_url(url, language?, model?, wait_seconds=50, output="text")

Starts (or reuses) a transcription. Short clips return the transcript directly; long ones return a job id. output: text, timestamped, srt.

get_transcript(job_id, output?, wait_seconds=0, offset=0)

Status or transcript of a job; waits up to 10 min; pages long transcripts.

get_transcript_file(job_id, format="txt", wait_seconds=0)

The finished transcript as a file (txt, md, srt, vtt, json), inline plus a 24 h download link that needs no token. Says "still running" until done.

list_transcripts(limit=20)

Recent jobs with ids, status, title and length.

REST API

All endpoints except /health need Authorization: Bearer <API_TOKEN>. Interactive docs: http://your-server:8000/docs.

Endpoint

POST /transcribe {"url", "language"?, "model"?, "wait"?}

Queue a job (202 + id), or with "wait": true block until done (max 10 min)

GET /jobs/{id}

Status, progress, and the full result (text + segments) when done

GET /jobs/{id}/transcript?format=txt|srt|vtt|json

Raw transcript

GET /jobs/{id}/file?format=txt|md|srt|vtt|json

Download as a file named after the video. 202 + Retry-After while running, 409 if it failed

GET /jobs

Recent jobs

GET /health

Liveness, loaded models, queue length

Example .txt file:

Title:       Steve Jobs' 2005 Stanford Commencement Address
By:          Stanford (Youtube)
Length:      15:04
Language:    en (100% sure)
Model:       Whisper large-v3-turbo
------------------------------------------------------------

[0:20] Thank you. I'm honored to be with you today for your commencement …

[0:47] Today, I want to tell you three stories from my life. That's it. No big deal …

Models, speed and memory

Measured on an Intel i9-11900 (8 threads, CPU only, int8):

Model

Speed

1 h of audio

RAM while working

Best for

large-v3-turbo (default)

~7× real time

~9 min

~2 GB

Most videos

large-v3

~2.6× real time

~23 min

~4 GB

Non-English, accents, names, lyrics

medium, small

faster

less

Weak hardware

Jobs run one at a time and use WHISPER_THREADS cores. With nothing to do, models unload after IDLE_UNLOAD_SECONDS.

Configuration

Variable

Default

API_TOKEN

(empty = no auth, don't do that)

Bearer token for the REST API and MCP; also signs download links

WHISPER_MODEL

large-v3-turbo

large-v3-turbo, large-v3, medium, small

WHISPER_THREADS

CPUs, max 8

CPU threads per job

MAX_DURATION_SECONDS

14400

Longest video accepted (4 h)

IDLE_UNLOAD_SECONDS

600

Free model RAM after this idle time; 0 = keep loaded

PRELOAD_MODEL

false

Load the default model at startup

WAIT_TIMEOUT_SECONDS

600

Max blocking time for "wait": true

PUBLIC_BASE_URL

(address the client used)

Base for download links, e.g. behind a reverse proxy or tunnel

DOWNLOAD_LINK_TTL_SECONDS

86400

How long signed download links work

ALLOW_PRIVATE_URLS

false

Allow links to localhost / LAN addresses

Login-only posts (private Instagram/Facebook, age-restricted YouTube): export cookies from a logged-in browser in Netscape format (e.g. with a "Get cookies.txt" extension) and copy the file to /data/cookies.txt in the volume: docker cp cookies.txt social-whisper-transcript:/data/cookies.txt.

Security notes

  • Always set API_TOKEN. Without it, anyone who can reach the port can use your CPU.

  • Meant for your LAN or a VPN such as Tailscale. To expose it to the internet, put it behind HTTPS (Caddy, Traefik, Cloudflare Tunnel) and set PUBLIC_BASE_URL.

  • MCP DNS-rebinding protection is off so LAN and Tailscale hostnames work; the bearer token is the guard.

  • Links that resolve to private, loopback or link-local addresses are refused unless ALLOW_PRIVATE_URLS=true.

Troubleshooting

  • "Sign in to confirm you're not a bot" / a site stopped working: restart the container (docker restart social-whisper-transcript), which updates yt-dlp. For logins, add cookies.txt.

  • Empty transcript on music videos: handled automatically (retries without voice detection); large-v3 does better with lyrics.

  • Wrong language detected: pass language ("hi", "de", …).

  • Slow: use large-v3-turbo, raise WHISPER_THREADS, or give the container more CPU.

Development

pip install -r requirements-dev.txt
pytest                       # no network, model or ffmpeg needed
docker build -t social-whisper-transcript-mcp .

Everything lives in app.py: FastAPI + the official MCP Python SDK (FastMCP), one worker thread, jobs stored as JSON in /data/jobs.

You are responsible for having the right to download and transcribe the content you send to this server, and for complying with each site's terms of service. This project is not affiliated with OpenAI, YouTube, Meta, TikTok or X.

License

MIT © Viresh Mahajan

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers