CaptionPipe

Uma chamada grava legendas no seu vídeo. Hospedado, pré-pago, sem assinatura. MP4 mais SRT e VTT.

Servidor MCP hospedado

npx add-mcp 'https://api.captionpipe.com/mcp'

Instala no Claude Code, Codex, Cursor e outros

Documentação

Conecte-se e depois legendas.

Escolha a ferramenta em que você está. Clientes interativos entram pelo navegador; ferramentas de automação usam uma chave do painel. De qualquer forma, são as mesmas quatro ferramentas, e um vídeo em uma URL é uma única chamada.

MCP

https://api.captionpipe.com/mcp

REST

https://api.captionpipe.com/v1

Claude Code

Entre, ou use uma chave

Um comando adiciona o servidor. Entre uma vez e ele estará disponível em todos os seus projetos.

  1. 1 Adicione o servidor e entre
    claude mcp add --transport http captionpipe https://api.captionpipe.com/mcp
    claude
    > /mcp        # choose captionpipe, finish sign-in in the browser
    
  2. 2 Pergunte
    Caption https://cdn.acme.com/clip.mp4 with the highlight preset. Get "Acme" and "SK-7" spelled right, and give me the MP4 and the SRT.
    

Um arquivo na sua máquina

Forneça o caminho. O Claude Code chama create_upload, envia os bytes e depois caption_video. Você não faz nada disso manualmente.

Outras formas de acesso

Em vez do comando no passo 1

Ou adicione-o ao repositório

O Claude Code ignora uma entrada remota sem tipo e avisa que ela precisa de um. A maioria dos trechos online omite isso.

{
  "mcpServers": {
    "captionpipe": { "type": "http", "url": "https://api.captionpipe.com/mcp" }
  }
}

Em vez de entrar

Com uma chave de API

Crie uma chave no painel em Conectar. Ela é exibida apenas uma vez.

claude mcp add --transport http captionpipe https://api.captionpipe.com/mcp \
  --header "Authorization: Bearer $CAPTIONPIPE_API_KEY"

Verificado com Claude Code 2.1.263 em 8 de setembro de 2026.

Ferramentas

As quatro ferramentas

Os caminhos REST são /v1/create_upload, /v1/caption_video, /v1/jobs/{id} e /v1/render_captions. As ferramentas MCP aceitam o mesmo JSON como argumentos.

create_upload{ contentLength?, sha256?, idempotencyKey? }

→ { jobId, uploadUrl, expiresAt }

Apenas para um arquivo do seu lado. Retorna uma URL somente-PUT para um objeto, válida por uma hora. Declare contentLength se você souber o tamanho em bytes e a URL estiver vinculada a ele; omita-o e o limite de 2 GB será verificado quando caption_video for executado. O objeto é selado quando caption_video é executado. Se o seu vídeo já estiver em uma URL, pule esta ferramenta completamente.

caption_video{ jobId | inputUrl, preset, highlightColor?, dictionary?, language?, idempotencyKey? }

→ { jobId, status: "probing" }

Exatamente uma fonte: o jobId de create_upload ou um link direto para um arquivo de vídeo. Páginas de plataformas como YouTube ou TikTok são recusadas. preset é highlight, clean ou boxed. dictionary tem até 1.000 termos de até seis palavras cada, mantidos para este job e excluídos com seus arquivos. language é auto ou uma tag BCP-47. highlightColor é um RGB hexadecimal para a palavra falada e se aplica apenas ao preset highlight; o padrão é o accent do CaptionPipe.

get_caption_job{ jobId }

→ o job, com artefatos uma vez concluído

Faça polling. retryAfterSeconds informa quando voltar enquanto o job está em execução. Uma vez concluído, os artefatos são links assinados válidos até expiresAt, 24 horas após a conclusão; depois disso, o job responde job_not_found. Após uma chamada render_captions, render informa qual versão foi solicitada e se ainda está renderizando, concluída ou falhou; os links sempre pertencem à versão finalizada mais recente. Cada resposta carrega seu saldo, para que um agente nunca descubra um saldo vazio ao encontrar um erro.

render_captions{ jobId, words, preset?, highlightColor?, idempotencyKey? }

→ o job, com render.status aceito

