关于 moviepilot-api
moviepilot-api 是通过结构化 API 网关路由 MoviePilot 操作的技能,指导 Agent 选择文档化操作、遵守用户权限范围并核验结果。
主要功能
- 01选择结构化操作
- 02按用户范围管理订阅
- 03检查授权与确认要求
- 04按类别提供 API 合约
- 05核验写入操作结果
适用场景
- 01搜索或管理媒体与下载
- 02按用户所有权处理订阅
- 03查看插件、站点或存储操作
- 04核验请求变更后的结果
MCP 相关
该技能通过宿主提供的 `moviepilot_api` 工具执行常规 MoviePilot 业务操作。网关负责固定 HTTP 路径、当前用户身份验证、授权和确认策略,不提供任意 HTTP 访问。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jxxghp/ moviepilot --skill moviepilot-api安装后在 Claude Code 中输入/moviepilot-api确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
code-execution.mdapi/config.mddashboard.mddatabase.mddownload.mdfilter.mdlibrary.mdmedia.mdmusic.mdplugin.mdrecommendation.mdscheduler.mdsearch.mdsite.mdslash.mdstorage.mdsubscription.mdsubtitle.mdsystem.mdtorrent.mdtransfer.mdworkflow.md详细介绍
MoviePilot API
对于日志中报告的历史无效插件实例 ID,plugin.instance.purge
只接受精确的 ID,且仅将 config: true(所有其他作用域标志均为 false)。它只会删除空的已禁用主机记录:不包含已保存配置、显示覆盖项、默认目标或日志覆盖项。即使已保存的配置对象为空,也会保护该记录。此恢复路径绝不会停止插件,也不会删除插件数据、数据库或文件。
存在设置的记录、克隆记录、缺失的记录以及混合作用域均会被拒绝。
耐久传输步骤账本之外的未处理异常会停止自动重放,并生成 unhandled_execution_review 诊断。应修复或禁用出错的插件,并检查文件,然后才能将其解决为 not_applied;如有需要,应先回滚未跟踪的影响。此诊断会拒绝 applied,且不会替代任何已记录文件操作的证据。
如需参考相关的先前对话或之前的工具证据,请在可用时使用主机提供的 session_search 工具。先查找会话,再读取其中锚定的消息;过去的结果只能作为上下文,不能证明当前状态,也不代表有权重复写入操作。稳定偏好请使用 search_memory;它以前的 activity 类别已不再存在。这两个工具都不是 API 操作或外部 MCP 工具。
对于常规 MoviePilot 业务操作,请使用 moviepilot_api。该工具只接受 operation_id、path_params、query 和 body。主机会选择固定的 HTTP 方法和路径,创建当前用户的身份验证令牌,应用授权和确认策略,并返回 API 响应。
网关使用 HOST 和
PORT 直接连接本地后端监听器,绕过环境代理。APP_DOMAIN 用于 Passkey 来源等公共 URL,并非网关基础 URL。即使容器内无法访问公共反向代理,也请保持其配置。
subscription.add、subscription.update 和 subscription.delete 需要针对操作及作用域的授权,并使用绑定到渠道账户的当前 MoviePilot 用户,即使是渠道管理员也不例外。创建的订阅归该用户所有;普通用户只能更新或删除自己的订阅。未绑定或未激活的渠道用户必须先绑定一个已激活账户再重试,不得切换为管理员身份。
subscription.list 使用当前用户身份,并按订阅归属进行筛选。单独的全局订阅集成端点需要有效的 API_TOKEN 和管理员身份。该端点不在此技能允许的操作范围内,绝不能用于绕过用户作用域。
对于 QQ,qq_userid 或 qq_openid 均可与当前渠道 ID 匹配;对于
Feishu,feishu_userid 或 feishu_openid 均可匹配。只需匹配一个字段,但该匹配必须能在所有候选字段中唯一识别出一个已激活的 MoviePilot 用户。不得通过将 openid 复制到 userid 字段来变通,也不得绕过存在歧义的绑定。
对于 subscription.update,应省略需要保持不变的设置。发送 JSON
null 可清除受支持的可选设置;确切字段和表单空字符串兼容规则请参阅 Subscription APIs。
音乐下载会保留现有媒体类别;如果没有现有媒体类别,则使用中文音乐标签作为下载器类别,而不会更改媒体库或元数据类别。
qBittorrent 仍遵循 MoviePilot 配置的自动管理开关:启用时,其类别规则会控制保存位置;禁用时,MoviePilot 会省略类别,并显式禁用自动管理,以便应用请求的 save_path。现有任务不会被重新分类或移动。
此文件特意保留为路由和执行指南。详细的操作约定位于 api/ 下链接的分类文件中;只加载所选操作所需的一个分类文件。默认情况下不要加载所有分类文件。
绝不要提供 URL、方法、身份验证标头、API 密钥或访问令牌。绝不要回退使用已弃用的工具名称或 moviepilot tool MCP 命令。如果此技能未列出某项操作,不要通过任意 HTTP 模拟该操作;请使用更具体的技能,或说明该结构化操作不可用。
整理 SMB 文件时,请将源 FileItem.storage 与相对于共享目录的 path 保持对应。映射到 SMB 的下载器任务路径保留 smb: 前缀;绝不要将其解释为本地文件系统路径。同一存储中的 SMB 复制、移动和硬链接操作在服务器上执行;如果服务器无法执行这些操作,则会失败,不会通过下载并重新上传媒体来完成。这不会改变单独的内容处理操作,例如嵌入式音乐标签处理。使用 shares: ["video", "downloads"] 时,路径以共享名称开头,例如 /downloads/Movie.mkv 和 /video/Movie.mkv。旧版 share 保留相对于共享目录的路径。跨共享移动会先在服务器上复制,再删除源文件,因此不是原子操作;不支持跨共享硬链接。切换路径模式时,请更新已保存的目录和下载器映射。
整体工作流
- 从下方分类索引中选择确切的
operation_id。 - 再次调用
read_skill,并使用name="moviepilot-api"和file="api/<category>.md"加载完整、独立的分类约定。不要使用read_file读取 Skill 文档。 - 所选分类文件已包含构造调用所需的共享 Body Models;不要再加载第二份 Models 文档。
- 构造一次网关调用,且只包含已声明的字段。保留源生标识符,并使用文档规定的分页字段。将对象和数组请求体作为原生 JSON 值传递,仅当所选操作允许时才传递 null。唯一的字符串请求体是
system.upgrade.dev使用的字面值"dev"。如果模型将整个请求体编码为 JSON 字符串,每个网关入口点都会在验证和分派前还原一层对象、数组或 null。嵌套字符串值保持不变,且仍须遵循所选操作的约定。绝不要将操作字段平铺到operation_id旁边:应将每个字段放入其声明的path_params、query或body容器中。不要从其他操作复制分页或筛选条件。invalid_input响应会指出出错字段并包含input_contract;修正该字段及所有必填字段后再重试。无效输入会在发送 API 请求前被拒绝。 - 对于副作用操作,请检查针对该操作、目标和范围的授权。复用用户明确提出的请求或先前授权,无需再次询问;仅在缺少重要选择或需要扩大范围时询问。遵守宿主要求的任何确认,然后只执行一次网关调用。
- 在报告结果或执行依赖操作前,检查
success、execution_outcome、错误、空结果和集合元数据。绝不要将失败报告为成功。 - 如果约定要求,请使用该分类的回读操作验证写入;若操作结果为
unknown,不要重复执行写入。
调用形式示例
将示例 ID 替换为之前调用返回的准确标识符。这些是彼此独立的操作契约,参数模板不可互换。
{"operation_id":"media.detail","path_params":{"media_id":"27205"},"query":{"media_source":"tmdb","type_name":"\u7535\u5f71"}}
{"operation_id":"subscription.execution.list","query":{"limit":10}}
{"operation_id":"site.rss","query":{"page":1,"count":20}}
media.detail 要求同时提供源系统原生 ID 及其来源/类型。最近的订阅执行使用 limit,而不是 page 或 count。site.rss 会列出启用了 RSS 的站点;它不接受 site_id 筛选条件。
media.detail 和 transfer.file 的 type_name 接受 movie、tv 或 music;subscription.add 的 type 也接受相同的值。仍支持相应的中文标签。
API 分类索引
每个分类文件都包含其命名空间的完整操作契约。操作的权威依据是分类契约和 frontmatter 允许列表。
| 分类 | 详情文件 | 操作命名空间 | 用途 |
|---|---|---|---|
| 配置 | api/config.md | config.* | 标识符、公开/用户设置、系统设置发现与更新 |
| 仪表板 | api/dashboard.md | dashboard.* | 媒体、存储、进程、系统、下载器、CPU、内存、网络和传输摘要 |
| 数据库 | api/database.md | database.backups.* | 管理员备份生命周期 |
| 下载 | api/download.md | download.* | 提交下载、客户端、路径、活动任务和历史记录 |
| 筛选器 | api/filter.md | filter.* | 内置/自定义规则、分组和测试 |
| 媒体库 | api/library.md | library.* | 存在性和最新媒体检查 |
| 媒体 | api/media.md | media.* | 媒体搜索/详情、识别、刮削、日程、来源、人物、季和分类 |
| 音乐 | api/music.md | music.* | 识别、全局及按任务应用的 CUE 策略、探索、专辑、艺人、文本规范化、版本优先级和缓存管理 |
| 插件 | api/plugin.md | plugin.* | 插件市场、安装/运行时、配置、来源、文件夹、评分、版本发布和统计 |
| 推荐 | api/recommendation.md | recommendation.* | 推荐列表 |
| 调度器 | api/scheduler.md | scheduler.* | 调度器列表、进度和执行 |
| 搜索 | api/search.md | search.* | 标题、种子、结果和推荐搜索 |
| 站点 | api/site.md | site.* | 站点发现、身份验证、Cookie、用户数据、资源、RSS、优先级和统计 |
| 斜杠命令 | api/slash.md | slash.* | 斜杠命令发现与执行 |
| 存储 | api/storage.md | storage.* | 存储设置、浏览、目录、重命名和删除 |
| 订阅 | api/subscription.md | subscription.* | 订阅增删改查、搜索/刷新、历史记录、文件、分享、关注和状态 |
| 字幕 | api/subtitle.md | subtitle.search.* | 字幕标题和媒体搜索 |
| 系统 | api/system.md | system.* | 版本、更新、重启、模块、网络和用量 |
| 种子缓存 | api/torrent.md | torrent.cache.* | 种子缓存检查、刷新、重新识别和删除 |
| 传输 | api/transfer.md | transfer.* | 传输队列/历史记录、文件、命名、人工审核、重试和目标路径 |
| 工作流 | api/workflow.md | workflow.* | 工作流定义、操作、执行、分享和生命周期 |
每个分类文件都是一份独立契约:其中包含该分类所需的操作详情以及通用请求/响应体 Models。添加或移动操作时,请同时更新其分类文件、此索引、frontmatter 允许列表和对应的网关契约。
API 范围
/api/v1/widget/* 下的系统小组件端点不属于此技能和 Agent 工具目录。上下文、注册和所有者撤销使用现有的主登录凭据。快照读取和自行撤销使用单独的、有时效限制的只读 Bearer 凭据;切勿将其用作普通 API/MCP 登录凭据,也不要代表用户启用、轮换或导出小组件授权。读取上下文不得签发或轮换凭据。协议和用户范围请参阅 docs/widgets.md。系统扩展不得持有主登录令牌。
插件元数据可包含 plugin_readme,即可选的 HTTP(S) 文档链接。
如果链接缺失,UI 会通过管理 REST 端点
GET /api/v1/plugin/readme/{plugin_id}?repo_url=... 进行解析;该端点会返回 url 或 null,
且不会安装插件。此端点不会添加 Agent 操作。
对于已安装且绑定了源的插件,plugin.market 仅当该仓库有更新版本时才会列出更新。
其他仓库中有更高版本不会触发 has_update。使用 plugin.source.options 检查其他来源;切换来源仍需明确更改来源。未绑定来源的已安装插件仍会保留市场候选项,以供选择来源。
操作声明了身份范围:public 无需绑定频道账号即可读取外部公开元数据;bound_user 使用绑定到稳定频道发送者 ID 的当前 MoviePilot 用户(Web 使用其已认证的用户 ID);admin 需要管理员权限。只读不等于公开。频道昵称不能用于确定身份。个人记录和订阅写入仍遵循现有的所有权与权限检查。
身份解析失败时,请转发网关提供的实际处理建议消息和发送者 ID。频道用户应通过头像 > 个人信息 > 账号绑定绑定自己的 MoviePilot 账号,填写指定的频道字段并保存。不要虚构“设置 > 用户”绑定页面,不要以昵称、群组 ID 或机器人 ID 替代,不要将含糊的绑定失败归因于网络问题,也不要要求 Web 用户绑定通知频道。公开操作无需绑定。
此 Skill 是 Agent 可调用的完整 MoviePilot 业务 API 范围。allowed-api-operations 中的每项操作都在某个类别文件中有一份确切的参数约定,并在默认的 full 架构模式下对应一个 MCP tools/list 分支。明确发送
X-MCP-Schema-Mode: compact 的客户端会收到尽力生成的投影,以处理过大的架构;此处以及通过
GET /api/v1/mcp/tools/moviepilot_api/schema 均可查阅精确的操作约定。不存在回退到任意 REST 路由的隐藏机制。
MoviePilot 底层的 OpenAPI 文档范围更广,因为它还服务于 Web UI、身份验证、账号生命周期、二进制和流式响应、回调、兼容性端点以及 GitHub 识别/展示路由。这些路由不会复制到此 Skill 中。未列出的路由必须满足以下条件之一,Agent 才可使用其功能:
- 在此 Skill 中由一项稳定的聚合操作表示;
- 归属
downloader-operation、mediaserver-operation或其他具有自身精确操作约定的领域 Skill; - 保留给宿主传输、身份、UI、流式传输、二进制或诊断行为,因此不可作为 Agent 业务操作;或
- 明确标记为未获批准,直到补充角色、影响、确认、恢复、结果和英文参数约定。
按路由维护的清单是 app/agent/policy/api.py 中的固定注册表。若 OpenAPI 发生变化但未作出明确的归属决定,偏差测试将失败。
管理恢复路由 POST /api/v1/history/transfer/{history_id}/discard-corrupt
保留给直接进行身份验证的管理客户端,不是可调用的 Agent 操作。它会清除损坏的任务状态,同时保留历史记录。
调用约定
MCP 操作和字段描述均以中文编写;操作 ID、字段名、枚举值和请求格式保留其文档中的准确写法。精简架构会改写涉及已省略分支的描述;如需精确的输入,请使用完整架构。
将订阅设置为状态 S 后,系统会在安全边界处停止排队中和运行中的自动搜索任务,包括新订阅任务和站点重试任务。即使订阅已暂停,仍可通过显式订阅搜索执行一次搜索和下载;如需停止该次运行,请取消其执行批次。暂停或取消不会移除已提交给下载器的任务。
请按以下格式调用网关:
{
"operation_id": "media.search",
"path_params": {},
"query": {"title": "The Wandering Earth", "type": "media"},
"body": {}
}
常见读取和下载约定
search.recommend 在 check_only=true 时读取当前状态,不加载搜索结果。
已禁用的推荐会立即返回 disabled。force=true 优先于只读标志,并会加载候选项以启动新任务。
浏览器端点 /media/status 和 /subscribe/calendar 不属于 Agent 操作目录;不要为它们虚构网关调用。
先为任务选择操作,再仅发送该操作声明的字段。常见验证约定如下:
| operation_id | path_params | query |
|---|---|---|
subscription.find | media_id | media_source;可选 season、music_type |
subscription.list | 无 | 可选 page、count |
download.tasks.active | 无 | 可选 page、count、name |
site.list | 无 | 可选 page、count、name、status=all|active|inactive |
订阅执行日志是浏览器资源端点:
GET /api/v1/subscribe/{subscription_id}/logs(SSE,或使用 length=-1 返回文本)
以及 /logs/download(ZIP)。这些端点要求使用现有资源 Cookie,并会验证订阅归属;它们不是 JSON 网关或 MCP 工具。不要传入日志文件路径,也不要尝试通过 call_api 调用它们。
通过受支持的订阅操作读取订阅状态;搜索任务完成并不代表订阅已完成。
download.add 请求体必须包含 torrent_in(至少包含 title 和 enclosure),以及同级的 media_source 和 media_id;不要将磁力 URI 放入 url,也不要把媒体标识和筛选条件移到 query 中。写入返回 unknown 时,绝不要重试;先使用受支持的读取操作核实实际状态。
保留候选项的 site ID 和下载 URL。对于直接的 HTTP(S) 种子,可以省略 site_cookie:仅当下载 URL 的协议、主机和端口与配置的站点匹配时,后端才会用该站点的配置补齐缺失的 Cookie 和 User-Agent。如果没有站点 ID,则必须恰好匹配一个已配置的站点。
显式凭据和代理选择会保留。磁力链接和两步令牌交换下载遵循其现有凭据规则。
- 将
subscribe_id、hashString、plugin_id、workflow_id、media_id、storage、rule_id和name等路由占位符放入path_params。 - 将 GET 筛选条件和控制值放入
query。网关也接受放在body中的 GET 值,但除下方受保护的密钥流程外,应始终使用query。 - 将 POST、PUT 和 PATCH 请求模型放入
body。 - 保留搜索或详情响应返回的原始
media_source+media_id。对于音乐,也要保留music_type=recording|album|artist;艺人仅可浏览。 - 将
success=false、HTTP 错误数据、空结果和验证错误视为实际结果。未经检查响应,不要声称操作成功。 media.scrape会将拒绝的媒体和 NFO 写入失败报告为业务失败,包括目录内发生的失败。对于并发的自定义筛选条件变更,应重新读取规则,并在重试冲突前确认预期变更。- 遵循明确的
execution_outcome:pending表示已接受但尚未完成,而unknown表示写入可能已经发生。不要重复未知写入,也不要仅为规避重复保护而更改默认值。在内置 Agent 中,使用返回的调用 ID 调用get_tool_execution;对于受支持的非敏感设置替换,宿主可通过只读检查进行协调。 - 当内置 Agent 的预览包含
result_id和next_offset时,使用read_tool_result获取下一页,而不要重复执行该操作。这些回执和结果工具仅供 Agent 内部使用,不是外部 MCP 工具。
Agent 任务与对话状态
- 对于
agent_task更新,enabled=null会保留当前的启用状态。重命名已暂停的任务不会恢复其计划。 - 传统消息会话按频道、配置的来源和用户 ID 进行范围限定。停止、清除、状态查询或确认操作均针对当前来源的会话。
- 后台 WebAgent 完成后,会将当前轮次追加到显示历史记录中。前端完整快照仍遵循现有的替换约定。
- 使用
overwrite=false创建文件时,若有并发创建者则会拒绝操作。版本化编辑会拒绝覆盖其他进程期间写入的内容;重试前请重新读取文件,并使用当前 SHA。 - 安装市场技能时会保留明确选择的 GitHub 分支。如果该分支不可用,应将安装视为失败,而不是静默切换分支。
订阅身份与工作流恢复
- 查找或创建订阅时,请保留媒体类型、来源、媒体 ID、季、剧集组和音乐实体类型。数字 ID 相同的电影和电视剧是不同的目标。基于来源进行查找时,请保留剧集组。
- 为同一用户和身份并发创建时,会返回现有订阅 ID。更新现有目标身份时,该更新会被取消;请重新读取两个订阅,再决定下一步操作。
- 更改作品、季、剧集组或音乐实体会重置先前目标的下载和升级进度。缺失的剧集会根据新的总数重新开始;清除剧集组也会更改目标。
- Servarr 添加重复剧集时会返回实际的现有订阅 ID。如果已取消的搜索失去其执行器,租约到期后会完成取消操作,并允许发起新的搜索。
- 工作流恢复会重试失败的节点,以及因依赖项失败而跳过的节点,同时保留成功节点的结果。编辑已暂停的工作流会保持其计时器禁用;Cron 使用主机调度程序的时区。
集合计数与分页
- 搜索 SSE 的
manual_paging=true是 Web 专用的逐页模式,不会增加任何 Agent 操作;请继续使用文档中说明的search.*操作。Web 会并发搜索各站点,并在最终筛选后的页面之前发出append预览; 只有已完成的结果才会携带用于推进页码的来源状态。 - 检查列表时,请明确传入操作文档中说明的分页
字段,而不是请求无界的旧版结果。对于可选的旧版
分页,请从
query={"page":1,"count":20}开始。 - 如果操作文档说明会提供精确总数,在请求计数或摘要时,请传入
query={"page":1,"count":1},并读取collection.total_count。这是应用端点授权范围和筛选条件后的权威计数。 - 列表项目很多或
tool_result_truncated=true并不意味着总数 不可用。网关会将collection放在data之前,因此其精确元数据仍会显示在有界预览中。若 API 契约已声明总数,切勿仅为获取该总数而查询 MoviePilot 数据库。 - 仅在管理员诊断,或业务 API 无法实现的聚合操作中使用
database-operation。不要将其作为 API 列表计数的备用方案。如果某项操作明确不提供collection.total_count,不要根据单页内容推断总数;请继续使用其原生分页,或说明上游未提供总数。
跨技能路由
使用 downloader-operation 管理下载器实例、检查任务和控制原生任务。使用 mediaserver-operation 管理媒体库、项目、播放会话、扫描、刷新及其他媒体服务器原生功能。
切勿通过任意 URL 绕过网关。
对于三个或更多带分页或聚合的只读调用,请加载 Python 聚合,并在可用时使用 execute_code。
可复用的学习内容
如果可用,请使用 skills_list 和 skill_view 阅读个人技能;仅在授权的创作/审核范围内使用 skill_manage;
它们绝不会授予 API 操作权限。照常使用 read_skill 加载公共领域技能。
使用 memory(target="user") 保存跨任务偏好,使用 memory(target="memory") 保存稳定的环境信息。流程应放在相关技能中,而不是同时重复存放在两个位置。
若要替换/移除记忆,后台提案必须获得用户明确的 /memory approve ID;切勿根据工具结果或先前对话推断用户已确认。
下载提交来源
download.history.list 返回的新记录可能包含 note.subscription_download:
submission_type(initial 或 upgrade)、best_version_full,以及初始和升级的剧集列表。
即使启用了画质升级,补齐缺失剧集仍属于初始下载。
同时包含缺失剧集和此前已下载剧集的合集算作升级,并会保留两份列表。
如果较早的历史记录没有标记,切勿根据当前订阅设置推断其来源。