Skip to main content
Glama

Server Details

MCP server for visual regression testing: triage a PR's UI diffs from your coding agent.

If you are the author of this connector, you can claim ownership with GitHub, an HTTP challenge, or a DNS record. Claimed connector authors can inspect health checks, view analytics, and manage their listing.
Status
Healthy
Uptime
100.0% over 21 days
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL
Repository
uiverify/uiverify
GitHub Stars
18

TDQS

A4.6/5.0

Scored across 14 tools

Disambiguation5/5

Every tool targets a distinct resource and action: builds, diffs, PR changesets, comments, and review decisions all have clear ownership. The only near-overlap (accept_build vs review_diff) is explicitly distinguished as bulk vs single-story, and get_build vs get_pr_changeset are differentiated by comparison basis.

Naming Consistency5/5

All tool names follow a strict verb_noun snake_case pattern with consistent verbs: get_ for retrieval, list_ for paginated browsing, post_/update_/delete_/resolve_ for comment operations, and review_/accept_/render_ for actions. No naming convention mixing or stylistic drift.

Tool Count5/5

14 tools is well within the ideal range and each one earns its place: 3 build triage tools, 2 image/diff tools, 2 PR-changeset tools, and 5 comment tools cover distinct sub-workflows without redundancy. The count matches the complexity of a visual regression review system.

Completeness5/5

The tool surface fully covers the visual regression lifecycle: discovering builds, inspecting diffs, rendering pixels, reviewing/accepting/denying changes, and managing comment threads. No obvious dead ends exist—bulk accept, per-story review, pagination, and image fetching all have supporting tools, and the PR-vs-base changeset fills a subtle but important gap.

Available Tools

14 tools
accept_buildAccept every changed story in a buildAInspect

Accept ALL changed stories in one build at once (resolved by commitSha/prNumber/buildId), advancing each story's per-branch baseline so the next build is clean. This is the bulk form of review_diff='accept' — use it when you've decided the whole build's changes are intended. It accepts every changed story, including stories that already have a prior denied review; failed stories are unaffected. Returns the build triage after accepting (first page of changed stories, each now showing decision='accepted'; page the rest with list_build_stories if changedNextCursor is set). Refused, with nothing accepted, while any changed story has an unresolved review comment: the error names those stories; read them with list_comments, address each note, resolve_comment its thread, then accept again.

ParametersJSON Schema
NameRequiredDescriptionDefault
buildIdNoResolve this exact build id.
prNumberNoResolve the latest build for this PR number.
commitShaNoResolve the build for this git commit SHA.

Output Schema

ParametersJSON Schema
NameRequiredDescription
branchYes
countsYes
statusYes
buildIdYes
aiReviewYes
commentsYes
prNumberYes
commitShaYes
createdAtYes
gateStatusYes
failedStoriesYes
changedStoriesYes
failedNextCursorYes
autoAcceptChangesYes
changedNextCursorYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (mutating, non-idempotent, non-destructive), the description discloses key side effects: advancing each story's per-branch baseline, accepting stories with prior denied reviews, leaving failed stories unaffected, atomic refusal when unresolved comments exist, and the paginated return shape via changedNextCursor. This adds substantial behavioral context the annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every sentence earns its place: core action, side effect, sibling relationship, usage condition, exceptional cases, return behavior, and remediation workflow. It is front-loaded with the verb and resource, though the single dense paragraph could be lightly restructured to separate normal behavior from the refusal-recovery path.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists, annotations cover the mutation profile, and the description covers side effects, exceptions, pagination, and recovery steps, this is nearly complete. The one gap: with zero required parameters, the description never states that exactly one of commitSha/prNumber/buildId should be provided or what happens if multiple are passed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents each parameter ('Resolve this exact build id', 'Resolve the latest build for this PR number', 'Resolve the build for this git commit SHA'). The description only re-lists them as alternative resolvers without adding precedence or exclusivity rules, so the schema carries the weight and baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('accept') and resource ('ALL changed stories in one build'), and immediately names the sibling it relates to ('bulk form of review_diff="accept"'), so an agent can distinguish it from review_diff, list_build_stories, and get_pr_changeset without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells when to use it ('use it when you've decided the whole build's changes are intended') and names the alternative (review_diff='accept'), implying the per-story path for the opposite case. It also gives a concrete error-recovery workflow (list_comments → resolve_comment → accept again) for the refusal condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_commentDelete a commentA
Destructive
Inspect

Soft-delete a comment (get its id from list_comments). An agent key can delete only agent-authored comments, never a human's. Deleting a thread root removes its replies too. Requires the image comments feature.

ParametersJSON Schema
NameRequiredDescriptionDefault
commentIdYesThe comment id to delete (from list_comments).

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
deletedYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already say destructiveHint=true, but the description adds significant value by explaining the soft-delete behavior, cascade deletion of replies, the agent-key permission boundary, and the feature requirement. This goes well beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three tight sentences with no filler. Each sentence adds essential operational information: the action, id source, permission constraint, cascade behavior, and prerequisite feature.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter destructive operation with an output schema and annotations, this description is complete. It covers what the agent needs to know before calling: id origin, authorization limits, side effects on replies, and feature availability.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the commentId property already includes 'The comment id to delete (from list_comments).' The description repeats this id-source guidance but adds no new parameter-level information beyond what the schema provides, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Soft-delete a comment'. It also clarifies the agent-facing scope ('agent-authored comments') and cascade behavior, making it easy to distinguish from siblings like update_comment or resolve_comment.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: the id source is list_comments, only agent-authored comments can be deleted, and human comments are explicitly off-limits. It does not explicitly name alternative tools, but it gives enough when/when-not guidance for typical use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_buildGet what changed in a UI Verify buildA
Read-only
Inspect

Triage one build, resolved by commitSha, prNumber, or buildId (exactly one). Returns the gate verdict and counts (total/changed/failed/unchanged), then the FIRST page (25) of the changed stories (story id, viewport, % pixels changed, review decision, the AI verdict aiVerdict=intended|regression + aiConfidence, and for a regression the judge's one-line aiFlagReason=what-looks-unintended, when AI review is on, and the story's own review-comment tally comments {total, unresolved}) and the first page of failed stories (failedStories[].kind is render when the story produced no frame, or interaction when it rendered and its play() assertion threw; failedStories[].error is the message's first line, errorTruncated marks the ones that carried more). When AI review ran, aiReview tallies how many changes look like regressions vs intended, and the changed list is ordered likely-regressions-first. changedNextCursor / failedNextCursor are non-null when there are more than 25: page the rest with list_build_stories. counts.unchanged is how many stories did NOT change and have a baseline - this triage call does NOT list them (keeps the response lean); call list_build_stories status=unchanged to browse them (e.g. to confirm a passed build's stories are 'identical to baseline'). comments is the build-wide review-comment tally {total, unresolved}: unresolved>0 means a designer/QA (or another agent) left an open note on a story - read it with list_comments BEFORE you accept. No image URLs here - call get_diff or render_diff_image for pixels.

ParametersJSON Schema
NameRequiredDescriptionDefault
buildIdNoResolve this exact build id.
prNumberNoResolve the latest build for this PR number.
commitShaNoResolve the build for this git commit SHA.

Output Schema

ParametersJSON Schema
NameRequiredDescription
branchYes
countsYes
statusYes
buildIdYes
aiReviewYes
commentsYes
prNumberYes
commitShaYes
createdAtYes
gateStatusYes
failedStoriesYes
changedStoriesYes
failedNextCursorYes
autoAcceptChangesYes
changedNextCursorYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate readOnlyHint=true, and the description consistently describes a read operation, aligning with that. The description goes beyond annotations by detailing response structure, pagination cursors, ordering (likely-regressions-first), and that no image URLs are included—calling out get_diff or render_diff_image for pixels. This adds significant behavioral transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but information-dense, with every sentence adding necessary detail for an agent to understand the tool's behavior. It is front-loaded with the main purpose and return structure, but includes a lot of detail in one paragraph, which could be improved with more structured formatting, but given the complexity it remains efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is highly complete for the tool's complexity. It covers resolution methods, response format, pagination, ordering, exclusions, and guidance on related tools. With an output schema present, return values are documented elsewhere, and the description fills in all behavioral gaps, making it fully usable by an agent without additional research.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all three parameters are already documented. However, the description adds critical selection constraints: exactly one of buildId, prNumber, or commitSha must be provided. This is not explicit in the schema's individual descriptions but is essential for correct invocation, justifying a score above the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: triage one build resolved by one of three identifiers, returning gate verdict, counts, and first pages of changed and failed stories. It distinguishes itself from sibling tools like list_build_stories by explicitly noting pagination is handled elsewhere and that unchanged stories are not listed here.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear usage context: it explains that list_build_stories should be used for pagination and for browsing unchanged stories, and that list_comments should be read before acceptance when unresolved comments exist. It does not explicitly state when not to use this tool versus alternatives, but the context is strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_diffGet per-story diff detail with image URLsA
Read-only
Inspect

Per-story diff detail for a build (resolved by commitSha/prNumber/buildId). Returns diff metrics and presigned, time-limited URLs (download them to a file, or link them in a PR comment) for the baseline, candidate, and diff PNGs. Defaults to the changed stories; pass storyId for one specific story. When that storyId is an UNCHANGED story it returns its baseline (diffResultId null, changed false, the baseline URL as both baselineUrl and candidateUrl) - the story rendered identical to baseline. Use render_diff_image instead when you want the actual pixels inline for a vision model, not a URL. When AI review is on, each diff carries the judge's call: aiVerdict (intended|regression), aiConfidence, aiSummary (what changed), aiReasoning, and aiFlagReason; all null when AI review didn't run for it. Each diff also carries comments {total, unresolved} for THAT story - unresolved>0 means an open review note; read the thread with list_comments before accepting.

ParametersJSON Schema
NameRequiredDescriptionDefault
buildIdNoResolve this exact build id.
storyIdNoLimit to one story id.
prNumberNoResolve the latest build for this PR number.
commitShaNoResolve the build for this git commit SHA.

Output Schema

ParametersJSON Schema
NameRequiredDescription
diffsYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, the description reveals important behavior: the URLs are time-limited and intended for download/PR comments, an unchanged story returns baseline URLs and null diffResultId, AI-review fields are null when review did not run, and unresolved comment counts signal open review notes. None of this contradicts the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but information-dense, with each clause covering a distinct behavior: core returns, default selection, the unchanged-story edge case, the sibling alternative, AI fields, and comment semantics. It is front-loaded with the primary purpose and contains no filler or repeated schema text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only diff tool with an output schema and readOnlyHint annotation, the description covers all the behavior an agent needs to call it correctly: resolution options, story selection, unchanged-story handling, the alternative tool, AI-review payload details, and a related review workflow. The only minor omission is resolution-parameter precedence, which does not make the definition inadequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, and the description still adds real meaning for storyId by explaining the default-to-changed-stories behavior and the unchanged-story response. However, it does not specify precedence or mutual exclusivity among commitSha, prNumber, and buildId when more than one is provided, so the extra value is good but not complete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb-plus-resource statement ('Per-story diff detail for a build') and enumerates the exact returned artifacts: diff metrics and presigned, time-limited URLs for baseline, candidate, and diff PNGs. This clearly separates it from siblings such as render_diff_image, which is explicitly named.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says to use render_diff_image instead when inline pixels are needed for a vision model, and it gives a concrete selection rule for storyId: default to changed stories or pass a specific story. It also directs the agent to list_comments when unresolved comments are present, which is useful post-call guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_pr_changesetGet what this PR does to the UI vs its base branchA
Read-only
Inspect

