Publish a report
publish_report turns a live agent analysis into a frozen, shareable HTML report hosted on your brand’s own subdomain.
Your agent calls it after building a report in your chat; you do not call it yourself.
Because publish_report writes something new (it is annotated as a write tool, like the Brand Knowledge Base write tools), most MCP clients ask you to approve the call before it runs.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
| title | string | Yes | Human title for the report. Kreel derives the URL slug from it (lowercased, hyphenated, capped at 80 characters). A title that collides with an existing report in the same brand gets a numeric suffix, like -2. Always use the slug/url Kreel returns rather than reconstructing it from the title. |
| html | string | Yes | The full, self-contained HTML document to publish. See What to pass as html below. |
| brand | string | Only if you can reach more than one brand | Brand name or id. Auto-selected when you can reach exactly one brand. |
| supersedes | string | No | The slug or id of a previously published report, in the same brand, that this report corrects. See Updating or replacing a report. |
Returns: {slug, url, viewable, note}.
viewable is true only when the report can actually be opened right now (a handle is claimed, a password is set, and the workspace’s billing is current).
note is present whenever there is something you need to do before the report is viewable; see Access gating.
What to pass as html
Section titled “What to pass as html”Tell your agent to build one self-contained HTML document: structure, styling, and any charts inline in the page, not split across files. CSS and JavaScript are allowed and continue to work once published.
A few things to know about how the HTML is handled:
- Reference images by URL, not base64. Kreel snapshots images for you at publish time (see below), so inlining large base64 images just bloats the document.
- Do not add your own trust or methodology section. Kreel automatically appends a data-trust section server-side: connected sources, last successful sync and data-through dates, common metric definitions, and a note that revenue reported by different channels overlaps and should not be summed. Your authored HTML renders below that section inside a sandboxed frame, and cannot hide, rewrite, or navigate over it.
- Do not summarize revenue by adding it across channels.
Store revenue (Shopify, refund-corrected) and attributed revenue (Meta, Google, Klaviyo) are different bases.
Have your agent call
get_brand_contextbefore building the report and disclose any readiness warnings, the same as it would for a live answer.
Image handling
Section titled “Image handling”If your report includes creative thumbnails from get_creatives, only one URL form survives publishing:
Images up to 4 MB are inlined directly into the published document. Larger images are stored at a durable URL on the report itself and load from there instead, behind the same password gate as the report.
Where the report is served
Section titled “Where the report is served”A published report lives at:
https://{handle}.reports.kreel.ai/{slug}{handle}is a subdomain an owner or admin claims once per brand, in Manage reports, not per report. It is globally unique across all of Kreel.{slug}is derived fromtitleand only needs to be unique within your brand.
This is a separate origin from app.kreel.ai.
Report HTML and JavaScript run isolated from your dashboard session and from any other brand’s reports.
Access gating
Section titled “Access gating”A newly published report is not publicly reachable right away. Two things must be true first, both set by an owner or admin in Manage reports:
- The brand has a claimed report handle.
- The brand has a report password set (minimum 8 characters).
Until both are true, publish_report still succeeds and stores the report, but the response tells you what is missing:
- No handle claimed yet:
urlisnull,viewable: false, with a note that an owner or admin needs to claim a handle. - Handle claimed but no password set:
viewable: false, with a note that an owner or admin needs to set a password. - Both set, but the workspace’s billing has lapsed:
viewable: false, with a note that the report is temporarily not being served (see below).
Once a password is set, a visitor enters it once and it unlocks every report on that brand, not just the one they opened. Rotating the password signs everyone out.
Updating or replacing a report
Section titled “Updating or replacing a report”Reports are immutable once published. There is no edit call.
Never call publish_report twice with the same title.
If a live report - one that has not already been superseded - with that exact title already exists in your brand, the call is refused instead of quietly creating a second, disconnected report.
The refusal comes back with existing_slug and existing_url naming the report already in place.
Get your human’s approval, then re-call publish_report with supersedes set to that existing_slug.
If the title match is a coincidence and you actually meant a different, unrelated report, change the title instead of retrying.
To correct a report you own the intent to replace, publish a new report and pass supersedes set to the old report’s slug or id.
The old report stays stored and individually viewable, but its URL now redirects to the new one.
supersedes accepts a reference to any report previously published in this brand, including one that has already been superseded itself - it always links at the current end of that report’s correction chain, so a chain of two or more corrections still redirects straight to the newest report, not an intermediate one.
supersedes must point at a report in the same brand.
A cross-brand reference is rejected.
There is no MCP delete or archive call. Removing a report entirely is a permanent, human-only action in the dashboard - see Manage reports in the dashboard.
Manage reports in the dashboard
Section titled “Manage reports in the dashboard”Claiming a handle, setting or rotating the password, and viewing or deleting existing reports all happen in the dashboard, not through the agent. See Hosted reports for the Reports page: claiming a handle, setting a password, and reading each report’s view count and last-viewed date.
Deleting a report is a permanent, human-only action available to owners and admins there.
publish_report itself can only create new reports; it cannot delete or overwrite one.
Example: publish a monthly report
Section titled “Example: publish a monthly report”-
Ask your connected agent to build and publish the report, naming your brand if you have more than one:
Using Kreel, build my Acme performance report for last month and publish it with publish_report using brand "Acme".Or use the ready-made monthly report prompt instead of writing this from scratch.
-
The agent gathers the data it needs, typically
get_brand_contextfor readiness and revenue policy,get_performancefor the month’s channel-by-channel numbers, andget_creativesif the report includes creative highlights. -
The agent composes one HTML document from that data and calls the tool:
publish_report(title="July 2026 Performance Report",html="<html>...</html>",brand="Acme") -
Kreel stores the report, appends the data-trust section, and returns a
slugand (if your brand already has a handle and password set) aurlyou can open right away. -
If the response came back with
viewable: falseor nourl, an owner or admin sets the handle and password once, in Hosted reports, and the same link starts working without republishing anything.
Need help?
Section titled “Need help?”Email support@kreel.ai.