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.
Antes de começar
Seção intitulada “Antes de começar”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.
Entrar com o Salesbud
Seção intitulada “Entrar com o Salesbud”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.
Usar uma credencial fixa
Seção intitulada “Usar uma credencial fixa”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:
| Header | Valor |
|---|---|
X-Client-Id | sb_client_... |
X-Client-Secret | sb_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.
| Tool | Escopo |
|---|---|
get_api_context | nenhum além de uma credencial válida |
list_meetings | meetings.read |
find_meetings | meetings.read |
get_meeting | meetings.read |
get_meeting_overall_evaluation | meetings.read |
get_meeting_answers | meetings.read |
get_meeting_transcript | meetings.read + transcriptions.read |
list_calls | calls.read |
find_calls | calls.read |
get_call | calls.read |
get_call_overall_evaluation | calls.read |
get_call_answers | calls.read |
get_call_transcript | calls.read + transcriptions.read |
list_emails | emails.read |
get_email | emails.read |
list_email_messages | emails.read + emails.content.read |
list_whatsapp_conversations | whatsapp.read |
get_whatsapp_conversation | whatsapp.read |
list_whatsapp_messages | whatsapp.read + whatsapp.content.read |
list_accounts | qualquer um de meetings.read, calls.read, emails.read, whatsapp.read |
list_teams | qualquer um de meetings.read, calls.read, emails.read, whatsapp.read |
list_tags | qualquer 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.
O catálogo de tools
Seção intitulada “O catálogo de 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.
curl https://api.salesbud.com.br/mcp/toolsAchar as reuniões e ligações de uma conta
Seção intitulada “Achar as reuniões e ligações de uma conta”“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.
Transcrições vêm em janelas
Seção intitulada “Transcrições vêm em janelas”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.
Corpo de e-mail custa mais que metadado
Seção intitulada “Corpo de e-mail custa mais que metadado”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.
Texto de WhatsApp custa mais que metadado
Seção intitulada “Texto de WhatsApp custa mais que metadado”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.
O que o servidor resolve, e o que não
Seção intitulada “O que o servidor resolve, e o que não”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.
Cota compartilhada
Seção intitulada “Cota compartilhada”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.