The cumulative 'this PR vs base' visual changeset (resolved by commitSha/prNumber/buildId) - what the whole PR does to the UI versus the branch it merges into, INDEPENDENT of what is left to review on the latest build. Unlike get_build (this commit vs the branch's own accepted baseline), this survives in-PR accepts: a story accepted mid-PR still shows under changed with status=accepted, so it answers 'what did this PR change' even after the gate reads clean. Returns base (the branch it merges into), counts {new,changed,removed,unchanged}, and the first page of new + changed + removed stories (storyId, title, name, kind, review status, aiVerdict). removed lists stories that HAD a baseline on the base branch but are gone from this PR's head (a deletion - otherwise invisible; each carries lastBuildId, the build that rendered its now-orphaned baseline). newNextCursor / changedNextCursor / removedNextCursor page the rest with list_pr_stories. No image URLs - fetch pixels by storyId with get_diff / render_diff_image. Requires the PR visual changeset feature.

ParametersJSON Schema
NameRequiredDescriptionDefault
buildIdNoResolve this exact build id.
prNumberNoResolve the latest build for this PR number.
commitShaNoResolve the build for this git commit SHA.

Output Schema

ParametersJSON Schema
NameRequiredDescription
newYes
baseYes
countsYes
changedYes
removedYes
newNextCursorYes
changedNextCursorYes
removedNextCursorYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnlyHint=true; the description goes well beyond that by explaining the resolved-by semantics (commitSha/prNumber/buildId), the independent-of-review-state behavior, and especially the `removed` list which surfaces otherwise-invisible baseline deletions with lastBuildId context. It also notes the feature requirement and the absence of image URLs, both useful behavioral disclosures.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but information-dense: every clause earns its place, and the most decision-relevant contrast (vs get_build, survives in-PR accepts) is front-loaded. It trails into a multi-item return-value inventory, which makes it slightly heavy, but that inventory includes behavioral caveats (removed stories carry lastBuildId) rather than mere schema repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers what the tool answers, how it differs from its closest sibling, what the response contains including pagination cursors, and how to get pixels elsewhere. With an output schema present, return-value detail is appropriately summarized. For a read-only changeset query, this is complete at the right level of detail.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value by clarifying that resolution can come from any of the three identifiers and that the result is 'resolved by commitSha/prNumber/buildId', tying the parameters to the same concept. It doesn't explain precedence among them, but the schema already documents each field adequately.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise noun phrase and verb — 'cumulative this PR vs base visual changeset' — and immediately distinguishes it from get_build by the in-PR accept behavior. It names siblings and states exactly what it returns (base, counts, first page of stories, deleted stories with lastBuildId).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly contrasts with get_build ('unlike get_build...') and even explains the carve-out for mid-PR accepted stories, so an agent knows when to choose this tool over the alternative. It also tells the caller to page with list_pr_stories and fetch pixels with get_diff / render_diff_image, which are concrete routing instructions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_buildsList recent UI Verify buildsA
Read-only
Inspect

Recent UI Verify builds for your project, newest first. Each row is a one-line verdict (gateStatus: passed | changed | failed) for a commit/PR — use it to find the build to inspect. No image URLs or per-story detail here: call get_build for the changed-story list, get_diff for images.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax builds to return (default 20).
branchNoOnly builds on this git branch.
statusNoOnly builds with this raw status.

Output Schema

ParametersJSON Schema
NameRequiredDescription
buildsYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only, and the description adds useful behavioral context: results are newest-first rows containing only a gateStatus verdict, and the tool intentionally omits image URLs and per-story details. This goes beyond the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, all information-dense and front-loaded with the core purpose before limitations and alternatives. Every sentence earns its place, and there is no redundant restating of the schema or title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with an output schema present, the description covers what an agent needs: what the rows look like, how results are ordered, what is intentionally excluded, and which sibling tools to use for the excluded details. No critical call-time context is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema fully documents all three parameters (limit, branch, status) with descriptions and enumerations, so the schema carries the parameter-meaning burden. The description does not add additional parameter semantics beyond what the schema already provides, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb and resource ('List recent UI Verify builds'), specifies ordering ('newest first'), and defines the output scope ('one-line verdict'). It also differentiates itself from siblings by explicitly stating what it lacks ('no image URLs or per-story detail') and naming the alternatives for those details.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit usage direction: use this to find the build to inspect, then 'call get_build for the changed-story list, get_diff for images.' This directly routes the agent to the correct sibling tools and states the boundary of this tool's usefulness.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_build_storiesPage through a build's stories by statusA
Read-only
Inspect

Page through one build's stories filtered by status (resolved by commitSha/prNumber/buildId). Use it to read past get_build's first page, or to browse the unchanged/passed stories get_build only counts. status='changed' returns changed stories (same shape + order as get_build, regression-first, each with its comments {total, unresolved}; unresolved>0 means an open review note - read it with list_comments first); status='failed' returns failed stories; status='unchanged' returns the stories that did NOT change this build but have a baseline on this branch (storyId, viewport, browser) - fetch any of their images by storyId with get_diff or render_diff_image to confirm 'identical to baseline'. Returns { stories, nextCursor }: pass nextCursor back as cursor for the next page; null means no more. limit defaults to 25 (max 100). Unchanged is only available once the build has settled (an in-progress build has rendered nothing, so it returns an empty page).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoPage size (default 25, max 100).
cursorNoThe nextCursor from a prior page; omit for the first page.
statusYesWhich stories to page: changed, failed, or unchanged (baselined, didn't change this build).
buildIdNoResolve this exact build id.
prNumberNoResolve the latest build for this PR number.
commitShaNoResolve the build for this git commit SHA.

Output Schema

ParametersJSON Schema
NameRequiredDescription
storiesYes
nextCursorYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal readOnlyHint=true, and the description adds rich behavioral context: pagination via nextCursor/cursor, limit default and max, status-specific response shapes, the unresolved>0 review-note convention, and the caveat that unchanged stories only appear once the build has settled. No contradiction with annotations is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but densely packed with behaviorally important details; the core purpose is front-loaded before the status-specific explanations. Minor redundancy such as 'status='failed' returns failed stories' keeps it from a 5, but it remains efficient relative to the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, the description is complete: it covers the return shape, pagination contract, default and max page size, all three statuses, build resolution options, and the in-progress-build empty page behavior. The output schema exists, so additional return-value detail is not required.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description goes well beyond the schema: it explains the meaning of each status value, how cursor pagination works, how limit defaults and caps, and clarifies that buildId/prNumber/commitSha are alternative resolvers. This materially helps an agent set parameters correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Page through one build's stories filtered by status') and differentiates itself from get_build by noting it reads past the first page and covers statuses get_build only counts. The status values are each given concrete semantics, so an agent can select this tool without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to use it ('Use it to read past get_build's first page, or to browse the unchanged/passed stories get_build only counts') and points to sibling tools for follow-up actions: list_comments for open review notes, and get_diff or render_diff_image to fetch unchanged images. It also distinguishes between build resolution methods (commitSha/prNumber/buildId).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_commentsList the review comments on a build's diffsA
Read-only
Inspect

Every review comment on a build's changed stories (resolved by commitSha/prNumber/buildId), each carrying its diffResultId, author (human name or 'agent'), body, createdAt, and anchor - where on the candidate image it points: null (whole diff), {type:'point',x,y}, {type:'rect',x,y,w,h}, or {type:'path',points,closed}, all normalized 0..1 to the candidate image. Use it to read what a designer/QA (or another agent) flagged on a screenshot before acting. Requires the image comments feature.

ParametersJSON Schema
NameRequiredDescriptionDefault
buildIdNoResolve this exact build id.
prNumberNoResolve the latest build for this PR number.
commitShaNoResolve the build for this git commit SHA.

Output Schema

ParametersJSON Schema
NameRequiredDescription
commentsYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false. The description adds value beyond annotations by specifying the exact resolution criteria (commitSha/prNumber/buildId) and the exact fields each comment carries (diffResultId, author, body, createdAt, anchor). It also discloses the 'Requires the image comments feature' prerequisite and normalizes anchor values to 0..1, which is helpful. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single paragraph of moderate length. It front-loads the main purpose of listing comments and then provides detailed field information and the anchor format, which is useful. The 'Requires the image comments feature' line could be considered extra but it's a necessary caveat. It is structured logically, moving from purpose to data details to usage guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has 3 parameters (all optional but one presumably required), a rich output schema (though not detailed here, it's present), and no nested objects. The description covers the resolution criteria, the data fields returned, and the prerequisite feature. It does not need to explain the output schema because it exists. Given its complexity, it is complete for an agent to call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so each parameter (buildId, prNumber, commitSha) is already documented. The description adds the resolution logic (e.g., 'resolved by commitSha/prNumber/buildId') which clarifies that exactly one must be provided and that prNumber resolves the latest build. This adds modest value beyond the schema, so a 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists review comments on a build's diffs, with a precise verb ('list') and resource ('review comments on a build's diffs'). It distinguishes itself from siblings like review_diff (which creates comments) and get_diff (which likely fetches diff content) by focusing on comments. The mention of 'before acting' implies a specific role in the workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description says 'Use it to read what a designer/QA (or another agent) flagged on a screenshot before acting,' which provides clear context on when to use the tool. However, it does not explicitly state when not to use it or name alternative tools for other scenarios (e.g., if you need to create a comment, use review_diff). Sibling tool names provide clues, but the description itself lacks explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_pr_storiesPage through the PR-vs-base changeset by kindA
Read-only
Inspect

