From 99024093ddb7c60526250a893cf7b8dcde9c8698 Mon Sep 17 00:00:00 2001 From: WilcoLouwerse Date: Tue, 8 Sep 2026 20:01:53 +0200 Subject: [PATCH 1/2] docs(playwright): browser-1 by default, seven-browser pool opt-in on one shared server Companion to ConductionNL/hydra "feat(mcp): browser-1 by default, seven-browser pool opt-in on one shared server". Claude Code starts every stdio MCP server in .mcp.json at session start; seven per session is how a 16 GB WSL VM ran out of memory on 2026-09-08 with 98 idle Playwright processes and zero browsers open. - playwright-setup.md rewritten around the new layout: one browser-1 in the project .mcp.json, the pool under hydra/.claude/mcp/, one shared @playwright/mcp on localhost:8931 referenced by http URLs (zero processes per session), user-scope registration for VS Code (which cannot take --mcp-config), and the headed browser-6 kept as stdio. The old "CLI alternative" with seven ports is superseded by the shared server. - examples/.mcp.json.example is now browser-1 only; examples/browser-pool-shared.json.example is the opt-in pool. - README.md, testing.md, global-claude-settings.md and workstation-setup.md point at the same facts instead of describing .mcp.json as the 7-browser file. Co-Authored-By: Claude Fable 5.1 --- docs/claude/README.md | 11 +- docs/claude/examples/.mcp.json.example | 24 --- .../examples/browser-pool-shared.json.example | 14 ++ docs/claude/global-claude-settings.md | 2 +- docs/claude/playwright-setup.md | 185 +++++++----------- docs/claude/testing.md | 2 +- docs/claude/workstation-setup.md | 12 ++ 7 files changed, 101 insertions(+), 149 deletions(-) create mode 100644 docs/claude/examples/browser-pool-shared.json.example diff --git a/docs/claude/README.md b/docs/claude/README.md index 0c3905f15..9d43d9893 100644 --- a/docs/claude/README.md +++ b/docs/claude/README.md @@ -114,7 +114,7 @@ How to run Claude Code with a local Qwen model via Ollama for privacy, cost redu ### [Playwright MCP Browser Setup](./playwright-setup.md) -Detailed setup guide for the 7 independent Playwright browser sessions used for parallel testing, including VS Code extension configuration, CLI alternatives, and usage rules. +Setup guide for the Playwright MCP browsers: `browser-1` by default, the opt-in seven-browser pool on one shared server for parallel testing, VS Code user-scope registration, verification and usage rules. ### [Usage Tracker](../../usage-tracker/README.md) @@ -440,7 +440,7 @@ cp docs/claude/examples/CLAUDE.local.md.example .claude/CLAUDE.local.md ## Playwright MCP Browser Setup -The workspace uses 7 independent Playwright browser sessions for parallel testing. Copy the [example .mcp.json](./examples/.mcp.json.example) to your project root as `.mcp.json`, or see the [playwright-setup.md](./playwright-setup.md) guide for the full configuration, verification steps, CLI alternatives, and usage rules. +Every project ships **one** headless browser (`browser-1`) in its root `.mcp.json` — copy the [example .mcp.json](./examples/.mcp.json.example). The seven-browser pool for parallel agents is opt-in: one shared `@playwright/mcp` server on `localhost:8931`, referenced by URL, so a pool costs zero processes per session ([example](./examples/browser-pool-shared.json.example)). Claude Code starts every stdio server in `.mcp.json` at session start; seven per session is how WSL ran out of memory on 2026-09-08. See [playwright-setup.md](./playwright-setup.md) for the shared server, the user-scope registration for VS Code, verification steps and usage rules. **Quick summary:** @@ -491,7 +491,8 @@ This repo contains **documentation**, **global settings**, and **project templat │ ├── retrofit.md # Legacy app retrofit playbook │ └── examples/ # Project-level template files │ ├── CLAUDE.local.md.example # Template for project .claude/CLAUDE.local.md -│ └── .mcp.json.example # Template for project root .mcp.json (7 browsers) +│ ├── .mcp.json.example # Template for project root .mcp.json (browser-1 only) +│ └── browser-pool-shared.json.example # Opt-in 7-browser pool pointing at the shared server │ ├── global-settings/ # Mandatory user-level settings for ~/.claude/ │ ├── settings.json # → ~/.claude/settings.json (global read-only policy) @@ -511,7 +512,7 @@ Each Conduction project (Nextcloud apps, WordPress sites, etc.) has its own `.cl ``` / -├── .mcp.json # Playwright browser MCP servers (see docs/claude/examples/.mcp.json.example) +├── .mcp.json # Playwright browser-1 (see docs/claude/examples/.mcp.json.example); pools live in .claude/mcp/ │ └── .claude/ ├── CLAUDE.md # Workflow rules, project context @@ -647,6 +648,8 @@ npx -y @playwright/mcp@latest --headless --isolated --port 9999 # Should print: Listening on http://localhost:9999 ``` +If the pool entries (`browser-2`…) fail while `browser-1` works, the shared server is not running: `scripts/playwright-mcp-server.sh status` in the hydra checkout. + ### Claude Code doesn't see commands Ensure `.claude/` is at the workspace root and Claude Code is started from that directory. diff --git a/docs/claude/examples/.mcp.json.example b/docs/claude/examples/.mcp.json.example index 3ee23759d..7e0a3ba22 100644 --- a/docs/claude/examples/.mcp.json.example +++ b/docs/claude/examples/.mcp.json.example @@ -3,30 +3,6 @@ "browser-1": { "command": "npx", "args": ["-y", "@playwright/mcp@latest", "--browser", "chromium", "--headless", "--isolated"] - }, - "browser-2": { - "command": "npx", - "args": ["-y", "@playwright/mcp@latest", "--browser", "chromium", "--headless", "--isolated"] - }, - "browser-3": { - "command": "npx", - "args": ["-y", "@playwright/mcp@latest", "--browser", "chromium", "--headless", "--isolated"] - }, - "browser-4": { - "command": "npx", - "args": ["-y", "@playwright/mcp@latest", "--browser", "chromium", "--headless", "--isolated"] - }, - "browser-5": { - "command": "npx", - "args": ["-y", "@playwright/mcp@latest", "--browser", "chromium", "--headless", "--isolated"] - }, - "browser-6": { - "command": "npx", - "args": ["-y", "@playwright/mcp@latest", "--browser", "chromium", "--isolated"] - }, - "browser-7": { - "command": "npx", - "args": ["-y", "@playwright/mcp@latest", "--browser", "chromium", "--headless", "--isolated"] } } } diff --git a/docs/claude/examples/browser-pool-shared.json.example b/docs/claude/examples/browser-pool-shared.json.example new file mode 100644 index 000000000..9d78f5480 --- /dev/null +++ b/docs/claude/examples/browser-pool-shared.json.example @@ -0,0 +1,14 @@ +{ + "mcpServers": { + "browser-1": { "type": "http", "url": "http://localhost:8931/mcp" }, + "browser-2": { "type": "http", "url": "http://localhost:8931/mcp" }, + "browser-3": { "type": "http", "url": "http://localhost:8931/mcp" }, + "browser-4": { "type": "http", "url": "http://localhost:8931/mcp" }, + "browser-5": { "type": "http", "url": "http://localhost:8931/mcp" }, + "browser-6": { + "command": "npx", + "args": ["-y", "@playwright/mcp@latest", "--browser", "chromium", "--isolated"] + }, + "browser-7": { "type": "http", "url": "http://localhost:8931/mcp" } + } +} diff --git a/docs/claude/global-claude-settings.md b/docs/claude/global-claude-settings.md index 46ce6c34b..da14cb639 100644 --- a/docs/claude/global-claude-settings.md +++ b/docs/claude/global-claude-settings.md @@ -283,7 +283,7 @@ Restart Claude Code or run `/hooks`. From then on your hooks fire alongside the `settings.json` does not read an `mcpServers` key ([Claude Code docs](https://code.claude.com/docs/en/debug-your-config#check-common-causes)), so MCP servers are **not** part of the global settings. Versions up to 2.4.0 shipped a dead `mcpServers` block with 7 Playwright browsers; it never loaded anything and was removed in 2.4.1. Configure MCP servers at one of the two supported scopes instead: -- **Project scope** — `.mcp.json` at the repository root, committed so the whole team gets the same servers. Hydra ships one with the 7-browser pool; a workspace that symlinks Hydra's `.claude/skills` symlinks its `.mcp.json` the same way. See [playwright-setup.md](playwright-setup.md). +- **Project scope** — `.mcp.json` at the repository root, committed so the whole team gets the same servers. Hydra ships one with `browser-1` only; the seven-browser pool is opt-in under `.claude/mcp/` (shared server, URL entries). A workspace that symlinks Hydra's `.claude/skills` symlinks `.mcp.json` and `.claude/mcp` the same way. See [playwright-setup.md](playwright-setup.md). - **User scope** — `claude mcp add --scope user …`, stored in `~/.claude.json` and loaded in every project on your machine. See [playwright-setup.md → User scope](playwright-setup.md#user-scope-all-projects-on-this-machine). When both define the same server name, the project-scope entry wins. diff --git a/docs/claude/playwright-setup.md b/docs/claude/playwright-setup.md index 7c6f2755c..78417f8df 100644 --- a/docs/claude/playwright-setup.md +++ b/docs/claude/playwright-setup.md @@ -1,165 +1,112 @@ # Playwright MCP Browser Setup -Each project workspace configures its own Playwright MCP browser sessions in a `.mcp.json` file at the project root. The Nextcloud workspace uses 7 browsers; other workspaces may use fewer depending on the parallelism their tests demand. An [example .mcp.json](./examples/.mcp.json.example) with the 7-browser configuration is available as a starting point. +Claude Code drives browsers through [`@playwright/mcp`](https://github.com/microsoft/playwright-mcp). Two things matter for how it is configured: -Hydra ships this file at its repository root (`hydra/.mcp.json`). A workspace that symlinks Hydra's `.claude/skills` should symlink `.mcp.json` the same way, so the browser pool always travels with the skills that depend on it: +1. **Claude Code starts every stdio MCP server in `.mcp.json` at session start**, whether or not the session ever touches a browser. A server costs ~60 MB idle (node + the `npm exec` wrapper); the browser itself is only launched on first use. +2. **A Playwright MCP server on a port serves many clients.** Every connection gets its own session and its own isolated browser context, so parallel agents stay separated exactly as they would with one process each. -```bash -ln -sfn /path/to/hydra/.mcp.json /path/to/workspace/.mcp.json -``` - -Do **not** put `mcpServers` in `~/.claude/settings.json` — Claude Code ignores that key there ([docs](https://code.claude.com/docs/en/debug-your-config#check-common-causes)). +So the setup is: one browser per project by default, and the seven-browser pool as an opt-in that points at a single shared server. -## Browser Pool (Nextcloud workspace) - -| Server | Mode | Purpose | -| ----------- | ---------- | --------------------------------- | -| `browser-1` | Headless | Main agent (default) | -| `browser-2` | Headless | Sub-agent / parallel | -| `browser-3` | Headless | Sub-agent / parallel | -| `browser-4` | Headless | Sub-agent / parallel | -| `browser-5` | Headless | Sub-agent / parallel | -| `browser-6` | **Headed** | User observation (visible window) | -| `browser-7` | Headless | Sub-agent / parallel | +> Background: on 2026-09-08 Hydra shipped the seven-browser pool as its root `.mcp.json` ([hydra#651](https://github.com/ConductionNL/hydra/pull/651)). Fourteen open Claude Code sessions then held 98 idle MCP processes and ~6 GB, and WSL ran out of memory. Hydra reverted to `browser-1` only and moved the pool to `.claude/mcp/`. -## VS Code Extension Setup +## Default: `browser-1` in `.mcp.json` -The VS Code extension loads MCP servers from `.mcp.json` in the **project root** (this file lives in each project repo, not in the `.github` documentation repo). The file defines 7 browser instances. Browsers 1–5 and 7 are headless; browser-6 is headed (omits `--headless`) so the browser window is visible when you want to watch: +Each project ships a `.mcp.json` at its root with a single headless browser. Copy the [example .mcp.json](./examples/.mcp.json.example): ```json { "mcpServers": { "browser-1": { "command": "npx", - "args": [ - "-y", - "@playwright/mcp@latest", - "--browser", - "chromium", - "--headless", - "--isolated" - ] - }, - "browser-2": { - "command": "npx", - "args": [ - "-y", - "@playwright/mcp@latest", - "--browser", - "chromium", - "--headless", - "--isolated" - ] - }, - "browser-3": { - "command": "npx", - "args": [ - "-y", - "@playwright/mcp@latest", - "--browser", - "chromium", - "--headless", - "--isolated" - ] - }, - "browser-4": { - "command": "npx", - "args": [ - "-y", - "@playwright/mcp@latest", - "--browser", - "chromium", - "--headless", - "--isolated" - ] - }, - "browser-5": { - "command": "npx", - "args": [ - "-y", - "@playwright/mcp@latest", - "--browser", - "chromium", - "--headless", - "--isolated" - ] - }, - "browser-6": { - "command": "npx", - "args": [ - "-y", - "@playwright/mcp@latest", - "--browser", - "chromium", - "--isolated" - ] - }, - "browser-7": { - "command": "npx", - "args": [ - "-y", - "@playwright/mcp@latest", - "--browser", - "chromium", - "--headless", - "--isolated" - ] + "args": ["-y", "@playwright/mcp@latest", "--browser", "chromium", "--headless", "--isolated"] } } } ``` -Project servers from `.mcp.json` need a one-time approval per workspace: accept the workspace-trust dialog when Claude Code first opens the folder, then approve the servers from `/mcp` if prompted. That is all — **no pre-approval settings are required**: +Hydra ships this file at its repository root (`hydra/.mcp.json`) and the pools under `hydra/.claude/mcp/`. A workspace that symlinks Hydra's `.claude/skills` should symlink both, so the browsers travel with the skills that depend on them: + +```bash +ln -sfn /path/to/hydra/.mcp.json /path/to/workspace/.mcp.json +ln -sfn /path/to/hydra/.claude/mcp /path/to/workspace/.claude/mcp +``` + +Do **not** put `mcpServers` in `~/.claude/settings.json` — Claude Code ignores that key there ([docs](https://code.claude.com/docs/en/debug-your-config#check-common-causes)). + +Project servers from `.mcp.json` need a one-time approval per workspace: accept the workspace-trust dialog when Claude Code first opens the folder, then approve the server from `/mcp` if prompted. No pre-approval settings are required: - `enableAllProjectMcpServers` only skips that one prompt. Hydra deliberately does not commit `.claude/settings.json` (it is machine-specific, see its `.gitignore`), and Claude Code ignores committed approvals in an untrusted folder anyway ([docs](https://code.claude.com/docs/en/mcp#project-server-approvals-and-workspace-trust)). -- An `mcp__browser-*` allow-list is not needed for parallel sub-agents (`/test-app` Full mode, `/test-counsel`): background subagents surface their permission prompts in the main session, and in auto mode the classifier evaluates their tool calls with the same rules as the main conversation ([subagent permissions](https://code.claude.com/docs/en/sub-agents)). Earlier versions of this page claimed sub-agents were "silently denied" without it; that is no longer how Claude Code behaves. +- An `mcp__browser-*` allow-list is not needed for parallel sub-agents (`/test-app` Full mode, `/test-counsel`): background subagents surface their permission prompts in the main session, and in auto mode the classifier evaluates their tool calls with the same rules as the main conversation ([subagent permissions](https://code.claude.com/docs/en/sub-agents)). Then **reload the VS Code window**: `Ctrl+Shift+P` → type `reload window` → Enter. -## Verification +## Browser pool (parallel agents) -After reload, open the MCP servers panel to verify all 7 browsers show **Connected**. You can do this two ways: +The skills that fan out — `/test-app` Full mode, `/test-counsel`, `opsx-pipeline` — assign one browser per agent: -- Type `/MCP servers` in the Claude Code chat input -- Or `Ctrl+Shift+P` → search **"MCP servers"** +| Server | Mode | Purpose | +| ----------- | ---------- | --------------------------------- | +| `browser-1` | Headless | Main agent (default) | +| `browser-2` | Headless | Sub-agent / parallel | +| `browser-3` | Headless | Sub-agent / parallel | +| `browser-4` | Headless | Sub-agent / parallel | +| `browser-5` | Headless | Sub-agent / parallel | +| `browser-6` | **Headed** | User observation (visible window) | +| `browser-7` | Headless | Sub-agent / parallel | + +The names are stable; only where the processes come from changed. Hydra keeps two pool files under `.claude/mcp/`: -![MCP servers panel showing all 7 browser instances connected](./img/mcp-servers-connected.png) +| File | Shape | When | +| ---- | ----- | ---- | +| `browser-pool-shared.json` | `browser-1`…`browser-5` and `browser-7` are `{"type": "http", "url": "http://localhost:8931/mcp"}`; `browser-6` stays a headed stdio entry | **Recommended.** Zero processes per session; needs the shared server (below) | +| `browser-pool.json` | seven stdio servers | No background process, 7 processes per session. Fallback when the shared server is not installed | -If any server shows an error, check the output panel: `Ctrl+Shift+P` → **"Output: Focus on Output"** → select **"Claude VSCode"** from the dropdown. +An [example of the shared pool](./examples/browser-pool-shared.json.example) is in this repo. Load a pool for one terminal session: -## User scope (all projects on this machine) +```bash +claude --mcp-config .claude/mcp/browser-pool-shared.json +``` -To have the browser pool in every project on your machine — including repositories that do not ship a `.mcp.json` — register the servers at user scope. They are stored in `~/.claude.json` and load in every project. Run once: +### The shared server + +Hydra's `scripts/playwright-mcp-server.sh` runs one `@playwright/mcp` process on `localhost:8931` (headless, isolated). Install it once as a systemd user unit so it starts with your WSL session: ```bash -for i in 1 2 3 4 5 7; do - claude mcp add --scope user "browser-$i" -- npx -y @playwright/mcp@latest --browser chromium --headless --isolated -done -claude mcp add --scope user browser-6 -- npx -y @playwright/mcp@latest --browser chromium --isolated # headed +cd /path/to/hydra +scripts/playwright-mcp-server.sh install-service +scripts/playwright-mcp-server.sh status ``` -Verify with `claude mcp list`. A project `.mcp.json` that defines the same server name takes precedence over the user-scope entry, so both can coexist. Remove one with `claude mcp remove --scope user browser-N`. +`start` / `stop` / `restart` / `logs` / `uninstall-service` do what they say; `PLAYWRIGHT_MCP_PORT` changes the port (keep the pool file in sync). The unit pins the `npx` it finds at install time, because a user unit does not load nvm. The headed `browser-6` is deliberately not served by it: a systemd user unit has no WSLg display, and observation browsers are rare enough that a per-session stdio entry is fine. -## CLI Alternative (terminal only) +Two concurrent MCP sessions against one server were verified to get distinct session ids and separate Chromium processes, so the isolation the numbered browsers promise still holds. -For the Claude Code CLI (`claude` terminal command, not VS Code), you can start servers as HTTP endpoints on fixed ports and reference them via URL: +### The pool in VS Code -```bash -# Start headless browsers -for port in 9221 9222 9223 9224 9225 9227; do - npx -y @playwright/mcp@latest --headless --isolated --port $port & -done +The VS Code extension cannot take `--mcp-config`. Register the URL entries at user scope instead; a URL entry costs a connection, not a process, so this is free per session. The project `.mcp.json` keeps winning for `browser-1`: -# Start headed browser -npx -y @playwright/mcp@latest --isolated --port 9226 & +```bash +for i in 2 3 4 5 7; do claude mcp add --scope user --transport http "browser-$i" http://localhost:8931/mcp; done +claude mcp add --scope user browser-6 -- npx -y @playwright/mcp@latest --browser chromium --isolated # headed, on demand ``` -> This is **not needed for VS Code** — the extension manages server processes automatically via `.mcp.json`. Only use this approach if you're running `claude` from the terminal without VS Code. +Verify with `claude mcp list`. Remove one with `claude mcp remove --scope user browser-N`. If the shared server is down, these entries show as failed in `/mcp` and nothing else breaks. + +## Verification + +After reload, open the MCP servers panel and check that `browser-1` shows **Connected** (plus whatever pool entries you registered): + +- Type `/MCP servers` in the Claude Code chat input +- Or `Ctrl+Shift+P` → search **"MCP servers"** + +![MCP servers panel showing browser instances connected](./img/mcp-servers-connected.png) + +If a server shows an error, check the output panel: `Ctrl+Shift+P` → **"Output: Focus on Output"** → select **"Claude VSCode"** from the dropdown. For the shared server, `scripts/playwright-mcp-server.sh status` and `journalctl --user -u playwright-mcp.service` are the places to look. ## Usage Rules 1. **Default**: Use `browser-1` for normal work -2. **Parallel agents**: Assign sub-agents `browser-2` through `browser-5` and `browser-7` +2. **Parallel agents**: Assign sub-agents `browser-2` through `browser-5` and `browser-7` — and check they are actually loaded first; the pool is opt-in 3. **User watching**: Switch to `browser-6` when the user wants to observe 4. **Fallback**: If a browser errors, try the next numbered browser 5. **Keep `browser-6` reserved**: Only for explicit user observation diff --git a/docs/claude/testing.md b/docs/claude/testing.md index b150f010d..3dc770398 100644 --- a/docs/claude/testing.md +++ b/docs/claude/testing.md @@ -393,4 +393,4 @@ Ensure Docker is running and Nextcloud is accessible before testing. See [docker **Rule:** Single agent = `browser-1`. Parallel agents = each gets a distinct browser (`browser-2`, `browser-3`, `browser-4`, …) to avoid session conflicts. -For browser pool configuration, verification steps, and `.mcp.json` setup, see [playwright-setup.md](playwright-setup.md). +The default `.mcp.json` ships only `browser-1`; the parallel rows above need the opt-in pool (one shared server, URL entries). For configuration, verification and setup, see [playwright-setup.md](playwright-setup.md). diff --git a/docs/claude/workstation-setup.md b/docs/claude/workstation-setup.md index a40c05ae5..96234a807 100644 --- a/docs/claude/workstation-setup.md +++ b/docs/claude/workstation-setup.md @@ -292,6 +292,18 @@ npx playwright install chromium > If the MCP server reports a different revision is needed (e.g. after a `@playwright/mcp` update), run the install from the npx cache that the MCP server uses. You can find it at `~/.npm/_npx/` — look for the directory containing `@playwright/mcp`. +### Shared Playwright MCP server (recommended) + +Projects ship only `browser-1` in `.mcp.json`. The parallel-testing pool (`browser-2`…`browser-7`) points at one shared server, so it costs no processes per session. Install it once from the hydra checkout; it runs as a systemd user unit and starts with your WSL session: + +```bash +cd ~/hydra +scripts/playwright-mcp-server.sh install-service +for i in 2 3 4 5 7; do claude mcp add --scope user --transport http "browser-$i" http://localhost:8931/mcp; done +``` + +See [playwright-setup.md](./playwright-setup.md) for the why and the fallbacks. + ### OpenSpec CLI Used by all `/opsx-*` commands for spec-driven development: From 09dea59601d088a3410cccda263ac305fc331ba4 Mon Sep 17 00:00:00 2001 From: WilcoLouwerse Date: Fri, 11 Sep 2026 11:18:04 +0200 Subject: [PATCH 2/2] docs(playwright): address review findings on #745 - global-claude-settings.md:287 linked playwright-setup.md#user-scope-all-projects-on-this-machine, a heading this PR's own rewrite removed. Point it at "The pool in VS Code", which is where user-scope registration now lives. - Say that the shared server resolves @playwright/mcp@latest once, at start, so a long-running unit keeps that build until restarted. That is a real change from the per-session stdio model, where every session re-resolved @latest. - The `claude --mcp-config` snippet appears before the section that explains how to get the server running; make the dependency explicit in the snippet itself. Three stale references outside the original diff, each contradicting what this PR establishes: - docs/claude/README.md:245 listed browser-1 through browser-7 as available discovery tooling, contradicting the same file at line 442. - docs/iso/code.md:468 stated "7 Playwright MCP browser sessions" as standing ICT infrastructure in a compliance document. - docs/claude/commands-tender.md:90 described /ecosystem-investigate as using browsers 1-5 with no note that the pool is now opt-in. Co-Authored-By: Claude Opus 5 (1M context) --- docs/claude/README.md | 2 +- docs/claude/commands-tender.md | 2 +- docs/claude/global-claude-settings.md | 2 +- docs/claude/playwright-setup.md | 3 ++- docs/iso/code.md | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/claude/README.md b/docs/claude/README.md index 9d43d9893..aa2173891 100644 --- a/docs/claude/README.md +++ b/docs/claude/README.md @@ -242,7 +242,7 @@ Collect requirements, study existing solutions, and identify what to build. Clau | Source | How | Commands / Tools | | ---------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | | **Tracking issues** | Sync and analyze open issues from project repos (GitHub; `tea` only for non-Conduction Forgejo repos) | `/swc-update`, `gh issue list`, `tea issues list` | -| **Other applications** | Crawl code or browse running apps to understand patterns | `/opsx-explore`, Playwright browsers (`browser-1`–`browser-7`) | +| **Other applications** | Crawl code or browse running apps to understand patterns | `/opsx-explore`, Playwright browsers (`browser-1`; `browser-2`–`browser-7` opt-in) | | **Documentation** | Read docs from other platforms, APIs, standards | `WebFetch`, `WebSearch`, `/opsx-explore` | | **Tenders** | Scrape TenderNed, classify by category, analyze requirements and ecosystem gaps | `/tender-scan`, `/tender-status`, `/tender-gap-report`, `/ecosystem-investigate`, `Read` (PDF support) | | **App store scouting** | Spot interesting apps on WordPress plugin directory, GitHub/Codeberg trending, ArtifactHub, Nextcloud app store | `WebSearch`, `WebFetch`, Playwright browsers | diff --git a/docs/claude/commands-tender.md b/docs/claude/commands-tender.md index 87c5a116a..fc72bb199 100644 --- a/docs/claude/commands-tender.md +++ b/docs/claude/commands-tender.md @@ -87,7 +87,7 @@ Deep-dive research into a software category — find and analyze open-source com **What it does:** 1. Loads category context and related tenders from the intelligence database -2. Uses the browser pool (browser-1 through browser-5) to scrape 5-10 competitors from multiple source types +2. Uses the browser pool (browser-1 through browser-5) to scrape 5-10 competitors from multiple source types — the pool beyond `browser-1` is opt-in and needs the shared server, see [playwright-setup.md](playwright-setup.md) 3. Creates competitor profiles in `concurrentie-analyse/{category}/{competitor-slug}/` 4. Inserts competitors and feature data into the database with provenance tracking 5. Presents a comparison table and recommendation for Nextcloud ecosystem fit diff --git a/docs/claude/global-claude-settings.md b/docs/claude/global-claude-settings.md index da14cb639..5d67d3391 100644 --- a/docs/claude/global-claude-settings.md +++ b/docs/claude/global-claude-settings.md @@ -284,7 +284,7 @@ Restart Claude Code or run `/hooks`. From then on your hooks fire alongside the `settings.json` does not read an `mcpServers` key ([Claude Code docs](https://code.claude.com/docs/en/debug-your-config#check-common-causes)), so MCP servers are **not** part of the global settings. Versions up to 2.4.0 shipped a dead `mcpServers` block with 7 Playwright browsers; it never loaded anything and was removed in 2.4.1. Configure MCP servers at one of the two supported scopes instead: - **Project scope** — `.mcp.json` at the repository root, committed so the whole team gets the same servers. Hydra ships one with `browser-1` only; the seven-browser pool is opt-in under `.claude/mcp/` (shared server, URL entries). A workspace that symlinks Hydra's `.claude/skills` symlinks `.mcp.json` and `.claude/mcp` the same way. See [playwright-setup.md](playwright-setup.md). -- **User scope** — `claude mcp add --scope user …`, stored in `~/.claude.json` and loaded in every project on your machine. See [playwright-setup.md → User scope](playwright-setup.md#user-scope-all-projects-on-this-machine). +- **User scope** — `claude mcp add --scope user …`, stored in `~/.claude.json` and loaded in every project on your machine. See [playwright-setup.md → The pool in VS Code](playwright-setup.md#the-pool-in-vs-code). When both define the same server name, the project-scope entry wins. diff --git a/docs/claude/playwright-setup.md b/docs/claude/playwright-setup.md index 78417f8df..6219d282b 100644 --- a/docs/claude/playwright-setup.md +++ b/docs/claude/playwright-setup.md @@ -64,6 +64,7 @@ The names are stable; only where the processes come from changed. Hydra keeps tw An [example of the shared pool](./examples/browser-pool-shared.json.example) is in this repo. Load a pool for one terminal session: ```bash +# the shared server must be running first — see "The shared server" below claude --mcp-config .claude/mcp/browser-pool-shared.json ``` @@ -77,7 +78,7 @@ scripts/playwright-mcp-server.sh install-service scripts/playwright-mcp-server.sh status ``` -`start` / `stop` / `restart` / `logs` / `uninstall-service` do what they say; `PLAYWRIGHT_MCP_PORT` changes the port (keep the pool file in sync). The unit pins the `npx` it finds at install time, because a user unit does not load nvm. The headed `browser-6` is deliberately not served by it: a systemd user unit has no WSLg display, and observation browsers are rare enough that a per-session stdio entry is fine. +`start` / `stop` / `restart` / `logs` / `uninstall-service` do what they say; `PLAYWRIGHT_MCP_PORT` changes the port (keep the pool file in sync). The server resolves `@playwright/mcp@latest` once, when it starts, so a long-running unit keeps that build until you `restart` it — unlike the old per-session stdio model, where every new session re-resolved `@latest`. The unit pins the `npx` it finds at install time, because a user unit does not load nvm. The headed `browser-6` is deliberately not served by it: a systemd user unit has no WSLg display, and observation browsers are rare enough that a per-session stdio entry is fine. Two concurrent MCP sessions against one server were verified to get distinct session ids and separate Chromium processes, so the isolation the numbered browsers promise still holds. diff --git a/docs/iso/code.md b/docs/iso/code.md index 1e7681533..1feb70940 100644 --- a/docs/iso/code.md +++ b/docs/iso/code.md @@ -465,7 +465,7 @@ _What._ Determine and provide persons necessary. _What._ Determine, provide and maintain infrastructure (buildings, equipment, ICT, transport). -**Our implementation.** ICT infrastructure: GitHub (code + CI + issues + PRs), Cyso hosting (production, ISAE 3402), Docker Compose (dev/test), 7 Playwright MCP browser sessions (browser-1 … browser-7), Ollama + Qwen 3.5 for local LLM inference. Documented in CLAUDE.md and [.github/docs/claude/](../claude/). +**Our implementation.** ICT infrastructure: GitHub (code + CI + issues + PRs), Cyso hosting (production, ISAE 3402), Docker Compose (dev/test), one shared Playwright MCP server serving up to 7 named browser sessions (browser-1 … browser-7; only browser-1 is configured by default), Ollama + Qwen 3.5 for local LLM inference. Documented in CLAUDE.md and [.github/docs/claude/](../claude/). **Coverage.** _Full._