1. Início
  2. Servidor MCP
MCP · Model Context Protocol

Faça outreach por DM no TikTok pelo seu LLM

O servidor MCP do Hooka dá ao Claude, ao ChatGPT, ao Cursor ou ao seu próprio agente 26 ferramentas sobre a API do Hooka. Com elas, ele pode conectar contas do TikTok por QR, criar e lançar campanhas de DM, cuidar do inbox e gerenciar sua lista “Não contatar”. Use o servidor hospedado em mcp.hooka.to (login com OAuth ou envio de uma chave de API), ou rode-o localmente via stdio com npx hooka-mcp.

Última atualização: 30 de setembro de 2026 · hooka-mcp 0.3.0 · Pela equipe Hooka

O que é o servidor MCP do Hooka?

O servidor MCP do Hooka é um servidor Model Context Protocol. Ele expõe a API REST v1 do Hooka como ferramentas que o seu LLM pode chamar. Cada ferramenta corresponde a exatamente um endpoint de https://api.hooka.to/v1 e repassa a sua própria credencial (uma chave de API ou um token OAuth). O servidor não guarda credenciais, e valem os mesmos limites do lado do servidor de quando você chama a API diretamente.

Além das chamadas simples à API, o servidor faz algumas coisas pelo modelo:

  • Devolve o QR code de conexão como imagem, para que o assistente possa mostrá-lo a você.
  • Envia uma chave de idempotência nas ferramentas de escrita que aceitam uma, para que uma chamada repetida não crie uma segunda campanha nem envie uma segunda DM.
  • Transforma os erros da API em uma linha legível com o código do erro, o campo com problema e o id da requisição.

Os títulos e as descrições das ferramentas, as instruções do servidor, os prompts, os recursos e as notas e erros que o próprio servidor escreve (chave ausente, timeout, erro de rede) estão em espanhol. Escolher um prompt adiciona uma mensagem em espanhol à conversa. Os erros devolvidos pela API do Hooka chegam sem alteração, em inglês, assim como os erros de validação de schema (-32602).

26
ferramentas
12
só de leitura
3
prompts guiados
0.3.0
versão documentada

Como conectar o Hooka ao Claude, ChatGPT ou Cursor?

Há três formas de conectar. Todas dão acesso às mesmas 26 ferramentas:

OpçãoOnde rodaCredencialClientes típicos
Hospedado + OAuthhttps://mcp.hooka.to/mcp (Streamable HTTP)Login no Hooka e aprovação do acessoClaude.ai, Claude Desktop (Conectores), ChatGPT
Hospedado + chave de APIhttps://mcp.hooka.to/mcp (Streamable HTTP)Cabeçalho Authorization: Bearer hk_live_…Claude Code, Cursor, agentes próprios
LocalSua máquina, via stdio (npx hooka-mcp, Node.js 20+)Variável de ambiente HOOKA_API_KEYArquivo de configuração do Claude Desktop, Cursor, qualquer cliente stdio

Hospedado, com OAuth (Claude.ai, Claude Desktop, ChatGPT)

Adicione o Hooka como conector personalizado e cole esta URL. Não há nada para instalar nem chave para copiar:

https://mcp.hooka.to/mcp

O cliente descobre o servidor de autorização do Hooka, se registra e leva você ao Hooka para fazer login e aprovar o acesso (OAuth 2.1, com PKCE S256 obrigatório). Depois, as ferramentas aparecem. Alguns detalhes que vale saber:

  • A aprovação dá acesso total ao seu workspace, igual a uma chave de API live. A única exceção é o gerenciamento de chaves de API, que os tokens OAuth não podem fazer.
  • Os tokens de acesso duram 30 minutos. O cliente os renova com um refresh token, que dura 60 dias e é trocado a cada uso.
  • A tela de login e consentimento está só em espanhol.

Hospedado, com chave de API (Claude Code, Cursor, agentes próprios)

Os clientes que conseguem enviar cabeçalhos HTTP podem pular o OAuth e enviar sua chave. No Claude Code:

claude mcp add --transport http hooka https://mcp.hooka.to/mcp --header "Authorization: Bearer hk_live_..."

No Cursor (mcp.json) e em outros clientes que usam o formato url + headers:

{
  "mcpServers": {
    "hooka": {
      "url": "https://mcp.hooka.to/mcp",
      "headers": { "Authorization": "Bearer hk_live_..." }
    }
  }
}

O servidor hospedado não verifica a chave quando você conecta. Uma chave inválida ou revogada ainda lista as ferramentas, e então toda chamada de ferramenta devolve 401 authentication_error/invalid_api_key. Para conferir sua configuração, peça ao assistente para chamar get_workspace.

Local, via stdio (npx)

O pacote npm hooka-mcp roda o mesmo servidor na sua máquina, falando stdio. Adicione isto à configuração MCP do seu cliente:

{
  "mcpServers": {
    "hooka": {
      "command": "npx",
      "args": ["-y", "hooka-mcp"],
      "env": { "HOOKA_API_KEY": "hk_live_..." }
    }
  }
}

No Claude Desktop, isso vai em claude_desktop_config.json. Esse arquivo só carrega servidores locais, então use um conector para a URL hospedada. No Cursor, use os mesmos command, args e env. Requer Node.js 20 ou mais recente. O servidor local lê estas variáveis de ambiente:

  • HOOKA_API_KEY (obrigatória): sua chave. Sem ela, o servidor até inicia, mas toda ferramenta devolve um erro pedindo a chave.
  • HOOKA_API_BASE (opcional): a URL base da API. Padrão: https://api.hooka.to.
  • HOOKA_API_TIMEOUT_MS (opcional): o timeout de cada chamada à API. Padrão: 30000.

Esta página documenta o hooka-mcp 0.3.0, a versão por trás do servidor hospedado. As versões 0.1.x anteriores têm 23 ferramentas e não incluem a imagem do QR, a ferramenta de verificação nem o comportamento de novas tentativas descrito aqui. Antes de rodar localmente, confira qual versão o npx vai baixar com npm view hooka-mcp version. Se aparecer 0.1.x, a 0.2.0 ainda não está no npm: use o servidor hospedado até que esteja. Ao conectar, o servidor também informa a versão dele ao seu cliente (serverInfo).

Qual credencial o agente deve usar?

CredencialComo obterO que o agente pode fazer
hk_live_…A página Desenvolvedores do seu painel do Hooka (ela sempre cria chaves live), ou POST /v1/api_keysLer e escrever: ações reais nas suas contas reais do TikTok
hk_test_…POST /v1/api_keys com {"mode":"test"}, autenticado com uma chave liveSó leitura: toda ferramenta que escreve devolve 403 permission_error/test_key_read_only
Token OAuthEmitido quando você aprova o conector (só no servidor hospedado)Ler e escrever, como uma chave live. Não pode gerenciar chaves de API.

Não há sandbox. Uma chave de teste lê o seu workspace real; ela não simula envios. Funciona bem quando um agente só deve olhar: relatórios, resumos do inbox, estatísticas de campanha. Para criar uma, chame a API com uma chave live:

curl https://api.hooka.to/v1/api_keys \
  -H "Authorization: Bearer hk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"mode":"test","label":"agente só leitura"}'
{
  "id": "key_6a1e…",
  "object": "api_key",
  "mode": "test",
  "prefix": "hk_test_1a2b3c",
  "secret": "hk_test_1a2b3c…"
}

O secret aparece uma única vez. Com uma chave de teste, as leituras funcionam, incluindo get_workspace. Toda escrita falha do mesmo jeito, seja qual for a ferramenta:

403 permission_error/test_key_read_only: Test keys (hk_test_) are read-only: Hooka has no sandbox, so any write would act on your real TikTok accounts. Use an hk_live_ key to create, start or send. [request_id req_…]

Todas as chaves e tokens OAuth de um workspace compartilham o rate-limit dele, de 300 requisições à API por minuto, junto com qualquer tráfego direto à API.

O que o agente pode fazer? As 26 ferramentas

Cada ferramenta chama um endpoint da API v1 do Hooka. As ferramentas de leitura levam a anotação MCP readOnlyHint. As marcadas como destrutivas levam destructiveHint porque enviam DMs de verdade, cortam conexões ou voltam a permitir contato. Os clientes que respeitam as anotações podem perguntar a você antes de executá-las.

FerramentaO que fazChamada à APITipo
Senders (contas do TikTok) · 7
list_sendersTodas as contas do TikTok (senders) do workspace, em qualquer status, com status_reason, health, daily_limit e sent_today. Filtro opcional por status.GET /v1/sendersleitura
get_senderUm sender. É a ferramenta para consultar durante uma conexão: enquanto connection.status for requires_scan, o QR volta como imagem.GET /v1/senders/{id}leitura
create_senderComeça a conectar uma conta do TikTok por QR (sem senha). country é o país da conta: ela recebe lá seu próprio IP residencial dedicado, e o país não pode ser mudado depois. Devolve o sender em awaiting_scan, ainda sem QR. Ocupa uma vaga e cancela qualquer outra conexão em andamento no workspace.POST /v1/sendersdestrutiva
refresh_sender_connectionUma nova tentativa de conexão (QR novo) para um sender que não está conectado: expirado, desconectado, em pausa ou banido. Mantém o IP próprio do sender.POST /v1/senders/{id}/connection/refreshdestrutiva
verify_sender_connectionConclui o passo do TikTok de confirmar que é você depois da leitura do QR: escolhe e-mail ou telefone, envia o código ou pede um novo.POST /v1/senders/{id}/connection/verifyescrita
update_senderMuda o rótulo (label) de um sender, o único campo que a API pode editar.PATCH /v1/senders/{id}escrita
delete_senderDesconecta uma conta. O sender continua na lista como disconnected e a vaga dele é liberada. Também cancela uma conexão por QR em andamento desse sender. As campanhas rodando que ficam sem sender conectado são pausadas, e os follow-ups pendentes que só essa conta podia enviar são ignorados (sender_unavailable).DELETE /v1/senders/{id}destrutiva
Campanhas · 8
list_campaignsAs campanhas, da mais recente para a mais antiga. As arquivadas não aparecem.GET /v1/campaignsleitura
get_campaignUma campanha com estatísticas ao vivo: pending, processing, sent, failed, skipped, replied, reply_rate.GET /v1/campaigns/{id}leitura
create_campaignCria um rascunho. Aceita uma mensagem ou até 20 variações, até 10 follow-ups, até 1.000 targets, até 10 senders e configurações de ritmo. Não envia nada.POST /v1/campaignsescrita
add_targetsAdiciona até 1.000 targets por chamada. Numa campanha running, eles começam a receber DMs em segundos. Uma campanha completed reabre (resumed: true) se um dos senders dela estiver conectado. Se nenhum estiver, a resposta traz resume_blocked_reason: "no_connected_sender": reconecte um sender e depois chame start_campaign ou resume_campaign.POST /v1/campaigns/{id}/targetsdestrutiva
list_targetsOs targets na ordem em que foram adicionados, com o status e um código error estável quando um falhou ou foi ignorado. Filtro opcional por status.GET /v1/campaigns/{id}/targetsleitura
start_campaignComeça a enviar DMs de verdade. Funciona com um draft, uma campanha paused ou uma completed que ainda tem targets pendentes.POST /v1/campaigns/{id}/startdestrutiva
pause_campaignPausa uma campanha running. Uma DM que já está sendo enviada ainda pode sair.POST /v1/campaigns/{id}/pauseescrita
resume_campaignRetoma o envio de uma campanha paused, ou de uma completed que ainda tem targets pendentes.POST /v1/campaigns/{id}/resumedestrutiva
Inbox · 4
list_conversationsAs conversas pela atividade mais recente. Filtros opcionais por status e sender_id.GET /v1/conversationsleitura
get_conversationUma conversa: qual sender, a outra pessoa, o status, a contagem de não lidas e a última mensagem.GET /v1/conversations/{id}leitura
get_messagesAs mensagens de uma conversa, da mais antiga para a mais recente (in = a outra pessoa, out = você).GET /v1/conversations/{id}/messagesleitura
send_replyColoca na fila uma resposta de 1 a 2.000 caracteres. Ela sai como uma DM de verdade pelo sender da conversa em segundos.POST /v1/conversations/{id}/messagesdestrutiva
Lista “Não contatar” · 3
list_suppressionsOs usernames que nunca devem ser contatados, com o reason (manual, opt_out…).GET /v1/suppressionsleitura
add_suppressionsAdiciona de 1 a 1.000 usernames. Os targets pendentes deles em todas as campanhas são ignorados na hora.POST /v1/suppressionsescrita
remove_suppressionRemove um username. Isso pode voltar a permitir DMs para alguém que pediu para parar.DELETE /v1/suppressions/{username}destrutiva
Eventos, webhooks e workspace · 4
list_eventsOs eventos do workspace, os mesmos que os webhooks entregam, guardados por 30 dias. Navegue do mais recente para o mais antigo, ou consulte os eventos novos com after.GET /v1/eventsleitura
list_webhook_endpointsSeus endpoints de webhook, sem os segredos.GET /v1/webhook_endpointsleitura
create_webhook_endpointCria um endpoint (URL pública https://). Devolve o segredo de assinatura whsec_… uma única vez.POST /v1/webhook_endpointsescrita
get_workspaceWhoami: id do workspace, país padrão das contas novas (exit_ip.region) e vagas.GET /v1/workspaceleitura

As listas paginadas aceitam limit (1-100, padrão 50) e starting_after (o next_cursor da página anterior). Passe-o enquanto has_more for true. list_webhook_endpoints não é paginada.

Exemplos

Conectar uma conta do TikTok

Você diz: “Conecte minha conta do TikTok e coloque o rótulo Shop ES.” O agente então segue estes passos:

  1. get_workspace: confere se há uma vaga livre (seats.used < seats.limit; um limite null significa sem limite) e lê o país padrão (exit_ip.region). Se a conta for de outro país, o agente pergunta a você.
  2. create_sender {"label":"Shop ES","country":"ES"}: o sender volta em awaiting_scan, com connection.status "pending" e ainda sem QR. A conta recebe seu próprio IP residencial dedicado nesse país; enquanto ele está sendo preparado, exit_ip.status é "provisioning".
  3. get_sender a cada 3-5 segundos. connection.status passa por pending, requires_scan, scanned, às vezes verification_required, e termina com o sender connected.
  4. Em requires_scan, o resultado da ferramenta traz o QR como imagem, e você o escaneia com o app do TikTok. O QR se renova sozinho; o agente mostra o mais recente.
  5. Em verification_required, ele pergunta onde você quer receber o código e qual é o código. Depois chama verify_sender_connection, por exemplo {"id":"snd_…","action":"submit_code","code":"482913"}.

Assim fica um resultado de get_sender com o QR pronto (resumido):

{
  "content": [
    { "type": "text", "text": "{ \"id\": \"snd_…\", \"object\": \"sender\", \"status\": \"awaiting_scan\", \"connection\": { \"status\": \"requires_scan\", \"qr_code\": \"[QR adjunto como imagen en esta respuesta: …]\", … } }" },
    { "type": "image", "data": "iVBORw0KGgo…", "mimeType": "image/png" }
  ]
}

A tentativa falhou se connection.status virar expired ou failed (connection.error diz por quê), ou se o sender virar disconnected (status_reason diz por quê). O agente para de consultar e pode oferecer refresh_sender_connection para um QR novo. Conecte as contas uma de cada vez, porque cada nova tentativa cancela a que está em andamento.

Criar uma campanha e só iniciá-la depois da sua confirmação

Você diz: “Prepare um rascunho de campanha para estes dois criadores, com um follow-up depois de 3 dias, 90 segundos entre DMs e no máximo 40 por dia.” O agente chama:

{
  "name": "create_campaign",
  "arguments": {
    "name": "Criadores ES - outubro",
    "message": {
      "variants": [
        "Oi {{first_name}}, adorei seu último vídeo. Topa uma parceria paga?",
        "E aí, {{first_name}}! Estamos procurando criadores como você. Tem interesse?"
      ]
    },
    "follow_ups": [
      { "wait_days": 3, "variants": ["{{first_name}}, você chegou a ver minha mensagem?"] }
    ],
    "targets": [
      { "username": "@maria.ugc", "variables": { "first_name": "Maria" } },
      { "username": "@leo_creates", "variables": { "first_name": "Leo" } }
    ],
    "settings": { "rate_limit_seconds": 90, "daily_limit": 40 }
  }
}

O resultado é a campanha em "status": "draft", mais targets_accepted, target_ids e targets_skipped. Nada foi enviado até aqui. Algumas observações sobre os argumentos:

  • Sem settings.sender_ids, a campanha usa até 10 dos senders conectados mais antigos do workspace.
  • daily_limit limita a campanha inteira por dia. Cada conta também mantém o próprio limite diário.
  • Os follow-ups saem pela mesma conta que enviou a primeira DM, e param quando a pessoa responde.

Em seguida, o agente mostra um resumo e pergunta antes de chamar start_campaign {"id":"cmp_…"}. As instruções do servidor e o prompt launch_campaign mandam ele fazer isso.

Triar o inbox com uma chave só de leitura

Com uma chave hk_test_, você pode deixar um agente rodar list_conversations {"status":"open"} e get_messages, separar as respostas em interessado, dúvida, sem interesse ou spam, e escrever rascunhos de resposta para você. Ele não consegue enviá-las: send_reply devolve 403 test_key_read_only. Você revisa os rascunhos e os envia você mesmo, ou troca para uma chave live.

Ver o que aconteceu durante a noite

“O que aconteceu nas minhas campanhas desde ontem?” O agente lê list_events, por exemplo com type igual a target.replied ou sender.status_changed, e get_campaign para as estatísticas. O recurso hooka://event-types explica o que cada tipo de evento significa.

Prompts, recursos e instruções do servidor

Prompts (fluxos guiados que o usuário pode escolher nos clientes que os suportam):

  • launch_campaign (argumento opcional goal). Confere se há uma conta conectada, propõe uma mensagem com 2-3 variações e follow-ups, cria o rascunho e pede sua confirmação explícita antes de start_campaign.
  • triage_inbox. Percorre as conversas abertas, classifica-as e escreve rascunhos de respostas curtas. Espera o seu OK antes de qualquer send_reply.
  • connect_account (argumento opcional label). Executa o fluxo de QR descrito acima, incluindo o passo de verificação do TikTok.

Recursos (texto só de leitura; sem chamada à API, então funcionam com qualquer chave):

  • hooka://event-types lista os 12 tipos de evento de webhook mais o ping, com o significado de cada um.
  • hooka://api-reference cobre a URL base, os prefixos de id, a paginação, a idempotência, o formato de erro e o rate-limit.

As instruções do servidor são enviadas no initialize. Elas cobrem o seguinte: as chaves de teste são só de leitura, quais ferramentas enviam DMs de verdade e precisam da sua confirmação, o fluxo de conexão, a paginação, a idempotência e o formato de erro.

O que o agente não pode fazer?

O servidor MCP só pode fazer o que a API permite. Algumas coisas são exclusivas do painel ou não são expostas:

  • Cobrança, plano e país padrão. Assinar e mudar o país padrão são feitos no painel; get_workspace só os lê. O país próprio de uma conta é definido com create_sender e não pode ser mudado depois (o suporte do Hooka pode mudá-lo).
  • Limite diário por conta e aquecimento. São exclusivos do painel. O limite padrão é de 30 DMs por dia por conta (ajustável até 100). O daily_limit de uma campanha não consegue aumentá-lo.
  • Editar campanhas. Nenhum endpoint edita, arquiva ou exclui uma campanha. Pela API, a mensagem, os follow-ups e os senders de uma campanha não mudam depois da criação (o editor de campanhas do painel consegue mudar tudo isso).
  • Status da conversa. open, interested e os outros status são só de leitura pela API.
  • Manutenção de webhooks. Testar, editar ou excluir um endpoint, e buscar um único evento pelo id, existem na API, mas não como ferramentas.
  • Chaves de API. Não há ferramenta para elas. Os tokens OAuth recebem 403 oauth_token_not_allowed nas rotas de chaves.
  • Automações de comentário para DM. São gerenciadas no painel e não são expostas pela API.
  • Configurações que não existem. create_campaign.settings é estrito, então sender_pool, stop_on_reply ou qualquer outra chave desconhecida é um erro de validação. Os follow-ups sempre param quando a pessoa responde.
  • Outras plataformas. Só TikTok.
  • Notificações push. O servidor hospedado é stateless e não envia notificações. Consulte list_events, ou crie um endpoint de webhook para o seu backend.

O que “sent” significa. send_reply responde {"id":"rpl_…","object":"message","status":"queued"}, e a DM sai em segundos. Um target conta como sent quando o TikTok aceitou a mensagem e não mostrou nenhum aviso de “não entregue” nos segundos seguintes. Isso não prova que a pessoa leu. Quando o envio não pode ser confirmado, o target termina failed com send_unconfirmed e nunca é tentado de novo, para evitar uma DM duplicada.

É seguro deixar uma IA enviar DMs?

Quatro ações enviam DMs de verdade e irreversíveis: start_campaign, resume_campaign, send_reply e add_targets numa campanha running ou completed. As instruções do servidor mandam o modelo pedir a sua confirmação explícita antes de cada uma delas.

Oito ferramentas levam a anotação destructiveHint:

  • as quatro acima;
  • create_sender e refresh_sender_connection, que cancelam outras conexões em andamento;
  • delete_sender;
  • remove_suppression, que pode voltar a permitir contato com alguém que pediu descadastro (opt-out).

Se um cliente pergunta ou não antes de uma ferramenta destrutiva depende do cliente e das suas configurações.

O Hooka aplica os mesmos limites seja quem for que o chame: painel, API ou MCP.

  • Um limite diário por conta.
  • Intervalo entre DMs da mesma conta: rate_limit_seconds, 30-3600, padrão 60.
  • Um limite diário opcional por campanha.
  • Follow-ups que param quando a pessoa responde.
  • Deduplicação entre campanhas (ativada por padrão).
  • A lista “Não contatar”.

As contas se conectam por QR; o Hooka nunca pede uma senha do TikTok.

Nota honesta: a automação de DMs no TikTok funciona fora da API oficial do TikTok e tem um risco real, e nenhuma ferramenta pode prometer zero banimentos. O servidor MCP não muda isso. Ele dá ao seu LLM uma forma estruturada de comandar o Hooka com a sua confirmação. Use contas dedicadas ao outreach e comece com volumes baixos.

Novas tentativas, idempotência e erros

Estas 10 ferramentas de escrita aceitam um idempotency_key opcional e sempre enviam um cabeçalho Idempotency-Key:

  • create_sender, refresh_sender_connection, verify_sender_connection
  • create_campaign, add_targets, start_campaign, pause_campaign, resume_campaign
  • send_reply, create_webhook_endpoint

Como a chave funciona:

  • Chave derivada. Sem idempotency_key, a chave vem do nome da ferramenta, dos argumentos e da janela fixa de 10 minutos do relógio atual (12:00-12:10, 12:10-12:20…). Uma chamada idêntica na mesma janela devolve o resultado guardado com uma nota, em vez de executar de novo. Na janela seguinte, ela executa de novo, mesmo segundos depois. Duas exceções, em que o MCP passa para a próxima chave da série (até 5 por janela) e a chamada executa de novo: o resultado guardado foi um erro 4xx, ou, para create_sender e refresh_sender_connection, a tentativa de conexão guardada já terminou (o sender não está mais em awaiting_scan, ou connection.status é expired ou failed). Então repetir a mesma chamada create_sender na mesma janela, para outra conta depois que a primeira conectou, inicia sim uma nova conexão. Um idempotency_key explícito não tem essas exceções.
  • Timeouts e erros de rede. O texto do erro inclui a chave exata que foi enviada, para que a chamada possa ser repetida com idempotency_key igual a ela: se a original terminou, você recebe o resultado guardado em vez de uma segunda execução; se ainda está rodando, recebe 409 idempotency_key_in_use (espere e tente de novo com a mesma chave). Uma requisição travada por mais de 5 minutos é considerada morta e executa de novo. O Hooka guarda as chaves por 24 horas.
  • 409 idempotency_key_in_use. A requisição original ainda está rodando. Espere alguns segundos e tente de novo com a mesma chave.
  • Repetir de propósito. Para pausar de novo depois de retomar, ou para pedir outro código de verificação, passe um idempotency_key novo.
  • Ferramentas sem chave. add_suppressions (idempotente por natureza), update_sender, delete_sender e remove_suppression não enviam nenhuma.

Os erros das ferramentas voltam com isError: true e uma única linha de texto:

<status> <type>/<code>: <message> (param: <field>) [request_id req_…]
409 conflict_error/invalid_campaign_state: Cannot start a campaign that is running. [request_id req_…]
400 invalid_request_error/no_sender_available: Cannot start this campaign: none of its senders is connected. Reconnect one (POST /v1/senders/{id}/connection/refresh) and retry. [request_id req_…]
429 rate_limit_error/rate_limited: Too many requests. Retry in 7 s. (Retry-After: 7 s) [request_id req_…]

O servidor confere os argumentos com o schema de cada ferramenta antes de chamar a API. Um argumento inválido devolve MCP error -32602: Input validation error: …. Argumentos desconhecidos de nível superior são descartados em silêncio. create_campaign.settings é a exceção: ali, uma chave desconhecida é um erro. Cada chamada à API tem timeout de 30 segundos, e nesse caso o erro diz que a ação pode ou não ter sido aplicada.

Posso chamar o servidor hospedado pelo meu próprio código?

Sim. https://mcp.hooka.to/mcp fala MCP Streamable HTTP em modo stateless. Ele segue estas regras:

  • Envie JSON-RPC com POST /mcp. GET e DELETE devolvem 405, e não há Mcp-Session-Id.
  • Envie Accept: application/json, text/event-stream. Sem os dois tipos, você recebe 406.
  • As respostas chegam como server-sent events.
  • Sempre envie um objeto arguments, mesmo vazio: um tools/call sem ele falha na validação.
curl -N https://mcp.hooka.to/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer hk_live_..." \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_workspace","arguments":{}}}'
event: message
data: {"result":{"content":[{"type":"text","text":"{\n  \"id\": \"ws_…\",\n  \"object\": \"workspace\",\n  \"name\": \"Default\",\n  \"created\": 1790726400,\n  \"exit_ip\": {\n    \"status\": \"ready\",\n    \"region\": \"ES\",\n    \"suggested_region\": null,\n    \"per_sender\": true\n  },\n  \"seats\": {\n    \"limit\": 3,\n    \"used\": 1\n  }\n}"}]},"jsonrpc":"2.0","id":1}

O resultado de uma ferramenta é um item de texto com o JSON da API (formatado), mais um item de imagem quando há um QR anexado. Quando a API não devolve corpo, o texto é OK. Numa chamada repetida (a mesma chamada idempotente de novo dentro da janela de 10 minutos da chave, ou um idempotency_key repetido), o primeiro item de texto é uma linha NOTA: … em espanhol, o JSON é o item de texto seguinte e nenhuma imagem de QR é anexada. Para create_sender, refresh_sender_connection, verify_sender_connection, start_campaign, pause_campaign e resume_campaign, essa nota também traz o estado atual (Estado ACTUAL: …). Procure o item com o JSON em vez de supor content[0]. Não há structuredContent. Um cliente de verdade normalmente chama initialize primeiro, para receber as instruções do servidor.

Outros endpoints do servidor hospedado:

  • GET https://mcp.hooka.to/health devolve {"ok":true,"service":"hooka-mcp","version":"0.3.0","transport":"streamable-http"}.
  • Os clientes OAuth descobrem o servidor de autorização por /.well-known/oauth-protected-resource/mcp. O servidor de autorização é https://api.hooka.to. Ele aceita registro dinâmico de clientes e exige PKCE S256, e o recurso é https://mcp.hooka.to/mcp.

Se você só precisa de HTTP, pode pular o MCP e chamar a API REST diretamente. Referência completa (em inglês): app.hooka.to/docs.html.

Perguntas frequentes

O que é o servidor MCP do Hooka?

Um servidor Model Context Protocol que expõe a API v1 do Hooka como 26 ferramentas, para que o Claude, o ChatGPT, o Cursor ou o seu próprio agente conectem contas do TikTok, criem e lancem campanhas de DM, cuidem do inbox e gerenciem a lista “Não contatar” em linguagem natural. Cada ferramenta chama um endpoint da API do Hooka com a sua credencial, e o servidor não guarda credenciais. Esta página documenta a versão 0.2.0 (licença MIT); as versões 0.1.x anteriores no npm têm 23 ferramentas.

Como conecto o Hooka ao Claude, ChatGPT ou Cursor?

Hospedado: adicione https://mcp.hooka.to/mcp como conector personalizado no Claude.ai, no Claude Desktop ou no ChatGPT e faça login no Hooka (OAuth 2.1). Nos clientes que enviam cabeçalhos, como o Claude Code e o Cursor, use a mesma URL com Authorization: Bearer hk_live_.... Local: rode npx -y hooka-mcp via stdio com HOOKA_API_KEY definida com a sua chave (Node.js 20+). As 26 ferramentas exigem o hooka-mcp 0.2.0 ou mais recente: confira com npm view hooka-mcp version.

Preciso de uma chave de API?

Não com o conector OAuth: você faz login no Hooka e aprova o acesso. A opção com cabeçalho e o servidor local precisam de uma chave: crie uma chave hk_live_ na página Desenvolvedores do seu painel. As chaves hk_test_ são só de leitura: toda ferramenta que escreve devolve 403 permission_error/test_key_read_only.

Posso testar sem enviar DMs de verdade?

Não há sandbox. Uma chave hk_test_ deixa um agente ler o seu workspace real sem mudar nada. Com uma chave live, create_campaign só cria um rascunho e nada é enviado até start_campaign. As ferramentas que enviam DMs de verdade são start_campaign, resume_campaign, send_reply e add_targets numa campanha rodando ou concluída.

É seguro deixar uma IA enviar DMs no TikTok?

O servidor marca 8 ferramentas como destrutivas (elas enviam DMs, cortam conexões ou voltam a permitir contato), para que os clientes que respeitam as anotações MCP possam perguntar a você antes, e as instruções dele mandam o modelo obter a sua confirmação explícita antes de enviar. O Hooka aplica os mesmos limites a quem quer que o chame: um limite diário por conta, intervalo entre DMs, follow-ups que param quando a pessoa responde e a lista “Não contatar”. A automação do TikTok sempre envolve algum risco, então revise cada ação antes de confirmá-la.

O agente pode me mostrar o QR code para conectar uma conta?

Sim. create_sender inicia a conexão e o agente consulta get_sender a cada 3-5 segundos. Quando connection.status é requires_scan, o QR volta como imagem no resultado da ferramenta, e você o escaneia com o app do TikTok. Se o TikTok depois pedir para você confirmar que é você, o agente conclui esse passo com verify_sender_connection e o código que você receber.

Quanto custa?

O servidor MCP é gratuito (licença MIT). Conectar contas do TikTok e enviar DMs exige uma assinatura ativa do Hooka, com preço por conta do TikTok conectada. Sem ela, create_sender devolve 403 permission_error/no_active_subscription.

Continue lendo

Deixe o seu LLM tocar o outreach

Cancele quando quiser. Não pedimos sua senha do TikTok. Pagamento seguro com Stripe.