yutu

YouTube channel management over the YouTube Data API: uploads, comments, playlists, live streams

By eat-pray-ai Go Local · stdio MediaCommunication

59 popularity score ★ 715 ↓ 179/wk

Connect your client

Local (npm)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

It needs YUTU_CREDENTIAL, YUTU_CACHE_TOKEN. Replace each <NAME> with your value.

FirstTerminal
npm i -g @eat-pray-ai/yutu
Claude CodeTerminal
claude mcp add yutu -e YUTU_CREDENTIAL=<YUTU_CREDENTIAL> -e YUTU_CACHE_TOKEN=<YUTU_CACHE_TOKEN> -- yutu mcp
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "yutu": {
      "command": "yutu",
      "args": [
        "mcp"
      ],
      "env": {
        "YUTU_CREDENTIAL": "<YUTU_CREDENTIAL>",
        "YUTU_CACHE_TOKEN": "<YUTU_CACHE_TOKEN>"
      }
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "yutu": {
      "command": "yutu",
      "args": [
        "mcp"
      ],
      "env": {
        "YUTU_CREDENTIAL": "<YUTU_CREDENTIAL>",
        "YUTU_CACHE_TOKEN": "<YUTU_CACHE_TOKEN>"
      }
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "yutu": {
      "type": "stdio",
      "command": "yutu",
      "args": [
        "mcp"
      ],
      "env": {
        "YUTU_CREDENTIAL": "<YUTU_CREDENTIAL>",
        "YUTU_CACHE_TOKEN": "<YUTU_CACHE_TOKEN>"
      }
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.yutu]
command = "yutu"
args = ["mcp"]

[mcp_servers.yutu.env]
YUTU_CREDENTIAL = "<YUTU_CREDENTIAL>"
YUTU_CACHE_TOKEN = "<YUTU_CACHE_TOKEN>"
Gemini CLITerminal
gemini mcp add --scope user -e YUTU_CREDENTIAL=<YUTU_CREDENTIAL> -e YUTU_CACHE_TOKEN=<YUTU_CACHE_TOKEN> yutu yutu -- mcp
Local (container)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

It needs YUTU_CREDENTIAL, YUTU_CACHE_TOKEN. Replace each <NAME> with your value.

Claude CodeTerminal
claude mcp add yutu -e YUTU_CREDENTIAL=<YUTU_CREDENTIAL> -e YUTU_CACHE_TOKEN=<YUTU_CACHE_TOKEN> -- docker run -i --rm -v '<ABSOLUTE_PATH>:/app' -e YUTU_CREDENTIAL -e YUTU_CACHE_TOKEN ghcr.io/eat-pray-ai/yutu:latest mcp
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "yutu": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-v",
        "<ABSOLUTE_PATH>:/app",
        "-e",
        "YUTU_CREDENTIAL",
        "-e",
        "YUTU_CACHE_TOKEN",
        "ghcr.io/eat-pray-ai/yutu:latest",
        "mcp"
      ],
      "env": {
        "YUTU_CREDENTIAL": "<YUTU_CREDENTIAL>",
        "YUTU_CACHE_TOKEN": "<YUTU_CACHE_TOKEN>"
      }
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "yutu": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-v",
        "<ABSOLUTE_PATH>:/app",
        "-e",
        "YUTU_CREDENTIAL",
        "-e",
        "YUTU_CACHE_TOKEN",
        "ghcr.io/eat-pray-ai/yutu:latest",
        "mcp"
      ],
      "env": {
        "YUTU_CREDENTIAL": "<YUTU_CREDENTIAL>",
        "YUTU_CACHE_TOKEN": "<YUTU_CACHE_TOKEN>"
      }
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "yutu": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-v",
        "<ABSOLUTE_PATH>:/app",
        "-e",
        "YUTU_CREDENTIAL",
        "-e",
        "YUTU_CACHE_TOKEN",
        "ghcr.io/eat-pray-ai/yutu:latest",
        "mcp"
      ],
      "env": {
        "YUTU_CREDENTIAL": "<YUTU_CREDENTIAL>",
        "YUTU_CACHE_TOKEN": "<YUTU_CACHE_TOKEN>"
      }
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.yutu]
command = "docker"
args = ["run", "-i", "--rm", "-v", "<ABSOLUTE_PATH>:/app", "-e", "YUTU_CREDENTIAL", "-e", "YUTU_CACHE_TOKEN", "ghcr.io/eat-pray-ai/yutu:latest", "mcp"]

