Screenery

Docs / Reference

Screenery for AI agents

Screenery ships an MCP server that carries its own runbook. Add it to your coding agent, say one sentence, and the agent sets Screenery up for your repository.

Quick start

MCP, the Model Context Protocol, is how an agent host such as Claude Code, Cursor or Codex gives an agent extra tools. Add the Screenery server:

claude mcp add screenery -- npx -y screenery mcp

In Windows PowerShell 5.1 that command fails with unknown option '-y', because PowerShell drops the --. Run this instead, in any shell:

npx screenery install --tool claude-code

Then say:

Add the Screenery MCP server and set up self-updating screenshots for this repo.

The agent creates the project, pushes a first screenshot, adds the screenery/push@v1 step to your workflow and pastes the README snippet. It reads the runbook when it connects, and every tool result names the next tool to call, so it does not have to guess the order.

What stays yours

No agent can create a Screenery account or approve itself. Three things stay with you:

Neither visibility nor the path has a default. The agent is told to ask you for these together, up front. See Getting started for what each choice means.

Install the plugin

A plugin bundles the hosted MCP server and every Screenery skill into one install. It is published from github.com/screenery/agents, and the same plugin works in Claude Code, Codex and Cursor.

Claude Code, inside a session:

/plugin marketplace add screenery/agents
/plugin install screenery@screenery

Then run /mcp, pick plugin:screenery:screenery and choose Authenticate.

Codex:

codex plugin marketplace add screenery/agents
codex plugin add screenery@screenery
codex mcp login screenery

Cursor, on a team: an admin adds the marketplace first. In the Cursor dashboard, under Plugins & MCPs, choose Add Marketplace, then Import from Repo, and paste https://github.com/screenery/agents. That makes the plugin available. Whether it is installed depends on the installation mode the admin picks:

Cursor without a team marketplace: add the hosted server to ~/.cursor/mcp.json. This gives you the tools but not the skills:

{
  "mcpServers": {
    "screenery": { "url": "https://app.screenery.dev/mcp" }
  }
}

The plugin uses the hosted server, so it signs in with OAuth and does not read your files. For the local server, add it by hand as in the next sections.

Two ways to connect

LocalHosted
Addressnpx -y screenery mcphttps://app.screenery.dev/mcp
RunsOn your machine, over stdioOn Screenery, over HTTP
Signs in withA sign-in code you approve in the consoleOAuth, through your agent host
Reads your filesYesNo
NeedsNode 20 or newerAn MCP host that supports remote servers

Prefer the local server when the agent runs on the machine that has the screenshots. Use the hosted one when your host cannot start a process, such as an agent in a browser.

The local server is the screenery CLI from npm, currently 0.4.0. The hosted server is always the newest version, so it can have tools the local one does not have yet.

Adding it to a host

The CLI can write the config file for you:

npx screenery install --tool cursor
--toolFile it writes
claude-code~/.claude.json
cursor~/.cursor/mcp.json
vscodeVS Code's user mcp.json
codex~/.codex/config.toml
windsurf~/.codeium/windsurf/mcp_config.json
gemini~/.gemini/settings.json
opencode~/.config/opencode/opencode.json
continue~/.continue/config.json

--all writes every file above. --dry-run prints what it would write and writes nothing. Other servers in the file are kept, and a file that is not valid JSON is left alone. Afterwards, restart the host and say the sentence above. install only writes the config. It does not create a project, a token or a workflow.

Or add it by hand. For Codex, in ~/.codex/config.toml:

[mcp_servers.screenery]
command = "npx"
args = ["-y", "screenery", "mcp"]

For Cursor, or any host that reads an mcpServers file:

{
  "mcpServers": {
    "screenery": {
      "command": "npx",
      "args": ["-y", "screenery", "mcp"]
    }
  }
}

For VS Code:

code --add-mcp '{"name":"screenery","command":"npx","args":["-y","screenery","mcp"]}'

In Windows PowerShell 5.1 that command breaks, because PowerShell strips the double quotes out of the JSON. Use npx screenery install --tool vscode there.

If the server does not start, run npx screenery doctor. A host starts npx with the Node on its path, which is not always the one in your terminal. See the CLI reference.

The hosted server

claude mcp add --transport http screenery https://app.screenery.dev/mcp

The hosted server signs in with OAuth. Most hosts handle every step: the host registers itself, opens a Screenery consent screen, you sign in with GitHub and approve, and the host sends the token on each request. No client id or secret is needed.

A host asks for one or more scopes:

ScopeWhat it allows
screeneryAct as you: create projects, push screenshots, mint tokens, and everything below. The default when the host asks for no scope.
builds:readRead projects, builds and screenshot diffs.
reviews:writeApprove or reject a pull request's screenshots for you (your role must be publisher or higher).
comments:writeComment on a channel for you.

