Skip to content
| Marketplace
Sign in
Visual Studio Code>Testing>AEye BrowserNew to Visual Studio Code? Get it now.
AEye Browser

AEye Browser

Aesepus Technology

|
1 install
| (0) | Free
Gives Claude a private, Playwright-driven browser via MCP to inspect and test the web app you're building in VS Code.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

AEye Browser

A VS Code extension that gives Claude a private, Playwright-driven browser — via an MCP server — for testing and inspecting the web app you're building, right from inside VS Code.

Claude gets a real, isolated Chromium instance it can navigate, screenshot, and interact with, plus a set of higher-level tools for building reusable regression tests, checking role-based access with named test users, running WCAG accessibility scans and technical SEO audits, and drafting/previewing page mockups. The extension side adds a few VS Code panels and a status bar menu so a human developer can inspect and manage all of this without going through Claude at all.

What it does

  • Private browser for Claude. A persistent, isolated Chromium profile (separate from your everyday browser) that Claude drives through an MCP server bundled with the extension: navigate, screenshot, read the DOM/cookies/response headers/console errors, click, fill.
  • Reusable test cases. Claude creates named JSON test cases (create_test/update_test/delete_test/list_tests), runs them individually or all at once (run_test/run_all_tests), and gets a self-contained HTML pass/fail report with the failing element highlighted in its screenshot. Every test case also gets a plain-text, human-editable companion file — hand-edit its "Notes" section and the edit is picked up automatically the next time Claude touches that test, instead of being overwritten.
  • Login / role-based testing. Named test-user profiles (create_user/update_user/delete_user/list_users) back login/logout test steps. run_test_as_users repeats one test once per named user, overriding whatever user is written in the file, so you can check e.g. "can the viewer role see the delete button?" in one call.
  • Accessibility & SEO. check_accessibility runs a real WCAG scan (axe-core) with violations by impact level; check_seo audits title/meta description/canonical/viewport/headings/alt text/Open Graph/structured data. Both also work as steps inside a saved test case.
  • Page mockups. create_mockup/update_mockup/delete_mockup/list_mockups save self-contained HTML/CSS designs; preview_mockup renders one and captures desktop/tablet/mobile screenshots in a single call.
  • VS Code side, no Claude required. A status bar button (AEye Browser) opens a quick-pick menu for everything below:
    • AEye Browser: Open Configuration — edit config.json (base URL/viewport/headless), manage test users and mockups.
    • AEye Browser: Browse Tests — see every test's last pass/fail status, run one yourself with a click (via its own, separate browser profile so it can't collide with a Claude-driven session), open its report or notes file, delete it.
    • AEye Browser: Open Latest Report / Set Up Workspace / Configure MCP Server / About.

Architecture

