TVsubtitles
Pesquise séries de TV em tvsubtitles.net, veja a cobertura de legendas de uma temporada e um registro. Sem chave de API.
Documentação
mcp-tvsubtitles
TVsubtitles.net cataloga legendas para séries de televisão. Seus leitores enviam um arquivo para um episódio, sincronizado com um lançamento de vídeo específico, e o site registra o idioma, o lançamento para o qual foi cortado, quem o enviou e quando, o tamanho do arquivo e quantas vezes ele foi baixado. Ele contém cerca de trezentas mil legendas, distribuídas por cerca de oitenta e seis mil episódios em vinte e quatro idiomas.
Este servidor conecta um cliente de chat a esse catálogo. Você pode pesquisar por uma série, ler uma temporada e ver quais idiomas possuem algo para cada episódio, ler os registros de um episódio e abrir um registro com o lançamento para o qual foi cortado e quem o enviou. Cada registro carrega o endereço de sua página no site. Nenhuma chave de API e nenhuma conta são necessárias.
Instalação
Instalação com um clique
Claude Code
claude mcp add tvsubtitles -- npx -y mcp-tvsubtitles
Qualquer cliente que leia mcpServers
{
"mcpServers": {
"tvsubtitles": {
"command": "npx",
"args": ["-y", "mcp-tvsubtitles"]
}
}
}
Com Docker
{
"mcpServers": {
"tvsubtitles": {
"command": "docker",
"args": ["run", "--rm", "-i", "ghcr.io/smeet666/mcp-tvsubtitles:1.0.1"]
}
}
}
O contêiner alcança https://www.tvsubtitles.net e nada mais.
Pacote, sem npm
Baixe mcp-tvsubtitles.mcpb do
último lançamento e
abra-o com um host que instala pacotes MCP. Ele carrega suas dependências, então
Node 24 ou posterior é tudo o que precisa.
O que você pode perguntar
- "O tvsubtitles tem legendas em francês para Smallville?"
- "Quais idiomas cobrem a temporada 3 de Harbour Lights?"
- "Liste as legendas em inglês para o episódio 7 dessa temporada."
- "Para qual lançamento essa legenda está sincronizada e quem a enviou?"
- "Encontre-me a página para baixar a legenda em polonês para o final."
Ferramentas
| Ferramenta | O que faz |
|---|---|
search_titles | Encontra uma série de televisão pelo nome e retorna o id que as outras usam. |
list_subtitles | Lê a cobertura de uma temporada, ou os registros de legendas de um episódio. |
get_subtitle | Lê um registro, com seu lançamento, seu remetente e sua página de download. |
list_languages | Lista os idiomas que o catálogo possui, ou os que uma série possui. |
search_titles
Pesquisa o catálogo pelo nome. O site cataloga apenas televisão, então uma pesquisa por um filme é recusada em vez de respondida.
| Argumento | Tipo | Obrigatório | O que faz |
|---|---|---|---|
query | string, 1–120 caracteres | sim | O nome de uma série, ou parte dela. |
media_type | movie | tv | any | não | tv e any pesquisam o catálogo. movie é recusado. |
year | inteiro, 1900–2100 | não | Mantém linhas cujos anos publicados cobrem este. |
limit | inteiro, 1–100, padrão 20 | não | Linhas a renderizar. |
with_counts | booleano, padrão falso | não | Lê as contagens de legendas, episódios e temporadas de cada linha do índice do catálogo, ao custo de uma solicitação adicional. |
Em retorno: as séries correspondentes, cada uma com o id que as outras ferramentas usam, os
anos que o site publica e os idiomas para os quais ele exibe uma bandeira. imdb_id e
tmdb_id são nulos, porque a pesquisa do site não publica nenhum. subtitle_count,
episode_count e season_count são nulos a menos que with_counts os solicite,
já que o site publica esses três no índice do catálogo em vez de na
página que uma pesquisa responde; cada um conta todas as temporadas da série juntas, o que
counts_scope nomeia, cada um é lido por conta própria, e uma série que o índice não carrega
linha para mantém três nulos. total_available conta as linhas que esta pesquisa
retornou, o que total_counts nomeia. Um ano que não deixa nada é deixado de lado
e nomeado em filters_dropped.
list_subtitles
Lê o que uma série possui, em uma de duas formas que kind nomeia.
| Argumento | Tipo | Obrigatório | O que faz |
|---|---|---|---|
id | string, 1–12 caracteres | sim | Um id de série de search_titles. |
season | inteiro, 1–200 | não | Omitido, a temporada mais recente que o site possui é lida. |
episode | inteiro, 1–500 | não | Nomeado, a resposta são os registros desse episódio. |
language | string, 1–40 caracteres | não | Um idioma de list_languages, por nome, código do site ou tag BCP 47. |
limit | inteiro, 1–200, padrão 40 | não | Linhas a renderizar. |
Em retorno: com apenas uma temporada, kind lê coverage e cada linha é um
episódio, carregando episode_id, o número de legendas que o site conta e os
idiomas que possuem algo. Com um episódio nomeado, kind lê subtitles e
cada linha é um registro carregando o id que get_subtitle usa. season é a
temporada que o site serviu e season_requested a que foi solicitada, que
diferem quando a mais recente foi lida. seasons_available lista as temporadas que a série
possui. Um idioma que não possui nada é deixado de lado, a resposta volta
sem estreitamento, e filters_dropped o nomeia.
get_subtitle
Lê um registro de um id list_subtitles retornado.
| Argumento | Tipo | Obrigatório | O que faz |
|---|---|---|---|
id | string, 1–12 caracteres | sim | Um id de legenda de list_subtitles. |
Em retorno: o registro, com page_url para a página que um leitor abre para
baixar o arquivo. read_from lê record aqui e listing em uma linha
list_subtitles produziu, o que é o que distingue um campo não lido de um que o site
não publica: uma listagem não carrega file_name, nem size_text e nem
comment, porque o site imprime esses apenas na página do próprio registro. releases contém os lançamentos de vídeo que o site publicou e
release_match diz se ele publicou algum: stated onde publicou, none
onde não publicou, então um registro marcado none não diz nada sobre qual vídeo está
sincronizado. uploader é nulo em aproximadamente dois registros em três. published_at
é o carimbo do site lido em ISO 8601 e não carrega fuso horário, e
published_text mantém a própria redação do site. rating contém dois contadores que o
site publica, onde um zero é uma figura que ele imprimiu.
list_languages
Lista os idiomas que o site cataloga, ou os que uma série possui.
| Argumento | Tipo | Obrigatório | O que faz |
|---|---|---|---|
id | string, 1–12 caracteres | não | Um id de série, para ler o que essa série possui. |
season | inteiro, 1–200 | não | Qual temporada medir uma série. Ignorado sem id. |
Em retorno: cada idioma com o nome que o site imprime, o site_code de duas letras
pelo qual ele aborda o idioma, o code BCP 47 onde esse mapeamento é
certo, e differs_from_iso. scope diz o que foi medido: catalogue para
o site inteiro, ou season quando um id de série foi passado, e count é então os
episódios dessa temporada que possuem o idioma.
Idiomas e os códigos que o site usa
O site exibe vinte e quatro bandeiras e aborda cada idioma por duas letras de
sua própria escolha. Seis delas diferem do ISO 639-1, e uma colide: o site
escreve br para português brasileiro, que o ISO atribui ao bretão.
| Código do site | Idioma | BCP 47 |
|---|---|---|
br | Português brasileiro | pt-BR |
gr | Grego | el |
cz | Tcheco | cs |
jp | Japonês | ja |
cn | Chinês | zh |
ua | Ucraniano | uk |
language mantém o próprio nome do site e language_code carrega a tag, então
nada precisa ser derivado das duas letras. list_subtitles aceita um
idioma escrito de qualquer uma das três maneiras.
Configuração
Nada precisa ser definido. Cada variável abaixo é opcional.
| Variável | Padrão | Faixa | O que faz |
|---|---|---|---|
TVS_USER_AGENT | não definido | Prefixado ao próprio agente deste servidor, que permanece anexado. | |
TVS_MIN_INTERVAL_MS | 2000 | 1500–60000 | Milissegundos entre duas solicitações. 1500 é um piso. |
TVS_TIMEOUT_MS | 20000 | 1000–120000 | Prazo para uma tentativa. |
TVS_BUDGET_MS | 60000 | 5000–600000 | Prazo para uma leitura, com suas tentativas incluídas. |
TVS_MAX_RETRIES | 3 | 0–8 | Tentativas após a primeira. |
TVS_CACHE_TTL_MS | 900000 | 0–86400000 | Quanto tempo uma página é mantida na memória. 0 desliga o armazenamento. |
TVS_CACHE_MAX_ENTRIES | 200 | 1–5000 | Páginas mantidas antes que a menos usada recentemente seja descartada. |
TVS_MAX_BODY_BYTES | 8000000 | 100000–64000000 | A maior resposta lida para uma página. |
TVS_LOG_LEVEL | error | silent, error, info, debug | O que chega ao stderr. |
Um valor fora de sua faixa é recusado no stderr e o padrão permanece.
Erros
| Código | O que significa | O que fazer |
|---|---|---|
not_found | O site respondeu e não possui tal coisa. | Verifique se o id veio de uma listagem, em vez de ser digitado manualmente. |
invalid_input | Os argumentos não puderam gerar uma requisição. | Leia a mensagem, que nomeia o argumento. |
rate_limited | O site pediu que este cliente diminuísse o ritmo. | Aguarde e pergunte novamente. A coisa solicitada ainda existe. |
parse_failure | Uma resposta chegou em um formato que não pode ser lido. | Reporte com os argumentos utilizados. |
network_error | A requisição não foi concluída. | Tente novamente. |
timeout | Nenhuma resposta chegou dentro do prazo. | Tente novamente, ou aumente TVS_BUDGET_MS. |
Como biblioteca
A camada que lê o site é publicada separadamente, com o ritmo, o armazenamento e os códigos de erro, e sem protocolo anexado.
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);
Cada leitura retorna { data, cached }, com skipped quando linhas foram omitidas.
O construtor recebe { config, logger, fetchImpl }, e o piso do intervalo
mantém o que for passado.
Ritmo e atribuição
Uma requisição por vez, com dois segundos de intervalo, aumentando quando o site pressiona e diminuindo novamente em uma sequência de respostas limpas. O piso de 1,5 segundo não pode ser reduzido. A string do agente carrega o nome do projeto, sua versão e o endereço deste repositório, para que o site possa contatar uma pessoa.
As legendas são o trabalho das pessoas que as escreveram e cronometraram. Este servidor lê
o catálogo e não baixa nenhum arquivo de legenda: cada registro carrega page_url,
que é a página que um leitor abre para baixá-lo. Dê crédito ao tvsubtitles.net e vincule
essa página ao exibir um resultado.
Este servidor MCP não é afiliado ao tvsubtitles.net.
Privacidade
Sem conta, sem chave, sem telemetria. O único host acessado é
https://www.tvsubtitles.net. As páginas são mantidas em memória por quinze minutos e
nada é gravado em disco. Os diagnósticos vão para o stderr. Veja PRIVACY.md.
Desenvolvimento
npm install
npm run build:fixtures
npm test
npm run coverage
npm run check
npm run test:live faz uma requisição por rota contra o site e roda
todas as noites.
Contribuindo
Issues e pull requests são bem-vindos. Veja CONTRIBUTING.md e SECURITY.md.
Licença
MIT, veja LICENSE.
mcp-tvsubtitles (francês)
TVsubtitles.net cataloga legendas de séries de televisão. Seus leitores enviam um arquivo para um episódio, sincronizado com uma versão de vídeo, e o site registra o idioma, a versão para a qual foi feito, quem o enviou e quando, o tamanho do arquivo e o número de vezes que foi baixado. Ele mantém cerca de trezentas mil, em cerca de oitenta e seis mil episódios, em vinte e quatro idiomas.
Este servidor conecta um cliente de conversa a esse catálogo. Pode-se buscar uma série, ler uma temporada vendo quais idiomas possuem algo para cada episódio, ler as fichas de um episódio e abrir uma ficha com a versão para a qual foi feita e quem a enviou. Cada ficha carrega o endereço de sua página no site. Nenhuma chave de API nem conta são necessárias.
Instalação
Instalação em um clique
Claude Code
claude mcp add tvsubtitles -- npx -y mcp-tvsubtitles
Qualquer cliente que leia mcpServers
{
"mcpServers": {
"tvsubtitles": {
"command": "npx",
"args": ["-y", "mcp-tvsubtitles"]
}
}
}
Com Docker
{
"mcpServers": {
"tvsubtitles": {
"command": "docker",
"args": ["run", "--rm", "-i", "ghcr.io/smeet666/mcp-tvsubtitles:1.0.1"]
}
}
}
O contêiner inclui https://www.tvsubtitles.net e nada mais.
Bundle, sem npm
Baixar mcp-tvsubtitles.mcpb da
última publicação
e abri-lo com um host que instale bundles MCP. Ele carrega suas
dependências, então Node 24 ou mais recente é suficiente.
O que se pode pedir
- «O tvsubtitles tem legendas em francês para Smallville?»
- «Quais idiomas cobrem a temporada 3 de Harbour Lights?»
- «Liste as legendas em inglês do episódio 7 desta temporada.»
- «Em qual versão esta legenda está sincronizada e quem a enviou?»
- «Encontre-me a página para baixar a legenda em polonês do último episódio.»
As ferramentas
| Ferramenta | O que faz |
|---|---|
search_titles | Encontra uma série pelo nome e retorna o id que as outras aceitam. |
list_subtitles | Lê a cobertura de uma temporada, ou as fichas de um episódio. |
get_subtitle | Lê uma ficha, com sua versão, seu remetente e sua página de download. |
list_languages | Lista os idiomas do catálogo, ou aqueles que uma série possui. |
search_titles
Busca no catálogo pelo nome. O site só cataloga televisão, portanto uma busca por filme é recusada em vez de respondida.
| Argumento | Tipo | Obrigatório | O que faz |
|---|---|---|---|
query | string, 1 a 120 caracteres | sim | O nome de uma série, ou uma parte. |
media_type | movie | tv | any | não | tv e any buscam no catálogo. movie é recusado. |
year | inteiro, 1900 a 2100 | não | Mantém as linhas cujos anos publicados cobrem este. |
limit | inteiro, 1 a 100, padrão 20 | não | Linhas a retornar. |
with_counts | booleano, padrão falso | não | Lê as contagens de legendas, episódios e temporadas de cada linha no índice do catálogo, ao custo de uma requisição extra. |
Em retorno: as séries encontradas, cada uma com o id que as outras
ferramentas aceitam, os anos publicados pelo site e os idiomas para os quais ele desenha
uma bandeira. imdb_id e tmdb_id valem null, já que a busca do site não
publica nenhum. subtitle_count, episode_count e season_count valem null
enquanto with_counts não os solicitar, pois o site publica esses três números
no índice de seu catálogo e não na página que responde a uma busca;
cada um conta todas as temporadas da série juntas, o que counts_scope
nomeia, cada um é lido separadamente, e uma série cujo índice não carrega nenhuma linha
mantém três null. total_available conta as linhas que esta busca
trouxe, o que total_counts nomeia. Um ano que não deixa nada é colocado de
lado e nomeado em filters_dropped.
list_subtitles
Lê o que uma série possui, em uma de duas formas que kind nomeia.
| Argumento | Tipo | Obrigatório | O que faz |
|---|---|---|---|
id | string, 1 a 12 caracteres | sim | Um id de série vindo de search_titles. |
season | inteiro, 1 a 200 | não | Omitido, a temporada mais recente é lida. |
episode | inteiro, 1 a 500 | não | Nomeado, a resposta carrega as fichas deste episódio. |
language | string, 1 a 40 caracteres | não | Um idioma de list_languages, pelo nome, código ou tag BCP 47. |
limit | inteiro, 1 a 200, padrão 40 | não | Linhas a retornar. |
Em retorno: com uma temporada apenas, kind vale coverage e cada linha é
um episódio, carregando episode_id, o número de legendas que o site conta e
os idiomas que possuem algo. Com um episódio nomeado, kind vale
subtitles e cada linha é uma ficha carregando o id que aceita
get_subtitle. season é a temporada servida pelo site e season_requested
a solicitada, ambas diferindo quando a mais recente foi lida.
seasons_available lista as temporadas que a série possui. Um idioma que não possui
nada é colocado de lado, a resposta retorna sem a restrição, e
filters_dropped o nomeia.
get_subtitle
Lê uma ficha a partir de um id retornado por list_subtitles.
| Argumento | Tipo | Obrigatório | O que faz |
|---|---|---|---|
id | string, 1 a 12 caracteres | sim | Um id de legenda vindo de list_subtitles. |
Em retorno: a ficha, com page_url para a página que um leitor abre para
baixar o arquivo. read_from vale aqui record, e listing em uma
linha vinda de list_subtitles: é isso que distingue um campo não lido de um
campo que o site não publica, pois uma lista não carrega nem file_name, nem
size_text, nem comment, que o site só imprime na página de uma ficha. releases carrega as versões de vídeo publicadas pelo
site e release_match diz se ele publicou uma: stated quando sim, none
quando não, portanto uma ficha marcada none não diz nada sobre o vídeo no qual
está sincronizada. uploader vale null em cerca de duas fichas em três.
published_at é o timestamp do site lido em ISO 8601 e não carrega nenhum fuso,
e published_text mantém a formulação do site. rating carrega dois contadores
que o site publica, onde um zero é um número que ele imprimiu.
list_languages
Lista os idiomas que o site cataloga, ou aqueles que uma série possui.
| Argumento | Tipo | Obrigatório | O que faz |
|---|---|---|---|
id | string, 1 a 12 caracteres | não | Um id de série, para ler o que esta série possui. |
season | inteiro, 1 a 200 | não | Em qual temporada medir. Ignorado sem id. |
Em retorno: cada idioma com o nome que o site imprime, o site_code de
duas letras pelo qual ele o endereça, o code BCP 47 quando a correspondência
é certa, e differs_from_iso. scope diz o que foi medido:
catalogue para o site inteiro, ou season quando um id de série foi passado, e
count vale então os episódios desta temporada que possuem o idioma.
Os idiomas e os códigos do site
O site desenha vinte e quatro bandeiras e endereça cada idioma por duas letras
de sua escolha. Seis diferem da ISO 639-1, e uma entra em colisão: o site
escreve br para o português brasileiro, que a ISO atribui ao bretão.
| Código do site | Idioma | BCP 47 |
|---|---|---|
br | Português brasileiro | pt-BR |
gr | Grego | el |
cz | Tcheco | cs |
jp | Japonês | ja |
cn | Chinês | zh |
ua | Ucraniano | uk |
language mantém o nome do site e language_code carrega a tag, então nada precisa
ser deduzido das duas letras. list_subtitles aceita um idioma escrito de uma
das três formas.
Configuração
Nada precisa ser ajustado. Todas as variáveis abaixo são opcionais.
| Variável | Padrão | Limites | O que faz |
|---|---|---|---|
TVS_USER_AGENT | ausente | Colocado antes do agente do servidor, que permanece anexado. | |
TVS_MIN_INTERVAL_MS | 2000 | 1500 a 60000 | Milissegundos entre duas requisições. 1500 é um piso. |
TVS_TIMEOUT_MS | 20000 | 1000 a 120000 | Tempo limite de uma tentativa. |
TVS_BUDGET_MS | 60000 | 5000 a 600000 | Tempo limite de uma leitura, incluindo novas tentativas. |
TVS_MAX_RETRIES | 3 | 0 a 8 | Tentativas após a primeira. |
TVS_CACHE_TTL_MS | 900000 | 0 a 86400000 | Duração de retenção de uma página em memória. 0 desativa o cache. |
TVS_CACHE_MAX_ENTRIES | 200 | 1 a 5000 | Páginas guardadas antes que a mais antiga saia. |
TVS_MAX_BODY_BYTES | 8000000 | 100000 a 64000000 | Maior resposta lida para uma página. |
TVS_LOG_LEVEL | error | silent, error, info, debug | O que chega ao stderr. |
Um valor fora dos limites é recusado no stderr e o padrão é aplicado.
Erros
| Código | O que significa | O que fazer |
|---|---|---|
not_found | O site respondeu e não possui essa coisa. | Verificar se o id vem de uma lista e não de uma construção. |
invalid_input | Os argumentos não podem produzir uma requisição. | Ler a mensagem, que nomeia o argumento. |
rate_limited | O site pede que este cliente desacelere. | Aguardar e tentar novamente. A coisa solicitada ainda existe. |
parse_failure | Uma resposta chegou em formato ilegível. | Reportar com os argumentos usados. |
network_error | A requisição não foi concluída. | Tentar novamente. |
timeout | Nenhuma resposta dentro do prazo. | Tentar novamente, ou ampliar TVS_BUDGET_MS. |
Como biblioteca
A camada que lê o site é publicada separadamente, com seu ritmo, seu cache e seus códigos de erro, sem protocolo anexado.
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);
Toda leitura retorna { data, cached }, com skipped quando linhas foram
descartadas. O construtor aceita { config, logger, fetchImpl }, e o piso
de intervalo se mantém independentemente do que for passado.
Ritmo e atribuição
Uma requisição por vez, dois segundos de intervalo, ampliado quando o site rejeita e reduzido após uma série de respostas limpas. O piso de um segundo e meio não pode ser reduzido. A string do agente carrega o nome do projeto, sua versão e o endereço deste repositório, para que o site possa contatar uma pessoa.
As legendas são obra de quem as escreveu e sincronizou. Este servidor lê
o catálogo e não baixa nenhum arquivo de legendas: cada ficha carrega
page_url, a página que um leitor abre para baixá-lo. Creditar
tvsubtitles.net e vincular essa página ao mostrar um resultado.
Este servidor MCP não é afiliado ao tvsubtitles.net.
Privacidade
Nenhuma conta, nenhuma chave, nenhuma telemetria. O único host contatado é
https://www.tvsubtitles.net. As páginas são mantidas por quinze minutos em memória
e nada é gravado no disco. Os diagnósticos vão para o stderr. Veja
PRIVACY.md.
Desenvolvimento
npm install
npm run build:fixtures
npm test
npm run coverage
npm run check
npm run test:live faz uma requisição por rota contra o site, e roda todas as
noites.
Contribuindo
Issues e pull requests são bem-vindas. Veja CONTRIBUTING.md e SECURITY.md.
Licença
MIT, veja LICENSE.