Page through the PR-vs-base changeset stories of one kind (resolved by commitSha/prNumber/buildId) - use it to read past get_pr_changeset's first page. kind='new' returns stories the PR adds that the base branch has no baseline for; kind='changed' returns stories whose image differs from the base branch's accepted image (even if accepted mid-PR, with status=accepted); kind='removed' returns stories that HAD a baseline on the base branch but are gone from head (a deletion; each carries lastBuildId, not a review status or verdict). Returns { stories, nextCursor }: pass nextCursor back as cursor for the next page; null means no more. limit defaults to 25 (max 100). Requires the PR visual changeset feature.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindYesWhich changeset stories to page: new (added), changed (vs base), or removed (deleted).
limitNoPage size (default 25, max 100).
cursorNoThe nextCursor from a prior page; omit for the first page.
buildIdNoResolve this exact build id.
prNumberNoResolve the latest build for this PR number.
commitShaNoResolve the build for this git commit SHA.

Output Schema

ParametersJSON Schema
NameRequiredDescription
storiesYes
nextCursorYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true and openWorldHint=false, and the description adds meaningful behavior: exact semantics of new/changed/removed, that removed stories carry lastBuildId rather than review status/verdict, the cursor round-trip contract, and the default/max limit. No statement contradicts the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is information-dense but every clause earns its place: pagination role, kind semantics, output shape, cursor handling, limit, and feature gate. It is front-loaded with the core action and routing hint before the detailed kind definitions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-parameter paging tool, the description plus the provided schema and output schema cover resolution modes, pagination state, return shape, defaults, and prerequisites. An agent has what it needs to call the tool correctly and continue paging.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description goes beyond the schema by defining what each kind means (e.g., 'even if accepted mid-PR, with status=accepted') and how cursor pagination works. It does not fully remove ambiguity about whether exactly one of commitSha/prNumber/buildId must be supplied, which keeps it from a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb ('Page through'), a precise resource ('PR-vs-base changeset stories'), and a kind selector, then immediately ties it to the sibling tool: 'read past get_pr_changeset's first page'. Each kind value gets a distinct semantic definition, so an agent can tell this apart from get_pr_changeset and list_build_stories without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly names get_pr_changeset as the tool whose first-page result this continues, giving the when-condition ('read past ... first page'). It also states the prerequisite ('Requires the PR visual changeset feature'), which prevents calls in unsupported contexts.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

post_commentComment on a build's diffAInspect

