Pular para o conteúdo principal

Changelog

Mudanças relevantes na API pública, nos payloads de webhook e nas tools de MCP, mais recentes primeiro. Datas em UTC.

2026-10-25​

  • Adicionado — tool MCP me (título Get current identity): devolve a pessoa, a organização e o alcance do token da conexão, com o mesmo JSON de GET /v1/me. Qualquer token MCP válido pode chamá-la — sem escopo de recurso nem permissão — então o tools/list sempre a lista. Aditivo.

2026-10-22​

Servidor MCP, mais o bucket de rate limit que ele compartilha com a API REST.

  • Adicionado — toda tool do MCP traz um title legível (List e-mails, Replay webhook delivery), no descritor do tools/list e em annotations.title. O cliente mostra o título no lugar do identificador. Aditivo.
  • Alterado — o metadata do recurso protegido anuncia em scopes_supported só o que o authorization server concede a um cliente registrado pelo fluxo OAuth: um escopo inbox/… por recurso, mais read. inbox/all e write saíram da lista — o cliente que os pedia era recusado no /oauth/authorize.
  • Alterado — o limite de requisições do servidor MCP e da API REST conta por pessoa dentro da organização (sub + org), num único orçamento compartilhado. Todo token da mesma pessoa consome dele — um token novo nunca o zera — e a mesma pessoa em outra organização passa a ter orçamento próprio (antes o bucket era só o sub, atravessando organizações). Os limites não mudam.
  • Alterado — um caminho desconhecido no host MCP (https://mcp.inbox.kobana.com.br/qualquer-coisa) responde 404 com o corpo JSON { "error": { "code": "not_found", "message": "not_found" } } em qualquer método, em vez de uma página HTML. Veja Endpoints.
  • Documentado — o servidor MCP lê o token só de Authorization: Bearer; um token na query string (?access_token=) é ignorado e a requisição recebe o desafio 401. Esse já era o comportamento; agora está dito em Autenticação e coberto por testes. Do mesmo jeito, limit, cursor e sort só vêm dos argumentos nomeados — chaves não declaradas (per_page, page, um objeto filters) são descartadas (Paginação).
  • Alterado (incompatível) — tools MCP destrutivas só rodam depois de o servidor confirmá-las com o usuário. Um cliente que não consegue confirmar — protocolo 2025, ou 2026-07-28 sem formulários de elicitation — recebe o erro de tool confirmation_required e nada é executado (antes, a tool rodava e a confirmação ficava a cargo do tratamento de destructiveHint do cliente). Se o servidor não conseguir registrar a confirmação, a resposta é confirmation_unavailable.
  • Alterado (incompatível) — emails_reprocess, webhooks_test, webhooks_deliveries_replay e inboxes_add_recipient passam a ser destrutivas (destructiveHint: true): as três primeiras enviam algo para fora ou reexecutam um agente que pode responder, a última muda quem pode enviar para uma inbox. emails_reprocess, webhooks_test, webhooks_deliveries_replay e webhooks_regenerate_secret agora informam idempotentHint: false.
  • Alterado — uma confirmação executa a ação uma única vez: enviar de novo a mesma chamada confirmada responde confirmation_replayed sem executar nada. Para perguntar de novo, chame a tool sem requestState.
  • Alterado — o body da requisição MCP é limitado a 1 MB; acima disso a resposta é 413 com o erro JSON-RPC -32600 (Request body too large (limit 1048576 bytes)), conferido pelo Content-Length antes da autenticação e garantido na leitura do próprio stream. Veja Erros.

2026-10-21​

Só o servidor MCP — a API REST não muda.

  • Alterado (breaking) — Autenticação do MCP: o servidor MCP agora exige um token emitido para ele — o aud é a URL do servidor MCP (https://mcp.inbox.kobana.com.br), não a audience da API (inbox/prd). Um token emitido para a API REST é recusado com 401 invalid_token, e o inverso também vale; um token que nomeia mais de uma audience é recusado. Conecte pelo fluxo OAuth (o cliente só precisa da URL) ou com um token pessoal criado com o uso MCP.
  • Alterado (breaking) — todo token MCP é tratado como de uma pessoa, qualquer que seja o src que carrega: as permissões da pessoa no dashboard sempre se aplicam, e uma pessoa que não é membro da organização não alcança nada (403, no_membership). Antes, um token com src=system ou src=api passava só pelo escopo.
  • Adicionado — a revisão de protocolo 2026-07-28, ao lado de 2025-06-18 e 2025-03-26, decidida pelo body da requisição: server/discover, o envelope _meta, -32020 para headers que divergem do body e 404 para método desconhecido. Uma versão não suportada agora é 400 com o erro JSON-RPC -32022 e a lista das suportadas, em vez de unsupported_protocol_version.
  • Adicionado — resources sob kobana://inbox/ (e-mails, inboxes, agentes, execuções, webhooks, eventos, o catálogo de modelos e o uso), quatro prompts somente leitura e completions para os argumentos deles. Cada um é alcançado sob o mesmo escopo e a mesma permissão da tool por trás dele.
  • Adicionado — no 2026-07-28, uma tool destrutiva pede ao usuário que confirme antes (resultType: "input_required"); recusar responde user_declined. Clientes sem elicitation, e as revisões de 2025, se comportam como antes.
  • Adicionado — o nível de acesso do token (read, write, all) é respeitado ao lado de inbox/… + write: com escopos de recurso no token, os recursos definem o alcance e o nível age dentro deles. Veja Escopos.
  • Alterado — o authorization server inalcançável agora é 503 com Retry-After (era 500); tentativas com token inválido são limitadas por IP e recebem 429 acima do limite. Os metadados do recurso protegido nomeiam o authorization server pelo seu emissor.

2026-10-15​

  • Adicionado — Inbox.attachments_allow_rules: lista de anexos permitidos por extensão e/ou expressão regular no nome do arquivo, no create, update, upsert e nas tools MCP de inbox. Um anexo fora da lista é ignorado — o agente não o vê, os limites attachments_max_* não o contam e um passo de workflow que o referencia falha antes de qualquer requisição. O e-mail o registra em metadata.ignoredAttachments. O padrão null processa todos os anexos, como antes. Aditivo.
  • Alterado (comportamento) — um anexo de texto, ou um enviado ao agente em base64, acima de 256 KB agora chega ao agente só com o cabeçalho e (conteúdo não enviado: …), em vez do conteúdo. PDFs e imagens não mudam. Antes, um anexo ilegível grande (um .msg do Outlook, por exemplo) podia passar do limite de entrada do modelo e derrubar a execução.

2026-10-07​

  • Adicionado — todo webhook de saída agora carrega X-Idempotency-Key. No disparo original e em toda retentativa automática, é o id do evento (SystemEvent.id, o mesmo valor de X-Kobana-Event-Id), para que um endpoint que honra chaves de idempotência processe o evento uma vez e responda às repetições com a resposta original. Um replay manual envia uma chave nova e aleatória, para que o destino trate como uma entrega nova em vez de deduplicá-la contra o que aquele evento já resolveu. Veja Headers. Aditivo.
  • Alterado (comportamento) — WebhookDelivery: uma retentativa agendada não é mais enviada quando qualquer entrega do mesmo evento ao mesmo webhook já teve sucesso, tipicamente após um replay manual. Antes, a cadeia de retentativas da entrega original continuava depois de o replay ter entregue o evento, e o destino podia receber mais uma tentativa depois de um 2xx. O next_retry_at das linhas failed anteriores agora é limpo nesse momento. Nenhum campo mudou de formato.

2026-09-30​

  • Alterado (comportamento) — Workflows do agente deixam de parar na primeira falha. Todos os passos são tentados; um passo que falha fica failed sozinho e os seguintes continuam rodando. Um passo que referencia um passo que não teve sucesso (falhou ou foi pulado) fica skipped e nunca é enviado, com error depends on step N, which did not succeed. A execução continua failed se algum passo falhou, e seu error agora lista todas as falhas, uma por linha (step <posição>: <erro>). Sem retentativa, ainda sequencial.
  • Adicionado — failed_steps nos webhooks de workflow.run.failed (failedSteps no system event): as posições de todos os passos que falharam. failed_step e error continuam descrevendo a primeira falha.

O failed_steps é aditivo e nenhum campo mudou de forma — mas a mudança de execução é uma mudança de comportamento: uma execução que antes parava no passo 1 agora também roda os passos independentes depois dele.

2026-09-29​

  • Adicionado — Steps e placeholders: um passo request pode carregar form no lugar de body. É enviado como multipart/form-data, uma parte por campo; os dois são exclusivos.
  • Adicionado — namespace de placeholder ${{email.attachments.N}}: o N-ésimo anexo do e-mail por trás do run. Como valor inteiro de um campo de form, é enviado como parte binária de arquivo (bytes, nome e content type do e-mail); dentro de qualquer string, vira o base64 do arquivo. .base64, .filename, .content_type e .size também estão disponíveis. Os bytes nunca passam pelo modelo.
  • Alterado — os passos de WorkflowRun agora expõem request.form (null num passo com body). Um campo de arquivo é registrado como um descritor { attachment, filename, content_type, size }, e um anexo referenciado como base64 dentro de request.body é gravado como [attachment N: …] em vez dos bytes.

Tudo aditivo — nada existente mudou de forma ou comportamento.

2026-09-24​

  • Alterado (breaking) — Autenticação: o token Bearer passa a ser um access token RS256 emitido pelo Authorization Server da Kobana, verificado contra a chave pública que ele publica. Tokens assinados com o segredo HS512 compartilhado anterior deixam de ser aceitos. Nada muda em como você envia o token — só em quais tokens verificam.
    • org passa a ser obrigatória, e é ela que escopa seus dados. sub é a pessoa (users.public_id); o tenant é org (accounts.public_id). Token sem org é recusado em vez de cair no sub — o fallback não casaria com nada e responderia 403 em tudo, sem nada apontar a causa.
    • iss agora é a URL do Authorization Server (https://account[.{env}].kobana.com.br); aud é a URL desta API (https://api.inbox[.{env}].kobana.com.br) e pode ser uma lista, comparada por contém.
    • exp passa a ser obrigatória. Token sem expiração é recusado.
    • Novo modo de falha 500 as_unavailable: nosso Authorization Server não pôde ser alcançado. Não é 401 de propósito — seu token pode estar perfeito; tente de novo em instantes.

2026-09-09​

  • Adicionado — Workflows do agente: um agente agora pode encerrar sua execução com um array workflow ao lado de result, e a plataforma o executa como uma cadeia de requisições HTTP contra os seus sistemas. Sequencial, para na primeira falha, executado uma única vez.
  • Adicionado — recurso Secret e /v1/secrets (GET, POST, PUT upsert por key, GET/PATCH/DELETE por id). São os valores que um passo de workflow referencia como ${{secrets.KEY}}; o valor é somente escrita e nunca é devolvido por nenhum endpoint. Escopo inbox/secrets (+ write).
  • Adicionado — recurso WorkflowRun e /v1/workflow-runs (GET lista, GET por id com todos os passos). Somente leitura. Escopo inbox/workflow_runs. As contagens ficam agrupadas em summary: { total, succeeded, error }, e a chamada HTTP de cada passo em request: {} / response: {}.
  • Adicionado — tools MCP secrets_list, secrets_get, secrets_create, secrets_upsert, secrets_update, secrets_delete, workflow_runs_list, workflow_runs_get, e os servidores stdio correspondentes.
  • Adicionado — eventos de webhook workflow.run.succeeded, workflow.run.failed, workflow_run.db.created, workflow_run.db.updated, workflow_run.status_changed.
  • Alterado — payloads de email.agent.processed agora também trazem workflow_run_id (null quando o agente não devolveu workflow). Aditivo: quem já consome não é afetado.

Tudo aditivo — nada existente mudou de formato ou comportamento.

2026-09-08​

  • Adicionado — payloads de webhook email.* agora trazem data.email.download_url: um link pronto pra uso para o .eml original, válido por 30 minutos, que quem recebe o webhook pode seguir sem certificado mTLS nem JWT da API. Ver Baixando o .eml a partir de um webhook. Mudança aditiva — quem já consome data.email não é afetado.