# cypress-mcp

> MCP server for Cypress — let AI agents run tests, manage specs, snapshot pages, and automate browsers.

[![npm version](https://img.shields.io/npm/v/cypress-mcp)](https://www.npmjs.com/package/cypress-mcp)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Tested with Vitest](https://img.shields.io/badge/tested%20with-vitest-6e9f18)](https://vitest.dev)

---

## What is this?

`cypress-mcp` is a [Model Context Protocol](https://modelcontextprotocol.io) server that exposes Cypress as a set of AI-usable tools. Connect it to Claude, Cursor, VS Code, or any MCP client and let your AI assistant:

- **Run your Cypress tests** and get structured pass/fail results
- **Read and write spec files** — generate new tests from natural language
- **Snapshot any page** via the ARIA accessibility tree — no screenshots needed
- **Automate a browser** — navigate, click, type, evaluate JavaScript

Think of it as the Cypress equivalent of [`@playwright/mcp`](https://github.com/microsoft/playwright-mcp).

---

## How it works

```
Your AI (Claude / Cursor / VS Code)
        │
        │  MCP protocol (stdio or HTTP/SSE)
        ▼
   cypress-mcp server
        │
        ├── Spec tools ──────────► Filesystem (list / read / write .cy.ts files)
        ├── Runner tools ─────────► Cypress CLI (run tests, open GUI, get results)
        └── Browser tools ────────► Playwright-core (navigate, snapshot, screenshot)
```

Browser automation uses a separate Playwright-core instance — not the Cypress browser — keeping automation and testing concerns cleanly separated.

---

## Quick Start

### 1. Install browsers (one-time)

```bash
npx playwright install chromium
```

### 2. Connect to your MCP client

**Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
  "mcpServers": {
    "cypress": {
      "command": "npx",
      "args": ["cypress-mcp", "--project", "/path/to/your/app"]
    }
  }
}
```

**VS Code / Cursor** (HTTP/SSE mode):
```bash
npx cypress-mcp --port 8932 --project /path/to/your/app
```
Then point your MCP client at `http://localhost:8932/sse`.

### 3. Start asking your AI

```
> List the spec files in my project
> Navigate to http://localhost:3000/login and take a snapshot
> Write a Cypress test for the login form based on what you see
> Run the login spec and tell me what failed
```

---

## Tools

### Spec file tools
| Tool | Description |
|------|-------------|
| `cypress_list_specs` | List all spec files matching Cypress patterns |
| `cypress_read_spec` | Read a spec file's contents |
| `cypress_write_spec` | Create or overwrite a spec file |
| `cypress_get_config` | Read `cypress.config.ts/js` |

### Test runner tools
| Tool | Description |
|------|-------------|
| `cypress_run` | Run tests — returns pass/fail counts and error details |
| `cypress_open` | Open Cypress GUI |
| `cypress_get_last_run` | Read results from the last run |

### Browser automation tools
| Tool | Description |
|------|-------------|
| `cypress_navigate` | Navigate to a URL |
| `cypress_snapshot` | Get ARIA accessibility tree of the page |
| `cypress_screenshot` | Take a screenshot (full page or element) |
| `cypress_click` | Click an element by selector or text |
| `cypress_type` | Type into an input field |
| `cypress_evaluate` | Run JavaScript and return the result |
| `cypress_get_url` | Get the current URL |
| `cypress_wait_for` | Wait for an element or text to appear |
| `cypress_close_browser` | Close the automation browser |

---

## Example workflow

Here's what happens when you ask an AI to write tests for your app:

**1. Snapshot the page** — `cypress_navigate` + `cypress_snapshot`
```
Accessibility Snapshot:
- heading "My Todo List" [level=1]
- textbox "New todo"
- button "Add"
- list "Todo list"
  - listitem: No todos yet. Add one above!
```

**2. AI writes a spec** — `cypress_write_spec`
```typescript
describe('Todo App', () => {
  it('adds a new todo', () => {
    cy.visit('http://localhost:4000');
    cy.get('[aria-label="New todo"]').type('Buy groceries');
    cy.get('button').contains('Add').click();
    cy.get('#todo-list').should('contain', 'Buy groceries');
  });
});
```

**3. Run the tests** — `cypress_run`
```
✅ Cypress Run PASSED
Tests:    10
Passed:   10
Failed:   0
Duration: 3.21s
```

---

## CLI Options

```
cypress-mcp [options]

  --project <path>    Cypress project root (default: current directory)
  --port <number>     Start HTTP/SSE server instead of stdio
  --browser <name>    Browser for automation: chromium | firefox | webkit (default: chromium)
  --headed            Show the automation browser window
  --help              Show help
  --version           Show version
```

---

## Running Locally

```bash
git clone https://github.com/yashpreetbathla/cypress-mcp.git
cd cypress-mcp
npm install
npx playwright install chromium
npm run build
npm test
```

### Development mode
```bash
npm run dev        # TypeScript watch mode
npm test           # Run unit tests (Vitest)
npm run test:watch # Watch mode
```

---

## Requirements

| Requirement | Version |
|-------------|---------|
| Node.js | >= 18 |
| Cypress (in your project) | >= 12 |
| Chromium (for browser tools) | via `npx playwright install chromium` |

Cypress is a **peer dependency** — install it in your project, not globally. The MCP server picks it up automatically from `node_modules/.bin/cypress`.

---

## Architecture

```
cypress-mcp/
├── src/
│   ├── index.ts          CLI entry point
│   ├── server.ts         MCP server (stdio + HTTP/SSE transports)
│   ├── context.ts        Playwright-core browser context singleton
│   ├── toolHandler.ts    Central tool dispatcher
│   ├── tools/
│   │   ├── specs.ts      Spec file management (filesystem)
│   │   ├── runner.ts     Cypress test execution (CLI)
│   │   └── browser.ts    Browser automation (Playwright-core)
│   ├── types.ts          TypeScript interfaces
│   └── version.ts        Version constant
└── tests/
    └── unit/
        ├── specs.test.ts      13 tests for file tools
        ├── tools.test.ts       8 tests for tool definitions
        └── toolHandler.test.ts 4 tests for dispatch logic
```

### Why Playwright-core for browser automation?

Cypress is a testing framework — its browser isn't accessible as a real-time automation API. Rather than try to hack into the Cypress browser, `cypress-mcp` runs a lightweight separate Playwright-core instance for automation tasks (navigate, snapshot, screenshot). The Cypress browser is only used when running actual tests via `cypress_run`.

---

## Comparison with @playwright/mcp

| Feature | `cypress-mcp` | `@playwright/mcp` |
|---------|--------------|-------------------|
| Browser automation | ✅ (via Playwright-core) | ✅ (native) |
| Accessibility snapshot | ✅ ARIA tree | ✅ ARIA tree |
| Run existing tests | ✅ Cypress tests | ❌ |
| Write test files | ✅ `.cy.ts` / `.cy.js` | ❌ |
| Test results parsing | ✅ structured JSON | ❌ |
| Vision / coordinate tools | ❌ (coming) | ✅ |
| Best for | Teams using Cypress for E2E | General browser automation |

---

## Contributing

Issues and PRs welcome. Please open an issue before starting significant work.

```bash
npm test             # must pass
npm run build        # must compile cleanly
```

---

## License

MIT © [Yashpreet Bathla](https://github.com/yashpreetbathla)
