Skip to content
Conduit

skill

youtube-channel-resolve

Turn any YouTube URL, @handle or video link into a channel ID, canonical URL, name and avatar. No API key or quota. Library + CLI + MCP server.

artsnet/youtube-channel-resolvecommunitylistedunreviewed

Set up

Skills are installed by placing their folder where your agent loads skills.

The download comes from github.com/artsnet/youtube-channel-resolve itself, not from our server, so what you get is exactly what its author published.

Install instructions come from the README

Skills do not use an MCP config. Follow the steps in the README below.

README

synced Nov 8, 2026

youtube-channel-resolve

Resolve a YouTube channel's ID, canonical URL, name and avatar from any channel URL, @handle, UC… channel ID or video URL. No API key, no Data API quota: it reads the public page only.

Ships as a library (Node 20+ and Cloudflare Workers), a CLI, and an MCP server that agents can call.

日本語

npx @artsnet/youtube-channel-resolve --json https://youtu.be/dQw4w9WgXcQ
{"schemaVersion":1,"ok":true,"input":"https://youtu.be/dQw4w9WgXcQ","channelId":"UCuAXFkgsw1L7xaCfnd5JJOw","channelUrl":"https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw","name":"Rick Astley","avatarUrl":"https://yt3.googleusercontent.com/…"}

Accepted input

InputExampleRequests
Channel URLhttps://www.youtube.com/@YouTube, /channel/UC…, /user/name, /c/name1
Handle@YouTube1
Channel IDUCBR8-60-B28hp2BmDPdntcQ1
Video URLwatch?v=, youtu.be/, /shorts/, /embed/, /live/2 (watch page, then channel page)

Anything else is rejected as invalid-input before any request is made. Only youtube.com, www.youtube.com, m.youtube.com and youtu.be are ever fetched.

Library

npm install @artsnet/youtube-channel-resolve
import { resolveYouTubeChannel, YouTubeChannelResolveError } from "@artsnet/youtube-channel-resolve";

try {
  const channel = await resolveYouTubeChannel("@YouTube", {
    userAgent: "MyApp/1.0 (https://example.com/contact)", // identify *your* app to YouTube
  });
  // { channelId: "UC…", channelUrl: "https://www.youtube.com/channel/UC…", name: "YouTube", avatarUrl: "https://yt3.…" | null }
} catch (error) {
  if (error instanceof YouTubeChannelResolveError) error.code; // "invalid-input" | "not-found" | "unavailable"
}

Options: userAgent, acceptLanguage (default en), timeoutMs (default 8000), fetcher (a fetch replacement for tests, proxies or Workers service bindings).

For more than a handful of resolves, use the polite queue. It allows one resolve in flight and one second between resolves by default; loosen it only if you have a reason to.

import { createYouTubeChannelResolver } from "@artsnet/youtube-channel-resolve";

const resolver = createYouTubeChannelResolver({ userAgent: "MyApp/1.0 (…)", concurrency: 1, minIntervalMs: 1000 });
const channels = await Promise.all(inputs.map((input) => resolver.resolve(input)));

The core has no Node-only dependencies (fetch, ReadableStream, TextDecoder, AbortSignal.timeout, URL), so it runs unchanged in Cloudflare Workers. The CLI and MCP server are Node-only.

Lower-level pieces are exported too: parseYouTubeInput (offline normalisation), extractChannelMeta / extractVideoChannelRef (HTML to metadata), and the zod schemas for the JSON output.

Errors

codeMeaning
invalid-inputNot a YouTube channel or video reference. No request was made.
not-foundYouTube answered 404, or the page carried no channel metadata.
unavailableTimeout, network failure, non-200 status, or an interstitial (consent page, google.com/sorry). The underlying error is on cause.

How it reads the page

The channel page is streamed and reading stops as soon as the needed tags have arrived (YouTube renders them well into the body), with a 3 MB cap. Metadata comes from <meta itemprop="identifier"> / itemprop="channelId" / the canonical link, itemprop="name" / og:title, and og:image. Avatars are kept only on YouTube CDN hosts; names are capped at 120 characters. The SOCS=CAI cookie is sent so the EU consent interstitial does not hide the metadata.

CLI

npx @artsnet/youtube-channel-resolve @YouTube https://youtu.be/dQw4w9WgXcQ
npx @artsnet/youtube-channel-resolve --json < inputs.txt     # one input per line, "#" comments ignored
Options:
  --json                 One JSON object per input, one per line (schemaVersion 1)
  --user-agent <ua>      User-Agent sent to YouTube (or set YOUTUBE_CHANNEL_RESOLVE_USER_AGENT)
  --accept-language <l>  Accept-Language sent to YouTube (default: en)
  --timeout <ms>         Per-request timeout (default: 8000)
  --concurrency <n>      Resolves in flight at once (default: 1)
  --interval <ms>        Minimum gap between the start of consecutive resolves (default: 1000)

