> ## Documentation Index
> Fetch the complete documentation index at: https://docs.octasend.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Servidor MCP

> Conecte o Claude Code (ou outro cliente MCP) ao servidor MCP remoto da OctaSend para enviar mensagens e consultar dados sem escrever código de integração

A OctaSend tem um servidor **MCP (Model Context Protocol)** remoto. Com ele, assistentes de IA como o Claude Code chamam a API de mensagens diretamente: listam as comunicações, enviam mensagens, consultam estatísticas e verificam canais — tudo a partir de uma conversa, durante o desenvolvimento.

No painel, a página **Configurações → MCP Server** reúne o passo a passo e um prompt pronto para o Claude Code.

## Como funciona

O servidor fica hospedado pela OctaSend — não há pacote para instalar nem processo local para rodar. Você aponta o seu cliente MCP para a URL abaixo e se autentica com um OAuth Client:

```text theme={null}
https://octasend.com.br/mcp
```

| Item | Valor |
| - | - |
| Transporte | HTTP (Streamable HTTP) |
| Autenticação | Header `Authorization: Bearer client_id:client_secret` (recomendado) ou `Authorization: Bearer <access_token>` |
| Tools | `list_communications`, `send_message`, `send_messages_batch`, `get_message_stats`, `get_channel_config`, `create_communication`, `get_communication`, `update_communication`, `get_message`, `list_messages` |

