# YouTube Transcript Scraper – Download Subtitles & Captions (`harshmaur/youtube-transcript-scraper`) Actor

Extract transcripts, captions & subtitles from YouTube videos, channels or playlists — no API key. Timestamped or plain text, SRT/VTT export, 156-language translation, plus full video & channel metadata. Built for AI summaries, ChatGPT & research. Pay only for transcripts returned.

- **URL**: https://apify.com/harshmaur/youtube-transcript-scraper.md
- **Developed by:** [Harsh Maur](https://apify.com/harshmaur) (community)
- **Categories:** Videos, AI, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 3 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $4.00 / 1,000 successful results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## YouTube Transcript Scraper — Download Captions, Subtitles & Transcripts from Videos, Channels & Playlists (No API Key)

Pull the full **transcript** of any YouTube video — plus its **captions/subtitles**, metadata, and stats — as timestamped segments, plain text, or a ready-to-use **SRT/VTT** subtitle file. Feed it one video, a whole **channel**, or a **playlist**. No API key, no login, no Google account.

You pay **only for transcripts that are actually returned** — videos with no captions are reported back for free.

### What does the YouTube Transcript Scraper do? {#what-does-it-do}

#### ✅ No API key or login
No YouTube Data API quota, no OAuth, no cookies. Paste links and run.

#### 🎬 Videos, channels & playlists
One video, an `@handle`/channel (its recent uploads), or a full playlist — mix them in a single run.

#### 🌐 Translate into 156 languages
Get the transcript in the video's language, or auto-translate it into any of YouTube's 156 supported languages.

#### 📝 Timestamps, text, SRT & VTT
Choose timestamped segments, clean joined text, or a downloadable `.srt` / `.vtt` subtitle file.

#### 🤖 Auto-generated (ASR) + human captions
Works with creator-uploaded captions and YouTube's automatic speech-recognition subtitles.

#### 📊 Full video & channel metadata
Title, description, views, likes, comments, duration, publish date, thumbnail, channel name/ID/@handle, and subscriber count — on every result.

#### 🔄 Export anywhere
Download as JSON, CSV, Excel, or feed straight into Slack, Notion, Google Sheets, n8n, Zapier, Make, or an AI agent.

### How to get a YouTube transcript {#how-to-scrape}

1. Paste one or more YouTube **video** links into **Video URLs** (or an `@handle`/channel into **Channels**, or a **Playlist** link).
2. (Optional) Pick a **transcript language** and **format** (timestamps / text / SRT / VTT).
3. Click **Start** — transcripts and metadata land in the dataset, ready to export.

```json
{
  "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
  "channelUrls": ["@mkbhd"],
  "playlistUrls": [],
  "maxVideos": 50,
  "language": "en",
  "transcriptFormat": "both"
}
````

### What data you get from each video {#what-data}

- **Transcript** — `transcript` (array of `{ start, end, duration, text }`), `transcriptText` (joined plain text), and `srt` / `vtt` strings when you pick those formats.
- **Language** — `language`, `availableLanguages`, `isAutoGenerated`, `wasTranslated`.
- **Video** — `videoId`, `url`, `title`, `description`, `durationSeconds`, `viewCount`, `likeCount`, `commentCount`, `publishedAt`, `category`, `keywords`, `thumbnail`.
- **Channel** — `channelName`, `channelId`, `channelUrl`, `channelUsername` (@handle), `channelThumbnail`, `subscriberCount`.
- **Status** — `status` (`success`/`failed`) and an `errorCode` for videos that have no captions or aren't available.

### YouTube transcript use cases {#use-cases}

- **Summarize videos with ChatGPT, Claude or Gemini** — pull the transcript, drop it into an LLM, get the gist without watching.
- **AI training data & RAG** — build clean text corpora and search-augmentation indexes from video content.
- **Content repurposing** — turn videos into blog posts, newsletters, show notes, and social clips.
- **SEO & content audits** — mine a channel's spoken keywords and topics at scale.
- **Research & note-taking** — searchable text from lectures, talks, interviews, and podcasts.
- **Subtitles & localization** — export SRT/VTT and translate captions into other languages.
- **Market & sentiment analysis** — analyze what creators and competitors are actually saying.

### How to download a YouTube transcript to text {#video-to-text}

Set **Transcript format** to **Plain text** and paste your **Video URLs**. Each result's `transcriptText` is the full transcript as one clean string — paste-ready for an LLM, a doc, or a database.

### How to get transcripts for an entire YouTube channel {#channel}

Drop a channel URL or `@handle` into **Channels** and set **Max videos**. The scraper resolves the channel and pulls transcripts for its most recent uploads (paginating past the first page). Add several channels to batch them in one run.

### How to extract transcripts from a YouTube playlist {#playlist}

Paste a `youtube.com/playlist?list=…` link into **Playlists** and set **Max videos**. Every video in the playlist is transcribed. Tip: a channel's "uploads" playlist (`UU…` id) is an easy way to walk a back-catalog.

### How to translate YouTube subtitles into another language {#translate}

Set **Transcript language** to any ISO 639-1 code (`es`, `hi`, `ja`, `fr`, `de`, `pt`, …). If the video already has captions in that language we return them; otherwise YouTube auto-translates the transcript into it (156 languages). The `wasTranslated` field tells you which you got.

### How to export YouTube captions as SRT or VTT {#srt-vtt}

Set **Transcript format** to **SRT** or **VTT** and each result includes a ready-to-use subtitle-file string in the `srt` / `vtt` field — drop it straight into a video editor or re-upload it as captions.

### How to get YouTube transcripts for ChatGPT & AI agents {#ai}

Every result is structured JSON, so an AI agent can read it directly. Connect the actor over **MCP** (below) to pipe transcripts into Claude, ChatGPT, or your own agent, or schedule a channel and have each new video's transcript delivered automatically.

### Output example {#output-example}

```json
{
  "videoId": "dQw4w9WgXcQ",
  "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "title": "Rick Astley - Never Gonna Give You Up (Official Video)",
  "channelName": "Rick Astley",
  "channelUsername": "RickAstleyYT",
  "subscriberCount": 4510000,
  "publishedAt": "2009-10-25",
  "durationSeconds": 213,
  "viewCount": 1600000000,
  "likeCount": 19179747,
  "commentCount": 2400000,
  "language": "en",
  "isAutoGenerated": false,
  "wasTranslated": false,
  "availableLanguages": ["en", "de", "ja", "pt-BR", "es-419"],
  "transcript": [
    { "start": 18.64, "end": 21.88, "duration": 3.24, "text": "We're no strangers to love" }
  ],
  "transcriptText": "We're no strangers to love …",
  "thumbnail": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg",
  "status": "success"
}
```

### How much does it cost? {#pricing}

**$0.005 per transcript** ($5 per 1,000) — and you're charged **only when a transcript is actually returned**. Videos with no captions, or that are private/removed/age-restricted, come back as a free `failed` row, so you never pay for an empty result. Unlike scrapers that bill every input video, you don't pay for the ones YouTube has no transcript for. No per-run or start fee.

### Use with AI agents and MCP {#ai-mcp}

The actor speaks the **Model Context Protocol**, so Claude, ChatGPT, Cursor, and other agents can run it as a tool.

#### Push transcripts straight to Slack, Notion, or Sheets (no code) {#mcp-connectors}

Pick an authorized **MCP connector** in the input and every transcript is delivered to your app — Slack, Notion, Airtable, Google Sheets, and more. Your credentials stay in Apify; the actor never sees them. Schedule it on a channel and each new upload's transcript lands in your workspace automatically.

### Integrate with n8n, Zapier, and Make {#integrations}

Trigger runs and pull results from any automation platform via Apify's API and webhooks — wire transcripts into your own pipelines, sheets, or AI workflows.

### Support {#support}

Found a video that won't transcribe or want a new field? Open an issue from the actor's page — happy to help.

### FAQ {#faq}

#### Do I need a YouTube or Google API key?

No. There's no API key, login, OAuth, or cookies — just paste links.

#### Does every YouTube video have a transcript?

Only videos that are playable **and** have at least one caption track (creator-uploaded or auto-generated). That's a YouTube limitation, not the scraper's — and you're never charged for a video we can't transcribe.

#### Can I download transcripts for a whole channel or playlist?

Yes. Paste a channel URL/`@handle` or a playlist link and set **Max videos** — the scraper pulls transcripts for the channel's recent uploads or every video in the playlist.

#### Can I get the transcript in another language?

Yes — set **Transcript language** to any of 156 ISO 639-1 codes. We use the native caption track if it exists, otherwise YouTube auto-translates it.

#### Can I export SRT or VTT subtitle files?

Yes. Set **Transcript format** to **SRT** or **VTT** and the result includes a ready-to-use subtitle-file string.

#### Does it work with YouTube Shorts and auto-generated captions?

Yes to both — Shorts links work, and automatic (ASR) captions are returned when no manual ones exist (`isAutoGenerated` marks which).

#### How many transcripts can I scrape?

There's no hard cap — paste as many video URLs as you like, or scale via channels and playlists.

#### Can I use it with ChatGPT, Claude, or AI agents?

Yes — output is structured JSON and the actor is MCP-compatible, so agents can call it directly or receive transcripts through a connector.

#### Which export formats are supported?

JSON, CSV, Excel, HTML table, RSS, and direct delivery to Slack/Notion/Sheets via MCP.

#### How am I charged?

Per transcript actually delivered. No-caption or unavailable videos are free.

### Other Actors {#other-actors}

- [Reddit Scraper](https://apify.com/harshmaur/reddit-scraper) — posts, comments, subreddits, and user history.
- [Indeed Jobs Scraper](https://apify.com/harshmaur/indeed-scraper) — jobs with salary, company data, and full descriptions.
- [LinkedIn Jobs Scraper](https://apify.com/harshmaur/linkedin-jobs-scraper) — job listings via the public guest endpoints.
- [Facebook Ads Library Scraper](https://apify.com/harshmaur/facebook-ads-library-scraper) — ad creative, advertiser, and reach.

# Actor input Schema

## `videoUrls` (type: `array`):

Individual YouTube videos. Accepts watch links (youtube.com/watch?v=…), youtu.be/… short links, and Shorts links. One transcript per video.

## `channelUrls` (type: `array`):

Whole channels. Accepts @handles (e.g. @mkbhd), channel URLs (youtube.com/@handle, /channel/UC…, /c/Name). Fetches the channel's most recent videos — up to 'Max videos' below.

## `playlistUrls` (type: `array`):

Playlist links (youtube.com/playlist?list=…). Fetches each playlist's videos — up to 'Max videos' below.

## `maxVideos` (type: `integer`):

How many videos to fetch from EACH channel or playlist. Does NOT affect the Video URLs above (those are always fetched). Default 50.

## `dateFrom` (type: `string`):

Only fetch channel/playlist videos published on or after this date. Leave empty for no lower bound.

## `dateTo` (type: `string`):

Only fetch channel/playlist videos published on or before this date. Leave empty for no upper bound.

## `language` (type: `string`):

ISO 639-1 code (e.g. en, es, hi, ja, fr). If the video has captions in this language we use them; otherwise YouTube auto-translates the transcript into it (156 languages supported). Leave empty for the video's original language.

## `transcriptFormat` (type: `string`):

Shape of the transcript in each result. 'Both' gives the timestamped array AND joined plain text. SRT/VTT return a ready-to-use subtitle file string.

## `mcpConnector` (type: `string`):

Pick an authorized MCP connector (Slack, Notion, Airtable, Google Sheets, …) to receive the transcripts. Your credentials stay in Apify and are never exposed to this actor (Apify's proxy injects them). Leave empty to scrape only. Tip: schedule this on a channel to auto-capture every new video's transcript into your workspace.

## `mcpMode` (type: `string`):

perPost: one message/record per video transcript. summary: a single digest of the whole run.

## `mcpTarget` (type: `string`):

Where to write — the destination ID the tool needs: a Notion database/page ID, a Google Sheet ID, or a Slack channel. Leave blank for connectors that post to a default location. Advanced shapes go in Arguments JSON below.

## `mcpMessage` (type: `string`):

Template for each message. Use {{field}} placeholders from ANY transcript field — common ones: {{title}}, {{channelName}}, {{url}}, {{publishedAt}}, {{viewCount}}, {{language}}, {{transcriptText}}, {{transcriptSnippet}} (first 280 chars). Missing fields render empty.

## `mcpTool` (type: `string`):

Force a specific tool name on the connector (e.g. send\_message, create\_page, append\_row). Leave empty to auto-detect the connector's write/notify tool.

## `mcpArguments` (type: `object`):

Extra/override arguments merged into each tool call as JSON — e.g. {"channel": "#yt-transcripts"} for Slack. {{field}} placeholders work inside string values too, so you can nest live data into any shape — e.g. Notion: {"properties": {"Title": {"title": \[{"text": {"content": "{{title}}"}}]}, "Link": {"url": "{{url}}"}}}.

## `mcpMaxItems` (type: `integer`):

Safety cap on how many transcripts are piped to the connector per run (perPost mode). Protects against flooding the destination.

## `mcpServerUrl` (type: `string`):

Advanced/testing only. Connect directly to a raw MCP server URL, bypassing the connector above. For real use prefer a connector — your credentials then stay in Apify. When set, this overrides the connector.

## `mcpServerToken` (type: `string`):

Bearer token for the dev MCP server URL above. A token entered here IS visible to the actor at runtime — for production use an MCP Connector instead. Ignored unless the URL is set.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "maxVideos": 50,
  "transcriptFormat": "both",
  "mcpMode": "perPost",
  "mcpMessage": "*{{title}}* — {{channelName}}\n{{url}}",
  "mcpMaxItems": 50
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped transcripts.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "videoUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ],
    "maxVideos": 50,
    "transcriptFormat": "both",
    "mcpMode": "perPost",
    "mcpMessage": `*{{title}}* — {{channelName}}
{{url}}`,
    "mcpMaxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("harshmaur/youtube-transcript-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "maxVideos": 50,
    "transcriptFormat": "both",
    "mcpMode": "perPost",
    "mcpMessage": """*{{title}}* — {{channelName}}
{{url}}""",
    "mcpMaxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("harshmaur/youtube-transcript-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "maxVideos": 50,
  "transcriptFormat": "both",
  "mcpMode": "perPost",
  "mcpMessage": "*{{title}}* — {{channelName}}\\n{{url}}",
  "mcpMaxItems": 50
}' |
apify call harshmaur/youtube-transcript-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=harshmaur/youtube-transcript-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "YouTube Transcript Scraper – Download Subtitles & Captions",
        "description": "Extract transcripts, captions & subtitles from YouTube videos, channels or playlists — no API key. Timestamped or plain text, SRT/VTT export, 156-language translation, plus full video & channel metadata. Built for AI summaries, ChatGPT & research. Pay only for transcripts returned.",
        "version": "0.0",
        "x-build-id": "FeeD6oFS60T94M3LA"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/harshmaur~youtube-transcript-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-harshmaur-youtube-transcript-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/harshmaur~youtube-transcript-scraper/runs": {
            "post": {
                "operationId": "runs-sync-harshmaur-youtube-transcript-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/harshmaur~youtube-transcript-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-harshmaur-youtube-transcript-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "videoUrls": {
                        "title": "🎬 Video URLs",
                        "type": "array",
                        "description": "Individual YouTube videos. Accepts watch links (youtube.com/watch?v=…), youtu.be/… short links, and Shorts links. One transcript per video.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "channelUrls": {
                        "title": "📺 Channels / @handles",
                        "type": "array",
                        "description": "Whole channels. Accepts @handles (e.g. @mkbhd), channel URLs (youtube.com/@handle, /channel/UC…, /c/Name). Fetches the channel's most recent videos — up to 'Max videos' below.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "playlistUrls": {
                        "title": "🎵 Playlists",
                        "type": "array",
                        "description": "Playlist links (youtube.com/playlist?list=…). Fetches each playlist's videos — up to 'Max videos' below.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxVideos": {
                        "title": "#️⃣ Max videos per channel / playlist",
                        "minimum": 1,
                        "type": "integer",
                        "description": "How many videos to fetch from EACH channel or playlist. Does NOT affect the Video URLs above (those are always fetched). Default 50.",
                        "default": 50
                    },
                    "dateFrom": {
                        "title": "📅 Published after",
                        "type": "string",
                        "description": "Only fetch channel/playlist videos published on or after this date. Leave empty for no lower bound."
                    },
                    "dateTo": {
                        "title": "📅 Published before",
                        "type": "string",
                        "description": "Only fetch channel/playlist videos published on or before this date. Leave empty for no upper bound."
                    },
                    "language": {
                        "title": "🌐 Transcript language",
                        "type": "string",
                        "description": "ISO 639-1 code (e.g. en, es, hi, ja, fr). If the video has captions in this language we use them; otherwise YouTube auto-translates the transcript into it (156 languages supported). Leave empty for the video's original language."
                    },
                    "transcriptFormat": {
                        "title": "📝 Transcript format",
                        "enum": [
                            "both",
                            "segments",
                            "text",
                            "srt",
                            "vtt"
                        ],
                        "type": "string",
                        "description": "Shape of the transcript in each result. 'Both' gives the timestamped array AND joined plain text. SRT/VTT return a ready-to-use subtitle file string.",
                        "default": "both"
                    },
                    "mcpConnector": {
                        "title": "Send results to an app (MCP connector)",
                        "type": "string",
                        "description": "Pick an authorized MCP connector (Slack, Notion, Airtable, Google Sheets, …) to receive the transcripts. Your credentials stay in Apify and are never exposed to this actor (Apify's proxy injects them). Leave empty to scrape only. Tip: schedule this on a channel to auto-capture every new video's transcript into your workspace."
                    },
                    "mcpMode": {
                        "title": "Delivery mode",
                        "enum": [
                            "perPost",
                            "summary"
                        ],
                        "type": "string",
                        "description": "perPost: one message/record per video transcript. summary: a single digest of the whole run.",
                        "default": "perPost"
                    },
                    "mcpTarget": {
                        "title": "Target page / database / channel",
                        "type": "string",
                        "description": "Where to write — the destination ID the tool needs: a Notion database/page ID, a Google Sheet ID, or a Slack channel. Leave blank for connectors that post to a default location. Advanced shapes go in Arguments JSON below."
                    },
                    "mcpMessage": {
                        "title": "Message template",
                        "type": "string",
                        "description": "Template for each message. Use {{field}} placeholders from ANY transcript field — common ones: {{title}}, {{channelName}}, {{url}}, {{publishedAt}}, {{viewCount}}, {{language}}, {{transcriptText}}, {{transcriptSnippet}} (first 280 chars). Missing fields render empty.",
                        "default": "*{{title}}* — {{channelName}}\n{{url}}"
                    },
                    "mcpTool": {
                        "title": "Tool override (advanced)",
                        "type": "string",
                        "description": "Force a specific tool name on the connector (e.g. send_message, create_page, append_row). Leave empty to auto-detect the connector's write/notify tool."
                    },
                    "mcpArguments": {
                        "title": "Tool arguments override (advanced)",
                        "type": "object",
                        "description": "Extra/override arguments merged into each tool call as JSON — e.g. {\"channel\": \"#yt-transcripts\"} for Slack. {{field}} placeholders work inside string values too, so you can nest live data into any shape — e.g. Notion: {\"properties\": {\"Title\": {\"title\": [{\"text\": {\"content\": \"{{title}}\"}}]}, \"Link\": {\"url\": \"{{url}}\"}}}."
                    },
                    "mcpMaxItems": {
                        "title": "Max transcripts to send",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Safety cap on how many transcripts are piped to the connector per run (perPost mode). Protects against flooding the destination.",
                        "default": 50
                    },
                    "mcpServerUrl": {
                        "title": "MCP server URL (dev / diagnostic)",
                        "type": "string",
                        "description": "Advanced/testing only. Connect directly to a raw MCP server URL, bypassing the connector above. For real use prefer a connector — your credentials then stay in Apify. When set, this overrides the connector."
                    },
                    "mcpServerToken": {
                        "title": "MCP server token (dev / diagnostic)",
                        "type": "string",
                        "description": "Bearer token for the dev MCP server URL above. A token entered here IS visible to the actor at runtime — for production use an MCP Connector instead. Ignored unless the URL is set."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
