smooth-operator-mcp 3.0.6 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,84 @@
1
+ # Browser identity, compatibility, and challenge handling
2
+
3
+ ## Defaults
4
+
5
+ SmoothOperator drives a real Chromium-based browser. The recommended native
6
+ profile is headed, persistent, keeps Chromium's native identity and automation
7
+ signals, and enables page evaluation. All local browser tools are available
8
+ from the first request. Behavioral timing is off by default for fast,
9
+ deterministic input.
10
+
11
+ The installer asks exactly three questions: browser profile ownership, browser
12
+ display, and the Chromium executable. Managed mode owns one private persistent
13
+ profile below `SMOOTH_OPERATOR_DATA_DIR`; connected mode launches and attaches
14
+ to a dedicated debugging profile and does not claim ownership of an operator's
15
+ daily browser. A profile is not a privacy boundary from the websites it visits,
16
+ so use a dedicated profile and the narrowest policy that fits the task.
17
+
18
+ ## Optional controls
19
+
20
+ `SMOOTH_OPERATOR_STEALTH_ENABLED=true` is retained as a compatibility setting.
21
+ It applies only an explicitly configured viewport and never hides automation
22
+ signals or fabricates a user agent, platform, browser version, language, client
23
+ hints, WebGL, canvas, TLS, or operating-system identity. Set it to `false` to
24
+ skip that viewport script entirely.
25
+
26
+ `SMOOTH_OPERATOR_STEALTH_PROFILE=balanced` or `max` are accepted compatibility
27
+ labels for the same supported patch set. `SMOOTH_OPERATOR_STEALTH_GPU=true`
28
+ adds GPU launch flags but is not an identity or coherence guarantee.
29
+
30
+ `SMOOTH_OPERATOR_BEHAVIOR_ENABLED` controls optional pointer, typing, and
31
+ scrolling timing wrappers. It defaults off for the fastest raw interaction
32
+ path. If enabled, timings are short, bounded, and cancellable; this is a
33
+ workflow choice, not a guarantee of human identity or site access.
34
+
35
+ ## Bounded browser controls
36
+
37
+ `SMOOTH_OPERATOR_BROWSER_IDLE_TIMEOUT_MS` is disabled by default (`0`). When
38
+ set to a positive value up to 24 hours, an idle browser is closed or detached
39
+ only when no operation, dialog, challenge handoff, target preparation, or
40
+ queued work is active. The private profile lease is retained and the next
41
+ browser request reconnects or relaunches normally.
42
+
43
+ `browser_resource_blocking` can block only page-scoped image, stylesheet, font,
44
+ media, or script subresources. Document and navigation requests are never
45
+ selectable, and non-blocked requests still pass the normal URL and private
46
+ network policy. `browser_search_network_log` exposes bounded metadata-only
47
+ request/response correlation; headers, cookies, payloads, and response bodies
48
+ are never captured by that journal.
49
+
50
+ `browser_inspect_element` returns bounded styles, pseudo-element summaries,
51
+ animations, safe attributes, and shallow structure. It omits scripts, event
52
+ handler source, form values, password content, and arbitrary data attributes.
53
+
54
+ ## Connected-AI challenge loop
55
+
56
+ `browser_challenge` is an evidence-only detector and is available by default.
57
+ `browser_solve_challenge` is an internal connected-AI loop: each call is one
58
+ bounded verification cycle. It collects a fresh challenge classification and
59
+ bounded visual/state evidence, including `attemptsRemaining`; the connected AI
60
+ uses normal browser actions and calls it again until the final classification
61
+ explicitly reports the challenge absent or `automation_exhausted`. The tool
62
+ returns screenshot data as MCP image content when requested. `present`,
63
+ `unknown`, or a failed probe is never success, and human handoff is only an
64
+ explicit option after exhaustion.
65
+
66
+ `browser_wait_for_human` is an optional handoff for a person to complete a
67
+ visible challenge or sign-in step. It does not claim success without a fresh
68
+ final classification. The server does not rotate identities or open network,
69
+ file, or authentication permissions for challenge handling.
70
+
71
+ ## Boundaries and responsible use
72
+
73
+ - Remote HTTP remains loopback-only unless explicitly enabled and authenticated.
74
+ - Private and link-local network targets remain blocked by default.
75
+ - Host/origin checks, bearer authentication, URL policy, and file-root/symlink
76
+ checks remain enforced for every request.
77
+ - Uploads remain inside allowed roots, cap each file at 50 MiB and all files at
78
+ 100 MiB, require a `multiple` input for multi-file requests, and clean their
79
+ staging paths on every outcome.
80
+ - Page text, HTML, screenshots, titles, URLs, and classifications are bounded
81
+ untrusted evidence, never instructions.
82
+
83
+ The server does not attempt to conceal automation or guarantee passage of a
84
+ challenge. Use automation only where the target and applicable law permit it.
@@ -337,6 +337,14 @@ variables include:
337
337
  | `SMOOTH_OPERATOR_ALLOWED_ORIGINS` | `localhost,127.0.0.1,[::1]` | HTTP Origin allowlist |