Envie o words.json editado e queimamos o vídeo novamente exatamente com essas palavras. Nenhum modelo de fala é executado. Opcionalmente, altere o preset ou a cor de destaque. Grátis, 3 vezes por job em conta paga e 1 na conta de teste, dentro de 24 horas após a conclusão; a janela e os arquivos expiram juntos. Faça polling de get_caption_job até render.status ser completed, quando os links mudam para a nova versão. Sem um idempotencyKey, cada chamada usa um re-render da cota.

Status

Status do job

Um formato de resposta em todos os lugares: MCP, REST e o painel leem o mesmo objeto.

upload_pending

create_upload emitiu uma URL; os bytes ainda não chegaram.

probing

Estamos verificando se é um vídeo dentro dos limites. Nada é cobrado ainda.

reserved

Duração conhecida; os segundos são retidos no seu saldo e a fala está prestes a começar.

processing

Fala e queima. retryAfterSeconds informa quando fazer polling novamente.

completed

Artefatos prontos. chargedSeconds é final e nunca excede a retenção.

failed

Um erro tipado. A retenção é liberada e nada é cobrado.

{
  "jobId": "job_9f2",
  "status": "completed",
  "preset": "highlight",
  "durationSeconds": 42,
  "chargedSeconds": 42,
  "retryAfterSeconds": null,
  "balance": {
    "remainingSeconds": 258,
    "trialRemainingSeconds": 0,
    "paidRemainingSeconds": 258,
    "reservedSeconds": 0,
    "topUpUrl": null
  },
  "balanceWarning": null,
  "rerendersRemaining": 3,
  "dictionaryCapacityApplied": 1000,
  "artifacts": {
    "mp4":       { "url": "https://...", "expiresAt": "2026-09-04T12:00:00Z" },
    "srt":       { "url": "https://...", "expiresAt": "..." },
    "vtt":       { "url": "https://...", "expiresAt": "..." },
    "ass":       { "url": "https://...", "expiresAt": "..." },
    "wordsJson": { "url": "https://...", "expiresAt": "..." }
  },
  "expiresAt": "2026-09-04T12:00:00Z",
  "error": null,
  "render": null
}

Erros

Erros

Um envelope, um código legível por máquina e uma mensagem escrita para ser a solução. Nenhum erro é cobrado: a retenção, se houve, é devolvida.

{
  "ok": false,
  "error": {
    "code": "insufficient_balance",
    "message": "This video needs 0:42 and 0:18 is available. No job was started.",
    "retryable": false,
    "details": { "requiredSeconds": 42, "remainingSeconds": 18 }
  },
  "balance": { "remainingSeconds": 18, "reservedSeconds": 0, "topUpUrl": "https://..." }
}
CódigoQuandoRepetirO que fazer
unauthenticatedChave ou token ausente ou inválido. HTTP 401.NãoVerifique o cabeçalho Authorization ou entre novamente no seu cliente.
job_not_foundjobId desconhecido ou pertencente a outra conta.NãoUse o jobId da resposta que o criou.
invalid_sourceAmbos ou nenhum de jobId e inputUrl.NãoEnvie exatamente um.
invalid_requestArgumentos malformados, ou um dicionário ou lista de palavras com formato incorreto.NãoA mensagem nomeia o campo.
upload_incompletecaption_video chamado antes do PUT terminar.SimConclua o upload e chame novamente com o mesmo jobId.
upload_url_expiredPUT tentado após a janela de uma hora.NãoChame create_upload novamente para uma URL nova.
checksum_mismatchVocê enviou um sha256 e os bytes enviados não correspondem.NãoEnvie o arquivo novamente ou omita o hash.
file_size_limit_exceededAcima de 2 GB, em create_upload ou no meio do fluxo.NãoComprima ou divida o arquivo.
invalid_mediaO arquivo não pôde ser lido como vídeo com áudio utilizável.NãoVerifique se ele reproduz e tem áudio e envie novamente.
probe_failedO arquivo não pôde ser inspecionado.NãoReencode para H.264 em MP4 e tente novamente.
unsupported_ratioQuadrado ou proporção incomum.NãoUse um vídeo 9:16 ou 16:9. Os detalhes trazem largura e altura.
unsupported_inputCodec não suportado ou taxa de quadros acima do limite.NãoReencode para H.264 a 60 fps ou menos.
duration_limit_exceededAcima de 30 minutos.NãoCorte o vídeo.
trial_duration_limit_exceededAcima de 3 minutos em conta de teste.NãoUse um vídeo mais curto ou compre minutos para legendar até 30:00.
insufficient_balanceO vídeo custa mais segundos do que você tem. Verificado após a sondagem, antes de qualquer fala.Após recargatopUpUrl na resposta leva direto ao checkout.
trial_concurrency_limitUm segundo job enquanto um job de teste está em execução.SimAguarde o job em execução.
concurrency_limitMais de 3 dos seus jobs em execução, ou o serviço está na capacidade máxima.SimAguarde um job terminar e repita.
unsupported_source_urlUma página de plataforma em vez de um arquivo de vídeo, conteúdo que não é vídeo, ou um endereço ao qual nunca nos conectamos (privado, local, metadados).NãoPasse uma URL https pública direta para o arquivo de mídia ou envie o arquivo.
url_fetch_failedO host não resolveu, conectou ou respondeu 200; muito lento para iniciar ou terminar; muitos redirecionamentos.Quando transitórioVerifique se a URL serve o arquivo diretamente ou envie-o.
rerenders_exhaustedrender_captions além da cota.NãoInicie um novo job.
rerender_window_expiredrender_captions mais de 24 horas após a conclusão.NãoInicie um novo job.
processing_unavailableAmbos os fornecedores de fala estão fora do ar, ou um job não pôde ser despachado.SimSe a chamada foi recusada, repita-a com o mesmo idempotencyKey após retryAfterSeconds. Se um job retornou failed, envie-o novamente com um novo.

Limites

Limites

Cada um destes é verificado antes de você ser cobrado, então um arquivo que não podemos aceitar não custa nada.

Duração

Até 30 minutos

Tamanho

Até 2 GB

Saída

1080p H.264, teto de 60 fps

Formato

Retrato primeiro. 16:9 suportado. Quadrado é recusado antes de você ser cobrado

Arquivos

Disponíveis por 24 horas após o job terminar

Por chamada

Um vídeo

Cobrança

Cobrança e reembolsos

  • Cada job é cobrado pelo segundo inteiro da duração do vídeo, arredondado para cima, contra um saldo pré-pago.
  • Segundos de teste são usados antes dos segundos pagos. Um job pode abranger ambos.
  • Quando um job começa, retemos os segundos sondados; o painel mostra a retenção como reservado. Na conclusão, a retenção vira a cobrança, nunca mais. Na falha, a retenção é devolvida.
  • $10 compram 250 minutos, blocos de 1 a 10 por checkout. Sem assinatura, nada renova, minutos pagos nunca expiram.
  • Cada resposta carrega balance.topUpUrl. É null até você estar com saldo baixo ou bloqueado; então é um link de checkout que um agente pode entregar a você.
  • Minutos pagos não utilizados são reembolsáveis mediante solicitação, líquidos da taxa de cartão que a Stripe retém. O teste não é.

Solução de problemas

Solução de problemas

O job fica em probing ou processing

Faça polling de get_caption_job e respeite retryAfterSeconds. Um job que não pode ser concluído falha em minutos com a retenção devolvida; ele nunca fica preso para sempre.

O link do artefato retorna 403

Os links expiram 24 horas após a conclusão, e os arquivos também. Inicie um novo job.

Meu cliente não lista ferramentas

Recarregue ou reinicie o cliente após editar sua configuração e verifique o formato da configuração para esse cliente acima. Blocos do Cursor e do VS Code não são intercambiáveis.

O login abre, mas o cliente nunca conecta

Conclua a etapa do navegador na mesma máquina em que o cliente roda. Se ainda falhar, crie uma chave de API no painel e use o formato de chave da configuração.

Um nome está escrito errado

Envie-o no dicionário da próxima vez. Para este job, edite words.json e chame render_captions; o re-render é grátis.

A resposta diz dictionaryCapacityApplied: 0

Nosso fornecedor principal de fala estava indisponível e o fallback rodou sem o dicionário. Re-renderize com as palavras corrigidas ou execute o job novamente mais tarde.