A mini-site is a sandboxed HTML page attached to a brain.
One-pagers, dashboards, intake forms, decks, custom admin panels,
visualizations — anything you'd otherwise build in a notebook and
never share. Each mini-site lives at /m/<id>, renders in a strict
sandbox with no outbound network, and can optionally talk to a
board and/or an embedded chat agent.
Why this exists
Users want to render their data as something more visual than a list of search results. Telling Claude "make me a one-pager about Project X" or "build me an admin panel for my leads board" should produce something they can share by URL — not a Markdown blob they have to paste somewhere.
Mini-sites are the "publish what you've built" primitive. They sit between a board (the data) and an audience (your team, your investors, a customer) and let you ship a real surface in one tool call.
Shape
mini_site
├── id, brain_id, name, description
├── html — the whole rendered document (head, body, inline CSS/JS)
├── context — hidden author notes; consumed by the embedded chat agent
├── board_id? — optional bound board for live read/write via postMessage
└── created_at, updated_at
The HTML is stored verbatim. brains doesn't template it server-side — it serves it inside a sandboxed iframe and stops worrying. Any "templating" you want (passing in a board's rows, embedding a chart library) happens at creation time when Claude composes the HTML.
How it renders — and why the sandbox matters
/m/<id> returns a page that wraps the mini-site's HTML in an iframe:
<iframe
src="/m/<id>/raw"
sandbox="allow-scripts"
csp="default-src 'self' 'unsafe-inline'; connect-src 'none'; …"
></iframe>
The connect-src 'none' line is load-bearing: mini-site code
cannot fetch anything, which means it can't leak the user's
session cookie or call out to the brains MCP. Anything that needs
data has to come from the mini-site's HTML at creation time — or
through the postMessage bridge to the parent window.
The parent page proxies bridge messages to the right MCP tool on behalf of the signed-in user. Permissions still apply: the bridge only executes operations the current user is authorised to perform.
The relationship with boards
A mini-site bound to a board is the most common pattern. The
mini-site reads the board's rows (inlined at creation, or live via
the bridge) and writes new ones via postMessage — same protocol
documented in boards for dashboards.
<!-- inside a mini-site bound to a "leads" board -->
<form id="f">
<input name="name" required />
<input name="email" required />
<button>Add lead</button>
</form>
<script>
document.getElementById('f').addEventListener('submit', (e) => {
e.preventDefault();
const row = Object.fromEntries(new FormData(e.target));
window.parent.postMessage(
{ type: 'board.row.append', dataset: 'leads', row },
'*'
);
});
</script>
The same surface used by board dashboards is reused here — same
message types, same .result echoes, same permission model.
Dashboards, forms, admin panels — same primitive
What you build inside a mini-site is up to you. Three common shapes:
- Dashboard — read-only chart or list of a board's rows. The
rows are inlined at build time as a
<script type="application/json">blob; the chart code is inlined too. - Form — intake that appends rows to a board via
postMessage, with an optional thank-you state after submission. No backend required. - Admin panel — full CRUD over a board's rows. Read/append/update/ delete all flow through the bridge. The board's existing permissions still gate every write.
Embedded chat
A mini-site can include a chat panel that runs an in-product agent:
- User types a question in the panel.
- The web app enqueues an agent run with the mini-site's
contextas system prompt and the user's question as the first turn. - The agent runs the Anthropic Agent SDK loop with a focused tool
grant (typically just
get_page,search, and the board tools relevant to the mini-site's topic). - Events stream back to the panel.
The context field is the trick — it's hidden from the rendered
page but seeded into the agent's system prompt, so the in-page chat
"knows" what the mini-site is about without that knowledge leaking
into the public HTML. Read the transcript any time with
get_mini_site_chat.
Versioning and publish
Every save creates a new version. The latest version is what /m/<id>
serves. Earlier versions are kept, so you can:
- Inspect the history with
list_mini_site_history. - Pull a specific version's HTML with
get_mini_site_history_entry. - Roll back with
revert_mini_site entry_id=<old version id>.
Use this when you ship a redesign and a colleague reports something broke — roll back, debug, re-ship.
Sharing and embedding
Two modes:
- Brain members — read access by default for any user in the brain that owns the mini-site.
- External sharing —
share_mini_siteinvites a user by email, or mints a one-off share token. Roles tracked per mini-site.
External shares get a URL like /m/<id>?share=<token>. The token
grants read-only access without requiring sign-in. Use it for
fundraising one-pagers, partnership decks, customer-facing dashboards.
share_mini_site_with_org cascades the access to your whole org;
unshare_mini_site / unshare_mini_site_with_org revoke it.
Limitations to keep in mind
- No live data. The HTML is frozen at creation time. To "refresh" a mini-site, regenerate it (often through Claude with the latest data) or bind it to a board and read live via the bridge.
- No outbound network. No real-time charts, no third-party embeds that need to fetch. Charts have to be built with inlined data (or a board-bound bridge read).
- One HTML document. No multi-page mini-sites today — though internal CSS/JS-driven "views" inside a single document work fine.
Tool surface
| Tool | Purpose |
|---|---|
create_mini_site |
Create. Returns id + URL. |
update_mini_site |
Patch html / context / name. Creates a new version. |
get_mini_site |
Read one. |
list_mini_sites |
All for a brain. |
delete_mini_site |
Self-explanatory. |
add_mini_site_comment / list_mini_site_comments |
Threaded comments on a mini-site. |
share_mini_site / unshare_mini_site / list_mini_site_members |
Per-user sharing. |
share_mini_site_with_org / unshare_mini_site_with_org |
Org-wide sharing. |
list_mini_site_history / get_mini_site_history_entry / revert_mini_site |
Versioning. |
get_mini_site_chat |
Read the embedded-chat transcript. |