Skip to main content
Glama

Server Details

UI Verify is visual regression testing built for coding agents. Connect the MCP server and your agent (Claude Code, Cursor, Codex) pulls a pull request's UI changes into the conversation, views each visual diff, reads the AI judge's verdict of regression vs intended change, and accepts the intended baselines - all over MCP.

Ownership verified
Status
Healthy
Last Tested
Transport
Streamable HTTP
URL

Available Tools

9 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).

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
prNumberYes
commitShaYes
createdAtYes
gateStatusYes
failedStoriesYes
changedStoriesYes
failedNextCursorYes
autoAcceptChangesYes
changedNextCursorYes

TDQS

A4.6/5.0
Behavior5/5

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

Annotations are minimal (readOnlyHint=false, destructiveHint=false), so the description carries the behavioral burden and does so well. It discloses real side effects: advancing each story's per-branch baseline, making the next build clean, accepting previously denied stories, leaving failed stories unaffected, and returning a paginated triage result with a cursor for further pages.

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 contributes: it names the operation, gives the use condition, describes exceptions, and specifies the return/pagination behavior. The main action is front-loaded and there is no filler or redundant restatement of the title.

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?

For a mutating bulk operation, the description covers scope, side effects, edge cases, return shape, and pagination routing to list_build_stories. The main gap is the missing explicit constraint that at least one of buildId/prNumber/commitSha must be supplied, and whether they are mutually exclusive. This is material enough to prevent a perfect score, but the rest of the context is strong.

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 buildId, prNumber, and commitSha adequately. The description merely restates that resolution happens via these three fields and adds no new parameter-level detail. A notable unresolved point is that it never states whether exactly one resolver must be provided or what happens if multiple are supplied.

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 a specific verb ('accept'), a specific resource ('changed stories in a build'), and the bulk scope ('ALL changed stories in one build at once'). It also explicitly positions itself as the bulk form of review_diff='accept', which distinguishes it from sibling tools like review_diff and list_build_stories.

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 an explicit selection condition: 'use it when you've decided the whole build's changes are intended.' It also names the relevant alternative (review_diff='accept') for the non-bulk case, and clarifies edge cases such as prior denied reviews and unaffected failed stories.

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 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'). 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
prNumberYes
commitShaYes
createdAtYes
gateStatusYes
failedStoriesYes
changedStoriesYes
failedNextCursorYes
autoAcceptChangesYes
changedNextCursorYes

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only mark the call read-only, so the description carries the behavioral burden and fully delivers: first-page truncation at 25, changed and failed story semantics, AI verdict fields, ordering by likely regressions first, non-null cursor behavior, and explicit omission of unchanged stories. 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 long and dense, but every block of detail earns its place: pagination, excluded unchanged stories, image routing, and output-field semantics all affect correct invocation. The main structural flaw is that much of this is packed into run-on sentences with heavy parentheticals.

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 definition covers the triage scope, response pagination, omitted data, related-tool handoffs, and failure-mode distinctions, while an output schema handles the raw return shape. Nothing an agent needs to decide whether and how to call get_build 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 description coverage is 100%, so the baseline is 3; the description adds genuine value by asserting the exactly-one constraint among the otherwise all-optional parameters and by clarifying that prNumber/commitSha resolve to a build. It does not add per-parameter details beyond that, hence 4 rather than 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 'Triage one build' and specifies the exact resource (a UI Verify build) and resolution keys (commitSha, prNumber, or buildId, exactly one), then enumerates the return contents. This clearly distinguishes get_build from siblings like list_builds and list_build_stories, which handle collections or paging.

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 routes follow-up actions: page beyond 25 with list_build_stories, browse unchanged stories with list_build_stories status=unchanged, and fetch images from get_diff or render_diff_image. It also states why unchanged stories are omitted, so an agent can decide when this tool is the right entry point.

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.

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.8/5.0
Behavior5/5

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

Beyond the readOnlyHint and openWorldHint annotations, the description discloses time-limited URLs, the unchanged-story edge case (diffResultId null, changed false, baseline URL repeated), and AI review fields being null when not run. This is substantial behavioral context that helps the agent understand responses.

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 each sentence adds value: purpose, URL behavior, defaults, unchanged story behavior, alternative tool, and AI review output. It is front-loaded with the core purpose. Slightly long, but justified by the number of edge cases and output 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?

Given the output schema exists and covers the return shape, the description does not need to restate return values. It covers the main behaviors, edge cases, parameter roles, and alternative routing. For a read-only diff retrieval tool with multiple resolution options, this is complete enough for an agent to call it correctly.

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%, but the description adds semantic meaning: it explains how the three resolution identifiers (commitSha/prNumber/buildId) select a build, and what happens when a storyId corresponds to an unchanged story. It does not specify precedence if multiple identifiers are passed, but this is a minor gap.

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 a specific action and resource: returns per-story diff detail for a build resolved by commitSha/prNumber/buildId, including diff metrics and presigned URLs for baseline, candidate, and diff PNGs. It also distinguishes itself from render_diff_image by noting when that sibling is preferred.

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 describes when to use the tool: defaults to changed stories, pass storyId for a specific story, and contains an explicit exclusion: 'Use render_diff_image instead when you want the actual pixels inline for a vision model, not a URL.' This gives clear selection 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 say only readOnlyHint=true and openWorldHint=false; the description adds non-obvious behavior such as accepted stories remaining under changed with status=accepted, the meaning of removed stories with lastBuildId, and the absence of image URLs. It also discloses the feature requirement, all beyond what annotations provide.

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?

Dense but purposeful: every sentence adds a distinct fact, including scope, sibling contrast, return fields, removed semantics, pagination, no image URLs, and the feature gate. It is front-loaded with the core definition and contrast, though it could be easier to scan with a short bulleted structure.

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 complex filtered-list tool with an output schema, the description is complete: it states resolution modes, response contents, pagination behavior, the meaning of removed stories, and what the tool does not return. It also names the sibling tools for follow-up actions, leaving no major operational gap.

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?

The input schema already describes all three resolution parameters at 100% coverage, so the baseline is 3. The description adds the useful framing that the changeset is resolved by commitSha/prNumber/buildId and treats them as alternative resolution modes, which helps an agent understand the intended selection pattern.

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 title and description center on a specific verb+resource: it retrieves the cumulative PR-vs-base visual changeset. It sharply distinguishes itself from get_build by defining scope (whole PR vs branch it merges into) and semantics (survives in-PR accepts), so an agent can tell exactly what the tool returns.

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_build as the alternative and explains the difference: this tool answers what the PR changed versus what's left to review on the latest build. It also routes pagination to list_pr_stories and image fetching to get_diff/render_diff_image, giving clear when-to-use guidance.

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.4/5.0
Behavior4/5

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

With no annotations provided, the description carries the behavioral burden. It discloses ordering, the gateStatus values, that each row is a one-line summary, and what is intentionally not included. It does not cover every edge case like pagination or empty results, but it addresses the key behavioral expectations.

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 compact and front-loaded with the core purpose and ordering. Every sentence adds value: purpose, row shape, use case, and exclusion with alternative routing. There is no redundant wording.

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 no output schema and no annotations, the description adequately explains what the rows look like, what they do not contain, and where to go for more detail. It omits minor procedural details like response metadata or pagination semantics, but an agent can correctly select and call this tool from the provided information.

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 already provides descriptions for limit, branch, and status, so the description does not need to repeat them. It adds a little context by mentioning gateStatus and commit/PR focus, but parameter meaning is largely covered by the schema itself.

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 states a specific verb and resource: list recent UI Verify builds, newest first. It also defines the row shape as a one-line verdict per commit/PR, and explicitly distinguishes itself from deeper-detail tools by saying 'No image URLs or per-story detail here'.

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 explicitly says the tool is for finding the build to inspect, and gives direct routing guidance: call get_build for the changed-story list and get_diff for images. This clearly tells an agent when to use this tool versus alternatives.

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); 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 declare readOnlyHint=true, and the description is fully consistent with that read-only profile. It adds rich behavior beyond the annotations: per-status return semantics (changed = regression-first, same shape/order as get_build), the cursor contract (pass nextCursor back as the cursor; null terminates), the limit default/max (25/100), and the edge case that unchanged returns an empty page for in-progress builds.

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?

