@pyrokine/mcp-chrome 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +103 -53
  2. package/dist/anti-detection/behavior.d.ts +0 -8
  3. package/dist/anti-detection/behavior.d.ts.map +1 -1
  4. package/dist/anti-detection/behavior.js +0 -16
  5. package/dist/anti-detection/behavior.js.map +1 -1
  6. package/dist/cdp/client.d.ts +0 -2
  7. package/dist/cdp/client.d.ts.map +1 -1
  8. package/dist/cdp/client.js +30 -45
  9. package/dist/cdp/client.js.map +1 -1
  10. package/dist/cdp/launcher.d.ts +1 -8
  11. package/dist/cdp/launcher.d.ts.map +1 -1
  12. package/dist/cdp/launcher.js +4 -20
  13. package/dist/cdp/launcher.js.map +1 -1
  14. package/dist/core/auto-wait.d.ts +2 -2
  15. package/dist/core/auto-wait.d.ts.map +1 -1
  16. package/dist/core/auto-wait.js +1 -1
  17. package/dist/core/auto-wait.js.map +1 -1
  18. package/dist/core/errors.d.ts +10 -13
  19. package/dist/core/errors.d.ts.map +1 -1
  20. package/dist/core/errors.js +19 -25
  21. package/dist/core/errors.js.map +1 -1
  22. package/dist/core/locator.d.ts +6 -7
  23. package/dist/core/locator.d.ts.map +1 -1
  24. package/dist/core/locator.js +77 -31
  25. package/dist/core/locator.js.map +1 -1
  26. package/dist/core/retry.d.ts.map +1 -1
  27. package/dist/core/retry.js +1 -1
  28. package/dist/core/retry.js.map +1 -1
  29. package/dist/core/session.d.ts +32 -33
  30. package/dist/core/session.d.ts.map +1 -1
  31. package/dist/core/session.js +154 -114
  32. package/dist/core/session.js.map +1 -1
  33. package/dist/core/types.d.ts +4 -0
  34. package/dist/core/types.d.ts.map +1 -1
  35. package/dist/core/types.js +6 -0
  36. package/dist/core/types.js.map +1 -1
  37. package/dist/core/unified-session.d.ts +54 -67
  38. package/dist/core/unified-session.d.ts.map +1 -1
  39. package/dist/core/unified-session.js +215 -181
  40. package/dist/core/unified-session.js.map +1 -1
  41. package/dist/extension/bridge.d.ts +0 -19
  42. package/dist/extension/bridge.d.ts.map +1 -1
  43. package/dist/extension/bridge.js +6 -52
  44. package/dist/extension/bridge.js.map +1 -1
  45. package/dist/extension/http-server.d.ts +13 -11
  46. package/dist/extension/http-server.d.ts.map +1 -1
  47. package/dist/extension/http-server.js +101 -95
  48. package/dist/extension/http-server.js.map +1 -1
  49. package/dist/index.js +11 -64
  50. package/dist/index.js.map +1 -1
  51. package/dist/tools/browse.d.ts +3 -80
  52. package/dist/tools/browse.d.ts.map +1 -1
  53. package/dist/tools/browse.js +135 -291
  54. package/dist/tools/browse.js.map +1 -1
  55. package/dist/tools/cookies.d.ts +3 -71
  56. package/dist/tools/cookies.d.ts.map +1 -1
  57. package/dist/tools/cookies.js +75 -157
  58. package/dist/tools/cookies.js.map +1 -1
  59. package/dist/tools/evaluate.d.ts +3 -52
  60. package/dist/tools/evaluate.d.ts.map +1 -1
  61. package/dist/tools/evaluate.js +35 -86
  62. package/dist/tools/evaluate.js.map +1 -1
  63. package/dist/tools/extract.d.ts +3 -226
  64. package/dist/tools/extract.d.ts.map +1 -1
  65. package/dist/tools/extract.js +98 -170
  66. package/dist/tools/extract.js.map +1 -1
  67. package/dist/tools/index.d.ts +9 -9
  68. package/dist/tools/index.d.ts.map +1 -1
  69. package/dist/tools/index.js +9 -9
  70. package/dist/tools/index.js.map +1 -1
  71. package/dist/tools/input.d.ts +3 -258
  72. package/dist/tools/input.d.ts.map +1 -1
  73. package/dist/tools/input.js +56 -143
  74. package/dist/tools/input.js.map +1 -1
  75. package/dist/tools/logs.d.ts +3 -51
  76. package/dist/tools/logs.d.ts.map +1 -1
  77. package/dist/tools/logs.js +47 -108
  78. package/dist/tools/logs.js.map +1 -1
  79. package/dist/tools/manage.d.ts +3 -64
  80. package/dist/tools/manage.d.ts.map +1 -1
  81. package/dist/tools/manage.js +243 -373
  82. package/dist/tools/manage.js.map +1 -1
  83. package/dist/tools/schema.d.ts +16 -182
  84. package/dist/tools/schema.d.ts.map +1 -1
  85. package/dist/tools/schema.js +70 -159
  86. package/dist/tools/schema.js.map +1 -1
  87. package/dist/tools/wait.d.ts +3 -221
  88. package/dist/tools/wait.d.ts.map +1 -1
  89. package/dist/tools/wait.js +74 -145
  90. package/dist/tools/wait.js.map +1 -1
  91. package/package.json +1 -1
@@ -13,434 +13,261 @@
13
13
  * - cdp: 发送任意 CDP 命令(高级)
14
14
  */
15
15
  import { z } from 'zod';
16
- import { devices, formatErrorResponse, getSession, getUnifiedSession } from '../core/index.js';
17
- /**
18
- * manage 工具定义
19
- */
20
- export const manageToolDefinition = {
21
- name: 'manage',
22
- description: '页面与环境管理:新建页面、关闭页面、缓存、视口、UA、设备模拟',
23
- inputSchema: {
24
- type: 'object',
25
- properties: {
26
- action: {
27
- type: 'string',
28
- enum: [
29
- 'newPage',
30
- 'closePage',
31
- 'clearCache',
32
- 'viewport',
33
- 'userAgent',
34
- 'emulate',
35
- 'inputMode',
36
- 'stealth',
37
- 'cdp',
38
- ],
39
- description: '管理操作',
40
- },
41
- inputMode: {
42
- type: 'string',
43
- enum: ['stealth', 'precise'],
44
- description: '输入模式(inputMode)。precise=debugger API(默认,可绕过 CSP 但显示调试提示);stealth=JS 事件模拟(不触发调试提示但受 CSP 限制,适用于反检测场景)',
45
- },
46
- cdpMethod: {
47
- type: 'string',
48
- description: 'CDP 方法名(cdp),如 Runtime.evaluate、Page.captureScreenshot',
49
- },
50
- cdpParams: {
51
- type: 'object',
52
- description: 'CDP 方法参数(cdp)',
53
- },
54
- targetId: {
55
- type: 'string',
56
- description: '目标页面 ID(closePage)',
57
- },
58
- cacheType: {
59
- type: 'string',
60
- enum: ['all', 'cookies', 'storage', 'cache'],
61
- description: '清除类型(clearCache)',
62
- },
63
- width: {
64
- type: 'number',
65
- description: '视口宽度(viewport)',
66
- },
67
- height: {
68
- type: 'number',
69
- description: '视口高度(viewport)',
70
- },
71
- userAgent: {
72
- type: 'string',
73
- description: 'User-Agent 字符串(userAgent)',
74
- },
75
- device: {
76
- type: 'string',
77
- description: '设备名称(emulate),如 iPhone 13, iPad Pro',
78
- },
79
- },
80
- required: ['action'],
81
- },
82
- };
16
+ import { devices, formatErrorResponse, formatResponse, getSession, getUnifiedSession } from '../core/index.js';
83
17
  /**
84
18
  * manage 参数 schema
85
19
  */
