cdp-mcp-server 5.0.3 → 5.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.
Files changed (45) hide show
  1. package/README.md +14 -0
  2. package/dist/config.js +2 -0
  3. package/dist/config.js.map +1 -1
  4. package/dist/connection/capabilities.d.ts +58 -0
  5. package/dist/connection/capabilities.js +126 -0
  6. package/dist/connection/capabilities.js.map +1 -0
  7. package/dist/connection/index.d.ts +1 -0
  8. package/dist/connection/index.js +1 -0
  9. package/dist/connection/index.js.map +1 -1
  10. package/dist/connection/tab-session-service.d.ts +12 -2
  11. package/dist/connection/tab-session-service.js +48 -14
  12. package/dist/connection/tab-session-service.js.map +1 -1
  13. package/dist/index.js +44 -4
  14. package/dist/index.js.map +1 -1
  15. package/dist/snapshot/accessibility.d.ts +2 -0
  16. package/dist/snapshot/accessibility.js +1 -1
  17. package/dist/snapshot/accessibility.js.map +1 -1
  18. package/dist/tools/device-presets.d.ts +24 -0
  19. package/dist/tools/device-presets.js +62 -0
  20. package/dist/tools/device-presets.js.map +1 -0
  21. package/dist/tools/emulate.js +79 -0
  22. package/dist/tools/emulate.js.map +1 -1
  23. package/dist/tools/interact.js +191 -31
  24. package/dist/tools/interact.js.map +1 -1
  25. package/dist/tools/observe.js +201 -27
  26. package/dist/tools/observe.js.map +1 -1
  27. package/dist/tools/page.d.ts +52 -1
  28. package/dist/tools/page.js +242 -25
  29. package/dist/tools/page.js.map +1 -1
  30. package/dist/tools/storage.d.ts +1 -1
  31. package/dist/tools/storage.js +115 -3
  32. package/dist/tools/storage.js.map +1 -1
  33. package/dist/tools/tabs.js +4 -2
  34. package/dist/tools/tabs.js.map +1 -1
  35. package/dist/types.d.ts +14 -0
  36. package/dist/utils/actionability.d.ts +62 -0
  37. package/dist/utils/actionability.js +190 -0
  38. package/dist/utils/actionability.js.map +1 -0
  39. package/dist/utils/wait.d.ts +0 -25
  40. package/dist/utils/wait.js +0 -76
  41. package/dist/utils/wait.js.map +1 -1
  42. package/package.json +1 -1
  43. package/dist/utils/retry.d.ts +0 -40
  44. package/dist/utils/retry.js +0 -75
  45. package/dist/utils/retry.js.map +0 -1
package/README.md CHANGED
@@ -64,6 +64,20 @@ command lines are never logged — disable with `CDP_PROCESS_SCAN=false`), and
64
64
  can connect via the `chrome://inspect` toggle by reading `DevToolsActivePort`.
65
65
  `ping`/`status` report the connection mode (`legacy` | `approval`).
66
66
 
67
+ ## Browser compatibility
68
+
69
+ | Browser | Flag mode | Toggle (approval) | Process scan | Notes |
70
+ |---------|-----------|-------------------|--------------|-------|
71
+ | Chrome 136+ | ✅ requires non-default `--user-data-dir` | ✅ Chrome 144+ | ✅ | default-profile restriction since Chrome 136 |
72
+ | Brave | ✅ | ✅ (verified on 153) | ✅ (verified on 153) | portapps wrappers: launch inner `app\brave.exe`, not wrapper shortcut |
73
+ | Edge | ✅ | ✅ Chrome 144+ | ✅ | same Chromium behavior |
74
+ | Chromium | ✅ | ✅ Chrome 144+ | ✅ | restriction is Chrome-branding-gated |
75
+ | Vivaldi | ✅ | ✅ Chrome 144+ | ✅ | discovery path added in 5.0.3 |
76
+ | Opera | ✅ | ✅ Chrome 144+ | ✅ | discovery path added in 5.0.3 |
77
+ | Chrome for Testing | ✅ no restriction | — | ✅ | recommended automated/CI setups |
78
+
79
+ Connection failures auto-detect the failure mode and print the exact fix — see Troubleshooting above.
80
+
67
81
  ## Environment variables
68
82
 
69
83
  | Variable | Default | Description |
package/dist/config.js CHANGED
@@ -33,6 +33,8 @@ export function loadConfig() {
33
33
  userDataDir: process.env.CDP_USER_DATA || '',
34
34
  /** Process command-line scan on discovery failure (default ON). */
35
35
  processScan: process.env.CDP_PROCESS_SCAN !== 'false',
36
+ /** Actionability gate before element interactions (default ON). */
37
+ autoWait: process.env.CDP_AUTO_WAIT !== 'false',
36
38
  slimMode: process.env.CDP_SLIM_MODE === 'true',
37
39
  };
38
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;GAMG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,WAAW;QAC5C,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,MAAM,EAAE,EAAE,CAAC;QAErD,kBAAkB;QAClB,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO,EAAE,EAAE,CAAC;QACtE,iBAAiB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,EAAE,EAAE,CAAC;QAC9E,eAAe,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,OAAO,EAAE,EAAE,CAAC;QAC1E,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,EAAE,EAAE,CAAC;QAE/D,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,QAAQ,EAAE,EAAE,CAAC;QACjE,eAAe,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,OAAO,EAAE,EAAE,CAAC;QAE1E,mEAAmE;QACnE,sBAAsB,EACnB,OAAO,CAAC,GAAG,CAAC,oBAAwC,IAAI,QAAQ;QAEnE,YAAY,EAAE,MAAM;QACpB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,EAAE,sBAAsB;QAC/D,YAAY,EAAE,EAAE;QAChB,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;QAE3C,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE;QAEjD,0EAA0E;QAC1E,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE;QAE5C,mEAAmE;QACnE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,OAAO;QAErD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,MAAM;KAC/C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;GAMG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,WAAW;QAC5C,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,MAAM,EAAE,EAAE,CAAC;QAErD,kBAAkB;QAClB,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO,EAAE,EAAE,CAAC;QACtE,iBAAiB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,EAAE,EAAE,CAAC;QAC9E,eAAe,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,OAAO,EAAE,EAAE,CAAC;QAC1E,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,EAAE,EAAE,CAAC;QAE/D,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,QAAQ,EAAE,EAAE,CAAC;QACjE,eAAe,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,OAAO,EAAE,EAAE,CAAC;QAE1E,mEAAmE;QACnE,sBAAsB,EACnB,OAAO,CAAC,GAAG,CAAC,oBAAwC,IAAI,QAAQ;QAEnE,YAAY,EAAE,MAAM;QACpB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,EAAE,sBAAsB;QAC/D,YAAY,EAAE,EAAE;QAChB,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;QAE3C,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE;QAEjD,0EAA0E;QAC1E,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE;QAE5C,mEAAmE;QACnE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,OAAO;QAErD,mEAAmE;QACnE,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,OAAO;QAE/C,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,MAAM;KAC/C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * CDP domain capability report (5.1.0 B1, redesigned as multi-canary probing).
3
+ *
4
+ * `Schema.getDomains` — the original probe — was removed from Chrome years ago:
5
+ * on any modern Chrome/Brave it replies "'Schema.getDomains' wasn't found"
6
+ * (confirmed live on Brave 153, approval mode). There is no domain-enumeration
7
+ * command anymore, so presence is now probed per domain with a real canary
8
+ * command whose empty-params call is either read-only or rejected by parameter
9
+ * validation before any handler runs — a probe never mutates meaningful state.
10
+ *
11
+ * Classification:
12
+ * - `"'X' wasn't found"` → domain/method absent
13
+ * - any other outcome (success / Invalid parameters / domain-specific error)
14
+ * → domain present
15
+ *
16
+ * Cache lives on the instance and is invalidated on disconnect
17
+ * (wired in index.ts next to the other per-connection caches).
18
+ */
19
+ import type { CDPClient } from './cdp-client.js';
20
+ /** Domains whose absence is worth surfacing in `status` output. */
21
+ export declare const NOTABLE_DOMAINS: readonly ["WebAuthn", "FedCm", "WebMCP", "Preload", "Ads", "Extensions", "PWA", "FindInPage", "Tracing", "Overlay"];
22
+ export type NotableDomain = (typeof NOTABLE_DOMAINS)[number];
23
+ /** True when a CDP error means "domain or method not implemented". */
24
+ export declare function isMethodMissingError(err: unknown): boolean;
25
+ export declare class DomainCapabilities {
26
+ /** Probe key (domain or Domain.method) → present? */
27
+ private cache;
28
+ private inFlight;
29
+ /**
30
+ * Probe a single canary / method. Empty params on purpose:
31
+ * required-params canaries fail validation (proving presence), read-only
32
+ * canaries succeed (proving presence), unknown methods report "wasn't found".
33
+ *
34
+ * Pass a page-session id when probing page-scoped domains: the browser-level
35
+ * endpoint only serves browser-wide domains (Target/Browser/SystemInfo/
36
+ * Tracing/Extensions...), so page-scoped domains report "wasn't found"
37
+ * without a session (live-confirmed: browser-level probes said 2/10).
38
+ */
39
+ hasMethod(client: CDPClient, method: string, sessionId?: string): Promise<boolean>;
40
+ /**
41
+ * True when the connected browser supports the given domain. Domain names
42
+ * resolve through their canary; dotted "Domain.method" keys probe directly
43
+ * (useful for version-gated methods like Emulation.setCPUPerformanceOverride).
44
+ */
45
+ has(client: CDPClient, key: string, sessionId?: string): Promise<boolean>;
46
+ /** Feature-gate helper: throws an actionable error when absent. */
47
+ require(client: CDPClient, key: string, minChrome?: string, sessionId?: string): Promise<void>;
48
+ /** Invalidate on disconnect/reconnect. */
49
+ clear(): void;
50
+ /**
51
+ * Summary for the `status` tool: how many of the notable domains are
52
+ * present, and which are missing. Every entry is individually probed.
53
+ */
54
+ summarize(client: CDPClient, sessionId?: string): Promise<{
55
+ count: number;
56
+ missing: string[];
57
+ }>;
58
+ }
@@ -0,0 +1,126 @@
1
+ /** Domains whose absence is worth surfacing in `status` output. */
2
+ export const NOTABLE_DOMAINS = [
3
+ 'WebAuthn',
4
+ 'FedCm',
5
+ 'WebMCP',
6
+ 'Preload',
7
+ 'Ads',
8
+ 'Extensions',
9
+ 'PWA',
10
+ 'FindInPage',
11
+ 'Tracing',
12
+ 'Overlay',
13
+ ];
14
+ /**
15
+ * Canary command per domain (method names verified against the Chromium
16
+ * browser-protocol surface shipped with Playwright 1.65):
17
+ *
18
+ * - requires parameters → `{}` is rejected with "Invalid parameters" before
19
+ * the handler runs (zero side effect): WebAuthn.addVirtualAuthenticator
20
+ * (options), FedCm.selectAccount (dialogId+accountIndex),
21
+ * WebMCP.invokeTool (frameId+toolName+input), Extensions.loadUnpacked
22
+ * (path), PWA.getOsAppState (manifestId), FindInPage.findFirst (query),
23
+ * Overlay.setInspectMode (mode)
24
+ * - read-only with no required params → succeeds harmlessly:
25
+ * Ads.getAdScripts, Tracing.getCategories
26
+ * - Preload.enable is the one intentional soft exception: it succeeds and
27
+ * merely enables speculative preloading for the session (the browser's
28
+ * own default behavior).
29
+ */
30
+ const CANARIES = {
31
+ WebAuthn: 'WebAuthn.addVirtualAuthenticator',
32
+ FedCm: 'FedCm.selectAccount',
33
+ WebMCP: 'WebMCP.invokeTool',
34
+ Preload: 'Preload.enable',
35
+ Ads: 'Ads.getAdScripts',
36
+ Extensions: 'Extensions.loadUnpacked',
37
+ PWA: 'PWA.getOsAppState',
38
+ FindInPage: 'FindInPage.findFirst',
39
+ Overlay: 'Overlay.setInspectMode',
40
+ Tracing: 'Tracing.getCategories',
41
+ };
42
+ /** True when a CDP error means "domain or method not implemented". */
43
+ export function isMethodMissingError(err) {
44
+ const msg = err instanceof Error ? err.message : String(err);
45
+ return /wasn'?t found|not found/i.test(msg);
46
+ }
47
+ export class DomainCapabilities {
48
+ /** Probe key (domain or Domain.method) → present? */
49
+ cache = new Map();
50
+ inFlight = new Map();
51
+ /**
52
+ * Probe a single canary / method. Empty params on purpose:
53
+ * required-params canaries fail validation (proving presence), read-only
54
+ * canaries succeed (proving presence), unknown methods report "wasn't found".
55
+ *
56
+ * Pass a page-session id when probing page-scoped domains: the browser-level
57
+ * endpoint only serves browser-wide domains (Target/Browser/SystemInfo/
58
+ * Tracing/Extensions...), so page-scoped domains report "wasn't found"
59
+ * without a session (live-confirmed: browser-level probes said 2/10).
60
+ */
61
+ async hasMethod(client, method, sessionId) {
62
+ const cached = this.cache.get(method);
63
+ if (cached !== undefined)
64
+ return cached;
65
+ const pending = this.inFlight.get(method);
66
+ if (pending)
67
+ return pending;
68
+ const probe = (async () => {
69
+ try {
70
+ await client.send(method, {}, sessionId);
71
+ return true;
72
+ }
73
+ catch (err) {
74
+ if (isMethodMissingError(err))
75
+ return false;
76
+ // Invalid parameters / domain-specific error → the method exists
77
+ return true;
78
+ }
79
+ finally {
80
+ this.inFlight.delete(method);
81
+ }
82
+ })();
83
+ this.inFlight.set(method, probe);
84
+ const present = await probe;
85
+ this.cache.set(method, present);
86
+ return present;
87
+ }
88
+ /**
89
+ * True when the connected browser supports the given domain. Domain names
90
+ * resolve through their canary; dotted "Domain.method" keys probe directly
91
+ * (useful for version-gated methods like Emulation.setCPUPerformanceOverride).
92
+ */
93
+ async has(client, key, sessionId) {
94
+ if (key.includes('.'))
95
+ return this.hasMethod(client, key, sessionId);
96
+ const canary = CANARIES[key];
97
+ if (!canary)
98
+ return false; // no canary → unknown, treated as absent
99
+ return this.hasMethod(client, canary, sessionId);
100
+ }
101
+ /** Feature-gate helper: throws an actionable error when absent. */
102
+ async require(client, key, minChrome, sessionId) {
103
+ if (await this.has(client, key, sessionId))
104
+ return;
105
+ const versionNote = minChrome ? ` (requires Chrome ${minChrome}+)` : '';
106
+ const err = new Error(`This browser does not support the CDP "${key}" feature${versionNote}. ` +
107
+ `Update Chrome/Brave or use a feature-gated alternative.`);
108
+ err.name = 'DomainUnsupportedError';
109
+ throw err;
110
+ }
111
+ /** Invalidate on disconnect/reconnect. */
112
+ clear() {
113
+ this.cache.clear();
114
+ this.inFlight.clear();
115
+ }
116
+ /**
117
+ * Summary for the `status` tool: how many of the notable domains are
118
+ * present, and which are missing. Every entry is individually probed.
119
+ */
120
+ async summarize(client, sessionId) {
121
+ const results = await Promise.all(NOTABLE_DOMAINS.map(async (d) => [d, await this.has(client, d, sessionId)]));
122
+ const missing = results.filter(([, present]) => !present).map(([d]) => d);
123
+ return { count: results.length - missing.length, missing };
124
+ }
125
+ }
126
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/connection/capabilities.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ export type { ConnectionState, CDPClientOptions } from './cdp-client.js';
6
6
  export { discoverBrowserInstances, resolveWsUrl, resolveWsUrlAsync, findBestInstance, parseBrowserCommandLine, scanBrowserProcesses, } from './browser-discovery.js';