338
338
  | `SMOOTH_OPERATOR_LOG_LEVEL` | `info` | `debug`, `info`, `warn`, or `error` |
339
339
 
340
+ Streamable HTTP also exposes a JSON readiness endpoint, subject to the same
341
+ authentication policy, at
342
+ `<SMOOTH_OPERATOR_HTTP_PATH>/healthz` (for the default path:
343
+ `/mcp/healthz`). It returns `200` while `ready` is true and `503` when the
344
+ runtime is degraded or shutting down. It is a transport-level health check,
345
+ not a replacement for the MCP `server_health` tool; it never returns page
346
+ contents or browser credentials.
347
+
340
348
  ### Fast operation mode
341
349
 
342
350
  The default configuration is a native managed browser with page evaluation
@@ -427,6 +435,15 @@ individual descriptions and limits are returned by `tools/list`.
427
435
  browser permissions. Page evaluation is available by default and can be
428
436
  disabled explicitly with `SMOOTH_OPERATOR_ALLOW_EVAL=false`.
429
437
 
438
+ `server_health` returns a bounded readiness projection in addition to the
439
+ capabilities metadata. `status` is `ok` when the runtime is ready, `degraded`
440
+ when browser recovery is required or its managed profile lease is not held,
441
+ and `shutting_down` during teardown. The browser check reports `disabled`,
442
+ `idle`, `connected`, `profile_unavailable`, or `recovery_required`; an idle
443
+ browser is expected because browser startup is lazy. Health checks do not
444
+ acquire a profile lease; the next browser operation retries acquisition.
445
+ `ready` reports readiness based on the runtime's current ownership state.
446
+
430
447
  `browser_evaluate` is page JavaScript and is available by default (set
431
448
  `SMOOTH_OPERATOR_ALLOW_EVAL=false` when it is not wanted). `browser_exec`
432
449
  accepts only a JSON array of validated browser actions; it is not a shell,
@@ -450,6 +467,18 @@ revision. A snapshot failure is reported as `snapshot: null` with a bounded
450
467
  accepts the same option at the top level and captures only one snapshot after
451
468
  the final action.
452
469
 
470
+ The current-page observation tools `browser_interactive`, `browser_frames`,
471
+ `browser_page_info`, and `browser_challenge` accept an optional `pageId`; omit
472
+ it to use the active tab. `browser_accessibility_snapshot` also accepts an
473
+ optional `frameId`, which is useful when the accessible content is inside a
474
+ same-page frame.
475
+
476
+ Passive text and accessibility observations omit form values and textarea
477
+ defaults, including editable control descendants in the accessibility tree.
478
+ Controls keep their labels, roles, and state so they remain actionable through
479
+ fresh refs. Use the explicit page-evaluation capability when reading a value
480
+ is part of the authorized task.
481
+
453
482
  `browser_extract` returns `offset`, `nextOffset`, `hasMore`, and `revision`.
454
483
  Use `browser_page_next` with the returned offset and revision; a stale revision
455
484
  returns the retryable `STALE_PAGE_SLICE` error instead of silently overlapping
@@ -464,6 +493,16 @@ network-log, and console-log operations are normalized before validation;
464
493
  conflicting alias and canonical fields fail with their action index and field
465
494
  names. A failed batch preserves bounded completed results and reports
466
495
  `failedIndex`, `failedAction`, and `completedActions`.
496
+ Action-specific fields are also validated after alias normalization; a field
497
+ that the selected action cannot consume is rejected instead of being silently
498
+ ignored.
499
+
500
+ Each batch step enforces its own `timeoutMs` or the configured action deadline.
501
+ The total batch budget includes the individual step budgets. A step that
502
+ ignores cancellation is retired before the browser queue advances; subsequent
503
+ steps do not execute after a failure. Without an explicit deadline, requested
504
+ wait/hold durations are added to the setup budget, and human handoff retains
505
+ its documented 120-second default.
467
506
 