86
20
  const manageSchema = z.object({
87
21
  action: z.enum([
88
- 'newPage',
89
- 'closePage',
90
- 'clearCache',
91
- 'viewport',
92
- 'userAgent',
93
- 'emulate',
94
- 'inputMode',
95
- 'stealth',
96
- 'cdp',
97
- ]),
98
- targetId: z.string().optional(),
99
- cacheType: z.enum(['all', 'cookies', 'storage', 'cache']).optional(),
100
- width: z.number().optional(),
101
- height: z.number().optional(),
102
- userAgent: z.string().optional(),
103
- device: z.string().optional(),
104
- inputMode: z.enum(['stealth', 'precise']).optional(),
105
- cdpMethod: z.string().optional(),
106
- cdpParams: z.record(z.unknown()).optional(),
22
+ 'newPage', 'closePage', 'clearCache', 'viewport',
23
+ 'userAgent', 'emulate', 'inputMode', 'stealth', 'cdp',
24
+ ]).describe('管理操作'),
25
+ inputMode: z.enum(['stealth', 'precise']).optional().describe('输入模式(inputMode)。precise=debugger API(默认,可绕过 CSP 但显示调试提示);stealth=JS 事件模拟(不触发调试提示但受 CSP 限制,适用于反检测场景)'),
26
+ cdpMethod: z.string().optional().describe('CDP 方法名(cdp),如 Runtime.evaluate、Page.captureScreenshot'),
27
+ cdpParams: z.record(z.unknown()).optional().describe('CDP 方法参数(cdp)'),
28
+ targetId: z.string().optional().describe('目标页面 ID(closePage)'),
29
+ cacheType: z.enum(['all', 'cookies', 'storage', 'cache']).optional().describe('清除类型(clearCache)'),
30
+ width: z.number().optional().describe('视口宽度(viewport)'),
31
+ height: z.number().optional().describe('视口高度(viewport)'),
32
+ userAgent: z.string().optional().describe('User-Agent 字符串(userAgent)'),
33
+ device: z.string().optional().describe('设备名称(emulate),如 iPhone 13, iPad Pro'),
107
34
  });
108
35
  /**
109
36
  * manage 工具处理器
110
37
  */