7
7
  export type { DiscoverOptions, WsUrlResult, CommandLineInfo, ProcessScanResult, } from './browser-discovery.js';
8
8
  export { HealthMonitor } from './health-monitor.js';
9
+ export { DomainCapabilities } from './capabilities.js';
9
10
  export type { HealthStatus, HealthState, HealthMonitorOptions, ConnectionMode, } from './health-monitor.js';
10
11
  export { DomainManager } from './domain-manager.js';
11
12
  export { TabSessionService } from './tab-session-service.js';
@@ -4,6 +4,7 @@
4
4
  export { CDPClient } from './cdp-client.js';
5
5
  export { discoverBrowserInstances, resolveWsUrl, resolveWsUrlAsync, findBestInstance, parseBrowserCommandLine, scanBrowserProcesses, } from './browser-discovery.js';
6
6
  export { HealthMonitor } from './health-monitor.js';
7
+ export { DomainCapabilities } from './capabilities.js';
7
8
  export { DomainManager } from './domain-manager.js';
8
9
  export { TabSessionService } from './tab-session-service.js';
9
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connection/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EACL,wBAAwB,EACxB,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAQhC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connection/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EACL,wBAAwB,EACxB,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAQhC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAQvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -19,6 +19,10 @@ export declare class TabSessionService {
19
19
  private childToParent;
20
20
  /** uid → childSessionId routing for cross-frame element resolution */
21
21
  private refSessionRouting;
22
+ /** CDP sessionId → tabId (reverse lookup for auto-attach event routing) */
23
+ private sessionToTab;
24
+ /** CDP clients already wired for auto-attach event routing */
25
+ private wiredClients;
22
26
  /**
23
27
  * Get (or create) a CDP session for a tab.
24
28
  *
@@ -32,9 +36,15 @@ export declare class TabSessionService {
32
36
  */
33
37
  ensureDomain(cdpClient: CDPClient, tabId: string, domain: string): Promise<void>;
34
38
  /**
35
- * Enable Target.setAutoAttach on a tab session to discover OOP iframes.
39
+ * Register Target.autoAttach event routing (idempotent per CDP client).
40
+ *
41
+ * `Target.attachedToTarget` events emitted by managed page sessions are
42
+ * translated into child-session registrations (OOP iframes);
43
+ * `Target.detachedFromTarget` prunes them. This is what feeds
44
+ * `captureFullTree`'s multi-frame snapshot and the uid → child-session
45
+ * routing used for cross-frame element interaction.
36
46
  */
37
- setupAutoAttach(cdpClient: CDPClient, tabId: string): Promise<void>;
47
+ private wireAutoAttachEvents;
38
48
  /** Track a child session (OOP iframe) under a parent session. */
39
49
  addChildSession(parentSessionId: string, childTargetId: string, childSessionId: string, url: string): void;
40
50
  /** Remove a child session when an OOP iframe detaches. */
@@ -18,6 +18,10 @@ export class TabSessionService {
18
18
  childToParent = new Map();
19
19
  /** uid → childSessionId routing for cross-frame element resolution */
20
20
  refSessionRouting = new Map();
21
+ /** CDP sessionId → tabId (reverse lookup for auto-attach event routing) */
22
+ sessionToTab = new Map();
23
+ /** CDP clients already wired for auto-attach event routing */
24
+ wiredClients = new WeakSet();
21
25
  /**
22
26
  * Get (or create) a CDP session for a tab.
23
27
  *
@@ -25,21 +29,28 @@ export class TabSessionService {
25
29
  * Otherwise calls Target.attachToTarget with flatten: true.
26
30
  */
27
31
  async getSession(cdpClient, tabId) {
32
+ // Idempotent: register auto-attach event routing before any session can
33
+ // emit Target.attachedToTarget (no missed events on first attach)
34
+ this.wireAutoAttachEvents(cdpClient);
28
35
  // Check the CDPClient's own session pool first, then our map
29
36
  const pooled = cdpClient.getPooledSession(tabId);
30
37
  if (pooled) {
31
38
  this.sessions.set(tabId, pooled);
39
+ this.sessionToTab.set(pooled, tabId);
32
40
  return pooled;
33
41
  }
34
42
  const existing = this.sessions.get(tabId);
35
- if (existing)
43
+ if (existing) {
44
+ this.sessionToTab.set(existing, tabId);
36
45
  return existing;
46
+ }
37
47
  const result = await cdpClient.send('Target.attachToTarget', {
38
48
  targetId: tabId,
39
49
  flatten: true,
40
50
  });
41
51
  const sessionId = result.sessionId;
42
52
  this.sessions.set(tabId, sessionId);
53
+ this.sessionToTab.set(sessionId, tabId);
43
54
  cdpClient.poolSession(tabId, sessionId);
44
55
  // Enable auto-attach for OOP (cross-origin) iframe discovery
45
56
  try {
@@ -72,20 +83,41 @@ export class TabSessionService {
72
83
  // Domain manager already tracks via ensureDomain if needed externally
73
84
  }
74
85
  /**
75
- * Enable Target.setAutoAttach on a tab session to discover OOP iframes.
86
+ * Register Target.autoAttach event routing (idempotent per CDP client).
87
+ *
88
+ * `Target.attachedToTarget` events emitted by managed page sessions are
89
+ * translated into child-session registrations (OOP iframes);
90
+ * `Target.detachedFromTarget` prunes them. This is what feeds
91
+ * `captureFullTree`'s multi-frame snapshot and the uid → child-session
92
+ * routing used for cross-frame element interaction.
76
93
  */
77
- async setupAutoAttach(cdpClient, tabId) {
78
- const sessionId = await this.getSession(cdpClient, tabId);
79
- try {
80
- await cdpClient.send('Target.setAutoAttach', {
81
- autoAttach: true,
82
- waitForDebuggerOnStart: false,
83
- flatten: true,
84
- }, sessionId);
85
- }
86
- catch {
87
- // Older Chrome versions may not support auto-attach on page sessions
88
- }
94
+ wireAutoAttachEvents(cdpClient) {
95
+ if (this.wiredClients.has(cdpClient))
96
+ return;
97
+ this.wiredClients.add(cdpClient);
98
+ cdpClient.on('event', (event) => {
99
+ if (event.method === 'Target.attachedToTarget' && event.sessionId) {
100
+ const parentSessionId = event.sessionId;
101
+ // Only page sessions we manage — browser-level / foreign events ignored
102
+ if (!this.sessionToTab.has(parentSessionId))
103
+ return;
104
+ const params = event.params;
105
+ if (!params?.sessionId || !params.targetInfo?.targetId)
106
+ return;
107
+ if (params.targetInfo.type !== 'iframe')
108
+ return;
109
+ this.addChildSession(parentSessionId, params.targetInfo.targetId, params.sessionId, params.targetInfo.url ?? '');
110
+ }
111
+ else if (event.method === 'Target.detachedFromTarget') {
112
+ const params = event.params;
113
+ if (!params?.sessionId)
114
+ return;
115
+ const parentSessionId = this.getParentSession(params.sessionId);
116
+ if (parentSessionId) {
117
+ this.removeChildSession(parentSessionId, params.sessionId);
118
+ }
119
+ }
120
+ });
89
121
  }
90
122
  /** Track a child session (OOP iframe) under a parent session. */
91
123
  addChildSession(parentSessionId, childTargetId, childSessionId, url) {
@@ -148,6 +180,7 @@ export class TabSessionService {
148
180
  this.childSessions.delete(sessionId);
149
181
  }
150
182
  this.refSessionRouting.delete(sessionId);
183
+ this.sessionToTab.delete(sessionId);
151
184
  cdpClient?.unpoolSession(tabId);
152
185
  }
153
186
  this.sessions.delete(tabId);
@@ -167,6 +200,7 @@ export class TabSessionService {
167
200
  this.childSessions.clear();
168
201
  this.childToParent.clear();
169
202
  this.refSessionRouting.clear();
203
+ this.sessionToTab.clear();
170
204
  }
171
205
  /** Iterate over all [tabId, sessionId] pairs. */
172
206
  entries() {
@@ -1 +1 @@
1
- {"version":3,"file":"tab-session-service.js","sourceRoot":"","sources":["../../src/connection/tab-session-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tab-session-service.js","sourceRoot":"","sources":["../../src/connection/tab-session-service.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -30,6 +30,7 @@ import { SessionManager } from './session/session-manager.js';
30
30
  import { TabOwnership } from './session/tab-ownership.js';
31
31
  import { ModalStateManager } from './session/modal-state.js';
32
32
  import { HealthMonitor } from './connection/health-monitor.js';
33
+ import { DomainCapabilities } from './connection/capabilities.js';
33
34
  import { SnapshotCache } from './snapshot/cache.js';
34
35
  import { ToolRegistry } from './tools/registry.js';
35
36
  import { preprocessToolCall } from './tools/dispatch.js';
@@ -50,7 +51,7 @@ import { registerDebugTools } from './tools/debug.js';
50
51
  import { registerFormTools } from './tools/form.js';
51
52
  import { getSlimTools, mapSlimToFull } from './tools/slim-mode.js';
52
53
  // ─── Bootstrap ──────────────────────────────────────────────────────
53
- const VERSION = '5.0.3';
54
+ const VERSION = '5.1.0';
54
55
  const config = loadConfig();
55
56
  const cdpClient = new CDPClient({ commandTimeout: config.globalTimeout });
56
57
  // Lazy initialization: HealthMonitor is created but doesn't discover browsers
@@ -64,6 +65,8 @@ const healthMonitor = new HealthMonitor(cdpClient, {
64
65
  const domainManager = new DomainManager();
65
66
  const tabSessionService = new TabSessionService();
66
67
  const snapshotCache = new SnapshotCache();
68
+ // CDP domain capability report (5.1.0 B1) — invalidated on disconnect below
69
+ const capabilities = new DomainCapabilities();
67
70
  const registry = new ToolRegistry();
68
71
  // Wire auto-reconnect: when the WebSocket drops, let HealthMonitor retry
69
72
  // and clear domain state since all sessions are invalidated
@@ -74,6 +77,7 @@ cdpClient.on('disconnected', () => {
74
77
  eventPipelineWired = false;
75
78
  domainManager.clearAll();
76
79
  snapshotCache.clear();
80
+ capabilities.clear();
77
81
  tabSessionService.clear();
78
82
  healthMonitor.onDisconnect().catch(() => {
79
83
  // Reconnect failed — next tool call will trigger autoConnect
@@ -406,6 +410,7 @@ function wireEventPipeline(serverCtx) {
406
410
  }
407
411
  // ─── Server Context (DI container) ──────────────────────────────────
408
412
  const ctx = {
413
+ capabilities,
409
414
  config,
410
415
  cdpClient,
411
416
  healthMonitor,
@@ -422,6 +427,7 @@ const ctx = {
422
427
  networkReqs: new Map(),
423
428
  downloads: new Map(),
424
429
  pendingDialogs: new Map(),
430
+ findState: new Map(),
425
431
  pendingFileChoosers: new Map(),
426
432
  pausedTabs: new Map(),
427
433
  pendingFetchRequests: new Map(),
@@ -442,12 +448,13 @@ async function ensureConnected() {
442
448
  }
443
449
  }
444
450
  // ─── Demo Tools ─────────────────────────────────────────────────────
451
+ const AUTO_CONNECT_HINT = '\nBrowser connects automatically when you use any browser tool — just call tabs.list or page.goto.';
445
452
  registry.register(defineTool({
446
453
  name: 'ping',
447
454
  description: 'Health check. Returns server version and connection status.',
448
455
  inputSchema: { type: 'object', properties: {} },
449
456
  handler: async () => success(`pong — CDP Browser MCP v${VERSION}\nConnected: ${cdpClient.isConnected}` +
450
- (cdpClient.isConnected ? `\nMode: ${healthMonitor.connectionMode}` : '')),
457
+ (cdpClient.isConnected ? `\nMode: ${healthMonitor.connectionMode}` : AUTO_CONNECT_HINT)),
451
458
  }));
452
459
  registry.register(defineTool({
453
460
  name: 'status',
@@ -459,13 +466,41 @@ registry.register(defineTool({
459
466
  `Connected: ${cdpClient.isConnected}`,
460
467
  ...(cdpClient.isConnected
461
468
  ? [`Connection mode: ${healthMonitor.connectionMode}`]
462
- : []),
469
+ : [AUTO_CONNECT_HINT.trim()]),
463
470
  `Process scan: ${config.processScan ? 'on' : 'off'}`,
464
471
  `Default timeout: ${config.globalTimeout}ms`,
465
472
  `Default cleanup: ${config.defaultCleanupStrategy}`,
466
473
  `Session TTL: ${config.sessionTTL}ms`,
467
474
  `Registered tools: ${registry.size}`,
468
475
  ];
476
+ if (cdpClient.isConnected) {
477
+ try {
478
+ // Probe through a managed page session - the browser-level endpoint
479
+ // only serves browser-wide domains, so page-scoped domains (Overlay,
480
+ // FindInPage, Ads, ...) report "wasn't found" without one.
481
+ let firstSession = tabSessionService.entries().next().value?.[1];
482
+ if (!firstSession) {
483
+ // No managed tab yet - attach to any open page tab just for probing
484
+ // (canaries are read-only or validation-rejected; attaching is inert)
485
+ try {
486
+ const { targetInfos } = (await cdpClient.send('Target.getTargets', {}));
487
+ const pageTarget = targetInfos?.find((t) => t.type === 'page');
488
+ if (pageTarget) {
489
+ firstSession = (await tabSessionService.getSession(cdpClient, pageTarget.targetId));
490
+ }
491
+ }
492
+ catch { /* fall back to browser-level probe */ }
493
+ }
494
+ const { count, missing } = await capabilities.summarize(cdpClient, firstSession);
495
+ lines.push(`CDP features (probed${firstSession ? ' on page session' : ' browser-level - no page session'}): ${count}/${count + missing.length}`);
496
+ if (missing.length > 0) {
497
+ lines.push(`Notable domains missing: ${missing.join(', ')}`);
498
+ }
499
+ }
500
+ catch (e) {
501
+ lines.push('CDP features: unavailable (' + (e instanceof Error ? e.message : String(e)) + ')');
502
+ }
503
+ }
469
504
  return success(lines.join('\n'));
470
505
  },
471
506
  }));
@@ -506,7 +541,12 @@ else {
506
541
  registerFormTools(registry, ctx);
507
542
  }
508
543
  // ─── MCP Server─────────────────────────────────────────────────────
509
- const server = new Server({ name: 'cdp-browser', version: VERSION }, { capabilities: { tools: {} } });
544
+ const server = new Server({ name: 'cdp-browser', version: VERSION }, {
545
+ capabilities: { tools: {} },
546
+ instructions: `CDP Browser MCP attaches your REAL running browser (cookies, logins, extensions stay). 14 tools: tabs, page, interact, form, execute, observe, emulate, storage, intercept, debug, browser, cleanup, ping, status. The browser connects automatically on the first browser-tool call - ping/status may say Connected: false before that; just call any browser tool.
547
+
548
+ CALLING CONVENTION (critical): every tool is ONE tool with an action enum parameter - there are NO per-action subtools. Call like tools["cdp-browser"].tabs({ action: "list" }), tools["cdp-browser"].page({ action: "goto", tabId, url }), tools["cdp-browser"].interact({ action: "click", tabId, uid }). WRONG: tabs.list(), tabs(), page.goto(url) - these tool names do not exist and fail schema validation. If unsure of an action or parameter, read the tool's description/enum first; tabs without action defaults to listing. Two connection modes: launch flag (--remote-debugging-port + explicit --user-data-dir) or the browser built-in chrome://inspect/#remote-debugging toggle (a permission dialog appears - click Allow).`,
549
+ });
510
550
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
511
551
  tools: config.slimMode
512
552
  ? registry.list().filter(t => t.name.startsWith('browser_') || t.name === 'ping' || t.name === 'status')