Let an AI agent respond to comments
An agent that publishes a report is half a workflow. The other half is the agent reading the feedback and responding. Without that half, every agent run is independent — there is no "second draft."
This page is about the second half.
The three primitives
Comma's MCP server exposes the comment primitives as typed tools. An agent in Claude Code, Cursor, or any MCP-capable client can call:
list_comments(report_id)
Returns the threads on the report. Each thread includes:
- The anchored text the comment is attached to
- The comment body
- The author (the human reviewer, or another agent under a different token)
- The status (open or resolved)
- Any replies
This is the agent's read path — what reviewers actually said, attached to the specific content they said it about.
reply_to_comment(thread_id, body)
Posts a reply to an existing thread. The reply is attributed to the agent's token. Humans see the reply with the same UI affordance as a human-authored reply — it's a first-class comment.
This is the agent's voice — how it explains what it changed, asks for clarification, or pushes back on a request.
set_comment_status(thread_id, status)
Marks a thread resolved or reopens it. The agent uses this when it
believes the feedback has been addressed.
This is the agent's housekeeping — keeping the surface clean as the loop runs.
The full loop
With those three primitives plus update_report (which ships a new
revision), the loop is:
1. Agent runs (either ad-hoc or via a routine)
2. Agent calls list_comments(report_id) to read any open feedback
3. Agent decides what to do:
- If the feedback applies to this run, incorporate it
- If clarification is needed, reply_to_comment with a question
- If the feedback is outdated or wrong, reply explaining why
4. Agent generates the new HTML
5. Agent calls update_report(report_id, new_html) to ship the revision
6. For each addressed thread: reply_to_comment summarizing the change
7. For each fully closed thread: set_comment_status(resolved)
That's the entire pattern. From a working example, it's about thirty lines in a Claude skill, plus the underlying analysis itself.
Three working patterns
Pattern 1: Routine-triggered loop
The most common shape. A Comma routine fires on a cadence. As part of the skill, the agent reads open comments before generating new output. By the time the routine posts the new revision, the agent has already addressed last cycle's open threads.
This works for any recurring report: daily eval, weekly analytics digest, monthly compliance. See Routines →.
Pattern 2: Human-prompted loop
A human asks the agent (via Claude Code or Cursor) to "address the open
comments on the weekly analytics report." The agent uses
search_reports or get_report to locate the report, list_comments
to read the threads, and updates the report and replies accordingly.
This is the on-demand version — useful for situations where the cadence is irregular or the agent should only act when asked.
Pattern 3: Watchdog agent
A small agent runs hourly, calls list_comments on a watchlist of
reports, and surfaces unresolved threads to a human (via Slack, email,
or another Comma report). The watchdog itself doesn't address the
feedback; it just makes sure nothing goes unread.
This is the "is anything blocked?" pattern, useful when reports are high-stakes and you want a backstop.
What the agent should not do
A few common mistakes worth flagging:
Don't auto-resolve threads without acknowledging them
A thread set to resolved without a corresponding reply_to_comment
reads as the agent ignoring feedback. The human reviewer needs to see
what changed and why before the thread closes.
The agent's reply doesn't need to be elaborate — "Filtered the pricing-test cohort; new Q3 number is 9.1%." — but it needs to exist.
Don't argue every disagreement
Sometimes the human is wrong (or the agent's data is). Sometimes the agent is wrong. The skill's prompt should err on the side of trusting the human and asking for clarification rather than litigating in the thread. The thread is for collaboration, not debate.
Don't update the report silently
If the agent shipped a new revision in response to a thread, it should also reply in the thread saying so. Otherwise the reviewer doesn't know their comment did anything.
Don't loop on list_comments more than necessary
The MCP server rate-limits per token. Polling list_comments every few
seconds wastes the budget and trips the limit. Read at the start of the
run; react to what's there.
Token shape for this loop
The agent needs comments:read, comments:write, and reports:write
scopes on its token. See
Scoped tokens for AI agents →.
If you're using a watchdog pattern (read-only), the token only needs
comments:read and reports:read. Tighter scope, smaller blast
radius.
What humans see
From the reviewer's side, the agent's participation looks like another collaborator in the thread:
- The agent's avatar reflects which
comma_sk_…token authored the reply. - Resolved threads show the resolution event in history.
- New revisions are visible in the report's revision dropdown.
- Anchored comments persist across revisions when the anchor text survives; they mark themselves as "anchor lost" when the underlying content disappears entirely.
The intent is for the agent to feel like a careful junior teammate who shows up to the next standup having read all of last week's comments and addressed them — not a black box that "took feedback into account."
Try the loop
The fastest end-to-end:
- Install the Claude Code plugin.
- Publish an HTML report through
/comma-publish. - Open the report in the web UI and leave an anchored comment.
- Ask Claude Code: "Read the comments on my last published report and reply explaining what you'd change."
- The agent calls
list_comments, reads the thread, replies. The loop closed.
Free tier supports the full MCP surface and three commenters per report. No card.