Skip to main content
Glama
DivyaV18

YouTube MCP Server

by DivyaV18
README.md
# 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

A4.1/5.0

Scored across 14 tools

Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness3/5

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.

Maintenance

ActivityInactive
ResponsivenessNo issues