Leave a review comment on one of a build's changed-story diffs (resolve the build by commitSha/prNumber/buildId, target the diff by diffResultId from get_build/get_diff). The comment is authored as the agent. Optionally anchor it to a spot on the candidate image with anchor: omit or null for a whole-diff comment, {type:'point',x,y} to pin a point, {type:'rect',x,y,w,h} for a box, or {type:'path',points:[{x,y},...],closed} for a shape - all coordinates 0..1 normalized to the candidate image. side picks the pane ('after' the candidate, default; 'before' the baseline). Pass parentId (a root comment id from list_comments) to REPLY in that thread instead - a reply inherits the root's side and carries no anchor, so anchor/side are ignored. A new root comment is refused when a newer build exists on the branch (comment on the latest build); replies stay allowed. Requires the image comments feature.

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyYesThe comment text.
sideNoWhich pane: 'after' (candidate, default) or 'before' (baseline). Ignored on a reply.
anchorNoWhere on the candidate image to pin it (0..1 normalized): omit/null = whole diff; {type:'point',x,y}; {type:'rect',x,y,w,h}; {type:'path',points,closed}. Ignored on a reply.
buildIdNoResolve this exact build id.
parentIdNoReply to this thread ROOT comment's id (from list_comments) instead of starting a new thread.
prNumberNoResolve the latest build for this PR number.
commitShaNoResolve the build for this git commit SHA.
diffResultIdYesThe diff result to comment on (from get_build/get_diff).

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false, and openWorldHint=false, so the agent knows this is a non-read, non-idempotent mutation. The description adds valuable behavioral context beyond that: the comment is authored as the agent, a new root comment is refused when a newer build exists, replies inherit the root's side and carry no anchor, and the feature requires 'image comments.' It also explains that anchor/side are ignored on replies. This is rich behavioral disclosure that goes well beyond the annotations, though it doesn't explicitly state whether the operation is reversible or what the response contains (the output schema covers that).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized: it front-loads the core action and resolution method, then explains the optional anchor and side parameters, then the reply behavior, then the refusal condition, and finally the feature requirement. Every sentence earns its place, and the structure follows the natural decision flow an agent would use. It is longer than the calibration examples, but the complexity of the tool (8 params, nested anchor shapes, reply semantics) justifies the length. It could be slightly tighter, but it is not bloated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (8 parameters, three anchor shape variants, reply semantics, build resolution alternatives, and a refusal condition), the description is remarkably complete. It covers how to resolve the build, how to target the diff, how to anchor, how to reply, what gets ignored on a reply, when a comment is refused, and the feature requirement. The output schema exists, so return values need not be described. An agent has everything needed to call this tool correctly in the right situation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 8 parameters. The description adds meaning beyond the schema by explaining the resolution semantics (commitSha/prNumber/buildId as alternative ways to resolve the build), the anchor coordinate system (0..1 normalized to the candidate image), and the reply behavior (parentId from list_comments, reply inherits root's side, anchor/side ignored). This is more than the schema provides, though the schema already does a good job with its own descriptions. The description doesn't add much about body or diffResultId beyond what the schema says, but the added context on anchor, side, and parentId is substantial.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Leave a review comment on one of a build's changed-story diffs.' It immediately distinguishes the tool from siblings like list_comments, update_comment, and delete_comment by stating the creation action and the target (a diff). It also names the resolution methods (commitSha/prNumber/buildId) and the diff target (diffResultId), so an agent can tell exactly what this tool does without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: it says to resolve the build by commitSha/prNumber/buildId and target the diff by diffResultId from get_build/get_diff. It also explains when to use parentId to reply instead of starting a new thread, and it states a refusal condition: a new root comment is refused when a newer build exists on the branch, while replies stay allowed. This is clear routing guidance that distinguishes the tool from siblings like review_diff and list_comments.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

render_diff_imageFetch the actual pixels of a story imageA
Read-only
Inspect

Fetch a story's image as an INLINE image (base64 pixels, not a URL) so a vision model can look at it directly. Needs a native MCP client that renders image content; piped through raw curl it is useless (use get_diff's URLs there instead). Two ways to address it: (1) diffResultId + which for a CHANGED story - which is baseline|candidate|diff (the triptych) or before_after, the baseline and candidate SIDE BY SIDE (before on the left, after on the right) cropped to the changed region - and when a story changed in SEVERAL far-apart places, one such crop PER region stacked top to bottom, so a header-plus-footer change is two tight crops, not a page-tall image. before_after is usually what you want for a code change - it zooms to what moved instead of a full page. Get diffResultId from get_build (changedStories[].diffResultId) or get_diff. (2) a build selector (commitSha|prNumber|buildId) + storyId for ANY story's current image - the candidate if it changed this build, else its baseline. This second form is the only way to see an UNCHANGED/passed story's pixels (list them via list_build_stories status=unchanged), so you can confirm 'identical to baseline'. Errors if the image doesn't exist (a genuinely new story has no baseline, so no before_after either). When the story has unresolved review comments, a text note saying so comes with the image: read them with list_comments before you accept.

ParametersJSON Schema
NameRequiredDescriptionDefault
whichNoFor the diffResultId form: baseline|candidate|diff (one triptych image, default candidate), or before_after (baseline+candidate side by side, cropped to the change - one crop per changed region, stacked, when the change spans several places). Ignored for the storyId form.
buildIdNoResolve this exact build id.
storyIdNoWith a build selector: fetch THIS story's current image (works for unchanged stories).
prNumberNoResolve the latest build for this PR number.
commitShaNoResolve the build for this git commit SHA.
diffResultIdNoA CHANGED story's diff result id (from get_build/get_diff); pair with `which`.
pxPaginationNoPaginate a TALL image slice by slice instead of one unreadable image: return the `height` device px starting at y=`offset`, so a 5000px page is reviewed in readable slices. Omit for the whole image. Ignored for the before_after form (already cropped to the change).

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations establish readOnlyHint=true, and the description adds valuable behavioral context beyond that: the output requires a native MCP client, before_after returns cropped/side-by-side/stacked crops, unresolved comments trigger a text note, and missing baselines cause errors. No contradiction with readOnlyHint exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but organized into numbered addressing modes, a usage recommendation, an error caveat, and a comment-handling note. Nearly every sentence earns its place; it only misses a perfect score because the volume of detail makes it somewhat dense.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter tool with nested objects and no output schema, the description covers rendering environment, both invocation forms, return behavior (inline image plus optional text note), error conditions, and sibling-tool routing. An agent has enough context to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description adds meaning beyond the schema: it explains that diffResultId pairs with `which`, that before_after crops per changed region, that pxPagination is ignored for before_after, and that diffResultId comes from get_build or get_diff. This materially helps an agent choose and populate parameters correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description leads with a specific verb-resource pair: 'Fetch a story's image as an INLINE image (base64 pixels, not a URL)' and immediately differentiates it from get_diff by contrasting inline pixels vs. URLs. It also explains the two invocation forms, making the tool's purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: 'piped through raw curl it is useless (use get_diff's URLs there instead)' and 'before_after is usually what you want for a code change'. It also states the second form is 'the only way to see an UNCHANGED/passed story's pixels' and directs the agent to list_build_stories and list_comments.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolve_commentResolve or reopen a comment threadAInspect

