Documentation Menu

Agentic Workflows (MCP)

RegressionBot supports the Model Context Protocol (MCP). Expose visual testing tools directly to your AI agents (Claude Code, OpenAI Codex, Gemini CLI, Windsurf, and Cursor) via our remote Streamable HTTP MCP server. This allows your agents to autonomously trigger visual regression jobs. They can also check job status and approve baselines. No local installation is required.

šŸ”‘ Prerequisite: API Key RequiredA valid API key is required to connect your agent to the remote MCP server.
Get API Key →

Install

Configure your MCP client to connect to RegressionBot via Streamable HTTP using https://mcp.regressionbot.com/ and either the standard Authorization: Bearer <token> header or the legacy x-api-key header.

Claude Code

Agentic IDEs and CLIs (such as Anthropic's Claude Code, OpenAI Codex, Cursor, Windsurf, and Gemini CLI) natively support Streamable HTTP transports and header configuration via command line, config files, or visual settings. RegressionBot's MCP endpoint is Streamable HTTP: configure the remote URL directly and authenticate with the Authorization: Bearer YOUR_API_KEY header. Do not configure it as a legacy SSE server.

Terminal
claude mcp add --transport http regressionbot https://mcp.regressionbot.com/ --header "Authorization: Bearer YOUR_API_KEY"

OpenAI Codex

Codex supports Streamable HTTP MCP servers in both the CLI and IDE extension. Both clients share the same MCP configuration, so you only need to configure RegressionBot once. The RegressionBot server does not use a legacy SSE endpoint event.

Add the following to ~/.codex/config.toml. The bearer_token_env_var entry tells Codex to pass the token as a Bearer token read from your environment (recommended for authorization status to show green).

~/.codex/config.toml
[mcp_servers.regressionbot]
url = "https://mcp.regressionbot.com/"
bearer_token_env_var = "REGRESSIONBOT_API_KEY"

Make sure to export the environment variable containing your API key in your shell configuration or current terminal:

export REGRESSIONBOT_API_KEY="sk_live_..."

Note that the configuration parameter bearer_token_env_var expects the name of the environment variable itself ("REGRESSIONBOT_API_KEY"), not the literal API key.

Alternatively, if you are using legacy headers, you can configure it via env_http_headers:

~/.codex/config.toml (Legacy Headers)
[mcp_servers.regressionbot]
url = "https://mcp.regressionbot.com/"
env_http_headers = { "x-api-key" = "REGRESSIONBOT_API_KEY" }

Alternatively, register the server via the Codex CLI and it will write the [mcp_servers.regressionbot] entry for you. You still need to add bearer_token_env_var manually afterwards as the CLI does not accept header/bearer flags.

Terminal (optional)
export REGRESSIONBOT_API_KEY="YOUR_API_KEY"
codex mcp add regressionbot --url https://mcp.regressionbot.com/
# then manually add bearer_token_env_var to ~/.codex/config.toml

In the Codex terminal UI, run /mcp to verify the server is active. In the Codex IDE extension, open MCP settings from the gear menu after editing config.toml to verify that RegressionBot is listed.

Cursor

Configure remote servers directly through Cursor's graphical interface to keep your API keys encrypted.

  1. Open Cursor Settings and navigate to Features > MCP Servers.
  2. Click + Add New MCP Server.
  3. Fill out the configuration:
    • Name: regressionbot
    • Type: http
    • URL: https://mcp.regressionbot.com/
  4. Add a header row:
    • Using Bearer Auth (recommended): set key to Authorization and value to Bearer YOUR_API_KEY.
    • Or using Custom Header (legacy): set key to x-api-key and value to your API key.
  5. Click Save and verify the green status indicator.

Windsurf

Windsurf handles remote Streamable HTTP MCPs using a structured JSON file. Add the following to your ~/.codeium/windsurf/mcp_config.json:

mcp_config.json
{
  "mcpServers": {
    "regressionbot": {
      "serverUrl": "https://mcp.regressionbot.com/",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

Gemini CLI

Gemini CLI supports direct Streamable HTTP transport. You can configure it via the command line or a settings file. We recommend using Bearer token authentication:

Option 1: Command Line
gemini mcp add --transport http regressionbot https://mcp.regressionbot.com/ --header "Authorization: Bearer YOUR_API_KEY"
Option 2: settings.json
{
  "mcpServers": {
    "regressionbot": {
      "httpUrl": "https://mcp.regressionbot.com/",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

Agent Examples

These examples show a real session with an MCP-enabled agentic IDE or CLI. The agent connects to the RegressionBot MCP server. It handles polling, result interpretation, and image analysis automatically.

Legend: USER> is what the user types, AGENT> is the assistant response, TOOL> is an MCP tool call, and TOOL RESULT> is raw tool output.

Compare a preview URL against production baselines

Agentic IDE — terminal session
USER> start a visual regression job for https://staging.myapp.com against stored baselines

AGENT> I'll trigger a visual regression job using the RegressionBot MCP.

TOOL> [run_regression_job]
  testOrigin: "https://staging.myapp.com"
  project:    "myapp"
  devices:    ["Desktop Chrome", "iPhone 12"]

TOOL RESULT> {
    "message": "Job started",
    "jobId": "6ee84bac-40de-44cc-8dca-4760ab108153"
  }

TOOL> [get_job_status] jobId: "6ee84bac-40de-44cc-8dca-4760ab108153"

TOOL RESULT> {
    "jobId": "6ee84bac-40de-44cc-8dca-4760ab108153",
    "status": "PROCESSING",
    "isComplete": false,
    "progress": { "total": 6, "completed": 3, "percent": "50.00" }
  }

TOOL> [get_job_status] jobId: "6ee84bac-40de-44cc-8dca-4760ab108153"

TOOL RESULT> {
    "jobId": "6ee84bac-40de-44cc-8dca-4760ab108153",
    "status": "SUMMARIZING",
    "isComplete": false,
    "progress": { "total": 6, "completed": 6, "percent": "100.00" }
  }

TOOL> [get_job_status] jobId: "6ee84bac-40de-44cc-8dca-4760ab108153"

TOOL RESULT> {
    "jobId": "6ee84bac-40de-44cc-8dca-4760ab108153",
    "status": "COMPLETED",
    "isComplete": true,
    "progress": { "total": 6, "completed": 6, "percent": "100.00" },
    "executionTime": 48
  }

TOOL> [get_job_summary] jobId: "6ee84bac-40de-44cc-8dca-4760ab108153", regressionsOnly: true

TOOL RESULT> {
    "regressionCount": 2,
    "matchCount": 4,
    "newBaselineCount": 0,
    "regressions": [
      {
        "url": "https://staging.myapp.com/pricing",
        "variantName": "Desktop Chrome",
        "status": "SUCCESS",
        "diffPercentage": 3.638671875,
        "score": 96.361328125,
        "isNewBaseline": false,
        "regressionbotSummary": [
          {"label":"A","text":"In the Pro tier card, a border highlight was added and the CTA button colour changed from grey to blue."}
        ],
        "diffUrl": "https://screenshots.regressionbot.com/r/token"
      },
      {
        "url": "https://staging.myapp.com/pricing",
        "variantName": "iPhone 12",
        "status": "SUCCESS",
        "diffPercentage": 3.638671875,
        "score": 96.361328125,
        "isNewBaseline": false,
        "regressionbotSummary": [
          {"label":"A","text":"In the Pro tier card, same border highlight and button colour change as desktop; font sizes unchanged."}
        ],
        "diffUrl": "https://screenshots.regressionbot.com/r/token"
      }
    ]
  }

AGENT> The job completed in 48 seconds. I found 2 regressions:

• /pricing [Desktop Chrome] — 420 pixels changed
  "The Pro tier card is now highlighted with a border and the CTA button
   colour shifted from grey to blue."

• /pricing [iPhone 12] — 380 pixels changed
  "Same pricing regression on iPhone 12 — card highlight and button colour visible."

AGENT> The other 4 pages matched their baselines exactly.
AGENT> Would you like me to fetch the regression images and review them before approving?

Inspect a regression image and approve

Agentic IDE — terminal session (continued)
USER> yes, look at the pricing regression and tell me if the changes look intentional

AGENT> [fetching diffUrl for /pricing Desktop Chrome via HTTP GET...]
AGENT> I can see the 3-panel comparison — BEFORE | AFTER | ANNOTATED DIFF.
AGENT> The regressions are clearly intentional:
- The Pro plan card now has a visible border and background highlight
- The "Get started" button changed from grey to blue
- No layout shifts, broken text, or clipped elements

AGENT> This looks like a deliberate design update. Safe to approve.

USER> approve it

TOOL> [approve_job] jobId: "6ee84bac-40de-44cc-8dca-4760ab108153"

TOOL RESULT> {
    "message": "Job approved",
    "approvedCount": 2,
    "failedCount": 0
  }

AGENT> Done. The 2 updated screenshots have been promoted to new baselines.
AGENT> Future jobs will compare against the new design.

Provide PR intent for automated visual approval

Agentic CI Workflow
USER> Check the UI for regressions. The PR updates the header background to blue.

AGENT> I'll run the regression job and pass the developer's intent via runContext so the AI can automatically classify the change.

TOOL> [run_regression_job]
  project:    "myapp"
  runContext: { "prDescription": "The PR updates the header background to blue." }

TOOL RESULT> { "message": "Job started", "jobId": "a1b2c3d4-..." }

AGENT> [polling get_job_status...]
AGENT> The job is COMPLETED. I'll get the final AI verdict.

TOOL> [get_verdict] jobId: "a1b2c3d4-..."

TOOL RESULT> {
    "intentAssessment": {
      "allAccountedFor": true,
      "unaccountedRegressions": []
    }
  }

AGENT> The AI verdict confirmed that all detected visual regressions align perfectly with your stated intent ("header background to blue"). No unexpected bugs were found. I will proceed to approve the build!

Run multiple jobs in parallel across devices

Agentic IDE — terminal session
USER> test the PR preview against baselines on desktop, mobile, and tablet

AGENT> I'll start 3 parallel jobs — one per device — then poll all of them.

TOOL> [run_regression_job] project: "myapp", devices: ["Desktop Chrome"]
TOOL RESULT> { "jobId": "31c66aa4-5bd7-4df1-a8e3-1394d77a33f9" }

TOOL> [run_regression_job] project: "myapp", devices: ["iPhone 12"]
TOOL RESULT> { "jobId": "1a597938-b08e-4417-9802-cbb457870c96" }

TOOL> [run_regression_job] project: "myapp", devices: ["tablet"]
TOOL RESULT> { "jobId": "d5452cb0-6b7a-4186-a0b1-0e23204a31e3" }

TOOL> [get_job_status] jobId: "31c66aa4-5bd7-4df1-a8e3-1394d77a33f9"
TOOL RESULT> { "status": "PROCESSING", "isComplete": false, "progress": { "total": 3, "completed": 1, "percent": "33.33" } }
TOOL> [get_job_status] jobId: "1a597938-b08e-4417-9802-cbb457870c96"
TOOL RESULT> { "status": "PROCESSING", "isComplete": false, "progress": { "total": 3, "completed": 2, "percent": "66.67" } }
TOOL> [get_job_status] jobId: "d5452cb0-6b7a-4186-a0b1-0e23204a31e3"
TOOL RESULT> { "status": "PROCESSING", "isComplete": false, "progress": { "total": 3, "completed": 0, "percent": "0.00" } }
...
TOOL> [get_job_status] jobId: "31c66aa4-5bd7-4df1-a8e3-1394d77a33f9"
TOOL RESULT> { "status": "COMPLETED", "isComplete": true, "progress": { "total": 3, "completed": 3, "percent": "100.00" } }
TOOL> [get_job_status] jobId: "1a597938-b08e-4417-9802-cbb457870c96"
TOOL RESULT> { "status": "COMPLETED", "isComplete": true, "progress": { "total": 3, "completed": 3, "percent": "100.00" } }
TOOL> [get_job_status] jobId: "d5452cb0-6b7a-4186-a0b1-0e23204a31e3"
TOOL RESULT> { "status": "COMPLETED", "isComplete": true, "progress": { "total": 3, "completed": 3, "percent": "100.00" } }

TOOL> [get_job_summary] jobId: "31c66aa4-5bd7-4df1-a8e3-1394d77a33f9", regressionsOnly: true
TOOL RESULT> {
    "regressionCount": 1,
    "regressions": [{ "url": "https://staging.myapp.com/about", "variantName": "Desktop Chrome", "diffCount": 180, "regressionbotSummary": "Hero section padding increased, CTA button widened." }]
  }
TOOL> [get_job_summary] jobId: "1a597938-b08e-4417-9802-cbb457870c96", regressionsOnly: true
TOOL RESULT> {
    "regressionCount": 1,
    "regressions": [{ "url": "https://staging.myapp.com/about", "variantName": "iPhone 12", "diffCount": 120, "regressionbotSummary": "Same layout regression on iPhone 12 — consistent with desktop update." }]
  }
TOOL> [get_job_summary] jobId: "d5452cb0-6b7a-4186-a0b1-0e23204a31e3", regressionsOnly: true
TOOL RESULT> { "regressionCount": 0, "regressions": [] }

AGENT> Results across all devices:

• /about  [Desktop Chrome]  — 180 pixels changed
  "Hero section padding increased, CTA button widened."

• /about  [iPhone 12]          — 120 pixels changed
  "Same visual regression on iPhone 12 — consistent with desktop update."

AGENT> • All tablet pages matched baselines.

Recover a previous job by listing recent jobs

Agentic IDE — terminal session
USER> what was the result of the last job for the myapp project?

TOOL> [list_jobs] project: "myapp", limit: 10

TOOL RESULT> {
    "jobs": [
      {
        "jobId": "6ee84bac-40de-44cc-8dca-4760ab108153",
        "project": "myapp",
        "status": "APPROVED",
        "totalUrls": 6,
        "completedCount": 6,
        "createdAt": "2026-05-19T10:53:26.000Z",
        "finishedAt": "2026-05-19T10:54:14.000Z"
      },
      {
        "jobId": "e69062bb-f140-40e7-a3e8-40f84deadcdb",
        "project": "myapp",
        "status": "COMPLETED",
        "totalUrls": 6,
        "completedCount": 6,
        "createdAt": "2026-05-17T13:22:01.000Z",
        "finishedAt": "2026-05-17T13:22:06.000Z"
      }
    ]
  }

AGENT> Most recent: job 6ee84bac — APPROVED, 6 pages tested, finished ~1 hour ago.
AGENT> The job before that is COMPLETED but not yet approved (2 regressions pending).

Tip: The agent can fetch and visually inspect regression images directly. Use the shortened, clickable diffUrl in the results. Each regression is a 3-panel image containing BEFORE | AFTER | ANNOTATED DIFF. The regression pixels are highlighted in red. Yellow bounding boxes are drawn around clusters of regressions. The AI uses this same image to generate regressionbotSummary.

Projects

A project is a named configuration. It locks in your job parameters, such as testOrigin, devices, and paths. The first run_regression_job invocation with a new project name creates the configuration automatically. Subsequent jobs enforce that the parameters match. This protects baseline integrity.

How it works

  • Initial job — supply all parameters. RegressionBot creates the project configuration and captures baselines.
  • Repeat jobs — omit parameters or supply identical ones to reuse the stored configuration. If you pass parameters that differ from the stored configuration, the job is rejected. The error response lists the differing fields.
  • Shorthand — use run_from_project to trigger a repeat job without supplying any parameters.
  • Update configuration — use update_project to update a saved project's configuration. This resets its baselines. Example: update_project({ name: "my-project", testOrigin: "https://v2.example.com" })
  • Approve by name — use approve_project to approve the most recent completed job for a project. This does not require a job ID. Example: approve_project({ name: "my-project" })
  • Live-vs-live jobs — these are always accepted regardless of the stored configuration. Passing baseOrigin skips the configuration check entirely.

Managed CI workflow example

Agentic IDE — terminal session
USER> start a regression job for myapp

AGENT> I'll create the project on the initial job and capture baselines.

TOOL> [run_regression_job]
  project:    "myapp"
  testOrigin: "https://www.myapp.com"
  devices:    ["Desktop Chrome", "iPhone 12"]
  paths:      [{"path":"/"}, {"path":"/pricing"}, {"path":"/docs"}]
  autoApprove: true

TOOL RESULT> { "message": "Job started", "jobId": "a1b2c3d4-..." }

AGENT> Baselines are being captured for 3 pages on desktop and mobile.
AGENT> The configuration is now saved as project "myapp". Future jobs are locked to these parameters.

---

USER> start a regression job for myapp

TOOL> [run_from_project] name: "myapp"

TOOL RESULT> { "message": "Job started", "jobId": "e5f6a7b8-...", "project": "myapp" }

AGENT> Job started using stored config — testOrigin myapp.com, Desktop Chrome + iPhone 12, 3 paths.

---

USER> what projects do I have?

TOOL> [list_projects]

TOOL RESULT> {
  "projects": [
    {
      "name": "myapp",
      "testOrigin": "https://www.myapp.com",
      "devices": ["Desktop Chrome", "iPhone 12"],
      "lastRunAt": "2026-06-02T10:15:00.000Z",
      "lastJobId": "e5f6a7b8-..."
    }
  ]
}

Available Tools

Once connected, your agent has access to the following tools. The MCP server provides instructions automatically. This helps your agent understand the workflow without any additional prompting.

ToolWhat it does
run_regression_jobStart a visual regression job. Accepts explicit paths, a sitemapUrl to crawl, or glob scans to filter a sitemap. Supports multiple devices, element masks, an optional baseOrigin for live-vs-live mode comparisons, and an optional runContext object containing developer intent (e.g. prDescription, gitCommitMessage) to inform the AI verdict.
get_job_statusPoll progress. Returns status, summaryStatus, progress (total / completed / percent), executionTime, and an isComplete flag so your agent knows when to stop polling. Status lifecycle: INITIALIZING → PROCESSING → SUMMARIZING → COMPLETED. Once status is complete, you can download images and view regression metrics immediately. You must wait for summaryStatus === 'COMPLETE' to fetch AI summaries.
get_job_summaryGet full results once the job is complete. Returns summaryStatus alongside results. If the status is 'COMPLETE', regressions include the AI-written regressionbotSummary and verdict fields, and the job includes the top-level intentAssessment for CI gating. Each regression also includes diffPercentage, visualMatchScore, and shortened screenshot redirect URLs. Pass regressionsOnly: true to filter out matching pages.
get_verdictFetch only the top-level AI intentAssessment for a completed job. This explicitly indicates if all visual regressions can be safely explained by the provided runContext. Highly recommended for automated CI agent approval steps instead of fetching the entire job summary.
list_jobsList recent jobs ordered by most recent first. Filter by project or set a limit. Useful for recovering a jobId or checking the status of recent jobs without leaving the agent session.
approve_jobPromote current screenshots to baselines. This accepts all visual regressions as intentional. This is permanent. Existing baselines are overwritten. Only call after reviewing regressions in get_job_summary.
run_from_projectRun a job using a saved project config. No need to re-supply testOrigin, devices, or paths. Ideal for repeat CI jobs once a project is established. Accepts optional autoApprove.
get_projectRetrieve the stored configuration for a named project. Returns testOrigin, devices, paths, scans, and job metadata.
list_projectsList all saved project configs for your organization. Returns name, testOrigin, devices, and last job info for each project.
update_projectUpdate a saved project's configuration and reset its baselines. Pass any subset of testOrigin, devices, paths, masks, etc. Triggers baseline invalidation. The next job will re-baseline everything.
approve_projectApprove the most recent completed job for a project, promoting its screenshots to baselines. No job ID required. Ideal for CI workflows where the approval step is executed separately from the regression job check.