DEV Community

Cover image for Give Claude Code and Cursor eyes: a hosted MCP screenshot tool in one command
Harpreet singh
Harpreet singh

Posted on Originally published at snaplab.dev

Give Claude Code and Cursor eyes: a hosted MCP screenshot tool in one command

Coding agents are surprisingly blind. Claude Code can read your CSS, but it cannot tell you that the hero text is overlapping the nav on mobile. Cursor can write a Playwright test, but it cannot glance at the page it just changed. The fix is small: give the agent a tool that returns a real screenshot.

This post sets that up with the Model Context Protocol (MCP) in one command, using a hosted server so there is nothing to run locally.

What you get

Four tools appear in the agent:

  • screenshot – URL or raw HTML in, PNG/JPEG/WebP out, returned inline as an image so the model can look at it. Options: fullPage, width/height, mobile, darkMode, blockAds, dismissBanners.
  • pdf – the same, but a print-quality PDF (A4/Letter, landscape, margins).
  • html_to_image – HTML/CSS in, a 1200×630 image out. Handy for OG cards.
  • usage – how many renders you have left this month.

Renders run in real Chromium on the server with hard timeouts, ad blocking and cookie-banner dismissal, so the agent sees what a user sees, not a consent modal.

Setup: Claude Code

claude mcp add --transport http snaplab https://snaplab.dev/mcp \
  --header "Authorization: Bearer sk_live_…"
Enter fullscreen mode Exit fullscreen mode

Get a key at snaplab.dev/app/keys. The free tier is 100 renders a month, no card.

Setup: Claude Desktop or Cursor

Add this to your MCP config (claude_desktop_config.json, or Cursor → Settings → MCP):

{
  "mcpServers": {
    "snaplab": {
      "type": "http",
      "url": "https://snaplab.dev/mcp",
      "headers": { "Authorization": "Bearer sk_live_…" }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

That is the whole install. Streamable HTTP, no npm package, no Docker, nothing to keep updated.

What it looks like in practice

You: Check the pricing page on staging at 390px wide and tell me if anything overflows.

Claude: (calls screenshot with url, mobile: true, fullPage: true) The plan cards stack correctly, but the comparison table overflows by about 180px; the third column is cut off. Here is the capture. Want me to make the table scroll horizontally on small screens?

Because the image comes back as an inline content block, the model reasons about the pixels directly. No OCR, no "please describe the page".

Other prompts that work well:

  • "Screenshot https://example.com in dark mode and compare it to the light version."
  • "Render this HTML as a 1200×630 card and show me." (paste the HTML)
  • "Make a PDF of the docs page and tell me how many pages it is."

Why hosted instead of a local Playwright MCP

A local browser MCP is great on your laptop. It is less great in CI, in a devcontainer, on a teammate's machine without Chromium, or inside an agent that runs in the cloud. A hosted server means every environment gets the same renderer, and the agent never has to install or babysit a browser.

The trade-off is that the renderer only sees what the public internet sees. For a local dev server, tunnel it (ngrok, Cloudflare Tunnel) or pass the HTML directly with html instead of url.

Security notes

  • The server refuses private and loopback addresses, cloud metadata endpoints and non-HTTP schemes, so an agent cannot be tricked into screenshotting your internal network.
  • Keys are hashed at rest and shown once. Revoke from the dashboard.
  • Nothing is stored beyond the render cache (24 h) and any captures you explicitly persist.

Beyond MCP

The same API behind the MCP server is a plain REST endpoint (POST /api/render), has signed URLs so you can put a screenshot straight into an <img> tag, an n8n community node, a JS SDK (npm i snaplab), and an Apify actor. Docs: snaplab.dev/docs.

If you try it with your agent, I would like to hear what it got right and where it fell short. Reply here or email snaplab@hsingh.app.

Top comments (0)