@roxybrowser/openapi 1.0.3 → 1.0.4-beta.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/lib/index.js CHANGED
@@ -10,8 +10,8 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
10
10
  import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
11
11
  import { RoxyClient } from './roxy-client.js';
12
12
  import { BrowserCreator } from './browser/browser-creator.js';
13
- import { TemplateManager } from './browser/template-manager.js';
14
13
  import { ProxyManager } from './proxy/proxy-manager.js';
14
+ import { ErrorAnalyzer } from './utils/error-analyzer.js';
15
15
  import { ConfigError, BrowserCreationError, } from './types.js';
16
16
  // ========== Configuration ==========
17
17
  function getConfig() {
@@ -137,7 +137,7 @@ const TOOLS = [
137
137
  },
138
138
  {
139
139
  name: 'roxy_create_browser_simple',
140
- description: 'Create a browser with simple configuration - ideal for quick setup with basic proxy',
140
+ description: 'Create a browser with simple configuration - ideal for quick setup with basic proxy and common options',
141
141
  inputSchema: {
142
142
  type: 'object',
143
143
  properties: {
@@ -178,13 +178,27 @@ const TOOLS = [
178
178
  enum: ['HTTP', 'HTTPS', 'SOCKS5'],
179
179
  description: 'Proxy type (optional, default: HTTP)',
180
180
  },
181
+ cookie: {
182
+ type: 'array',
183
+ description: 'Cookie list (optional)',
184
+ },
185
+ searchEngine: {
186
+ type: 'string',
187
+ enum: ['Google', 'Microsoft Bing', 'Yahoo', 'Yandex', 'DuckDuckGo'],
188
+ description: 'Default search engine (optional, default: Google)',
189
+ },
190
+ labelIds: {
191
+ type: 'array',
192
+ items: { type: 'number' },
193
+ description: 'Label IDs to assign (optional)',
194
+ },
181
195
  },
182
196
  required: ['workspaceId'],
183
197
  },
184
198
  },
185
199
  {
186
200
  name: 'roxy_create_browser_standard',
187
- description: 'Create a browser with standard configuration - covers most common use cases',
201
+ description: 'Create a browser with standard configuration - covers most common use cases with commonly used fingerprint settings',
188
202
  inputSchema: {
189
203
  type: 'object',
190
204
  properties: {
@@ -218,6 +232,43 @@ const TOOLS = [
218
232
  enum: ['138', '137', '136', '135', '133', '130', '125', '117', '109'],
219
233
  description: 'Browser core version (optional, default: 125)',
220
234
  },
235
+ userAgent: {
236
+ type: 'string',
237
+ description: 'Custom user agent (optional)',
238
+ },
239
+ cookie: {
240
+ type: 'array',
241
+ description: 'Cookie list (optional)',
242
+ },
243
+ searchEngine: {
244
+ type: 'string',
245
+ enum: ['Google', 'Microsoft Bing', 'Yahoo', 'Yandex', 'DuckDuckGo'],
246
+ description: 'Default search engine (optional)',
247
+ },
248
+ labelIds: {
249
+ type: 'array',
250
+ items: { type: 'number' },
251
+ description: 'Label IDs to assign (optional)',
252
+ },
253
+ defaultOpenUrl: {
254
+ type: 'array',
255
+ items: { type: 'string' },
256
+ description: 'URLs to open by default (optional)',
257
+ },
258
+ windowPlatformList: {
259
+ type: 'array',
260
+ items: {
261
+ type: 'object',
262
+ properties: {
263
+ platformUrl: { type: 'string', description: 'Platform URL' },
264
+ platformUserName: { type: 'string', description: 'Platform username' },
265
+ platformPassword: { type: 'string', description: 'Platform password' },
266
+ platformEfa: { type: 'string', description: 'Platform EFA' },
267
+ platformRemarks: { type: 'string', description: 'Platform remarks' },
268
+ },
269
+ },
270
+ description: 'Platform account information (optional)',
271
+ },
221
272
  proxyInfo: {
222
273
  type: 'object',
223
274
  description: 'Complete proxy configuration object (optional)',
@@ -234,26 +285,25 @@ const TOOLS = [
234
285
  checkChannel: { type: 'string', enum: ['IPRust.io', 'IP-API', 'IP123.in'] },
235
286
  },
236
287
  },
237
- openWidth: {
238
- type: 'string',
239
- description: 'Browser window width (optional, default: 1000)',
240
- },
241
- openHeight: {
242
- type: 'string',
243
- description: 'Browser window height (optional, default: 1000)',
244
- },
245
- language: {
246
- type: 'string',
247
- description: 'Browser language (optional, e.g., en-US)',
248
- },
249
- timeZone: {
250
- type: 'string',
251
- description: 'Browser timezone (optional, e.g., GMT-5:00 America/New_York)',
252
- },
253
- defaultOpenUrl: {
254
- type: 'array',
255
- items: { type: 'string' },
256
- description: 'URLs to open by default (optional)',
288
+ fingerInfo: {
289
+ type: 'object',
290
+ description: 'Common fingerprint configuration (optional) - for full control use roxy_create_browser_advanced',
291
+ properties: {
292
+ // Language and timezone
293
+ language: { type: 'string', description: 'Browser language (e.g., en-US)' },
294
+ timeZone: { type: 'string', description: 'Browser timezone (e.g., GMT-5:00 America/New_York)' },
295
+ // Window settings (commonly used)
296
+ openWidth: { type: 'string', description: 'Window width (default: 1000)' },
297
+ openHeight: { type: 'string', description: 'Window height (default: 1000)' },
298
+ // Media settings (commonly adjusted)
299
+ forbidAudio: { type: 'boolean', description: 'Enable/disable sound' },
300
+ forbidImage: { type: 'boolean', description: 'Enable/disable image loading' },
301
+ forbidMedia: { type: 'boolean', description: 'Enable/disable video playback' },
302
+ // Common fingerprint settings
303
+ webRTC: { type: 'number', enum: [0, 1, 2], description: 'WebRTC: 0=replace, 1=real, 2=disable' },
304
+ canvas: { type: 'boolean', description: 'Canvas: random vs real' },
305
+ webGL: { type: 'boolean', description: 'WebGL: random vs real' },
306
+ },
257
307
  },
258
308
  },
259
309
  required: ['workspaceId'],
@@ -261,7 +311,7 @@ const TOOLS = [
261
311
  },
262
312
  {
263
313
  name: 'roxy_create_browser_advanced',
264
- description: 'Create a browser with complete configuration control - for expert users',
314
+ description: 'Create a browser with complete configuration control - for expert users needing full parameter access',
265
315
  inputSchema: {
266
316
  type: 'object',
267
317
  properties: {
@@ -279,7 +329,7 @@ const TOOLS = [
279
329
  },
280
330
  windowRemark: {
281
331
  type: 'string',
282
- description: 'Window remarks (optional)',
332
+ description: 'Window remarks/notes (optional)',
283
333
  },
284
334
  os: {
285
335
  type: 'string',
@@ -299,6 +349,10 @@ const TOOLS = [
299
349
  type: 'string',
300
350
  description: 'Custom user agent (optional)',
301
351
  },
352
+ cookie: {
353
+ type: 'array',
354
+ description: 'Cookie list (optional)',
355
+ },
302
356
  searchEngine: {
303
357
  type: 'string',
304
358
  enum: ['Google', 'Microsoft Bing', 'Yahoo', 'Yandex', 'DuckDuckGo'],
@@ -314,26 +368,174 @@ const TOOLS = [
314
368
  items: { type: 'string' },
315
369
  description: 'Default URLs to open (optional)',
316
370
  },
371
+ windowPlatformList: {
372
+ type: 'array',
373
+ items: {
374
+ type: 'object',
375
+ properties: {
376
+ platformUrl: { type: 'string', description: 'Platform URL' },
377
+ platformUserName: { type: 'string', description: 'Platform username' },
378
+ platformPassword: { type: 'string', description: 'Platform password' },
379
+ platformEfa: { type: 'string', description: 'Platform EFA' },
380
+ platformRemarks: { type: 'string', description: 'Platform remarks' },
381
+ },
382
+ },
383
+ description: 'Platform account information (optional)',
384
+ },
317
385
  proxyInfo: {
318
386
  type: 'object',
319
- description: 'Proxy configuration (optional)',
387
+ description: 'Complete proxy configuration (optional)',
388
+ properties: {
389
+ proxyMethod: { type: 'string', enum: ['custom', 'choose', 'api'] },
390
+ proxyCategory: { type: 'string', enum: ['noproxy', 'HTTP', 'HTTPS', 'SOCKS5', 'SSH'] },
391
+ ipType: { type: 'string', enum: ['IPV4', 'IPV6'] },
392
+ protocol: { type: 'string', enum: ['HTTP', 'HTTPS', 'SOCKS5'] },
393
+ host: { type: 'string' },
394
+ port: { type: 'string' },
395
+ proxyUserName: { type: 'string' },
396
+ proxyPassword: { type: 'string' },
397
+ refreshUrl: { type: 'string' },
398
+ checkChannel: { type: 'string', enum: ['IPRust.io', 'IP-API', 'IP123.in'] },
399
+ },
320
400
  },
321
401
  fingerInfo: {
322
402
  type: 'object',
323
403
  description: 'Complete fingerprint configuration (optional)',
324
- },
325
- windowPlatformList: {
326
- type: 'array',
327
- items: { type: 'object' },
328
- description: 'Platform account information (optional)',
404
+ properties: {
405
+ // Language and timezone
406
+ isLanguageBaseIp: { type: 'boolean', description: 'Follow IP for browser language' },
407
+ language: { type: 'string', description: 'Custom browser language' },
408
+ isDisplayLanguageBaseIp: { type: 'boolean', description: 'Follow IP for display language' },
409
+ displayLanguage: { type: 'string', description: 'Custom display language' },
410
+ isTimeZone: { type: 'boolean', description: 'Follow IP for timezone' },
411
+ timeZone: { type: 'string', description: 'Custom timezone' },
412
+ // Geolocation
413
+ position: { type: 'number', enum: [0, 1, 2], description: 'Geolocation prompt: 0=ask, 1=allow, 2=deny' },
414
+ isPositionBaseIp: { type: 'boolean', description: 'Follow IP for geolocation' },
415
+ longitude: { type: 'string', description: 'Custom longitude' },
416
+ latitude: { type: 'string', description: 'Custom latitude' },
417
+ precisionPos: { type: 'string', description: 'Precision in meters' },
418
+ // Media settings
419
+ forbidAudio: { type: 'boolean', description: 'Enable/disable sound' },
420
+ forbidImage: { type: 'boolean', description: 'Enable/disable image loading' },
421
+ forbidMedia: { type: 'boolean', description: 'Enable/disable video playback' },
422
+ // Window settings
423
+ openWidth: { type: 'string', description: 'Window width' },
424
+ openHeight: { type: 'string', description: 'Window height' },
425
+ openBookmarks: { type: 'boolean', description: 'Enable bookmarks' },
426
+ positionSwitch: { type: 'boolean', description: 'Window position switch' },
427
+ windowRatioPosition: { type: 'string', description: 'Window position ratio' },
428
+ isDisplayName: { type: 'boolean', description: 'Show window name in title bar' },
429
+ // Sync settings
430
+ syncBookmark: { type: 'boolean', description: 'Sync bookmarks' },
431
+ syncHistory: { type: 'boolean', description: 'Sync history' },
432
+ syncTab: { type: 'boolean', description: 'Sync tabs' },
433
+ syncCookie: { type: 'boolean', description: 'Sync cookies' },
434
+ syncExtensions: { type: 'boolean', description: 'Sync extensions' },
435
+ syncPassword: { type: 'boolean', description: 'Sync saved passwords' },
436
+ syncIndexedDb: { type: 'boolean', description: 'Sync IndexedDB' },
437
+ syncLocalStorage: { type: 'boolean', description: 'Sync LocalStorage' },
438
+ // Cleanup settings
439
+ clearCacheFile: { type: 'boolean', description: 'Clear cache files on startup' },
440
+ clearCookie: { type: 'boolean', description: 'Clear cookies on startup' },
441
+ clearLocalStorage: { type: 'boolean', description: 'Clear LocalStorage on startup' },
442
+ // Advanced settings
443
+ randomFingerprint: { type: 'boolean', description: 'Generate random fingerprint' },
444
+ forbidSavePassword: { type: 'boolean', description: 'Disable password save prompts' },
445
+ stopOpenNet: { type: 'boolean', description: 'Stop opening if network fails' },
446
+ stopOpenIP: { type: 'boolean', description: 'Stop opening if IP changes' },
447
+ stopOpenPosition: { type: 'boolean', description: 'Stop opening if IP location changes' },
448
+ openWorkbench: { type: 'number', enum: [0, 1, 2], description: 'Open workbench: 0=close, 1=open, 2=follow app' },
449
+ // Display settings
450
+ resolutionType: { type: 'boolean', description: 'Custom resolution vs follow system' },
451
+ resolutionX: { type: 'string', description: 'Custom resolution width' },
452
+ resolutionY: { type: 'string', description: 'Custom resolution height' },
453
+ fontType: { type: 'boolean', description: 'Random fonts vs system fonts' },
454
+ // Browser fingerprint settings
455
+ webRTC: { type: 'number', enum: [0, 1, 2], description: 'WebRTC: 0=replace, 1=real, 2=disable' },
456
+ webGL: { type: 'boolean', description: 'WebGL: random vs real' },
457
+ webGLInfo: { type: 'boolean', description: 'WebGL info: custom vs real' },
458
+ webGLManufacturer: { type: 'string', description: 'Custom WebGL manufacturer' },
459
+ webGLRender: { type: 'string', description: 'Custom WebGL renderer' },
460
+ webGpu: { type: 'string', enum: ['webgl', 'real', 'block'], description: 'WebGPU setting' },
461
+ canvas: { type: 'boolean', description: 'Canvas: random vs real' },
462
+ audioContext: { type: 'boolean', description: 'AudioContext: random vs real' },
463
+ speechVoices: { type: 'boolean', description: 'Speech Voices: random vs real' },
464
+ doNotTrack: { type: 'boolean', description: 'Enable Do Not Track' },
465
+ clientRects: { type: 'boolean', description: 'ClientRects: random vs real' },
466
+ deviceInfo: { type: 'boolean', description: 'Media devices: random vs real' },
467
+ deviceNameSwitch: { type: 'boolean', description: 'Device names: random vs real' },
468
+ macInfo: { type: 'boolean', description: 'MAC address: custom vs real' },
469
+ // Hardware settings
470
+ hardwareConcurrent: { type: 'string', description: 'Hardware concurrency' },
471
+ deviceMemory: { type: 'string', description: 'Device memory' },
472
+ // Security settings
473
+ disableSsl: { type: 'boolean', description: 'SSL fingerprint settings' },
474
+ disableSslList: { type: 'array', items: { type: 'string' }, description: 'SSL feature list' },
475
+ portScanProtect: { type: 'boolean', description: 'Port scan protection' },
476
+ portScanList: { type: 'string', description: 'Port scan whitelist' },
477
+ useGpu: { type: 'boolean', description: 'Use GPU acceleration' },
478
+ sandboxPermission: { type: 'boolean', description: 'Disable sandbox' },
479
+ startupParam: { type: 'string', description: 'Browser startup parameters' },
480
+ },
329
481
  },
330
482
  },
331
483
  required: ['workspaceId'],
332
484
  },
333
485
  },
334
486
  {
335
- name: 'roxy_create_browser_from_template',
336
- description: 'Create browsers using predefined templates - perfect for batch creation and common scenarios',
487
+ name: 'roxy_validate_proxy_config',
488
+ description: 'Validate proxy configuration before using it',
489
+ inputSchema: {
490
+ type: 'object',
491
+ properties: {
492
+ proxyInfo: {
493
+ type: 'object',
494
+ description: 'Proxy configuration to validate (required)',
495
+ properties: {
496
+ proxyMethod: { type: 'string', enum: ['custom', 'choose', 'api'] },
497
+ proxyCategory: { type: 'string', enum: ['noproxy', 'HTTP', 'HTTPS', 'SOCKS5', 'SSH'] },
498
+ ipType: { type: 'string', enum: ['IPV4', 'IPV6'] },
499
+ protocol: { type: 'string', enum: ['HTTP', 'HTTPS', 'SOCKS5'] },
500
+ host: { type: 'string' },
501
+ port: { type: 'string' },
502
+ proxyUserName: { type: 'string' },
503
+ proxyPassword: { type: 'string' },
504
+ refreshUrl: { type: 'string' },
505
+ checkChannel: { type: 'string', enum: ['IPRust.io', 'IP-API', 'IP123.in'] },
506
+ },
507
+ },
508
+ },
509
+ required: ['proxyInfo'],
510
+ },
511
+ },
512
+ {
513
+ name: 'roxy_system_diagnostics',
514
+ description: 'Perform comprehensive system diagnostics and health checks',
515
+ inputSchema: {
516
+ type: 'object',
517
+ properties: {
518
+ includeWorkspaceCheck: {
519
+ type: 'boolean',
520
+ description: 'Include workspace connectivity tests (optional, default: true)',
521
+ default: true,
522
+ },
523
+ includeBrowserCheck: {
524
+ type: 'boolean',
525
+ description: 'Include browser availability checks (optional, default: true)',
526
+ default: true,
527
+ },
528
+ verbose: {
529
+ type: 'boolean',
530
+ description: 'Include detailed diagnostic information (optional, default: false)',
531
+ default: false,
532
+ },
533
+ },
534
+ },
535
+ },
536
+ {
537
+ name: 'roxy_list_accounts',
538
+ description: 'Get list of accounts (platform credentials) in specified workspace',
337
539
  inputSchema: {
338
540
  type: 'object',
339
541
  properties: {
@@ -341,55 +543,150 @@ const TOOLS = [
341
543
  type: 'number',
342
544
  description: 'Workspace ID (required)',
343
545
  },
344
- templateName: {
345
- type: 'string',
346
- enum: ['gmail', 'facebook', 'ecommerce', 'social_media', 'general', 'custom'],
347
- description: 'Template to use (required)',
546
+ accountId: {
547
+ type: 'number',
548
+ description: 'Account ID to filter by (optional)',
348
549
  },
349
- count: {
550
+ pageIndex: {
350
551
  type: 'number',
351
- description: 'Number of browsers to create (optional, default: 1)',
352
- minimum: 1,
353
- maximum: 50,
552
+ description: 'Page index for pagination (default: 1)',
553
+ default: 1,
354
554
  },
355
- namePrefix: {
356
- type: 'string',
357
- description: 'Prefix for browser names (optional)',
555
+ pageSize: {
556
+ type: 'number',
557
+ description: 'Number of items per page (default: 15)',
558
+ default: 15,
358
559
  },
359
- projectId: {
560
+ },
561
+ required: ['workspaceId'],
562
+ },
563
+ },
564
+ {
565
+ name: 'roxy_list_labels',
566
+ description: 'Get list of labels in specified workspace',
567
+ inputSchema: {
568
+ type: 'object',
569
+ properties: {
570
+ workspaceId: {
360
571
  type: 'number',
361
- description: 'Project ID (optional)',
572
+ description: 'Workspace ID (required)',
362
573
  },
363
- proxyList: {
574
+ },
575
+ required: ['workspaceId'],
576
+ },
577
+ },
578
+ {
579
+ name: 'roxy_get_connection_info',
580
+ description: 'Get connection information (CDP endpoints, PIDs) for currently opened browsers',
581
+ inputSchema: {
582
+ type: 'object',
583
+ properties: {
584
+ dirIds: {
364
585
  type: 'array',
365
- items: { type: 'object' },
366
- description: 'List of proxy configurations to distribute across browsers (optional)',
367
- },
368
- customConfig: {
369
- type: 'object',
370
- description: 'Custom configuration to override template defaults (optional)',
586
+ items: { type: 'string' },
587
+ description: 'Array of browser directory IDs to query (optional, returns all if not specified)',
371
588
  },
372
589
  },
373
- required: ['workspaceId', 'templateName'],
374
590
  },
375
591
  },
376
592
  {
377
- name: 'roxy_list_browser_templates',
378
- description: 'List available browser templates with descriptions',
593
+ name: 'roxy_get_browser_detail',
594
+ description: 'Get detailed information for a specific browser window',
379
595
  inputSchema: {
380
596
  type: 'object',
381
- properties: {},
597
+ properties: {
598
+ workspaceId: {
599
+ type: 'number',
600
+ description: 'Workspace ID (required)',
601
+ },
602
+ dirId: {
603
+ type: 'string',
604
+ description: 'Browser directory ID (required)',
605
+ },
606
+ },
607
+ required: ['workspaceId', 'dirId'],
382
608
  },
383
609
  },
384
610
  {
385
- name: 'roxy_validate_proxy_config',
386
- description: 'Validate proxy configuration before using it',
611
+ name: 'roxy_update_browser',
612
+ description: 'Update/modify an existing browser configuration with full control over all settings',
387
613
  inputSchema: {
388
614
  type: 'object',
389
615
  properties: {
616
+ workspaceId: {
617
+ type: 'number',
618
+ description: 'Workspace ID (required)',
619
+ },
620
+ dirId: {
621
+ type: 'string',
622
+ description: 'Browser directory ID to update (required)',
623
+ },
624
+ windowName: {
625
+ type: 'string',
626
+ description: 'Browser window name (optional)',
627
+ },
628
+ projectId: {
629
+ type: 'number',
630
+ description: 'Project ID (optional)',
631
+ },
632
+ windowRemark: {
633
+ type: 'string',
634
+ description: 'Window remarks/notes (optional)',
635
+ },
636
+ os: {
637
+ type: 'string',
638
+ enum: ['Windows', 'macOS', 'Linux', 'IOS', 'Android'],
639
+ description: 'Operating system (optional)',
640
+ },
641
+ osVersion: {
642
+ type: 'string',
643
+ description: 'OS version (optional)',
644
+ },
645
+ coreVersion: {
646
+ type: 'string',
647
+ enum: ['138', '137', '136', '135', '133', '130', '125', '117', '109'],
648
+ description: 'Browser core version (optional)',
649
+ },
650
+ userAgent: {
651
+ type: 'string',
652
+ description: 'Custom user agent (optional)',
653
+ },
654
+ cookie: {
655
+ type: 'array',
656
+ description: 'Cookie list (optional)',
657
+ },
658
+ searchEngine: {
659
+ type: 'string',
660
+ enum: ['Google', 'Microsoft Bing', 'Yahoo', 'Yandex', 'DuckDuckGo'],
661
+ description: 'Default search engine (optional)',
662
+ },
663
+ labelIds: {
664
+ type: 'array',
665
+ items: { type: 'number' },
666
+ description: 'Label IDs to assign (optional)',
667
+ },
668
+ defaultOpenUrl: {
669
+ type: 'array',
670
+ items: { type: 'string' },
671
+ description: 'Default URLs to open (optional)',
672
+ },
673
+ windowPlatformList: {
674
+ type: 'array',
675
+ items: {
676
+ type: 'object',
677
+ properties: {
678
+ platformUrl: { type: 'string', description: 'Platform URL' },
679
+ platformUserName: { type: 'string', description: 'Platform username' },
680
+ platformPassword: { type: 'string', description: 'Platform password' },
681
+ platformEfa: { type: 'string', description: 'Platform EFA' },
682
+ platformRemarks: { type: 'string', description: 'Platform remarks' },
683
+ },
684
+ },
685
+ description: 'Platform account information (optional)',
686
+ },
390
687
  proxyInfo: {
391
688
  type: 'object',
392
- description: 'Proxy configuration to validate (required)',
689
+ description: 'Complete proxy configuration (optional)',
393
690
  properties: {
394
691
  proxyMethod: { type: 'string', enum: ['custom', 'choose', 'api'] },
395
692
  proxyCategory: { type: 'string', enum: ['noproxy', 'HTTP', 'HTTPS', 'SOCKS5', 'SSH'] },
@@ -403,8 +700,141 @@ const TOOLS = [
403
700
  checkChannel: { type: 'string', enum: ['IPRust.io', 'IP-API', 'IP123.in'] },
404
701
  },
405
702
  },
703
+ fingerInfo: {
704
+ type: 'object',
705
+ description: 'Complete fingerprint configuration (optional)',
706
+ properties: {
707
+ // Language and timezone
708
+ isLanguageBaseIp: { type: 'boolean', description: 'Follow IP for browser language' },
709
+ language: { type: 'string', description: 'Custom browser language' },
710
+ isDisplayLanguageBaseIp: { type: 'boolean', description: 'Follow IP for display language' },
711
+ displayLanguage: { type: 'string', description: 'Custom display language' },
712
+ isTimeZone: { type: 'boolean', description: 'Follow IP for timezone' },
713
+ timeZone: { type: 'string', description: 'Custom timezone' },
714
+ // Geolocation
715
+ position: { type: 'number', enum: [0, 1, 2], description: 'Geolocation prompt: 0=ask, 1=allow, 2=deny' },
716
+ isPositionBaseIp: { type: 'boolean', description: 'Follow IP for geolocation' },
717
+ longitude: { type: 'string', description: 'Custom longitude' },
718
+ latitude: { type: 'string', description: 'Custom latitude' },
719
+ precisionPos: { type: 'string', description: 'Precision in meters' },
720
+ // Media settings
721
+ forbidAudio: { type: 'boolean', description: 'Enable/disable sound' },
722
+ forbidImage: { type: 'boolean', description: 'Enable/disable image loading' },
723
+ forbidMedia: { type: 'boolean', description: 'Enable/disable video playback' },
724
+ // Window settings
725
+ openWidth: { type: 'string', description: 'Window width' },
726
+ openHeight: { type: 'string', description: 'Window height' },
727
+ openBookmarks: { type: 'boolean', description: 'Enable bookmarks' },
728
+ positionSwitch: { type: 'boolean', description: 'Window position switch' },
729
+ windowRatioPosition: { type: 'string', description: 'Window position ratio' },
730
+ isDisplayName: { type: 'boolean', description: 'Show window name in title bar' },
731
+ // Sync settings
732
+ syncBookmark: { type: 'boolean', description: 'Sync bookmarks' },
733
+ syncHistory: { type: 'boolean', description: 'Sync history' },
734
+ syncTab: { type: 'boolean', description: 'Sync tabs' },
735
+ syncCookie: { type: 'boolean', description: 'Sync cookies' },
736
+ syncExtensions: { type: 'boolean', description: 'Sync extensions' },
737
+ syncPassword: { type: 'boolean', description: 'Sync saved passwords' },
738
+ syncIndexedDb: { type: 'boolean', description: 'Sync IndexedDB' },
739
+ syncLocalStorage: { type: 'boolean', description: 'Sync LocalStorage' },
740
+ // Cleanup settings
741
+ clearCacheFile: { type: 'boolean', description: 'Clear cache files on startup' },
742
+ clearCookie: { type: 'boolean', description: 'Clear cookies on startup' },
743
+ clearLocalStorage: { type: 'boolean', description: 'Clear LocalStorage on startup' },
744
+ // Advanced settings
745
+ randomFingerprint: { type: 'boolean', description: 'Generate random fingerprint' },
746
+ forbidSavePassword: { type: 'boolean', description: 'Disable password save prompts' },
747
+ stopOpenNet: { type: 'boolean', description: 'Stop opening if network fails' },
748
+ stopOpenIP: { type: 'boolean', description: 'Stop opening if IP changes' },
749
+ stopOpenPosition: { type: 'boolean', description: 'Stop opening if IP location changes' },
750
+ openWorkbench: { type: 'number', enum: [0, 1, 2], description: 'Open workbench: 0=close, 1=open, 2=follow app' },
751
+ // Display settings
752
+ resolutionType: { type: 'boolean', description: 'Custom resolution vs follow system' },
753
+ resolutionX: { type: 'string', description: 'Custom resolution width' },
754
+ resolutionY: { type: 'string', description: 'Custom resolution height' },
755
+ fontType: { type: 'boolean', description: 'Random fonts vs system fonts' },
756
+ // Browser fingerprint settings
757
+ webRTC: { type: 'number', enum: [0, 1, 2], description: 'WebRTC: 0=replace, 1=real, 2=disable' },
758
+ webGL: { type: 'boolean', description: 'WebGL: random vs real' },
759
+ webGLInfo: { type: 'boolean', description: 'WebGL info: custom vs real' },
760
+ webGLManufacturer: { type: 'string', description: 'Custom WebGL manufacturer' },
761
+ webGLRender: { type: 'string', description: 'Custom WebGL renderer' },
762
+ webGpu: { type: 'string', enum: ['webgl', 'real', 'block'], description: 'WebGPU setting' },
763
+ canvas: { type: 'boolean', description: 'Canvas: random vs real' },
764
+ audioContext: { type: 'boolean', description: 'AudioContext: random vs real' },
765
+ speechVoices: { type: 'boolean', description: 'Speech Voices: random vs real' },
766
+ doNotTrack: { type: 'boolean', description: 'Enable Do Not Track' },
767
+ clientRects: { type: 'boolean', description: 'ClientRects: random vs real' },
768
+ deviceInfo: { type: 'boolean', description: 'Media devices: random vs real' },
769
+ deviceNameSwitch: { type: 'boolean', description: 'Device names: random vs real' },
770
+ macInfo: { type: 'boolean', description: 'MAC address: custom vs real' },
771
+ // Hardware settings
772
+ hardwareConcurrent: { type: 'string', description: 'Hardware concurrency' },
773
+ deviceMemory: { type: 'string', description: 'Device memory' },
774
+ // Security settings
775
+ disableSsl: { type: 'boolean', description: 'SSL fingerprint settings' },
776
+ disableSslList: { type: 'array', items: { type: 'string' }, description: 'SSL feature list' },
777
+ portScanProtect: { type: 'boolean', description: 'Port scan protection' },
778
+ portScanList: { type: 'string', description: 'Port scan whitelist' },
779
+ useGpu: { type: 'boolean', description: 'Use GPU acceleration' },
780
+ sandboxPermission: { type: 'boolean', description: 'Disable sandbox' },
781
+ startupParam: { type: 'string', description: 'Browser startup parameters' },
782
+ },
783
+ },
406
784
  },
407
- required: ['proxyInfo'],
785
+ required: ['workspaceId', 'dirId'],
786
+ },
787
+ },
788
+ {
789
+ name: 'roxy_random_fingerprint',
790
+ description: 'Randomize browser fingerprint for a specific browser',
791
+ inputSchema: {
792
+ type: 'object',
793
+ properties: {
794
+ workspaceId: {
795
+ type: 'number',
796
+ description: 'Workspace ID (required)',
797
+ },
798
+ dirId: {
799
+ type: 'string',
800
+ description: 'Browser directory ID (required)',
801
+ },
802
+ },
803
+ required: ['workspaceId', 'dirId'],
804
+ },
805
+ },
806
+ {
807
+ name: 'roxy_clear_local_cache',
808
+ description: 'Clear local cache for specified browsers',
809
+ inputSchema: {
810
+ type: 'object',
811
+ properties: {
812
+ dirIds: {
813
+ type: 'array',
814
+ items: { type: 'string' },
815
+ description: 'Array of browser directory IDs (required)',
816
+ },
817
+ },
818
+ required: ['dirIds'],
819
+ },
820
+ },
821
+ {
822
+ name: 'roxy_clear_server_cache',
823
+ description: 'Clear server-side cache for specified browsers',
824
+ inputSchema: {
825
+ type: 'object',
826
+ properties: {
827
+ workspaceId: {
828
+ type: 'number',
829
+ description: 'Workspace ID (required)',
830
+ },
831
+ dirIds: {
832
+ type: 'array',
833
+ items: { type: 'string' },
834
+ description: 'Array of browser directory IDs (required)',
835
+ },
836
+ },
837
+ required: ['workspaceId', 'dirIds'],
408
838
  },
409
839
  },
410
840
  ];
@@ -452,23 +882,38 @@ class RoxyBrowserMCPServer {
452
882
  return await this.handleCreateBrowserStandard(args);
453
883
  case 'roxy_create_browser_advanced':
454
884
  return await this.handleCreateBrowserAdvanced(args);
455
- case 'roxy_create_browser_from_template':
456
- return await this.handleCreateBrowserFromTemplate(args);
457
- case 'roxy_list_browser_templates':
458
- return await this.handleListBrowserTemplates();
459
885
  case 'roxy_validate_proxy_config':
460
886
  return await this.handleValidateProxyConfig(args);
887
+ case 'roxy_system_diagnostics':
888
+ return await this.handleSystemDiagnostics(args);
889
+ case 'roxy_list_accounts':
890
+ return await this.handleListAccounts(args);
891
+ case 'roxy_list_labels':
892
+ return await this.handleListLabels(args);
893
+ case 'roxy_get_connection_info':
894
+ return await this.handleGetConnectionInfo(args);
895
+ case 'roxy_get_browser_detail':
896
+ return await this.handleGetBrowserDetail(args);
897
+ case 'roxy_update_browser':
898
+ return await this.handleUpdateBrowser(args);
899
+ case 'roxy_random_fingerprint':
900
+ return await this.handleRandomFingerprint(args);
901
+ case 'roxy_clear_local_cache':
902
+ return await this.handleClearLocalCache(args);
903
+ case 'roxy_clear_server_cache':
904
+ return await this.handleClearServerCache(args);
461
905
  default:
462
906
  throw new Error(`Unknown tool: ${name}`);
463
907
  }
464
908
  }
465
909
  catch (error) {
466
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
910
+ // Use enhanced error analysis
911
+ const formattedError = ErrorAnalyzer.formatErrorForDisplay(error instanceof Error ? error : new Error('Unknown error'));
467
912
  return {
468
913
  content: [
469
914
  {
470
915
  type: 'text',
471
- text: `Error: ${errorMessage}`,
916
+ text: formattedError,
472
917
  },
473
918
  ],
474
919
  };
@@ -605,74 +1050,6 @@ class RoxyBrowserMCPServer {
605
1050
  ],
606
1051
  };
607
1052
  }
608
- async handleCreateBrowserFromTemplate(args) {
609
- const params = args;
610
- if (!params.workspaceId || !params.templateName) {
611
- throw new Error('workspaceId and templateName are required');
612
- }
613
- // Get template configuration
614
- const templateConfig = TemplateManager.getTemplateConfig(params.templateName, params.customConfig);
615
- // Build configurations for multiple browsers
616
- const configs = BrowserCreator.buildConfigsFromTemplate(params, templateConfig);
617
- // Validate all configurations
618
- const validation = BrowserCreator.validateConfigs(configs);
619
- if (!validation.valid) {
620
- const errorDetails = validation.errors.map(err => `Browser ${err.index + 1}: ${err.errors.join(', ')}`).join('\n');
621
- throw new BrowserCreationError(`Configuration validation failed:\n${errorDetails}`);
622
- }
623
- // Create browsers in batch
624
- const batchResult = await this.roxyClient.createBrowsers(configs);
625
- const response = {
626
- browsers: batchResult.results,
627
- template: params.templateName,
628
- successCount: batchResult.successCount,
629
- failureCount: batchResult.failureCount,
630
- total: batchResult.total,
631
- message: `Template-based creation completed: ${batchResult.successCount}/${batchResult.total} browsers created successfully`,
632
- };
633
- // Create result summary
634
- const successBrowsers = batchResult.results.filter(r => r.success);
635
- const failedBrowsers = batchResult.results.filter(r => !r.success);
636
- let resultText = `✅ **Template Browser Creation Complete**\n\n` +
637
- `**Template:** ${params.templateName}\n` +
638
- `**Success:** ${response.successCount}/${response.total}\n` +
639
- `**Workspace:** ${params.workspaceId}\n` +
640
- `${params.projectId ? `**Project:** ${params.projectId}\n` : ''}\n`;
641
- if (successBrowsers.length > 0) {
642
- resultText += `**✅ Successfully Created (${successBrowsers.length}):**\n`;
643
- successBrowsers.forEach((browser, index) => {
644
- resultText += ` ${index + 1}. \`${browser.dirId}\` - ${browser.windowName}\n`;
645
- });
646
- }
647
- if (failedBrowsers.length > 0) {
648
- resultText += `\n**❌ Failed (${failedBrowsers.length}):**\n`;
649
- failedBrowsers.forEach((browser, index) => {
650
- resultText += ` ${index + 1}. ${browser.windowName} - ${browser.error}\n`;
651
- });
652
- }
653
- resultText += `\n*Use \`roxy_open_browsers\` with the successful browser IDs to start them for automation.*`;
654
- return {
655
- content: [
656
- {
657
- type: 'text',
658
- text: resultText,
659
- },
660
- ],
661
- };
662
- }
663
- async handleListBrowserTemplates() {
664
- const templates = TemplateManager.getAvailableTemplates();
665
- const templateText = templates.map(template => `**${template.name}**\n ${template.description}`).join('\n\n');
666
- return {
667
- content: [
668
- {
669
- type: 'text',
670
- text: `📋 **Available Browser Templates**\n\n${templateText}\n\n` +
671
- `*Use these template names with \`roxy_create_browser_from_template\` for optimized browser configurations.*`,
672
- },
673
- ],
674
- };
675
- }
676
1053
  async handleValidateProxyConfig(args) {
677
1054
  const { proxyInfo } = args;
678
1055
  if (!proxyInfo) {
@@ -825,16 +1202,6 @@ class RoxyBrowserMCPServer {
825
1202
  }
826
1203
  catch (error) {
827
1204
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
828
- const response = {
829
- results: params.dirIds.map(dirId => ({
830
- dirId,
831
- success: false,
832
- error: errorMessage,
833
- })),
834
- successCount: 0,
835
- failureCount: params.dirIds.length,
836
- message: `Failed to delete browsers: ${errorMessage}`,
837
- };
838
1205
  return {
839
1206
  content: [
840
1207
  {
@@ -850,20 +1217,317 @@ class RoxyBrowserMCPServer {
850
1217
  };
851
1218
  }
852
1219
  }
1220
+ async handleSystemDiagnostics(args) {
1221
+ const { includeWorkspaceCheck = true, includeBrowserCheck = true, verbose = false } = args || {};
1222
+ // Perform comprehensive diagnostics
1223
+ const diagnostics = await this.roxyClient.performDiagnostics();
1224
+ let diagnosticText = `## 🔍 系统诊断报告 / System Diagnostics Report\n\n`;
1225
+ // Basic connectivity
1226
+ diagnosticText += `### 🌐 连接状态 / Connectivity Status\n`;
1227
+ diagnosticText += `- **API连接 / API Connection**: ${diagnostics.connected ? '✅ 已连接' : '❌ 连接失败'}\n`;
1228
+ diagnosticText += `- **认证状态 / Authentication**: ${diagnostics.authentication ? '✅ 成功' : '❌ 失败'}\n`;
1229
+ diagnosticText += `- **工作区访问 / Workspace Access**: ${diagnostics.workspaceAccess ? '✅ 正常' : '⚠️ 受限'}\n\n`;
1230
+ // Additional workspace checks
1231
+ if (includeWorkspaceCheck && diagnostics.connected && diagnostics.authentication) {
1232
+ try {
1233
+ const workspaces = await this.roxyClient.getWorkspaces(1, 5);
1234
+ diagnosticText += `### 📁 工作区信息 / Workspace Information\n`;
1235
+ diagnosticText += `- **可用工作区 / Available Workspaces**: ${workspaces.total}\n`;
1236
+ if (workspaces.rows.length > 0) {
1237
+ diagnosticText += `- **工作区详情 / Workspace Details**:\n`;
1238
+ workspaces.rows.slice(0, 3).forEach(ws => {
1239
+ const projectCount = ws.project_details.length;
1240
+ diagnosticText += ` - ${ws.workspaceName} (ID: ${ws.id}) - ${projectCount} projects\n`;
1241
+ });
1242
+ if (workspaces.total > 3) {
1243
+ diagnosticText += ` - ... and ${workspaces.total - 3} more\n`;
1244
+ }
1245
+ }
1246
+ diagnosticText += '\n';
1247
+ }
1248
+ catch (error) {
1249
+ diagnosticText += `### 📁 工作区信息 / Workspace Information\n`;
1250
+ diagnosticText += `- **状态**: ❌ 无法获取工作区信息\n`;
1251
+ diagnosticText += `- **错误**: ${error instanceof Error ? error.message : 'Unknown error'}\n\n`;
1252
+ }
1253
+ }
1254
+ // Browser availability checks
1255
+ if (includeBrowserCheck && diagnostics.connected && diagnostics.authentication && diagnostics.workspaceAccess) {
1256
+ try {
1257
+ // Get first workspace and check browsers
1258
+ const workspaces = await this.roxyClient.getWorkspaces(1, 1);
1259
+ if (workspaces.rows.length > 0) {
1260
+ const firstWorkspace = workspaces.rows[0];
1261
+ const browsers = await this.roxyClient.getBrowsers({
1262
+ workspaceId: firstWorkspace.id,
1263
+ page_index: 1,
1264
+ page_size: 5,
1265
+ });
1266
+ diagnosticText += `### 🖥️ 浏览器状态 / Browser Status\n`;
1267
+ diagnosticText += `- **检查工作区 / Checked Workspace**: ${firstWorkspace.workspaceName} (ID: ${firstWorkspace.id})\n`;
1268
+ diagnosticText += `- **可用浏览器 / Available Browsers**: ${browsers.total}\n`;
1269
+ if (browsers.rows.length > 0) {
1270
+ diagnosticText += `- **浏览器示例 / Browser Examples**:\n`;
1271
+ browsers.rows.slice(0, 3).forEach(browser => {
1272
+ diagnosticText += ` - ${browser.windowName || 'Unnamed'} (${browser.os}) - Status: ${browser.status}\n`;
1273
+ });
1274
+ }
1275
+ diagnosticText += '\n';
1276
+ }
1277
+ }
1278
+ catch (error) {
1279
+ diagnosticText += `### 🖥️ 浏览器状态 / Browser Status\n`;
1280
+ diagnosticText += `- **状态**: ⚠️ 无法检查浏览器状态\n`;
1281
+ diagnosticText += `- **原因**: ${error instanceof Error ? error.message : 'Unknown error'}\n\n`;
1282
+ }
1283
+ }
1284
+ // Error details
1285
+ if (diagnostics.errors.length > 0) {
1286
+ diagnosticText += `### ❌ 检测到的问题 / Detected Issues\n`;
1287
+ diagnostics.errors.forEach((error, index) => {
1288
+ diagnosticText += `${index + 1}. ${error}\n`;
1289
+ });
1290
+ diagnosticText += '\n';
1291
+ }
1292
+ // Recommendations
1293
+ if (diagnostics.recommendations.length > 0) {
1294
+ diagnosticText += `### 💡 建议操作 / Recommendations\n`;
1295
+ diagnostics.recommendations.slice(0, 8).forEach((rec, index) => {
1296
+ diagnosticText += `${index + 1}. ${rec}\n`;
1297
+ });
1298
+ if (diagnostics.recommendations.length > 8) {
1299
+ diagnosticText += `... and ${diagnostics.recommendations.length - 8} more\n`;
1300
+ }
1301
+ diagnosticText += '\n';
1302
+ }
1303
+ // Verbose information
1304
+ if (verbose) {
1305
+ diagnosticText += `### 🔧 详细信息 / Detailed Information\n`;
1306
+ diagnosticText += `- **API主机 / API Host**: ${this.roxyClient.config.apiHost}\n`;
1307
+ diagnosticText += `- **超时设置 / Timeout**: ${this.roxyClient.config.timeout}ms\n`;
1308
+ diagnosticText += `- **诊断时间 / Diagnosis Time**: ${new Date().toISOString()}\n\n`;
1309
+ }
1310
+ // Overall status
1311
+ const overallStatus = diagnostics.connected && diagnostics.authentication;
1312
+ diagnosticText += `### 📋 总体状态 / Overall Status\n`;
1313
+ diagnosticText += `**${overallStatus ? '✅ 系统正常运行' : '❌ 系统存在问题'}** / `;
1314
+ diagnosticText += `**${overallStatus ? 'System Operating Normally' : 'System Issues Detected'}**\n\n`;
1315
+ if (overallStatus) {
1316
+ diagnosticText += `*系统已准备就绪,可以进行浏览器自动化操作。*\n`;
1317
+ diagnosticText += `*System ready for browser automation operations.*`;
1318
+ }
1319
+ else {
1320
+ diagnosticText += `*请解决上述问题后重新运行诊断。*\n`;
1321
+ diagnosticText += `*Please resolve the issues above and run diagnostics again.*`;
1322
+ }
1323
+ return {
1324
+ content: [
1325
+ {
1326
+ type: 'text',
1327
+ text: diagnosticText,
1328
+ },
1329
+ ],
1330
+ };
1331
+ }
1332
+ async handleListAccounts(args) {
1333
+ const params = {
1334
+ workspaceId: args.workspaceId,
1335
+ accountId: args.accountId,
1336
+ page_index: args.pageIndex || 1,
1337
+ page_size: args.pageSize || 15,
1338
+ };
1339
+ if (!params.workspaceId) {
1340
+ throw new Error('workspaceId is required');
1341
+ }
1342
+ const data = await this.roxyClient.getAccounts(params);
1343
+ return {
1344
+ content: [
1345
+ {
1346
+ type: 'text',
1347
+ text: `Found ${data.total} accounts in workspace ${params.workspaceId}:\n\n` +
1348
+ data.rows.map(account => `**${account.platformName}** (ID: ${account.id})\n` +
1349
+ ` - Username: ${account.platformUserName}\n` +
1350
+ ` - Platform URL: ${account.platformUrl}\n` +
1351
+ ` - Remarks: ${account.platformRemarks || 'N/A'}\n` +
1352
+ ` - Created: ${account.createTime}`).join('\n\n'),
1353
+ },
1354
+ ],
1355
+ };
1356
+ }
1357
+ async handleListLabels(args) {
1358
+ const { workspaceId } = args;
1359
+ if (!workspaceId) {
1360
+ throw new Error('workspaceId is required');
1361
+ }
1362
+ const labels = await this.roxyClient.getLabels(workspaceId);
1363
+ return {
1364
+ content: [
1365
+ {
1366
+ type: 'text',
1367
+ text: `Found ${labels.length} labels in workspace ${workspaceId}:\n\n` +
1368
+ labels.map(label => `**${label.name}** (ID: ${label.id})\n` +
1369
+ ` - Color: ${label.color}`).join('\n\n'),
1370
+ },
1371
+ ],
1372
+ };
1373
+ }
1374
+ async handleGetConnectionInfo(args) {
1375
+ const { dirIds } = args;
1376
+ const connections = await this.roxyClient.getConnectionInfo(dirIds);
1377
+ if (connections.length === 0) {
1378
+ return {
1379
+ content: [
1380
+ {
1381
+ type: 'text',
1382
+ text: '⚠️ No opened browsers found.\n\nUse `roxy_open_browsers` to open browsers first.',
1383
+ },
1384
+ ],
1385
+ };
1386
+ }
1387
+ return {
1388
+ content: [
1389
+ {
1390
+ type: 'text',
1391
+ text: `Found ${connections.length} opened browser(s):\n\n` +
1392
+ connections.map(conn => `**${conn.windowName || 'Unnamed'}** (${conn.dirId})\n` +
1393
+ ` - PID: ${conn.pid}\n` +
1394
+ ` - CDP WebSocket: \`${conn.ws}\`\n` +
1395
+ ` - HTTP Endpoint: \`${conn.http}\`\n` +
1396
+ ` - Core Version: ${conn.coreVersion}\n` +
1397
+ ` - Driver: ${conn.driver}`).join('\n\n'),
1398
+ },
1399
+ ],
1400
+ };
1401
+ }
1402
+ async handleGetBrowserDetail(args) {
1403
+ const { workspaceId, dirId } = args;
1404
+ if (!workspaceId || !dirId) {
1405
+ throw new Error('workspaceId and dirId are required');
1406
+ }
1407
+ const detail = await this.roxyClient.getBrowserDetail(workspaceId, dirId);
1408
+ return {
1409
+ content: [
1410
+ {
1411
+ type: 'text',
1412
+ text: `**Browser Details**\n\n` +
1413
+ `**ID:** \`${detail.dirId}\`\n` +
1414
+ `**Name:** ${detail.windowName}\n` +
1415
+ `**OS:** ${detail.os} ${detail.osVersion}\n` +
1416
+ `**Core:** ${detail.coreVersion}\n` +
1417
+ `**User Agent:** ${detail.userAgent}\n` +
1418
+ `**Proxy:** ${detail.proxyInfo?.host || 'None'}:${detail.proxyInfo?.port || ''}\n` +
1419
+ `**Created:** ${detail.createTime}\n` +
1420
+ `**Updated:** ${detail.updateTime}\n` +
1421
+ `**Open Status:** ${detail.openStatus ? 'Opened' : 'Closed'}`,
1422
+ },
1423
+ ],
1424
+ };
1425
+ }
1426
+ async handleUpdateBrowser(args) {
1427
+ const params = args;
1428
+ if (!params.workspaceId || !params.dirId) {
1429
+ throw new Error('workspaceId and dirId are required');
1430
+ }
1431
+ await this.roxyClient.updateBrowser(params);
1432
+ return {
1433
+ content: [
1434
+ {
1435
+ type: 'text',
1436
+ text: `✅ **Browser Updated Successfully**\n\n` +
1437
+ `**Browser ID:** \`${params.dirId}\`\n` +
1438
+ `**Workspace:** ${params.workspaceId}\n\n` +
1439
+ `*Browser configuration has been updated.*`,
1440
+ },
1441
+ ],
1442
+ };
1443
+ }
1444
+ async handleRandomFingerprint(args) {
1445
+ const { workspaceId, dirId } = args;
1446
+ if (!workspaceId || !dirId) {
1447
+ throw new Error('workspaceId and dirId are required');
1448
+ }
1449
+ await this.roxyClient.randomBrowserFingerprint(workspaceId, dirId);
1450
+ return {
1451
+ content: [
1452
+ {
1453
+ type: 'text',
1454
+ text: `✅ **Browser Fingerprint Randomized**\n\n` +
1455
+ `**Browser ID:** \`${dirId}\`\n` +
1456
+ `**Workspace:** ${workspaceId}\n\n` +
1457
+ `*Browser fingerprint has been randomized. Restart the browser to apply changes.*`,
1458
+ },
1459
+ ],
1460
+ };
1461
+ }
1462
+ async handleClearLocalCache(args) {
1463
+ const { dirIds } = args;
1464
+ if (!dirIds || dirIds.length === 0) {
1465
+ throw new Error('dirIds are required');
1466
+ }
1467
+ await this.roxyClient.clearBrowserLocalCache(dirIds);
1468
+ return {
1469
+ content: [
1470
+ {
1471
+ type: 'text',
1472
+ text: `✅ **Local Cache Cleared**\n\n` +
1473
+ `**Browser Count:** ${dirIds.length}\n\n` +
1474
+ `**Browser IDs:**\n` +
1475
+ dirIds.map((id, index) => ` ${index + 1}. \`${id}\``).join('\n'),
1476
+ },
1477
+ ],
1478
+ };
1479
+ }
1480
+ async handleClearServerCache(args) {
1481
+ const { workspaceId, dirIds } = args;
1482
+ if (!workspaceId || !dirIds || dirIds.length === 0) {
1483
+ throw new Error('workspaceId and dirIds are required');
1484
+ }
1485
+ await this.roxyClient.clearBrowserServerCache(workspaceId, dirIds);
1486
+ return {
1487
+ content: [
1488
+ {
1489
+ type: 'text',
1490
+ text: `✅ **Server Cache Cleared**\n\n` +
1491
+ `**Workspace:** ${workspaceId}\n` +
1492
+ `**Browser Count:** ${dirIds.length}\n\n` +
1493
+ `**Browser IDs:**\n` +
1494
+ dirIds.map((id, index) => ` ${index + 1}. \`${id}\``).join('\n'),
1495
+ },
1496
+ ],
1497
+ };
1498
+ }
853
1499
  async run() {
854
- // Test connection before starting
855
- console.error('🔗 Testing RoxyBrowser API connection...');
856
- const isConnected = await this.roxyClient.testConnection();
857
- if (!isConnected) {
1500
+ // Enhanced connection testing with diagnostics
1501
+ console.error('🔗 Performing RoxyBrowser API diagnostics...');
1502
+ const diagnostics = await this.roxyClient.performDiagnostics();
1503
+ if (!diagnostics.connected) {
858
1504
  console.error('❌ Failed to connect to RoxyBrowser API');
859
- console.error(' Please check:');
860
- console.error(' 1. RoxyBrowser is running');
861
- console.error(' 2. API is enabled in RoxyBrowser settings');
862
- console.error(' 3. ROXY_API_KEY environment variable is set');
863
- console.error(' 4. API host is correct (default: http://127.0.0.1:50000)');
1505
+ console.error('\n📋 Diagnostic Results:');
1506
+ diagnostics.errors.forEach(error => console.error(` ${error}`));
1507
+ if (diagnostics.recommendations.length > 0) {
1508
+ console.error('\n💡 Recommendations:');
1509
+ diagnostics.recommendations.slice(0, 5).forEach((rec, index) => {
1510
+ console.error(` ${index + 1}. ${rec}`);
1511
+ });
1512
+ }
1513
+ process.exit(1);
1514
+ }
1515
+ if (!diagnostics.authentication) {
1516
+ console.error('❌ Authentication failed');
1517
+ console.error('\n📋 Diagnostic Results:');
1518
+ diagnostics.errors.forEach(error => console.error(` ❌ ${error}`));
1519
+ if (diagnostics.recommendations.length > 0) {
1520
+ console.error('\n💡 Recommendations:');
1521
+ diagnostics.recommendations.slice(0, 5).forEach((rec, index) => {
1522
+ console.error(` ${index + 1}. ${rec}`);
1523
+ });
1524
+ }
864
1525
  process.exit(1);
865
1526
  }
866
- console.error('✅ Connected to RoxyBrowser API');
1527
+ console.error('✅ API Diagnostics Passed:');
1528
+ console.error(' ✓ Connection established');
1529
+ console.error(' ✓ Authentication successful');
1530
+ console.error(` ✓ Workspace access: ${diagnostics.workspaceAccess ? 'Yes' : 'Limited'}`);
867
1531
  console.error('🚀 Starting RoxyBrowser MCP Server...');
868
1532
  const transport = new StdioServerTransport();
869
1533
  await this.server.connect(transport);