- Início
- Servidor MCP
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.
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).
Como conectar o Hooka ao Claude, ChatGPT ou Cursor?
Há três formas de conectar. Todas dão acesso às mesmas 26 ferramentas:
| Opção | Onde roda | Credencial | Clientes típicos |
|---|---|---|---|
| Hospedado + OAuth | https://mcp.hooka.to/mcp (Streamable HTTP) | Login no Hooka e aprovação do acesso | Claude.ai, Claude Desktop (Conectores), ChatGPT |
| Hospedado + chave de API | https://mcp.hooka.to/mcp (Streamable HTTP) | Cabeçalho Authorization: Bearer hk_live_… | Claude Code, Cursor, agentes próprios |
| Local | Sua máquina, via stdio (npx hooka-mcp, Node.js 20+) | Variável de ambiente HOOKA_API_KEY | Arquivo 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?
| Credencial | Como obter | O 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_keys | Ler e escrever: ações reais nas suas contas reais do TikTok |
hk_test_… | POST /v1/api_keys com {"mode":"test"}, autenticado com uma chave live | Só leitura: toda ferramenta que escreve devolve 403 permission_error/test_key_read_only |
| Token OAuth | Emitido 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.
| Ferramenta | O que faz | Chamada à API | Tipo |
|---|---|---|---|
| Senders (contas do TikTok) · 7 | |||
list_senders | Todas 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/senders | leitura |
get_sender | Um 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_sender | Começ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/senders | destrutiva |
refresh_sender_connection | Uma 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/refresh | destrutiva |
verify_sender_connection | Conclui 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/verify | escrita |
update_sender | Muda o rótulo (label) de um sender, o único campo que a API pode editar. | PATCH /v1/senders/{id} | escrita |
delete_sender | Desconecta 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_campaigns | As campanhas, da mais recente para a mais antiga. As arquivadas não aparecem. | GET /v1/campaigns | leitura |
get_campaign | Uma campanha com estatísticas ao vivo: pending, processing, sent, failed, skipped, replied, reply_rate. | GET /v1/campaigns/{id} | leitura |
create_campaign | Cria 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/campaigns | escrita |
add_targets | Adiciona 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}/targets | destrutiva |
list_targets | Os 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}/targets | leitura |
start_campaign | Começ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}/start | destrutiva |
pause_campaign | Pausa uma campanha running. Uma DM que já está sendo enviada ainda pode sair. | POST /v1/campaigns/{id}/pause | escrita |
resume_campaign | Retoma o envio de uma campanha paused, ou de uma completed que ainda tem targets pendentes. | POST /v1/campaigns/{id}/resume | destrutiva |
| Inbox · 4 | |||
list_conversations | As conversas pela atividade mais recente. Filtros opcionais por status e sender_id. | GET /v1/conversations | leitura |
get_conversation | Uma conversa: qual sender, a outra pessoa, o status, a contagem de não lidas e a última mensagem. | GET /v1/conversations/{id} | leitura |
get_messages | As mensagens de uma conversa, da mais antiga para a mais recente (in = a outra pessoa, out = você). | GET /v1/conversations/{id}/messages | leitura |
send_reply | Coloca 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}/messages | destrutiva |
| Lista “Não contatar” · 3 | |||
list_suppressions | Os usernames que nunca devem ser contatados, com o reason (manual, opt_out…). | GET /v1/suppressions | leitura |
add_suppressions | Adiciona de 1 a 1.000 usernames. Os targets pendentes deles em todas as campanhas são ignorados na hora. | POST /v1/suppressions | escrita |
remove_suppression | Remove 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_events | Os 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/events | leitura |
list_webhook_endpoints | Seus endpoints de webhook, sem os segredos. | GET /v1/webhook_endpoints | leitura |
create_webhook_endpoint | Cria um endpoint (URL pública https://). Devolve o segredo de assinatura whsec_… uma única vez. | POST /v1/webhook_endpoints | escrita |
get_workspace | Whoami: id do workspace, país padrão das contas novas (exit_ip.region) e vagas. | GET /v1/workspace | leitura |
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:
get_workspace: confere se há uma vaga livre (seats.used < seats.limit; um limitenullsignifica 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ê.create_sender {"label":"Shop ES","country":"ES"}: o sender volta emawaiting_scan, comconnection.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".get_sendera cada 3-5 segundos.connection.statuspassa porpending,requires_scan,scanned, às vezesverification_required, e termina com o senderconnected.- 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. - Em
verification_required, ele pergunta onde você quer receber o código e qual é o código. Depois chamaverify_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_limitlimita 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 opcionalgoal). 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 destart_campaign.triage_inbox. Percorre as conversas abertas, classifica-as e escreve rascunhos de respostas curtas. Espera o seu OK antes de qualquersend_reply.connect_account(argumento opcionallabel). 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-typeslista os 12 tipos de evento de webhook mais oping, com o significado de cada um.hooka://api-referencecobre 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_workspacesó os lê. O país próprio de uma conta é definido comcreate_sendere 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_limitde 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,interestede 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_allowednas 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ãosender_pool,stop_on_replyou 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_sendererefresh_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_connectioncreate_campaign,add_targets,start_campaign,pause_campaign,resume_campaignsend_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, paracreate_sendererefresh_sender_connection, a tentativa de conexão guardada já terminou (o sender não está mais emawaiting_scan, ouconnection.statuséexpiredoufailed). Então repetir a mesma chamadacreate_senderna mesma janela, para outra conta depois que a primeira conectou, inicia sim uma nova conexão. Umidempotency_keyexplí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_keyigual a ela: se a original terminou, você recebe o resultado guardado em vez de uma segunda execução; se ainda está rodando, recebe409 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_keynovo. - Ferramentas sem chave.
add_suppressions(idempotente por natureza),update_sender,delete_sendereremove_suppressionnã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.GETeDELETEdevolvem 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: umtools/callsem 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/healthdevolve{"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
A API REST por trás de cada ferramenta: senders, campanhas, targets, inbox e webhooks.
docsReferência completa da APICada endpoint, campo, código de erro e evento de webhook, com exemplos (em inglês).
preçosPreços do HookaPor conta do TikTok conectada, por mês. O servidor MCP é gratuito.
Deixe o seu LLM tocar o outreach
Cancele quando quiser. Não pedimos sua senha do TikTok. Pagamento seguro com Stripe.