[mcp_servers.yutu.env]
YUTU_CREDENTIAL = "<YUTU_CREDENTIAL>"
YUTU_CACHE_TOKEN = "<YUTU_CACHE_TOKEN>"
Gemini CLITerminal
gemini mcp add --scope user -e YUTU_CREDENTIAL=<YUTU_CREDENTIAL> -e YUTU_CACHE_TOKEN=<YUTU_CACHE_TOKEN> yutu docker -- run -i --rm -v '<ABSOLUTE_PATH>:/app' -e YUTU_CREDENTIAL -e YUTU_CACHE_TOKEN ghcr.io/eat-pray-ai/yutu:latest mcp
Local (from source)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

It needs YUTU_CREDENTIAL, YUTU_CACHE_TOKEN. Replace each <NAME> with your value.

FirstTerminal
go install github.com/eat-pray-ai/yutu@latest
Claude CodeTerminal
claude mcp add yutu -e YUTU_CREDENTIAL=<YUTU_CREDENTIAL> -e YUTU_CACHE_TOKEN=<YUTU_CACHE_TOKEN> -- yutu mcp
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "yutu": {
      "command": "yutu",
      "args": [
        "mcp"
      ],
      "env": {
        "YUTU_CREDENTIAL": "<YUTU_CREDENTIAL>",
        "YUTU_CACHE_TOKEN": "<YUTU_CACHE_TOKEN>"
      }
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "yutu": {
      "command": "yutu",
      "args": [
        "mcp"
      ],
      "env": {
        "YUTU_CREDENTIAL": "<YUTU_CREDENTIAL>",
        "YUTU_CACHE_TOKEN": "<YUTU_CACHE_TOKEN>"
      }
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "yutu": {
      "type": "stdio",
      "command": "yutu",
      "args": [
        "mcp"
      ],
      "env": {
        "YUTU_CREDENTIAL": "<YUTU_CREDENTIAL>",
        "YUTU_CACHE_TOKEN": "<YUTU_CACHE_TOKEN>"
      }
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.yutu]
command = "yutu"
args = ["mcp"]

[mcp_servers.yutu.env]
YUTU_CREDENTIAL = "<YUTU_CREDENTIAL>"
YUTU_CACHE_TOKEN = "<YUTU_CACHE_TOKEN>"
Gemini CLITerminal
gemini mcp add --scope user -e YUTU_CREDENTIAL=<YUTU_CREDENTIAL> -e YUTU_CACHE_TOKEN=<YUTU_CACHE_TOKEN> yutu yutu -- mcp

Settings 4

YUTU_CREDENTIAL secret Required: Google OAuth client secret, given as a file path under YUTU_ROOT, a Base64 string or raw JSON. Default client_secret.json.
YUTU_CACHE_TOKEN secret Required: OAuth token written by yutu auth, given as a file path under YUTU_ROOT, a Base64 string or raw JSON. Default youtube.token.json.
YUTU_ROOT Optional: Folder that file paths are resolved against, for videos, thumbnails, captions and the auth files. Default current working directory.
YUTU_LOG_LEVEL Optional: Log level: DEBUG, INFO, WARN or ERROR. Default INFO.

In a container, a setting goes in with -e NAME=value after docker run.

What it does

yutu is one Go program that works as a YouTube command-line tool, an MCP server (`yutu mcp`) and a standalone agent. As an MCP server it wraps the YouTube Data API v3 and acts on your own channel through your Google account. An assistant can upload and edit videos, set thumbnails and watermarks, manage playlists, moderate comments, run live broadcasts and their chat, manage subscriptions and search YouTube.

The v0.11.0 release has 74 tools, one per API action, named resource-action (`video-list`, `comment-setModerationStatus`). Video categories, interface languages and regions come as three MCP resource templates instead. The tables in docs/FEATURES.md list the quota cost of each action.

It speaks stdio by default. With `yutu mcp --mode http` it serves streamable HTTP at http://localhost:8216/mcp, and there each call must carry a Google OAuth token that the server checks. Request bodies are capped at 2 MiB in that mode (cmd/mcp.go).

Besides npm and `go install`, the project now ships a container image on GHCR and Docker Hub. The image holds only the binary and starts it from /app, so you mount a folder there that holds client_secret.json and youtube.token.json and pass `mcp` as the argument (Dockerfile at v0.11.0).

File paths for uploads, downloads and the two auth files are resolved against YUTU_ROOT, which falls back to the working directory (pkg/init.go, pkg/auth/service.go). The separate `agent` mode runs its own model and is not needed for the MCP server.

What it needs

RuntimeA prebuilt binary
Runs onmacOS, Windows, Linux
Google Cloud project with YouTube Data API v3Free tierOAuth client of type Desktop app plus a YouTube channel to act on; daily API quota applies
Also
  • Docker, for the container image way

Create an OAuth client of type Desktop app in a Google Cloud project with YouTube Data API v3 turned on and save it as client_secret.json. Then run `yutu auth --credential client_secret.json` once. It opens a browser to grant access and writes youtube.token.json. The binary comes from npm, Homebrew, winget, go install, a release download or the container image.

Limits

  • Rate limit YouTube Data API quota is 10,000 units a day by default. A video upload costs 1,600 units, a search 100 and a caption update 450.
  • Early release member-list and membershipsLevel-list are marked as not working pending issue #3.
  • Not covered Channel sections can only be listed and deleted. Creating or updating them is not supported, and guideCategories is not covered.
  • Not covered No YouTube Analytics or Reporting tools in the MCP tool set. It acts only as the signed-in account.
  • Size cap In HTTP mode request bodies are capped at 2 MiB and the server listens on localhost:8216.
  • Limit Auth file paths are read relative to YUTU_ROOT. In Docker give Base64 or JSON values, or a path inside the mounted /app folder.

YouTube Data API quota is 10,000 units a day per project by default; one video upload costs 1,600 units, a search 100, a caption update 450 (docs/FEATURES.md). member-list and membershipsLevel-list are marked as not working pending issue #3. Channel section create and update are not yet supported, and the deprecated guideCategories API is not covered. It acts as the signed-in account only; there are no YouTube Analytics or Reporting tools in the MCP tool set.

Who it suits

Suits a YouTube creator or channel manager who wants an assistant to do routine channel work: uploads, metadata edits, playlists, comment moderation, live chat. It needs a Google Cloud project and OAuth set-up before first use, so it is more work than a key-based server. Many tools write or delete on a live channel, so clients that ask before each call are a good fit. Not a fit for analytics reporting or for reading YouTube without your own Google project; it is a community project, not published by Google.

Tools 60 of 74

20 only read, 29 change things, 11 can delete or overwrite.

activity-list
List recent activity on a channel
caption-delete deletes
Delete a caption track
caption-download
Save a caption track to a local file
caption-insert changes
Upload a caption track for a video
caption-list
List the caption tracks of a video
caption-update changes
Replace or edit a caption track
channel-list
Read channel details
channel-update changes
Change channel details such as description or keywords
channelBanner-insert changes
Upload a channel banner image
channelSection-list
List the sections shown on a channel page
comment-delete deletes
Delete a comment
comment-insert changes
Reply to a comment
comment-list
List replies to a comment
comment-markAsSpam changes
Flag comments as spam
comment-setModerationStatus changes
Hold, publish or reject comments
comment-update changes
Edit a comment
commentThread-insert changes
Post a new top-level comment
commentThread-list
List top-level comment threads
liveBroadcast-bind changes
Attach a broadcast to a live stream
liveBroadcast-delete deletes
Delete a live broadcast
liveBroadcast-insert changes
Schedule a live broadcast
liveBroadcast-insertCuepoint changes
Insert a cue point, such as an ad break, into a broadcast
liveBroadcast-list
List live broadcasts
liveBroadcast-transition changes
Move a broadcast to testing, live or complete
liveBroadcast-update changes
Edit a live broadcast
liveChatBan-delete deletes
Lift a live chat ban
liveChatBan-insert changes
Ban a user from a live chat
liveChatMessage-delete deletes
Remove a live chat message
liveChatMessage-insert changes
Post a message to a live chat
liveChatMessage-list
Read live chat messages
liveChatMessage-transition changes
Close a live chat poll
liveChatModerator-delete deletes
Remove a live chat moderator
liveChatModerator-insert changes
Add a live chat moderator
liveChatModerator-list
List live chat moderators
liveStream-delete deletes
Delete a live stream
liveStream-insert changes
Create a live stream with its ingestion settings
liveStream-list
List live streams
liveStream-update changes
Edit a live stream
member-list
List channel members (broken upstream, issue #3)
membershipsLevel-list
List membership levels (broken upstream, issue #3)
playlist-delete deletes
Delete a playlist
playlist-insert changes
Create a playlist
playlist-list
List playlists
playlist-update changes
Edit a playlist
playlistItem-delete deletes
Remove an item from a playlist
playlistItem-insert changes
Add a video to a playlist
playlistItem-list
List the items in a playlist
playlistItem-update changes
Change an item's position or note in a playlist
search-list
Search YouTube for videos, channels or playlists
subscription-delete deletes
Unsubscribe from a channel
subscription-insert changes
Subscribe to a channel
subscription-list
List subscriptions
superChatEvent-list
List Super Chat events for the channel
thumbnail-set changes
Upload a custom thumbnail for a video
video-delete deletes
Delete a video
video-getRating
Read your own rating of given videos
video-insert changes
Upload a video file with its metadata
video-list
List videos and their details
video-rate changes
Like, dislike or clear a rating on a video
video-update changes
Edit a video's title, description, tags or status

Resources 3

video://category/{hl}
YouTube video categories, labelled in the given interface language
i18n://language/{hl}
Interface languages YouTube supports
i18n://region/{hl}
Content regions YouTube supports

Similar servers