Mark a comment thread resolved or reopen it (get the id from list_comments). Resolving stamps the thread ROOT, so pass a root comment's id - a reply id is a no-op. Any team writer may toggle this. Requires the image comments feature.

ParametersJSON Schema
NameRequiredDescriptionDefault
resolvedYestrue to resolve the thread, false to reopen it.
commentIdYesThe thread root comment id (from list_comments).

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
resolvedYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false, destructiveHint=false, and idempotentHint=false, indicating a mutating, non-idempotent operation. The description adds critical behavioral context: it explains the no-op behavior for reply ids and notes the 'image comments feature' requirement. It does not state the response format, but that is covered by the output schema, so this is strong.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each earning its place: the action, the critical id constraint, and the permission/feature precondition. Front-loaded with the core purpose, then the key caveat.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and annotations covering the safety profile, the description covers all necessary operational details: the id source, the no-op case, permissions, and feature requirement. Nothing essential is missing for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already explains both parameters: commentId as thread root and resolved as boolean. The description reinforces this by repeating the root-id requirement and the meaning of true/false, but it adds no new syntactic or type details beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Mark a comment thread resolved or reopen it.' It clearly describes the two possible actions and explicitly differentiates from siblings by noting that the id comes from list_comments and that resolving affects the root thread. This makes it distinguishable from update_comment and delete_comment.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance on when to use: it tells the agent to get the id from list_comments, warns that resolving stamps the thread ROOT so a reply id is a no-op, and mentions that any team writer may toggle this. It also implies when not to use (e.g., if you need to edit text, use update_comment) by specifying the exact action.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

review_diffAccept, deny, or ignore one story's changeAInspect

Record a review on a single diff result (get diffResultId from get_build/get_diff). 'accept' makes the candidate the new baseline for that story on its branch, so the next build is clean; 'deny' records the rejection without changing the baseline; 'ignore' excludes the story from the gate persistently (the snapshot keeps differing on future builds but no longer flags the check) — use it for an intentional, ongoing diff like an animation or a live timestamp. This is the same accept/deny/ignore as the dashboard, attributed to your project key. Use after you've inspected the diff (e.g. with render_diff_image) and decided intended vs. regression. accept and ignore are refused while the story has an unresolved review comment (read it with list_comments, address it, resolve_comment the thread, then retry); deny is always allowed.

ParametersJSON Schema
NameRequiredDescriptionDefault
decisionYes'accept' advances the baseline; 'deny' records a rejection; 'ignore' excludes the story from the gate.
diffResultIdYesThe diff result id from get_build or get_diff.

Output Schema

ParametersJSON Schema
NameRequiredDescription
decisionYes
diffResultIdYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description explains the full behavioral impact of each decision: accept advances the baseline and makes the next build clean; deny records rejection without changing baseline; ignore persistently excludes the story from the gate while the snapshot keeps differing. It also discloses the unresolved-comment refusal condition and project-key attribution, going well beyond the sparse annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place: core action, per-decision effects, workflow context, and a critical refusal condition. It is front-loaded with the action and scoping, with no filler or repetition of schema details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with two parameters and an output schema, the description covers the workflow, the meaning of each decision, the persistent behavior of ignore, the unresolved-comment constraint, and the source of the required ID. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema by explaining where diffResultId comes from ('from get_build/get_diff') and by giving the behavioral consequence of each decision enum value, which the schema only names.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Record a review on a single diff result', a specific verb and resource, and the title narrows it to 'one story's change'. It clearly distinguishes this from build-level tools like accept_build by emphasizing the per-story, per-diff scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance: 'Use after you've inspected the diff (e.g. with render_diff_image) and decided intended vs. regression.' It also states when-not: accept and ignore are refused while an unresolved review comment exists, while deny is always allowed. It does not explicitly name an alternative tool for the same decision, so it falls just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_commentEdit a comment's textAInspect