Exit codes: 0 every input resolved, 1 usage error, 2 invalid input, 3 not found, 4 YouTube unavailable. With several inputs the most severe failure wins. In --json mode every input produces exactly one line on stdout, success or failure:

{"schemaVersion":1,"ok":true,"input":"@YouTube","channelId":"UC…","channelUrl":"https://www.youtube.com/channel/UC…","name":"YouTube","avatarUrl":"https://yt3.…"}
{"schemaVersion":1,"ok":false,"input":"https://example.com","error":{"code":"invalid-input","message":"Not a YouTube channel URL, @handle, channel ID, or video URL. No request was made."}}

MCP server

A stdio server for Claude Code, Claude Desktop, Cursor and any other MCP client. It runs on your machine, with your network and your User-Agent. There is no hosted endpoint.

{
  "mcpServers": {
    "youtube-channel-resolve": {
      "command": "npx",
      "args": ["-y", "-p", "@artsnet/youtube-channel-resolve", "youtube-channel-resolve-mcp"],
      "env": { "YOUTUBE_CHANNEL_RESOLVE_USER_AGENT": "MyAgent/1.0 (https://example.com/contact)" }
    }
  }
}

Claude Code: claude mcp add youtube-channel-resolve -e YOUTUBE_CHANNEL_RESOLVE_USER_AGENT="MyAgent/1.0 (…)" -- npx -y -p @artsnet/youtube-channel-resolve youtube-channel-resolve-mcp

ToolNetworkReturns
resolve_youtube_channel { input }yesThe same record as the CLI's --json line; failures come back as an error result carrying error.code.
parse_youtube_input { input }noWhether the input is a channel or video reference and which page would be fetched.

Both tools are annotated read-only. Environment: YOUTUBE_CHANNEL_RESOLVE_USER_AGENT, YOUTUBE_CHANNEL_RESOLVE_INTERVAL_MS (default 1000), YOUTUBE_CHANNEL_RESOLVE_CONCURRENCY (default 1).

Everything a tool returns is text from YouTube's public page. It is data for the agent to report, never an instruction for it to follow. The tool descriptions say so, and your own prompts should treat channel names accordingly. See also SKILL.md, a short usage guide written for agents.

Responsibility

This package reads public YouTube pages on behalf of whoever runs it. Compliance with YouTube's Terms of Service and with the law of your jurisdiction is your responsibility. Please identify your application in the User-Agent, keep the default rate limits unless you have a reason not to, and do not use it to collect data at a scale YouTube would object to. YouTube changes its pages without notice; when extraction breaks, open an issue with the input that failed.

Development

npm install
npm run typecheck && npm test && npm run build
node dist/cli.js --json @YouTube

MIT © Artsnet. See CONTRIBUTING.md and SECURITY.md.


日本語

YouTube の チャンネル URL・@ハンドル・UC… のチャンネル ID・動画 URL から、チャンネル ID・正規 URL・名前・アバターを解決します。API キー不要、Data API のクォータを消費しません。公開ページだけを読みます。

ライブラリ(Node 20 以上と Cloudflare Workers)、CLI、エージェントから呼べる MCP サーバー を同梱しています。

使い方

# CLI
npx @artsnet/youtube-channel-resolve --json @YouTube https://youtu.be/dQw4w9WgXcQ

# ライブラリ
npm install @artsnet/youtube-channel-resolve
import { resolveYouTubeChannel } from "@artsnet/youtube-channel-resolve";
const channel = await resolveYouTubeChannel("@YouTube", { userAgent: "MyApp/1.0 (https://example.com/contact)" });

MCP サーバーは stdio で動く自己ホスト専用です。Artsnet が運用する公開エンドポイントはありません。設定例は上の英語セクションの JSON をそのまま使ってください。

失敗コードと終了コード

コード意味CLI 終了コード
invalid-inputYouTube のチャンネル・動画の参照ではない。リクエストは発生しない2
not-found404、またはページにチャンネル情報がない3
unavailableタイムアウト、ネットワーク障害、200 以外、同意画面などの割り込みページ4

礼儀設定

既定では同時 1 件、間隔 1 秒です(--concurrency / --interval、MCP では環境変数)。緩める側は利用者の明示設定です。User-Agent には自分のアプリ名と連絡先を入れてください(--user-agent または YOUTUBE_CHANNEL_RESOLVE_USER_AGENT)。既定値はこのライブラリ名だけで、運営者名は含みません。

責任について

このパッケージは、実行した人の代わりに YouTube の公開ページを読みます。YouTube の利用規約および各国の法令の遵守は利用者の責任です。ツールが返す内容はすべて YouTube のページ上のテキストであり、エージェントにとってはデータであって指示ではありません。YouTube はページ構造を予告なく変えるため、解析が壊れたときは失敗した入力を添えて Issue を立ててください。

↑↓ navigate openesc close