Files
melabidi c37fb170ab
Tests / test (push) Failing after 5m3s
Tests / build-and-push-image (push) Has been skipped
Harden Docker and process safety guardrails.
Confine container ops to tracked IDs, tighten image/compose/volume checks, enforce binary allow-lists on background processes, and fix scoped npm docs lookup.
2026-07-31 16:59:46 -04:00

251 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# web-dev-mcp
An MCP (Model Context Protocol) server that gives AI coding agents a framework-aware toolkit for
web development: project/dependency workflow (install, dev server, lint, test, build), and
code/project scaffolding, with first-class support for **Laravel**, **CodeIgniter 4**,
**React**, **Vue**, and **Nuxt**, plus detection stubs for **Django**, **Rails**, and **Symfony**
— including combined backend+frontend setups.
See [`PLAN.md`](./PLAN.md) for the full design and roadmap. This README covers what's
implemented today and how to run it.
## Implementation status
Implemented **v1** (PLAN.md milestones 114) plus post-v1 **v1.1v1.5**:
- **Framework detection & adapters** — `detect_framework` auto-detects Laravel (Sail-aware), CodeIgniter 4,
Symfony, Django, Rails backends and React / Vue / Nuxt frontends, including a PHP/Python/Ruby
backend + separate frontend living side-by-side (`frontend/`, `client/`, `web/`).
- **Core workflow tools** — `detect_framework`, `detect_workspace` (monorepo package scan),
`run_install`, `run_script`, `start_dev_server` (Sail `up` when present), `stop_process`,
`get_process_logs`, `list_processes`, `run_lint`, `run_tests`, `build_project`,
`deploy_project` (opt-in `confirm: true`; optional `registryPush`). Most workflow tools accept
an optional `package` argument to scope to a monorepo package.
- **Scaffolding tools** — `scaffold_project` (vite-react, vite-vue, next, express-api,
static-html, laravel, codeigniter, laravel-react, codeigniter-react), `generate_component`
(React TSX/JSX or Vue SFC), `generate_api_route`, `add_dependency`.
- **Laravel tools** — `artisan` (allow-listed subcommands; destructive ones need `confirm: true`;
`queue:work`/`queue:listen`/`reverb:start` run as tracked background processes), `generate_laravel_resource`,
`generate_eloquent_relation`, `generate_filament_resource`, `generate_nova_resource`, `laravel_queue_status`,
`composer_require` / `composer_remove` (shared with CodeIgniter backends), `run_phpunit` /
`run_pest`, `laravel_tinker_eval` (write-looking expressions need `confirm: true`).
- **CodeIgniter tools** — `spark` (allow-listed subcommands; `migrate:refresh` needs
`confirm: true`), `spark_discover`, `generate_codeigniter_resource` (optional `apiVersion` /
ResourceController), `generate_codeigniter_shield_auth` (`confirm: true`), `run_codeigniter_tests`.
- **Django / Rails / Symfony** — `generate_django_resource`, `generate_rails_resource`,
`generate_symfony_resource` (file-based stubs).
- **React tools** — `generate_react_hook`, `add_react_route` (Next.js / react-router /
TanStack Router), `generate_next_page` / `generate_next_layout` (App Router), `run_react_tests`,
`analyze_react_component` (incl. missing `"use client"` / server→client prop heuristics).
`generate_component` supports `clientComponent: true`.
- **Browser tools** — `browser_navigate`, `browser_screenshot`, `browser_screenshot_baseline`,
`browser_visual_diff`, `browser_get_console_logs`, `browser_inspect_dom`, `browser_click`,
`browser_fill`, `browser_eval` (Playwright-backed; Chromium binaries via `npx playwright install chromium`).
- **Git helpers** — `git_status`, `git_diff`, `git_diff_summarize`, `git_log`, `git_branch` (create needs
`confirm: true`), `git_commit` (`confirm: true`; no amend/force/push).
- **Lighthouse audit** — `lighthouse_audit` (category details, opportunities, `failingByCategory`).
- **Prompts** — `new-feature`, `new-laravel-resource`, `new-codeigniter-resource`, `new-react-component`,
`visual-diff-ci`.
- **Docker tools** — `docker_build_image`, `docker_run_container` (with workspace-confined volume
mounts, image allow-list, and resource limits), `docker_list_containers`, `docker_get_container_logs`,
`docker_exec`, `docker_stop_container`, `docker_remove_container`, `docker_compose_up`,
`docker_compose_down`, `generate_dockerfile`, `generate_compose`, `generate_sail` (`confirm: true`),
`docker_push_image` (`confirm: true`).
- **Docs & package lookup** — `search_package_docs` (npm README via unpkg, Composer metadata via
Packagist), `search_mdn`, `search_laravel_docs`, `search_codeigniter_docs`, `get_package_info`.
- **Resources & prompts** — `workspace://project.json`, `workspace://logs/{processId}`,
`workspace://containers/{containerId}/logs`, and reusable prompts `new-feature`,
`new-laravel-resource`, `new-codeigniter-resource`, `new-react-component`.
- **Safety** — every filesystem path is confined to `WORKSPACE_ROOT`
(`src/lib/sandbox.ts`), spawned binaries are restricted to an allow-list, and
destructive ops (`deploy_project`, `composer_remove`, `migrate:fresh`, `migrate:refresh`,
`git_commit`, …) require an explicit `confirm: true`. Docker containers are tracked and
force-removed on server shutdown.
- **Both transports work today**: stdio (for Cursor/Claude Desktop) and Streamable HTTP (for
remote/shared use), sharing one `createServer()` implementation. The HTTP transport includes
bearer-token auth and a production-ready `Dockerfile`.
- **Automated test suite** — Vitest tests for sandbox/path confinement, binary allow-list,
process management, Laravel/CodeIgniter subcommand allow-lists, destructive-command `confirm: true`
enforcement, Docker guardrails, framework detection, baselines/visual diff, and Lighthouse parsing.
- **Distribution-ready** — install via `npx web-dev-mcp` or add to your MCP client config.
Post-v1 roadmap (see `PLAN.md` §9): **v1.4** Vue/Nuxt adapters, **v1.5** Sail/polish.
## Requirements
- Node.js >= 22 (developed/tested on Node 24)
- For Laravel/CodeIgniter tools: PHP + Composer on `PATH`
- For scaffolding Laravel/CodeIgniter projects: Composer on `PATH`
- For browser tools: `npx playwright install chromium` (run once after `npm install`)
- For Docker tools: Docker Engine (Docker Desktop or `dockerd`) running and accessible to the current user
- For `lighthouse_audit`: Chrome/Chromium available (Lighthouse is pulled via `npx` on demand)
- For git tools: `git` on `PATH` and a git workspace under `WORKSPACE_ROOT`
## Setup
```bash
npm install
npm run build
```
## Running tests
```bash
npm run test
```
## Running
**stdio** (what Cursor/Claude Desktop use):
```bash
npm run dev # ts-node/tsx, no build step needed
# or, after `npm run build`:
npm start
```
**Streamable HTTP** (remote/shared use):
```bash
npm run build
npm run start:http
```
Environment variables:
| Variable | Default | Purpose |
|---|---|---|
| `WORKSPACE_ROOT` | current working directory | The project root every tool is confined to. |
| `MCP_HTTP_HOST` | `127.0.0.1` | Host the HTTP transport binds to. |
| `MCP_HTTP_PORT` | `3939` | Port the HTTP transport binds to. |
| `MCP_HTTP_TOKEN` | _(unset)_ | Bearer token required on `/mcp` when set. **Required** if binding to a non-localhost host. |
**Docker / containerization**:
```bash
docker build -t web-dev-mcp .
docker run -p 3939:3939 -e MCP_HTTP_TOKEN=change-me -v /path/to/project:/workspace web-dev-mcp
```
The image exposes the Streamable HTTP transport on port `3939` and uses `/workspace` as the confined `WORKSPACE_ROOT`. The `Dockerfile` uses a multi-stage build so the final image only contains production dependencies plus the compiled `dist/` directory.
## Using it from Cursor
Add to your MCP config (Cursor Settings → MCP, or `.cursor/mcp.json`):
```json
{
"mcpServers": {
"web-dev": {
"command": "node",
"args": ["/path/to/web-dev-mcp/dist/transports/stdio.js"],
"env": { "WORKSPACE_ROOT": "${workspaceFolder}" }
}
}
}
```
### Published npm package (recommended)
```json
{
"mcpServers": {
"web-dev": {
"command": "npx",
"args": ["-y", "web-dev-mcp"],
"env": { "WORKSPACE_ROOT": "${workspaceFolder}" }
}
}
}
```
### Claude Desktop config
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"web-dev": {
"command": "npx",
"args": ["-y", "web-dev-mcp"],
"env": { "WORKSPACE_ROOT": "/path/to/your/project" }
}
}
}
```
### Local checkout
```json
{
"mcpServers": {
"web-dev": {
"command": "node",
"args": ["/path/to/web-dev-mcp/dist/transports/stdio.js"],
"env": { "WORKSPACE_ROOT": "${workspaceFolder}" }
}
}
}
```
## Project layout
```
src/
config.ts # env vars, allow-lists, timeouts
server.ts # createServer(): registers all tools/resources
transports/
stdio.ts # stdio entrypoint (bin)
http.ts # Streamable HTTP entrypoint
lib/
logger.ts # stderr-only logging (stdout is reserved for JSON-RPC)
sandbox.ts # workspace path confinement + binary allow-list
runCommand.ts # foreground command execution with capped output
processManager.ts # tracks background processes (dev servers, backgrounded scripts)
strings.ts # pascal/camel/kebab-case helpers for codegen
frameworks/
types.ts # FrameworkAdapter interface
detect.ts # workspace inspection -> detected adapter(s)
resolve.ts # picks backend/frontend/primary adapter for a tool call
generic.ts, react.ts, vue.ts, djangoRailsSymfony.ts, laravel.ts, codeigniter.ts, phpBase.ts
packageManager.ts, composer.ts # npm/pnpm/yarn/bun and Composer helpers
tools/
shared.ts # zod schema + result helpers shared by tools
workflow/ # detect_framework, run_install, run_script, start_dev_server,
# stop_process, get_process_logs, list_processes, run_lint,
# run_tests, build_project, deploy_project
scaffold/ # scaffold_project (+ templates/), generate_component,
# generate_api_route, add_dependency
laravel/ # artisan, generate_laravel_resource, composer_require/remove,
# run_phpunit/run_pest, laravel_tinker_eval
codeigniter/ # spark, generate_codeigniter_resource, run_codeigniter_tests
react/ # generate_react_hook, add_react_route, run_react_tests,
# analyze_react_component
browser/ # browserManager, navigate, screenshot, consoleLogs,
# inspectDom, interact
docker/ # dockerManager, buildImage, runContainer, listContainers,
# containerLogs, exec, stopRemove, compose
docs/ # searchPackageDocs, searchMdn, searchLaravelDocs,
# searchCodeIgniterDocs, getPackageInfo
git/ # git_status, git_diff, git_log, git_branch, git_commit
audit/ # lighthouse_audit
resources/ # process/container log resources
prompts/ # new-feature / laravel / codeigniter / react prompts
```
Screenshot baselines for `browser_visual_diff` are stored under `.web-dev-mcp/baselines/` inside
the workspace (you may commit them for CI, or ignore them locally).
## Publishing
```bash
npm run build
npm run test
npm version <patch|minor|major>
npm publish
```
The package is published as `web-dev-mcp` and exposes `dist/transports/stdio.js` as the `bin` entry,
so `npx web-dev-mcp` launches the stdio transport directly.