111
- export async function handleManage(params) {
38
+ async function handleManage(args) {
112
39
  try {
113
- const args = manageSchema.parse(params);
114
40
  const unifiedSession = getUnifiedSession();
115
41
  const mode = unifiedSession.getMode();
116
42
  switch (args.action) {
117
43
  case 'newPage': {
118
44
  const target = await unifiedSession.newPage();
119
- return {
120
- content: [
121
- {
122
- type: 'text',
123
- text: JSON.stringify({
124
- success: true,
125
- action: 'newPage',
126
- target,
127
- mode,
128
- }),
129
- },
130
- ],
131
- };
45
+ return formatResponse({
46
+ success: true,
47
+ action: 'newPage',
48
+ target,
49
+ mode,
50
+ });
132
51
  }
133
52
  case 'closePage': {
134
53
  await unifiedSession.closePage(args.targetId);
135
- return {
136
- content: [
137
- {
138
- type: 'text',
139
- text: JSON.stringify({
140
- success: true,
141
- action: 'closePage',
142
- targetId: args.targetId ?? 'current',
143
- mode,
144
- }),
145
- },
146
- ],
147
- };
54
+ return formatResponse({
55
+ success: true,
56
+ action: 'closePage',
57
+ targetId: args.targetId ?? 'current',
58
+ mode,
59
+ });
148
60
  }
149
61
  case 'clearCache': {
150
- const cacheType = (args.cacheType ?? 'all');
151
- if (mode === 'extension') {
152
- // Extension 模式:只支持 cookies 清除
153
- if (cacheType === 'all' || cacheType === 'cookies') {
154
- await unifiedSession.clearCookies();
62
+ return await unifiedSession.withTabId(undefined, async () => {
63
+ const cacheType = (args.cacheType ?? 'all');
64
+ if (mode === 'extension') {
65
+ // Extension 模式:只支持 cookies 清除
66
+ if (cacheType === 'all' || cacheType === 'cookies') {
67
+ await unifiedSession.clearCookies();
68
+ }
69
+ if (cacheType === 'storage' || cacheType === 'cache') {
70
+ return formatResponse({
71
+ success: true,
72
+ action: 'clearCache',
73
+ cacheType,
74
+ mode,
75
+ warning: 'Extension 模式仅支持清除 cookies,storage 和 cache 需要 CDP 模式',
76
+ });
77
+ }
78
+ }
79
+ else {
80
+ const session = getSession();
81
+ await session.clearCache(cacheType);
155
82
  }
156
- if (cacheType === 'storage' || cacheType === 'cache') {
83
+ return formatResponse({
84
+ success: true,
85
+ action: 'clearCache',
86
+ cacheType,
87
+ mode,
88
+ });
89
+ });
90
+ }
91
+ case 'viewport': {
92
+ return await unifiedSession.withTabId(undefined, async () => {
93
+ if (args.width === undefined || args.height === undefined) {
157
94
  return {
158
95
  content: [
159
96
  {
160
97
  type: 'text',
161
98
  text: JSON.stringify({
162
- success: true,
163
- action: 'clearCache',
164
- cacheType,
165
- mode,
166
- warning: 'Extension 模式仅支持清除 cookies,storage 和 cache 需要 CDP 模式',
99
+ error: {
100
+ code: 'INVALID_ARGUMENT',
101
+ message: '设置视口需要 width 和 height 参数',
102
+ },
167
103
  }),
168
104
  },
169
105
  ],
106
+ isError: true,
170
107
  };
171
108
  }
172
- }
173
- else {
174
- const session = getSession();
175
- await session.clearCache(cacheType);
176
- }
177
- return {
178
- content: [
179
- {
180
- type: 'text',
181
- text: JSON.stringify({
182
- success: true,
183
- action: 'clearCache',
184
- cacheType,
185
- mode,
186
- }),
187
- },
188
- ],
189
- };
190
- }
191
- case 'viewport': {
192
- if (args.width === undefined || args.height === undefined) {
193
- return {
194
- content: [
195
- {
196
- type: 'text',
197
- text: JSON.stringify({
198
- error: {
199
- code: 'INVALID_ARGUMENT',
200
- message: '设置视口需要 width 和 height 参数',
201
- },
202
- }),
203
- },
204
- ],
205
- isError: true,
206
- };
207
- }
208
- if (mode === 'extension') {
209
- // Extension 模式:使用 debugger API 设置视口
210
- await unifiedSession.sendCdpCommand('Emulation.setDeviceMetricsOverride', {
109
+ if (mode === 'extension') {
110
+ // Extension 模式:使用 debugger API 设置视口
111
+ await unifiedSession.sendCdpCommand('Emulation.setDeviceMetricsOverride', {
112
+ width: args.width,
113
+ height: args.height,
114
+ deviceScaleFactor: 1,
115
+ mobile: false,
116
+ });
117
+ }
118
+ else {
119
+ const session = getSession();
120
+ await session.setViewport(args.width, args.height);
121
+ }
122
+ // 触发 resize 事件(Emulation API 不会自动触发)
123
+ await unifiedSession.evaluate('window.dispatchEvent(new Event("resize"))');
124
+ return formatResponse({
125
+ success: true,
126
+ action: 'viewport',
211
127
  width: args.width,
212
128
  height: args.height,
213
- deviceScaleFactor: 1,
214
- mobile: false,
129
+ mode,
215
130
  });
216
- }
217
- else {
218
- const session = getSession();
219
- await session.setViewport(args.width, args.height);
220
- }
221
- return {
222
- content: [
223
- {
224
- type: 'text',
225
- text: JSON.stringify({
226
- success: true,
227
- action: 'viewport',
228
- width: args.width,
229
- height: args.height,
230
- mode,
231
- }),
232
- },
233
- ],
234
- };
131
+ });
235
132
  }
236
133
  case 'userAgent': {
237
- if (!args.userAgent) {
238
- return {
239
- content: [
240
- {
241
- type: 'text',
242
- text: JSON.stringify({
243
- error: {
244
- code: 'INVALID_ARGUMENT',
245
- message: '设置 User-Agent 需要 userAgent 参数',
246
- },
247
- }),
248
- },
249
- ],
250
- isError: true,
251
- };
252
- }
253
- if (mode === 'extension') {
254
- // Extension 模式:使用 debugger API 设置 UA
255
- await unifiedSession.sendCdpCommand('Emulation.setUserAgentOverride', {
134
+ return await unifiedSession.withTabId(undefined, async () => {
135
+ if (!args.userAgent) {
136
+ return {
137
+ content: [
138
+ {
139
+ type: 'text',
140
+ text: JSON.stringify({
141
+ error: {
142
+ code: 'INVALID_ARGUMENT',
143
+ message: '设置 User-Agent 需要 userAgent 参数',
144
+ },
145
+ }),
146
+ },
147
+ ],
148
+ isError: true,
149
+ };
150
+ }
151
+ if (mode === 'extension') {
152
+ // Extension 模式:使用 debugger API 设置 UA
153
+ await unifiedSession.sendCdpCommand('Emulation.setUserAgentOverride', {
154
+ userAgent: args.userAgent,
155
+ });
156
+ }
157
+ else {
158
+ const session = getSession();
159
+ await session.setUserAgent(args.userAgent);
160
+ }
161
+ return formatResponse({
162
+ success: true,
163
+ action: 'userAgent',
256
164
  userAgent: args.userAgent,
165
+ mode,
257
166
  });
258
- }
259
- else {
260
- const session = getSession();
261
- await session.setUserAgent(args.userAgent);
262
- }
263
- return {
264
- content: [
265
- {
266
- type: 'text',
267
- text: JSON.stringify({
268
- success: true,
269
- action: 'userAgent',
270
- userAgent: args.userAgent,
271
- mode,
272
- }),
273
- },
274
- ],
275
- };
167
+ });
276
168
  }
277
169
  case 'inputMode': {
278
170
  if (!args.inputMode) {
279
171
  // 返回当前模式
280
- return {
281
- content: [
282
- {
283
- type: 'text',
284
- text: JSON.stringify({
285
- success: true,
286
- action: 'inputMode',
287
- currentMode: unifiedSession.getInputMode(),
288
- availableModes: ['stealth', 'precise'],
289
- description: {
290
- stealth: 'JS 事件模拟,不触发调试提示,但受 CSP 限制(evaluate 可能失败)',
291
- precise: 'debugger API,可绕过 CSP,但显示"扩展程序正在调试此浏览器"',
292
- },
293
- }),
294
- },
295
- ],
296
- };
172
+ return formatResponse({
173
+ success: true,
174
+ action: 'inputMode',
175
+ currentMode: unifiedSession.getInputMode(),
176
+ availableModes: ['stealth', 'precise'],
177
+ description: {
178
+ stealth: 'JS 事件模拟,不触发调试提示,但受 CSP 限制(evaluate 可能失败)',
179
+ precise: 'debugger API,可绕过 CSP,但显示"扩展程序正在调试此浏览器"',
180
+ },
181
+ });
297
182
  }
298
183
  unifiedSession.setInputMode(args.inputMode);
299
- return {
300
- content: [
301
- {
302
- type: 'text',
303
- text: JSON.stringify({
304
- success: true,
305
- action: 'inputMode',
306
- inputMode: args.inputMode,
307
- mode,
308
- }),
309
- },
310
- ],
311
- };
184
+ return formatResponse({
185
+ success: true,
186
+ action: 'inputMode',
187
+ inputMode: args.inputMode,
188
+ mode,
189
+ });
312
190
  }
313
191
  case 'emulate': {
314
- if (!args.device) {
315
- // 列出可用设备
316
- return {
317
- content: [
318
- {
319
- type: 'text',
320
- text: JSON.stringify({
321
- success: true,
322
- action: 'emulate',
323
- availableDevices: Object.keys(devices),
324
- }),
325
- },
326
- ],
327
- };
328
- }
329
- const device = devices[args.device];
330
- if (!device) {
331
- return {
332
- content: [
333
- {
334
- type: 'text',
335
- text: JSON.stringify({
336
- error: {
337
- code: 'INVALID_ARGUMENT',
338
- message: `未知设备: ${args.device}`,
339
- suggestion: `可用设备: ${Object.keys(devices).join(', ')}`,
340
- },
341
- }),
342
- },
343
- ],
344
- isError: true,
345
- };
346
- }
347
- if (mode === 'extension') {
348
- // Extension 模式:使用 debugger API
349
- await unifiedSession.sendCdpCommand('Emulation.setDeviceMetricsOverride', {
350
- width: device.viewport.width,
351
- height: device.viewport.height,
352
- deviceScaleFactor: device.viewport.deviceScaleFactor || 1,
353
- mobile: device.viewport.isMobile || false,
354
- });
355
- await unifiedSession.sendCdpCommand('Emulation.setUserAgentOverride', {
356
- userAgent: device.userAgent,
192
+ return await unifiedSession.withTabId(undefined, async () => {
193
+ if (!args.device) {
194
+ // 列出可用设备
195
+ return formatResponse({
196
+ success: true,
197
+ action: 'emulate',
198
+ availableDevices: Object.keys(devices),
199
+ });
200
+ }
201
+ const device = devices[args.device];
202
+ if (!device) {
203
+ return {
204
+ content: [
205
+ {
206
+ type: 'text',
207
+ text: JSON.stringify({
208
+ error: {
209
+ code: 'INVALID_ARGUMENT',
210
+ message: `未知设备: ${args.device}`,
211
+ suggestion: `可用设备: ${Object.keys(devices)
212
+ .join(', ')}`,
213
+ },
214
+ }),
215
+ },
216
+ ],
217
+ isError: true,
218
+ };
219
+ }
220
+ if (mode === 'extension') {
221
+ // Extension 模式:使用 debugger API
222
+ await unifiedSession.sendCdpCommand('Emulation.setDeviceMetricsOverride', {
223
+ width: device.viewport.width,
224
+ height: device.viewport.height,
225
+ deviceScaleFactor: device.viewport.deviceScaleFactor || 1,
226
+ mobile: device.viewport.isMobile || false,
227
+ });
228
+ await unifiedSession.sendCdpCommand('Emulation.setUserAgentOverride', {
229
+ userAgent: device.userAgent,
230
+ });
231
+ }
232
+ else {
233
+ const session = getSession();
234
+ await session.setViewport(device.viewport.width, device.viewport.height);
235
+ await session.setUserAgent(device.userAgent);
236
+ }
237
+ // 触发 resize 事件(Emulation API 不会自动触发)
238
+ await unifiedSession.evaluate('window.dispatchEvent(new Event("resize"))');
239
+ return formatResponse({
240
+ success: true,
241
+ action: 'emulate',
242
+ device: args.device,
243
+ viewport: device.viewport,
244
+ mode,
357
245
  });
358
- }
359
- else {
360
- const session = getSession();
361
- await session.setViewport(device.viewport.width, device.viewport.height);
362
- await session.setUserAgent(device.userAgent);
363
- }
364
- return {
365
- content: [
366
- {
367
- type: 'text',
368
- text: JSON.stringify({
369
- success: true,
370
- action: 'emulate',
371
- device: args.device,
372
- viewport: device.viewport,
373
- mode,
374
- }),
375
- },
376
- ],
377
- };
246
+ });
378
247
  }
379
248
  case 'stealth': {
380
- await unifiedSession.injectStealth();
381
- return {
382
- content: [
383
- {
384
- type: 'text',
385
- text: JSON.stringify({
386
- success: true,
387
- action: 'stealth',
388
- mode,
389
- note: '已注入反检测脚本',
390
- }),
391
- },
392
- ],
393
- };
249
+ return await unifiedSession.withTabId(undefined, async () => {
250
+ await unifiedSession.injectStealth();
251
+ return formatResponse({
252
+ success: true,
253
+ action: 'stealth',
254
+ mode,
255
+ note: '已注入反检测脚本',
256
+ });
257
+ });
394
258
  }
395
259
  case 'cdp': {
396
- if (!args.cdpMethod) {
397
- return {
398
- content: [
399
- {
400
- type: 'text',
401
- text: JSON.stringify({
402
- error: {
403
- code: 'INVALID_ARGUMENT',
404
- message: '缺少 cdpMethod 参数',
405
- suggestion: '请指定 CDP 方法名,如 Runtime.evaluate、Page.captureScreenshot',
406
- },
407
- }),
408
- },
409
- ],
410
- isError: true,
411
- };
412
- }
413
- try {
414
- const result = await unifiedSession.sendCdpCommand(args.cdpMethod, args.cdpParams);
415
- return {
416
- content: [
417
- {
418
- type: 'text',
419
- text: JSON.stringify({
420
- success: true,
421
- action: 'cdp',
422
- method: args.cdpMethod,
423
- result,
424
- mode,
425
- }, null, 2),
426
- },
427
- ],
428
- };
429
- }
430
- catch (error) {
431
- const errorMessage = error instanceof Error ? error.message : String(error);
432
- // Extension 模式下某些 CDP 域不支持
433
- if (mode === 'extension' && (errorMessage.includes('not supported') || errorMessage.includes('not found'))) {
434
- const domain = args.cdpMethod.split('.')[0];
260
+ return await unifiedSession.withTabId(undefined, async () => {
261
+ if (!args.cdpMethod) {
435
262
  return {
436
263
  content: [
437
264
  {
438
265
  type: 'text',
439
266
  text: JSON.stringify({
440
267
  error: {
441
- code: 'CDP_DOMAIN_NOT_SUPPORTED',
442
- message: `Extension 模式不支持 ${domain} 域`,
443
- suggestion: 'Extension 模式可用域:Page、Runtime、Emulation、DOM、Input、Network。如需完整 CDP 支持,请使用 CDP 模式(browse action="launch")',
268
+ code: 'INVALID_ARGUMENT',
269
+ message: '缺少 cdpMethod 参数',
270
+ suggestion: '请指定 CDP 方法名,如 Runtime.evaluate、Page.captureScreenshot',
444
271
  },
445
272
  }),
446
273
  },
@@ -448,8 +275,42 @@ export async function handleManage(params) {
448
275
  isError: true,
449
276
  };
450
277
  }
451
- throw error;
452
- }
278
+ try {
279
+ const result = await unifiedSession.sendCdpCommand(args.cdpMethod, args.cdpParams);
280
+ return formatResponse({
281
+ success: true,
282
+ action: 'cdp',
283
+ method: args.cdpMethod,
284
+ result,
285
+ mode,
286
+ });
287
+ }
288
+ catch (error) {
289
+ const errorMessage = error instanceof Error ? error.message : String(error);
290
+ // Extension 模式下某些 CDP 域不支持
291
+ if (mode ===
292
+ 'extension' &&
293
+ (errorMessage.includes('not supported') || errorMessage.includes('not found'))) {
294
+ const domain = args.cdpMethod.split('.')[0];
295
+ return {
296
+ content: [
297
+ {
298
+ type: 'text',
299
+ text: JSON.stringify({
300
+ error: {
301
+ code: 'CDP_DOMAIN_NOT_SUPPORTED',
302
+ message: `Extension 模式不支持 ${domain} 域`,
303
+ suggestion: 'Extension 模式可用域:Page、Runtime、Emulation、DOM、Input、Network。如需完整 CDP 支持,请使用 CDP 模式(browse action="launch")',
304
+ },
305
+ }),
306
+ },
307
+ ],
308
+ isError: true,
309
+ };
310
+ }
311
+ return formatErrorResponse(error);
312
+ }
313
+ });
453
314
  }
454
315
  default:
455
316
  return {
@@ -472,4 +333,13 @@ export async function handleManage(params) {
472
333
  return formatErrorResponse(error);
473
334
  }
474
335
  }
336
+ /**
337
+ * 注册 manage 工具
338
+ */
339
+ export function registerManageTool(server) {
340
+ server.registerTool('manage', {
341
+ description: '页面与环境管理:新建页面、关闭页面、缓存、视口、UA、设备模拟',
342
+ inputSchema: manageSchema,
343
+ }, (args) => handleManage(args));
344
+ }
475
345
  //# sourceMappingURL=manage.js.map