feat(browser_mcp): add browser_list/launch_profile/close lifecycle tools

Three MCP tools to manage the user's Chromium instances by profile, distinct
from browser_launch's isolated automation Chrome:

- browser_list: enumerate running Chromium master processes by scanning
  /proc/*/cmdline (has --user-data-dir, no --type=). Returns pid, profile,
  user_data_dir, cdp_port, has_cdp as a JSON array.
- browser_launch_profile: launch a concrete profile using the REAL binary
  /usr/lib/chromium/chromium (bypassing the /usr/bin/chromium wrapper). No CDP
  by default so Google keeps the session for human profiles; cdp=true adds
  --remote-debugging-port + --remote-allow-origins=*. Detects DISPLAY/XAUTHORITY
  from the XFCE session and launches decoupled via setsid.
- browser_close: locate a master by profile/cdp_port/pid, SIGTERM with a 10s
  wait, then SIGKILL as a last resort.

Per-profile instances are NOT registered in the connection pool: they are
user-facing and survive the MCP dying; cleanup is explicit via browser_close.

Unit tests for cmdline master detection, flag parsing, and close-target
matching. Bumps version 0.6.0 -> 0.7.0 (42 -> 45 tools).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-10 18:23:45 +02:00
parent 54fe1b7f17
commit 1fae6c1df9
5 changed files with 661 additions and 10 deletions
+2 -1
View File
@@ -15,7 +15,7 @@ import (
"fn-registry/functions/browser"
)
const version = "0.6.0"
const version = "0.7.0"
type config struct {
httpAddr string
@@ -92,6 +92,7 @@ func main() {
// registerTools wires every tool group. Mutating tools are skipped under --read-only.
func registerTools(s *server.MCPServer, d *deps) {
registerSessionTools(s, d)
registerLifecycleTools(s, d)
registerNavTools(s, d)
registerReadTools(s, d)
registerDomTools(s, d)