Changelog
Notable changes to the public API, webhook payloads and MCP tools, newest first. Dates are UTC.
2026-10-25
- Added — MCP tool
me(titleGet current identity): returns the person, organization and token reach behind the connection, with the same JSON asGET /v1/me. Any valid MCP token may call it — no resource scope or permission required — so it is always listed bytools/list. Additive.
2026-10-22
MCP server, plus the rate-limit bucket it shares with the REST API.
- Added — every MCP tool carries a human
title(List e-mails,Replay webhook delivery), on thetools/listdescriptor and inannotations.title. Clients show it instead of the tool identifier. Additive. - Changed — the protected-resource metadata advertises in
scopes_supportedonly what the authorization server grants a client registered through the OAuth flow: oneinbox/…scope per resource, plusread.inbox/allandwriteare no longer listed — a client that asked for them was refused at/oauth/authorize. - Changed — rate limiting on the MCP server and on the REST API counts per person within the organization (
sub+org), on one shared budget. Every token of the same person draws from it — a new token never resets it — and the same person in another organization now has a budget of its own (before, the bucket wassubalone, across organizations). Limits are unchanged. - Changed — an unknown path on the MCP host (
https://mcp.inbox.kobana.com.br/anything) answers404with the JSON body{ "error": { "code": "not_found", "message": "not_found" } }for every method, instead of an HTML page. See Endpoints. - Documented — the MCP server reads the token only from
Authorization: Bearer; a token in the query string (?access_token=) is ignored and the request gets the401challenge. This was already the behaviour; it is now stated in Authentication and covered by tests. Likewiselimit,cursorandsortare only taken from their named arguments — undeclared keys (per_page,page, afiltersobject) are dropped (Pagination). - Changed (breaking) — destructive MCP tools run only after the server confirms them with the user. A client that cannot confirm — protocol 2025, or
2026-07-28without elicitation forms — gets the tool errorconfirmation_requiredand nothing runs (before, the tool ran and confirmation was left to the client'sdestructiveHinthandling). If the server cannot take the confirmation, the answer isconfirmation_unavailable. - Changed (breaking) —
emails_reprocess,webhooks_test,webhooks_deliveries_replayandinboxes_add_recipientare now destructive (destructiveHint: true): the first three send something outside or re-run an agent that may reply, the last changes who may send to an inbox.emails_reprocess,webhooks_test,webhooks_deliveries_replayandwebhooks_regenerate_secretnow reportidempotentHint: false. - Changed — a confirmation runs its action once: sending the same confirmed call again answers
confirmation_replayedwithout running anything. Ask again by calling the tool withoutrequestState. - Changed — the MCP request body is limited to 1 MB; above it the answer is
413with the JSON-RPC error-32600(Request body too large (limit 1048576 bytes)), checked onContent-Lengthbefore authentication and enforced on the stream itself. See Errors.
2026-10-21
MCP server only — the REST API is unchanged.
- Changed (breaking) — MCP authentication: the MCP server now requires a token issued for it —
audis the MCP server URL (https://mcp.inbox.kobana.com.br), not the API audience (inbox/prd). A token issued for the REST API is refused with401 invalid_token, and the reverse holds too; a token naming more than one audience is refused. Connect by the OAuth flow (the client only needs the URL) or with a personal token created with the MCP use. - Changed (breaking) — every MCP token is treated as a person's, whatever
srcit carries: the person's dashboard permissions always apply, and a person who is not a member of the organization reaches nothing (403,no_membership). Before, a token withsrc=systemorsrc=apipassed on scope alone. - Added — protocol revision
2026-07-28, next to2025-06-18and2025-03-26, decided by the request body:server/discover, the_metaenvelope,-32020for headers that disagree with the body and404for an unknown method. An unsupported version is now400with the JSON-RPC error-32022and the supported list, instead ofunsupported_protocol_version. - Added — resources under
kobana://inbox/(e-mails, inboxes, agents, runs, webhooks, events, the model catalog and usage), four read-only prompts and completions for their arguments. Each one is reached under the same scope and permission as the tool behind it. - Added — on
2026-07-28, a destructive tool asks the user to confirm first (resultType: "input_required"); declining answersuser_declined. Clients without elicitation, and the 2025 revisions, behave as before. - Added — the token's access level (
read,write,all) is honoured next toinbox/…+write: with resource scopes in the token, the resources define the reach and the level acts within them. See Scopes. - Changed — the authorization server being unreachable is
503withRetry-After(was500); invalid-token attempts are throttled per IP and answered429over the limit. The protected-resource metadata names the authorization server by its issuer.
2026-10-15
- Added —
Inbox.attachments_allow_rules: an allow list of attachments by extension and/or a regular expression on the filename, on create, update, upsert and the MCP inbox tools. An attachment outside the list is ignored — the agent does not see it, theattachments_max_*limits do not count it, and a workflow step that references it fails before any request. The e-mail records it inmetadata.ignoredAttachments. Defaultnullprocesses every attachment, as before. Additive. - Changed (behaviour) — a text attachment, or one sent to the agent as base64, above 256 KB now reaches the agent as its headline and
(conteúdo não enviado: …)instead of its content. PDFs and images are unaffected. Before, a large unreadable attachment (an Outlook.msg, say) could push the request past the model's input limit and fail the run.
2026-10-07
- Added — every outbound webhook now carries
X-Idempotency-Key. On the original dispatch and every automatic retry it is the event id (SystemEvent.id, the same value asX-Kobana-Event-Id), so an endpoint that honours idempotency keys processes the event once and answers the original response to the repeats. A manual replay sends a fresh, random key instead, so the destination treats it as a new delivery rather than deduplicating it against whatever that event already settled. See Headers. Additive. - Changed (behaviour) —
WebhookDelivery: a scheduled retry is no longer sent once any delivery of the same event to the same webhook has succeeded, typically after a manual replay. Previously the retry chain of the original failed delivery kept running after the replay got the event through, so the destination could receive one more attempt after a2xx. Thenext_retry_atof the earlierfailedrows is now cleared at that point. No field changed shape.
2026-09-30
- Changed (behaviour) — Agent workflows no longer stop at the first failure. Every step is attempted; a failing step is
failedon its own and the steps after it still run. A step that references a step that did not succeed (failed or skipped) isskippedand never sent, witherrordepends on step N, which did not succeed. The run is stillfailedif any step failed, and itserrornow lists every failure, one per line (step <position>: <error>). No retry, still sequential. - Added —
failed_stepsonworkflow.run.failedwebhooks (failedStepson the system event): the positions of every failed step.failed_stepanderrorkeep describing the first failure.
failed_steps is additive and no field changed shape — but the execution change is a behaviour change: a run that used to stop at step 1 now also runs the independent steps after it.
2026-09-29
- Added — Steps and placeholders: a
requeststep may carryforminstead ofbody. It is sent asmultipart/form-data, one part per field; the two are mutually exclusive. - Added — placeholder namespace
${{email.attachments.N}}: the N-th attachment of the e-mail behind the run. As the whole value of aformfield it is uploaded as a binary file part (bytes, filename and content type from the e-mail); inside any string it resolves to the file's base64..base64,.filename,.content_typeand.sizeare also available. The bytes never pass through the model. - Changed —
WorkflowRunsteps now exposerequest.form(nullfor abodystep). A file field is recorded as a{ attachment, filename, content_type, size }descriptor, and an attachment referenced as base64 insiderequest.bodyis stored as[attachment N: …]rather than as its bytes.
All additive — nothing existing changed shape or behaviour.
2026-09-24
- Changed (breaking) — Authentication: the Bearer token is now an RS256 access token issued by the Kobana authorization server, verified against the public key it publishes. Tokens signed with the previous shared
HS512secret are no longer accepted. Nothing changes in how you send the token — only which tokens verify.orgis now required, and it is what scopes your data.subis the person (users.public_id); the tenant isorg(accounts.public_id). A token withoutorgis refused rather than falling back tosub— a fallback would match nothing and answer403to everything, with nothing naming the cause.issis now the authorization server's URL (https://account[.{env}].kobana.com.br);audis this API's URL (https://api.inbox[.{env}].kobana.com.br) and may be a list, matched by contains.expis now required. A token without an expiry is rejected.- New failure mode
500 as_unavailable: our authorization server could not be reached. It is deliberately not a401— your token may be perfectly valid; retry shortly.
2026-09-09
- Added — Agent workflows: an agent may now end its run with a
workflowarray alongsideresult, and the platform executes it as a chain of HTTP requests against your systems. Sequential, fail-fast, executed once. - Added —
Secretresource and/v1/secrets(GET,POST,PUTupsert bykey,GET/PATCH/DELETEby id). Values a workflow step references as${{secrets.KEY}}; the value is write-only and is never returned by any endpoint. Scopeinbox/secrets(+write). - Added —
WorkflowRunresource and/v1/workflow-runs(GETlist,GETby id with every step). Read-only. Scopeinbox/workflow_runs. Counts are grouped undersummary: { total, succeeded, error }, and each step's HTTP call underrequest: {}/response: {}. - Added — MCP tools
secrets_list,secrets_get,secrets_create,secrets_upsert,secrets_update,secrets_delete,workflow_runs_list,workflow_runs_get, and the matching stdio servers. - Added — webhook events
workflow.run.succeeded,workflow.run.failed,workflow_run.db.created,workflow_run.db.updated,workflow_run.status_changed. - Changed —
email.agent.processedpayloads now also carryworkflow_run_id(nullwhen the agent returned no workflow). Additive: existing consumers are unaffected.
All additive — nothing existing changed shape or behaviour.
2026-09-08
- Added —
email.*webhook payloads now carrydata.email.download_url: a ready-to-use link to the original.eml, valid for 30 minutes, that a webhook receiver can follow with no mTLS certificate or API JWT. See Downloading the.emlfrom a webhook. Additive change — existingdata.emailconsumers are unaffected.