Two OS processes, one npm project:

  • VS Code extension host (src/extension.ts, src/commands/*) — command registration, the status bar item, and the webview panels. Deliberately never imports Playwright (it's a heavy, native-binary-having dependency) except lazily inside the Tests panel's Run handler (dynamic import(), loaded only the first time Run is actually clicked, so normal extension activation stays fast).
  • Standalone MCP server (src/mcp/server.ts, run via node out/mcp/server.js, spawned by the claude CLI per the workspace's .mcp.json) — owns the persistent Playwright browser and exposes all the MCP tools for the life of a Claude Code session.
src/
  extension.ts              activation: command registration, status bar item
  commands/                 VS Code-side only — no Playwright (except one lazy import)
    setupWorkspace.ts       scaffolds AEyeBrowser/ in the target workspace, installs Chromium
    configureMcp.ts         writes/merges the workspace .mcp.json
    openLatestReport.ts     opens the newest HTML report externally
    openConfigPanel.ts      webview: settings + test users + mockups (create/edit/delete)
    openTestsPanel.ts       webview: browse tests, run one (separate browser profile), status
    showMenu.ts             status bar quick-pick menu
    showAbout.ts            webview: about/use-cases/links
  mcp/
    server.ts               MCP entry point (stdio transport), registers all tools
    browserManager.ts        Playwright lifecycle: persistent context, navigation, screenshots,
                             console/response capture, a11y/SEO wrappers
    testRunner.ts            executes a TestCase's steps against the shared page
    reportGenerator.ts       self-contained HTML report generation (also exports describeStep)
    testSchema.ts            TestCase/TestStep/TestRunResult types + slugify + stepSelector
    testStore.ts             pure fs/path: read/scan JSON test-case files
    testStatusStore.ts       pure fs/path: last pass/fail status per test
    testTextExport.ts        pure fs/path: plain-text companion file for each test
    userStore.ts             pure fs/path: users.local.json (test-user profiles)
    configStore.ts           pure fs/path: config.json (baseUrl/viewport/headless)
    mockupStore.ts           pure fs/path: mockup HTML files
    accessibilityRunner.ts   axe-core injection + scan
    seoAuditor.ts            in-page DOM/head technical SEO checks
    consoleStore.ts / headerStore.ts   bounded ring buffers for console messages / response headers
    tools/                  one file per MCP tool group, each `registerXTools(server, ...)`
      navigation.ts          navigate, get_dom, get_cookies, get_headers
      interaction.ts         click, fill, evaluate, screenshot
      testing.ts             create/update/delete/list/run_test, run_all_tests, run_test_as_users
      analysis.ts            check_accessibility, check_seo
      users.ts               create/update/delete/list_user
      mockups.ts              create/update/delete/list_mockup, preview_mockup

The mcp/*Store.ts modules are pure fs/path (no playwright, no vscode), which is what lets both the MCP server and the VS Code extension host safely read/write the same config.json/users.local.json/test files without either one depending on the other's heavy runtime.

Notable design decisions / gotchas

  • zod must be imported from "zod/v3", never bare "zod". The MCP SDK's dual v3/v4 zod-compat layer causes TypeScript to blow the heap (JavaScript heap out of memory) on a bare "zod" import, via a runaway structural-type comparison. Every tool schema file already follows this; keep doing so in any new one.
  • A single Page reliably delivers exactly one click/keyboard-triggered navigation. A second real navigation-triggering action (e.g. a second form submit) on the same Page object can be silently swallowed by Chromium — no error, no request even sent — even though the DOM looks identical. BrowserManager.resetPage()/resetPageKeepingUrl() work around this by giving login/logout steps (and the start of every runTest() call) a fresh Page on the same persistent context (cookies/session survive). Confirmed via a bare-Playwright reproduction with zero of this project's code involved, so it's a Chromium/Playwright characteristic, not a bug to "fix" upstream.
  • The Tests panel's Run button uses a separate browser profile (AEyeBrowser/.profile-panel, vs. Claude's AEyeBrowser/.profile). Two processes pointing launchPersistentContext at the same profile directory would fight over Chromium's SingletonLock; a dedicated profile lets a panel-triggered run and a Claude-triggered session coexist safely.
  • VS Code webviews use --vscode-* theme CSS variables (button/input/panel/foreground colors, with hardcoded fallbacks) instead of a fixed palette, so the panels look native in both light and dark themes rather than a hardcoded light UI dropped into a dark editor.

Requirements

  • Node.js >= 18
  • VS Code >= 1.90
  • Windows/macOS/Linux (Playwright installs its own Chromium; see below)

Compiling the code

npm install
npm run compile      # tsc -p . -> out/
npm run watch         # tsc -w -p ., for iterative development

out/mcp/server.js is what actually runs as the standalone MCP server (via node), so it must exist and be current — npm run compile builds both it and the extension host code (out/extension.js) from the same tsc invocation.

Running / testing the extension

There's no automated unit-test suite in this repo (no npm test script) — verification throughout development has been:

  1. Manual, in the real Extension Development Host. Launch it either by pressing F5 in VS Code with this folder open, or from a terminal:

    code --new-window --extensionDevelopmentPath="C:/Dev/AEyeBrowser" "<path-to-a-test-workspace>"
    

    In that window, run AEye Browser: Set Up Workspace then AEye Browser: Configure MCP Server against a throwaway target workspace, then exercise the panels (Open Configuration, Browse Tests, About) and status bar menu directly.

  2. Direct MCP protocol smoke tests, bypassing VS Code entirely. Since the MCP server is just node out/mcp/server.js reading AEYEBROWSER_WORKSPACE_ROOT from its environment, you can drive it with the official SDK's client directly — this is the fastest way to test new/changed tools:

    import { Client } from "@modelcontextprotocol/sdk/client/index.js";
    import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
    
    const transport = new StdioClientTransport({
      command: "node",
      args: ["C:/Dev/AEyeBrowser/out/mcp/server.js"],
      env: { ...process.env, AEYEBROWSER_WORKSPACE_ROOT: "<path-to-a-scratch-workspace>" },
    });
    const client = new Client({ name: "smoke-test", version: "0.0.1" });
    await client.connect(transport);
    console.log(await client.callTool({ name: "navigate", arguments: { url: "https://example.com" } }));
    await client.close();
    

    The scratch workspace needs an AEyeBrowser/config.json ({"baseUrl": "...", "viewport": {"width":1280,"height":720}, "headless": false}) — everything else (tests/, reports/, .profile/, etc.) is created on demand.

  3. npm run compile itself is the first and cheapest check — a broken tool schema or a stray bare "zod" import will either fail to compile or (worse) hang/OOM tsc, which is itself a signal something's wrong (see the zod gotcha above).

Creating a deployable (.vsix)

npm run package     # vsce package

This runs @vscode/vsce (already a devDependency) and produces aeyebrowser-<version>.vsix in the repo root, using publisher/version/description etc. straight from package.json. .vscodeignore controls what actually ships inside it (source .ts, node_modules/.bin, and a few other dev-only paths are excluded; compiled out/ and runtime node_modules are included since the MCP server runs via node against the shipped node_modules, not a bundled single file).

To try the packaged extension for real:

code --install-extension aeyebrowser-<version>.vsix

To publish it to the Marketplace (requires a Personal Access Token for the AesepusTechnology publisher):

npx vsce login AesepusTechnology
npx vsce publish
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft