keepcalculator

06 Numbers and Powers

Visual Testing in AI Coding with MCP: How-To

Card No. 06·52165 · Updated · Standard formula, shown below

This guide shows you how to add visual testing to your AI-assisted coding workflow using the Model Context Protocol (MCP). By the end, you’ll have an AI coding assistant that can capture screenshots, compare them against expected designs, and flag visual regressions automatically—all within your existing editor or CLI. You’ll need a basic understanding of MCP servers and clients, plus a project where visual checks matter.

What You’ll Need

  • An MCP-compatible AI coding tool (e.g., Claude Desktop, Cursor, or a custom MCP client)
  • Node.js (v18 or later) and npm installed
  • A code repository with a web frontend (React, Vue, plain HTML, etc.)
  • Playwright or Puppeteer installed in your project (we’ll use Playwright)
  • Basic familiarity with JavaScript and terminal commands

Step-by-Step

  1. Set up a new MCP server project

    Create a new directory for your visual testing MCP server. Run npm init -y to generate a package.json, then install the MCP SDK and Playwright:

    npm install @modelcontextprotocol/sdk playwright
    npx playwright install chromium
    

    This gives you the tools to create an MCP server that can launch a browser.

  2. Define the server’s tools and resources

    Create an index.js file. Import the MCP SDK and set up a server instance. You’ll expose a tool called capture_screenshot that takes a URL and an optional viewport size. Also expose a compare_screenshots tool that takes two image paths and returns a similarity score. Use Playwright to capture the screenshot and a pixel-diff library (like pixelmatch) for comparison.

  3. Implement the screenshot capture logic

    Inside the tool handler, launch a headless browser with Playwright, navigate to the given URL, wait for the page to load, and take a screenshot. Save it to a temporary file and return the file path. Make sure to handle dynamic content by waiting for network idle or specific selectors.

    async function captureScreenshot(url, viewport) {
      const browser = await chromium.launch();
      const page = await browser.newPage({ viewport });
      await page.goto(url, { waitUntil: 'networkidle' });
      const path = `screenshots/${Date.now()}.png`;
      await page.screenshot({ path });
      await browser.close();
      return path;
    }
    
  4. Implement the comparison logic

    For comparison, read both image files, use pixelmatch to compare them, and return the percentage difference. A lower percentage means fewer visual changes. You can also generate a diff image to highlight differences.

    const diff = pixelmatch(img1, img2, output, width, height, { threshold: 0.1 });
    const percentage = (diff / (width * height)) * 100;
    
  5. Register the tools with the MCP server

    Use the MCP SDK’s Server class to register your tools. Define input schemas for each tool—for example, capture_screenshot expects url (string) and viewport (object with width/height). Then start the server and listen for connections.

    server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [{ name: 'capture_screenshot', inputSchema: {...} }]
    }));
    
  6. Connect the server to your AI coding client

    In your MCP client (e.g., Claude Desktop or Cursor), add a new MCP server configuration pointing to your local server. For Claude Desktop, edit claude_desktop_config.json and add a mcpServers entry with the command to run your server: node /path/to/your/index.js. Restart the client.

  7. Test the integration

    In your AI chat, ask the assistant to “Take a screenshot of http://localhost:3000” or “Compare current homepage with the baseline.” The AI should invoke your tool and return the screenshot path or diff percentage. Verify the output appears in the chat.

  8. Incorporate visual tests into your workflow

    Create a baseline set of screenshots for key pages. Whenever you make UI changes, ask the AI to run a comparison against the baseline. The AI can then report whether any visual regression occurred. You can also set up a script that runs the MCP server in CI, but for now, focus on interactive use.

Common Mistakes

  • Forgetting to install browser binaries – Playwright needs npx playwright install to download Chromium. Without it, the browser won’t launch.
  • Hardcoding viewport sizes – Different devices render differently. Always pass viewport as a parameter.
  • Not waiting for page load – If you screenshot too early, you’ll capture a blank or partially loaded page. Use waitUntil: 'networkidle' or wait for specific elements.
  • Ignoring dynamic content – Animations, carousels, or lazy-loaded images can cause false positives. Consider pausing animations or fixing a test environment.
  • Using absolute file paths – The MCP server may run from a different directory. Use relative paths or resolve them based on the project root.

Tips

  • Store baseline screenshots in a __visual_tests__ folder and keep them in version control. This makes comparisons reproducible.
  • Use a threshold parameter in pixelmatch to ignore minor anti-aliasing differences. A threshold of 0.1–0.2 works well.
  • Generate a diff image (with red highlighting) so you can visually see what changed. The AI can even describe the diff if you feed the image back.
  • For responsive design, capture screenshots at multiple viewports (e.g., 375px, 768px, 1440px) in one go.
  • Name your screenshots descriptively, like home-desktop-baseline.png, so the AI can reference them easily.
  • If your app requires authentication, use Playwright’s storage state to save cookies and reuse them.

Troubleshooting

MCP client doesn’t show the tool – Check that your server is running and the client’s config points to the correct command. Look for errors in the client’s logs. Ensure the server is using the correct transport (stdio vs HTTP). For local development, stdio is typical.

Browser won’t launch – Run npx playwright install chromium again. If you’re in a restricted environment, you may need to install system dependencies with npx playwright install-deps.

Screenshots look different every time – This is often due to animations, fonts loading late, or dynamic content. Try disabling CSS animations via Playwright’s page.addStyleTag or wait for specific elements to be stable.

Comparison returns 100% difference even for identical pages – Check if the viewport size matches between captures. Also, ensure the page is fully loaded before each capture. Sometimes, a slight scroll position difference causes large diffs—scroll to top before capturing.

Server crashes when handling multiple requests – Make sure you’re not creating a new browser instance for every screenshot without closing it. Reuse a single browser instance and create new pages per request.

AI doesn’t pass the right arguments – If the AI sends the wrong format, your tool schema might be too vague. Provide clear descriptions and examples in the input schema.

Frequently Asked Questions

Can I use this with any MCP client? – Yes, as long as the client supports custom MCP servers. Most modern AI coding tools do.

How do I handle pages that require login? – Use Playwright’s storage state. Log in once, save the state to a file, and load it before each capture.

Is it possible to run this in CI/CD? – Yes, you can run the MCP server in a headless environment, but you’ll need to adapt the flow. Typically, you’d write a script that uses Playwright directly rather than an MCP server.

What if my app uses a lot of animations? – Disable CSS transitions and animations in your test environment. You can inject a style tag that sets * { transition: none !important; animation: none !important; }.

Can I compare screenshots from different browsers? – Yes, but expect some differences due to rendering engines. It’s best to stick to one browser for consistent baselines.

How do I update a baseline after an intentional design change? – Simply replace the baseline image with the new screenshot. You can ask the AI to “update baseline for homepage” and it will overwrite the file.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →