YouTube MCP Server
# YouTube MCP Server
A Python [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that exposes YouTube Data API tools. Use it from [MCP Inspector](https://github.com/modelcontextprotocol/inspector), Cursor, or any MCP client.
**Tool reference:** [Composio YouTube Toolkit](https://docs.composio.dev/toolkits/youtube)
---
## Table of contents
- [Project structure](#project-structure)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Getting OAuth2 credentials](#getting-oauth2-credentials)
- [Configuration (.env)](#configuration-env)
- [Running the server](#running-the-server)
- [MCP Inspector](#mcp-inspector)
- [Cursor MCP config](#cursor-mcp-config)
- [Tools overview](#tools-overview)
- [Troubleshooting](#troubleshooting)
---
## Project structure
```
youtube mcp/
├── src/youtubemcp/
│ ├── config.py # OAuth2, .env, YouTube API client
│ ├── mcp.py # FastMCP instance
│ ├── main.py # Entry point
│ └── tools/ # Tool modules (channel, captions, playlists, etc.)
├── .env # Your credentials (create from .env.example)
├── .env.example # Template for .env
├── pyproject.toml
├── requirements.txt
├── run.py # Run server: python run.py
└── README.md
```
---
## Prerequisites
- **Python 3.10+**
- **Google account** (for YouTube / OAuth2)
- **uv** (optional, for `uv run`) or **pip**
---
## Installation
### Option A: Using pip
```bash
cd "d:\clg files\PROJECTS\youtube mcp"
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
```
### Option B: Using uv
```bash
cd "d:\clg files\PROJECTS\youtube mcp"
uv sync
```
---
## Getting OAuth2 credentials
Follow these steps to get **Client ID** and **Client Secret** from Google Cloud.
### Step 1: Open Google Cloud Console
1. Go to **[Google Cloud Console](https://console.cloud.google.com/)**.
2. Sign in with the Google account you want to use for YouTube.
### Step 2: Create or select a project
1. At the top, click the **project dropdown** (next to “Google Cloud”).
2. Click **New Project**.
3. Enter a name (e.g. **YouTube MCP**) and click **Create**.
4. Select this project from the dropdown so it’s the active project.
### Step 3: Enable YouTube Data API v3
1. In the left menu: **APIs & Services** → **Library**
Or go to: **[APIs Library](https://console.cloud.google.com/apis/library)**.
2. Search for **YouTube Data API v3**.
3. Click it, then click **Enable**.
### Step 4: Configure OAuth consent screen
1. In the left menu: **APIs & Services** → **OAuth consent screen**.
2. Choose **External** (unless you use Google Workspace and want Internal only).
3. Click **Create**.
4. **App information**
- **App name:** e.g. `YouTube MCP`
- **User support email:** your email
- **Developer contact:** your email
5. Click **Save and Continue**.
6. **Scopes**
- Click **Add or Remove Scopes**.
- Filter or search for **YouTube Data API v3**.
- Add at least:
- **View your YouTube account** (`.../auth/youtube.readonly`)
- **See, edit, and permanently delete your YouTube videos, ratings, comments and captions** (`.../auth/youtube.force-ssl`)
- **Manage your YouTube videos** (`.../auth/youtube.upload`) — needed for uploads and thumbnails
- Click **Update** → **Save and Continue**.
7. **Test users** (required while app is in Testing)
- Click **Add Users**.
- Add the Gmail address you will use to sign in (e.g. `yourname@gmail.com`).
- Click **Save and Continue**.
8. Click **Back to Dashboard**.
### Step 5: Create OAuth 2.0 Client ID
1. In the left menu: **APIs & Services** → **Credentials**.
2. Click **+ Create Credentials** → **OAuth client ID**.
3. **Application type:** **Desktop app**.
4. **Name:** e.g. `YouTube MCP desktop`.
5. Click **Create**.
6. In the popup, copy:
- **Client ID** (looks like `123456789-xxxx.apps.googleusercontent.com`)
- **Client secret** (looks like `GOCSPX-xxxxxxxxxxxxxxxx`)
Keep these for the next section.
---
## Configuration (.env)
1. Copy the example env file:
```bash
copy .env.example .env
```
(On macOS/Linux: `cp .env.example .env`)
2. Open **`.env`** and set your credentials:
```env
client_id=YOUR_CLIENT_ID.apps.googleusercontent.com
client_secret=YOUR_CLIENT_SECRET
```
3. Optional variables:
| Variable | Description |
|----------------------|-------------|
| `oauth_redirect_uri` | Redirect URI (default: `http://localhost`) |
| `scopes` | Comma-separated OAuth scopes (default includes readonly; add `https://www.googleapis.com/auth/youtube.force-ssl` and `https://www.googleapis.com/auth/youtube.upload` for full features) |
Example for full access (read, write, upload, thumbnails):
```env
scopes=https://www.googleapis.com/auth/youtube.readonly,https://www.googleapis.com/auth/youtube.force-ssl,https://www.googleapis.com/auth/youtube.upload
```
4. **First run:** When you start the server, a browser window will open. Sign in with the same Google account you added as a test user and approve the requested permissions. The app will save tokens to **`token.json`** (created automatically; do not commit it).
---
## Running the server
From the project root:
```bash
python run.py
```
Or, if you use **uv**:
```bash
uv run run.py
```
The server runs over **STDIO** by default (for MCP Inspector and Cursor). It will wait for input; close with Ctrl+C when done.
---
## MCP Inspector
### Connect via STDIO (recommended)
1. Start MCP Inspector:
```bash
npx -y @modelcontextprotocol/inspector
```
2. In the Inspector:
- **Transport:** **STDIO**
- **Command:** `uv` (or `python`)
- **Arguments:** `run run.py` (or `run.py` if Command is `python`)
- Ensure the working directory is the project root (where `run.py` and `.env` are).
3. Click **Connect**. The server starts; on first run, a browser may open for Google sign-in.
4. Call any tool (e.g. **get_channel_id_by_handle** with `@YouTube`) to verify.
---
## Cursor MCP config
Add the server to Cursor so it can call YouTube tools.
1. Open **Cursor Settings** → **MCP** (or edit your MCP config file).
2. Add a server entry, for example:
```json
{
"mcpServers": {
"youtube": {
"command": "C:\\path\\to\\youtube mcp\\.venv\\Scripts\\python.exe",
"args": ["C:\\path\\to\\youtube mcp\\run.py"],
"env": {
"YOUTUBE_CLIENT_ID": "YOUR_CLIENT_ID",
"YOUTUBE_CLIENT_SECRET": "YOUR_CLIENT_SECRET"
}
}
}
}
```
Replace `C:\\path\\to\\youtube mcp` with your actual project path. You can omit `env` if `.env` is in the project root and Cursor runs from there.
3. Restart Cursor or reload MCP; the YouTube tools should appear.
---
## Tools overview
All tools return an object with `data` (object), `error` (string, optional), and `successful` (boolean).
| Tool | Description |
|------|-------------|
| **get_channel_activities** | Recent activities for a channel (uploads, playlists, likes). |
| **get_channel_id_by_handle** | Get channel ID from handle (e.g. `@Google`). |
| **get_channel_statistics** | Channel stats (subscribers, views, video count). |
| **list_channel_videos** | List videos from a channel. |
| **list_captions** | List caption tracks for a video (your videos). |
| **download_caption_track** | Download caption content by track ID (your videos). |
| **list_user_playlists** | Playlists owned by the authenticated user. |
| **list_user_subscriptions** | Channels the authenticated user is subscribed to. |
| **subscribe_to_channel** | Subscribe the authenticated user to a channel. |
| **search_youtube** | Search videos, channels, or playlists. |
| **update_thumbnail** | Set custom thumbnail from image URL (your videos). |
| **update_video** | Update video metadata (title, description, tags, privacy). |
| **upload_video** | Upload a video from a local file path. |
| **video_details** | Get video details (snippet, statistics, etc.) by video ID. |
---
## Troubleshooting
### "Access blocked" or "Error 403: access_denied"
- Your app is in **Testing** mode. Add your Google account under **OAuth consent screen** → **Test users** and try again.
### "Request had insufficient authentication scopes"
- Add the needed scope to **OAuth consent screen** (e.g. `youtube.force-ssl`, `youtube.upload`).
- Delete **`token.json`**, then run the server again and sign in to get a new token with the new scopes.
### "The authenticated user doesn't have permissions to upload and set custom video thumbnails"
- Add scope **Manage your YouTube videos** (`youtube.upload`) in the OAuth consent screen.
- Delete **`token.json`** and sign in again.
- Ensure your **YouTube channel is verified** (e.g. phone verification in [YouTube Studio](https://studio.youtube.com) → Settings → Channel).
### "YouTube Data API v3 has not been used in project ... or it is disabled"
- In [APIs Library](https://console.cloud.google.com/apis/library), enable **YouTube Data API v3** for the same project that has your OAuth client.
### Invalid scope (e.g. `scopes=https://...` in error)
- In **`.env`**, the `scopes` value must be **only** the comma-separated URLs, e.g.
`scopes=https://www.googleapis.com/auth/youtube.readonly,https://www.googleapis.com/auth/youtube.force-ssl`
Do not repeat the word `scopes=` inside the value.
### Token refresh
- Access tokens expire in about an hour. The server refreshes them automatically using `token.json`. If you change scopes or get auth errors, delete **`token.json`** and sign in again.
### `.env` and `token.json` location
- Both must be in the **project root** (same folder as `run.py`). The server loads them from there.
---
## License
MIT
TDQS
Scored across 14 tools
All tools target distinct resources and actions. Channel stats, activities, videos, playlists, subscriptions, captions, search, upload, and update are clearly separated with no overlapping purposes.
Most tools follow a consistent verb_noun snake_case pattern (get_channel_statistics, list_channel_videos, update_video). One outlier is 'video_details' which is a noun phrase rather than verb-first, but it's readable and doesn't cause confusion.
14 tools is well within the ideal range and matches the broad YouTube API scope. Each tool covers a significant operation, and no redundant tools are present.
The set covers read operations comprehensively (search, details, lists) and includes upload/update for videos. However, missing delete operations (videos, playlists, subscriptions, captions) and playlist creation/modification are notable gaps that limit full lifecycle management.