A dev sidecar that gives AI agents live access to your browser during development. The agent sees what you see — console logs, DOM, screenshots, form state — through your existing browser tab, with your auth, your state, your HMR.
Not a browser automation tool. For that, use Playwright. This is for the dev loop: edit code → check the browser → fix → repeat.
graph LR
Agent -->|MCP tools| GW
GW -->|JSON commands| Browser
subgraph GW["Gateway :3333"]
MCP["/__mcp/sse"]
CMD["/__rpc"]
end
In your project directory:
npx webdev initThat detects your framework (Vite, Next.js, Astro, Storybook), wires the adapter into your config, installs the dev dependencies, and writes MCP server config for Claude / Cursor / Windsurf / VS Code.
Then start your dev server as usual (npm run dev). The adapter auto-starts the gateway. Open the page in your browser, connect your agent — done.
// .mcp.json (written by `init`)
{
"mcpServers": {
"webdev": {
"url": "http://localhost:3333/__mcp/sse"
}
}
}If you only need MCP registration (e.g. you've already wired your config manually):
npx webdev register # project-level
npx webdev register --global # user-level (~/.claude, ~/.cursor)See getting-started.md for the full setup guide and manual install.
Six tools. eval_js does most of the work.
get_diagnostics — console logs + errors + network + HMR/build status in one call. Use since_checkpoint: true after clear for clean reads.
clear — reset logs. Call before a code change.
eval_js — run JavaScript directly in the browser. Full DOM access, multi-statement, supports await. Promises auto-awaited. Accepts string | string[] — array of steps auto-waits for DOM to settle between each.
// Read the page as markdown
eval_js: return browser.markdown('#main')
// Click by visible text
eval_js: browser.click('text=Submit')
// Fill a form
eval_js: browser.fill('#email', 'test@example.com')
// Take a screenshot
eval_js: return browser.screenshot('#my-component')
// DOM traversal
eval_js: |
const link = document.querySelector('a[href*="doom"]')
const row = link.closest('tr').nextElementSibling
return row.querySelector('a:last-child').href
// Store refs across calls
eval_js: state.heading = document.querySelector('h1'); return state.heading.textContent
eval_js: return state.heading.getAttribute('class')
// Auto-waited pipeline (array of steps)
eval_js: ["browser.click('text=Submit')", "return document.querySelector('.toast').textContent"]Element grabber — Hold Cmd+Shift+C in your browser to activate, then hover and click any element to get its component name, source location, and CSS selector. The selection is pushed to the gateway and available via the get_element_context MCP tool.
set_project / list_projects / list_browsers — multi-project management.
Full tools available at /__mcp/sse?tools=full (23 tools including click, fill, screenshot, navigate, query_dom, etc. as individual tools).
Pick the adapter for your framework. Each one auto-starts the gateway.
npm install -D @winstonfassett/webdev-vite @winstonfassett/webdev-gateway// vite.config.ts
import { webdev } from '@winstonfassett/webdev-vite'
export default defineConfig({
plugins: [react(), webdev()],
})If @vitejs/devtools is installed in the same project, the adapter auto-registers two entries in the DevTools dock — no extra config:
- webdev-ai — iframes the gateway admin UI, scoped to the current Vite server
- Element picker — toggles the element grabber from the dock
// vite.config.ts
import { DevTools } from '@vitejs/devtools'
import { webdev } from '@winstonfassett/webdev-vite'
export default defineConfig({
plugins: [react(), DevTools(), webdev()],
})@vitejs/devtools is an opt-in peer — if it's not installed, the dock hook is never called and there's zero runtime cost.
// .storybook/main.ts
export default {
addons: ['@winstonfassett/webdev-vite/storybook'],
}npm install -D @winstonfassett/webdev-next @winstonfassett/webdev-gateway// next.config.js
import { withWebdev } from '@winstonfassett/webdev-next'
export default withWebdev(nextConfig)For Turbopack, also add the client component to your root layout:
// app/layout.tsx
import { WebdevInit } from '@winstonfassett/webdev-next/init'
// ... add <WebdevInit /> as a child of <body>npm install -D @winstonfassett/webdev-astro @winstonfassett/webdev-gateway// astro.config.mjs
import webdev from '@winstonfassett/webdev-astro'
export default defineConfig({
integrations: [webdev()],
})Framework adapters (recommended): Vite and Next.js adapters inject the client script and forward HMR/build events to the gateway.
Proxy plugin (npm install @winstonfassett/webdev-proxy): browse http://localhost:3333/http://any-url/ to proxy and instrument any page. Works with any dev server or website.
Manual: add <script src="http://localhost:3333/__webdev.js"></script> to your HTML.
Three actors, one local gateway holding them together.
graph TB
AGENT["AI Agent<br/>(Claude / Cursor / Windsurf / VS Code)"]
subgraph GW["Gateway :3333"]
REG[("Server<br/>registry")]
LOGS[("Log writers<br/>NDJSON")]
MCP["MCP server<br/>/__mcp/sse"]
ADMIN["Admin UI<br/>/__admin"]
end
subgraph DEV["Your dev project"]
SERVER["Dev server<br/>(Vite / Next / Astro / Storybook)"]
ADAPTER["webdev adapter"]
BROWSER["Browser tab<br/>(your app)"]
CLIENT["Injected client<br/>(console patch + RPC)"]
end
SERVER -->|hosts| ADAPTER
ADAPTER -->|registers + dev events| REG
ADAPTER -->|injects| CLIENT
BROWSER -->|runs| CLIENT
CLIENT -->|console + errors + network| LOGS
CLIENT <-->|RPC commands + results| MCP
AGENT <-->|tool calls| MCP
MCP -->|reads| LOGS
MCP -->|reads| REG
A single tool call goes through it like this:
sequenceDiagram
participant Agent
participant Gateway
participant Browser
Browser->>Gateway: WebSocket — event stream + command channel
Agent->>Gateway: MCP tool call (e.g. eval_js)
Gateway->>Browser: JSON command
Browser-->>Gateway: result
Gateway-->>Agent: MCP response
The injected client script:
- Patches
console.*,fetch,XMLHttpRequestto relay events to NDJSON log files - Connects to
/__rpcvia WebSocket for JSON commands - Handles commands: eval, screenshot, click, fill, navigate, queryDom, markdown, etc.
When the browser extension is installed, the gateway upgrades the same browser_* tools to Playwright via CDP — pixel-perfect screenshots and reliable locators, transparent to the agent.
See the examples/ directory for working setups:
- vite-app — Basic Vite + React with webdev adapter
- tanstack-start — TanStack Start (Vite-based) with element-source integration
- astro-site — Astro integration with webdev
- nextjs-turbopack — Next.js 15+ with Turbopack and WebdevInit component
- nextjs-webpack — Next.js 14 with webpack mode
- storybook-app — Storybook with webdev addon
- static-site — Plain HTML with manual script tag
- admin-svelte — Svelte admin UI (gateway's built-in dashboard)
Each example demonstrates a different framework or integration pattern.
MIT



