关于 mcp-tvsubtitles
mcp-tvsubtitles 将聊天客户端连接到 TVsubtitles.net 电视剧字幕目录。它可搜索剧集、查看季内各集的语言覆盖情况并读取字幕记录,无需 API 密钥或账户。
主要功能
- 01搜索电视剧
- 02按剧集和语言查看季覆盖情况
- 03列出单集的字幕记录
- 04读取记录及下载页面详情
- 05列出目录或剧集的语言
适用场景
- 01查看某一季的字幕语言覆盖情况
- 02查找特定一集的字幕记录
- 03确认字幕对应的版本和上传者
- 04打开字幕对应的目录页面
MCP 相关
向 MCP 客户端提供 TVsubtitles.net 剧集搜索、季覆盖情况、字幕记录和语言列表工具;不会下载字幕文件。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
4收录的工具列表 · 更新于 今天
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| year | integer | 否 | 仅保留公布年份涵盖此年份的剧集。如果没有符合条件的结果,搜索会在不应用此条件的情况下报告,并附注说明已忽略年份条件。 |
| limit | integer | 否 | 要显示的行数,默认为 20,最多为 100。 |
| query | string | 是 | 电视剧名称或名称的一部分。网站仅按名称匹配。 |
| media_type | enum | 否 | 'tv' 和 'any' 都会搜索该目录,该目录仅收录电视剧。'movie' 会被拒绝,因为返回空列表会错误地表示该网站能够确认没有电影。movie | tv | any |
| with_counts | boolean | 否 | 从网站的目录索引读取每行的字幕、剧集和季数。对于数百 KB 的结果页,这需要额外发起一次请求。每个数字统计整部剧,而非本次搜索结果;各项分别读取,索引中为空的单元格保留为 null。 |
详细介绍
mcp-tvsubtitles
TVsubtitles.net 收录了电视剧字幕。用户会为某一集上传字幕文件,并标明其对应的视频发行版本;网站会记录语言、适用的发行版本、上传者和上传时间、文件大小以及下载次数。网站收录了约 30 万条字幕,涵盖约 8.6 万集、24 种语言。
此服务将聊天客户端连接到该目录。你可以搜索剧集、查看某一季,并了解每集有哪些语言的字幕;也可以查看某集的字幕记录,打开一条记录以查看其适用的发行版本和上传者。每条记录都附有其网站页面地址。无需 API 密钥或账户。
安装
一键安装
Claude Code
claude mcp add tvsubtitles -- npx -y mcp-tvsubtitles
任何支持读取 mcpServers 的客户端
{
"mcpServers": {
"tvsubtitles": {
"command": "npx",
"args": ["-y", "mcp-tvsubtitles"]
}
}
}
使用 Docker
{
"mcpServers": {
"tvsubtitles": {
"command": "docker",
"args": ["run", "--rm", "-i", "ghcr.io/smeet666/mcp-tvsubtitles:1.0.1"]
}
}
}
容器只会访问 https://www.tvsubtitles.net,不会访问其他地址。
打包版本,无需 npm
从最新发行版下载 mcp-tvsubtitles.mcpb,并使用支持安装 MCP bundle 的宿主打开。该文件包含所有依赖,因此只需 Node 24 或更高版本。
你可以这样提问
- “tvsubtitles 上有《Smallville》的法语字幕吗?”
- “《Harbour Lights》第 3 季有哪些语言的字幕?”
- “列出该季第 7 集的英文字幕。”
- “这条字幕适用于哪个发行版本?由谁上传?”
- “帮我找出大结局波兰语字幕的下载页面。”
工具
| 工具 | 功能说明 |
|---|---|
search_titles | 按名称查找电视剧,并返回其他工具所需的 ID。 |
list_subtitles | 查看某一季的字幕覆盖情况,或某一集的字幕记录。 |
get_subtitle | 查看一条记录及其版本、上传者和下载页面。 |
list_languages | 列出目录收录的语言,或某部剧集收录的语言。 |
search_titles
按名称搜索目录。该网站仅收录电视剧,因此搜索电影时会拒绝请求,而不会返回结果。
| 参数 | 类型 | 必填 | 功能说明 |
|---|---|---|---|
query | string,1–120 个字符 | 是 | 剧集名称或名称的一部分。 |
media_type | movie | tv | any | 否 | tv 和 any 会搜索目录。movie 会被拒绝。 |
year | integer,1900–2100 | 否 | 仅保留发行年份涵盖该年份的条目。 |
limit | integer,1–100,默认值为 20 | 否 | 要呈现的条目数。 |
with_counts | boolean,默认值为 false | 否 | 从目录索引读取每条记录的字幕、剧集和季数;代价是额外发起一次请求。 |
**返回内容:**匹配的剧集,每部剧集都包含其他工具所需的 id、网站发布的年份,以及网站会为其显示旗帜的语言。imdb_id 和 tmdb_id 为 null,因为网站的搜索结果不提供这两个字段。除非通过 with_counts 请求,否则 subtitle_count、episode_count 和 season_count 均为 null,因为网站是在目录索引而非搜索结果页面上发布这三个数值;每个数值都统计该剧的所有季,统计范围由 counts_scope 标明;每个数值都会单独读取;如果该剧在索引中没有对应条目,则这三个字段均为 null。total_available 统计本次搜索返回的条目数,该数值由 total_counts 标明。如果某个年份筛选条件未筛出任何结果,则会被舍弃并列入 filters_dropped。
list_subtitles
读取某部剧集包含的内容,形状有两种,由 kind 命名。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string,1–12 个字符 | 是 | 来自 search_titles 的剧集 ID。 |
season | integer,1–200 | 否 | 留空时,读取网站收录的最新一季。 |
episode | integer,1–500 | 否 | 指定后,返回该集的记录。 |
language | string,1–40 个字符 | 否 | 来自 list_languages 的语言,可按名称、网站代码或 BCP 47 标签指定。 |
limit | integer,1–200,默认值为 40 | 否 | 要渲染的行数。 |
**返回内容:**仅指定季时,kind 为 coverage,每行代表一集,包含 episode_id、网站统计的字幕数量以及有字幕的语言。指定某一集后,kind 为 subtitles,每行代表一条记录,并包含 get_subtitle 所需的 id。season 是网站实际提供的季,season_requested 是请求的季;读取最新一季时,两者会不同。seasons_available 列出该剧集收录的季。没有内容的语言会被忽略,结果会取消该语言筛选,filters_dropped 会列出被忽略的语言。
get_subtitle
读取 list_subtitles 返回的某个 ID 对应的记录。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string,1–12 个字符 | 是 | 来自 list_subtitles 的字幕 ID。 |
**返回内容:**记录本身,其中 page_url 是读者打开以下载文件的页面 URL。read_from 在此处为 record,在 list_subtitles 生成的行中为 listing;它可以区分尚未读取的字段和网站不提供的字段:列表不包含 file_name、size_text 和 comment,因为网站只会在记录自己的页面上显示这些信息。releases 列出网站公布的视频发行版本,release_match 表示网站是否公布了任何版本:公布了则为 stated,未公布则为 none,因此标记为 none 的记录并未说明字幕对应哪个视频。约三分之二的记录中,uploader 为 null。published_at 是网站的时间戳,转换为 ISO 8601 格式且不带时区;published_text 保留网站原文。rating 包含网站公布的两个计数器,其中 0 表示网站显示的数值。
list_languages
列出网站收录的语言,或某部剧集包含的语言。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string,1–12 个字符 | 否 | 剧集 ID,用于读取该剧集包含的内容。 |
season | integer,1–200 | 否 | 要统计剧集哪一季。未指定 id 时将忽略此参数。 |
**返回内容:**每种语言均包含网站显示的名称、用于标识该语言的两字母 site_code、在映射关系确定时提供的 BCP 47 code,以及 differs_from_iso。scope 表示统计范围:整个网站为 catalogue;传入剧集 ID 时为 season,此时 count 为该季包含该语言字幕的集数。
语言及网站使用的代码
网站展示 24 面旗帜,并用自行选定的两个字母表示每种语言。其中 6 个代码不同于 ISO 639-1,另有一个代码与其冲突:网站用 br 表示巴西葡萄牙语,而 ISO 将其分配给布列塔尼语。
| 网站代码 | 语言 | BCP 47 |
|---|---|---|
br | 巴西葡萄牙语 | pt-BR |
gr | 希腊语 | el |
cz | 捷克语 | cs |
jp | 日语 | ja |
cn | 中文 | zh |
ua | 乌克兰语 | uk |
language 保留网站自己的名称,language_code 则保存标签,因此无需根据两个字母推导任何信息。list_subtitles 接受以上三种形式的语言名称。
配置
无需设置任何内容。以下所有变量均为可选项。
| 变量 | 默认值 | 范围 | 作用 |
|---|---|---|---|
TVS_USER_AGENT | 未设置 | 添加在此服务自身的 Agent 前面,且自身 Agent 仍会保留。 | |
TVS_MIN_INTERVAL_MS | 2000 | 1500–60000 | 两次请求之间的毫秒数。下限为 1500。 |
TVS_TIMEOUT_MS | 20000 | 1000–120000 | 单次尝试的截止时间。 |
TVS_BUDGET_MS | 60000 | 5000–600000 | 单次读取的截止时间,包括重试。 |
TVS_MAX_RETRIES | 3 | 0–8 | 首次尝试之后的重试次数。 |
TVS_CACHE_TTL_MS | 900000 | 0–86400000 | 页面在内存中的保留时长。0 表示关闭存储。 |
TVS_CACHE_MAX_ENTRIES | 200 | 1–5000 | 达到此数量后,将移除最近最少使用的页面。 |
TVS_MAX_BODY_BYTES | 8000000 | 100000–64000000 | 单个页面读取的最大响应大小。 |
TVS_LOG_LEVEL | error | silent、error、info、debug | 输出到 stderr 的内容。 |
超出范围的值会在 stderr 上被拒绝,并使用默认值。
错误
| 代码 | 含义 | 处理方法 |
|---|---|---|
not_found | 网站已响应,但没有此内容。 | 确认该 ID 来自列表,而非手动输入。 |
invalid_input | 参数无法生成请求。 | 阅读消息,其中会指出相关参数。 |
rate_limited | 网站要求此客户端降低请求频率。 | 等待后重试。所请求的内容仍然存在。 |
parse_failure | 收到的响应格式无法读取。 | 连同使用的参数一起报告。 |
network_error | 请求未能完成。 | 重试。 |
timeout | 截止时间内未收到响应。 | 重试,或调高 TVS_BUDGET_MS。 |
作为库使用
读取网站的这一层单独发布,包含请求间隔控制、存储和错误代码,不附带任何协议。
import { TvSubtitlesClient } from "mcp-tvsubtitles/client";
const client = new TvSubtitlesClient();
const found = await client.searchShows("Smallville");
const season = await client.getSeason(found.data.rows[0].id, 0);
console.log(season.data.showName, season.data.season, season.data.episodes.length);
每次读取都会返回 { data, cached },如果有行被省略,还会包含 skipped。构造函数接收 { config, logger, fetchImpl },并会遵守传入值对应的间隔下限。
节奏控制与署名
每次只发送一个请求,间隔两秒;如果网站施加限制,就逐步延长间隔,连续收到正常响应后再逐步缩短。间隔下限为 1.5 秒,无法再缩短。Agent 标识包含项目名称、版本和此仓库的地址,以便网站联系相关人员。
字幕是由编写并校准时间轴的人制作的。本服务读取目录,不下载字幕文件:每条记录都包含 page_url,这是读者打开后可以下载字幕的页面。展示结果时,请注明 tvsubtitles.net 并链接到该页面。
此 MCP 服务与 tvsubtitles.net 无隶属关系。
隐私
无需账户、密钥,也没有遥测。唯一访问的主机是
https://www.tvsubtitles.net。页面会在内存中保留十五分钟,不会写入磁盘。诊断信息会输出到 stderr。请参阅 PRIVACY.md。
开发
npm install
npm run build:fixtures
npm test
npm run coverage
npm run check
npm run test:live 会针对网站的每个路由发送一个请求,并且每晚运行。
贡献
欢迎提交问题和拉取请求。请参阅 CONTRIBUTING.md 和 SECURITY.md。
许可证
MIT,详见 LICENSE。
mcp-tvsubtitles(法语)
TVsubtitles.net 收录了电视剧字幕。用户会为某一集上传一个与特定视频版本同步的文件,网站会记录其语言、适配的视频版本、上传者、上传时间、文件大小和下载次数。网站收录了约三十万条字幕,覆盖约八万六千集内容,涉及二十四种语言。
此服务将对话客户端连接到该目录。你可以搜索剧集,查看某一季中每集有哪些语言有字幕,查看某一集的字幕条目,并打开某条字幕的详情,查看其适配的视频版本和上传者。每条字幕都附有其网站页面的地址。无需 API 密钥或账户。
安装
一键安装
Claude Code
claude mcp add tvsubtitles -- npx -y mcp-tvsubtitles
任何读取 mcpServers 的客户端
{
"mcpServers": {
"tvsubtitles": {
"command": "npx",
"args": ["-y", "mcp-tvsubtitles"]
}
}
}
使用 Docker
{
"mcpServers": {
"tvsubtitles": {
"command": "docker",
"args": ["run", "--rm", "-i", "ghcr.io/smeet666/mcp-tvsubtitles:1.0.1"]
}
}
}
容器只会连接到 https://www.tvsubtitles.net。
Bundle,无需 npm
从
最新发布版本
下载 mcp-tvsubtitles.mcpb,然后使用可安装 MCP bundle 的宿主打开。它包含所需依赖,因此只需 Node 24 或更高版本。
可以提出的问题
- “tvsubtitles 上有 Smallville 的法语字幕吗?”
- “Harbour Lights 第 3 季有哪些语言的字幕?”
- “列出本季第 7 集的英语字幕。”
- “这条字幕适配哪个版本,是谁上传的?”
- “帮我找到最后一集波兰语字幕的下载页面。”
工具
| 工具 | 功能 |
|---|---|
search_titles | 按名称查找剧集,并返回其他工具使用的 id。 |
list_subtitles | 查看某一季的概览,或某一集的条目。 |
get_subtitle | 查看某个条目及其版本、上传者和下载页面。 |
list_languages | 列出目录中的语言,或某部剧集提供的语言。 |
search_titles
按名称在目录中搜索。该网站只收录电视节目,因此搜索电影时会被拒绝,而不是返回结果。
| 参数 | 类型 | 必填 | 功能 |
|---|---|---|---|
query | 字符串,1 至 120 个字符 | 是 | 剧集名称或名称的一部分。 |
media_type | movie | tv | any | 否 | tv 和 any 会在目录中搜索。movie 会被拒绝。 |
year | 整数,1900 至 2100 | 否 | 仅保留已发布年份范围包含该年份的条目。 |
limit | 整数,1 至 100,默认值为 20 | 否 | 返回的条目数。 |
with_counts | 布尔值,默认值为 false | 否 | 从目录索引读取每个条目的字幕、剧集和季数统计,但需要额外发起一次请求。 |
返回内容: 找到的剧集,每部剧集都包含其他工具使用的 id、网站公布的年份,以及网站显示旗帜的语言。imdb_id 和 tmdb_id 的值为 null,因为该网站的搜索结果不会公布这两项信息。除非 with_counts 请求统计数据,否则 subtitle_count、episode_count 和 season_count 的值为 null,因为网站是在目录索引中公布这三项数字,而不是在搜索结果页面中公布;每项统计都汇总该剧集的所有季,counts_scope 会说明这一点;各项统计分别读取;如果某部剧集在索引中没有任何条目,则这三项的值均为 null。total_available 统计此次搜索返回的条目数,total_counts 会说明这一点。未能匹配任何结果的年份会被忽略,并列在 filters_dropped 中。
list_subtitles
读取某个剧集提供的内容,具体读取哪一种由 kind 指定。
| 参数 | 类型 | 必填 | 作用 |
|---|---|---|---|
id | 1 到 12 个字符的字符串 | 是 | 来自 search_titles 的剧集 id。 |
season | 1 到 200 的整数 | 否 | 省略时读取最新一季。 |
episode | 1 到 500 的整数 | 否 | 指定后,响应会包含该集的字幕条目。 |
language | 1 到 40 个字符的字符串 | 否 | 来自 list_languages 的语言,可用名称、代码或 BCP 47 标签指定。 |
limit | 1 到 200 的整数,默认值为 40 | 否 | 返回的行数。 |
**返回内容:**仅指定季时,kind 为 coverage,每行对应一集,包含 episode_id、网站统计的字幕数量,以及有字幕的语言。指定具体集时,kind 为 subtitles,每行都是一个字幕条目,包含可供 get_subtitle 使用的 id。season 是网站提供的季,season_requested 是请求的季;读取最新一季时,两者可能不同。seasons_available 列出该剧集提供的季。如果指定的语言没有任何字幕,响应会忽略该限制并返回结果,同时在 filters_dropped 中注明该语言。
get_subtitle
根据 list_subtitles 返回的 id 读取字幕条目。
| 参数 | 类型 | 必填 | 作用 |
|---|---|---|---|
id | 1 到 12 个字符的字符串 | 是 | 来自 list_subtitles 的字幕条目 id。 |
**返回内容:**字幕条目,其中 page_url 是读者可打开以下载文件的页面。此处 read_from 的值为 record;对于来自 list_subtitles 的行,read_from 的值为 listing。该字段用于区分未读取的字段和网站未发布的字段:列表不包含 file_name、size_text 或 comment,这些信息只有在条目页面上才会由网站显示。releases 包含网站发布的视频版本,release_match 表示网站是否发布了匹配版本:有则为 stated,没有则为 none,因此标记为 none 的条目并未说明字幕对应的视频版本。约三分之二的条目中,uploader 为 null。published_at 是网站时间戳,以 ISO 8601 格式读取,不包含时区;published_text 保留网站上的原始表述。rating 包含网站公布的两个计数器,其中零表示网站明确显示了 0。
list_languages
列出网站收录的语言,或某个剧集提供的语言。
| 参数 | 类型 | 必填 | 作用 |
|---|---|---|---|
id | 1 到 12 个字符的字符串 | 否 | 剧集 id,用于读取该剧集提供的语言。 |
season | 1 到 200 的整数 | 否 | 指定统计哪一季。不提供 id 时会忽略。 |
**返回内容:**每种语言都包含网站显示的名称、网站用于标识该语言的两字母 site_code、能够确定对应关系时提供的 BCP 47 code,以及 differs_from_iso。scope 说明统计范围:整个网站为 catalogue;传入剧集 id 时为 season,此时 count 表示该季中提供该语言字幕的集数。
语言与网站代码
网站绘制了二十四面旗帜,并为每种语言指定了自选的两字母代码。其中六种与 ISO 639-1 不同,且有一种会产生冲突:网站用 br 表示巴西葡萄牙语,而 ISO 将该代码分配给布列塔尼语。
| 网站代码 | 语言 | BCP 47 |
|---|---|---|
br | 巴西葡萄牙语 | pt-BR |
gr | 希腊语 | el |
cz | 捷克语 | cs |
jp | 日语 | ja |
cn | 中文 | zh |
ua | 乌克兰语 | uk |
language 保留网站使用的名称,language_code 则存放标签,因此无需根据两个字母推断任何信息。list_subtitles 接受以上三种写法中的任意一种语言。
配置
无需进行任何设置。以下变量均为可选项。
| 变量 | 默认值 | 范围 | 作用 |
|---|---|---|---|
TVS_USER_AGENT | 未设置 | 添加在服务端 Agent 前面;服务端 Agent 仍会保留。 | |
TVS_MIN_INTERVAL_MS | 2000 | 1500 到 60000 | 两次请求之间的毫秒数。1500 是下限。 |
TVS_TIMEOUT_MS | 20000 | 1000 到 120000 | 单次尝试的超时时间。 |
TVS_BUDGET_MS | 60000 | 5000 到 600000 | 一次读取的超时时间,包括重试。 |
TVS_MAX_RETRIES | 3 | 0 到 8 | 首次尝试之后的重试次数。 |
TVS_CACHE_TTL_MS | 900000 | 0 到 86400000 | 页面在内存中的保留时长。0 表示关闭缓存。 |
TVS_CACHE_MAX_ENTRIES | 200 | 1 到 5000 | 最旧的页面被移除前保留的页面数。 |
TVS_MAX_BODY_BYTES | 8000000 | 100000 到 64000000 | 单个页面可读取的最大响应大小。 |
TVS_LOG_LEVEL | error | silent、error、info、debug | 输出到 stderr 的日志级别。 |
超出范围的值会被拒绝并显示在 stderr 中,随后使用默认值。
错误
| 代码 | 含义 | 处理方式 |
|---|---|---|
not_found | 网站已响应,但没有此项内容。 | 确认 ID 来自列表,而非自行构造。 |
invalid_input | 参数无法生成请求。 | 阅读错误消息,其中会指出具体参数。 |
rate_limited | 网站要求此客户端降低请求频率。 | 等待后重试。请求的内容仍然存在。 |
parse_failure | 收到的响应格式无法读取。 | 连同所用参数一起报告此问题。 |
network_error | 请求未能完成。 | 重试。 |
timeout | 在时限内没有收到响应。 | 重试,或增大 TVS_BUDGET_MS。 |
作为库
读取网站的这一层单独发布,具有自己的请求节奏、缓存和错误代码,不绑定任何协议。
import { TvSubtitlesClient } from "mcp-tvsubtitles/client";
const client = new TvSubtitlesClient();
const found = await client.searchShows("Smallville");
const season = await client.getSeason(found.data.rows[0].id, 0);
console.log(season.data.showName, season.data.season, season.data.episodes.length);
每次读取都会返回 { data, cached },如果有行被跳过,还会包含 skipped。构造函数接收 { config, logger, fetchImpl },无论传入什么值,间隔下限都不会改变。
请求节奏与署名
一次只发送一个请求,间隔两秒;当网站要求放慢时延长间隔,连续收到正常响应后缩短间隔。间隔下限为一秒半,无法调低。Agent 字符串包含项目名称、版本和此仓库的地址,以便网站联系相关人员。
字幕由撰写和校准字幕的人创作。本服务器读取目录,不下载任何字幕文件:每条记录都包含 page_url,也就是读者可打开并下载字幕的页面。展示结果时,请注明 tvsubtitles.net 并链接到该页面。
此 MCP 服务与 tvsubtitles.net 无关联。
隐私
无需账户或密钥,也没有遥测。唯一连接的主机是
https://www.tvsubtitles.net。页面会在内存中缓存十五分钟,不会写入磁盘。诊断信息输出到 stderr。请参阅
PRIVACY.md。
开发
npm install
npm run build:fixtures
npm test
npm run coverage
npm run check
npm run test:live 会针对网站的每个路由发送一个请求,并且每晚运行。
参与贡献
欢迎提交 issues 和 pull requests。请参阅 CONTRIBUTING.md 和 SECURITY.md。
许可证
MIT,详见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。