内容
# ytdl-rmcp
[](https://www.npmjs.com/package/ytdl-rmcp)
[](https://github.com/jmagar/rytdl/actions/workflows/release.yml)
[](https://github.com/jmagar/rytdl/actions/workflows/ci.yml)
跨平台、单二进制 **MCP 服务器**,从任意
[yt-dlp](https://github.com/yt-dlp/yt-dlp)-支持的站点(YouTube、Vimeo 等)下载媒体,
嵌入元数据和封面艺术,按艺术家组织文件,并将结果传输到本地路径、
SSH 目标或 rclone 目标。
使用 Rust 编写,基于 [`rmcp`](https://crates.io/crates/rmcp) crate。
**yt-dlp 和 ffmpeg 会自动下载**到每个用户的缓存中,因此主机不需要预安装 —
一个二进制文件就是整个安装包。
**30 秒路径:** `npx -y ytdl-rmcp setup` -> 配置目标路径 ->
调用 `youtube_search` 或 `youtube_probe`;仅在目标和信任边界清晰时使用 `youtube_download`。
**状态:** 生产环境个人媒体 MCP 服务器。只读搜索/探测/统计路径是安全的;
下载、播放列表、队列排水和标签写入路径会创建或移动状态,适用于受信任的调用者。
**不适用于:** 通用网络下载器 SaaS、多租户媒体摄入边界、
yt-dlp 上游站点处理的替代品或不受信任的 MCP 调用者的任意文件系统写入。
## 目录
- [命名](#命名)
- [功能和边界](#功能和边界)
- [安装](#安装)
- [快速入门](#快速入门)
- [客户端配置](#客户端配置)
- [运行时界面](#运行时界面)
- [MCP 工具参考](#mcp-工具参考)
- [CLI 参考](#cli-参考)
- [配置](#配置)
- [身份验证](#身份验证)
- [安全性和信任模型](#安全性和信任模型)
- [架构](#架构)
- [分发合约](#分发合约)
- [开发](#开发)
- [验证](#验证)
- [部署](#部署)
- [故障排除](#故障排除)
- [相关服务器](#相关服务器)
- [文档](#文档)
- [许可证](#许可证)
## 命名
| 界面 | 此仓库 |
| --- | --- |
| 仓库 | `ytdl-rmcp` |
| npm 包 | `ytdl-rmcp` |
| CLI / 二进制文件 | `rytdl` |
| MCP 工具 | `youtube_search`、`youtube_search_ui`、`youtube_download`、`youtube_probe`、`youtube_identify`、`youtube_stats`、`youtube_plex_playlist`、`youtube_transfer_queue` |
| 环境前缀 | `YTDLP_*`,以及 `FFMPEG_*`、`FPCALC_PATH` 和 `YTDLP_LOG` |
仓库和 npm 包使用 `*-rmcp` 命名模式,而运行时二进制文件为 `rytdl`,
因此本地 shell 可以获得一个简短的 Rust 原生命令。
## 功能和边界
- 通过 yt-dlp 在不下载媒体的情况下搜索 YouTube。
- 将音频、视频或两者下载到暂存树中,标记音频元数据,并将结果传输到本地、SSH 或 rclone 目的地。
- 可选地通过 AcoustID/MusicBrainz 指纹识别音频,并将完成的音频下载同步到 Plex 播放列表。
- 从成功传输历史记录中构建 Plex 播放列表,并排空服务器制作的保留暂存传输清单。
- 为能够渲染嵌入式小部件的主机公开 MCP 应用搜索 UI。
- 保留一个 JSONL 账本,用于重复安全下载和统计。
| 此仓库拥有 | 上游拥有 | 明确超出范围 |
| --- | --- | --- |
| MCP 工具、CLI 设置、媒体暂存、标记、传输策略、队列清单、配置验证、响应塑形、插件/包元数据。 | yt-dlp 提取行为、源站点可用性、ffmpeg 媒体转换、Plex 库索引、SSH/rclone 身份验证。 | 多租户隔离、未经信任的调用者的任意本地写入、凭证代理、站点特定抓取保证、媒体服务器替换。 |
---
## 功能
- **音频、视频或两者** — 默认优先音频,音频和视频有单独的目标。
- **适当的标记** — 嵌入标题/艺术家/专辑/日期和封面艺术,并按 `Artist/Title [id].ext` 组织输出,以便媒体服务器(例如 Plex)能干净地索引它。
非贪婪的 `Artist - Title` 解析从自由格式的视频标题中恢复艺术家。
源 `.info.json`、缩略图和描述边车保存在媒体旁边以便未来的重新标记/索引。
默认情况下,从嵌入式标题元数据中删除常见的 YouTube 标题噪音,如 `(Official Video)`、 `[Official Audio]` 和尾随频道句柄。
- **自包含路径** — 二进制文件在运行时下载/缓存 yt-dlp + ffmpeg;
容器镜像将 ffmpeg、fpcalc、SSH 和 rsync 集成到媒体主机批量作业中。
- **自我安装** — `ytdl-rmcp setup` 将服务器注册到 Claude Code、Codex 和/或 Gemini CLI,每个工具都有自己的 `mcp add`。
- **强大的传输** — 本地路径(如果存在)使用 `rsync --partial`,SSH 目标 (`host:/path`) 使用 `rsync --protect-args` 和 `scp` 回退,
而 rclone 目标 (`remote:path` 或 `rclone:remote:/path`) 使用 `rclone copy`。
如果传输失败,本地暂存副本将被保留以供重试。
- **重复安全** — `use_archive` 记录下载的 ID(按模式)并在后续运行中跳过它们;
YouTube 混合/广播 URL 会自动清理为种子视频。
- **统计账本** — 每个完成的下载调用都会追加一个 JSONL 条目,包含时间戳、目的地、文件、字节、上载者和传输状态。
- **Plex 播放列表同步** — 配置 Plex 凭证后,下载的音频会添加到 `yt-dlp Downloads`(默认)。
## MCP 工具参考
| 工具 | 用途 |
| --- | --- |
| `youtube_search` | 使用 yt-dlp 搜索 YouTube 并返回结果 URL 而不下载。 |
| `youtube_search_ui` | 在支持 MCP 应用的主机上打开交互式 YouTube 搜索 UI。 |
| `youtube_download` | 下载一个或多个 URL(音频/视频/两者)并将它们传输到目标路径。 |
| `youtube_probe` | 只读:解析标题/时长/上传者/格式计数而不下载。 |
| `youtube_identify` | 使用 `fpcalc` 指纹识别本地音频,返回 AcoustID/MusicBrainz 候选者,预览规范标签,并可选地写入高置信度标签。 |
| `youtube_stats` | 汇总下载账本:总数、文件类型、上载者、最近的条目。 |
| `youtube_plex_playlist` | 从成功的传输历史记录中构建或预览 Plex 音频播放列表。 |
| `youtube_transfer_queue` | 列出和排空服务器创建的传输失败清单。 |
### `youtube_download` 参数
| 参数 | 默认值 | 含义 |
| --- | --- | --- |
| `urls` | — (必填) | 一个 URL 字符串或 URL 数组。 |
| `mode` | `audio` | `audio`、`video` 或 `both`。 |
| `audio_format` | 环境变量 `YTDLP_AUDIO_FORMAT` → `mp3` | `mp3`/`m4a`/`opus`/`flac`/`wav`/`best`。 |
| `audio_quality` | `0` | yt-dlp 损耗编码的质量:`0`–`9` 或类似 `192K` 的比特率。 |
| `max_height` | 最佳 | 视频分辨率上限(例如 `1080`)。 |
| `container` | `mp4` | 视频的 `mp4` 或 `mkv`。 |
| `target_path` | 环境变量 `YTDLP_TARGET_PATH` | 音频的目标路径。使用 `/path` 表示本地,`host:/path` 表示 SSH,或 `remote:path` 或 `rclone:remote:/path` 表示 rclone。 |
| `video_target_path` | 环境变量 `YTDLP_VIDEO_TARGET_PATH` → `target_path` | 视频的目标路径(如果应与音频分开)。相同的目标形式。 |
| `keep_local` | `false` | 在传输后保留本地暂存副本。 |
| `use_archive` | `false` | 记录 + 跳过已下载的 ID(按模式)。 |
| `plex_playlist` | 环境变量 `YTDLP_PLEX_PLAYLIST` → `yt-dlp Downloads`(当配置了 Plex 时) | 要将下载的音频轨道添加到其中的 Plex 播放列表标题或 ID。需要 `YTDLP_PLEX_URL` 和 `YTDLP_PLEX_TOKEN`。 |
| `response_format` | `markdown` | `markdown` 或 `json`。 |
当配置了 Plex 凭证时,成功的下载会搜索 Plex 的每个下载的曲目,创建目标播放列表(如果需要),
并添加缺少的曲目,同时跳过已存在的条目。默认播放列表是 `yt-dlp Downloads`;
设置 `YTDLP_PLEX_PLAYLIST` 或传递 `plex_playlist` 以覆盖它。
Plex 错误被报告为 `plex_playlist_error`,不会使已完成的下载失败。
JSON 响应包括一个 `plex_playlist` 摘要,包含 `matched`、`added`、`already_present` 和 `missing` 计数。
### `youtube_download` JSON 响应
使用 `response_format=json` 调用时,调用返回一个描述批次的单个对象:
| 字段 | 含义 |
| --- | --- |
| `transferred` | 如果每个生成的子树都到达了其目标,则为 `true`。 |
| `transfer_error` | 成功时为 `null`,否则为失败/超时消息(字符串)。 |
| `target_path` / `destination` / `destinations` | 实际使用的每个类型的目标目的地。 |
| `staging_kept_at` | 用于重试的保留的本地暂存路径(当传输失败或请求 `keep_local` 时设置)。 |
| `total_files` / `total_bytes` / `total_size` | 跨所有项目的聚合计数。 |
| `partial_items` | 错误的项目数量 **但** 仍生成了文件。 |
| `failed_items` | 错误的项目数量 **且** 没有生成文件。 |
| `items[]` | 每个 URL 的结果,每个结果都有一个 `status`、`title`、`video_id`、`error` 和一个 `files[]` 列表。 |
每个 `items[].status` 是以下之一:
- `ok` — 成功生成文件。
- `partial` — 发生错误但仍生成了一些文件。
- `failed` — 错误且无文件。
- `skipped` — 没有新的内容(已在存档中)。
### `youtube_plex_playlist`
从成功的 ytdl-rmcp 下载历史记录中构建或预览 Plex 音频播放列表。
操作:
| 操作 | 含义 |
| --- | --- |
| `list_candidates` | 返回 `transferred` 为 `true` 的历史记录条目的音频候选者。 |
| `preview` | 在不修改 Plex 的情况下,将选定的候选者解析为 Plex。 |
| `apply` | 将选定的候选者幂等添加到 Plex 音频播放列表 ID。 |
候选者源自历史记录,限于音频。失败或保留暂存的传输故意被排除在外。
### `youtube_transfer_queue`
列出和排空服务器创建的传输失败清单。
操作:
| 操作 | 含义 |
| --- | --- |
| `list` | 显示待处理的保留暂存传输清单。 |
| `retry` | 通过不透明的 `manifest_id` 重试某个清单。 |
| `retry_all` | 重试所有待处理清单。 |
| `prune` | 删除其暂存目录已消失的清单。 |
队列永远不会接受任意文件系统路径。重试使用原始目标路径记录的失败时间并在传输前重新检查本地目标策略。
清单由本地服务器在传输失败时创建,此时暂存目录、清单 ID、文件列表和原始目标仍然匹配。
### `youtube_identify` 参数
| 参数 | 默认值 | 含义 |
| --- | --- | --- |
| `paths` | — (必填) | 一个本地音频文件路径字符串或路径数组。 |
| `write_tags` | `false` | 将高置信度的 MusicBrainz 预览标签写入音频文件。 |
| `response_format` | `markdown` | `markdown` 或 `json`。 |
`youtube_identify` 运行 Chromaprint `fpcalc`,将指纹发送到 AcoustID,
并返回 MusicBrainz 记录候选者。当最佳候选者具有高置信度时,它还会获取 MusicBrainz 记录/发布数据,
并包含一个 `retag_preview` 显示规范的艺术家、标题、发行版、发行日期、发行类型、曲目编号和 MusicBrainz ID。
默认情况下,它仅用于预览。通过 `write_tags=true`,它将预览写入文件,
使用 Lofty,包括常见的标题/艺术家/专辑/日期/曲目字段以及 MusicBrainz 记录、发行版、发行组和发行类型标签。
它需要 `YTDLP_ACOUSTID_CLIENT_KEY`;如果 `fpcalc` 不在 `PATH` 上,请设置 `FPCALC_PATH`。
### `youtube_search` 参数
| 参数 | 默认值 | 含义 |
| --- | --- | --- |
| `query` | - (必填) | YouTube 搜索文本。服务器将其传递给 yt-dlp 作为 `ytsearchN:<query>`。 |
| `limit` | `10` | 结果数量,限制在 `1..=25`。 |
| `response_format` | `markdown` | `markdown` 或 `json`。 |
`youtube_search_ui` 接受相同的输入并返回相同的搜索负载,
以及支持渲染嵌入式 UI 的主机的 MCP 应用元数据。
### `youtube_stats` 参数
| 参数 | 默认值 | 含义 |
| --- | --- | --- |
| `limit` | `10` | 包括的最近账本条目数量,限制在 `0..=100`。 |
| `response_format` | `markdown` | `markdown` 或 `json`。 |
JSON 统计数据包括 `total_downloads`、`total_files`、`total_bytes`、
`skipped_entries`、`by_kind`、`by_uploader` 和 `recent`。桶字段包括
`downloads`(兼容性别名 `call_count`)、`calls`、`items`、`files`、
`bytes` 和人类可读的 `size`。损坏的账本行被跳过并计数,而不是使整个统计调用失败。
如果下载成功,但账本追加失败,下载响应仍成功并在 JSON 输出中包含 `history_error`。
## CLI 参考
| 命令 | 用途 |
| --- | --- |
| `rytdl` 或 `rytdl serve` | 通过 stdio 提供 MCP。此客户端使用的默认运行时。 |
| `rytdl setup` | 在需要时获取工具依赖项并注册本地 MCP 客户端。 |
| `rytdl doctor` | 打印版本、平台、工具解析和配置存在诊断。 |
npm 启动器公开相同的二进制文件:
```bash
npx -y ytdl-rmcp doctor
npx -y ytdl-rmcp serve
```
## 安装
通过 npm 运行引导安装程序:
```bash
npx -y ytdl-rmcp setup
```
或全局安装命令:
```bash
npm i -g ytdl-rmcp
ytdl-rmcp setup
```
npm 包在 `postinstall` 期间下载匹配的 GitHub Release 二进制文件;
安装的命令是 Rust 二进制文件通过一个小的 Node 启动器提供。您也可以使用一行的安装程序:
```bash
curl -fsSL https://raw.githubusercontent.com/jmagar/rytdl/main/scripts/install.sh | bash
```
或从
[发布](https://github.com/jmagar/rytdl/releases) 页面下载您所在平台的二进制文件 tarball,
或自行构建(参见下文)。引导安装程序获取 yt-dlp + ffmpeg,
提示您的音频/视频目标路径,检测哪些代理 CLI 存在,
并将服务器注册到您选择的代理。
## 快速入门
安装完成后,首先测试只读路径:
```bash
npx -y ytdl-rmcp doctor
```
对于原始 MCP 客户端,通过 JSON-RPC 调用 `tools/call` 调用只读工具:
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "youtube_search",
"arguments": {
"query": "lcd soundsystem live",
"limit": 3,
"response_format": "json"
}
}
}
```
然后在下载之前探测一个已知 URL:
```json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "youtube_probe",
"arguments": {
"urls": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}
}
}
```
仅在 `YTDLP_TARGET_PATH` 或 `YTDLP_VIDEO_TARGET_PATH` 指向您信任的调用者写入的目标时,
才使用 `youtube_download`。
## 客户端配置
通过 stdio 运行,无需子命令,`npx -y ytdl-rmcp` 提供 MCP 服务。
您可以自己注册:
```bash
# Claude Code
claude mcp add -s user ytdl-rmcp -e YTDLP_TARGET_PATH=tootie:/media/music -e YTDLP_EXTRACTOR_ARGS=youtube:player_client=android -- npx -y ytdl-rmcp
# Codex
codex mcp add --env YTDLP_TARGET_PATH=tootie:/media/music --env YTDLP_EXTRACTOR_ARGS=youtube:player_client=android ytdl-rmcp -- npx -y ytdl-rmcp
```
Gemini CLI(命令参数,环境变量在最后)
gemini mcp add -s user ytdl-rmcp npx -y ytdl-rmcp -e YTDLP_TARGET_PATH=tootie:/mediae YTDLP_EXTRACTOR_ARGS=youtube:player_client=android
使用 `npm i -tdl-rmcp`、`scripts/install.sh` 或包安装了独立的二进制文件,你可以在此处使用文件路径代替 `npx -y ytdl-rmcp`。
对于原始的 MCP JSON 配置文件,请包含所需的目标路径环境变量和 YouTube 提取器覆盖:
```json
{
"m": {
"ytdl-rmcp": {
"command": "npx",
"args": ["-y", "ytdl-rmcp"],
"env": {
"YTDLP_TARGET_PATH": "tootie:/mnt/user/data/media/music/yt-dlp",
"YTDLP_VIDEO_TARGET_PATH": "tootie:/mnt/user/data/media/movies/yt-dlp",
"YTDLP_AUTO_UPDATE": "1",
"YTDLP_MAX_AGE_DAYS": "1",
"YTDLP_EXTRACTOR_ARGS": "youtube:player_client=android"
}
}
}
}
```
内置的 `.mcp.json` 文件也是一个完整的原始 MCP 配置文件:它声明了插件/软件包清单使用的相同 `user_config` 键,为本地网关导入提供默认值,并将每个设置映射到服务器环境中。
为了可靠的 YouTube 搜索/探测行为,默认情况下 `YTDLP_EXTRACTOR_ARGS` 设置为 `youtube:player_client=android`;官方音乐视频结果在元数据提取期间经常拒绝 yt-dlp 的默认 YouTube 客户端。
## 运行时界面
| 界面 | 命令或文件 | 备注 |
| --- | --- | --- |
| stdio MCP 服务器 | `npx -y ytdl` 或 `rytdl` | 本地 MCP 客户端的默认运行时。 |
| CLI | `rytdl --help` | 相同的二进制文件;提供设置和诊断。 |
| 有导向的设置 | `npx -y ytdl-rmcp setup` | 在可用时注册 Claude Code、Codex 和 Gemini CLI 配置。 |
| | `youtube_search_ui` | 嵌入式搜索小部件和正常的备用。 |
| 软件包 | `mcpb/m` | 用于支持的桌面主机的B/DXT 软件包。 |
| 容器 |cr.io/jmagar/rytdl:main 包括 ffmpeg、fpcalc、SSH、rcloneync,用于共享部署。 |
## 分发合约npm 启动器** — `npx -y ytdl-rmcp` 下载并运行匹配的 GitHub Release 二进制文件。无需子命令即可运行,它通过 stdio 提供 MCP 服务;`npx -y ytdl-rmcp setup` 运行有导向的安装程序。从 GitHub Actions附带 npm 。
- **Claude Code 插件** — `.-plugin/plugin.json` 通过 `userConfig` 提示mcp.json `npx -y y-rmcp`,后者通过 npm 下载匹配的 GitHub Release 二进制文件。
- **Gemini CLI 扩展** — `gemini-extension.json`;使用 `gemini extensions install https://github.com/jmagar/rytdl` 安装。MCP 客户端应优先使用 npm 启动器命令 `npx -y ytdcp`。
- **容器镜像** — `ghcr.io/jmagar/rytdl:main` 在 `main` 时使用 `docker build ytdl-rmcp:local .` 在本地构建。它包括 `ffmpeg`、`fpcalc`、`openssh-client`、`rclone`rsync`。有关挂载库示例,请 [`docs/container.md`](docs/container.md)。
MCP 软件包(cpb` / `.dxt`)**mcpb/m` 为具有 MCPB桌面主机定义了一种` 类型软件包键安装。每个主版本发布 `ytdl.mcpb`版 `ytdcp.dxt` 别名;两者包含相同的 Linux + Windows 二进制文件。软件包默认将可选配置为空字符串,以便 Claude Desktop 可以安装它,然后再填写。在扩展设置中配置至少目标路径,然后再## 配置
下载只需要一个值:`YTDLP_TARGET_PATH`。仅当视频文件应放置在与音频不同的位置时,才需要 `YTDLP_VIDEO_TARGET_PATH`。`youtube_search`、`youtube_probe` 和_identify` 不需要目标。
安装清单默认将 `YTDLP_EXTRACTOR_ARGS` 设置为 `youtube:player_client=android`,因为该客户端可以在官方音乐视频结果中生存常见的 YouTube 元数据块,这些块使得音乐视频结果不可用。
目标路径形式:
- `/path/to/library` — 本地目录。使用 `rsync --partial`(如果可用),否则使用 Rust 文件系统复制。需要 `YTDLP_ALLOW_LOCAL_TARGETS=true`,因为本地路径允许 MCP 调用者选择写入位置。
- `host:/path/to/library` — SSH 目标。使用现有的 rsync/scp 流,并遵循 `YTDLP_SSH_OPTS`。
- `remote:path/to/library` — rclone 目标,带有相对远程路径。使用 `rclone copy`;clone` 必须在服务器进程的 `PATH` 上配置。
- `rclone:remote:/path/to/library` — 显式 rclone 目标,用于绝对远程路径;如果没有 `rclone:` 前缀,则通过设计,`host:/path` 仍。
| 变量 | 是否需要? | 默认值 | 使用者 | 含义 |
| --- | --- | --- | --- |
| `YTDLP_TARGET_PATH` | 下载所需 | — | download | **音频** 的目标。 使用 `/path` 表示本地,`host:/path` 表示 SSH,或 `remote:path` 或 `rclone:remote:/path` 表示 rclone。 |
| `YTDLP_VIDEO_TARGET_PATH` | 可选 | 默认为 `YTDLP_TARGET_PATH` | download | **视频** 的目标,当视频文件应放置在与音频不同的位置时。 使用相同的目标形式。 |
| `YTDLP_REMOTE` | 已弃用 | — | download | 旧版 SSH 远程别名或 `user@host`。在迁移期间,与 `YTDLP_REMOTE_PATH` / `YTDLP_VIDEO_REMOTE_PATH` 结合使用, 作为显式 SSH 目标。 优先使用 `YTDLP_TARGET_PATH`。 |
| `YT_REMOTE_PATH`弃用 | — | download | 旧版 SSH 路径。YTDLP`;拒绝相对路径。 优先使用 `_TARGET_PATH`| `YTDLOTE_PATH` | 已弃用 | — | 视频的旧版 路径。YTDLP_REMOTE`;如果未设置目标。 优先使用 `YTDLP_PATH`。 |
YTDLP_ALLOW` | 可选0` | download允许本地文件系统目标,例如 `/path`。您信任 MCP 调用本地写入位置,否则状态。 |
| `YTDLP_AUDIO_FORMAT 可选 | `` | download | 默认音频编解码器mp3`、`、`opusflac`、`wav` 或 `best`。 |
| `YTDLP_STAGING_DIR` | 可选 | 系统临时目录 | download | 媒体在传输之前暂存的本地目录。 在传输失败时,此暂存副本将保留用于重试。 |
| `YTDLP_SSH_OPTS` | 可选 | — | download | 使用 shell 单词语法解析的额外 SSH 选项,并追加在强制非交互式默认值之后。`-i "~/.sshl key" ProxyJump=media-b`。 拒绝格式错误的引用,并且离诸如 `` 之类的命令阱。 |
| `YTDLP_ARCHIVE_DIR` | 可选 | 用户状态目录 | download `use_archive`档的目录。创建单独的每个模式存档文件。 |
| `YTDLP` | 可选状态目录 `downloads` | download, `youtube_stats` JSONL 下载账本。 |
| `YTDLP_PLEX_URL` | Plex 同步所需 | download | P URL,例如 `http.local:324,用于将音频 Plex 播放 必须与 `YTDLP_PLEX_TOKEN` 配对。 |
| `YTDLP_PLEX_TOKEN` | Plex 同步所需 | — | download | 用于播放列表/搜索 API 调用的 Plex 身份验证令牌。 必须与 `YTDLP_PLEX_URL` 配 |
| `YT_PLEX_PLAYLIST 可选 | 设置 Plex URL/令牌时为 `yt-dlp Downloads` | download | 默认 Plex 播放列表标题或 ID;可以通过 `list` 按调用覆盖。 |
| `YTDLP_CLEAN_METADATA` | 可选 | `1` | download | 在嵌入之前去除常见的 You标题噪音。 `0` 以精确保留源标题。 `YTDLPID_CLIENT_KEY 识别/自动所需 | — | download | AcoustID API 密钥。_identify`;当设置时youtube_download` 还音频之前将高置信度的 MusicBrainz 标签写入下载的音频中。 |
| `FPCALC_PATH` | 可选 | `PATH` 上的 `fpcalc` | identify, download 重新标记 | Chromaprint `fpcalc` 可执行文件的可选显式路径。 |
| `YTDLPBRAINZ_CONTACT`选 | 仓库 URL | identify, download 重新标记包含在 MusicBrainz 查找 User-Agent 字符串 URL/电子| `YTDLP_AUTO_UPDATE` | 可选 | `1` | 工具引导 | 当陈旧时,重新下载 yt-dlp。 仅当 `YTDLP_PATH` / `YTDLP_HASH` 哈希值通过外部管理可执行文件时禁用。 |
| `YTDLP_MAX_AGE_DAYS` | 可选 | `14` | 工具引导 | yt-dlp 自动更新的天数阈值。 |
| `YTDLP_UPDATE_PRE` | 可选 | `0` | 工具引导 | 跟踪 yt-dlp 的夜间预发布频道,而不是稳定频道。 |
| `YTDLP_EXTRACTOR_ARGS` | 可靠的 YouTube 搜索/探测所需 | 安装清单中默认为 `youtube:player_client=android`;在裸进程环境中未设置 | search, probe | 传递给lp `--extargs`。 Android 客户端修复了视频的常见 `This video is not available` 元数据失败。 |
| `YTDLP_TIMEOUT_SECS` | 可选 | `1800` | search, probe, download | 每个 yt-dlp/探测/的超时时间。 |
| `YTDLP_TRANSFER_TIMEOUT_SECS` | 可选 | `600` | download | 每个传输阶段的超时时间。 |
| `YTDLP_PATH` | 可选 | — | 工具引导 | 在自动解析/自动下载之前使用特定的 yt-dlp 可执行文件。 |
| `FFMPEG_PATH` | 可选 | — | 工具引导, 下载 | 在自动解析/自动下载之前使用特定的 ffmpeg 可执行文件。 探测/搜索不需要 ffmpeg。 |
| `YTDLP_SHA256` | 可选 | — | 工具引导 | 解析的 yt-dlp 可执行文件的可选 SHA-256 摘要。 |
| `FFMPEG_SHA256` | 可选 | — | 工具引导 | 解析的 ffmpeg 可执行文件的可选 SHA-256 摘要。 |
| `YTDLP_LOG` | 可选 | `info` | 服务器进程 | 写入 stderr 的 `tracing` 过滤器。 永远不要将日志发送到 stdout,因为 stdout 是 MCP JSON-RPC 通道。 |
>者:** 此表格**手动维护**。 `scripts/check-packaging.sh` 会交叉检查可读的配置文件(Claude 插件、`.mcp.json` `user_config`、`gemini-extension.json` 和 `mcpb/manifest.json`),并验证此 README 提到每个映射的环境变量名称。
> 它不会比较 README 描述或默认值。 当你添加、重命名或删除 `YTDLP_*`、`FFMPEG_*`、`FPCALC_PATH` 或 `YTDLP_LOG` 环境变量时,请手动更新此表格。
## 认证 服务器默认情况下监听器或 HTTP 身份验证层;访问权限由本地 MCP 客户端授予给它启动。外部凭证存储在控制的环境变量配置、SSH、rclone 配置lex/Acoust变量中。
MCP 调用者永远不会在工具参数中提供 令牌、SSH 密钥、r凭证、哈希值或下载器二进制文件路径参数携带媒体 URL、搜索/探测输出模式选择选择器,这些将被与进程配置 安全性和信任模型
### 引导信任模型
默认情况下,首次运行时,按以下顺序解析工具:显式环境变量覆盖、`PATH`、缓存,然后从上游发布源进行 HTTPS 下载。 如果配置了 `YTDLP_SHA256` 和/或 `FFMPEG_SHA256`,则在解析或下载后设置精确的可执行文件摘要。 这些哈希值会验证磁盘上的字节,但它们不会获取上游签名或自动发现受信任的哈希值;如果需要完全固定的供应链,操作员应通过 `YTDLP_PATH` / `FFMPEG_PATH` 加上匹配的 SHA-256 哈希值提供已知的良好二进制文件,或禁用 yt-dlp 自动更新。
对于更严格的引导控制,请将 `YTDLP_PATH` / `FFMPEG_PATH`的 `YTDLP_SHA256` / `FFMPEG_SHA256哈希值结合使用。 哈希值验证已解析的可执行文件字节;它们不是上游签名验证。
### 安全态势
此服务器设计为在**受信任的调用者和操作者提供的配置**下运行 — 它不是一个加固的多租户边界。
- **工具调用 URL 可达 yt-dlp.** MCP 调用者传递的任何 `urls` 都将传递给 yt-dlp,这是一个强大的提取工具。 只有将调用者指向它时才信任它。 工具调用 URL 在到达 yt-dlp 之前会验证为 `http`/`https`,并且每个位置参数都在 `--` 选项结束分隔符,因此不能将以 `-` 开头的数值解析为标志;上面的信任假设仍然成立。
- 仅限密钥且非交互式。** SSH 目标强制 `BatchMode=yes` 和 `StrictHostKeyChecking=accept-new`,因此无 TTY 的服务器快速失败而不是提示;没有密码身份验证。 身份验证来自您的 SSH 密钥/代理和您通过 `YTDLP_SSH_OPTS` 添加的任何选项。
- **目标路径已验证。** 本地和 SSH 路径必须绝对,并且不能包含遍历或控制字符。 SSH 远程还拒绝和包含空格/控制字符的值,然后再传递ssh`ync`/`scp`;远程路径为远程 shell 转义为单引号。
## 需求
- **rsync** 推荐用于本地和 SSH 传输;本地传输回退到 **cp**,SSH 传输回退到 **scp**。
- **ssh** 加无密码密钥身份验证身份验证,用于使用 `host:/path` 目标。
- **rclone** 加已配置的 rclone 远程,用于 `remote:path` 或 `rclone:remote:/path` 目标。
- yt-dlp 和 ffmpeg 将自动获取(使用 `YTDLP_PATH` / `FFMPEG_PATH` 覆盖,或将它们放在 `PATH` 上)。
- `youtube_identify` 还需要 `fpcalc`;容器镜像通过 `libchromaprint-tools` 包含它。
## 开发
从源代码构建和测试:
```bash
cargo build --release # Linux/macOS
cargo test && cargo clippy --all-targets -- -D warnings # 检查
# 在 Linux 上从交叉编译到 Windows(需要 nasm + LLVM 工具链):
sudo apt-get install -y nasm llvm clang lld
cargo install cargo-xwin
cargo xwin build --release --target x64-pc-windows-msvc
```
在 dookie/local shell 上,`~/.local/bin/cargo` 是一个可以破坏 `cargo xwin` 的包装器;对于本地 Windows 演练,请使用真正的 rustup cargo:
```bash
~/.cargo/bin/cargo xwin build --release --target x86_64-pc-windows-msvc
```
CI(`.github/workflows/`)在每次推送/PR 时运行 fmt + clippy和 Windows 交叉构建,并在*` 标签上将二进制文件 GitHub Release。
该 crate 在 Rust 2021 版,以便于可分发的单一二进制文件/插件构建。仅在证明 Linux、Windows MSVC 交叉构建和插件启动兼容性后,才迁移到 2024 版。
## 验证
在发布 README、软件包或运行时,请使用以下检查:bash
python3 /home/jmagar/workspace/soma/scripts/check-readme README.md packages/ytdl-rm.md
npm --prefix packages/ytdl-rmcp run check
cargo fmt --check
cargo check
cargo test
-packaging.sh
git diff --check
```
对于实时 MCP 烟雾测试,请使用临时配置注册并调用 `youtube_search` 或 `youtube_probe`再运行 `youtube_download`。
架构
裸调用服务通过 stdio 提供 MCP;在 `setup` 运行安装程序。 `youtube_download` 调用:
1. 解析 yt-dlp + ffmpeg(环境变量覆盖 → PATH → 缓存 → 下载),并在配置的情况下验证 SHA-256 哈希值。
2. 清理混音/电台 URL,然后将 yt-dlp 模式运行到具有元数据/缩略图/存档标志的暂存树(`staging/audio`、`staging/video`)中,带有源元数据侧车和 `Artist/Title [id]` 输出模板。
3. *(可选)* 当设置了 `YTDLP_ACOUSTID_CLIENT_KEY` 时,提取下载的音频指纹,并将高置信度的 MusicBrainz/AcoustID 标签写入就地 - 在传输之前,以便目标副本携带规范标签。
4. 将每种类型的文件树传输到其目标:本地 rsync/cp、SSH rsync/scp 或 rclone 复制。
5. *(可选)* 当配置了 Plex 凭证并且传输成功时,将下载的音频曲目添加到目标 Plex 播放6. 将已追加到 JSONL 下载账本中。
7. 返回 或 JSON 摘要,列出文件、大小和实际目标。
CLAUDE.md` 获取架构、约定和陷阱。
## 部署
- 本地客户端应使用 ` -y ytdl-rmcp` 或已安装的 `rytdl` 二进制文件通过 stdio。
- 共享运行时作业可以在需要 ffmpeg、fpcalc、SSH、rclone 和 rsync 而无需主机级安装时使用容器镜像。
- 主机部署应在将 MCP 服务器暴露给调用者之前,在进程环境或主机配置中设置目标、Plex、AcoustID、SSH 和 rclone 凭证。
- 保持 `YTDLP_ALLOW_LOCAL_TARGETS=0`,除非受信任的调用者被允许写入通过工具参数选择的本地文件系统路径。
## 故障排除
- YouTube 元数据看起来不可用:设置 `YTDLP_EXTRACTOR_ARGS=youtube:player_client=android` 或使用已检查的客户端/插件配置,它们已经默认为此设置。
- 下载成功但传输失败:检查 `staging_kept_at` 或 `youtube_transfer_queue` 列表,然后在修复 SSH、rclone 或本地目标权限后重试。
- Plex 播放列表更新丢失:确认 `YTDLP_PLEX_URL`、`YTDLP_PLEX_TOKEN`,并检查 Plex 是否可以看到传输的文件。
- 工具引导对于您的环境来说过于宽松:使用匹配的 SHA-256 变量固定 `YTDLP_PATH` 和 `FFMPEG_PATH`,或禁用 yt-dlp 自动更新。
## 相关服务器
- [soma](https://github.com/jmagar/soma) - 提供商支持的MCP服务器的RMCP运行时。
- [unifi-rmcp](https://github.com/jmagar/runifi) - UniFi控制器REST API桥接。
- [tailscale-rmcp](https://github.com/jmagar/rtailscale) - 设备、用户和tailnet操作的Tailscale API桥接。
- [unraid-rmcp](https://github.com/jmagar/runraid) - 用于NAS和服务器管理的Unraid GraphQL桥接。
- [apprise-rmcp](https://github.com/jmagar/rapprise) - 用于多个投递后端通知的Apprise通知扇出桥接。
- [gotify-rmcp](https://github.com/jmagar/rgotify) - 用于发送、消息、应用程序和客户端的Gotify推送通知桥接。
- [arcane-rmcp](https://github.com/jmagar/rarcane) - 用于容器和相关资源的Arcane Docker管理桥接。
- [yarr](https://github.com/jmagar/yarr) - 用于Sonarr、Radarr、Prowlarr、Plex和相关服务的媒体栈桥接。
- [synapse-rmcp](https://github.com/jmagar/synapse) - 用于侦察和flux操作的本地Synapse工作流服务器。
- [cortex](https://github.com/jmagar/cortex) - Syslog和homelab日志聚合MCP服务器。
- [axon](https://github.com/jmagar/axon) - RAG、爬取、抓取、提取和语义搜索项目。
- [labby](https://github.com/jmagar/labby) - Homelab控制平面和MCP网关项目。
- [lumen](https://github.com/jmagar/lumen) - 本地语义代码搜索MCP服务器。
## 文档
本README是精选的运营商入口点。生成的或机器可读的真实来源存在于软件包、插件和捆绑包清单中,`scripts/check-packaging.sh`会对这些清单进行交叉检查。
| 文档 | 目的 |
| --- | --- |
| `CLAUDE.md` | 架构、约定和本地代理说明。 |
| `docs/container.md` | 容器运行时示例和挂载库模式。 |
| `docs/musicbrainz-acoustid.md` | 规范的元数据匹配和重新标记行为。 |
| `.mcp.json` | 原始MCP配置文件和机器可读的用户配置默认值。 |
| `.claude-plugin/plugin.json`、`gemini-extension.json`、`mcpb/manifest.json` | 客户端特定的打包元数据。 |
## 许可证
MIT — 请参见 `LICENSE`。
## Rust MCP命名模式
此仓库遵循Rust MCP服务器命名约定:
- 仓库:`ytdl-rmcp`
- CLI别名:`rytdl`
- npm软件包:`ytdl-rmcp`
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器