At roughly 120 words, the description follows a strict logical order: purpose, when-to-use, per-status semantics, pagination mechanics, defaults, then the in-progress edge case. Every clause carries operational value and nothing restates the title or schema.

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 pagination tool with three behaviorally distinct status modes, this description covers cursor flow, defaults, the build-settling prerequisite, and cross-tool follow-up. Since an output schema exists and annotations cover safety, nothing an agent needs to call it correctly is left to guesswork.

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 rubric baseline is 3; the description earns a 4 by adding relational meaning not in the schema: the three resolver params are presented as equivalent ways to select the build, and the status values are explained behaviorally (regression-first ordering, 'did NOT change this build but have a baseline' for unchanged).

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 states a specific verb ('Page through'), a bounded resource ('one build's stories'), and the filtering dimension ('by status'), while naming the resolution mechanism (commitSha/prNumber/buildId). It also distinguishes itself from the closest sibling by explicitly referencing get_build's first-page limitation.

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 explicitly frames when to choose this tool: use it to read past get_build's first page, or to browse the unchanged/passed stories get_build only counts. It also routes follow-up image confirmation to get_diff or render_diff_image, giving the agent a complete decision path.

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 mark the tool readOnly, and the description adds rich behavioral detail: kind-specific semantics, the accepted-mid-PR nuance, removed stories carrying lastBuildId instead of a verdict, cursor termination with null, and pagination limits. There is no contradiction with the readOnlyHint.

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 front-loaded with purpose and usage, and every sentence earns its place by adding meaningful detail. The kind definitions are dense but necessary because they distinguish subtle behaviors, and there is no filler or 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?

For a tool with six parameters, an output schema, and readOnly annotations, the description covers pagination, cursor handling, limits, resolver modes, kind semantics, and a feature requirement. Nothing an agent needs to invoke 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 description coverage is 100%, so the baseline is 3. The description goes further by explaining exactly what each kind means, how nextCursor should be passed back, and how resolution via commitSha/prNumber/buildId works. It does not explicitly state whether the resolver parameters are mutually exclusive, but the schema already documents each parameter clearly.

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 action and resource: 'Page through the PR-vs-base changeset stories of one kind' and immediately names the resolver inputs. It also explicitly distinguishes the tool from get_pr_changeset by saying it is used to read past its first page, so an agent can tell them apart.

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 gives explicit guidance on when to use this tool: 'use it to read past get_pr_changeset's first page.' It also defines the three kind values and notes the feature prerequisite, giving an agent enough context to select the correct mode and avoid misuse.

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).

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`.

TDQS

A5/5.0
Behavior5/5

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

Beyond the readOnlyHint annotation, the description discloses important behavioral traits: the output is inline base64 pixels requiring a native MCP client, images are cropped to changed regions with per-region stacking, and the tool errors when the image does not exist (e.g., a genuinely new story has no baseline). This is substantial behavioral context that the annotations alone do not provide.

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 densely packed with necessary information: purpose, client requirement, alternative routing, two addressing modes, crop behavior, and error conditions. It is front-loaded with the core purpose, then builds outward, and every sentence serves a distinct guidance function.

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 there is no output schema, the description compensates by explaining the output form (inline base64 pixels), layout behavior (side-by-side crops, stacking), error cases, and how to obtain diffResultId from get_build/get_diff. The tool is complex with two alternative invocation forms, and the description covers both completely.

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?

Even though schema coverage is 100%, the description adds valuable cross-parameter meaning: it explains that diffResultId pairs with which, that buildId/prNumber/commitSha act as build selectors, and that storyId works even for unchanged stories. It also clarifies the nuanced semantics of before_after (side-by-side crops stacked per changed region), which the enum alone does not convey.

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: 'Fetch a story's image as an INLINE image (base64 pixels, not a URL)' and clearly distinguishes this from get_diff by stating that get_diff's URLs should be used in a curl pipeline. It also names two concrete addressing forms, leaving no ambiguity about what the tool does.

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 explains when to use this tool versus alternatives: 'piped through raw curl it is useless (use get_diff's URLs there)' and defines which addressing form to use for changed versus unchanged stories. It even recommends before_after for code changes and points to list_build_stories for unchanged stories, giving actionable routing guidance.

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.

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.8/5.0
Behavior5/5

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

The description explains the persistent side effects of each option: accepting advances the baseline, denying records a rejection without changing baseline, and ignoring permanently excludes the story from the gate while the snapshot continues to differ. It also notes attribution to the project key and the impact on the next build, going well beyond the minimal 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 dense but every sentence contributes essential decision-making information. It is front-loaded with the action and source of diffResultId, and the decision semantics are clearly separated. Slightly long, but the length is justified by the three distinct behaviors that must be explained.

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 presence of an output schema, the two-parameter input schema, and the rich descriptions, the description covers prerequisites, decision semantics, persistence, and attribution. An agent has enough context to call this tool correctly and understand the consequences of each choice.

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 meaningful semantics on top by explaining how to get diffResultId ('from get_build/get_diff') and by detailing the downstream effects of each decision value, which helps the agent choose the correct enum value in context.

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 states a specific action ('Record a review') on a concrete resource ('a single diff result') and enumerates the three decision semantics. It clearly distinguishes itself from inspection and retrieval siblings like render_diff_image and get_diff by focusing on the post-inspection review action.

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 explicitly says to use this after inspecting the diff (e.g., with render_diff_image) and after deciding whether the change is intended or a regression. It also clarifies that 'ignore' is for intentional, ongoing diffs, giving concrete when-to-use guidance that routes the agent correctly.

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. Dates show when Glama detected each change.

  1. 8 tool updates
    • Changedaccept_build1 field changed
      • changedOutput schema / (root)
        Before
        null
        After
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "additionalProperties": false,
          "properties": {
            "aiReview": {
              "anyOf": [
                {
                  "additionalProperties": false,
                  "properties": {
                    "intended": {
                      "type": "number"
                    },
                    "regressions": {
                      "type": "number"
                    },
                    "reviewed": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "regressions",
                    "intended",
                    "reviewed"
                  ],
                  "type": "object"
                },
                {
                  "type": "null"
                }
              ]
            },
            "autoAcceptChanges": {
              "type": "boolean"
            },
            "branch": {
              "type": "string"
            },
            "buildId": {
              "format": "uuid",
              "type": "string"
            },
            "changedNextCursor": {
              "type": [
                "string",
                "null"
              ]
            },
            "changedStories": {
              "items": {
                "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"
              },
              "type": "array"
            },
            "commitSha": {
              "type": "string"
            },
            "counts": {
              "additionalProperties": false,
              "properties": {
                "changed": {
                  "type": "number"
                },
                "failed": {
                  "type": "number"
                },
                "total": {
                  "type": "number"
                },
                "unchanged": {
                  "type": "number"
                }
              },
              "required": [
                "total",
                "changed",
                "failed",
                "unchanged"
              ],
              "type": "object"
            },
            "createdAt": {
              "type": "string"
            },
            "failedNextCursor": {
              "type": [
                "string",
                "null"
              ]
            },
            "failedStories": {
              "items": {
                "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"
              },
              "type": "array"
            },
            "gateStatus": {
              "type": "string"
            },
            "prNumber": {
              "type": [
                "number",
                "null"
              ]
            },
            "status": {
              "type": "string"
            }
          },
          "required": [
            "buildId",
            "commitSha",
            "branch",
            "prNumber",
            "status",
            "gateStatus",
            "autoAcceptChanges",
            "createdAt",
            "counts",
            "aiReview",
            "changedStories",
            "changedNextCursor",
            "failedStories",
            "failedNextCursor"
          ],
          "type": "object"
        }
    • Changedget_build1 field changed
      • changedOutput schema / (root)
        Before
        null
        After
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "additionalProperties": false,
          "properties": {
            "aiReview": {
              "anyOf": [
                {
                  "additionalProperties": false,
                  "properties": {
                    "intended": {
                      "type": "number"
                    },
                    "regressions": {
                      "type": "number"
                    },
                    "reviewed": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "regressions",
                    "intended",
                    "reviewed"
                  ],
                  "type": "object"
                },
                {
                  "type": "null"
                }
              ]
            },
            "autoAcceptChanges": {
              "type": "boolean"
            },
            "branch": {
              "type": "string"
            },
            "buildId": {
              "format": "uuid",
              "type": "string"
            },
            "changedNextCursor": {
              "type": [
                "string",
                "null"
              ]
            },
            "changedStories": {
              "items": {
                "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"
              },
              "type": "array"
            },
            "commitSha": {
              "type": "string"
            },
            "counts": {
              "additionalProperties": false,
              "properties": {
                "changed": {
                  "type": "number"
                },
                "failed": {
                  "type": "number"
                },
                "total": {
                  "type": "number"
                },
                "unchanged": {
                  "type": "number"
                }
              },
              "required": [
                "total",
                "changed",
                "failed",
                "unchanged"
              ],
              "type": "object"
            },
            "createdAt": {
              "type": "string"
            },
            "failedNextCursor": {
              "type": [
                "string",
                "null"
              ]
            },
            "failedStories": {
              "items": {
                "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"
              },
              "type": "array"
            },
            "gateStatus": {
              "type": "string"
            },
            "prNumber": {
              "type": [
                "number",
                "null"
              ]
            },
            "status": {
              "type": "string"
            }
          },
          "required": [
            "buildId",
            "commitSha",
            "branch",
            "prNumber",
            "status",
            "gateStatus",
            "autoAcceptChanges",
            "createdAt",
            "counts",
            "aiReview",
            "changedStories",
            "changedNextCursor",
            "failedStories",
            "failedNextCursor"
          ],
          "type": "object"
        }
    • Changedget_diff1 field changed
      • changedOutput schema / (root)
        Before
        null
        After
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "additionalProperties": false,
          "properties": {
            "diffs": {
              "items": {
                "additionalProperties": false,
                "properties": {
                  "aiConfidence": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "aiFlagReason": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "aiReasoning": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "aiSummary": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "aiVerdict": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "baselineUrl": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "browser": {
                    "type": "string"
                  },
                  "candidateUrl": {
                    "type": "string"
                  },
                  "changed": {
                    "type": "boolean"
                  },
                  "decision": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "diffResultId": {
                    "anyOf": [
                      {
                        "format": "uuid",
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "diffUrl": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "metrics": {
                    "additionalProperties": false,
                    "properties": {
                      "bbox": {
                        "anyOf": [
                          {
                            "additionalProperties": false,
                            "properties": {
                              "height": {
                                "type": "number"
                              },
                              "width": {
                                "type": "number"
                              },
                              "x": {
                                "type": "number"
                              },
                              "y": {
                                "type": "number"
                              }
                            },
                            "required": [
                              "x",
                              "y",
                              "width",
                              "height"
                            ],
                            "type": "object"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "changedPct": {
                        "type": "number"
                      },
                      "changedPx": {
                        "type": "number"
                      },
                      "changedPxAdjusted": {
                        "type": "number"
                      },
                      "flakinessPx": {
                        "type": "number"
                      },
                      "flakinessScore": {
                        "type": "number"
                      },
                      "hadBaseline": {
                        "type": "boolean"
                      },
                      "height": {
                        "type": "number"
                      },
                      "sizeChanged": {
                        "type": "boolean"
                      },
                      "threshold": {
                        "type": "number"
                      },
                      "width": {
                        "type": "number"
                      }
                    },
                    "type": "object"
                  },
                  "storyId": {
                    "type": "string"
                  },
                  "viewport": {
                    "type": "string"
                  }
                },
                "required": [
                  "diffResultId",
                  "storyId",
                  "viewport",
                  "browser",
                  "changed",
                  "decision",
                  "metrics",
                  "baselineUrl",
                  "candidateUrl",
                  "diffUrl",
                  "aiSummary",
                  "aiVerdict",
                  "aiConfidence",
                  "aiReasoning",
                  "aiFlagReason"
                ],
                "type": "object"
              },
              "type": "array"
            }
          },
          "required": [
            "diffs"
          ],
          "type": "object"
        }
    • Changedget_pr_changeset1 field changed
      • changedOutput schema / (root)
        Before
        null
        After
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "additionalProperties": false,
          "properties": {
            "base": {
              "type": "string"
            },
            "changed": {
              "items": {
                "$ref": "#/properties/new/items"
              },
              "type": "array"
            },
            "changedNextCursor": {
              "type": [
                "string",
                "null"
              ]
            },
            "counts": {
              "additionalProperties": false,
              "properties": {
                "changed": {
                  "type": "number"
                },
                "new": {
                  "type": "number"
                },
                "removed": {
                  "type": "number"
                },
                "unchanged": {
                  "type": "number"
                }
              },
              "required": [
                "new",
                "changed",
                "removed",
                "unchanged"
              ],
              "type": "object"
            },
            "new": {
              "items": {
                "additionalProperties": false,
                "properties": {
                  "aiConfidence": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "aiVerdict": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "browsers": {
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "kind": {
                    "enum": [
                      "new",
                      "changed"
                    ],
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "status": {
                    "enum": [
                      "accepted",
                      "denied",
                      "ignored",
                      "pending"
                    ],
                    "type": "string"
                  },
                  "storyId": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "unstable": {
                    "type": "boolean"
                  },
                  "viewports": {
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  }
                },
                "required": [
                  "storyId",
                  "title",
                  "name",
                  "kind",
                  "status",
                  "browsers",
                  "viewports",
                  "aiVerdict",
                  "aiConfidence",
                  "unstable"
                ],
                "type": "object"
              },
              "type": "array"
            },
            "newNextCursor": {
              "type": [
                "string",
                "null"
              ]
            },
            "removed": {
              "items": {
                "additionalProperties": false,
                "properties": {
                  "browsers": {
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "lastBuildId": {
                    "format": "uuid",
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "storyId": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "viewports": {
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  }
                },
                "required": [
                  "storyId",
                  "title",
                  "name",
                  "lastBuildId",
                  "browsers",
                  "viewports"
                ],
                "type": "object"
              },
              "type": "array"
            },
            "removedNextCursor": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          "required": [
            "base",
            "counts",
            "new",
            "newNextCursor",
            "changed",
            "changedNextCursor",
            "removed",
            "removedNextCursor"
          ],
          "type": "object"
        }
    • Changedlist_build_stories1 field changed
      • changedOutput schema / (root)
        Before
        null
        After
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "additionalProperties": false,
          "properties": {
            "nextCursor": {
              "type": [
                "string",
                "null"
              ]
            },
            "stories": {
              "items": {
                "anyOf": [
                  {
                    "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"
                  }
                ]
              },
              "type": "array"
            }
          },
          "required": [
            "stories",
            "nextCursor"
          ],
          "type": "object"
        }
    • Changedlist_builds1 field changed
      • changedOutput schema / (root)
        Before
        null
        After
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "additionalProperties": false,
          "properties": {
            "builds": {
              "items": {
                "additionalProperties": false,
                "properties": {
                  "autoAcceptChanges": {
                    "type": "boolean"
                  },
                  "branch": {
                    "type": "string"
                  },
                  "buildId": {
                    "format": "uuid",
                    "type": "string"
                  },
                  "commitSha": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "string"
                  },
                  "gateStatus": {
                    "type": "string"
                  },
                  "prNumber": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "status": {
                    "type": "string"
                  }
                },
                "required": [
                  "buildId",
                  "commitSha",
                  "branch",
                  "prNumber",
                  "status",
                  "gateStatus",
                  "autoAcceptChanges",
                  "createdAt"
                ],
                "type": "object"
              },
              "type": "array"
            }
          },
          "required": [
            "builds"
          ],
          "type": "object"
        }
    • Changedlist_pr_stories1 field changed
      • changedOutput schema / (root)
        Before
        null
        After
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "additionalProperties": false,
          "properties": {
            "nextCursor": {
              "type": [
                "string",
                "null"
              ]
            },
            "stories": {
              "items": {
                "anyOf": [
                  {
                    "additionalProperties": false,
                    "properties": {
                      "aiConfidence": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "aiVerdict": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "browsers": {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "kind": {
                        "enum": [
                          "new",
                          "changed"
                        ],
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "status": {
                        "enum": [
                          "accepted",
                          "denied",
                          "ignored",
                          "pending"
                        ],
                        "type": "string"
                      },
                      "storyId": {
                        "type": "string"
                      },
                      "title": {
                        "type": "string"
                      },
                      "unstable": {
                        "type": "boolean"
                      },
                      "viewports": {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      }
                    },
                    "required": [
                      "storyId",
                      "title",
                      "name",
                      "kind",
                      "status",
                      "browsers",
                      "viewports",
                      "aiVerdict",
                      "aiConfidence",
                      "unstable"
                    ],
                    "type": "object"
                  },
                  {
                    "additionalProperties": false,
                    "properties": {
                      "browsers": {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "lastBuildId": {
                        "format": "uuid",
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "storyId": {
                        "type": "string"
                      },
                      "title": {
                        "type": "string"
                      },
                      "viewports": {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      }
                    },
                    "required": [
                      "storyId",
                      "title",
                      "name",
                      "lastBuildId",
                      "browsers",
                      "viewports"
                    ],
                    "type": "object"
                  }
                ]
              },
              "type": "array"
            }
          },
          "required": [
            "stories",
            "nextCursor"
          ],
          "type": "object"
        }
    • Changedreview_diff1 field changed
      • changedOutput schema / (root)
        Before
        null
        After
        {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "additionalProperties": false,
          "properties": {
            "decision": {
              "enum": [
                "accepted",
                "denied",
                "ignored"
              ],
              "type": "string"
            },
            "diffResultId": {
              "format": "uuid",
              "type": "string"
            }
          },
          "required": [
            "diffResultId",
            "decision"
          ],
          "type": "object"
        }
  2. 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

Frequently Asked Questions

Discussions

No comments yet. Be the first to start the discussion!

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables detection and analysis of pre-public product launches through web search, content extraction, AI-powered scoring, and automated alerting. Provides comprehensive tools for surfacing stealth startup signals before they trend publicly.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Browse IndustryLens's published competitive-intelligence reports and head-to-head competitor comparisons from any AI agent — real, source-backed data.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI chat clients to perform market research and competitive intelligence by gathering company overviews, competitor lists, product portfolios, pricing snapshots, and recent news via live Tavily search.
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

TDQS

A4.7/5.0
Disambiguation5/5

Each tool targets a distinct concern: list vs get vs pagination, build triage vs PR changeset, diff URL vs inline pixels, single-review vs bulk-accept. The descriptions explicitly call out the differences between similar-sounding tools, so an agent can reliably choose the right one.

Naming Consistency5/5

All tool names follow a consistent lowercase verb_noun pattern: get_* for single entities, list_* for collections, and review_diff/accept_build for actions. There are no mixed conventions or vague verbs.

Tool Count5/5

Nine tools fit the visual regression review workflow well: discovery, triage, pagination, image inspection, and reviewing. Each tool fills a distinct role without redundancy, and the count is in the sweet spot for an agent to keep all tool purposes in context.

Completeness5/5

The surface covers the full review lifecycle: find builds, triage changed/failed/unchanged stories, paginate, inspect diffs as URLs or inline images, review per-diff, and bulk-accept an entire build. The PR-changeset tools also cover cross-PR questions and deletion cases that would otherwise be dead ends.

Resources