Replace the body of a comment (get its id from list_comments). An agent key can edit only agent-authored comments, never a human's. Requires the image comments feature.

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyYesThe new comment text.
commentIdYesThe comment id to edit (from list_comments).

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are sparse (readOnlyHint=false, destructiveHint=false), so the description carries most of the behavioral disclosure. It discloses the authorization rule (agent can edit only agent-authored comments) and the feature dependency (requires image comments feature), which goes beyond the schema and annotations. It doesn't state whether the edit is reversible or what the response contains, but the output schema exists to cover return values.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each carrying a distinct piece of information: the operation, the source of the id, and the permission/feature constraint. No filler or repetition of schema fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (2 params, 100% schema coverage, output schema exists). The description covers the core preconditions and permission rules. The only minor gap is that it doesn't explicitly say what succeeds — e.g., whether the full updated comment is returned — but the output schema covers return structure, so the description is adequately complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents both parameters (body and commentId). The description adds the provenance of commentId ('get its id from list_comments') and the constraint that only agent-authored comments can be edited, but it does not add detail beyond the schema's own parameter descriptions. Baseline 3 is appropriate because schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description states a specific verb and resource ('Replace the body of a comment'), distinguishes from siblings by scoping to agent-authored comments only and by noting the image comments feature. The sibling list includes post_comment, delete_comment, resolve_comment, so an agent can clearly tell this edits existing comment text.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to use this tool (editing a comment already fetched via list_comments) and when not to (cannot edit a human's comment; only agent-authored). The preconditions — permission/feature requirement — are stated upfront, and it differentiates itself from alternatives like delete_comment and post_comment.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updates
    • Changedaccept_build2 fields changed
      • addedOutput schema / properties / changedStories / items / properties / comments
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "total": {
        +      "$ref": "#/properties/comments/properties/total"
        +    },
        +    "unresolved": {
        +      "$ref": "#/properties/comments/properties/unresolved"
        +    }
        +  },
        +  "required": [
        +    "total",
        +    "unresolved"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / properties / changedStories / items / required
        Previous value: -[
        -  "diffResultId",
        -  "storyId",
        -  "title",
        -  "name",
        -  "viewport",
        -  "browser",
        -  "changedPct",
        -  "decision",
        -  "isNew",
        -  "unstable",
        -  "aiVerdict",
        -  "aiClassification",
        -  "aiIntroducedBy",
        -  "aiConfidence",
        -  "aiSummary",
        -  "aiFlagReason"
        -]New value: +[
        +  "diffResultId",
        +  "storyId",
        +  "title",
        +  "name",
        +  "viewport",
        +  "browser",
        +  "changedPct",
        +  "decision",
        +  "isNew",
        +  "unstable",
        +  "aiVerdict",
        +  "aiClassification",
        +  "aiIntroducedBy",
        +  "aiConfidence",
        +  "aiSummary",
        +  "aiFlagReason",
        +  "comments"
        +]
    • Changedget_build2 fields changed
      • addedOutput schema / properties / changedStories / items / properties / comments
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "total": {
        +      "$ref": "#/properties/comments/properties/total"
        +    },
        +    "unresolved": {
        +      "$ref": "#/properties/comments/properties/unresolved"
        +    }
        +  },
        +  "required": [
        +    "total",
        +    "unresolved"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / properties / changedStories / items / required
        Previous value: -[
        -  "diffResultId",
        -  "storyId",
        -  "title",
        -  "name",
        -  "viewport",
        -  "browser",
        -  "changedPct",
        -  "decision",
        -  "isNew",
        -  "unstable",
        -  "aiVerdict",
        -  "aiClassification",
        -  "aiIntroducedBy",
        -  "aiConfidence",
        -  "aiSummary",
        -  "aiFlagReason"
        -]New value: +[
        +  "diffResultId",
        +  "storyId",
        +  "title",
        +  "name",
        +  "viewport",
        +  "browser",
        +  "changedPct",
        +  "decision",
        +  "isNew",
        +  "unstable",
        +  "aiVerdict",
        +  "aiClassification",
        +  "aiIntroducedBy",
        +  "aiConfidence",
        +  "aiSummary",
        +  "aiFlagReason",
        +  "comments"
        +]
    • Changedlist_build_stories1 field changed
      • changedOutput schema / properties / stories / items / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "aiClassification": {
        -        "type": [
        -          "string",
        -          "null"
        -        ]
        -      },
        -      "aiConfidence": {
        -        "type": [
        -          "string",
        -          "null"
        -        ]
        -      },
        -      "aiFlagReason": {
        -        "type": [
        -          "string",
        -          "null"
        -        ]
        -      },
        -      "aiIntroducedBy": {
        -        "type": [
        -          "string",
        -          "null"
        -        ]
        -      },
        -      "aiSummary": {
        -        "type": [
        -          "string",
        -          "null"
        -        ]
        -      },
        -      "aiVerdict": {
        -        "type": [
        -          "string",
        -          "null"
        -        ]
        -      },
        -      "browser": {
        -        "type": "string"
        -      },
        -      "changedPct": {
        -        "type": [
        -          "number",
        -          "null"
        -        ]
        -      },
        -      "decision": {
        -        "type": [
        -          "string",
        -          "null"
        -        ]
        -      },
        -      "diffResultId": {
        -        "format": "uuid",
        -        "type": "string"
        -      },
        -      "isNew": {
        -        "type": "boolean"
        -      },
        -      "name": {
        -        "type": "string"
        -      },
        -      "storyId": {
        -        "type": "string"
        -      },
        -      "title": {
        -        "type": "string"
        -      },
        -      "unstable": {
        -        "type": "boolean"
        -      },
        -      "viewport": {
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "diffResultId",
        -      "storyId",
        -      "title",
        -      "name",
        -      "viewport",
        -      "browser",
        -      "changedPct",
        -      "decision",
        -      "isNew",
        -      "unstable",
        -      "aiVerdict",
        -      "aiClassification",
        -      "aiIntroducedBy",
        -      "aiConfidence",
        -      "aiSummary",
        -      "aiFlagReason"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "browser": {
        -        "type": "string"
        -      },
        -      "error": {
        -        "type": "string"
        -      },
        -      "errorTruncated": {
        -        "type": "boolean"
        -      },
        -      "kind": {
        -        "enum": [
        -          "render",
        -          "interaction"
        -        ],
        -        "type": "string"
        -      },
        -      "name": {
        -        "type": "string"
        -      },
        -      "storyId": {
        -        "type": "string"
        -      },
        -      "title": {
        -        "type": "string"
        -      },
        -      "viewport": {
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "storyId",
        -      "title",
        -      "name",
        -      "viewport",
        -      "browser",
        -      "error",
        -      "errorTruncated",
        -      "kind"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "browser": {
        -        "type": "string"
        -      },
        -      "storyId": {
        -        "type": "string"
        -      },
        -      "viewport": {
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "storyId",
        -      "viewport",
        -      "browser"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "aiClassification": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "aiConfidence": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "aiFlagReason": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "aiIntroducedBy": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "aiSummary": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "aiVerdict": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "browser": {
        +        "type": "string"
        +      },
        +      "changedPct": {
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      },
        +      "comments": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "total": {
        +            "type": "number"
        +          },
        +          "unresolved": {
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "total",
        +          "unresolved"
        +        ],
        +        "type": "object"
        +      },
        +      "decision": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "diffResultId": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "isNew": {
        +        "type": "boolean"
        +      },
        +      "name": {
        +        "type": "string"
        +      },
        +      "storyId": {
        +        "type": "string"
        +      },
        +      "title": {
        +        "type": "string"
        +      },
        +      "unstable": {
        +        "type": "boolean"
        +      },
        +      "viewport": {
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "diffResultId",
        +      "storyId",
        +      "title",
        +      "name",
        +      "viewport",
        +      "browser",
        +      "changedPct",
        +      "decision",
        +      "isNew",
        +      "unstable",
        +      "aiVerdict",
        +      "aiClassification",
        +      "aiIntroducedBy",
        +      "aiConfidence",
        +      "aiSummary",
        +      "aiFlagReason",
        +      "comments"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "browser": {
        +        "type": "string"
        +      },
        +      "error": {
        +        "type": "string"
        +      },
        +      "errorTruncated": {
        +        "type": "boolean"
        +      },
        +      "kind": {
        +        "enum": [
        +          "render",
        +          "interaction"
        +        ],
        +        "type": "string"
        +      },
        +      "name": {
        +        "type": "string"
        +      },
        +      "storyId": {
        +        "type": "string"
        +      },
        +      "title": {
        +        "type": "string"
        +      },
        +      "viewport": {
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "storyId",
        +      "title",
        +      "name",
        +      "viewport",
        +      "browser",
        +      "error",
        +      "errorTruncated",
        +      "kind"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "browser": {
        +        "type": "string"
        +      },
        +      "storyId": {
        +        "type": "string"
        +      },
        +      "viewport": {
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "storyId",
        +      "viewport",
        +      "browser"
        +    ],
        +    "type": "object"
        +  }
        +]
  2. 1 tool update
    • Changedrender_diff_image1 field changed
      • addedInput schema / properties / pxPagination
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Paginate a TALL image slice by slice instead of one unreadable image: return the `height` device px starting at y=`offset`, so a 5000px page is reviewed in readable slices. Omit for the whole image. Ignored for the before_after form (already cropped to the change).",
        +  "properties": {
        +    "height": {
        +      "default": 500,
        +      "description": "Slice height in device px (default 500).",
        +      "exclusiveMinimum": 0,
        +      "type": "integer"
        +    },
        +    "offset": {
        +      "description": "Top y (device px) of the slice to return.",
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "offset"
        +  ],
        +  "type": "object"
        +}
  3. 3 tool updates
    • Changedaccept_build2 fields changed
      • addedOutput schema / properties / comments
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "total": {
        +      "type": "number"
        +    },
        +    "unresolved": {
        +      "type": "number"
        +    }
        +  },
        +  "required": [
        +    "total",
        +    "unresolved"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "buildId",
        -  "commitSha",
        -  "branch",
        -  "prNumber",
        -  "status",
        -  "gateStatus",
        -  "autoAcceptChanges",
        -  "createdAt",
        -  "counts",
        -  "aiReview",
        -  "changedStories",
        -  "changedNextCursor",
        -  "failedStories",
        -  "failedNextCursor"
        -]New value: +[
        +  "buildId",
        +  "commitSha",
        +  "branch",
        +  "prNumber",
        +  "status",
        +  "gateStatus",
        +  "autoAcceptChanges",
        +  "createdAt",
        +  "counts",
        +  "comments",
        +  "aiReview",
        +  "changedStories",
        +  "changedNextCursor",
        +  "failedStories",
        +  "failedNextCursor"
        +]
    • Changedget_build2 fields changed
      • addedOutput schema / properties / comments
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "total": {
        +      "type": "number"
        +    },
        +    "unresolved": {
        +      "type": "number"
        +    }
        +  },
        +  "required": [
        +    "total",
        +    "unresolved"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "buildId",
        -  "commitSha",
        -  "branch",
        -  "prNumber",
        -  "status",
        -  "gateStatus",
        -  "autoAcceptChanges",
        -  "createdAt",
        -  "counts",
        -  "aiReview",
        -  "changedStories",
        -  "changedNextCursor",
        -  "failedStories",
        -  "failedNextCursor"
        -]New value: +[
        +  "buildId",
        +  "commitSha",
        +  "branch",
        +  "prNumber",
        +  "status",
        +  "gateStatus",
        +  "autoAcceptChanges",
        +  "createdAt",
        +  "counts",
        +  "comments",
        +  "aiReview",
        +  "changedStories",
        +  "changedNextCursor",
        +  "failedStories",
        +  "failedNextCursor"
        +]
    • Changedget_diff2 fields changed
      • addedOutput schema / properties / diffs / items / properties / comments
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "total": {
        +      "type": "number"
        +    },
        +    "unresolved": {
        +      "type": "number"
        +    }
        +  },
        +  "required": [
        +    "total",
        +    "unresolved"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / properties / diffs / items / required
        Previous value: -[
        -  "diffResultId",
        -  "storyId",
        -  "viewport",
        -  "browser",
        -  "changed",
        -  "decision",
        -  "metrics",
        -  "baselineUrl",
        -  "candidateUrl",
        -  "diffUrl",
        -  "aiSummary",
        -  "aiVerdict",
        -  "aiConfidence",
        -  "aiReasoning",
        -  "aiFlagReason"
        -]New value: +[
        +  "diffResultId",
        +  "storyId",
        +  "viewport",
        +  "browser",
        +  "changed",
        +  "decision",
        +  "metrics",
        +  "baselineUrl",
        +  "candidateUrl",
        +  "diffUrl",
        +  "aiSummary",
        +  "aiVerdict",
        +  "aiConfidence",
        +  "aiReasoning",
        +  "aiFlagReason",
        +  "comments"
        +]
  4. 4 tool updates
    • Addeddelete_comment
    • Addedpost_comment
    • Addedresolve_comment
    • Addedupdate_comment
  5. 1 tool update
    • Addedlist_comments
  6. 1 tool update
    • Removedget_change_attribution
  7. 1 tool update
    • Changedget_change_attribution3 fields changed
      • addedOutput schema / properties / stories / items / properties / approxReason
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "no-graph",
        +        "global-change",
        +        "too-large",
        +        "github-error",
        +        "unexplained"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ]
        +}
      • addedOutput schema / properties / stories / items / properties / narrowed
        Added value: +{
        +  "type": "boolean"
        +}
      • changedOutput schema / properties / stories / items / required
        Previous value: -[
        -  "storyId",
        -  "base",
        -  "truncated",
        -  "partial",
        -  "refs"
        -]New value: +[
        +  "storyId",
        +  "base",
        +  "truncated",
        +  "partial",
        +  "narrowed",
        +  "approxReason",
        +  "refs"
        +]
  8. 1 tool update
    • Addedget_change_attribution
  9. 9 tool updates
    • First observedaccept_build
    • First observedget_build
    • First observedget_diff
    • First observedget_pr_changeset
    • First observedlist_build_stories
    • First observedlist_builds
    • First observedlist_pr_stories
    • First observedrender_diff_image
    • First observedreview_diff

Related MCP Connectors

Related MCP Servers

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.