关于 yt
yt 是面向 Agent 和个人用户的 Go 命令行工具及 MCP 服务,可获取、搜索和监控 YouTube 字幕。它提供有界的时间戳结果和精确续读指针。
主要功能
- 01获取人工及自动生成的字幕
- 02搜索字幕并返回时间戳匹配
- 03监控频道上传及发布时间
- 04返回有界且可续读的字幕范围
- 05提供结构化错误和会话缓存
适用场景
- 01查找视频中的特定主题
- 02读取指定时间或字幕片段
- 03跟踪频道的新上传内容
- 04将字幕导出为 SRT 或 JSON
MCP 相关
同一二进制可通过 `yt mcp` 或接收管道输入时以 stdio 提供 MCP 服务。工具涵盖视频信息、字幕、字幕搜索、字幕轨道和频道上传列表。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
docker run -i --rm ghcr.io/arasandev/yt:0.1.1本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
ghcr.io/arasandev/yt:0.1.1stdio工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
yt
为 Agent 和用户提供 YouTube 字幕。一个静态 Go 二进制文件,无需 API 密钥、 无 AI 依赖,也无运行时要求。
- 通过 YouTube 的内部 Innertube API,使用
ANDROID/IOS客户端上下文获取 视频自带的字幕轨道(手动或自动生成)。自 2025 年年中起,WEB 客户端字幕 URL 受 pot-token 限制,会返回空内容。 - 按
innertube-android → innertube-ios → watch-page顺序回退,避免单个 受限端点导致获取失败;每个响应都会报告最终使用的方法(source)。 - 频道监控:
yt channel @handle(或list_channel_videos)解析频道 handle, 并从频道 RSS 源列出最新上传视频的精确发布时间戳,让 Agent 能与水位标记 对比并识别新内容。 - 同一个二进制文件也是 MCP 服务:使用
yt mcp,或在标准输入通过管道传入时 直接运行yt(这是 MCP 客户端启动的形式)。在终端中直接运行yt会显示帮助。 - MCP 响应专为 Agent 的上下文预算设计:限制载荷大小、结构化截断并提供精确
的续传指针、按时间/字幕条目定位的范围、服务端搜索、类型化错误,以及会话级缓存,
让一次
get_video_info+get_transcript+search_transcript共用一次播放器请求。
依赖项:cobra(CLI)、modelcontextprotocol/go-sdk(官方 MCP SDK),以及
golang.org/x/term(TTY 检测)。YouTube 获取层仅使用标准库 —
net/http、encoding/json、encoding/xml。
目录结构
仓库根目录是 Go 模块(github.com/ArasanDev/yt),也是产品根目录。
cmd/yt/ binary entry point
internal/cli/ cobra commands and flags
internal/mcp/ MCP tool schemas, handlers, safety warnings
internal/youtube/ Innertube client, captions, channels, cache, typed failures
internal/search/ pure transcript search
internal/render/ block/cue rendering, SRT, truncation metadata
internal/transcript/ shared Segment/Transcript model and timestamp helpers
internal/apperr/ typed error contract (code, retryable, suggestion)
internal/version/ build version, commit, and date
CI 配置位于 .github/workflows/ci.yml,会运行 gofmt、go vet、
go test -race、本机编译,以及面向发布目标的交叉编译矩阵。
依赖方向由外向内:cli 和 mcp 依赖 youtube、search、render 和
transcript;youtube 依赖 apperr 和 transcript;search 和 render 仅
依赖 transcript。采集层不会导入适配器。
安装
Homebrew(macOS/Linux)
brew trust arasandev/tap # Homebrew 7+ trusts third-party taps explicitly
brew install --cask arasandev/tap/yt
安装脚本(macOS/Linux)
curl -fsSL https://raw.githubusercontent.com/ArasanDev/yt/main/install.sh | sh
脚本会为你的操作系统/架构下载最新版本,与 checksums.txt 核验后进行安装;
若 /usr/local/bin 可写,则安装到该目录,否则安装到 ~/.local/bin。使用
YT_INSTALL_DIR 覆盖安装目录,并使用 YT_VERSION 固定版本:
YT_VERSION=v0.1.0 YT_INSTALL_DIR="$HOME/bin" \
curl -fsSL https://raw.githubusercontent.com/ArasanDev/yt/main/install.sh | sh
Go 开发者
go install github.com/ArasanDev/yt/cmd/yt@latest
go install 会记录模块版本,因此即使无法注入 ldflags,yt --version 仍会显示
发布版本。使用 make install 可进行本地构建,并同时写入提交和日期信息。
Docker
docker run --rm -i ghcr.io/arasandev/yt:latest mcp
# CLI use:
docker run --rm ghcr.io/arasandev/yt:latest transcript dQw4w9WgXcQ
该镜像是 distroless 静态构建。没有 TTY 时,直接运行 yt 就会提供 MCP 服务,
因此容器的默认命令是 mcp。
Linux 软件包
发布资源包含适用于 amd64 和 arm64 的 .deb、.rpm 和 .apk 软件包:
sudo dpkg -i yt_<version>_linux_amd64.deb
sudo rpm -i yt_<version>_linux_amd64.rpm
sudo apk add --allow-untrusted yt_<version>_linux_amd64.apk
预编译二进制文件
每个版本都会发布压缩包、Linux 软件包和 checksums.txt:
https://github.com/ArasanDev/yt/releases
目标平台:amd64 和 arm64 上的 darwin/linux/windows;Linux 还提供
deb/rpm/apk 软件包。
从源代码构建
git clone https://github.com/ArasanDev/yt.git
cd yt
make build # ./bin/yt
make install # into GOBIN with version/commit/date stamped
发布构建会写入版本、提交和日期信息(默认值为 dev):
go build -trimpath -ldflags "\
-X github.com/ArasanDev/yt/internal/version.Version=v0.1.0 \
-X github.com/ArasanDev/yt/internal/version.Commit=$(git rev-parse --short HEAD) \
-X github.com/ArasanDev/yt/internal/version.Date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
-o bin/yt ./cmd/yt
yt --version
CLI
yt transcript <url-or-id> # transcript to stdout
yt transcript <url> -l en,es -t # language fallback + [MM:SS] stamps
yt transcript <url> --start 1274 --end 1290 # time range
yt transcript <url> -f srt -o subs.srt # SRT file
yt transcript <url> -f json --max-chars 2000 # cue JSON, bounded
yt transcript <url> --bare # body only, no metadata header
yt transcript <url> --start-cue 120 --max-cues 40 # resumable cue window
yt search <url> "harness engineering" # timestamped hits, no full read
yt search <url> "M C P" --match-mode any # spelled acronyms collapse to mcp
yt search <url> "state of the art" --match-mode phrase
yt search <url> "harness" --context-cues 2 # human output shows context
yt tracks <url> # list caption languages
yt info <url> # title, channel, duration, views, chapters
yt channel @aiDotEngineer --limit 10 # latest uploads (exact timestamps)
yt channel @aiDotEngineer --since 2026-10-01 --json
yt doctor # probe which acquisition clients work
yt --version # build version (or module version under go install)
接受 watch?v=、youtu.be/、/shorts/、/live/、/embed/ URL,或不带前缀的 11 个字符视频 ID。默认情况下,-f text 会包含元数据头,并在需要时附带截断说明。使用 --bare 可仅将正文输出到 stdout;此时截断信息会报告到 stderr。获取内容和渲染相关说明始终输出到 stderr。
CLI 用法错误和上游故障均带有类型信息。cmd/yt 会将 code、
retryable、retry_after_seconds 和 suggestion 输出到 stderr,同时保持
stdout 干净。无效格式、负数限制和起止时间范围颠倒都会在发起任何网络请求前报错。
MCP
yt mcp 提供 stdio JSON-RPC;当 stdin 不是终端时,直接运行 yt 也会如此
(这是 MCP 客户端启动服务的方式),而在提示符下直接运行 yt 则会显示帮助信息。先调用
get_video_info:它会报告字幕可用性、直播状态和估算的字幕稿大小,便于你决定是读取完整
字幕稿、搜索内容,还是读取某个范围。
| 工具 | 用途 |
|---|---|
list_channel_videos | 频道最新上传视频(@handle/URL/UC…),来自 RSS:精确发布时间、标题、链接、描述摘录。 |
get_video_info | 元数据 + 字幕摘要 + 字幕稿大小估算 + 章节。不下载字幕稿。 |
get_transcript | 字幕稿文本或 cue JSON,可设定范围并按位置读取。 |
search_transcript | 查找主题并返回时间戳和上下文;match_mode 支持 all/any/phrase;无结果时会说明原因。 |
list_tracks | 字幕轨道。已弃用 — 请使用 get_video_info.captions。 |
监控频道时,调用 list_channel_videos,并将上次响应中的
newest_published 作为 since 传入。筛选条件严格为 published > since,因此不会重复报告视频。
信息流最多提供 15 条记录,不包含时长或观看次数;这些信息需要针对具体视频调用
get_video_info 获取。
get_transcript 的关键参数:languages(CSV,默认 en;original 表示上传者自己的
语言)、allow_translation、format(text|json)、
granularity(默认 block |cue)、timestamp_mode(默认 block
|cue|none)、start_seconds/end_seconds、start_cue/max_cues、
max_chars(默认 50000;仅限制字幕稿正文)。
截断绝不会被静默处理:头部会包含 TRUNCATED next_start_seconds=… next_cue_index=…,结构化元数据也包含相同字段,且 next_*
值精确无误(不会四舍五入),因此从这些值处继续读取绝不会漏掉边界 cue。
即使同时设置了 end_seconds,也会报告 max_cues 截断。
错误会以 isError 结果返回,包含机器可读的 error.code
(bot_check、rate_limited、no_captions、bad_request 等),以及
retryable 和 suggestion。
为兼容客户端,字幕稿正文会同时在 content 和 structuredContent 中返回,因此
响应大小约为正文的两倍;
returned_chars 计量的是其中一份副本。
自动配音视频会为每种语言列出一条自动生成的轨道。如果某条轨道的语言与已知的上传者原始语言不同,
无论该轨道是人工制作还是由 ASR 生成,都会报告为 translated=true,避免将机器翻译的语音
误认为说话者的原话。get_video_info.captions.original_language
会标明该轨道。如果播放器响应不包含音轨元数据,且存在多种字幕语言,则原始语言未知:
此时 languages=original
会返回可操作的 no_matching_language 错误,而不是猜测,且
original_language 可能为空。这种情况下,请指定具体语言。
接入任意 Agent:
devin mcp add yt -- yt mcp # Devin CLI
claude mcp add yt -- yt mcp # Claude Code
或使用原始 mcpServers JSON(Devin、Claude Desktop、Cursor、Windsurf 等):
{"mcpServers": {"yt": {"command": "yt", "args": ["mcp"]}}}
发布与分发
v* 标签会触发 .github/workflows/release.yml,该工作流会:
- 运行测试套件和 GoReleaser(归档文件、Linux 软件包、校验和、 GitHub Release);
- 构建并推送多架构
ghcr.io/arasandev/yt镜像; - 将版本写入
server.json并发布到 MCP 注册表。
git tag v0.1.0
git push origin v0.1.0
除非仓库中有 HOMEBREW_TAP_GITHUB_TOKEN 密钥,否则会跳过 Homebrew cask 更新:该密钥是一个精细粒度的 PAT,在 ArasanDev/homebrew-tap 上具有 contents: write
权限。没有该密钥时,发布仍会提供二进制文件、Docker 和 MCP 元数据;请手动添加 cask,或添加密钥后重新运行。
MCP 注册表任务尽力执行(continue-on-error)。GHCR 软件包默认是私有的:请在软件包设置中将 yt 软件包设为公开,然后重新运行任务。注册表会将镜像注释
io.modelcontextprotocol.server.name 与 server.json 中的 name 进行比对,因此这两个字符串必须保持一致。
打标签前可在本地进行的检查:
goreleaser check
goreleaser release --snapshot --clean # artifacts in dist/, never published
docker build --build-arg VERSION=dev -t yt:dev .
开发
make build # ./bin/yt
make test # go test -race ./...
make check # gofmt + go vet + go test -race
make snapshot # local GoReleaser snapshot
make clean
有关 Agent 必须保留的架构、约定和规范,请参阅 AGENTS.md。简而言之:标准输出是数据,标准错误是诊断信息;错误有类型;截断绝不会悄无声息,续传指针精确无误;来源信息和
content_trust 标签不可或缺;测试绝不会访问网络。
注意事项
- IP 封锁:数据中心 IP(AWS/GCP/VPS)会被 YouTube 封锁或限流,从而出现
bot_check或rate_limited。使用住宅 IP——例如你的 Mac——则可正常运行。对于服务器,请交叉编译 (GOOS=linux GOARCH=arm64 go build),并做好最终需要住宅代理的准备。 - 自动生成的(
asr)字幕缺少标点,因此granularity=sentence会降级为block,并附带说明。优先使用人工字幕轨道;当请求的语言没有对应轨道时,会使用 YouTube 自动翻译,并将结果标记为translated=true。 - 多配音视频会为每种语言提供一条 ASR 轨道。
languages=original会通过 YouTube 的音轨→字幕映射解析实际的原始语言;如果缺少该元数据,原始语言就无法确定,工具会返回可采取后续操作的错误,而不会猜测。 - 年龄受限或私有视频需要身份验证——当前不支持。
search_transcript会在同一条字幕片段内或最多 3 条相邻字幕片段中匹配多词查询。match_mode=any会放宽 AND 条件;match_mode=phrase要求词语相邻。由三个或更多单字母词组成的连续序列(M C P)会合并为mcp,长度不超过 3 个字符的词只匹配完整词。结果为零时,会提供每个词的命中次数,并说明缺失的词或起始字幕片段边界,因此不会让搜索无声无息地陷入僵局。搜索会覆盖整个字幕稿;目前没有时间范围筛选功能。chapters来源于描述中的Chapters:区块,并从完整描述中解析,再截断摘要。支持 emoji/markdown 标题和内联的首个条目;无效、重复、顺序错误或超出视频时长的条目会被丢弃。至少需要两个有效、严格递增且位于视频时长范围内的时间戳。timestamp_window_seconds根据时间戳模式确定:时间戳为区块级时是30,为字幕片段级或禁用时间戳时是0。引用区块时间戳时,应将其视为该时间窗口的起点,而不是单行时间戳。warnings仅供参考。它会标记字幕稿、搜索匹配项/上下文、视频元数据和频道列表中的指令式文本,以便调用方引用而不是遵从。无论如何,用户生成的内容仍会标记为content_trust: "untrusted"。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。