@genclass/mcp
Your coding agent can see the race, replay it, and prove the fix.
An MCP server for Claude Code and other coding agents. It connects to the pages of your app running on your machine
(through @genclass/runtime's agent link) and gives the agent:
- What happened, in order. Every click, request and response, the order the responses were delivered, what each
response wrote into the app's state, and uncaught errors with the click and request that led to them.
- Bugs that never throw. A response that overwrote newer data (the classic stale search result or lost edit), the
same order submitted twice by two clicks, and the on-device model's own detections.
- Races found before users find them.
genclass_explore runs your steps again with the network answering in
different orders (and slower, if you like) and reports what ends differently from the run where responses came back
in order.
- Proof.
genclass_replay delivers the exact order that produced a bug again, before your fix (reproduced) and
after it (not reproduced), and genclass_explain writes a Playwright test that fails while the bug is there.
By default everything stays on your machine (see Privacy). No dependencies. The server is free. For developers who want the loop run for
them, GenClass runs it as a service under Enterprise: the MCP server, collector and dashboard hosted by GenClass or
inside your network (genclass.dev/enterprise).
Install
Pick your client. Every block pins this release, so the client starts exactly this version;
npx -y @genclass/[email protected] config <client> prints the same lines, and genclass_setup prints the block for the
client it runs in.
Claude Code
As a plugin (the server, a prompt hook that brings new findings to each prompt, and the genclass skill with the procedure):
Or the server alone (--scope project writes .mcp.json for everyone on the project; --scope user for all your projects). init also writes the skill to .claude/skills/genclass/SKILL.md (--no-skill leaves it out):
Or just the skill (no server): npx skills add genclass-dev/genclass-plugin. (genclass-dev/genclass-plugin is this plugin at a repository root, assembled from this package; the marketplace in genclass-dev/GenClass lists the same plugin.)
Claude Desktop
Settings, Developer, Edit Config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):
Cursor
[Add genclass MCP server to Cursor] or cursor://anysphere.cursor-deeplink/mcp/install?name=genclass&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBnZW5jbGFzcy9tY3BAMC4yLjIiXX0%3D
Or .cursor/mcp.json in the project (~/.cursor/mcp.json for all projects):
VS Code
[Install in VS Code] or from a terminal:
Or .mcp.json at the workspace root (the portable format; .vscode/mcp.json takes the same entry under servers):
Codex CLI
As a plugin (the server and the genclass skill):
Or the server alone:
Or ~/.codex/config.toml (.codex/config.toml in a trusted project). The first start downloads the package, so allow more than the default 10 seconds:
Gemini CLI
As an extension (the server and the genclass skill):
Or the server alone:
Or .gemini/settings.json in the project (~/.gemini/settings.json for all projects):
Windsurf (Devin Desktop)
~/.codeium/windsurf/mcp_config.json (Windsurf), ~/.config/devin/mcp_config.json (Devin Desktop's Cascade agent; %APPDATA%\devin\mcp_config.json on Windows):
Devin CLI and Devin Desktop's Devin Local agent:
Cline
Or MCP Servers, Configure, Configure MCP Servers (~/.cline/data/settings/cline_mcp_settings.json):
Goose
goose://extension?cmd=npx&arg=-y&arg=%40genclass%2Fmcp%400.2.2&id=genclass&name=genclass&description=Find%20race%20conditions%20by%20reordering%20responses%2C%20replay%20one%2C%20prove%20the%20fix (open it to install), or goose configure (Add Extension, Command-line Extension, command npx -y @genclass/[email protected]), or ~/.config/goose/config.yaml:
Zed
~/.config/zed/settings.json (.zed/settings.json in the project), or Settings, AI, MCP Servers, Add Server:
JetBrains IDEs
AI Assistant: Settings, Tools, AI Assistant, Model Context Protocol (MCP), Add, then this JSON. Junie: .junie/mcp/mcp.json in the project (~/.junie/mcp/mcp.json for all projects), same JSON:
OpenCode
opencode.json in the project (~/.config/opencode/opencode.json for all projects), or opencode mcp add:
Any other MCP client: a stdio server, command npx, arguments -y @genclass/[email protected], no environment variables
required.
The genclass skill
The server's instructions (sent when it connects) tell the agent when to reach for GenClass: the symptom words
("sometimes", "randomly", "only in production", "on slow connections", a value that "flips back", stale or old
results, lost edits, double submits, sideways scrolling), the code changes that call for an explore, the scan before a
UI change is done, and the first call for each. The procedure (the explore arguments, the Playwright pairing, how to
read a report, what to say when done, what to do when the tools are missing) is the genclass skill,
plugin/skills/genclass/SKILL.md. Three ways to get it:
- the plugin installs it with the server and the hook;
npx -y @genclass/[email protected] init writes it to .claude/skills/genclass/SKILL.md in the project (--no-skill
leaves it out). The written file carries a genclass:init marker line: a rerun replaces a file with the marker and
leaves one without it (yours, or edited), and says which;
npx skills add genclass-dev/genclass-plugin (the skills CLI: Codex, Cursor, Copilot, Gemini CLI, Claude Code and
others) or gh skill install genclass-dev/genclass-plugin genclass (GitHub CLI 2.90 or later, for Copilot) installs
the skill alone, with no server (the skill then says how to add one). npx skills add genclass-dev/GenClass
installs the same file from this repository's root copy, skills/genclass/SKILL.md.
To remove it: delete .claude/skills/genclass/ (or the directory the skill tool wrote to); with the plugin,
/plugin uninstall genclass@genclass.
Then connect the app's development build (once). The agent link needs the newest runtime line, @genclass/runtime
0.3.0-beta.1 or later: npm install @genclass/[email protected], the version this release was tested with (npm's
latest is the older 0.2.x, which has no agent entry):
A production build drops all of this (measured with Vite, esbuild and Next.js 15; the package's sideEffects list names
neither entry). Load a page of the dev server and ask the agent for genclass_status. The agent can also ask genclass_setup,
which reads your package.json and shows the lines for your framework.
The skill and the server's instructions tell the agent to show you each of these and wait for your yes: running that
install or adding those lines; npx playwright install chromium and npm i -D playwright; genclass_scan with hosted: true; writing a fix or a
test when you only asked what broke.
What the agent does with it
On a real page in headless Chromium (the package's end-to-end check), explore found that race in 5 of 6 reordered runs
of a page that never showed it on the developer's fast backend, the generated test failed on the buggy page and passed
on the fixed one, and explore on the fixed page reported nothing. Details: docs/runtime/AGENT.md.
What it calls a race is what the page shows or writes, not the noise of a running page: an age that moved by the time
the session took ("13 minutes ago", "14 minutes ago"), a field name made for each load and a different count of a POST
that only reads are not differences by themselves; "3:30 PM" against "4:00 PM" and a save that never went out are. With
slow_ms one load runs with no added delay (runs + 3 loads: 2 slow baselines, that one, and the reordered runs): what
both slow baselines show and it does not is named as what a slow response alone does, and what only one of them does is
"worth a look". A report that compared nothing says NO VERDICT, not "no race".
Tools
New findings without asking
- Channels (Claude Code research preview): start Claude Code with
claude --dangerously-load-development-channels server:genclass and new findings arrive in the session as they
happen (notifications/claude/channel).
- Prompt hook (part of the Claude Code plugin):
npx -y @genclass/[email protected] init --hook adds a UserPromptSubmit
hook to .claude/settings.json; each prompt then carries the findings that changed since the last one.
Environment
Security
The bridge listens on 127.0.0.1 only and checks the Host header. Pages may talk to it only from your machine
(localhost, 127.0.0.1, *.localhost) or an origin you list in GENCLASS_AGENT_ORIGINS (a *.test or LAN dev host): a public
website, a router page or a captive portal you visit cannot plant findings, and a page can only add to its own run.
The agent API refuses browsers and needs a token only your user can read. Everything a page sends is validated,
capped, stripped of invisible characters and shown to the agent as quoted data, never as instructions. Nothing leaves
your machine (the exceptions are under Privacy). See section 6 of
AGENT.md.
Privacy
By default the server collects nothing and sends nothing to GenClass or anyone else. Findings stay on your machine, in
.genclass/agent/ in the server's working directory (the project, for clients that start servers there; set
GENCLASS_STATE_DIR for clients that do not, such as Claude Desktop), which the server gitignores, and in the bridge's memory; the bridge's token is in
~/.genclass. genclass_analytics {source: "production"} reads
your own GenClass dashboard when you set GENCLASS_DASHBOARD to its private link. genclass_scan loads the page the
agent names (that is the page's own traffic) in a local browser; only with hosted: true is the URL sent to the
genclass.dev page check, and when the project has no @genclass/runtime with scan, npx downloads the version this release pins, @genclass/[email protected], from npm. With GENCLASS_REPORT set (off by
default) the server also mirrors its log of the loop to that dashboard, in small batches: the id, kind and page path of
each finding, when its evidence was read, each replay armed and its verdict, when a regression test was written, each
explore report (page loads compared, races found) and each clear, so the dashboard's Closed-loop development view
draws every issue's path (found, reproduced, fix proven, closed, or round again) and lists what the agent did; never a
title, an evidence line, a snapshot or any page text, and nothing it sends feeds a decision.
The lines above start the runtime in development builds only. On a local or private address it sends no diagnostics (it
does fetch its on-device model from jsDelivr). Running it in production is a separate choice this server does not need:
outside the check GenClass.init() runs for every visitor and sends its disclosed anonymous diagnostics from public
hosts by default (PRIVACY.md), which
GenClass.init({ telemetry: false }) turns off; the agent link is not part of them.
License
Apache-2.0