# YouTube MCP Server > **YouTube MCP Server** is a hosted, multitenant Model Context Protocol (MCP) server run by **MewCP** (https://mewcp.com), giving AI agents managed access to YouTube. > > MewCP takes care of all MCP infrastructure for you — credential storage, OAuth flows, > token refresh, and production-grade auto-scaling — so your AI agents can connect to > third-party services and run freely without you managing any MCP server yourself. > > To connect your agent to this server you need a MewCP account and two values: > - MEWCP_KEY — your personal API key (dashboard → Developer) > - CREDENTIAL_ID — the stored credential MewCP securely injects per request > > Server page: https://mewcp.com/mcp/youtube > MewCP docs: https://docs.mewcp.com > Full catalog: https://mewcp.com/llms.txt ## About Manage YouTube content including videos, channels, playlists and creator operations. Search content, organize media, publish updates and interact with YouTube resources programmatically. ## How to connect Server Page URL: https://mewcp.com/mcp/youtube Gateway URL: https://gateway.mewcp.com/youtube/mcp Every request to this server requires two headers: Authorization: Bearer — your MewCP API key (dashboard → Developer) x-mewcp-credential-id: — the stored credential ID for this service All connection snippets and ready-to-use code examples are available on the server page and in this document below. --- ## Server documentation **Your YouTube, fully accessible through AI.** A Model Context Protocol (MCP) server that exposes YouTube's API for searching videos, managing playlists, reading channel data, posting comments, and more. ## Overview The MewCP YouTube MCP Server provides authenticated access to the YouTube Data API v3: - Search and retrieve videos, channel data, and comments - Manage playlists: create, browse, and add videos - Interact with content: rate videos, post comments, subscribe to channels Perfect for: - Building AI assistants that can search and analyze YouTube content - Automating YouTube channel management tasks - Integrating YouTube data into workflows and dashboards ## Tools
get_my_channel — Get the authenticated user's YouTube channel info Get information about the authenticated user's YouTube channel. Returns snippet, contentDetails, and statistics for the channel. **Inputs:** ``` (no parameters) ``` **Output `data` schema:** ```typescript { kind: string | null; etag: string | null; nextPageToken: string | null; prevPageToken: string | null; items: object[] | null; pageInfo: object | null; } ```
get_my_playlists — Get playlists from the authenticated user's channel Get playlists from the authenticated user's channel. Returns snippet and contentDetails for each playlist. **Inputs:** ``` - `max_results` (int, optional, default: 25) — Maximum playlists to return (capped at 50). Defaults to 25. ``` **Output `data` schema:** ```typescript { kind: string | null; etag: string | null; nextPageToken: string | null; prevPageToken: string | null; items: object[] | null; pageInfo: object | null; } ```
get_my_subscriptions — Get the authenticated user's channel subscriptions Get the authenticated user's channel subscriptions. Returns snippet and contentDetails for each subscription. **Inputs:** ``` - `max_results` (int, optional, default: 25) — Maximum subscriptions to return (capped at 50). Defaults to 25. ``` **Output `data` schema:** ```typescript { kind: string | null; etag: string | null; nextPageToken: string | null; prevPageToken: string | null; items: object[] | null; pageInfo: object | null; } ```
get_my_activities — Get recent activities on the authenticated user's channel Get recent activities on the authenticated user's channel. Returns snippet and contentDetails for each activity. **Inputs:** ``` - `max_results` (int, optional, default: 25) — Maximum activities to return (capped at 50). Defaults to 25. ``` **Output `data` schema:** ```typescript { kind: string | null; etag: string | null; nextPageToken: string | null; prevPageToken: string | null; items: object[] | null; pageInfo: object | null; } ```
subscribe_to_channel — Subscribe to a YouTube channel Subscribe to a YouTube channel. Returns the created subscription resource including snippet details. **Inputs:** ``` - `channel_id` (str, required) — Channel ID to subscribe to. Required. ``` **Output `data` schema:** ```typescript { kind: string | null; etag: string | null; id: string | null; snippet: object | null; contentDetails: object | null; statistics: object | null; status: object | null; } ```
search_videos — Search for videos on YouTube Search for videos on YouTube. **Inputs:** ``` - `query` (str, required) — Search query text. Required. - `max_results` (int, optional, default: 10) — Maximum videos to return (capped at 50). Defaults to 10. - `order` (str, optional, default: "relevance") — Sort order. Common values: `relevance`, `date`, `rating`, `title`, `videoCount`, `viewCount`. Defaults to `relevance`. ``` **Output `data` schema:** ```typescript { kind: string | null; etag: string | null; nextPageToken: string | null; prevPageToken: string | null; items: object[] | null; pageInfo: object | null; } ```
get_video_details — Get detailed information about a specific video Get detailed information about a specific video by ID. **Inputs:** ``` - `video_id` (str, required) — YouTube video ID. Required. ``` **Output `data` schema:** ```typescript { kind: string | null; etag: string | null; nextPageToken: string | null; prevPageToken: string | null; items: object[] | null; pageInfo: object | null; } ```
get_channel_videos — Get videos from a specific channel Get videos from a specific channel. **Inputs:** ``` - `channel_id` (str, required) — YouTube channel ID. Required. - `max_results` (int, optional, default: 25) — Maximum videos to return (capped at 50). Defaults to 25. ``` **Output `data` schema:** ```typescript { kind: string | null; etag: string | null; nextPageToken: string | null; prevPageToken: string | null; items: object[] | null; pageInfo: object | null; } ```
get_video_comments — Get comments for a specific video Get comments for a specific video. **Inputs:** ``` - `video_id` (str, required) — YouTube video ID. Required. - `max_results` (int, optional, default: 20) — Maximum comments to return (capped at 100). Defaults to 20. - `order` (str, optional, default: "relevance") — Comment order. Supported values: `relevance`, `time`. Defaults to `relevance`. ``` **Output `data` schema:** ```typescript { kind: string | null; etag: string | null; nextPageToken: string | null; prevPageToken: string | null; items: object[] | null; pageInfo: object | null; } ```
post_comment — Post a comment on a video Post a comment on a video. **Inputs:** ``` - `video_id` (str, required) — YouTube video ID. Required. - `text` (str, required) — Comment text content. Required. ``` **Output `data` schema:** ```typescript { kind: string | null; etag: string | null; id: string | null; snippet: object | null; contentDetails: object | null; statistics: object | null; status: object | null; } ```
rate_video — Rate a video (like or dislike) Rate a video (like or dislike). **Inputs:** ``` - `video_id` (str, required) — YouTube video ID. Required. - `rating` ("like" | "dislike" | "none", required) — Rating value: `like`, `dislike`, or `none` (removes rating). Required. ``` **Output `data` schema:** ```typescript { message: string; } ```
get_video_transcript — Fetch the transcript (captions) for a YouTube video Fetch the transcript (captions) for a YouTube video as plain text and individual timed segments. Uses auto-generated or manually created captions. Specify preferred languages in priority order; falls back to the first available if none match. **Inputs:** ``` - `video_id` (str, required) — YouTube video ID. Required. - `languages` (list[str], optional, default: null) — Preferred language codes in priority order (e.g. ['en', 'fr']). Omit to use the video's default language. ``` **Output `data` schema:** ```typescript { video_id: string; language: string; is_generated: boolean; segments: { text: string; start: number; duration: number; }[]; full_text: string; } ```
list_video_transcripts — List all available transcript tracks for a YouTube video List all available transcript tracks for a YouTube video, including language, language code, whether the track is auto-generated, and whether it can be translated. Use this before get_video_transcript to discover available languages. **Inputs:** ``` - `video_id` (str, required) — YouTube video ID. Required. ``` **Output `data` schema:** ```typescript { video_id: string; tracks: { language: string; language_code: string; is_generated: boolean; is_translatable: boolean; }[]; } ```
get_playlist_items — Get videos from a specific playlist Get videos from a specific playlist. **Inputs:** ``` - `playlist_id` (str, required) — YouTube playlist ID. Required. - `max_results` (int, optional, default: 50) — Maximum items to return (capped at 50). Defaults to 50. ``` **Output `data` schema:** ```typescript { kind: string | null; etag: string | null; nextPageToken: string | null; prevPageToken: string | null; items: object[] | null; pageInfo: object | null; } ```
create_playlist — Create a new playlist on the authenticated user's channel Create a new playlist on the authenticated user's channel. **Inputs:** ``` - `title` (str, required) — Playlist title. Required. - `description` (str, optional, default: "") — Optional playlist description. Defaults to empty string. - `privacy_status` (str, optional, default: "private") — Privacy setting. Common values: `private`, `public`, `unlisted`. Defaults to `private`. ``` **Output `data` schema:** ```typescript { kind: string | null; etag: string | null; id: string | null; snippet: object | null; contentDetails: object | null; statistics: object | null; status: object | null; } ```
add_video_to_playlist — Add a video to a playlist Add a video to a playlist. **Inputs:** ``` - `playlist_id` (str, required) — Target playlist ID. Required. - `video_id` (str, required) — Video ID to insert. Required. ``` **Output `data` schema:** ```typescript { kind: string | null; etag: string | null; id: string | null; snippet: object | null; contentDetails: object | null; statistics: object | null; status: object | null; } ```
## API Parameters Reference
Response Envelope Every tool returns the same top-level envelope. Only `data` varies per tool. ```json // Success { "success": true, "statusCode": 200, "retriable": false, "retry_after_seconds": null, "error": null, "data": { ... } } // Error { "success": false, "statusCode": 400, "retriable": false, "retry_after_seconds": null, "error": { "code": "ERROR_CODE", "message": "description", "details": {} }, "data": null } ``` - `retriable` — `true` when it is safe to retry (rate limit, network error, 503). `false` for validation and auth errors. - `retry_after_seconds` — seconds to wait before retrying; present only when `retriable` is `true` and the upstream specifies a delay. - `error.code` — machine-readable string: `VALIDATION_ERROR`, `AUTH_ERROR`, `UPSTREAM_ERROR`, `SERVER_ERROR`.
Common Parameters - `max_results` — Controls the number of items returned. Always capped at the YouTube API maximum for the given endpoint (50 for most resources, 100 for comments). - `order` — Controls result ordering. Supported values vary by tool; see each tool's parameter description for the accepted values.
Resource Formats **Video ID:** ``` 11-character alphanumeric string Example: dQw4w9WgXcQ ``` **Channel ID:** ``` Starts with "UC" followed by 22 characters Example: UCq-Fj5jknLsUf-MWSy4_brA ``` **Playlist ID:** ``` Starts with "PL" followed by alphanumeric characters Example: PLbpi6ZahtOH6Ar_3GPy3workbp73xONIf ```
## Troubleshooting
Missing or Invalid Headers - **Cause:** OAuth token not provided in request headers or incorrect format - **Solution:** 1. Verify `Authorization: Bearer YOUR_OAUTH_TOKEN` and `X-Mewcp-Credential-Id: CREDENTIAL-ID` headers are present 2. Check that your OAuth credential is active in your MewCP account
Insufficient Credits - **Cause:** API calls have exceeded your request limits - **Solution:** 1. Check credit usage in your Curious Layer dashboard 2. Upgrade to a paid plan or add credits for higher limits 3. Contact support for credit adjustments
Credential Not Connected - **Cause:** No YouTube credential linked to your account - **Solution:** 1. Go to **Credentials** in your MewCP dashboard 2. Connect your Google/YouTube account via OAuth 3. Retry the request with the correct `X-Mewcp-Credential-Id` header
Malformed Request Payload - **Cause:** JSON payload is invalid or missing required fields - **Solution:** 1. Validate JSON syntax before sending 2. Ensure all required tool parameters are included 3. Check parameter types match expected values
Server Not Found - **Cause:** Incorrect server name in the API endpoint - **Solution:** 1. Verify endpoint format: `{server-name}/mcp/{tool-name}` 2. Use correct server name from documentation 3. Check available servers in your Curious Layer account
YouTube API Error - **Cause:** Upstream YouTube Data API returned an error - **Solution:** 1. Check YouTube service status at [Google Workspace Status](https://www.google.com/appsstatus) 2. Verify your OAuth credential has the required YouTube scopes 3. Review the error message for specific details
---
Resources - **[YouTube Data API Documentation](https://developers.google.com/youtube/v3/docs)** — Official API reference - **[YouTube Data API Reference](https://developers.google.com/youtube/v3/docs/videos/list)** — Complete endpoint reference - **[FastMCP Docs](https://gofastmcp.com/v2/getting-started/welcome)** — FastMCP specification - **[FastMCP Credentials](https://pypi.org/project/fastmcp-credentials/)** — FastMCP Credentials package for credential handling
--- ## Connection snippets ### Python (fastmcp) ```python import asyncio from fastmcp import Client from fastmcp.client.transports import StreamableHttpTransport SERVER_URL = "https://gateway.mewcp.com/youtube/mcp" MEWCP_KEY = "YOUR_MEWCP_KEY" CREDENTIAL_ID = "YOUR_CREDENTIAL_ID" transport = StreamableHttpTransport( url=SERVER_URL, headers={ "Authorization": f"Bearer {MEWCP_KEY}", "x-mewcp-credential-id": CREDENTIAL_ID, } ) async def main(): client = Client(transport) async with client: await client.ping() tools = await client.list_tools() resources = await client.list_resources() prompts = await client.list_prompts() # Change the tool name and arguments with actual tool and arguments available in server result = await client.call_tool("example_tool", {"param": "value"}) print(result) asyncio.run(main()) ``` ### TypeScript (MCP SDK) ```typescript import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; const SERVER_URL = "https://gateway.mewcp.com/youtube/mcp"; const MEWCP_KEY = "YOUR_MEWCP_KEY"; const CREDENTIAL_ID = "YOUR_CREDENTIAL_ID"; const transport = new StreamableHTTPClientTransport(new URL(SERVER_URL), { requestInit: { headers: { Authorization: `Bearer ${MEWCP_KEY}`, "x-mewcp-credential-id": CREDENTIAL_ID, }, }, }); const client = new Client({ name: "mewcp-client", version: "1.0.0", }); await client.connect(transport); const tools = await client.listTools(); console.log("Available tools:", tools.tools.map(t => t.name)); // Change the tool name and arguments to a tool available on your server const result = await client.callTool({ name: "example_tool", arguments: { param: "value" }, }); console.log("Tool result:", result); ``` ### VS Code (settings.json) ```json { "servers": { "mewcp-youtube": { "type": "http", "url": "https://gateway.mewcp.com/youtube/mcp", "headers": { "Authorization": "Bearer YOUR_MEWCP_KEY", "x-mewcp-credential-id": "YOUR_CREDENTIAL_ID" } } } } ``` ### Cursor (mcp.json) ```json { "mcpServers": { "youtube": { "url": "https://gateway.mewcp.com/youtube/mcp", "headers": { "Authorization": "Bearer YOUR_MEWCP_KEY", "x-mewcp-credential-id": "YOUR_CREDENTIAL_ID" } } } } ``` ### Claude Desktop (claude_desktop_config.json) ```json "mcpServers": { "youtube": { "command": "npx", "args": [ "-y", "mcp-remote@latest", "https://gateway.mewcp.com/youtube/mcp", "--transport", "http-only", "--header", "Authorization: Bearer YOUR_MEWCP_KEY", "--header", "x-mewcp-credential-id: YOUR_CREDENTIAL_ID" ] } } ```