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:
- approve a sign-in once, in the console;
- say whether the screenshots are public or private;
- choose the setup path: github_app or static_token. On the GitHub App path, you also install the App and pick the repository.
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:
- Required or Default On: it is installed for every member.
- Default Off: each member opens Customize in Cursor's sidebar, finds Screenery, and installs it.
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
| Local | Hosted | |
|---|---|---|
| Address | npx -y screenery mcp | https://app.screenery.dev/mcp |
| Runs | On your machine, over stdio | On Screenery, over HTTP |
| Signs in with | A sign-in code you approve in the console | OAuth, through your agent host |
| Reads your files | Yes | No |
| Needs | Node 20 or newer | An 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
| --tool | File it writes |
|---|---|
| claude-code | ~/.claude.json |
| cursor | ~/.cursor/mcp.json |
| vscode | VS 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:
| Scope | What it allows |
|---|---|
| screenery | Act as you: create projects, push screenshots, mint tokens, and everything below. The default when the host asks for no scope. |
| builds:read | Read projects, builds and screenshot diffs. |
| reviews:write | Approve or reject a pull request's screenshots for you (your role must be publisher or higher). |
| comments:write | Comment 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.
| Tool | What it does |
|---|---|
| screenery_status | Where setup stands: the session, your projects, and the repository's workflows. The agent calls it first and after each step. |
| screenery_login | Local only. Starts the sign-in and returns a URL and a code for you to approve. |
| screenery_create_project | Creates the project, after asking you for visibility and the setup path. |
| screenery_push | Pushes a directory of screenshots as one build. On the hosted server, starts a push the agent uploads itself. |
| screenery_finish_push | Hosted only. Finishes that push. |
| screenery_setup_ci | Returns your workflow with the screenery/push@v1 step added. The agent writes the file and shows you the diff. |
| screenery_embed | The Markdown and HTML snippet for an asset. |
| screenery_verify | Checks that a delivery URL is being served. |
| screenery_verify_then_publish | Publishes check receipts onto @pr-N. Never moves @latest. |
| screenery_promote | Moves a channel, like screenery promote. |
| screenery_sign | A signed URL for an unlisted asset. |
| screenery_publish_token | Mints 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_assets | Every asset, with its visibility, its tags and description, and what @latest points at. |
| screenery_versions | One asset's version history. |
| screenery_trace | A five-minute download link for one version's Playwright trace, for members with the publisher role or higher. See Playwright traces. |
| screenery_list_builds | Recent builds. |
| screenery_get_build | One build and its files. |
| screenery_diff | Compares a build or channel with another channel: added, removed, changed, unchanged. |
| screenery_gallery | The gallery document for a pull request, build or channel. |
| screenery_manifest | Every 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_asset | Tags 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_report | A short report over the same comparison. On the local server it requires CLI 0.4.0. |
| screenery_review | Approves or rejects each changed screenshot of a pull request, or a whole channel. See Reviewing screenshots. Moves no channel. |
| screenery_comment | Leaves a comment on a channel. |
| screenery_clip | Local only. Captures a live page onto @clip. |
| screenery_demo | Local only. Publishes demo clips. |
| screenery_eval_publish | Local 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:
| URL | What it holds |
|---|---|
| https://app.screenery.dev/llms.txt | A short guide: how to add the MCP server to each host, and what you do. |
| https://app.screenery.dev/llms-full.txt | The full onboarding guide, the URL grammar and the server's runbook, in one file. |
| https://app.screenery.dev/skills.txt | The list of Screenery skills, with where to fetch each one and where to write it. |
| https://app.screenery.dev/auth.md | How 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.