Pular para o conteúdo

Servidor MCP

Esta API serve um servidor Model Context Protocol por HTTP em https://api.salesbud.com.br/mcp. Cadastrado uma vez como conector personalizado no claude.ai, ele deixa o modelo ler reuniões, ligações, transcrições, respostas do template, avaliações, e-mails e conversas de WhatsApp como você ou com uma credencial da empresa — sem nada para instalar.

Ele é um cliente da API pública, não uma superfície nova: mesma credencial OAuth, mesmos escopos, mesmos limites de uso e apenas operações de leitura — nada que ele alcance é diferente do que a API HTTP devolveria para a mesma credencial.

A sua empresa precisa da feature API_ACCESS habilitada. O resto depende de como o assistente entra:

  • Entrando com o Salesbud (OAuth) — cada pessoa conecta a própria conta e lê o que vê. Nada para criar antes. É o caminho para o Claude e o ChatGPT: veja Conectar o Claude ou o ChatGPT.
  • Uma credencial fixa em headers — um administrador cadastra uma credencial de API que a organização inteira no Claude compartilha. Você precisa dessa credencial e de acesso de administrador na organização do Claude. Veja no Começo rápido as duas espécies de credencial.

Aponte o assistente para https://api.salesbud.com.br/mcp e deixe que ele faça você entrar: ele encontra o servidor de autorização sozinho, abre a tela de consentimento do Salesbud e conecta como você. O passo a passo de cada assistente, a aprovação e a desconexão estão em Conectar o Claude ou o ChatGPT.

A conexão feita por quem não aprova credenciais aguarda um administrador. Até lá, toda tool responde que a conexão está aguardando aprovação do administrador.

Quem administra a organização no Claude ainda pode cadastrar um conector personalizado apontando para https://api.salesbud.com.br/mcp sem login, mandando a credencial da empresa cujos dados o conector deve ler em dois headers de requisição:

HeaderValor
X-Client-Idsb_client_...
X-Client-Secretsb_secret_...

Qualquer outro cliente HTTP pode mandar a mesma credencial como Basic (RFC 7617):

Authorization: Basic <base64 de client_id:client_secret>

Duas consequências de uma credencial cadastrada uma vez pelo administrador:

  • Ela fica guardada do lado da Anthropic e é compartilhada pela organização inteira no Claude. Todo mundo ali lê o que os escopos permitirem, e a trilha de auditoria registra a credencial, não quem pediu.
  • Revogar significa rotacionar. Rotacionar o segredo quebra junto qualquer outra integração que use a mesma credencial, então dê uma só para o conector.

Se a credencial restringe acesso por IP, a allowlist precisa conter a faixa de saída da Anthropic, 160.79.104.0/21: a requisição chega nesta API de lá, não do navegador do usuário.

Uma tool por operação pública de leitura. A coluna de escopo é o que a credencial precisa carregar — escopo faltando volta como uma mensagem legível de INSUFFICIENT_SCOPE, que o modelo consegue relatar, não como exceção.

ToolEscopo
get_api_contextnenhum além de uma credencial válida
list_meetingsmeetings.read
find_meetingsmeetings.read
get_meetingmeetings.read
get_meeting_overall_evaluationmeetings.read
get_meeting_answersmeetings.read
get_meeting_transcriptmeetings.read + transcriptions.read
list_callscalls.read
find_callscalls.read
get_callcalls.read
get_call_overall_evaluationcalls.read
get_call_answerscalls.read
get_call_transcriptcalls.read + transcriptions.read
list_emailsemails.read
get_emailemails.read
list_email_messagesemails.read + emails.content.read
list_whatsapp_conversationswhatsapp.read
get_whatsapp_conversationwhatsapp.read
list_whatsapp_messageswhatsapp.read + whatsapp.content.read
list_accountsqualquer um de meetings.read, calls.read, emails.read, whatsapp.read
list_teamsqualquer um de meetings.read, calls.read, emails.read, whatsapp.read
list_tagsqualquer um de meetings.read, calls.read, emails.read, whatsapp.read

list_accounts busca por nome ou domínio com q; list_teams e list_tags listam os times e as tags de reunião e ligação da empresa. list_meetings e list_calls aceitam account_id, team_id, tag_id, score_min e score_max; list_emails e list_whatsapp_conversations aceitam account_id e team_id. O fluxo típico é list_accounts com q: "acme" para achar o id e depois list_meetings com esse account_id. As listagens mostram todas as contas de cada registro, até três. Veja Filtrar por conta, time, tag e nota.

Peça get_api_context primeiro quando não souber o que a credencial alcança: ele responde com o client, se a credencial é de empresa ou de usuário e, na de usuário, quem é o dono, a empresa, os escopos e o limite por minuto.

