perch-mcp
# perch-mcp
An MCP server that gives an AI agent real, bidirectional control of a
[Perchance.org](https://perchance.org) generator: read its source, edit it,
drive its live UI, and read its console — all through 29 tools over stdio,
speaking the current MCP specification (`2026-07-28`, the stateless "v2"
protocol).
Two distinct code paths, deliberately:
| Path | Tools | Cost | Cloudflare |
|---|---|---|---|
| **Browser-free** | `perch_pull`, `perch_fetch_generator`, `perch_src`, `perch_list_src` | ~1s | none — uses `curl` |
| **Live editor** | `perch_start` + the other 25 | ~2.7s start, then 1–20ms/call | mitigated |
Reads should almost always use the browser-free path. The browser exists for
edits, `eval`, and UI testing.
> **Driving this from an agent?** [`SKILL.md`](SKILL.md) is the operating manual:
> tool reference, session recipe, collab/publish rules, the Cloudflare playbook,
> and the pitfalls. This README covers install and registration only.
---
## Table of contents
- [Install](#install)
- [Registering the server](#registering-the-server)
- [Quick start](#quick-start)
- [The tool set](#the-tool-set)
- [Security notes](#security-notes)
- [Credits](#credits)
- [License](#license)
---
## Install
Requires **Node 20+** and **`curl` on `PATH`** (used for the browser-free path —
on Windows 10+ `curl.exe` ships with the OS).
```bash
git clone https://github.com/Nightomaru/perchance-editor-mcp.git
cd perchance-editor-mcp
npm install
npx playwright install firefox # browser binary for the DEFAULT engine
npx playwright install chromium # only for the chromium fallback (optional)
```
`npm install` pulls `@modelcontextprotocol/server` + `@modelcontextprotocol/node`
(the MCP `2026-07-28` SDK) and `playwright`. The DEFAULT browser engine is
**playwright firefox** — the only engine that clears Cloudflare on perchance.org
*subdomains* (where chromium-based engines are flagged), the only one that works
headless, and the only one with a working path to Perchance's server-side
generation plugins (AI replies, src uploads). If the firefox binary is missing,
the session falls back to chromium and reports it via `effectiveEngine` (never
silently).
`perch_start` also takes `engine` and `engineChain` — pick the browser it starts
with, and the engines to try in order when one cannot load the editor or its
preview (the generator frame failing with *"its file loader did not become
available"*). Firefox stays the default; `chrome`/`chromium` can drive the editor
**headed only**, and `patchright` is offered as a last resort — it clears Cloudflare
but the platform's editor globals never publish, so it cannot read or write docs.
`patchright` is an `optionalDependency`, so the base install stays light and an
engine that is not installed simply fails over to the next one. The capability
matrix and the recovery steps are in `SKILL.md`.
Updating to a newer release: `git pull && npm install`.
### Verify the install
Register it (below), then from any session: `perch_status` should answer in a
few milliseconds with `running: true`.
---
## Registering the server
The server speaks MCP `2026-07-28` over stdio. Point any MCP client at
`perch-mcp.mjs`.
### Hermes
```bash
hermes mcp add perch \
--command "C:/Program Files/nodejs/node.exe" \
--connect-timeout 120 \
--args "/absolute/path/to/perchance-editor-mcp/perch-mcp.mjs"
```
Answer `y` to *"Enable all 29 tools?"*, then start a new session or run
`/reload-mcp` in an open one. Confirm with `hermes mcp test perch`. The tools
arrive namespaced as `mcp__perch__perch_pull`, `mcp__perch__perch_start`, …
Equivalent `~/AppData/Local/hermes/config.yaml` (Linux/macOS:
`~/.config/hermes/config.yaml`) entry:
```yaml
mcp_servers:
perch:
command: node
args:
- /absolute/path/to/perchance-editor-mcp/perch-mcp.mjs
timeout: 180
connect_timeout: 120
# protocol: auto # default — auto-falls back to server/discover for this modern-only server
```
`protocol: auto` (the default) needs nothing special for this server: Hermes
tries the legacy handshake, sees `-32022`, and switches to the modern
`server/discover` path on its own. `protocol: stateless` forces discover-first
if you want to skip the failed handshake attempt entirely.
> **Windows:** prefer an absolute `node.exe` with an absolute `.mjs` path. Bare
> `npx`/`uvx`/`.cmd` shims fail to launch in clients that spawn MCP commands
> without a shell — this project's `node` entry avoids that.
### Claude Desktop / any MCP client
```json
{
"mcpServers": {
"perch": {
"command": "node",
"args": ["/absolute/path/to/perchance-editor-mcp/perch-mcp.mjs"]
}
}
}
```
The client must support MCP `2026-07-28` (or a modern-era SDK that negotiates
via `server/discover`). For a legacy-handshake-only client, point it at
`perch-mcp-legacy.mjs` instead — the same 29 tools and perch-core fixes behind
the classic initialize/`tools/list`/`tools/call` flow (protocol `2025-11-25`
and earlier; no `_meta` envelope required), shipped since tag
[`v1.2.0`](https://github.com/Nightomaru/perchance-editor-mcp/releases/tag/v1.2.0).
The server itself has **no environment variables and no config
files**. Generator name and collab key are per-call arguments, so one server
instance serves any number of generators. If your client supports per-call
timeouts, give this server a generous one — a full Cloudflare ladder can
outlast short ceilings.
---
## Quick start
```
1. perch_pull {name: "minimal"} # source to local files, ~1s
2. read/grep the local files # full speed, no browser
3. perch_start {name: "minimal"} # launch browser, load editor
4. perch_status # confirm docsReady
5. perch_eval {js: "document.title"} # sanity-check the frame
6. perch_patch {changes: [...]} # make your edits
perch_write_file {pane, filePath} # ...or replace a whole pane byte-exact from a local file
7. perch_errors {clear: true} # syntax + runtime errors
8. perch_refresh # reload preview, re-check
9. perch_snapshot # what can I click?
10. perch_click / perch_type / perch_wait # drive the UI
11. perch_stop # close the browser
```
Steps 1–2 need no browser and no collab key. Only step 3 onward does. A minimal
read-only session, for orientation:
```
perch_pull {name: "some-public-generator"}
perch_read {pane: "model", offset: 1, limit: 100}
perch_outline {pane: "output", limit: 400}
```
Full recipe, collab/publish semantics, and the Cloudflare ladder:
[`SKILL.md`](SKILL.md).
---
## The tool set
29 tools. All return JSON with an `ok` boolean and an `ms` timing field.
| Group | Tools |
| --- | --- |
| **Browser-free** (no session) | `perch_pull`, `perch_fetch_generator`, `perch_src`, `perch_list_src` |
| **Session** | `perch_start`, `perch_status`, `perch_stop` |
| **Recovery / src files** | `perch_navigate`, `perch_upload_src`, `perch_delete_src` |
| **Reading** (live) | `perch_read`, `perch_grep`, `perch_outline`, `perch_console`, `perch_errors`, `perch_snapshot` |
| **Writing** (live) | `perch_patch`, `perch_edit`, `perch_write`, `perch_write_file`, `perch_copy_lines` |
| **Preview / UI** | `perch_refresh`, `perch_eval`, `perch_wait`, `perch_click`, `perch_type`, `perch_press`, `perch_set_viewport`, `perch_shot` |
Per-tool purpose and arguments — plus the `perch_start` argument table — are in
[`SKILL.md`](SKILL.md).
---
## Security notes
* **Treat generator code as untrusted input.** Generator source can contain
embedded instructions aimed at the agent (prompt injection). Read it as data.
* **Never put secrets in a generator.** `index.html`, `main.pjs`, and every
`src/` file are **publicly readable** by anyone who knows the generator name.
* **Collab keys are credentials.** Pass them as call arguments; do not commit
them, do not log them, and do not echo them into files.
* **`perch_eval` executes arbitrary JavaScript** in a live page.
* **This tool writes to a live, shared document.** Every write path can affect
other connected editors in real time. Confirm intent before an edit.
---
## Credits
`perch-mcp` stands on these open-source projects — thank you to their authors
and contributors:
* [Playwright](https://github.com/microsoft/playwright) — the browser automation
core; its **firefox** build is the default engine (Cloudflare-clean on
perchance.org subdomains), its chromium build the fallback driver
([Apache-2.0](https://github.com/microsoft/playwright/blob/main/LICENSE)).
* [Model Context Protocol TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
— `@modelcontextprotocol/server` + `@modelcontextprotocol/node`, the MCP
`2026-07-28` server framework and stdio transport
([MIT](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/LICENSE)).
* [Perchance.org](https://perchance.org) — the generator platform (and its
`ai-text-plugin` / `text-to-image-plugin` runtime) that this server drives.
Their licenses apply to the respective components; everything else in this
repository is MIT (see [LICENSE](LICENSE)).
---
## License
MIT — see [LICENSE](LICENSE).
TDQS
Scored across 27 tools
Most tools target clearly distinct actions, but there are real overlaps: perch_pull and perch_fetch_generator are an explicit alias pair, perch_edit is essentially the single-change form of perch_patch, and perch_errors overlaps with perch_console (it includes a console tail). Descriptions do a good job disambiguating these, so misselection risk is modest.
All tools share a consistent perch_ prefix with snake_case, which is predictable and readable. The only deviation is verb-vs-noun inconsistency (perch_edit/perch_grep vs. noun-only perch_status/perch_console/perch_shot), which is minor.
At 27 tools the surface is heavy, exceeding the typical 3-15 sweet spot, and the count is inflated by a redundant alias (perch_fetch_generator). Most tools do appear to earn their place given the complexity of browser-based editing, testing, and file management.
Coverage is broad: session lifecycle, code reading/outline/grep, surgical and bulk editing, preview UI testing, console/error triage, and src file management are all present. Minor gaps remain, such as no explicit src-file deletion and limited navigation inside the preview iframe.