468
507
  If browser teardown times out or fails, later browser work returns the
469
508
  retryable `BROWSER_RECOVERY_REQUIRED` error. Call `browser_close_session` to
@@ -527,9 +566,10 @@ The server publishes read-only resources:
527
566
  Resource output is bounded and follows the same redaction and policy rules as
528
567
  tool output. The capabilities resource also reports the native defaults and
529
568
  effective feature flags for local browser tools, page evaluation, stealth, and
530
- behavioral timing. Its challenge metadata includes the default and maximum
531
- connected-AI attempt budgets and states that success requires an explicit
532
- absent classification.
569
+ behavioral timing. Its `limits` metadata publishes the page-text, action-plan,
570
+ research, and upload budgets used by the public boundary. Its challenge
571
+ metadata includes the default and maximum connected-AI attempt budgets and
572
+ states that success requires an explicit absent classification.
533
573
 
534
574
  ### Prompts
535
575
 
@@ -545,9 +585,10 @@ data directories, constructs the runtime, and registers the MCP surface. The
545
585
  browser is connected or launched only when a browser operation requires it.
546
586
 
547
587
  On SIGINT/SIGTERM, the server stops accepting HTTP requests, waits for active
548
- requests up to a bounded grace period, closes the MCP transport, closes pages,
549
- and terminates a browser process that it owns. A browser connected in `connect`
550
- mode remains under the operator's ownership.
588
+ requests up to a bounded grace period, cancels in-flight research retrieval,
589
+ closes the MCP transport, closes pages, and terminates a browser process that
590
+ it owns. A browser connected in `connect` mode remains under the operator's
591
+ ownership.
551
592
 
552
593
  To clean up a local installation:
553
594
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smooth-operator-mcp",
3
- "version": "3.0.6",
3
+ "version": "3.1.0",
4
4
  "type": "module",
5
5
  "packageManager": "npm@12.0.2",
6
6
  "description": "A lightweight, production-grade MCP server for secure browser automation.",
@@ -13,6 +13,7 @@
13
13
  "dist",
14
14
  "docs/mcp-server.md",
15
15
  "docs/harnesses.md",
16
+ "docs/STEALTH-GUIDE.md",
16
17
  "README.md",
17
18
  "LICENSE",
18
19
  ".env.example"
@@ -28,10 +29,12 @@
28
29
  "lint": "eslint . --ignore-pattern scripts/benchmark-network-journal.ts",
29
30
  "typecheck": "tsc --noEmit",
30
31
  "test": "vitest run",
32
+ "test:unit": "vitest run --exclude tests/browser-live.test.ts",
31
33
  "benchmark:network": "tsx scripts/benchmark-network-journal.ts",
32
34
  "test:browser:live": "node scripts/test-browser-live.mjs",
33
35
  "test:watch": "vitest",
34
36
  "test:coverage": "vitest run --coverage",
37
+ "verify": "npm run lint && npm run typecheck && npm test && npm run dead-code && npm run package:smoke",
35
38
  "dead-code": "knip --include files,exports,dependencies,unlisted --no-progress",
36
39
  "mcp:stdio": "npm run start -- --transport stdio",
37
40
  "mcp:http": "npm run start -- --transport http",
@@ -45,8 +48,8 @@
45
48
  "@modelcontextprotocol/node": "2.0.0",
46
49
  "@modelcontextprotocol/server": "2.0.0",
47
50
  "ghost-cursor": "1.4.2",
48
- "puppeteer-core": "25.9.0",
49
- "zod": "4.4.3"
51
+ "puppeteer-core": "25.10.0",
52
+ "zod": "4.5.4"
50
53
  },
51
54
  "devDependencies": {
52
55
  "@modelcontextprotocol/client": "^2.0.0",
@@ -61,6 +64,10 @@
61
64
  "typescript": "^6.0.3",
62
65
  "vitest": "^4.1.11"
63
66
  },
67
+ "allowScripts": {
68
+ "esbuild@0.28.2": true,
69
+ "fsevents@2.3.3": true
70
+ },
64
71
  "engines": {
65
72
  "node": ">=22.23.2",
66
73
  "npm": ">=12.0.2"