# Playwright MCP für Codex und Claude auf tnix Beide Agenten auf `tnix` erhalten den Playwright-MCP-Server standardmäßig, also ohne gesonderten Startbefehl. Grundlage ist das Paket `playwright-mcp` aus der über `flake.lock` gepinnten Nixpkgs-Revision, keine imperativ per `npx` installierte Abhängigkeit. Ein Versions-Guard im Modul verlangt **0.0.76**; bei einem Flake-Update bricht die Evaluierung ab, bis Version, Dokumentation und Smoke-Test bewusst nachgezogen wurden. Modul: `home/tnix/localModules/playwright-mcp.nix`. ## Wie beide Agenten den Server bekommen Keiner der beiden Agenten bekommt seine eigene Zustandsdatei von home-manager verwaltet: Codex schreibt selbst in `~/.codex/config.toml` (Trust-Level, Modell-Hinweise), Claude in `~/.claude.json`. Das Modul legt deshalb je eine eigene, ausschließlich deklarative Datei daneben und bindet sie über die Standardmechanismen der Agenten ein: | Agent | Datei aus dem Nix-Store | Einbindung | | ------ | -------------------------------- | ----------------------------- | | Codex | `~/.codex/playwright.config.toml` | `codex --profile playwright` | | Claude | `~/.claude/mcp-playwright.json` | `claude --mcp-config ` | Damit das der Normalfall und kein Extrabefehl ist, setzt das Modul in zsh die Aliase `codex` und `claude` auf genau diese Aufrufe. zsh expandiert einen Alias nicht in sich selbst, die echten Binaries werden also weiterhin aufgerufen. Codex' Profil wird über die Basiskonfiguration **gelegt**, nicht an ihre Stelle gesetzt: Modell, Trust-Level und der bestehende Server `openaiDeveloperDocs` bleiben erhalten. Ebenso ergänzt Claudes `--mcp-config` die bereits konfigurierten Server, statt sie zu ersetzen (das täte erst `--strict-mcp-config`). **Grenze:** Aliase wirken nur in interaktiven zsh-Sitzungen. Skripte, andere Shells und Agenten auf anderen Hosts rufen weiterhin das nackte Binary ohne MCP-Server auf; dort ist der Aufruf aus der Tabelle oben explizit anzugeben. ## Browser Der Server nutzt die Browser, die das `playwright-mcp`-Paket bereits mitbringt (`--browser chromium`). Ein zusätzliches `pkgs.chromium` als `--executable-path` wäre eine zweite, überflüssige Browser-Closure und entfällt daher. `--browser chrome` wäre falsch: Playwright sucht dann ein gebrandetes Google Chrome unter `/opt/google/chrome/chrome` und bricht ab. Der Browser startet sichtbar (kein `--headless`). ## Profile und parallele Agenten Ein Chromium-Profil darf nur von genau einem Prozess gleichzeitig benutzt werden. Codex und Claude bekommen deshalb getrennte Profile und können parallel einen Browser steuern: ``` ~/.local/share/playwright-mcp/codex/profile ~/.local/share/playwright-mcp/claude/profile ``` Die Verzeichnisse legt eine home-manager-Activation mit Modus `0700` an. Profilinhalte sind absichtlich Laufzeitdaten, keine Store-Artefakte: zum Abmelden oder Zurücksetzen erst den Agenten und dessen Browser beenden, dann nur das betreffende Profilverzeichnis entfernen. Der nixpkgs-Wrapper braucht denselben Pfad zusätzlich als `PLAYWRIGHT_MCP_USER_DATA_DIR`, sonst schaltet er auf ein Arbeitsspeicher-Profil um und verwirft Logins zwischen Sitzungen. Seitenausgaben (Snapshots) landen über `--output-dir` unter `~/.local/share/playwright-mcp//output`. Ohne das Flag schreibt der Server sie in ein `.playwright-mcp`-Verzeichnis im aktuellen Arbeitsverzeichnis, also in das jeweils bearbeitete Repository. ## Verifikation Der Server selbst lässt sich ohne Agent über das nackte Protokoll prüfen (`initialize`, dann `tools/call browser_navigate` gegen einen lokalen HTTP-Server). Verifiziert am 17.09.2026 mit `playwright-mcp` 0.0.76 und Playwright 1.61.1: Navigation und Snapshot funktionieren allein mit den gebündelten Browsern. Pro Agent: ```console codex --profile playwright mcp list # playwright ... enabled claude -p "Answer YES or NO: do you have a tool named browser_navigate?" ``` Beide wurden am 17.09.2026 gegen eine Negativkontrolle geprüft (gleiche Frage in einem Verzeichnis ohne MCP-Konfiguration): dort `NO`, mit Konfiguration `YES`. Zu `claude mcp list`: Server aus einer Projekt-`.mcp.json` erscheinen dort als „⏸ Pending approval". Das betrifft die interaktive Freigabe; in `-p`-Läufen stehen die Werkzeuge trotzdem zur Verfügung. Der hier genutzte Weg über `--mcp-config` kennt diese Freigabe-Hürde ohnehin nicht. ## Aktivierung und Aktualisierung ```console sudo nixos-rebuild switch --flake .#tnix ``` Danach eine **neue** Shell öffnen (die Aliase stammen aus zsh) und den Agenten neu starten; laufende Sitzungen bekommen den Server nicht mehr nachgereicht. Eine Aktualisierung von `flake.lock` darf die MCP-Version nicht stillschweigend ändern: den `playwrightMcpVersion`-Guard erst nach Release-Review und erneutem Smoke-Test anpassen. ## Quellen - [Microsoft: Playwright MCP](https://github.com/microsoft/playwright-mcp) dokumentiert `--browser`, `--user-data-dir`, `--output-dir`, sichtbaren Betrieb als Standard und getrennte Profile bei parallelen Clients. - [OpenAI: Codex MCP](https://developers.openai.com/codex/mcp/) dokumentiert lokale STDIO-Server und `[mcp_servers.]`; `codex --help` das Überlagern per `--profile` aus `$CODEX_HOME/.config.toml`. - `claude --help` dokumentiert `--mcp-config` und `--strict-mcp-config`.