How do I connect TubeTranscript to AI agents with the Model Context Protocol?
By TubeTranscript · Content updated
View as MarkdownTubeTranscript runs two stateless remote MCP servers over Streamable HTTP: /api/mcp fetches YouTube transcripts and /api/mcp/tools turns them into hooks, mindmaps and blog drafts. Register both in Cursor, Claude Code, Windsurf or n8n with the same Pro plan API key. Captioned videos return in seconds via the Tier-1 Fast Path; videos without captions are transcribed from audio.
To fetch transcripts from scripts or n8n HTTP nodes instead of an agent, use the REST API with the same key.
| Server | URL | Tools |
|---|---|---|
| Transcript | https://tubetranscript.io/api/mcp |
get_transcript |
| AI tools | https://tubetranscript.io/api/mcp/tools |
extract_hooks, create_mindmap, generate_brand_voice_blog |
Which MCP tools does TubeTranscript expose?
get_transcript fetches a video and stores its transcript as a job owned by your Pro team, then returns the transcript and that job's job_id. The AI tools take that job_id, read the job's transcript and generate output with Google Gemini. They never fetch or transcribe videos themselves.
| Tool | Server | Input | Output (structuredContent) |
|---|---|---|---|
get_transcript |
/api/mcp |
video_url or video_id |
{ "video_id", "status", "job_id", "transcript" } |
extract_hooks |
/api/mcp/tools |
job_id |
{ "hooks": [{ "start_time", "end_time", "hook_title", "summary" }] }, max 10 |
create_mindmap |
/api/mcp/tools |
job_id |
{ "mermaid": "<Mermaid mindmap source>" } |
generate_brand_voice_blog |
/api/mcp/tools |
job_id, brand_voice_id (UUID) |
{ "blog": "<Markdown>" } |
generate_chapters |
/api/mcp/tools |
job_id, style, count |
{ "chapters": [{ "start", "clock", "title" }], "text" } |
generate_description |
/api/mcp/tools |
job_id, tone, cta, chapters |
{ "description", "tags", "hashtags", "chars" } |
find_moments |
/api/mcp/tools |
job_id, length |
{ "moments": [{ "start", "end", "hook", "reason", "quote" }] } |
analyze_hook |
/api/mcp/tools |
job_id, topic |
{ "opening", "hookType", "parts", "pace", "rewrites" } |
translate_subtitles |
/api/mcp/tools |
job_id, target_languages, format, glossary |
{ "outputs": [{ "language", "text" }], "failed" } |
The five creator tools (generate_chapters to translate_subtitles) take the same options as the REST creator endpoint and follow its limits: one creator-tool AI run each (30 per hour per team, one per language for translations), charged only when a result is returned.
The typical agent workflow takes two or three calls:
- Call
get_transcriptwith the video URL or ID. - If
statusis"processing", wait about 60 seconds and callget_transcriptagain with the same video untilstatusis"completed". - Pass the returned
job_idto any AI tool, such asextract_hooks,generate_chaptersortranslate_subtitles.
What does get_transcript return?
get_transcript accepts video_url (any YouTube URL, max 2,048 characters) or video_id (the 11-character YouTube ID), or both if they match. It returns structuredContent with four fields, plus text content blocks for clients without structured-content support: the transcript as clean plain text (one paragraph per caption chunk, no timestamps, normalized for RAG), then a job_id: … line. For timed chunks, call the REST endpoint POST /api/v1/extract instead.
{ "name": "get_transcript", "arguments": { "video_url": "https://www.youtube.com/watch?v=jNQXAC9IVRw" } }
{
"video_id": "jNQXAC9IVRw",
"status": "completed",
"job_id": "71d2b675-3bc5-48a8-8b10-7e2b7f7f0011",
"transcript": "First paragraph of the transcript…
Second paragraph…"
}
| Field | Type | Description |
|---|---|---|
video_id |
string | The 11-character YouTube ID. |
status |
string | completed, or processing while a video without captions is transcribed from audio. |
job_id |
string | null | Team job holding the transcript; input for the AI tools. null only if storing the job failed. |
transcript |
string | Plain-text transcript; empty while status is processing. |
What happens when I call get_transcript for the same video again?
Repeat calls are cheap and safe. TubeTranscript resolves the video in this order:
| Situation | status |
job_id |
|---|---|---|
| Your team already has a completed job for the video | completed |
That job; the same job_id on every call |
| Another user published a public transcript of the video | completed |
A new private copy in your team |
| Your team's audio transcription is still running | processing |
That job, so no second transcription is started |
| The video has captions | completed |
A new job holding the captions |
| The video has no captions | processing |
A new audio transcription job |
Two calls for the same new video that arrive at the same time fetch the captions once but each store their own job, so they return different job_ids with the same transcript; without captions they share one audio job. If an audio transcription fails, the next call starts a new one. A worker outage returns isError: true with a plain-text message; retry later.
When can I call the AI tools?
Call them with a job_id whose status was "completed": one returned by get_transcript, or the ID of a job created in the web app, or a non-null data.job_id from POST /api/v1/extract. The job must belong to the API key's team; a video ID or URL in place of job_id is rejected as an invalid argument. Each result is stored per job: calling a tool again with the same job_id returns the stored result without calling the model (a blog is regenerated when another Brand Voice profile is used or the profile text changed). Outputs are returned as structuredContent plus a JSON text block.
| Tool | Behavior on thin source material |
|---|---|
extract_hooks |
Empty hooks array (not an error). |
create_mindmap |
Root node states that the source information is insufficient. |
generate_brand_voice_blog |
Empty blog string. |
How are invalid arguments and server errors reported?
Both servers validate tools/call arguments before any quota is spent. A call with missing, mistyped or unknown arguments, or an unknown tool name, returns HTTP 400 with JSON-RPC error -32602; error.data.issues lists each problem (path and message) so an agent can correct the call and retry.
{ "jsonrpc": "2.0", "id": 1, "error": { "code": -32602, "message": "Invalid arguments for tool extract_hooks: job_id: Required", "data": { "code": "INVALID_ARGUMENTS", "tool": "extract_hooks", "issues": [{ "code": "invalid_type", "expected": "string", "received": "undefined", "path": ["job_id"], "message": "Required" }], "formErrors": [], "fieldErrors": { "job_id": ["Required"] } } } }
A tool that runs but cannot complete returns HTTP 200 with result.isError: true and a JSON text block { "error": "<CODE>", "message": "…" }, so always check isError:
error |
Meaning |
|---|---|
JOB_NOT_FOUND |
Unknown job_id, or a job of another team. |
JOB_NOT_READY |
Still being transcribed; call get_transcript again until status is completed. |
INVALID_TRANSCRIPT |
The job has no usable timed transcript, or it is too long. |
BRAND_VOICE_NOT_FOUND |
brand_voice_id is not a saved profile of your team. |
INVALID_BRAND_VOICE |
The profile text is empty or longer than 20,000 characters. |
AI_TIMEOUT and other AI_* codes |
Model or validation failure; retry later and do not use partial output. |
An unexpected server failure returns HTTP 500 with a fixed JSON body and is safe to retry later.
{ "error": true, "message": "Internal Server Error", "code": "MCP_CRASH" }
How do I add TubeTranscript to Claude Code?
Register the server with the Claude Code CLI using claude mcp add --transport http, the server URL, and an Authorization header carrying your Pro API key. Add the AI tools server the same way under a second name. Run claude mcp list afterwards to confirm both servers connect. Tools are loaded when a session starts, so open a new Claude Code session after adding the servers.
- Export your key as
TUBETRANSCRIPT_API_KEY(see Quickstart). - Run the first
claude mcp addcommand below to registertubetranscript. - Run the second
claude mcp addcommand below to registertubetranscript-ai. - Run
claude mcp list. - Confirm that both servers are listed as connected.
- Start a new session so the agent can see
get_transcriptand the AI tools.
claude mcp add --transport http tubetranscript https://tubetranscript.io/api/mcp \
--header "Authorization: Bearer $TUBETRANSCRIPT_API_KEY"
claude mcp add --transport http tubetranscript-ai https://tubetranscript.io/api/mcp/tools \
--header "Authorization: Bearer $TUBETRANSCRIPT_API_KEY"
How do I add TubeTranscript to Cursor?
Add both servers to .cursor/mcp.json in the project, or ~/.cursor/mcp.json for every project, under mcpServers. Each entry needs a url and a headers object with Authorization: Bearer <API_KEY>. Cursor detects the Streamable HTTP transport from the URL. Keep the file out of version control because it contains the key.
- Create
.cursor/mcp.jsonin the project root (or~/.cursor/mcp.jsonfor all projects). - Paste the JSON below into the file.
- Replace both
tt_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXplaceholders with your API key. - Save the file.
- Add
.cursor/mcp.jsonto.gitignore. - Confirm that
tubetranscriptandtubetranscript-aiappear in Cursor's MCP settings.
{
"mcpServers": {
"tubetranscript": {
"url": "https://tubetranscript.io/api/mcp",
"headers": { "Authorization": "Bearer tt_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
},
"tubetranscript-ai": {
"url": "https://tubetranscript.io/api/mcp/tools",
"headers": { "Authorization": "Bearer tt_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
}
}
}
How do I add TubeTranscript to Windsurf?
Add both servers to ~/.codeium/windsurf/mcp_config.json under mcpServers. Windsurf uses serverUrl for remote servers and a headers object for the Authorization: Bearer <API_KEY> header. After saving the file, refresh the MCP server list in Cascade so the get_transcript and AI tools appear before prompting the agent.
- Open
~/.codeium/windsurf/mcp_config.json. - Paste the JSON below into the file.
- Replace both
tt_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXplaceholders with your API key. - Save the file.
- Refresh the MCP server list in Cascade.
- Confirm that
get_transcriptand the AI tools appear in the tool list.
{
"mcpServers": {
"tubetranscript": {
"serverUrl": "https://tubetranscript.io/api/mcp",
"headers": { "Authorization": "Bearer tt_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
},
"tubetranscript-ai": {
"serverUrl": "https://tubetranscript.io/api/mcp/tools",
"headers": { "Authorization": "Bearer tt_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
}
}
}
How do I use TubeTranscript in n8n?
Add an MCP Client Tool node to an AI Agent workflow. Set the endpoint to https://tubetranscript.io/api/mcp, the server transport to HTTP Streamable, and authentication to Bearer Auth with your Pro API key as the token. For single-step automations without an agent, call POST /api/v1/extract from an HTTP Request node.
- Open a workflow that contains an AI Agent node.
- Add an MCP Client Tool node to the agent's tool input.
- Set Endpoint to
https://tubetranscript.io/api/mcp. - Set Server Transport to HTTP Streamable.
- Set Authentication to Bearer Auth.
- Create a Bearer credential whose token is your
tt_live_…API key. - Save the workflow.
- Repeat steps 2–7 with endpoint
https://tubetranscript.io/api/mcp/toolsto add the AI tools; the agent needs both, because the AI tools take thejob_idthatget_transcriptreturns.
| n8n field | Value |
|---|---|
| Endpoint | https://tubetranscript.io/api/mcp (or /api/mcp/tools) |
| Server Transport | HTTP Streamable |
| Authentication | Bearer Auth |
| Credential token | Your tt_live_… API key |
How are MCP requests authenticated and rate limited?
Every MCP request needs Authorization: Bearer <API_KEY> from a Pro team; otherwise the server returns 402 Payment Required with a machine-readable invoice. Protocol handshakes (initialize, tools/list, ping) are free. Each tools/call counts once against the 1,000 requests per 24 hours limit shared with the REST API key, including a get_transcript call that returns processing. The guest limit of 10 transcripts per IP does not apply to the MCP servers. Details: Security & Rate Limits.
| Condition | Response |
|---|---|
GET or DELETE on the server URL |
405 METHOD_NOT_ALLOWED (stateless, no SSE stream) |
| Missing key | 402, reason: MISSING_API_KEY |
| Unknown or revoked key | 402, reason: INVALID_API_KEY |
| Team not on Pro | 402, reason: PLAN_UPGRADE_REQUIRED |
Limit exceeded on tools/call |
402, reason: RATE_LIMIT_EXCEEDED, Retry-After |
Quota store unreachable on tools/call |
503 RATE_LIMIT_UNAVAILABLE with Retry-After: 60 |
The 402 body differs by the reason field and the invoice. A caller without a usable Pro key is invoiced the Pro plan (shown below). A Pro key that used up its daily quota is invoiced a top-up instead: amount: 2.0, description: "TubeTranscript Overage Top-up - 500 additional requests". An exhausted quota also resets on its own after Retry-After seconds.
{
"error": "Payment Required",
"code": "M2M_INSUFFICIENT_FUNDS",
"message": "Your agent has exhausted its quota or requires a Pro API key to execute this tool.",
"reason": "MISSING_API_KEY",
"payment_protocols_supported": ["stripe_metered", "crypto_x402"],
"invoice": {
"amount": 9.0,
"currency": "USD",
"description": "TubeTranscript Pro Tier - 1,000 requests/day",
"payment_url": "https://tubetranscript.io/billing/agent-checkout",
"crypto_wallet_mock": "DOGE: D8vxyz... (For future implementation)"
}
}
| MCP method | Counts against quota |
|---|---|
initialize |
No |
tools/list |
No |
ping |
No |
tools/call |
Yes, once per call |