Skip to main content
Glama
dahbimoad

mcp-youtube-transcript

by dahbimoad
README.md
# mcp-youtube-transcript

An [MCP](https://modelcontextprotocol.io) server that extracts YouTube transcripts in any available language, including auto-generated ones.

It exposes a single tool, `get_transcript`, which takes a YouTube URL or video ID and returns the transcript as plain text.

## Why this exists

This is a repaired fork of [`@kimtaeyoon83/mcp-server-youtube-transcript`](https://github.com/kimtaeyoon83/mcp-server-youtube-transcript) (MIT). That package no longer returns transcripts, for two independent reasons:

**1. Successful calls rendered as `[object Object]`.**
The tool handler returned its payload wrapped in a `toolResult` key:

```js
return { toolResult: { content: [...], isError: false } };
```

That was the shape used by MCP SDK 0.6 before the spec settled. A current client looks for `content` at the top level of the result, finds nothing, and stringifies the object it got instead. The failure only appeared on *successful* fetches — errors still propagated correctly, which made it look like a language problem rather than a response-shape problem.

**2. Transcripts came back empty.**
The upstream dependency `youtube-captions-scraper` reads the caption `baseUrl` out of the watch-page HTML. YouTube now serves those URLs as **HTTP 200 with a zero-length body**, so the scraper parsed an empty document and produced an empty transcript with no error.

This fork resolves caption tracks through the InnerTube player API instead. Of the clients tested, only `IOS` both returns a working `baseUrl` and serves the legacy `<transcript>` XML format:

| InnerTube client | Result |
| --- | --- |
| `IOS` | works, legacy `<transcript>` XML |
| `ANDROID` | works, but word-level `srv3` format |
| `WEB` / `MWEB` | `playabilityStatus: UNPLAYABLE`, no tracks |
| `TVHTML5` | `playabilityStatus: ERROR`, no tracks |

Two smaller improvements came along with that:

- **Dependency-free caption handling.** `youtube-captions-scraper`, `he`, and `striptags` are all gone. The only remaining dependency is the MCP SDK itself.
- **Actionable language errors.** Asking for a language the video does not have now tells you what it *does* have:
  ```
  Could not find en captions for TjKwL_L8gic. Available: ar (Arabic (auto-generated))
  ```
  Previously this was a bare "Could not find en captions", which gave no hint that the video was captioned in another language.

## Requirements

Node.js 18 or newer (the server uses the global `fetch`).

## Install

```bash
git clone https://github.com/dahbimoad/mcp-youtube-transcript.git
cd mcp-youtube-transcript
npm install
```

## Use with Claude Code

```bash
claude mcp add youtube-transcript -s user -- node /absolute/path/to/mcp-youtube-transcript/src/index.js
```

## Use with Claude Desktop

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "youtube-transcript": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-youtube-transcript/src/index.js"]
    }
  }
}
```

## Tool

### `get_transcript`

| Parameter | Type | Description |
| --- | --- | --- |
| `url` | string | YouTube URL or bare 11-character video ID |
| `lang` | string | Language code, e.g. `en`, `ar`, `ko`. Defaults to `en`. |

Accepted URL forms: `https://www.youtube.com/watch?v=ID`, `https://youtu.be/ID` (tracking parameters such as `?si=` are ignored), or the bare ID.

Language matching falls back in this order: exact `languageCode`, then a manual track (`vssId` of `.xx`), then an auto-generated track (`a.xx`), then a regional variant (`ar` will match an `ar-MA` track). Note that this does not run in reverse — requesting `ar-MA` when the video only carries `ar` reports the mismatch rather than guessing.

## Notes and limitations

- Caption discovery relies on YouTube's internal InnerTube API, which is undocumented and can change without warning. If transcripts start coming back empty again, that is the first place to look.
- Only videos that already carry captions work. This server does not transcribe audio.
- Auto-generated captions are unpunctuated and can misrender proper nouns and dialect. They are a usable transcript, not a clean one.

## Credits

Original work by [Freddie (kimtaeyoon83)](https://github.com/kimtaeyoon83/mcp-server-youtube-transcript). Licensed MIT; see [LICENSE](LICENSE), which carries both the original and the modification copyright.