cdp-toolkit 1.11.0 → 2.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.
package/src/manifest.ts CHANGED
@@ -25,21 +25,21 @@ export interface ToolSpec {
25
25
  export const MANIFEST: ToolSpec[] = [
26
26
  {
27
27
  "name": "list_pages",
28
- "description": "Enumerate browser page targets (GET /json/list); page-type tabs only unless all=true. Each entry carries its targetId plus an origin field: 'agent' means this toolkit created it (also carries the creating label/createdAt, and stays 'agent' after the lease is released or the creator dies, making stray agent tabs findable), 'unknown' means no creation record - it never says 'human', the honest word for any tab it did not create; a record that exists but won't read adds originUnreadable. An entry under an active, readable lease also carries a 'lease' object {label,pid,idleMs,expiresAt,stale}, with idleMs and expiresAt computed fresh every call (never off disk), independent of probe. Under CDP_REQUIRE_LEASE this call also reaps abandoned agent tabs into an additive reaped array - but a lease reads reclaimable the moment its TTL elapses, while the tab is CLOSED only after a further grace (CDP_REAP_GRACE_MS, default 2700000ms/45min, so 60min total after last use); a dead-pid lease is reaped at once, a tab with no lease never. With probe, each page-type entry also gets 'responsive' (and humanActiveMs where human input is seen); both are absent, never false/null, without probe.",
28
+ "description": "List browser page targets; optionally include non-page targets and probe responsiveness.",
29
29
  "inputSchema": {
30
30
  "type": "object",
31
31
  "properties": {
32
32
  "lease": {
33
33
  "type": "string",
34
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
34
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
35
35
  },
36
36
  "all": {
37
37
  "type": "boolean",
38
- "description": "Include non-page targets (service/shared workers, background pages); default false lists page-type tabs only."
38
+ "description": "Include non-page targets."
39
39
  },
40
40
  "probe": {
41
41
  "type": "boolean",
42
- "description": "Ping each page-type renderer before returning, one bounded 500ms check per target and never more, so a wedged tab can't stall the listing. Adds 'responsive' (false on timeout/exception/unreachable, never an error for the whole call) and, where the same round trip finds human input, humanActiveMs. Default false. On a backend that cannot answer the ping, responsive is absent too (not false)."
42
+ "description": "Probe renderer responsiveness."
43
43
  }
44
44
  },
45
45
  "required": [],
@@ -48,29 +48,29 @@ export const MANIFEST: ToolSpec[] = [
48
48
  },
49
49
  {
50
50
  "name": "new_page",
51
- "description": "Open a new browser tab via Target.createTarget and return {targetId,url}. Defaults to about:blank; navigation is not awaited here (use navigate_page to load and wait).",
51
+ "description": "Open a browser tab, optionally claim it; navigation is not awaited.",
52
52
  "inputSchema": {
53
53
  "type": "object",
54
54
  "properties": {
55
55
  "lease": {
56
56
  "type": "string",
57
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
57
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
58
58
  },
59
59
  "url": {
60
60
  "type": "string",
61
- "description": "URL to open in the new tab; defaults to about:blank."
61
+ "description": "URL value."
62
62
  },
63
63
  "claim": {
64
64
  "type": "boolean",
65
- "description": "Claim the new tab atomically and return a lease token alongside {targetId,url}. Under CDP_REQUIRE_LEASE the tab is claimed and a lease returned even without claim:true; claim:true makes it an EXPLICIT lease that demands its token on every later call, even from this process. Default false."
65
+ "description": "Claim the new tab."
66
66
  },
67
67
  "label": {
68
68
  "type": "string",
69
- "description": "Agent label recorded on the lease when the tab is claimed; surfaced in conflict errors and list_leases. Defaults to pid-<pid>."
69
+ "description": "Agent lease label."
70
70
  },
71
71
  "ttlMs": {
72
72
  "type": "number",
73
- "description": "How long a claimed lease survives without use before it is reclaimable. Defaults to CDP_LEASE_TTL_MS, else 900000 (15min); every checked call refreshes it. Ignored when not claiming."
73
+ "description": "Lease TTL in milliseconds."
74
74
  }
75
75
  },
76
76
  "required": [],
@@ -79,17 +79,17 @@ export const MANIFEST: ToolSpec[] = [
79
79
  },
80
80
  {
81
81
  "name": "close_page",
82
- "description": "Close a page target via Target.closeTarget. Requires an explicit, resolvable target; errors rather than guessing when the selector matches nothing.",
82
+ "description": "Close a selected page; target must resolve explicitly.",
83
83
  "inputSchema": {
84
84
  "type": "object",
85
85
  "properties": {
86
86
  "lease": {
87
87
  "type": "string",
88
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
88
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
89
89
  },
90
90
  "target": {
91
91
  "type": "string",
92
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
92
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
93
93
  }
94
94
  },
95
95
  "required": [
@@ -100,17 +100,17 @@ export const MANIFEST: ToolSpec[] = [
100
100
  },
101
101
  {
102
102
  "name": "select_page",
103
- "description": "Activate/focus a page target via Target.activateTarget and persist its bare targetId to the selected-state file (CDP_STATE_DIR/selected). Requires an explicit, resolvable target.",
103
+ "description": "Focus a selected page and persist it as active; target must resolve explicitly.",
104
104
  "inputSchema": {
105
105
  "type": "object",
106
106
  "properties": {
107
107
  "lease": {
108
108
  "type": "string",
109
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
109
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
110
110
  },
111
111
  "target": {
112
112
  "type": "string",
113
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
113
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
114
114
  }
115
115
  },
116
116
  "required": [
@@ -121,25 +121,25 @@ export const MANIFEST: ToolSpec[] = [
121
121
  },
122
122
  {
123
123
  "name": "navigate_page",
124
- "description": "Navigate a target page to a URL (Page.navigate), reload it (reload:true), OR go back/forward in its session history (history:'back'|'forward'), then wait for the load milestone with a bounded timeout so a wedged renderer can't hang. Exactly one of url / reload / history per call. Returns {url,frameId,waitedFor} (plus reloaded:true on a reload, traversed:'back'|'forward' on a history move); waitUntil supports 'load'|'domcontentloaded' only (no 'networkidle'), and there is no auto-snapshot of the new page. Pass reload:true with ignoreCache:true for a hard reload that refetches every subresource (e.g. to pick up a freshly-deployed, non-content-hashed bundle the HTTP cache would serve stale).",
124
+ "description": "Navigate, reload, or traverse page history; choose exactly one operation.",
125
125
  "inputSchema": {
126
126
  "type": "object",
127
127
  "properties": {
128
128
  "lease": {
129
129
  "type": "string",
130
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
130
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
131
131
  },
132
132
  "target": {
133
133
  "type": "string",
134
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
134
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
135
135
  },
136
136
  "url": {
137
137
  "type": "string",
138
- "description": "Destination URL to navigate to. Required unless reload:true."
138
+ "description": "URL value."
139
139
  },
140
140
  "reload": {
141
141
  "type": "boolean",
142
- "description": "Reload the current page (Page.reload) instead of navigating to url. Default false."
142
+ "description": "Reload before capture."
143
143
  },
144
144
  "history": {
145
145
  "type": "string",
@@ -147,11 +147,11 @@ export const MANIFEST: ToolSpec[] = [
147
147
  "back",
148
148
  "forward"
149
149
  ],
150
- "description": "Traverse this tab's session history instead of loading a url: 'back' and 'forward' are the browser's Back and Forward buttons. Mutually exclusive with 'url' and 'reload' — passing two of the three is refused by name, not resolved by precedence. Works on BOTH backends and waits for the same load milestone as an ordinary navigation. Going back from the first entry, or forward from the last, is an ERROR naming the direction — never a silent no-op. The result carries traversed:'back'|'forward' alongside the resulting url."
150
+ "description": "History direction."
151
151
  },
152
152
  "ignoreCache": {
153
153
  "type": "boolean",
154
- "description": "On reload, bypass the HTTP cache (hard reload) so subresources are refetched. Ignored unless reload:true. Default false."
154
+ "description": "Bypass cache on reload."
155
155
  },
156
156
  "waitUntil": {
157
157
  "type": "string",
@@ -159,11 +159,11 @@ export const MANIFEST: ToolSpec[] = [
159
159
  "load",
160
160
  "domcontentloaded"
161
161
  ],
162
- "description": "Which load milestone to wait for. Defaults to 'load'. No 'networkidle' support."
162
+ "description": "Load milestone."
163
163
  },
164
164
  "timeoutMs": {
165
165
  "type": "number",
166
- "description": "Override the navigation timeout in milliseconds."
166
+ "description": "Timeout in milliseconds."
167
167
  }
168
168
  },
169
169
  "additionalProperties": false
@@ -171,29 +171,29 @@ export const MANIFEST: ToolSpec[] = [
171
171
  },
172
172
  {
173
173
  "name": "wait_for",
174
- "description": "Poll the target until the substring appears in document.body.innerText (Runtime.evaluate on a fixed interval), or throw on timeout. Text-substring only -- no aria/role/selector or event variants; throws rather than returning {found:false}.",
174
+ "description": "Wait for a text substring in document.body.innerText; timeout throws.",
175
175
  "inputSchema": {
176
176
  "type": "object",
177
177
  "properties": {
178
178
  "lease": {
179
179
  "type": "string",
180
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
180
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
181
181
  },
182
182
  "target": {
183
183
  "type": "string",
184
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
184
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
185
185
  },
186
186
  "text": {
187
187
  "type": "string",
188
- "description": "Substring to wait for in document.body.innerText. Required."
188
+ "description": "Text substring."
189
189
  },
190
190
  "timeoutMs": {
191
191
  "type": "number",
192
- "description": "Total time budget in ms. Default 15000."
192
+ "description": "Timeout in milliseconds."
193
193
  },
194
194
  "pollMs": {
195
195
  "type": "number",
196
- "description": "Poll interval in ms. Default 250."
196
+ "description": "Polling interval in milliseconds."
197
197
  }
198
198
  },
199
199
  "required": [
@@ -204,37 +204,37 @@ export const MANIFEST: ToolSpec[] = [
204
204
  },
205
205
  {
206
206
  "name": "evaluate_script",
207
- "description": "Run arbitrary JavaScript in the target's main-world context over raw CDP and return the evaluated value (returnByValue). With no 'args', 'expression' is a raw expression; with 'args' it must be a function literal (arrow or classic) invoked on globalThis with args passed positionally. A thrown exception surfaces as an error; non-serializable returns (DOM nodes, functions) come back as their CDP description string. savePath writes the value to a JSON file instead -- the response then carries only {path,bytes,type,target} and the value never appears in it, the way to read a credential (a JWT/session token from localStorage) without putting the secret in the transcript. This is the one tool that EVALUATES inside an MV3 extension's background SERVICE WORKER rather than OBSERVING it (Chrome, Capability 'worker.targets'): a worker: target reads chrome.storage.local, chrome.runtime and the worker's own globals directly, with an idle-evicted worker started first (see 'wake').",
207
+ "description": "Evaluate JavaScript in a page or Chrome worker; args require a function literal.",
208
208
  "inputSchema": {
209
209
  "type": "object",
210
210
  "properties": {
211
211
  "lease": {
212
212
  "type": "string",
213
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
213
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
214
214
  },
215
215
  "target": {
216
216
  "type": "string",
217
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', '<targetId>'; plus 'worker:<substring>' to reach a service/shared worker (e.g. an MV3 extension background worker). The worker: arm is CHROME-ONLY (Capability 'worker.targets'). Grammar: see server instructions."
217
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
218
218
  },
219
219
  "wake": {
220
220
  "type": "boolean",
221
- "description": "Worker targets only, when starting a capture. Default true: an idle-evicted MV3 service worker exists in no target listing, so it is started first (ServiceWorker.startWorker) and re-confirmed; false fails fast. Rejected on a page target, a bare target id, or a read-only call. See server instructions."
221
+ "description": "Wake worker before capture."
222
222
  },
223
223
  "expression": {
224
224
  "type": "string",
225
- "description": "JavaScript to run. Evaluated as an expression when 'args' is omitted; must be a function literal (arrow or classic) whose parameters receive 'args' when provided. REQUIRED -- the code always goes in this key, never in 'function', 'code', 'js', 'script', 'fn' or 'body'; a call using one of those is rejected with an error naming the wrong key."
225
+ "description": "JavaScript expression or function."
226
226
  },
227
227
  "awaitPromise": {
228
228
  "type": "boolean",
229
- "description": "Await the result if it is a Promise. Default true."
229
+ "description": "Await Promise results."
230
230
  },
231
231
  "args": {
232
232
  "type": "array",
233
- "description": "Positional JSON-serializable arguments passed to the expression (treated as a function). No live element/page handle is bound."
233
+ "description": "Positional JSON arguments."
234
234
  },
235
235
  "savePath": {
236
236
  "type": "string",
237
- "description": "Write the evaluated value to this file as JSON and KEEP IT OUT OF THE RESPONSE: the result is {path,bytes,type,target} only, with no copy, preview or truncation of the value -- read credentials without putting them in a transcript. An absolute path (starting with /) is used as-is; a relative path resolves under the artifact dir (/tmp/cdp-toolkit); missing parents are created. Omit to get the value back inline."
237
+ "description": "Output file path."
238
238
  }
239
239
  },
240
240
  "required": [
@@ -245,29 +245,29 @@ export const MANIFEST: ToolSpec[] = [
245
245
  },
246
246
  {
247
247
  "name": "list_cookies",
248
- "description": "Read the target page's cookie store INCLUDING httpOnly cookies, which document.cookie (and therefore evaluate_script) cannot see. Page-scoped, not browser-wide: returns cookies of the resolved tab, so point at a page on the site you want. Each cookie carries name, value, domain, path, expires (Unix seconds, -1 for a session cookie), size, httpOnly, secure, sameSite ('strict'|'lax'|'none'|'default'), session. Filter with 'domain' and/or 'name'. Pass 'savePath' to write the array to a JSON file instead: the response is then {path,bytes,count,target} with no cookie value in any form, the way to capture a session cookie without putting the credential in the transcript.",
248
+ "description": "Read cookies for a selected page, including httpOnly values; savePath keeps values out of the response.",
249
249
  "inputSchema": {
250
250
  "type": "object",
251
251
  "properties": {
252
252
  "lease": {
253
253
  "type": "string",
254
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
254
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
255
255
  },
256
256
  "target": {
257
257
  "type": "string",
258
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
258
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
259
259
  },
260
260
  "domain": {
261
261
  "type": "string",
262
- "description": "Keep only cookies for this domain. A leading dot is ignored on both sides and subdomains match too, so 'example.test' matches '.example.test' and 'app.example.test'. No wildcards."
262
+ "description": "Cookie domain."
263
263
  },
264
264
  "name": {
265
265
  "type": "string",
266
- "description": "Keep only the cookie with exactly this name. Exact match, not a substring."
266
+ "description": "Cookie name."
267
267
  },
268
268
  "savePath": {
269
269
  "type": "string",
270
- "description": "Write the cookie array here as JSON and KEEP THE VALUES OUT OF THE RESPONSE: the result is {path,bytes,count,target} only, with no preview or truncation of any value. An absolute path (starting with /) is used as-is; a relative path resolves under the artifact dir (/tmp/cdp-toolkit); missing parents are created. Omit to get the cookies back inline."
270
+ "description": "Output file path."
271
271
  }
272
272
  },
273
273
  "required": [],
@@ -276,49 +276,49 @@ export const MANIFEST: ToolSpec[] = [
276
276
  },
277
277
  {
278
278
  "name": "set_cookie",
279
- "description": "Write one cookie into the target page's cookie store, INCLUDING httpOnly or secure cookies that document.cookie (and therefore evaluate_script) cannot create. Either 'url' or 'domain' is REQUIRED: the call is refused when neither is given, rather than guessing the page origin. The response is {set:true,target} and never echoes the value back. A 'set:true' is earned, not assumed: Chrome raises an error when it declines the cookie (a domain the url does not belong to, a secure cookie on an insecure origin, an oversized value). On Firefox 'domain' is derived from 'url' when only the url was given (BiDi has no url parameter), and a url with no host such as about:blank or a data URL is an error, not a silent no-op. Read the result back with list_cookies when you need proof.",
279
+ "description": "Set one page cookie, including httpOnly or secure flags; provide url or domain.",
280
280
  "inputSchema": {
281
281
  "type": "object",
282
282
  "properties": {
283
283
  "lease": {
284
284
  "type": "string",
285
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
285
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
286
286
  },
287
287
  "target": {
288
288
  "type": "string",
289
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
289
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
290
290
  },
291
291
  "name": {
292
292
  "type": "string",
293
- "description": "Cookie name. Required and non-empty."
293
+ "description": "Cookie name."
294
294
  },
295
295
  "value": {
296
296
  "type": "string",
297
- "description": "Cookie value. Required. It is not echoed back in the response."
297
+ "description": "Cookie value."
298
298
  },
299
299
  "url": {
300
300
  "type": "string",
301
- "description": "URL the cookie is set for, e.g. 'https://example.com/'. Chrome derives domain, path and secure from it; Firefox derives only the domain from its host. Give this or 'domain'."
301
+ "description": "URL value."
302
302
  },
303
303
  "domain": {
304
304
  "type": "string",
305
- "description": "Cookie domain, e.g. 'example.com' or '.example.com' for subdomains. Give this or 'url'. When both are given, this wins on Firefox and Chrome applies its own url plus domain consistency rule."
305
+ "description": "Cookie domain."
306
306
  },
307
307
  "path": {
308
308
  "type": "string",
309
- "description": "Cookie path, passed through exactly as given and NOT defaulted to '/': with a 'url' Chrome derives the path from it, so an invented default here would widen a cookie you meant to scope narrowly."
309
+ "description": "Cookie path."
310
310
  },
311
311
  "expires": {
312
312
  "type": "number",
313
- "description": "Expiry as Unix time in SECONDS, matching what list_cookies reports. Omit for a session cookie, which is what both backends do when no expiry is supplied."
313
+ "description": "Expiry Unix time in seconds."
314
314
  },
315
315
  "httpOnly": {
316
316
  "type": "boolean",
317
- "description": "Set the httpOnly flag, making the cookie invisible to document.cookie. Only a protocol write like this one can create such a cookie."
317
+ "description": "Set HttpOnly flag."
318
318
  },
319
319
  "secure": {
320
320
  "type": "boolean",
321
- "description": "Set the secure flag. Chrome declines a secure cookie on an insecure origin, and that refusal surfaces as an error."
321
+ "description": "Set Secure flag."
322
322
  },
323
323
  "sameSite": {
324
324
  "type": "string",
@@ -328,7 +328,7 @@ export const MANIFEST: ToolSpec[] = [
328
328
  "none",
329
329
  "default"
330
330
  ],
331
- "description": "SameSite attribute, lowercase, matching what list_cookies reports. 'default' means the attribute is not set at all."
331
+ "description": "SameSite attribute."
332
332
  }
333
333
  },
334
334
  "required": [
@@ -340,33 +340,33 @@ export const MANIFEST: ToolSpec[] = [
340
340
  },
341
341
  {
342
342
  "name": "delete_cookies",
343
- "description": "Delete the named cookie from the target page's cookie store, httpOnly cookies included. Both 'name' and one of 'url' or 'domain' are REQUIRED: without a site constraint it would delete by name across the whole partition, so it is refused with an error instead. Narrow further with 'path'. The response is {deleted:true,target} and carries NO count, because neither protocol reports how many cookies it removed and a number here would be invented; call list_cookies before and after for a real count. 'deleted:true' means the backend accepted and performed the deletion, not that a matching cookie existed, since deleting an absent cookie succeeds on both backends.",
343
+ "description": "Delete a named page cookie; provide name and url or domain.",
344
344
  "inputSchema": {
345
345
  "type": "object",
346
346
  "properties": {
347
347
  "lease": {
348
348
  "type": "string",
349
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
349
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
350
350
  },
351
351
  "target": {
352
352
  "type": "string",
353
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
353
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
354
354
  },
355
355
  "name": {
356
356
  "type": "string",
357
- "description": "Exact cookie name to delete. Required and non-empty. No wildcards: this removes a named cookie, not a swathe of them."
357
+ "description": "Cookie name."
358
358
  },
359
359
  "url": {
360
360
  "type": "string",
361
- "description": "Delete cookies matching this URL, e.g. 'https://example.com/'. Give this or 'domain'. On Firefox only the host is used, because BiDi's filter has no url field."
361
+ "description": "URL value."
362
362
  },
363
363
  "domain": {
364
364
  "type": "string",
365
- "description": "Delete cookies with this exact domain. Give this or 'url'."
365
+ "description": "Cookie domain."
366
366
  },
367
367
  "path": {
368
368
  "type": "string",
369
- "description": "Narrow the deletion to cookies with this exact path. Omit to match any path allowed by the other constraints."
369
+ "description": "Cookie path."
370
370
  }
371
371
  },
372
372
  "required": [
@@ -377,21 +377,21 @@ export const MANIFEST: ToolSpec[] = [
377
377
  },
378
378
  {
379
379
  "name": "take_snapshot",
380
- "description": "Captures the page's accessibility tree as an indented text tree, each line prefixed [uid] (a CDP backendDOMNodeId). Every interaction tool (click/hover/fill/etc.) resolves that uid via DOM.resolveNode — run this first to discover uids to act on.",
380
+ "description": "Capture the page accessibility tree with interaction UIDs.",
381
381
  "inputSchema": {
382
382
  "type": "object",
383
383
  "properties": {
384
384
  "lease": {
385
385
  "type": "string",
386
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
386
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
387
387
  },
388
388
  "target": {
389
389
  "type": "string",
390
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
390
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
391
391
  },
392
392
  "interactiveOnly": {
393
393
  "type": "boolean",
394
- "description": "When true, emit only interactive/meaningful nodes as a flat list; default false returns the full hierarchical tree."
394
+ "description": "Only interactive nodes."
395
395
  }
396
396
  },
397
397
  "required": [],
@@ -400,25 +400,25 @@ export const MANIFEST: ToolSpec[] = [
400
400
  },
401
401
  {
402
402
  "name": "click",
403
- "description": "Click an element via a synthetic mouse press/release at its scrolled-into-view center. Give exactly one of uid or selector. modifiers (Alt/Control/Meta/Shift) throws on the Firefox backend — use --browser chrome for a modifier-click. clickCount:3 triple-clicks (selects a line/paragraph in most editors).",
403
+ "description": "Click an element by UID or CSS selector; provide exactly one.",
404
404
  "inputSchema": {
405
405
  "type": "object",
406
406
  "properties": {
407
407
  "lease": {
408
408
  "type": "string",
409
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
409
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
410
410
  },
411
411
  "target": {
412
412
  "type": "string",
413
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
413
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
414
414
  },
415
415
  "uid": {
416
416
  "type": "number",
417
- "description": "CDP backendDOMNodeId of the element to click, from take_snapshot. Exactly one of uid or selector."
417
+ "description": "Element backendDOMNodeId."
418
418
  },
419
419
  "selector": {
420
420
  "type": "string",
421
- "description": "CSS selector for the element to click (document.querySelector). Exactly one of uid or selector."
421
+ "description": "CSS selector."
422
422
  },
423
423
  "button": {
424
424
  "type": "string",
@@ -427,11 +427,11 @@ export const MANIFEST: ToolSpec[] = [
427
427
  "right",
428
428
  "middle"
429
429
  ],
430
- "description": "Mouse button: 'left' (default), 'right', or 'middle'."
430
+ "description": "Mouse button."
431
431
  },
432
432
  "clickCount": {
433
433
  "type": "number",
434
- "description": "Number of clicks: 1 (default), 2 = double-click, 3 = triple-click."
434
+ "description": "Click count."
435
435
  },
436
436
  "modifiers": {
437
437
  "type": "array",
@@ -444,7 +444,7 @@ export const MANIFEST: ToolSpec[] = [
444
444
  "Shift"
445
445
  ]
446
446
  },
447
- "description": "Modifier keys held for the click's press and release, e.g. ['Shift']. Non-empty on the Firefox backend throws — not supported over BiDi."
447
+ "description": "Modifier keys: Control|Ctrl|Shift|Alt|Meta|Cmd."
448
448
  }
449
449
  },
450
450
  "required": [],
@@ -453,25 +453,25 @@ export const MANIFEST: ToolSpec[] = [
453
453
  },
454
454
  {
455
455
  "name": "hover",
456
- "description": "Hovers the mouse over an element by dispatching a mouseMoved event at its scrolled-into-view center, firing framework hover handlers. Give exactly one of uid or selector.",
456
+ "description": "Hover an element by UID or CSS selector; provide exactly one.",
457
457
  "inputSchema": {
458
458
  "type": "object",
459
459
  "properties": {
460
460
  "lease": {
461
461
  "type": "string",
462
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
462
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
463
463
  },
464
464
  "target": {
465
465
  "type": "string",
466
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
466
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
467
467
  },
468
468
  "uid": {
469
469
  "type": "number",
470
- "description": "CDP backendDOMNodeId of the element to hover, from take_snapshot. Exactly one of uid or selector."
470
+ "description": "Element backendDOMNodeId."
471
471
  },
472
472
  "selector": {
473
473
  "type": "string",
474
- "description": "CSS selector for the element to hover (document.querySelector). Exactly one of uid or selector."
474
+ "description": "CSS selector."
475
475
  }
476
476
  },
477
477
  "required": [],
@@ -480,67 +480,67 @@ export const MANIFEST: ToolSpec[] = [
480
480
  },
481
481
  {
482
482
  "name": "drag",
483
- "description": "Drags from a source element to a destination or by an offset. mode:'mouse' (default) dispatches synthetic mouse press/move/release; at the default steps:2 an HTML5 drop zone (dragover preventDefault) gets ZERO dragover events and refuses the drop. mode:'html5' replays real dragstart/dragEnter/dragOver/drop with the page's own dataTransfer instead — deterministic regardless of pointer path, but CHROME-ONLY (rejected with a clear error on the Firefox backend). 'from' takes uid or selector; destination is exactly one of 'to' (uid/selector/x+y) or 'by' ({dx,dy} offset — sliders, map panning, resize handles).",
483
+ "description": "Drag from an element to a destination or offset; html5 mode is Chrome-only.",
484
484
  "inputSchema": {
485
485
  "type": "object",
486
486
  "properties": {
487
487
  "lease": {
488
488
  "type": "string",
489
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
489
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
490
490
  },
491
491
  "target": {
492
492
  "type": "string",
493
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
493
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
494
494
  },
495
495
  "from": {
496
496
  "type": "object",
497
- "description": "Source element to drag from. Exactly one of uid or selector.",
497
+ "description": "Drag source.",
498
498
  "properties": {
499
499
  "uid": {
500
500
  "type": "number",
501
- "description": "CDP backendDOMNodeId of the source element, obtained from take_snapshot."
501
+ "description": "Element backendDOMNodeId."
502
502
  },
503
503
  "selector": {
504
504
  "type": "string",
505
- "description": "CSS selector for the source element (resolved via document.querySelector)."
505
+ "description": "CSS selector."
506
506
  }
507
507
  },
508
508
  "additionalProperties": false
509
509
  },
510
510
  "to": {
511
511
  "type": "object",
512
- "description": "Where the drag ends: exactly one of uid, selector, or x+y. Mutually exclusive with 'by'; exactly one of to/by required.",
512
+ "description": "Drag destination.",
513
513
  "properties": {
514
514
  "uid": {
515
515
  "type": "number",
516
- "description": "CDP backendDOMNodeId of the destination element, obtained from take_snapshot."
516
+ "description": "Element backendDOMNodeId."
517
517
  },
518
518
  "selector": {
519
519
  "type": "string",
520
- "description": "CSS selector for the destination element (resolved via document.querySelector)."
520
+ "description": "CSS selector."
521
521
  },
522
522
  "x": {
523
523
  "type": "number",
524
- "description": "Absolute viewport x-coordinate to drop at. Must be given together with 'y'. Use this when there is no droppable element to name (a canvas, a slider track)."
524
+ "description": "Viewport x-coordinate."
525
525
  },
526
526
  "y": {
527
527
  "type": "number",
528
- "description": "Absolute viewport y-coordinate to drop at. Must be given together with 'x'."
528
+ "description": "Viewport y-coordinate."
529
529
  }
530
530
  },
531
531
  "additionalProperties": false
532
532
  },
533
533
  "by": {
534
534
  "type": "object",
535
- "description": "Offset from the source element's center: at least one of dx/dy (other defaults to 0). Mutually exclusive with 'to'; exactly one of to/by required. For sliders (by:{dx:40}), map panning, resize handles.",
535
+ "description": "Drag offset.",
536
536
  "properties": {
537
537
  "dx": {
538
538
  "type": "number",
539
- "description": "Horizontal offset in CSS pixels; positive drags RIGHT."
539
+ "description": "Horizontal drag offset."
540
540
  },
541
541
  "dy": {
542
542
  "type": "number",
543
- "description": "Vertical offset in CSS pixels; positive drags DOWN."
543
+ "description": "Vertical drag offset."
544
544
  }
545
545
  },
546
546
  "additionalProperties": false
@@ -551,11 +551,11 @@ export const MANIFEST: ToolSpec[] = [
551
551
  "mouse",
552
552
  "html5"
553
553
  ],
554
- "description": "'mouse' (default): synthetic mouse press/move/release — at steps:2 an HTML5 drop zone sees zero dragover events and refuses the drop. 'html5': real HTML5 drag-and-drop, deterministic regardless of pointer path, CHROME-ONLY (rejected on Firefox)."
554
+ "description": "Drag mode."
555
555
  },
556
556
  "steps": {
557
557
  "type": "number",
558
- "description": "Number of interpolated mouse-move events between source and destination, evenly spaced, last landing on the destination. Integer 1-500, default 2. Raise for DnD libraries with a movement threshold or per-frame sampling."
558
+ "description": "Interpolation steps."
559
559
  }
560
560
  },
561
561
  "required": [
@@ -566,41 +566,41 @@ export const MANIFEST: ToolSpec[] = [
566
566
  },
567
567
  {
568
568
  "name": "scroll",
569
- "description": "Dispatches a wheel/scroll event at an anchor point — element (uid/selector) or x+y, scrolled into view first if an element; omit all three for viewport center. At least one of deltaX/deltaY required: positive deltaY scrolls DOWN, positive deltaX scrolls RIGHT (wheel-event convention — easy to invert). Returns the resolved anchor {x,y} plus the delta actually dispatched.",
569
+ "description": "Dispatch a wheel event at an element or coordinate anchor; provide deltaX or deltaY.",
570
570
  "inputSchema": {
571
571
  "type": "object",
572
572
  "properties": {
573
573
  "lease": {
574
574
  "type": "string",
575
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
575
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
576
576
  },
577
577
  "target": {
578
578
  "type": "string",
579
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
579
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
580
580
  },
581
581
  "uid": {
582
582
  "type": "number",
583
- "description": "CDP backendDOMNodeId of the element to scroll into view and anchor at, from take_snapshot. At most one of uid, selector, or x+y."
583
+ "description": "Element backendDOMNodeId."
584
584
  },
585
585
  "selector": {
586
586
  "type": "string",
587
- "description": "CSS selector for the element to anchor at (document.querySelector). At most one of uid, selector, or x+y."
587
+ "description": "CSS selector."
588
588
  },
589
589
  "x": {
590
590
  "type": "number",
591
- "description": "Absolute viewport x-coordinate to anchor at; must be given with y. At most one of uid, selector, or x+y."
591
+ "description": "Viewport x-coordinate."
592
592
  },
593
593
  "y": {
594
594
  "type": "number",
595
- "description": "Absolute viewport y-coordinate to anchor at; must be given with x. At most one of uid, selector, or x+y."
595
+ "description": "Viewport y-coordinate."
596
596
  },
597
597
  "deltaX": {
598
598
  "type": "number",
599
- "description": "Horizontal scroll delta; positive scrolls RIGHT. At least one of deltaX/deltaY required."
599
+ "description": "Horizontal scroll delta."
600
600
  },
601
601
  "deltaY": {
602
602
  "type": "number",
603
- "description": "Vertical scroll delta; positive scrolls DOWN. At least one of deltaX/deltaY required."
603
+ "description": "Vertical scroll delta."
604
604
  }
605
605
  },
606
606
  "required": [],
@@ -609,17 +609,17 @@ export const MANIFEST: ToolSpec[] = [
609
609
  },
610
610
  {
611
611
  "name": "dispatch_mouse",
612
- "description": "Dispatches one raw mouse event (move/down/up) at absolute viewport coordinates — the toolkit's lowest-level input primitive. Compose move/down/move/up calls yourself for anything click/drag's fixed sequences can't reach: canvas drag-painting, marquee/rubber-band selection, custom hit-testing widgets. Chrome-only: absent from tools/list under the Firefox backend, never present-and-throwing.",
612
+ "description": "Dispatch one raw mouse event at viewport coordinates; Chrome-only.",
613
613
  "inputSchema": {
614
614
  "type": "object",
615
615
  "properties": {
616
616
  "lease": {
617
617
  "type": "string",
618
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
618
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
619
619
  },
620
620
  "target": {
621
621
  "type": "string",
622
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
622
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
623
623
  },
624
624
  "action": {
625
625
  "type": "string",
@@ -628,15 +628,15 @@ export const MANIFEST: ToolSpec[] = [
628
628
  "down",
629
629
  "up"
630
630
  ],
631
- "description": "Which raw event to dispatch: 'move' (mouseMoved), 'down' (mousePressed), or 'up' (mouseReleased)."
631
+ "description": "Mouse action."
632
632
  },
633
633
  "x": {
634
634
  "type": "number",
635
- "description": "Viewport x-coordinate. Required every call — CDP has no 'current pointer position' to default from."
635
+ "description": "Viewport x-coordinate."
636
636
  },
637
637
  "y": {
638
638
  "type": "number",
639
- "description": "Viewport y-coordinate. Required every call."
639
+ "description": "Viewport y-coordinate."
640
640
  },
641
641
  "button": {
642
642
  "type": "string",
@@ -645,11 +645,11 @@ export const MANIFEST: ToolSpec[] = [
645
645
  "right",
646
646
  "middle"
647
647
  ],
648
- "description": "Mouse button: 'left' (default), 'right', or 'middle'."
648
+ "description": "Mouse button."
649
649
  },
650
650
  "clickCount": {
651
651
  "type": "number",
652
- "description": "Click-run length for a 'down' or 'up' event (2 = second half of a double-click, 3 = triple-click). Ignored for 'move'; defaults to 1."
652
+ "description": "Click count."
653
653
  },
654
654
  "modifiers": {
655
655
  "type": "array",
@@ -662,7 +662,7 @@ export const MANIFEST: ToolSpec[] = [
662
662
  "Shift"
663
663
  ]
664
664
  },
665
- "description": "Modifier keys held for this one event, e.g. ['Shift']."
665
+ "description": "Modifier keys: Control|Ctrl|Shift|Alt|Meta|Cmd."
666
666
  }
667
667
  },
668
668
  "required": [
@@ -675,25 +675,25 @@ export const MANIFEST: ToolSpec[] = [
675
675
  },
676
676
  {
677
677
  "name": "wait_for_download",
678
- "description": "Wait for a file download to finish and return it as a real file on disk: {path,suggestedFilename,bytes,url,target}, written under the artifact dir's downloads/. ORDERING RULE, not optional: capture must be ARMED BEFORE the click that starts the download — call wait_for_download{arm:true} first (returns {armed:true,downloadPath,pending}), then click, then call again to collect the file. The download-behavior override is per-connection state Chrome REVERTS the moment the arming client disconnects, and an unarmed headless Chrome denies the download outright, so one triggered before arming is lost. SIDE EFFECT, browser-global: arming redirects EVERY download in this browser (all tabs, all origins) into the toolkit's downloads dir until this server exits — they no longer land in the user's normal Downloads folder. The arm lives on a connection this server holds open (an MCP-server capability): under the one-shot CLI the connection dies with the process and nothing is captured. Chrome-only (capability 'browser.downloads'): absent from tools/list under Firefox.",
678
+ "description": "Arm or collect a browser download; arm capture before triggering the download.",
679
679
  "inputSchema": {
680
680
  "type": "object",
681
681
  "properties": {
682
682
  "lease": {
683
683
  "type": "string",
684
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
684
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
685
685
  },
686
686
  "target": {
687
687
  "type": "string",
688
- "description": "Names the tab for the lease check and the echoed target — a download is browser-scoped, so this does not pick which download is returned. Grammar: server instructions."
688
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
689
689
  },
690
690
  "arm": {
691
691
  "type": "boolean",
692
- "description": "Arm download capture and return immediately instead of waiting: {armed:true,downloadPath,pending}. Call this BEFORE the click that triggers the download. 'pending' counts downloads that already completed and have not been collected yet, so an arm call doubles as a peek."
692
+ "description": "Arm download capture."
693
693
  },
694
694
  "timeoutMs": {
695
695
  "type": "number",
696
- "description": "How long to wait for a download to complete, in milliseconds. Default 30000. Ignored with arm:true. A download that already completed and was not yet collected is returned immediately, so this only bounds the wait for one still in flight."
696
+ "description": "Timeout in milliseconds."
697
697
  }
698
698
  },
699
699
  "required": [],
@@ -702,32 +702,32 @@ export const MANIFEST: ToolSpec[] = [
702
702
  },
703
703
  {
704
704
  "name": "grant_permissions",
705
- "description": "Grant browser permissions for an origin up front, so a page asking for geolocation / notifications / clipboard gets an answer instead of a prompt no agent can click. 'permissions' takes CDP PermissionType values ('geolocation','notifications','clipboardReadWrite','camera',...); an unknown name is refused by Chrome, quoting the bad value. Returns {granted,origin,target}, or {reset:true,target} for a reset-only call. Grants are keyed by ORIGIN, not by tab: every tab on that origin is affected, including ones opened later. reset:true clears this server's previous grants first (or instead, when no permissions are given) — CDP's reset is not origin-scoped, so it clears them for every origin at once. The grant lives on a connection this server holds open and Chrome DISCARDS IT when that connection closes: an MCP-server capability, so under the one-shot CLI the grant dies with the process. Chrome-only (capability 'browser.permissions'): absent from tools/list under Firefox, never present-and-throwing.",
705
+ "description": "Grant or reset browser permissions; permissions are origin-scoped and Chrome-only.",
706
706
  "inputSchema": {
707
707
  "type": "object",
708
708
  "properties": {
709
709
  "lease": {
710
710
  "type": "string",
711
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
711
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
712
712
  },
713
713
  "target": {
714
714
  "type": "string",
715
- "description": "Also the origin source when 'origin' is omitted. Grammar: server instructions."
715
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
716
716
  },
717
717
  "permissions": {
718
718
  "type": "array",
719
719
  "items": {
720
720
  "type": "string"
721
721
  },
722
- "description": "CDP PermissionType values to grant, e.g. ['geolocation'] or ['clipboardReadWrite','clipboardSanitizedWrite']. Required unless reset:true. An empty array is refused rather than treated as a successful no-op."
722
+ "description": "CDP PermissionType values, e.g. geolocation|notifications|clipboardReadWrite."
723
723
  },
724
724
  "origin": {
725
725
  "type": "string",
726
- "description": "Origin the grant applies to, e.g. 'https://example.com'. Defaults to the target tab's own origin. Required explicitly when that tab has no grantable origin (data:, blob:, about:blank all serialize to the opaque origin 'null'), which is refused with a message naming the tab's url."
726
+ "description": "Permission origin."
727
727
  },
728
728
  "reset": {
729
729
  "type": "boolean",
730
- "description": "Clear this server's previous permission grants (Browser.resetPermissions). With 'permissions' it resets FIRST and then grants, so the result is exactly the listed permissions; on its own it is a reset-only call answering {reset:true}. Not scoped to 'origin': CDP resets every origin at once."
730
+ "description": "Reset permission grants."
731
731
  }
732
732
  },
733
733
  "required": [],
@@ -736,25 +736,25 @@ export const MANIFEST: ToolSpec[] = [
736
736
  },
737
737
  {
738
738
  "name": "fill",
739
- "description": "Fills an element by focusing it, clearing existing content, then inserting value via Input.insertText (atomic paste-like commit, not per-character keystrokes — won't fire per-keypress handlers). Give exactly one of uid or selector.",
739
+ "description": "Replace an element contents; provide exactly one of UID or selector.",
740
740
  "inputSchema": {
741
741
  "type": "object",
742
742
  "properties": {
743
743
  "lease": {
744
744
  "type": "string",
745
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
745
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
746
746
  },
747
747
  "target": {
748
748
  "type": "string",
749
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
749
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
750
750
  },
751
751
  "uid": {
752
752
  "type": "number",
753
- "description": "CDP backendDOMNodeId of the field to fill, from take_snapshot. Exactly one of uid or selector."
753
+ "description": "Element backendDOMNodeId."
754
754
  },
755
755
  "selector": {
756
756
  "type": "string",
757
- "description": "CSS selector for the field to fill (document.querySelector). Exactly one of uid or selector."
757
+ "description": "CSS selector."
758
758
  },
759
759
  "value": {
760
760
  "type": "string",
@@ -769,35 +769,35 @@ export const MANIFEST: ToolSpec[] = [
769
769
  },
770
770
  {
771
771
  "name": "fill_form",
772
- "description": "Fills multiple form fields in one call; each is focused, cleared, then set via Input.insertText (overwrites existing content, same as fill). Each entry in the non-empty 'fields' array takes exactly one of uid or selector plus a string value.",
772
+ "description": "Fill multiple elements atomically; each field needs a UID or selector.",
773
773
  "inputSchema": {
774
774
  "type": "object",
775
775
  "properties": {
776
776
  "lease": {
777
777
  "type": "string",
778
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
778
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
779
779
  },
780
780
  "target": {
781
781
  "type": "string",
782
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
782
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
783
783
  },
784
784
  "fields": {
785
785
  "type": "array",
786
- "description": "Non-empty array of fields to fill, each with exactly one of uid or selector plus a string value.",
786
+ "description": "Form fields to fill.",
787
787
  "items": {
788
788
  "type": "object",
789
789
  "properties": {
790
790
  "uid": {
791
791
  "type": "number",
792
- "description": "CDP backendDOMNodeId of the field, obtained from take_snapshot. Provide exactly one of uid or selector."
792
+ "description": "Element backendDOMNodeId."
793
793
  },
794
794
  "selector": {
795
795
  "type": "string",
796
- "description": "CSS selector for the field (resolved via document.querySelector). Provide exactly one of uid or selector."
796
+ "description": "CSS selector."
797
797
  },
798
798
  "value": {
799
799
  "type": "string",
800
- "description": "The text value to set; the field is cleared first so this overwrites existing content."
800
+ "description": "Text value to set; the field is cleared first, overwriting existing content."
801
801
  }
802
802
  },
803
803
  "required": [
@@ -815,29 +815,29 @@ export const MANIFEST: ToolSpec[] = [
815
815
  },
816
816
  {
817
817
  "name": "type_text",
818
- "description": "Focuses an element and appends text via Input.insertText without clearing first — closest primitive to typing, but still atomic (not per-character keystrokes). Give exactly one of uid or selector.",
818
+ "description": "Append text to an element; input is atomic and does not clear existing content.",
819
819
  "inputSchema": {
820
820
  "type": "object",
821
821
  "properties": {
822
822
  "lease": {
823
823
  "type": "string",
824
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
824
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
825
825
  },
826
826
  "target": {
827
827
  "type": "string",
828
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
828
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
829
829
  },
830
830
  "uid": {
831
831
  "type": "number",
832
- "description": "CDP backendDOMNodeId of the element to type into, from take_snapshot. Exactly one of uid or selector."
832
+ "description": "Element backendDOMNodeId."
833
833
  },
834
834
  "selector": {
835
835
  "type": "string",
836
- "description": "CSS selector for the element to type into (document.querySelector). Exactly one of uid or selector."
836
+ "description": "CSS selector."
837
837
  },
838
838
  "text": {
839
839
  "type": "string",
840
- "description": "Text to insert; appended to existing content rather than overwriting it."
840
+ "description": "Text substring."
841
841
  }
842
842
  },
843
843
  "required": [
@@ -848,25 +848,25 @@ export const MANIFEST: ToolSpec[] = [
848
848
  },
849
849
  {
850
850
  "name": "press_key",
851
- "description": "Dispatches a keyDown/keyUp pair for one key with optional modifiers. 'key' is a named key (Enter, Tab, Escape, ArrowDown, Backspace, etc.) or a single printable character — the named-key table is curated, with no F-keys, numpad, or IME support.",
851
+ "description": "Press one named key or printable character with modifiers; no F-keys or IME.",
852
852
  "inputSchema": {
853
853
  "type": "object",
854
854
  "properties": {
855
855
  "lease": {
856
856
  "type": "string",
857
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
857
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
858
858
  },
859
859
  "target": {
860
860
  "type": "string",
861
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
861
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
862
862
  },
863
863
  "key": {
864
864
  "type": "string",
865
- "description": "Key to press: a named key (Enter, Tab, Escape, ArrowDown, Backspace, ...) or a single printable character."
865
+ "description": "Named key or printable character; e.g. Enter|Tab|Escape|ArrowDown|Backspace."
866
866
  },
867
867
  "modifiers": {
868
868
  "type": "array",
869
- "description": "Modifier names held during the press: 'Control'/'Ctrl', 'Shift', 'Alt', 'Meta'/'Cmd'.",
869
+ "description": "Modifier keys: Control|Ctrl|Shift|Alt|Meta|Cmd.",
870
870
  "items": {
871
871
  "type": "string"
872
872
  }
@@ -880,32 +880,32 @@ export const MANIFEST: ToolSpec[] = [
880
880
  },
881
881
  {
882
882
  "name": "upload_file",
883
- "description": "Attaches one or more files to an <input type=file> element via DOM.setFileInputFiles. Give exactly one of uid or selector for the input; 'files' is an array of absolute path(s) — wrap a single path in an array too.",
883
+ "description": "Attach absolute file paths to a file input; provide an array.",
884
884
  "inputSchema": {
885
885
  "type": "object",
886
886
  "properties": {
887
887
  "lease": {
888
888
  "type": "string",
889
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
889
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
890
890
  },
891
891
  "target": {
892
892
  "type": "string",
893
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
893
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
894
894
  },
895
895
  "uid": {
896
896
  "type": "number",
897
- "description": "CDP backendDOMNodeId of the file input element, from take_snapshot. Exactly one of uid or selector."
897
+ "description": "Element backendDOMNodeId."
898
898
  },
899
899
  "selector": {
900
900
  "type": "string",
901
- "description": "CSS selector for the file input element (document.querySelector). Exactly one of uid or selector."
901
+ "description": "CSS selector."
902
902
  },
903
903
  "files": {
904
904
  "type": "array",
905
905
  "items": {
906
906
  "type": "string"
907
907
  },
908
- "description": "Absolute path(s) to attach to the <input type=file>, as an array — wrap a single path too, e.g. [\"/tmp/a.pdf\"]. Array-only because some model APIs (Google Gemini function calling) reject union-typed parameters."
908
+ "description": "Absolute file paths."
909
909
  }
910
910
  },
911
911
  "required": [
@@ -916,17 +916,17 @@ export const MANIFEST: ToolSpec[] = [
916
916
  },
917
917
  {
918
918
  "name": "take_screenshot",
919
- "description": "Captures the viewport (default), the full scrollable page (fullPage), or one element (uid or selector, mutually exclusive) via CDP Page.captureScreenshot. Past 16384 device px per side Chrome can hang rather than refuse, so size is checked first via Page.getLayoutMetrics; an oversized capture is auto-tiled into vertical bands stitched losslessly into one PNG (see tile) instead of wedging the tab. Writes PNG/JPEG to /tmp/cdp-toolkit (override savePath, dir auto-created); returns {path,bytes,format,target,scale} plus width/height measured from the encoded bytes (omitted if undecodable). renderSize/renderRestored(+renderRestoreError) accompany a renderWidth/renderHeight capture, tiled/bands a banded one. returnBase64 adds raw bytes to the result but is refused on a banded capture. quality applies to jpeg only.",
919
+ "description": "Capture a viewport, full page, or element to PNG/JPEG; oversized captures may be tiled.",
920
920
  "inputSchema": {
921
921
  "type": "object",
922
922
  "properties": {
923
923
  "lease": {
924
924
  "type": "string",
925
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
925
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
926
926
  },
927
927
  "target": {
928
928
  "type": "string",
929
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
929
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
930
930
  },
931
931
  "format": {
932
932
  "type": "string",
@@ -934,47 +934,47 @@ export const MANIFEST: ToolSpec[] = [
934
934
  "png",
935
935
  "jpeg"
936
936
  ],
937
- "description": "Image format, default png. quality applies only to jpeg."
937
+ "description": "Image/frame format."
938
938
  },
939
939
  "quality": {
940
940
  "type": "number",
941
- "description": "JPEG quality 0-100, default 80; ignored for png."
941
+ "description": "JPEG quality 0-100."
942
942
  },
943
943
  "fullPage": {
944
944
  "type": "boolean",
945
- "description": "Capture the full scrollable height (via Page.getLayoutMetrics), not just the viewport."
945
+ "description": "Capture full scrollable page."
946
946
  },
947
947
  "scale": {
948
948
  "type": "number",
949
- "description": "Output-pixel multiplier for this capture only (0<scale<=8, default 1): output px = ceil(css px x scale x devicePixelRatio); the page is never told anything changed. Chrome only (screenshot.scale) — Firefox BiDi has no scale param, use emulate{deviceScaleFactor} then scale:1. A projection over 16384 device px/side is refused up front, naming the largest scale that fits."
949
+ "description": "Output scale (0<scale<=8)."
950
950
  },
951
951
  "renderWidth": {
952
952
  "type": "number",
953
- "description": "Emulates this viewport width (CSS px, 1-16384) for one capture, then restores it. Required with renderHeight. Unlike scale, this changes what the page believes (media queries re-flow) — e.g. capture a responsive page at 1920x1080 from a differently-sized tab. Restore only works for an override this toolkit itself set; check result.renderRestored (false = still emulated, fix via emulate). Works on both backends (capability screenshot.renderSize)."
953
+ "description": "Rendered viewport width."
954
954
  },
955
955
  "renderHeight": {
956
956
  "type": "number",
957
- "description": "Emulates this viewport height (CSS px, 1-16384) for one capture. Required with renderWidth — a viewport is two numbers. A narrow renderWidth often reflows pages TALLER, which is the usual way a render-size capture trips the 16384px encode limit."
957
+ "description": "Rendered viewport height."
958
958
  },
959
959
  "tile": {
960
960
  "type": "boolean",
961
- "description": "Whether to allow vertical-band stitching: omitted=AUTO (band only if a single shot wouldn't fit), false=never band (refuse instead), true=always band (Chrome-only capability). Banded output is PNG-only, can't returnBase64, and only bands on HEIGHT (oversized WIDTH is refused, not split). Bands are a faithful crop, but lazy/virtualized content the real viewport never scrolled to renders blank."
961
+ "description": "Vertical-band stitching."
962
962
  },
963
963
  "uid": {
964
964
  "type": "number",
965
- "description": "Element to clip to: a backendDOMNodeId from take_snapshot. Mutually exclusive with selector."
965
+ "description": "Element backendDOMNodeId."
966
966
  },
967
967
  "selector": {
968
968
  "type": "string",
969
- "description": "CSS selector to clip the capture to. Mutually exclusive with uid."
969
+ "description": "CSS selector."
970
970
  },
971
971
  "savePath": {
972
972
  "type": "string",
973
- "description": "Override the output path (default /tmp/cdp-toolkit/screenshot-<id>-<stamp>.<ext>, stamped at capture START). Directory is created from this path's dirname."
973
+ "description": "Output file path."
974
974
  },
975
975
  "returnBase64": {
976
976
  "type": "boolean",
977
- "description": "Also return raw base64 bytes in the result. Refused on a banded capture (see tile) — a stitched image can run to hundreds of MB; read the file at the returned path instead."
977
+ "description": "Return base64 bytes."
978
978
  }
979
979
  },
980
980
  "required": [],
@@ -983,49 +983,49 @@ export const MANIFEST: ToolSpec[] = [
983
983
  },
984
984
  {
985
985
  "name": "emulate",
986
- "description": "Applies any subset of Chrome emulation overrides in one call: device metrics (width+height together, +deviceScaleFactor/mobile), userAgent, cpuThrottlingRate(>=1), media type+features, networkConditions. Device-metrics overrides PERSIST on the target until cleared or the renderer navigates/reloads; every other override is session-scoped and resets when this call's connection closes. clearOverrides:true resets everything (ignoring other fields) and, as of 1.9.2, genuinely clears a device-metrics override set by a DIFFERENT process — Chrome's clearDeviceMetricsOverride is normally a no-op unless the clearing connection also set the override, so the driver re-asserts the tab's current size first, then clears, throwing rather than reporting cleared:true if it can't verify.",
986
+ "description": "Apply browser emulation overrides; width and height must be paired.",
987
987
  "inputSchema": {
988
988
  "type": "object",
989
989
  "properties": {
990
990
  "lease": {
991
991
  "type": "string",
992
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
992
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
993
993
  },
994
994
  "target": {
995
995
  "type": "string",
996
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
996
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
997
997
  },
998
998
  "width": {
999
999
  "type": "number",
1000
- "description": "Device-metrics viewport width in CSS px. Must be paired with height."
1000
+ "description": "Viewport width; pair with height."
1001
1001
  },
1002
1002
  "height": {
1003
1003
  "type": "number",
1004
- "description": "Device-metrics viewport height in CSS px. Must be paired with width."
1004
+ "description": "Viewport height; pair with width."
1005
1005
  },
1006
1006
  "deviceScaleFactor": {
1007
1007
  "type": "number",
1008
- "description": "Device pixel ratio for the device-metrics override; 0 = platform default."
1008
+ "description": "Device pixel ratio."
1009
1009
  },
1010
1010
  "mobile": {
1011
1011
  "type": "boolean",
1012
- "description": "Emulate a mobile device (viewport meta, scrollbars, etc.) for the device-metrics override."
1012
+ "description": "Mobile emulation."
1013
1013
  },
1014
1014
  "userAgent": {
1015
1015
  "type": "string",
1016
- "description": "User-Agent string override (Emulation.setUserAgentOverride)."
1016
+ "description": "User-Agent override."
1017
1017
  },
1018
1018
  "cpuThrottlingRate": {
1019
1019
  "type": "number",
1020
- "description": "CPU throttling multiplier: 1=none, 2=2x slower, etc. Must be >=1."
1020
+ "description": "CPU throttling rate (>=1)."
1021
1021
  },
1022
1022
  "media": {
1023
1023
  "type": "string",
1024
- "description": "Emulated CSS media type: 'screen' | 'print' | '' (clear)."
1024
+ "description": "CSS media: screen|print|blank."
1025
1025
  },
1026
1026
  "mediaFeatures": {
1027
1027
  "type": "array",
1028
- "description": "Emulated media features, e.g. [{name:'prefers-color-scheme', value:'dark'}].",
1028
+ "description": "CSS media feature overrides.",
1029
1029
  "items": {
1030
1030
  "type": "object",
1031
1031
  "properties": {
@@ -1035,7 +1035,7 @@ export const MANIFEST: ToolSpec[] = [
1035
1035
  },
1036
1036
  "value": {
1037
1037
  "type": "string",
1038
- "description": "Media feature value, e.g. 'dark'."
1038
+ "description": "Feature value, e.g. 'dark'."
1039
1039
  }
1040
1040
  },
1041
1041
  "required": [
@@ -1047,34 +1047,34 @@ export const MANIFEST: ToolSpec[] = [
1047
1047
  },
1048
1048
  "networkConditions": {
1049
1049
  "type": "object",
1050
- "description": "Network overrides applied via Network.emulateNetworkConditions.",
1050
+ "description": "Network condition overrides.",
1051
1051
  "properties": {
1052
1052
  "offline": {
1053
1053
  "type": "boolean",
1054
- "description": "True to simulate offline."
1054
+ "description": "Simulate offline."
1055
1055
  },
1056
1056
  "latency": {
1057
1057
  "type": "number",
1058
- "description": "Additional round-trip latency in milliseconds."
1058
+ "description": "Network latency in milliseconds."
1059
1059
  },
1060
1060
  "downloadThroughput": {
1061
1061
  "type": "number",
1062
- "description": "Max download throughput in bytes/sec (-1 = no limit)."
1062
+ "description": "Download throughput; -1 unlimited."
1063
1063
  },
1064
1064
  "uploadThroughput": {
1065
1065
  "type": "number",
1066
- "description": "Max upload throughput in bytes/sec (-1 = no limit)."
1066
+ "description": "Upload throughput; -1 unlimited."
1067
1067
  },
1068
1068
  "connectionType": {
1069
1069
  "type": "string",
1070
- "description": "Connection type: 'none' | 'cellular2g' | 'cellular3g' | 'cellular4g' | 'bluetooth' | 'ethernet' | 'wifi' | 'wimax' | 'other'."
1070
+ "description": "Connection: none|cellular2g|cellular3g|cellular4g|bluetooth|ethernet|wifi|wimax|other."
1071
1071
  }
1072
1072
  },
1073
1073
  "additionalProperties": false
1074
1074
  },
1075
1075
  "clearOverrides": {
1076
1076
  "type": "boolean",
1077
- "description": "Reset every override (metrics, UA, CPU, media, network) to browser default; ignores all other fields when true."
1077
+ "description": "Clear all emulation overrides."
1078
1078
  }
1079
1079
  },
1080
1080
  "required": [],
@@ -1083,33 +1083,33 @@ export const MANIFEST: ToolSpec[] = [
1083
1083
  },
1084
1084
  {
1085
1085
  "name": "resize_page",
1086
- "description": "Sets the page's device-metrics width/height (the narrow case of emulate), optionally deviceScaleFactor/mobile, then verifies by reading back window.innerWidth/innerHeight after applying. Requires positive width and height. The override PERSISTS on the target until cleared (emulate{clearOverrides:true}) or the renderer navigates/reloads.",
1086
+ "description": "Set and verify page viewport metrics; width and height are required.",
1087
1087
  "inputSchema": {
1088
1088
  "type": "object",
1089
1089
  "properties": {
1090
1090
  "lease": {
1091
1091
  "type": "string",
1092
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1092
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1093
1093
  },
1094
1094
  "target": {
1095
1095
  "type": "string",
1096
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
1096
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1097
1097
  },
1098
1098
  "width": {
1099
1099
  "type": "number",
1100
- "description": "Viewport width in CSS px (required, must be positive)."
1100
+ "description": "Viewport width; pair with height."
1101
1101
  },
1102
1102
  "height": {
1103
1103
  "type": "number",
1104
- "description": "Viewport height in CSS px (required, must be positive)."
1104
+ "description": "Viewport height; pair with width."
1105
1105
  },
1106
1106
  "deviceScaleFactor": {
1107
1107
  "type": "number",
1108
- "description": "Device pixel ratio; 0 = platform default."
1108
+ "description": "Device pixel ratio."
1109
1109
  },
1110
1110
  "mobile": {
1111
1111
  "type": "boolean",
1112
- "description": "Emulate a mobile device for the device-metrics override."
1112
+ "description": "Mobile emulation."
1113
1113
  }
1114
1114
  },
1115
1115
  "required": [
@@ -1121,33 +1121,33 @@ export const MANIFEST: ToolSpec[] = [
1121
1121
  },
1122
1122
  {
1123
1123
  "name": "handle_dialog",
1124
- "description": "Wait for the next JavaScript dialog (alert/confirm/prompt/beforeunload) on a page and respond via Page.handleJavaScriptDialog, accepting or dismissing it. Default mode resolves with the first handled dialog or throws on timeout; set autoMs to handle every dialog opening during a fixed window and resolve with the list. Trigger the dialog out-of-band (e.g. click a button) — a blocking dialog freezes the renderer, so it cannot be triggered inline.",
1124
+ "description": "Handle the next JavaScript dialog; autoMs switches to timed multi-dialog mode.",
1125
1125
  "inputSchema": {
1126
1126
  "type": "object",
1127
1127
  "properties": {
1128
1128
  "lease": {
1129
1129
  "type": "string",
1130
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1130
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1131
1131
  },
1132
1132
  "target": {
1133
1133
  "type": "string",
1134
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
1134
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1135
1135
  },
1136
1136
  "accept": {
1137
1137
  "type": "boolean",
1138
- "description": "Whether to accept (OK) or dismiss (Cancel) the dialog."
1138
+ "description": "Accept or dismiss dialog."
1139
1139
  },
1140
1140
  "promptText": {
1141
1141
  "type": "string",
1142
- "description": "Text to enter for a prompt() dialog when accepting."
1142
+ "description": "Prompt response text."
1143
1143
  },
1144
1144
  "timeoutMs": {
1145
1145
  "type": "number",
1146
- "description": "How long to wait for the next dialog, in milliseconds (default 15000)."
1146
+ "description": "Timeout in milliseconds."
1147
1147
  },
1148
1148
  "autoMs": {
1149
1149
  "type": "number",
1150
- "description": "Auto-handle mode: keep handling every dialog that opens for this many milliseconds, then resolve with the list of handled dialogs (an empty list is valid; never throws on 'no dialog')."
1150
+ "description": "Multi-dialog window in milliseconds."
1151
1151
  }
1152
1152
  },
1153
1153
  "required": [
@@ -1158,29 +1158,29 @@ export const MANIFEST: ToolSpec[] = [
1158
1158
  },
1159
1159
  {
1160
1160
  "name": "list_console_messages",
1161
- "description": "Read console output (logs, warnings, exceptions) captured for the target. Reads the existing shared buffer by default (empty if no capture ran); reload:true reloads and records a fresh capture (console+network together, so a network reload never wipes console history). WORKER capture (Chrome, Capability 'worker.targets'): a worker: target records an MV3 background service worker -- its console.log arrives as Runtime.consoleAPICalled, its outbound requests from CDP's Network domain on the worker's own session -- so the two tricks callers try first fail for plain JS reasons, not worker ones: a value bound at module top level is not visible from evaluate_script's global scope, and assigning self.fetch cannot rebind a fetch the module already captured. A worker has no reload: reload:true means 'listen for durationMs while it runs', so trigger its work (tool call, message, alarm) during the window; a worker woken by the call already ran its top-level code, so a startup message can be missed. SIDE EFFECT: the CDP session KEEPS THE WORKER ALIVE for the capture (an idle MV3 worker is evicted in seconds); Chrome resumes evicting after.",
1161
+ "description": "Read or recapture console messages for a page or worker; worker capture is Chrome-only.",
1162
1162
  "inputSchema": {
1163
1163
  "type": "object",
1164
1164
  "properties": {
1165
1165
  "lease": {
1166
1166
  "type": "string",
1167
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1167
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1168
1168
  },
1169
1169
  "target": {
1170
1170
  "type": "string",
1171
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', '<targetId>'; plus 'worker:<substring>' to reach a service/shared worker (e.g. an MV3 extension background worker). The worker: arm is CHROME-ONLY (Capability 'worker.targets'). Grammar: see server instructions."
1171
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1172
1172
  },
1173
1173
  "reload": {
1174
1174
  "type": "boolean",
1175
- "description": "Record fresh by reloading the page and capturing a window. Default false (read existing buffer). With a worker: target nothing reloads -- records for durationMs while the worker runs and keeps it alive until the capture stops."
1175
+ "description": "Reload before capture."
1176
1176
  },
1177
1177
  "durationMs": {
1178
1178
  "type": "number",
1179
- "description": "Capture window for reload mode, in ms. Default 2500."
1179
+ "description": "Capture duration in milliseconds."
1180
1180
  },
1181
1181
  "wake": {
1182
1182
  "type": "boolean",
1183
- "description": "Worker targets only, when starting a capture. Default true: an idle-evicted MV3 service worker exists in no target listing, so it is started first (ServiceWorker.startWorker) and re-confirmed; false fails fast. Rejected on a page target, a bare target id, or a read-only call. See server instructions."
1183
+ "description": "Wake worker before capture."
1184
1184
  }
1185
1185
  },
1186
1186
  "required": [],
@@ -1189,21 +1189,21 @@ export const MANIFEST: ToolSpec[] = [
1189
1189
  },
1190
1190
  {
1191
1191
  "name": "get_console_message",
1192
- "description": "Return one console entry by zero-based index from the target's existing console buffer. Throws if the index is out of range; run list_console_messages (optionally reload:true) first to populate the buffer.",
1192
+ "description": "Return one console entry by zero-based index from the existing buffer.",
1193
1193
  "inputSchema": {
1194
1194
  "type": "object",
1195
1195
  "properties": {
1196
1196
  "lease": {
1197
1197
  "type": "string",
1198
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1198
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1199
1199
  },
1200
1200
  "target": {
1201
1201
  "type": "string",
1202
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
1202
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1203
1203
  },
1204
1204
  "index": {
1205
1205
  "type": "number",
1206
- "description": "Zero-based index into the parsed console entries. Default 0."
1206
+ "description": "Zero-based entry index."
1207
1207
  }
1208
1208
  },
1209
1209
  "required": [],
@@ -1212,33 +1212,33 @@ export const MANIFEST: ToolSpec[] = [
1212
1212
  },
1213
1213
  {
1214
1214
  "name": "list_network_requests",
1215
- "description": "Return correlated network rows (one per requestId; status/headers/state) for the target. Reads the existing buffer by default; reload:true records a fresh both-domains capture window. filterUrl keeps only URLs containing a substring. WORKER capture (Chrome, Capability 'worker.targets'): a worker: target records an MV3 background service worker's outbound requests from CDP's Network domain on the worker's own session -- what the code ACTUALLY SENT -- so the two tricks callers try first fail for plain JS reasons, not worker ones: a value bound at module top level is not visible from evaluate_script's global scope, and assigning self.fetch cannot rebind a fetch the module already captured. A worker has no reload: reload:true means 'listen for durationMs while it runs', so trigger its work (tool call, message, alarm) during the window; a worker woken by the call already ran its top-level code, so a startup request can be missed. SIDE EFFECT: the CDP session KEEPS THE WORKER ALIVE for the capture (an idle MV3 worker is evicted in seconds); Chrome resumes evicting after.",
1215
+ "description": "Read or recapture correlated network requests; worker capture is Chrome-only.",
1216
1216
  "inputSchema": {
1217
1217
  "type": "object",
1218
1218
  "properties": {
1219
1219
  "lease": {
1220
1220
  "type": "string",
1221
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1221
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1222
1222
  },
1223
1223
  "target": {
1224
1224
  "type": "string",
1225
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', '<targetId>'; plus 'worker:<substring>' to reach a service/shared worker (e.g. an MV3 extension background worker). The worker: arm is CHROME-ONLY (Capability 'worker.targets'). Grammar: see server instructions."
1225
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1226
1226
  },
1227
1227
  "reload": {
1228
1228
  "type": "boolean",
1229
- "description": "Record fresh by reloading the page and capturing a window. Default false (read existing buffer). With a worker: target nothing reloads -- records for durationMs while the worker runs and keeps it alive until the capture stops."
1229
+ "description": "Reload before capture."
1230
1230
  },
1231
1231
  "durationMs": {
1232
1232
  "type": "number",
1233
- "description": "Capture window for reload mode, in ms. Default 2500."
1233
+ "description": "Capture duration in milliseconds."
1234
1234
  },
1235
1235
  "filterUrl": {
1236
1236
  "type": "string",
1237
- "description": "Return only requests whose URL contains this substring."
1237
+ "description": "URL substring filter."
1238
1238
  },
1239
1239
  "wake": {
1240
1240
  "type": "boolean",
1241
- "description": "Worker targets only, when starting a capture. Default true: an idle-evicted MV3 service worker exists in no target listing, so it is started first (ServiceWorker.startWorker) and re-confirmed; false fails fast. Rejected on a page target, a bare target id, or a read-only call. See server instructions."
1241
+ "description": "Wake worker before capture."
1242
1242
  }
1243
1243
  },
1244
1244
  "required": [],
@@ -1247,37 +1247,37 @@ export const MANIFEST: ToolSpec[] = [
1247
1247
  },
1248
1248
  {
1249
1249
  "name": "get_network_request",
1250
- "description": "Return one network request (matched by exact requestId, else url substring) with status/headers. Requires requestId or url (throws otherwise). includeBody:true drives a fresh capture (page reload, or worker listen window) matched by url ONLY -- a fresh capture re-mints requestIds, so a carried-over requestId returns metadata plus bodyUnavailableReason. WORKER capture (Chrome, Capability 'worker.targets'): a worker: target records an MV3 background service worker's outbound requests from CDP's Network domain on the worker's own session -- what the code ACTUALLY SENT -- so the two tricks callers try first fail for plain JS reasons, not worker ones: a value bound at module top level is not visible from evaluate_script's global scope, and assigning self.fetch cannot rebind a fetch the module already captured. A worker has no reload: reload means 'listen for durationMs while it runs', so trigger its work (tool call, message, alarm) during the window; a worker woken by the call already ran its top-level code, so a startup request can be missed. SIDE EFFECT: the CDP session KEEPS THE WORKER ALIVE for the capture (an idle MV3 worker is evicted in seconds); Chrome resumes evicting after.",
1250
+ "description": "Return a network request by ID or URL; body capture requires URL.",
1251
1251
  "inputSchema": {
1252
1252
  "type": "object",
1253
1253
  "properties": {
1254
1254
  "lease": {
1255
1255
  "type": "string",
1256
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1256
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1257
1257
  },
1258
1258
  "target": {
1259
1259
  "type": "string",
1260
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', '<targetId>'; plus 'worker:<substring>' to reach a service/shared worker (e.g. an MV3 extension background worker). The worker: arm is CHROME-ONLY (Capability 'worker.targets'). Grammar: see server instructions."
1260
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1261
1261
  },
1262
1262
  "requestId": {
1263
1263
  "type": "string",
1264
- "description": "Match by exact requestId (metadata only; cannot fetch a body, since a reload re-mints requestIds)."
1264
+ "description": "Exact request ID."
1265
1265
  },
1266
1266
  "url": {
1267
1267
  "type": "string",
1268
- "description": "Match by URL substring (first match). Required for body fetch (includeBody), since url is stable across reload."
1268
+ "description": "URL value."
1269
1269
  },
1270
1270
  "includeBody": {
1271
1271
  "type": "boolean",
1272
- "description": "Also fetch the response body; drives a fresh capture and requires the url selector."
1272
+ "description": "Include response body."
1273
1273
  },
1274
1274
  "durationMs": {
1275
1275
  "type": "number",
1276
- "description": "Capture window for the body-fetch reload, in ms. Default 2500."
1276
+ "description": "Capture duration in milliseconds."
1277
1277
  },
1278
1278
  "wake": {
1279
1279
  "type": "boolean",
1280
- "description": "Worker targets only, when starting a capture. Default true: an idle-evicted MV3 service worker exists in no target listing, so it is started first (ServiceWorker.startWorker) and re-confirmed; false fails fast. Rejected on a page target, a bare target id, or a read-only call. See server instructions."
1280
+ "description": "Wake worker before capture."
1281
1281
  }
1282
1282
  },
1283
1283
  "required": [],
@@ -1286,24 +1286,24 @@ export const MANIFEST: ToolSpec[] = [
1286
1286
  },
1287
1287
  {
1288
1288
  "name": "performance_start_trace",
1289
- "description": "Starts a CDP trace recording on the target and holds the recording connection in-process; you MUST call performance_stop_trace from the SAME PROCESS to end it, or use performance_trace instead for a robust cross-call trace. Throws if a trace is already in progress for this target.",
1289
+ "description": "Start an in-process trace; stop it from the same process.",
1290
1290
  "inputSchema": {
1291
1291
  "type": "object",
1292
1292
  "properties": {
1293
1293
  "lease": {
1294
1294
  "type": "string",
1295
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1295
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1296
1296
  },
1297
1297
  "target": {
1298
1298
  "type": "string",
1299
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
1299
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1300
1300
  },
1301
1301
  "categories": {
1302
1302
  "type": "array",
1303
1303
  "items": {
1304
1304
  "type": "string"
1305
1305
  },
1306
- "description": "Trace categories to record. Defaults to timeline + user-timing + loading + disabled-by-default timeline tracks carrying LCP/LayoutShift/RunTask."
1306
+ "description": "Trace categories."
1307
1307
  }
1308
1308
  },
1309
1309
  "required": [],
@@ -1312,17 +1312,17 @@ export const MANIFEST: ToolSpec[] = [
1312
1312
  },
1313
1313
  {
1314
1314
  "name": "performance_stop_trace",
1315
- "description": "Stops the in-process trace started by performance_start_trace and writes it as JSON under /tmp/cdp-toolkit, returning {path,bytes,events,metrics}. Throws if no live trace exists in THIS process (e.g. start ran in a different process) — use performance_trace instead. The target arg is accepted only for API symmetry; at most one trace is ever live per process.",
1315
+ "description": "Stop the in-process trace and write JSON; a live trace is required.",
1316
1316
  "inputSchema": {
1317
1317
  "type": "object",
1318
1318
  "properties": {
1319
1319
  "lease": {
1320
1320
  "type": "string",
1321
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1321
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1322
1322
  },
1323
1323
  "target": {
1324
1324
  "type": "string",
1325
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
1325
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1326
1326
  }
1327
1327
  },
1328
1328
  "required": [],
@@ -1331,17 +1331,17 @@ export const MANIFEST: ToolSpec[] = [
1331
1331
  },
1332
1332
  {
1333
1333
  "name": "performance_analyze_insight",
1334
- "description": "Reads a trace JSON file (from performance_trace/performance_stop_trace) at tracePath and returns headline metrics: FCP/LCP/CLS/TBT, long tasks, layout shifts. Requires an EXPLICIT tracePath — there is no implicit 'latest trace'. Numbers approximate DevTools's insight analyzer (no main-thread attribution or frame-scoped LCP).",
1334
+ "description": "Analyze a trace JSON file for key performance metrics; tracePath is required.",
1335
1335
  "inputSchema": {
1336
1336
  "type": "object",
1337
1337
  "properties": {
1338
1338
  "lease": {
1339
1339
  "type": "string",
1340
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1340
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1341
1341
  },
1342
1342
  "tracePath": {
1343
1343
  "type": "string",
1344
- "description": "Path to a trace JSON file (bare array or {traceEvents:[...]}) written by performance_trace or performance_stop_trace. Required."
1344
+ "description": "Trace JSON file path."
1345
1345
  }
1346
1346
  },
1347
1347
  "required": [],
@@ -1350,36 +1350,36 @@ export const MANIFEST: ToolSpec[] = [
1350
1350
  },
1351
1351
  {
1352
1352
  "name": "performance_trace",
1353
- "description": "RECOMMENDED entry point: one-shot trace that starts tracing, optionally reloads or navigates the page, waits durationMs (default 3000ms), stops, and writes JSON under /tmp/cdp-toolkit — returns {path,bytes,events,metrics,target}. Holds one connection open for the whole window, so unlike start/stop it is NOT limited to a single process.",
1353
+ "description": "Run a one-shot trace with optional navigation and write JSON; durationMs controls capture time.",
1354
1354
  "inputSchema": {
1355
1355
  "type": "object",
1356
1356
  "properties": {
1357
1357
  "lease": {
1358
1358
  "type": "string",
1359
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1359
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1360
1360
  },
1361
1361
  "target": {
1362
1362
  "type": "string",
1363
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
1363
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1364
1364
  },
1365
1365
  "durationMs": {
1366
1366
  "type": "number",
1367
- "description": "How long to record after the optional reload/navigate, in ms. Default 3000."
1367
+ "description": "Capture duration in milliseconds."
1368
1368
  },
1369
1369
  "reload": {
1370
1370
  "type": "boolean",
1371
- "description": "Reload the page after starting the trace, to capture full navigation timing."
1371
+ "description": "Reload before capture."
1372
1372
  },
1373
1373
  "navigateTo": {
1374
1374
  "type": "string",
1375
- "description": "Navigate to this URL after starting the trace (alternative to reload)."
1375
+ "description": "Navigation URL."
1376
1376
  },
1377
1377
  "categories": {
1378
1378
  "type": "array",
1379
1379
  "items": {
1380
1380
  "type": "string"
1381
1381
  },
1382
- "description": "Trace categories to record. Defaults to timeline + user-timing + loading + disabled-by-default timeline tracks carrying LCP/LayoutShift/RunTask."
1382
+ "description": "Trace categories."
1383
1383
  }
1384
1384
  },
1385
1385
  "required": [],
@@ -1388,17 +1388,17 @@ export const MANIFEST: ToolSpec[] = [
1388
1388
  },
1389
1389
  {
1390
1390
  "name": "start_screen_recording",
1391
- "description": "Starts recording the target tab to video via CDP Page.startScreencast, holding one persistent connection and spooling every frame to disk — MUST be paired with stop_screen_recording WITHIN THE SAME PROCESS (frames are connection-scoped and cannot be reattached from another process, so this only works under the MCP server, not the one-process-per-call CLI). Chrome only: WebDriver BiDi has no screencast primitive, so both tools are absent under --browser firefox. Frames arrive ON REPAINT not on a clock (variable rate); each is timestamped into a ledger that stop_screen_recording turns into per-frame display durations, so a still page holds one long frame instead of racing. ffmpeg is probed here (not at stop) so a missing encoder fails before frames are captured and thrown away. Throws if the target already has a recording in progress; different targets record concurrently.",
1391
+ "description": "Start a tab screen recording; stop it from the same process.",
1392
1392
  "inputSchema": {
1393
1393
  "type": "object",
1394
1394
  "properties": {
1395
1395
  "lease": {
1396
1396
  "type": "string",
1397
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1397
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1398
1398
  },
1399
1399
  "target": {
1400
1400
  "type": "string",
1401
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
1401
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1402
1402
  },
1403
1403
  "format": {
1404
1404
  "type": "string",
@@ -1406,27 +1406,27 @@ export const MANIFEST: ToolSpec[] = [
1406
1406
  "jpeg",
1407
1407
  "png"
1408
1408
  ],
1409
- "description": "Frame format, default jpeg (much smaller per repaint); png is lossless. quality applies to jpeg only."
1409
+ "description": "Image/frame format."
1410
1410
  },
1411
1411
  "quality": {
1412
1412
  "type": "number",
1413
- "description": "JPEG frame quality 0-100. Ignored for png; omitted leaves Chrome's own default."
1413
+ "description": "JPEG quality 0-100."
1414
1414
  },
1415
1415
  "maxWidth": {
1416
1416
  "type": "number",
1417
- "description": "Caps the streamed frame width in px; also pins frame size if the viewport may change mid-recording."
1417
+ "description": "Maximum frame width."
1418
1418
  },
1419
1419
  "maxHeight": {
1420
1420
  "type": "number",
1421
- "description": "Caps the streamed frame height in px."
1421
+ "description": "Maximum frame height."
1422
1422
  },
1423
1423
  "everyNthFrame": {
1424
1424
  "type": "number",
1425
- "description": "Capture only every Nth repaint (1=every frame), to shrink spool size on a busy page; per-frame durations keep playback at wallclock speed either way."
1425
+ "description": "Capture every Nth frame."
1426
1426
  },
1427
1427
  "bringToFront": {
1428
1428
  "type": "boolean",
1429
- "description": "Activate the tab (Page.bringToFront) before recording, default false. A backgrounded/occluded tab may never repaint, yielding a 0-frame recording."
1429
+ "description": "Activate tab before recording."
1430
1430
  }
1431
1431
  },
1432
1432
  "required": [],
@@ -1435,21 +1435,21 @@ export const MANIFEST: ToolSpec[] = [
1435
1435
  },
1436
1436
  {
1437
1437
  "name": "stop_screen_recording",
1438
- "description": "Stops the recording started by start_screen_recording, assembling spooled frames into an MP4 via ffmpeg with PER-FRAME durations (frame N held until N+1 painted; last frame held until this call) — capped at 25fps by ffmpeg's concat demuxer, so frames under 40ms apart are deliberately coalesced (frameCount=captured, encodedFrames=what reached the video, never silently dropped). Returns {path,bytes,durationMs,frameCount,encodedFrames,codec,encoder,width,height,droppedFrames,target}; durationMs sums encoded durations, the file runs one 40ms step longer (final frame repeated). Encoder ladder (probed at start): hevc_videotoolbox>h264_videotoolbox>libx265>libx264 (+hvc1 tag, faststart, yuv420p, even dims). target: omit with one recording in flight, required with several (avoids guessing which to stop). Throws if nothing is recording in this process, or if 0 frames arrived (no silent empty video). On ffmpeg failure the spooled frames are KEPT — spool path + exact command are in the error.",
1438
+ "description": "Stop a screen recording and encode MP4; target is required when multiple recordings exist.",
1439
1439
  "inputSchema": {
1440
1440
  "type": "object",
1441
1441
  "properties": {
1442
1442
  "lease": {
1443
1443
  "type": "string",
1444
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1444
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1445
1445
  },
1446
1446
  "target": {
1447
1447
  "type": "string",
1448
- "description": "Which recording to stop — 'active' valid only when exactly one recording is in flight. Grammar: server instructions."
1448
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1449
1449
  },
1450
1450
  "savePath": {
1451
1451
  "type": "string",
1452
- "description": "Override the output path (default /tmp/cdp-toolkit/screen-recording-<targetIdShort>-<stamp>.mp4)."
1452
+ "description": "Output file path."
1453
1453
  }
1454
1454
  },
1455
1455
  "required": [],
@@ -1458,21 +1458,21 @@ export const MANIFEST: ToolSpec[] = [
1458
1458
  },
1459
1459
  {
1460
1460
  "name": "take_heapsnapshot",
1461
- "description": "Captures a V8 heap snapshot of the target page over CDP and writes it as a .heapsnapshot JSON file (loadable in the DevTools Memory panel) under /tmp/cdp-toolkit unless savePath is given. Returns {path,bytes,chunks,target} only — does NOT parse or summarize the snapshot.",
1461
+ "description": "Capture a V8 heap snapshot to JSON; the snapshot is not parsed.",
1462
1462
  "inputSchema": {
1463
1463
  "type": "object",
1464
1464
  "properties": {
1465
1465
  "lease": {
1466
1466
  "type": "string",
1467
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1467
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1468
1468
  },
1469
1469
  "target": {
1470
1470
  "type": "string",
1471
- "description": "Page selector: 'active' (default), 'index:N', 'url:<substr>', 'title:<substr>', 'label:<name>', or a 32-hex '<targetId>'. Grammar: see server instructions."
1471
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1472
1472
  },
1473
1473
  "savePath": {
1474
1474
  "type": "string",
1475
- "description": "Override the output path. Absolute paths (starting with /) are used as-is; relative paths resolve under the artifact dir (/tmp/cdp-toolkit). Defaults to an auto-named take_heapsnapshot-<targetId>-<timestamp>.heapsnapshot file."
1475
+ "description": "Output file path."
1476
1476
  }
1477
1477
  },
1478
1478
  "required": [],
@@ -1481,28 +1481,28 @@ export const MANIFEST: ToolSpec[] = [
1481
1481
  },
1482
1482
  {
1483
1483
  "name": "lighthouse_audit",
1484
- "description": "Runs a Lighthouse audit against a URL by shelling out to `npx --yes lighthouse` (the toolkit's only non-CDP tool) — it attaches to the already-running Chrome and audits its OWN about:blank tab, NOT any live user tab you've navigated. Writes a JSON report under /tmp/cdp-toolkit; returns {path,bytes} plus per-category scores (0..1 or null).",
1484
+ "description": "Run Lighthouse against a URL in its own tab; it does not audit a user tab.",
1485
1485
  "inputSchema": {
1486
1486
  "type": "object",
1487
1487
  "properties": {
1488
1488
  "lease": {
1489
1489
  "type": "string",
1490
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1490
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1491
1491
  },
1492
1492
  "url": {
1493
1493
  "type": "string",
1494
- "description": "The URL to audit. Required — never points at a user tab implicitly."
1494
+ "description": "URL value."
1495
1495
  },
1496
1496
  "categories": {
1497
1497
  "type": "array",
1498
1498
  "items": {
1499
1499
  "type": "string"
1500
1500
  },
1501
- "description": "Lighthouse categories to run (--only-categories). Defaults to the full set, e.g. [\"performance\"] or [\"performance\",\"accessibility\",\"seo\"]."
1501
+ "description": "Lighthouse categories to run (--only-categories)."
1502
1502
  },
1503
1503
  "savePath": {
1504
1504
  "type": "string",
1505
- "description": "Override the report output path; defaults to a timestamped file under /tmp/cdp-toolkit."
1505
+ "description": "Output file path."
1506
1506
  },
1507
1507
  "formFactor": {
1508
1508
  "type": "string",
@@ -1510,11 +1510,11 @@ export const MANIFEST: ToolSpec[] = [
1510
1510
  "desktop",
1511
1511
  "mobile"
1512
1512
  ],
1513
- "description": "\"desktop\" (default, uses --preset=desktop to avoid heavy mobile throttling) or \"mobile\"."
1513
+ "description": "Lighthouse form factor."
1514
1514
  },
1515
1515
  "timeoutMs": {
1516
1516
  "type": "number",
1517
- "description": "Overall budget for the lighthouse process, in ms. Default 120000."
1517
+ "description": "Timeout in milliseconds."
1518
1518
  }
1519
1519
  },
1520
1520
  "required": [
@@ -1525,21 +1525,21 @@ export const MANIFEST: ToolSpec[] = [
1525
1525
  },
1526
1526
  {
1527
1527
  "name": "mock_request",
1528
- "description": "Register a mock rule on a target's persistent fake-backend session (CDP Fetch domain): match requests by urlPattern and fulfill with a canned response, fail (abort), or continue -- optionally with fault injection (delayMs/failRate). The session survives reloads/navigations and lives until clear_mocks; call repeatedly to mock several endpoints on one target. reload:true applies it immediately. Persistent across calls only via the MCP server, not the one-shot CLI.",
1528
+ "description": "Register a persistent request mock; urlPattern is required.",
1529
1529
  "inputSchema": {
1530
1530
  "type": "object",
1531
1531
  "properties": {
1532
1532
  "lease": {
1533
1533
  "type": "string",
1534
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1534
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1535
1535
  },
1536
1536
  "target": {
1537
1537
  "type": "string",
1538
- "description": "Which page's mock session. Defaults to the active page. Grammar: server instructions."
1538
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1539
1539
  },
1540
1540
  "urlPattern": {
1541
1541
  "type": "string",
1542
- "description": "CDP Fetch urlPattern glob: '*' any run of chars, '?' exactly one, '\\' escapes. Only matching URLs are paused. e.g. \"*/api/users*\"."
1542
+ "description": "URL glob (*, ?; \\ escapes)."
1543
1543
  },
1544
1544
  "action": {
1545
1545
  "type": "string",
@@ -1552,39 +1552,39 @@ export const MANIFEST: ToolSpec[] = [
1552
1552
  },
1553
1553
  "status": {
1554
1554
  "type": "number",
1555
- "description": "fulfill: HTTP status for the canned response. Default 200."
1555
+ "description": "Mock HTTP status."
1556
1556
  },
1557
1557
  "body": {
1558
1558
  "type": "string",
1559
- "description": "fulfill: response body string (base64-encoded for CDP internally)."
1559
+ "description": "Mock response body."
1560
1560
  },
1561
1561
  "contentType": {
1562
1562
  "type": "string",
1563
- "description": "fulfill: Content-Type header. Default \"application/json\"."
1563
+ "description": "Response Content-Type."
1564
1564
  },
1565
1565
  "headers": {
1566
1566
  "type": "object",
1567
- "description": "fulfill: extra response headers (name->value); override Content-Type case-insensitively. Add \"Access-Control-Allow-Origin\" for cross-origin fetches."
1567
+ "description": "Extra response headers."
1568
1568
  },
1569
1569
  "errorReason": {
1570
1570
  "type": "string",
1571
- "description": "fail: CDP Network.ErrorReason, e.g. \"Failed\" (default), \"BlockedByClient\", \"ConnectionRefused\", \"TimedOut\"."
1571
+ "description": "CDP Network.ErrorReason, e.g. Failed|BlockedByClient|ConnectionRefused|TimedOut."
1572
1572
  },
1573
1573
  "method": {
1574
1574
  "type": "string",
1575
- "description": "Only mock this HTTP method (e.g. \"POST\"); others pass through."
1575
+ "description": "HTTP method."
1576
1576
  },
1577
1577
  "delayMs": {
1578
1578
  "type": "number",
1579
- "description": "Fault injection: artificial latency in ms before responding."
1579
+ "description": "Artificial delay in milliseconds."
1580
1580
  },
1581
1581
  "failRate": {
1582
1582
  "type": "number",
1583
- "description": "Fault injection: probability 0..1 of failing a matched request regardless of action."
1583
+ "description": "Failure probability 0..1."
1584
1584
  },
1585
1585
  "reload": {
1586
1586
  "type": "boolean",
1587
- "description": "Reload the target after arming so the mock catches traffic immediately."
1587
+ "description": "Reload before capture."
1588
1588
  }
1589
1589
  },
1590
1590
  "required": [
@@ -1595,13 +1595,13 @@ export const MANIFEST: ToolSpec[] = [
1595
1595
  },
1596
1596
  {
1597
1597
  "name": "list_mocks",
1598
- "description": "List active fake-backend sessions (one per target) with their rules and hit counts. Prunes sessions whose tab has closed.",
1598
+ "description": "List active request-mocking sessions and hit counts.",
1599
1599
  "inputSchema": {
1600
1600
  "type": "object",
1601
1601
  "properties": {
1602
1602
  "lease": {
1603
1603
  "type": "string",
1604
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1604
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1605
1605
  },
1606
1606
  "target": {
1607
1607
  "type": "string",
@@ -1614,17 +1614,17 @@ export const MANIFEST: ToolSpec[] = [
1614
1614
  },
1615
1615
  {
1616
1616
  "name": "clear_mocks",
1617
- "description": "Tear down fake-backend sessions (Fetch.disable + close the connection). Clears the resolved target's session by default, or every active session with all:true.",
1617
+ "description": "Clear the selected or all request-mocking sessions.",
1618
1618
  "inputSchema": {
1619
1619
  "type": "object",
1620
1620
  "properties": {
1621
1621
  "lease": {
1622
1622
  "type": "string",
1623
- "description": "Lease token from claim_page. Omit for a tab this process holds; required for a tab held by another process or one claimed explicitly. Auto-acquired under CDP_REQUIRE_LEASE (then pass target, not lease). See server instructions."
1623
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1624
1624
  },
1625
1625
  "target": {
1626
1626
  "type": "string",
1627
- "description": "Which page's mock session to clear. Defaults to the active page; ignored when all:true. Grammar: server instructions."
1627
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1628
1628
  },
1629
1629
  "all": {
1630
1630
  "type": "boolean",
@@ -1637,29 +1637,29 @@ export const MANIFEST: ToolSpec[] = [
1637
1637
  },
1638
1638
  {
1639
1639
  "name": "claim_page",
1640
- "description": "Take exclusive ownership of a browser tab, returning an opaque lease token (needed once under CDP_REQUIRE_LEASE for any tab you drive). Two modes: FRESH TAB (no target - opens one, optionally at url, and claims it: 'give me my own tab' in one call) and TAKEOVER (target - claims an already-open tab, e.g. the human's, resolving the selector against the live page list, creating nothing). The opened flag is true only when this call created the tab, and release_page consults that record, so a taken-over tab is left open on release. Refused from the CLI (its per-call process would make the lease instantly reclaimable). The answer carries humanActiveMs, ms since input this server did not dispatch; null is NO DATA (no activity beacon, or every input was this server's own) and never means 'no human'; absent on a backend that cannot answer. On takeover of a tab a human used within 30s it adds contention, a warning - but THE CLAIM IS NEVER REFUSED FOR THIS: takeover is its purpose, you already hold the lease; it only warns you're fighting a live person, so open your own tab or ask first. Limits: input inside a cross-origin iframe is invisible, and a second MCP server's clicks read as human.",
1640
+ "description": "Claim an existing tab or open a fresh one; CLI use is refused.",
1641
1641
  "inputSchema": {
1642
1642
  "type": "object",
1643
1643
  "properties": {
1644
1644
  "target": {
1645
1645
  "type": "string",
1646
- "description": "Take over an already-open tab (e.g. one the human has open). Resolved against the LIVE page list only, so it never opens a tab — a selector matching nothing is an error. Left open on release. Refused if another live process holds it (including a lease auto-acquired under CDP_REQUIRE_LEASE): takes over unleased human tabs, never steals from a live agent. Mutually exclusive with targetId. Selector grammar: server instructions."
1646
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1647
1647
  },
1648
1648
  "targetId": {
1649
1649
  "type": "string",
1650
- "description": "Exact target id (not a selector) of an already-open page to claim instead of opening one. Back-compat only; prefer target, which also accepts an exact id. Mutually exclusive with target."
1650
+ "description": "Exact target ID."
1651
1651
  },
1652
1652
  "url": {
1653
1653
  "type": "string",
1654
- "description": "When opening a fresh tab, navigate it here. Ignored when target or targetId is given."
1654
+ "description": "URL value."
1655
1655
  },
1656
1656
  "label": {
1657
1657
  "type": "string",
1658
- "description": "Agent label recorded on the lease; surfaced in conflict errors and list_leases. Defaults to pid-<pid>."
1658
+ "description": "Agent lease label."
1659
1659
  },
1660
1660
  "ttlMs": {
1661
1661
  "type": "number",
1662
- "description": "How long the lease survives without use before it is reclaimable. Defaults to CDP_LEASE_TTL_MS, else 900000 (15min); every checked call refreshes it."
1662
+ "description": "Lease TTL in milliseconds."
1663
1663
  }
1664
1664
  },
1665
1665
  "required": [],
@@ -1668,21 +1668,21 @@ export const MANIFEST: ToolSpec[] = [
1668
1668
  },
1669
1669
  {
1670
1670
  "name": "release_page",
1671
- "description": "Give a lease back, closing the tab only if this toolkit opened it. Take exactly one of lease (the token) or target (a selector for a tab this process holds - use this to release a lease the gate acquired for you automatically, since that path never handed you a token). A tab with a creation record from this toolkit is closed; a tab that was already open and merely claimed is released and left alone - override either way with close. Idempotent: an already-released, reclaimed, or expired lease reports released:false and closes nothing (by then the tab may belong to another agent). Answers {released, closed, targetId}.",
1671
+ "description": "Release a page lease and optionally close its tab; provide lease or target.",
1672
1672
  "inputSchema": {
1673
1673
  "type": "object",
1674
1674
  "properties": {
1675
1675
  "lease": {
1676
1676
  "type": "string",
1677
- "description": "Token from claim_page / new_page{claim:true}. Mutually exclusive with 'target'. Under CDP_REQUIRE_LEASE an auto-acquired lease never produced a token — give 'target' instead."
1677
+ "description": "Lease token; omit for a tab this process already holds. See server instructions."
1678
1678
  },
1679
1679
  "target": {
1680
1680
  "type": "string",
1681
- "description": "A tab THIS process holds (grammar: server instructions). Mutually exclusive with 'lease'. Refused if another process holds the tab."
1681
+ "description": "Page selector (index:/url:/title:/label:/targetId, default active); grammar in server instructions."
1682
1682
  },
1683
1683
  "close": {
1684
1684
  "type": "boolean",
1685
- "description": "Force the close decision instead of letting the creation record decide: true closes even a tab this toolkit did not open; false keeps an agent-created tab open. Omit to close only tabs this toolkit created."
1685
+ "description": "Override close behavior."
1686
1686
  }
1687
1687
  },
1688
1688
  "required": [],
@@ -1691,7 +1691,7 @@ export const MANIFEST: ToolSpec[] = [
1691
1691
  },
1692
1692
  {
1693
1693
  "name": "list_leases",
1694
- "description": "Enumerate every active lease for diagnosis - backend, target id, label, pid, createdAt, lastUsedAt, ttlMs, whether the owning process is alive, and whether the lease is reclaimable and why. No token required; it never returns the lease nonce, so it cannot be used to forge one. An unreadable or unparseable lease row instead carries unreadable, with label, pid and timestamps zeroed and stale forced false (an unreadable lease must never read as free to take). Under CDP_REQUIRE_LEASE it reaps abandoned agent tabs exactly as list_pages does, into an additive reaped array, omitting their rows. Where the tab can answer, a row also carries humanActiveMs, ms since input this server did not dispatch - note lastUsedAt tracks TOOLKIT calls only, so a tab a person has typed in for ten minutes looks idle, which is what this exposes; the field is absent, never null, when the tab cannot answer, and that absence means 'no answer', never 'nobody is there'. idleMs (now - lastUsedAt) and expiresAt (lastUsedAt + ttlMs) are computed fresh each call and omitted on an unreadable row.",
1694
+ "description": "List active leases for diagnosis without exposing lease tokens.",
1695
1695
  "inputSchema": {
1696
1696
  "type": "object",
1697
1697
  "properties": {},