Site-Shot MCP server
Give Claude, Cursor, and other AI agents the ability to see public web pages — take website screenshots
with Site-Shot over the Model Context Protocol.
Real Chromium rendering · full-page capture · country proxies · automatic ad & cookie-banner removal
(cleaner images, fewer vision tokens).
A Site-Shot API key is required. A confirmed account's API key comes with the free plan: 100 API
captures a month, no card needed; paid plans start at $5/mo for 2,000. The free plan renews every
month; once its 100 captures are spent, the API answers 403 until it renews. Free-plan captures
come from the default location or the US; other countries need a paid plan, and a request for one
is refused but still counts toward the month. Accounts confirmed before 2026-10-30 switch the free
plan on with one button on https://www.site-shot.com/start/; an account that has had a paid plan
before does not get it. Captures draw on that account's API allowance and limits.
Get the key at https://www.site-shot.com/start/ or from your
Site-Shot dashboard; pricing
lists the plans. The no-signup browser tool at https://www.site-shot.com/ is for checking output
quality; it does not issue keys.
Claude Code (plugin)
This repository doubles as a Claude Code plugin marketplace. The plugin runs the published
site-shot-mcp package over stdio and declares the API key as a required sensitive setting, so
Claude Code prompts you for it rather than asking you to paste it into this repository, a config
file, or a chat message.
Install
or from inside a session:
Both forms resolve the marketplace from GitHub, so they work only after these manifests are
published on the repository's public default branch — not from a local branch or a fork you
have not pushed.
Try it before that
Load the plugin directory for a single session:
Two things matter here. Pass an absolute path — --plugin-dir is resolved against the session's
working directory. And start that session from an ordinary project directory, not from this
checkout: this repo is the site-shot-mcp package, so npm resolves the name locally, finds no
linked binary, and the server dies with sh: site-shot-mcp: command not found before Claude Code
ever sees it. From an unrelated directory npx fetches the published package and starts it
normally — checked both ways: exit 127 in this checkout, clean stdio start from an empty one.
To exercise the real install path instead — marketplace resolution, manifests and the required
setting — add the checkout itself as a marketplace:
That installs into your user scope; undo it with claude plugin uninstall site-shot@site-shot and
claude plugin marketplace remove site-shot.
The API key
The plugin declares SITESHOT_API_KEY as a required, sensitive setting. Claude Code prompts you for
the key, masks it as you type, and substitutes it into the server's environment as
${user_config.SITESHOT_API_KEY}. Storage of the value is Claude Code's to handle.
Installing without one is not an error — Claude Code records it as still owed
(1 userConfig option not yet set (1 required)). Supply it through the masked prompt:
Configure it before expecting a capture: that setting is what feeds the server its key. What Claude
Code does while it is unset — whether the server is launched at all, whether the tools are offered —
is Claude Code's own behaviour and is not something documented here from observation.
The server's side is independent of that. When run directly over stdio without a key, it still
starts and prints a warning on stderr. Capture tools return a clear missing-key error instead of an image.
The plugin adds one skill (site-shot:website-screenshots) and the two capture tools
below. It declares no hooks, no monitors and no scheduled capture jobs; the only process
it launches is the declared stdio MCP server.
Codex CLI (plugin)
This repository is also a Codex plugin marketplace. It installs the same plugin directory as Claude
Code does — one shared skill, the same pinned [email protected] over stdio — with its own
manifest, because the two hosts wire the credential differently.
Install
Exercised against Codex CLI 0.147.0 on macOS (arm64). As with Claude Code, these resolve the
marketplace from GitHub, so they work only once these manifests are on the public default branch;
before that, point codex plugin marketplace add at a local checkout path instead.
Installing is not the same as being configured, and neither is the same as a capture succeeding.
Installation only puts the manifests in place. The server still needs the key below, and a capture
still needs allowance left on that key's account, from the free plan or a paid plan.
The API key
Codex forwards the variable named in the plugin's descriptor:
env_vars is an allow-list of names, not values: no key appears in this descriptor, in the command
below, or in the manual config.toml entry further down. You provision the key in the environment
of the session you start Codex from.
macOS defaults to zsh, where read -p starts a coprocess rather than printing a prompt — and a
bash-labelled code fence does not change the shell you paste into. Invoke bash explicitly:
-s keeps the key off the screen, nothing here puts it in argv, and the export is scoped to that
child session instead of lingering in the shell you typed from.
What this does not do is configure a Codex you start some other way. A desktop launcher or a remote
session begins from its own environment, so it will run the server without a key until you provision
one there too.
Manual MCP setup instead
If you would rather not install the plugin, the same stdio server can be configured by hand. This is
an alternative to the plugin, not an addition — run both and you have two configurations of one
server. Pick one.
codex mcp add site-shot -- npx -y [email protected] writes that entry for you; add env_vars
afterwards, since codex mcp add --env KEY=VALUE would store the key in the file in clear text.
Check it with codex mcp get site-shot. If you already have an entry like this and now install the
plugin, remove the manual one deliberately with codex mcp remove site-shot — nothing here edits
your configuration for you.
Either route, the caveat from the Claude Code section applies: unless the entry sets cwd, Codex
starts the server from wherever you ran Codex, so running it inside this repo hits the same
local-name collision.
Claude Desktop & other MCP clients
- Get a Site-Shot API key at https://www.site-shot.com/start/.
- Add this to your Claude Desktop config (
claude_desktop_config.json):
- Restart Claude Desktop. Ask it to "take a full-page screenshot of https://news.ycombinator.com" and
it will call the server and show you the image.
Works the same way in any MCP client (Cursor, Cline, VS Code, LangChain, CrewAI) — point the client at
npx -y site-shot-mcp with SITESHOT_API_KEY in the environment.
Every integration above runs the same local stdio server, published on npm and in the official MCP Registry. Hosted HTTPS MCP is a separate deployment and client-compatibility path, not something these plugin install commands configure. Publication here does not imply listing in the shared ChatGPT/Codex public plugin directory or Claude's remote connector directory.
Tools
Two tools, both returning the screenshot as an MCP image. There is no saved library, no listing,
no markdown conversion and no scheduling — this server captures images and hands them back.
capture_screenshot
Screenshot a web page (viewport by default).
Returns the screenshot as an MCP image.
"API default" is not a number this package gets to state. width, height and wait_ms
are forwarded only when you pass them, so whatever applies when you don't is decided by the
Site-Shot API and can change without a release here. Versions up to 1.1.0 printed pixel sizes
for width / height that the API does not use — an agent that omitted them to take "the
default" got a different viewport, with nothing in the returned image to reveal it. Pass
explicit values whenever the size matters.
Country codes are ISO codes, never names. Pass "DE", not "Germany". The API matches
codes exactly and would otherwise render through a US proxy without telling you, so the server
rejects full names before spending a render. strict_country (on by default) likewise turns an
unavailable country into an error instead of a silent US screenshot — pass false to opt back
into the fallback. Supported countries →
capture_full_page
Same as capture_screenshot with full-page capture enabled.
Why call this server instead of the agent's own browser?
If your agent drives a browser, it can screenshot pages itself — and for pages that must be signed
into or stepped through a flow, that is the right tool. For public URLs, delegating the capture to
this server is usually better engineering: every capture runs the same pipeline (no re-planning
between runs), can be taken from a specific country with matching locale and time zone
(country + strict_country), is scored by an image classifier with an escalating retry ladder
behind it before being returned, and costs a fraction of a cent instead of a browser session plus
vision tokens per look. The full comparison, both directions honestly argued:
AI agent vs. screenshot API — who should capture the page.
Configuration
The server is a thin wrapper over the existing Site-Shot HTTP API (https://api.site-shot.com/) — no
separate backend.
Local development
Requirements
Node.js ≥ 18 (uses the built-in fetch).
License
MIT