A builds:read grant can look but cannot set up a repository. You can revoke a session in the console, and the next request with it fails.

The hosted server cannot read your files.

So a push there takes two calls. screenery_push takes the list of files the agent hashed and returns an upload command for each file Screenery does not already have. The agent runs them, then calls screenery_finish_push. Sign-in codes, clips, demos and eval publishing are local only.

Tools

Every tool name starts with screenery_. You do not call them yourself; the agent does. This list is so you know what it can do.

ToolWhat it does
screenery_statusWhere setup stands: the session, your projects, and the repository's workflows. The agent calls it first and after each step.
screenery_loginLocal only. Starts the sign-in and returns a URL and a code for you to approve.
screenery_create_projectCreates the project, after asking you for visibility and the setup path.
screenery_pushPushes a directory of screenshots as one build. On the hosted server, starts a push the agent uploads itself.
screenery_finish_pushHosted only. Finishes that push.
screenery_setup_ciReturns your workflow with the screenery/push@v1 step added. The agent writes the file and shows you the diff.
screenery_embedThe Markdown and HTML snippet for an asset.
screenery_verifyChecks that a delivery URL is being served.
screenery_verify_then_publishPublishes check receipts onto @pr-N. Never moves @latest.
screenery_promoteMoves a channel, like screenery promote.
screenery_signA signed URL for an unlisted asset.
screenery_publish_tokenMints a publish token for CI outside GitHub Actions. It is shown once, and the agent hands it to you to store as a secret.
screenery_list_assetsEvery asset, with its visibility, its tags and description, and what @latest points at.
screenery_versionsOne asset's version history.
screenery_traceA five-minute download link for one version's Playwright trace, for members with the publisher role or higher. See Playwright traces.
screenery_list_buildsRecent builds.
screenery_get_buildOne build and its files.
screenery_diffCompares a build or channel with another channel: added, removed, changed, unchanged.
screenery_galleryThe gallery document for a pull request, build or channel.
screenery_manifestEvery screenshot on a channel with its description and tags, filtered by tag — e.g. every major or every android shot and its URL.
screenery_tag_assetTags or describes a screenshot in Screenery, e.g. social or feature. A push never changes these. Needs the publisher role. See Tags set in Screenery.
screenery_reportA short report over the same comparison. On the local server it requires CLI 0.4.0.
screenery_reviewApproves or rejects each changed screenshot of a pull request, or a whole channel. See Reviewing screenshots. Moves no channel.
screenery_commentLeaves a comment on a channel.
screenery_clipLocal only. Captures a live page onto @clip.
screenery_demoLocal only. Publishes demo clips.
screenery_eval_publishLocal only. Publishes an LLM UI eval onto @eval.

The tools that write need the screenery scope on the hosted server. screenery_review and screenery_comment appear only with their own scopes. The server also offers an onboard prompt, the whole setup as one instruction. See Clips, evals and demos for the last three tools.

Reviewing a change

An agent can compare a pull request's screenshots with @latest and see exactly what was added, removed or changed, with a URL for both sides so it can look at the pixels itself. It can then tell you which screen moved and why.

A review decision does not promote anything, does not move @latest, does not update a baseline and does not block a merge.

There is no tool that turns an approved diff into the new baseline. @latest moves when the default branch pushes, or when someone promotes it. See Visual testing and How @latest moves.

To set up this loop in Claude Code next to Playwright MCP, follow the Claude Code and Playwright MCP guide.

Files for agents

The console serves plain-text files written for agents to read:

URLWhat it holds
https://app.screenery.dev/llms.txtA short guide: how to add the MCP server to each host, and what you do.
https://app.screenery.dev/llms-full.txtThe full onboarding guide, the URL grammar and the server's runbook, in one file.
https://app.screenery.dev/skills.txtThe list of Screenery skills, with where to fetch each one and where to write it.
https://app.screenery.dev/auth.mdHow an agent gets credentials: OAuth, sign-in codes, and CI.
https://app.screenery.dev/errors/Every API error code and what to do about it.

A skill is one Markdown file of instructions an agent reads before it starts a job. The current ones cover writing Playwright screenshot tests, keeping embedded screenshots current in docs, Google Play listing screenshots, demo clips, eval results, comparing and reporting, and publishing Playwright goldens. Each is served at https://app.screenery.dev/skills/<id>.md, for example:

https://app.screenery.dev/skills/screenery-screenshots.md

The MCP server can point at the skill that fits your repository, but it cannot install one. Your agent fetches the file and writes it to .claude/skills/<id>/SKILL.md in your repository, with your agreement. The plugin carries every skill, so with it installed there is nothing to fetch.