O servidor MCP do Campbooks está em POST /api/mcp em qualquer instância do Campbooks. Implementa o protocolo MCP versão 2025-03-26 sobre HTTP streamable e expõe 72 tools (mais 3 tools de contexto que não requerem scope).
Autorização
POST /api/mcp aceita três formas de Authorization:
| Forma | Valor do cabeçalho | Notas |
|---|
| Chave MCP | Bearer <uid>.<client-secret> | UID do cliente e secret em texto simples separados por um ponto. Os UIDs e secrets do Doorkeeper não contêm pontos, por isso o ponto é inequívoco. |
| HTTP Basic | Basic base64(uid:secret) | Equivalente HTTP padrão da forma de chave MCP. |
| Token Doorkeeper | Bearer <access-token> | Token de curta duração (2 h) obtido em POST /api/oauth/token. Funciona para scripts pontuais; não adequado para configurações estáticas de agentes. |
A REST API (/api/v1/*) aceita apenas tokens bearer do Doorkeeper. As formas 1 e 2 — chaves MCP — são suportadas apenas em /api/mcp.
Expiração e rotação de chaves
As chaves MCP não expiram. O servidor realiza uma comparação bcrypt em cada pedido; as taxas de chamada de agentes estão bem dentro do limite de 600 req/min.
Revogar um token de acesso do Doorkeeper não desativa uma chave MCP. Para revogar uma chave MCP, rode o client secret ou elimine o cliente em Definições → Acesso à API. A chave MCP é mostrada uma vez na criação do cliente; regenere o client secret se a perder.
Códigos de erro de autenticação
| Estado | error.code | Quando |
|---|
| 401 | invalid_client | Cliente não encontrado, secret incorreto, aplicação não confidencial ou secret em branco |
| 403 | insufficient_scope | O cliente não tem scopes atribuídos |
Scopes
Os scopes controlam que tools aparecem em tools/list. Um conjunto mais restrito significa menos tools e menos contexto por sessão. A lista completa de scopes está documentada na visão geral da API em Programadores.
Os três tools de contexto — get_overview, get_setup_status e guide — não requerem scope e estão sempre disponíveis para qualquer cliente autenticado.
Limites de taxa
600 pedidos por minuto por cliente. Exceder o limite devolve HTTP 429 com error.code: "rate_limit_exceeded".
Os tools estão agrupados por família abaixo. A coluna "Scope" mostra o OAuth scope obrigatório; (any) significa que não é necessário scope.
Tools de contexto
| Tool | Scope | Finalidade |
|---|
get_overview | (any) | Snapshot barato do que precisa de atenção. Devolve apenas as secções cujas contagens não são zero. Chame este primeiro. |
get_setup_status | (any) | Snapshot de configuração da workspace para onboarding e diagnósticos. Lista lacunas como next_steps para guiar a skill de configuração. |
guide | (any) | Guias narrativos para trabalhar com o Campbooks via MCP. Sem tópico — lista de tópicos disponíveis. Passe um nome de tópico para o guia completo. |
Email
| Tool | Scope | Finalidade |
|---|
list_emails | emails:read | Lista os emails mais recentes acessíveis ao chamador, do mais recente para o mais antigo. Filtros opcionais: não lidos, consulta, conta, categoria, prioridade, intervalo de datas. |
search_emails | emails:read | Pesquisa emails com filtros. Usa uma combinação semântica + por palavras-chave quando é fornecida uma consulta de texto. |
get_email | emails:read | Obtém um único email por id. format=text (padrão) devolve o corpo em texto simples, truncado em 8 000 caracteres. |
send_email | emails:send | Envia um novo email a partir de uma das contas ligadas do chamador. |
reply_email | emails:send | Responde a um email existente. Encadeia a partir da mensagem de origem e envia pela sua conta, salvo se substituído. |
mark_email_read | emails:write | Marca um email como lido e sincroniza a flag com a caixa de correio do fornecedor. |
mark_email_unread | emails:write | Marca um email como não lido (apenas local). |
add_email_tag | tags:write | Anexa uma etiqueta existente da workspace a um email (por tag_id ou nome). As etiquetas não são criadas aqui — use create_tag. |
remove_email_tag | tags:write | Remove uma etiqueta de um email. |
update_emails | emails:write | Ação em massa sobre emails. archive/unarchive/trash/snooze/unsnooze atuam em threads completas (espelhando a UI da aplicação). |
move_emails_to_folder | emails:write | Move emails (e as suas threads completas) para uma pasta. Passe folder_name para trabalhar entre contas. |
tag_emails | tags:write | Adiciona ou remove uma etiqueta num conjunto de emails. A etiqueta deve existir — use create_tag para criar novas. |
forward_email | emails:send | Reencaminha um email para outro endereço. |
get_skim_deck | emails:read | Devolve o baralho de skim como anéis compactos e cartões de cluster. Aplique decisões com skim_decide. |
skim_decide | emails:write | Aplica uma decisão de triage do Skim aos emails de um cluster. Espelha o ciclo de aprendizagem da UI da caixa de entrada (arquivar, manter, promover). |
Contas de email
| Tool | Scope | Finalidade |
|---|
list_email_accounts | email_accounts:read | Lista as contas de email ligadas visíveis ao chamador. Use o id como email_account_id para filtragem. |
connect_email_account | email_accounts:write | Liga uma nova conta de email. mode=web devolve um URL para abrir num browser (fluxo OAuth normal — recomendado para utilizadores cloud). mode=token aceita um token de atualização pré-criado (caminho OAuth local para auto-alojado). |
Documentos
| Tool | Scope | Finalidade |
|---|
list_documents | documents:read | Lista os documentos da workspace, do mais recente para o mais antigo. Filtros opcionais por id de tipo de documento e estado de revisão. |
get_document | documents:read | Obtém um documento por id com os seus campos extraídos e informação do ficheiro (transferência via download_path do ficheiro). |
upload_document | documents:write | Carrega um novo documento a partir de conteúdo base64. A classificação por IA corre de forma assíncrona. |
update_document | documents:write | Edita os campos extraídos de um documento. Não altera o seu estado de revisão (use approve/reject/reclassify para isso). |
approve_document | documents:write | Aprova (assina) um documento. |
reject_document | documents:write | Rejeita um documento. |
reclassify_document | documents:write | Altera o tipo de um documento (também o aprova). |
| Tool | Scope | Finalidade |
|---|
list_contacts | contacts:read | Lista os contactos da workspace. Consulta de texto opcional sobre nome/email e filtro apenas de favoritos. |
get_contact | contacts:read | Obtém um único contacto por id. |
update_contact | contacts:write | Atualiza o nome e/ou tipo de relação de um contacto. |
set_contact_state | contacts:write | Marcar/desmarcar como favorito, permitir, bloquear ou desbloquear um contacto. |
Etiquetas
| Tool | Scope | Finalidade |
|---|
list_tags | tags:read | Lista as etiquetas da workspace (as etiquetas aplicam-se a emails). |
create_tag | tags:write | Cria uma nova etiqueta na workspace. As etiquetas aplicam-se a emails e podem ser usadas para filtragem. |
Tipos de documento
| Tool | Scope | Finalidade |
|---|
list_document_types | document_types:read | Lista os tipos de documento da workspace (usados para classificar documentos). |
create_document_type | document_types:write | Cria um novo tipo de documento para classificar anexos. |
Pastas
| Tool | Scope | Finalidade |
|---|
list_folders | folders:read | Lista as pastas personalizadas da workspace. |
get_folder | folders:read | Obtém uma pasta e os documentos arquivados nela. |
create_folder | folders:write | Cria uma pasta personalizada. Quando provision: true, a pasta é criada em cada conta de email ligada como uma etiqueta/pasta do lado do fornecedor. |
file_document | folders:write | Arquiva um documento numa pasta. |
unfile_document | folders:write | Remove um documento de uma pasta (por id de membro). |
Tarefas (funcionalidade condicional)
Os tools de tarefas requerem que a funcionalidade Tarefas esteja ativada no servidor (ENABLE_TASKS). Aparecem em tools/list apenas quando a funcionalidade está ativa.
| Tool | Scope | Finalidade |
|---|
list_tasks | tasks:read | Lista as tarefas da workspace. Filtro de estado opcional; include_archived para ver tarefas arquivadas. |
get_task | tasks:read | Obtém uma tarefa por id com detalhe completo. |
create_task | tasks:write | Cria uma tarefa na workspace. |
update_task | tasks:write | Atualiza os campos de uma tarefa. As mudanças de estado usam a transição adequada (publica eventos). |
complete_task | tasks:write | Marca uma tarefa como concluída. |
create_task_from_email | tasks:write | Extrai e cria uma tarefa a partir de um email via o registo de ações. |
Calendário
| Tool | Scope | Finalidade |
|---|
list_calendars | calendar:read | Lista os calendários visíveis ao chamador. Use o id como calendar_id em create_calendar_event. |
list_calendar_events | calendar:read | Lista os eventos de calendário acessíveis ao chamador, do mais próximo para o mais distante. Filtros opcionais start_after / start_before. |
get_calendar_event | calendar:read | Obtém um evento de calendário por id. |
create_calendar_event | calendar:write | Cria um evento de calendário num dos calendários graváveis do chamador. Os tempos são ISO-8601. |
update_calendar_event | calendar:write | Atualiza um evento de calendário (deve ter acesso de escrita ao seu calendário). recurrence_scope: this ou all. |
delete_calendar_event | calendar:write | Elimina um evento de calendário (eliminação assíncrona pelo fornecedor). recurrence_scope: this ou all. |
rsvp_calendar_event | calendar:write | Define o seu RSVP num evento (needs_action, accepted, declined, tentative). |
create_event_from_email | calendar:write | Extrai e cria um evento de calendário a partir de um email. A IA infere os detalhes do evento; forneça substituições conforme necessário. |
Lembretes
| Tool | Scope | Finalidade |
|---|
list_reminders | reminders:read | Lista os lembretes extraídos por IA acessíveis ao chamador. Filtro de estado opcional (pending, confirmed, dismissed, snoozed). |
get_reminder | reminders:read | Obtém um lembrete por id. |
confirm_reminder | reminders:write | Confirma um lembrete para um evento de calendário. Opcionalmente passe due_at para ajustar a hora primeiro. |
dismiss_reminder | reminders:write | Dispensa um lembrete. |
snooze_reminder | reminders:write | Adia um lembrete até ao tempo indicado, ou uma semana quando omitido. |
Emails agendados
| Tool | Scope | Finalidade |
|---|
list_scheduled_emails | scheduled_emails:read | Lista emails agendados (e recorrentes) na workspace, do mais próximo para o mais distante. |
get_scheduled_email | scheduled_emails:read | Obtém um email agendado por id. |
create_scheduled_email | scheduled_emails:write | Agenda um email para enviar mais tarde (opcionalmente recorrente via RRULE). Envia a partir de uma conta que o utilizador pode usar para enviar. |
update_scheduled_email | scheduled_emails:write | Atualiza um email agendado pendente (destinatário, assunto, corpo, hora, rrule). |
cancel_scheduled_email | scheduled_emails:write | Cancela um email agendado (suave: define o estado como cancelled). |
Scout
| Tool | Scope | Finalidade |
|---|
list_scout_threads | scout:read | Lista as threads de chat Scout do chamador, da mais recente para a mais antiga. |
create_scout_thread | scout:write | Inicia uma nova thread de chat Scout. |
list_scout_messages | scout:read | Lista mensagens numa thread Scout. Passe after_message_id para aguardar a resposta assíncrona da IA. |
send_scout_message | scout:write | Publica uma mensagem de utilizador numa thread Scout. A resposta da IA é gerada de forma assíncrona; use list_scout_messages com after_message_id até aparecer. |
Fluxos de trabalho (funcionalidade condicional)
Os tools de fluxos de trabalho requerem que a funcionalidade Fluxos de trabalho esteja ativada no servidor (ENABLE_WORKFLOWS). Aparecem em tools/list apenas quando a funcionalidade está ativa.
| Tool | Scope | Finalidade |
|---|
list_workflows | workflows:read | Lista os fluxos de trabalho de automação da workspace. |
trigger_workflow | workflows:trigger | Aciona um fluxo de trabalho webhook ativo com um payload JSON opcional. |
list_workflow_executions | workflows:read | Lista o histórico de execuções de um fluxo de trabalho (do mais recente para o mais antigo). |
Modelos (funcionalidade condicional)
| Tool | Scope | Finalidade |
|---|
list_email_templates | templates:read | Lista os modelos de email reutilizáveis da workspace. |
Famílias com funcionalidade condicional
Três famílias de tools estão ocultas quando a funcionalidade do servidor correspondente está desativada:
| Família | Variável de ambiente do servidor | Padrão |
|---|
| Tarefas | ENABLE_TASKS | desativado |
| Fluxos de trabalho | ENABLE_WORKFLOWS | desativado |
| Modelos | (flag interno) | varia |
Estes tools simplesmente não aparecem em tools/list quando a funcionalidade está desativada — não devolvem um erro.
connect_email_account — modo web vs. token
O tool connect_email_account suporta dois modos:
mode: "web" — devolve um caminho relativo para abrir num browser. O próprio fluxo OAuth do servidor trata do redirecionamento; esta é a escolha correta para utilizadores do Campbooks Cloud e qualquer servidor cujos callbacks OAuth sejam publicamente acessíveis.
mode: "token" — aceita um token de atualização pré-criado diretamente. Use isto para instâncias auto-alojadas onde os callbacks OAuth do servidor não são acessíveis a partir da internet pública. O token deve ter sido criado com as credenciais OAuth do próprio servidor (GOOGLE_CLIENT_ID/ZOHO_CLIENT_ID), caso contrário o servidor falhará ao atualizá-lo. Consulte Claude Code → OAuth Local para o script auxiliar.
Garantias de segurança
Permissões de caixa de correio por utilizador — uma chave MCP age como o utilizador que a criou. Caixas de correio que esse utilizador não pode ler na aplicação, a chave também não pode. Caixas de correio das quais esse utilizador não pode enviar, a chave também não pode. Os OAuth scopes são um teto adicional sobre essas permissões, não uma substituição.
404-não-403 — recursos que existem mas pertencem a uma workspace diferente devolvem 404, não 403. A API e o servidor MCP nunca revelam se um recurso existe fora dos seus dados.
Confirmar antes de enviar — as skills /campbooks:triage e /campbooks:setup foram concebidas para mostrar o texto completo do rascunho e aguardar um "sim" explícito antes de chamar send_email, reply_email ou forward_email. Se estiver a construir o seu próprio prompt de agente sobre os tools MCP, siga o mesmo padrão: nunca chame um tool de envio sem aprovação do utilizador na mesma sessão.