O /oauth/token não é tool de propósito, e expor isso gastaria o bucket de OAuth e colocaria o token na conversa. Com uma credencial fixa, o servidor emite e renova o token por dentro. Numa conexão com login, o próprio assistente (Claude ou ChatGPT) renova o token com o refresh token. As sondas de liveness e readiness também não são tools.

GET /mcp/tools lista as tools do servidor sem credencial: os mesmos name, title, description, inputSchema e annotations que o tools/list devolve, mais a versão do servidor em serverVersion. Um cliente monta a lista de tools, ou percebe que uma descrição mudou, sem abrir uma sessão MCP. A resposta pode ficar em cache por cinco minutos (Cache-Control: public, max-age=300). Ela só descreve as tools; chamar uma continua exigindo credencial.

Terminal window
curl https://api.salesbud.com.br/mcp/tools

“Me mostra as reuniões com a Acme” é uma chamada de find_meetings (ou find_calls). Ela acha a conta pelo nome, domínio, CNPJ ou id no catálogo de contas e lê os registros vinculados a ela — os últimos 12 meses, a menos que você passe meeting_after ou meeting_before. Sem nenhum vinculado, lê o período registro por registro (90 dias por padrão) e procura a conta no título, nas contas vinculadas e no domínio do e-mail dos participantes. Um nome que bate com várias contas volta com as candidatas, para o modelo perguntar ou escolher pelo id em vez de chutar.

Uma chamada lê no máximo 30 páginas em 20 segundos. complete diz se o período foi coberto; quando um teto para a busca, next_cursor continua de onde parou, passado de volta com a mesma conta e os mesmos filtros. A resposta traz os 50 registros mais recentes, inteiros, no structuredContent, e só diz que a conta não tem registros sobre um período lido até o fim.

Uma transcrição de uma hora tem milhares de falas e não cabe no contexto do modelo de uma vez. As tools de transcrição devolvem 200 falas por chamada e dizem quantas faltam; o modelo passa offset para continuar. A API devolve a transcrição inteira — o janelamento é do servidor MCP.

Registro sem transcrição não é erro: a tool responde transcript unavailable (status: not_started), que é o contrato descrito em Reuniões e ligações.

list_emails e get_email devolvem metadado da conversa — participantes, caixas conectadas, contas vinculadas, contagens — e nunca o corpo. Ler as mensagens é outra tool, list_email_messages, e ela pede mais: emails.content.read além de emails.read, e uma política de rate limit própria, mais apertada que a do resto da API. Peça uma página por vez em vez de varrer a caixa inteira.

Corpo com mais de 2.000 caracteres é cortado no texto que o modelo lê e vai inteiro no structuredContent. Conteúdo de anexo, corpo em HTML e bcc a API nunca serve, então nenhuma tool alcança.

list_whatsapp_conversations e get_whatsapp_conversation devolvem metadado da conversa — contato, vendedor, contas vinculadas, instantes de atividade — e nunca uma mensagem. Ler as mensagens é outra tool, list_whatsapp_messages, e ela pede mais: whatsapp.content.read além de whatsapp.read, e uma política de rate limit própria. Peça uma página por vez em vez de varrer o histórico inteiro.

Texto ou transcrição de áudio com mais de 2.000 caracteres é cortado no texto que o modelo lê e vai inteiro em structuredContent. Mensagem apagada para todos fica como lápide, sem conteúdo; mensagem editada mostra o texto atual. Conteúdo de mídia, identificadores do provedor, reações e estado de leitura nunca chegam ao modelo — a API não os serve. Veja a referência de WhatsApp.

Ele resolve renovação de token com margem de segurança e uma repetição em 401 com token novo quando usa uma credencial fixa, Retry-After em 429, backoff em 503 e falha imediata nos outros 4xx. Numa conexão com login, o próprio assistente renova o token, e o servidor não repete o 401: a tool responde com um erro pedindo para reconectar. Os erros chegam ao modelo com code e request_id, então um filtro de data mal formatado volta como INVALID_DATETIME e o modelo corrige o formato sozinho.

Quando o cliente cancela uma chamada, ou desiste da requisição, o servidor para as leituras que essa chamada começou. Todo parâmetro de data declara format: "date-time" no schema de entrada.

Ele não pagina por você, exceto dentro de find_meetings e find_calls. O modelo segue has_more e next_cursor como qualquer outro cliente, e a descrição da tool avisa disso, porque página curta não é a última página.

Também não existe sync incremental, porque a v1 não tem: janele por meeting_at ou created_at e reprocesse de forma idempotente por id.

Todas as credenciais de uma empresa dividem o mesmo bucket de 600 requisições por minuto. Um agente percorrendo um histórico longo consome a cota que as suas outras integrações estão usando; veja Limites de uso.