Use Comma with marimo

marimo fixed the notebook half of the problem: reactive execution, no hidden state, notebooks stored as plain Python files that diff cleanly in git. And it ships an honest export story — marimo export html snapshots the notebook, outputs included, into an HTML file.

What it doesn't ship is the step after: the analysis is done, the export exists, and now a PM, a data lead, and two engineers need to read it and tell you what's wrong with it. Git diffs of the .py file review the code. Nobody reviews the findings in a diff.

Comma is that step. Publish the export, share one link, and feedback arrives anchored to the exact output it's about.

The pipeline

1. Export the notebook

marimo export html retention_analysis.py -o retention.html

This snapshots the notebook as it last ran — markdown, code, rendered outputs — into a single HTML document. That's the right artifact for review: the run you got, frozen, not a live re-execution that might differ. (Skip the html-wasm export here; it builds a multi-file site for static hosting, and Comma takes one document.)

2. Publish it to Comma

The create endpoint accepts JSON with a required html field and optional title and description:

jq -Rs '{title: "Retention analysis — June", html: .}' retention.html |
  curl -s -X POST https://commareports.com/api/v1/reports \
    -H "Authorization: Bearer $COMMA_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data-binary @-

The response carries the link to share:

{
  "id": "b27e…",
  "title": "Retention analysis — June",
  "created_at": "2026-06-10T08:00:00Z",
  "edit_url": "/r/b27e…",
  "share_url": "/p/b27e…"
}

Reports default to public-with-link, view-only. Add "public_permission": "comment" so anyone with the link can comment, or "visibility": "private" to restrict it to people you invite. Tokens are minted under Settings → API tokens, scoped and revocable. HTML up to 5 MB.

3. Review like a document

Reviewers open the link in a browser — no marimo install, no environment setup, no repo access. They highlight a sentence in your markdown commentary or a cell in a results table and pin a comment to it, Google-Docs style. Threads, replies, resolution. Commenting is free on every plan; only creators pay, and only for scheduling and team features.

4. Re-run, republish, same link

When the comments come back — "cell 4's join is dropping nulls," "rerun with the May cohort included" — fix the notebook, export, and PATCH:

jq -Rs '{html: .}' retention.html |
  curl -s -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
    -H "Authorization: Bearer $COMMA_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data-binary @-

Comma appends a revision under the same share URL and keeps the comment threads attached, so the conversation and the artifact stay in one place across runs.

What renders, honestly

Comma renders the export untouched in an opaque-origin sandbox — no reformatting, no restyling. One deliberate exception: the API strips <script> tags before storage, as defense-in-depth on an endpoint that accepts arbitrary HTML. For a marimo export that means markdown, code, tables, and static figures (matplotlib SVG/PNG, rendered DataFrames) survive faithfully, while script-driven interactivity — altair/plotly tooltips, marimo UI elements — renders statically or not at all.

For review that's usually the right trade: a comment can anchor to a rendered chart; it can't anchor to a hover state. Keep the interactive notebook for exploration and publish the snapshot for review.

With an agent in the loop

If the notebook is run by Claude Code or Cursor, skip the curl. Comma's MCP server exposes create_report, update_report, list_comments, and reply_to_comment as typed tools under the same comma_sk_… token. The agent exports the notebook, publishes the HTML, and — on its next run — reads the anchored comments and addresses them before republishing. The Claude Code plugin installs in one line.

To make the whole thing recur, either run the export + PATCH from your own cron (works on Free), or use Comma routines — hosted scheduling that re-runs a skill and republishes, daily on Pro ($9/month) and hourly on Team.

Try it

Export a notebook you've already run and publish it. The difference shows up in the first comment: it lands on the row of the table it's about, instead of in a Slack thread describing where to look.

Create your first report →

Related