O servidor troca o `client_id:client_secret` por um access token de 1 hora (o mesmo fluxo de [Autenticação](https://docs.octasend.com.br/api-reference/autenticacao.md)) e reaproveita esse token até perto de ele vencer, quando pede outro sozinho — você não precisa cuidar de renovação. A credencial é conferida já na conexão: se ela não vale, o servidor responde antes de liberar as tools.

Também dá para colocar no header um access token (`at_...`) já emitido. Nesse caso o servidor não tem como renová-lo: depois de 1 hora as tools passam a responder `401` e é preciso trocar o token no header. Por isso, prefira o par `client_id:client_secret`.

> [!WARNING]
>
> Não configure o servidor como `"type": "stdio"` com `npx octasend-mcp`: esse pacote não é distribuído. Use sempre `"type": "http"` com a URL acima.

## Configuração no seu projeto

**1. Crie as credenciais**

Em **Configurações → OAuth Clients**, crie um client e guarde o `client_id` e o `client_secret` — o secret aparece uma única vez. Prefira um client só para o MCP, separado do usado em produção.

**2. Registre o servidor MCP**

Pela CLI do Claude Code, que cria o `.mcp.json` por você:

```bash theme={null}
claude mcp add --transport http octasend https://octasend.com.br/mcp \
  --header "Authorization: Bearer SEU_CLIENT_ID:SEU_CLIENT_SECRET"
```

Ou crie o arquivo `.mcp.json` na raiz do projeto:

```json theme={null}
{
  "mcpServers": {
    "octasend": {
      "type": "http",
      "url": "https://octasend.com.br/mcp",
      "headers": {
        "Authorization": "Bearer SEU_CLIENT_ID:SEU_CLIENT_SECRET"
      }
    }
  }
}
```

Cole os valores exatamente como aparecem no painel — o `client_id` já começa com `client_` e o `client_secret` com `secret_` — separados por dois-pontos, sem espaços.

**3. Proteja as credenciais**

O `.mcp.json` guarda o segredo no header. Tire o arquivo do versionamento:

```bash theme={null}
echo '.mcp.json' >> .gitignore
```

**4. Ative**

Abra (ou reinicie) o Claude Code na pasta do projeto. Rode `/mcp` e confirme que o servidor `octasend` aparece conectado, com as tools listadas acima.

> [!NOTE]
>
> Outros clientes MCP funcionam da mesma forma, desde que suportem transporte HTTP e permitam enviar o header `Authorization`.

## Referência das tools

A mesma credencial libera todas as tools — não existe permissão por tool. Quando a API responde com erro (por exemplo, `401` ou `404`), a tool devolve o erro com o código HTTP e a mensagem, como `API /send-message retornou 404: Communication not found`.

### `list_communications`

Lista as comunicações da conta, ativas e inativas, em ordem alfabética. Use antes de `send_message` para descobrir os slugs. Não recebe parâmetros.

```json theme={null}
{
  "communications": [
    {
      "id": "b1e6...",
      "name": "E-mail de boas-vindas",
      "slug": "boas-vindas",
      "description": "Enviado ao novo usuário após o cadastro",
      "is_active": true,
      "created_at": "2026-05-10T12:00:00Z"
    }
  ]
}
```

Só comunicações com `is_active: true` aceitam envio. Uma lista vazia significa que a credencial funciona, mas a conta ainda não tem comunicações — crie a comunicação no painel antes de enviar.

### `send_message`

Envia uma mensagem para um destinatário. Equivale ao endpoint [`send-message`](https://docs.octasend.com.br/api-reference/enviar-mensagens) e segue as mesmas regras de canais, idioma, variáveis e limite por minuto.

```json theme={null}
{
  "communication_slug": "boas-vindas",
  "recipient": {
    "email": "joao@empresa.com",
    "phone": "+5511999999999",
    "user_id": "user_123",
    "telegram_chat_id": "123456789",
    "slack_channel": "#avisos"
  },
  "variables": { "nome": "João Silva", "plano": "Pro" },
  "language": "pt-BR",
  "channels": ["email", "whatsapp", "in_app"],
  "tag": ["onboarding", "junho-2024"]
}
```

| Parâmetro | Obrigatório | Descrição |
| - | - | - |
| `communication_slug` | Sim | Slug da comunicação |
| `recipient` | Sim | Dados do destinatário: `email`, `phone`, `user_id`, `fcm_token`, `telegram_chat_id`, `slack_user_id`, `slack_channel`, `push_token` (endpoint do dispositivo no Amazon SNS, para Push mobile). Informe só os dos canais usados |
| `variables` | Não | Valores das `{{variáveis}}` do template |
| `language` | Não | Idioma preferido (ex.: `pt-BR`) |
| `channels` | Não | Restringe o envio a estes canais |
| `tag` | Não | Tag ou lista de tags para filtrar depois nos logs |

> [!WARNING]
>
> Uma falha num canal não gera erro na tool: a resposta vem com `success: true` e o resultado de cada canal em `results[].status` (`sent`, `queued`, `failed` ou `skipped`). Confira sempre esse campo. Quando a conta atinge o [limite diário de mensagens](https://docs.octasend.com.br/api-reference/enviar-mensagens.md), o canal volta `failed` com `error_code: "daily_limit_reached"`.

### `send_messages_batch`

Envia de 1 a 100 mensagens numa única chamada. Cada item aceita `communication_slug`, `recipient` (com os mesmos campos do `send_message`, inclusive `push_token`), `variables`, `language`, `channels` e `tag`. Um slug inexistente ou inativo não derruba o lote: aquele item volta com `error`. Para listas maiores, divida em lotes. Veja [Envio em lote](https://docs.octasend.com.br/api-reference/enviar-mensagens.md#envio-em-lote).

### `get_message_stats`

Devolve um resumo dos envios do período.

```json theme={null}
{
  "period": "30d",
  "channel": "email"
}
```

| Parâmetro | Obrigatório | Descrição |
| - | - | - |
| `period` | Não | `7d` (padrão), `30d` ou `90d` |
| `channel` | Não | Filtra por canal (ex.: `email`) |

```json theme={null}
{
  "total": 120,
  "sent": 110,
  "failed": 6,
  "skipped": 4,
  "by_channel": { "email": 120 },
  "by_day": [
    { "date": "2026-09-01", "sent": 40, "failed": 2 }
  ]
}
```

O resumo considera todos os envios do período. `sent` conta os envios enviados, entregues e lidos (status `sent`, `delivered` e `read`); `failed` e `skipped` contam os envios com exatamente esse status; envios `queued` ou `processing` entram só em `total` e `by_channel`. As datas de `by_day` estão em UTC.

> [!TIP]
>
> Para relatórios completos e paginados, use o endpoint [Consultar logs](https://docs.octasend.com.br/api-reference/consultar-logs.md).

### `get_channel_config`

Mostra se um canal está configurado, sem expor credenciais. Útil para conferir um canal antes de enviar.

```json theme={null}
{
  "channel": "email"
}
```

`channel` aceita `email`, `whatsapp`, `telegram`, `slack`, `web_push`, `push` ou `in_app`.

```json theme={null}
{
  "channel": "email",
  "is_active": true,
  "configured": true,
  "config": {
    "from_email": "contato@sualoja.com.br",
    "from_name": "Sua Loja"
  },
  "configured_fields": ["email_method", "from_email", "from_name", "smtp_host", "smtp_password", "smtp_port", "smtp_user"]
}
```

`config` traz só dados não sensíveis (provedor, remetente, região); `configured_fields` lista os nomes dos campos preenchidos, sem os valores. Quando não há configuração salva para o canal, a resposta é `{"config": null}`.

> [!NOTE]
>
> Sem a configuração principal do canal, a consulta olha as conexões ativas da aba **Conexões** (a conexão padrão primeiro). Assim, um WhatsApp conectado só pela aba **Conexões** aparece como configurado.

### `create_communication`

Cria uma comunicação nova, já **publicada**, com canais e conteúdo por idioma. Em seguida, o `send_message` com esse slug já funciona. Equivale a `POST /create-communication`.

```json theme={null}
{
  "name": "Boas-vindas",
  "slug": "boas-vindas",
  "description": "Enviada no cadastro",
  "channels": [
    {
      "channel": "email",
      "templates": [
        { "language_code": "pt-BR", "subject": "Bem-vindo, {{nome}}", "body_html": "<p>Olá, {{nome}}!</p>" }
      ]
    },
    {
      "channel": "whatsapp",
      "templates": [
        { "language_code": "pt-BR", "messages": [ { "message_type": "text", "body_text": "Olá, {{nome}}!" } ] }
      ]
    }
  ]
}
```

O slug aceita `a-z`, `0-9`, `-` e `_` e não muda depois. Cada canal precisa estar habilitado na conta. A resposta traz a comunicação, no formato de `get_communication`, e `changes`.

Campos de cada template por canal:

| Canal | Campos | Obrigatórios |
| - | - | - |
| `email` | `subject`, `body_html`, `body_text`, `preheader` | `subject`; `body_html` ou `body_text` |
| `whatsapp` | `messages` (de 1 a 20; cada uma com `message_type`, `body_text`, `media`, `buttons`, `list`, `carousel`, `delay_after_ms`) | `messages` |
| `sms` | `body_text` | `body_text` |
| `push` | `title`, `body_text` | `body_text` |
| `web_push` | `title`, `body_text`, `url`, `icon`, `image_url` | `body_text` |
| `in_app` | `title`, `body_text`, `url`, `category` (`info`, `success`, `warning` ou `error`), `icon_url`, `image_url` | `body_text` |
| `telegram` | `body_text`, `parse_mode` (`HTML` ou `MarkdownV2`), `media_type`, `media_url`, `disable_preview`, `buttons` | `body_text` |
| `slack` | `body_text`, `blocks`, `username`, `icon_emoji`, `icon_url` | `body_text` |

No e-mail, o `body_html` deve ter estilos inline: o `<head>` é descartado.

### `update_communication`

Altera uma comunicação existente pelo slug. Equivale a `POST /update-communication`.

```json theme={null}
{
  "slug": "boas-vindas",
  "description": null,
  "channels": [
    { "channel": "email", "templates": [ { "language_code": "pt-BR", "subject": "Novo assunto, {{nome}}" } ] },
    { "channel": "sms", "is_active": false }
  ]
}
```

* Aceita `name`, `description` (`null` limpa), `is_active` e `channels`. Só os campos enviados mudam.
* Cada idioma alterado vira uma **versão nova publicada** na hora (`Versão N (API)`). A anterior fica guardada no painel e pode ser reativada. Conteúdo igual ao publicado não cria versão (`unchanged`).
* Canal ou idioma que ainda não existe é criado. Nada é excluído pela API.

### `get_communication`

Lê o conteúdo de uma comunicação: os canais e, por idioma, o template com as `{{variáveis}}` ainda não preenchidas. Equivale a `GET /get-communication?slug=<slug>`. Só `slug` é obrigatório.

```json theme={null}
{
  "slug": "boas-vindas",
  "channel": "email",
  "language": "pt-BR",
  "version": "Versão 1",
  "status": "published"
}
```

| Parâmetro | Obrigatório | Descrição |
| - | - | - |
| `slug` | Sim | Slug da comunicação |
| `channel` | Não | Devolve só este canal (`email`, `whatsapp`, `sms`, `telegram`, `slack`, `web_push`, `in_app` ou `push`) |
| `language` | Não | Devolve só este idioma (ex.: `pt-BR`) |
| `version` | Não | Nome da versão (ex.: `Versão 1`) |
| `status` | Não | `published` ou `unpublished` |

Sem `version` nem `status`, cada idioma traz só a versão **publicada**, a que é enviada. Com qualquer um dos dois, cada idioma lista todas as versões que casam, cada uma com `published` `true` ou `false`. `versions_count` é sempre o total de versões do idioma. Canal ou idioma sem conteúdo devolve `channels` vazio.

```json theme={null}
{
  "communication": {
    "slug": "boas-vindas",
    "channels": [
      {
        "channel": "email",
        "is_active": true,
        "templates": [
          {
            "language_code": "pt-BR",
            "published": true,
            "version_name": "Versão 1",
            "versions_count": 1,
            "subject": "Bem-vindo, {{nome}}",
            "body_html": "<p>Olá, {{nome}}!</p>",
            "body_text": "Olá, {{nome}}!"
          }
        ]
      }
    ]
  }
}
```

> [!WARNING]
>
> Com `version` ou `status`, um idioma pode aparecer várias vezes. Essa saída é só para leitura: não a reenvie para editar a comunicação.

### `get_message`

Devolve uma mensagem enviada pelo id (o `message_id` do `send_message`), com o conteúdo final em `sent_content`. Equivale a `GET /query-message-logs?id=<id>`.

```json theme={null}
{ "id": "3f1c2b9e-..." }
```

O formato de `sent_content` por canal está em [Consultar logs](https://docs.octasend.com.br/api-reference/consultar-logs.md#conteudo-enviado). Um id inexistente devolve `404`.

### `list_messages`

Lista as mensagens enviadas, da mais recente para a mais antiga, com paginação e `sent_content` em cada item. Todos os parâmetros são opcionais: `channel`, `status`, `communication_slug`, `tag`, `from`, `to` (ISO 8601), `page` e `limit` (até 100). Têm o mesmo significado dos parâmetros de [Consultar logs](https://docs.octasend.com.br/api-reference/consultar-logs.md).

## Documentando as comunicações no `CLAUDE.md`

Para o Claude saber qual comunicação usar em cada evento do seu produto, adicione uma seção ao `CLAUDE.md` do projeto:

```markdown theme={null}
## Notificações (OctaSend MCP)

Para disparar notificações use as tools do OctaSend MCP — não crie código de integração direto com a API.

| Evento                | Slug da comunicação | Variáveis obrigatórias |
|-----------------------|---------------------|------------------------|
| Novo cadastro         | boas-vindas         | nome                   |
| Pagamento confirmado  | pagamento-aprovado  | nome, plano, valor     |
| Trial expirando       | trial-expirando     | nome, dias_restantes   |
| Senha redefinida      | senha-redefinida    | nome                   |

Regras:
- Use send_messages_batch quando houver mais de 1 destinatário
- Inclua language com o idioma do usuário quando disponível (ex.: "pt-BR")
- Chame list_communications para confirmar os slugs antes de usar
```

## Prompt pronto para o Claude Code

Em **Configurações → MCP Server**, o botão **Copiar prompt** copia um roteiro completo para colar no Claude Code. Ele instrui a IA a conectar o MCP remoto, proteger as credenciais, listar as comunicações, mapear os eventos do seu projeto, implementar os envios, documentar tudo no `CLAUDE.md` e testar a integração.

## Solução de problemas

> [accordion] O servidor não aparece em /mcp, ou aparece com falha
>
> Quase sempre é a configuração antiga com `"type": "stdio"` e `npx octasend-mcp`. Troque para `"type": "http"` com a URL `https://octasend.com.br/mcp`.

> [accordion] Alguma tool devolve 401
>
> Não é falta de permissão: a mesma credencial libera todas as tools. Um `401` significa credencial inválida ou revogada. Confira se o header está no formato exato `Bearer client_id:client_secret` (dois-pontos, sem espaços) e se o OAuth Client continua **Ativo** em **Configurações → OAuth Clients**. Se você colocou um access token (`at_...`) no header, ele vale só 1 hora: troque pelo par `client_id:client_secret`.

> [accordion] A conexão responde 429 ou 503
>
> Um `429` não indica credencial inválida: o limite de pedidos de token foi atingido. Espere os segundos indicados no header `Retry-After` e tente de novo. Um `503` significa que o serviço de autenticação não respondeu; tente de novo em instantes.

> [accordion] list\_communications devolve uma lista vazia
>
> A credencial está funcionando — a conta é que ainda não tem comunicações. Crie a comunicação no painel antes de enviar.

> [accordion] send\_message devolve 404 Communication not found
>
> O slug não existe ou a comunicação está inativa. Use `list_communications` para conferir o slug e o `is_active`.

> [accordion] O envio responde, mas a mensagem não chega
>
> Veja `results[].status` de cada canal: `failed` ou `skipped` trazem o motivo em `error`. Confira também se o canal está configurado com `get_channel_config` e acompanhe o envio em [Consultar logs](https://docs.octasend.com.br/api-reference/consultar-logs.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.