@roxybrowser/openapi 1.0.4-beta.0 → 1.0.4-beta.1

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
@@ -12,7 +12,7 @@ import { RoxyClient } from './roxy-client.js';
12
12
  import { BrowserCreator } from './browser/browser-creator.js';
13
13
  import { ProxyManager } from './proxy/proxy-manager.js';
14
14
  import { ErrorAnalyzer } from './utils/error-analyzer.js';
15
- import { ConfigError, BrowserCreationError, } from './types.js';
15
+ import { ConfigError, RoxyApiError, BrowserCreationError, LATEST_CORE_VERSION, } from './types.js';
16
16
  // ========== Configuration ==========
17
17
  function getConfig() {
18
18
  const apiHost = process.env.ROXY_API_HOST || 'http://127.0.0.1:50000';
@@ -925,130 +925,214 @@ class RoxyBrowserMCPServer {
925
925
  if (!params.workspaceId) {
926
926
  throw new Error('workspaceId is required');
927
927
  }
928
- // Build configuration from simple parameters
929
- const config = BrowserCreator.buildSimpleConfig(params);
930
- const finalConfig = BrowserCreator.applyDefaults(config);
931
- // Validate configuration
932
- const validation = BrowserCreator.validateConfig(finalConfig);
933
- if (!validation.valid) {
934
- throw new BrowserCreationError(`Configuration validation failed: ${validation.errors.join(', ')}`);
928
+ try {
929
+ // Build configuration from simple parameters
930
+ const config = BrowserCreator.buildSimpleConfig(params);
931
+ const finalConfig = BrowserCreator.applyDefaults(config);
932
+ // Validate configuration
933
+ const validation = BrowserCreator.validateConfig(finalConfig);
934
+ if (!validation.valid) {
935
+ throw new BrowserCreationError(`Configuration validation failed: ${validation.errors.join(', ')}`);
936
+ }
937
+ // Create browser
938
+ const result = await this.roxyClient.createBrowser(finalConfig);
939
+ const response = {
940
+ browser: {
941
+ dirId: result.dirId,
942
+ windowName: finalConfig.windowName || 'Simple Browser',
943
+ workspaceId: params.workspaceId,
944
+ projectId: params.projectId,
945
+ proxyConfigured: !!(params.proxyHost && params.proxyPort),
946
+ },
947
+ message: `Browser created successfully with ID: ${result.dirId}`,
948
+ };
949
+ return {
950
+ content: [
951
+ {
952
+ type: 'text',
953
+ text: `✅ **Simple Browser Created**\n\n` +
954
+ `**Browser ID:** \`${response.browser.dirId}\`\n` +
955
+ `**Name:** ${response.browser.windowName}\n` +
956
+ `**Workspace:** ${response.browser.workspaceId}\n` +
957
+ `${response.browser.projectId ? `**Project:** ${response.browser.projectId}\n` : ''}` +
958
+ `**Proxy:** ${response.browser.proxyConfigured ? '✅ Configured' : '❌ Not configured'}\n\n` +
959
+ `*Use this browser ID with \`roxy_open_browsers\` to start the browser and get CDP endpoints for automation.*`,
960
+ },
961
+ ],
962
+ };
963
+ }
964
+ catch (error) {
965
+ // Check for quota error specifically
966
+ if (error instanceof RoxyApiError && error.code === 409 &&
967
+ error.message.includes('额度不足')) {
968
+ return {
969
+ content: [{
970
+ type: 'text',
971
+ text: `❌ **浏览器创建失败 - 窗口额度不足 / Browser Creation Failed - Insufficient Profiles Quota**\n\n` +
972
+ `**错误信息 / Error:** ${error.message}\n\n` +
973
+ `**解决步骤 / Solution Steps:**\n` +
974
+ `1. 打开 RoxyBrowser 应用 / Open RoxyBrowser app\n` +
975
+ `2. 前往费用中心 / Go to Billing Center\n` +
976
+ `3. 购买或升级窗口套餐 / Purchase or upgrade profiles plan\n` +
977
+ `4. 或者删除不需要的浏览器窗口以释放额度 / Or delete unused browser profiles to free up quota\n` +
978
+ `5. 等待生效后重试创建 / Retry creation after quota is available\n\n` +
979
+ `💡 **重要提示 / Important:** 必须使用 \`roxy_delete_browsers\` 删除浏览器才能释放额度,仅关闭浏览器无法释放额度。\n` +
980
+ `You must use \`roxy_delete_browsers\` to delete profiles to free up quota. Simply closing browsers will NOT free up quota.`,
981
+ }],
982
+ };
983
+ }
984
+ // Use enhanced error analysis for other errors
985
+ const formattedError = ErrorAnalyzer.formatErrorForDisplay(error instanceof Error ? error : new Error('Unknown error'));
986
+ return {
987
+ content: [{ type: 'text', text: formattedError }],
988
+ };
935
989
  }
936
- // Create browser
937
- const result = await this.roxyClient.createBrowser(finalConfig);
938
- const response = {
939
- browser: {
940
- dirId: result.dirId,
941
- windowName: finalConfig.windowName || 'Simple Browser',
942
- workspaceId: params.workspaceId,
943
- projectId: params.projectId,
944
- proxyConfigured: !!(params.proxyHost && params.proxyPort),
945
- },
946
- message: `Browser created successfully with ID: ${result.dirId}`,
947
- };
948
- return {
949
- content: [
950
- {
951
- type: 'text',
952
- text: `✅ **Simple Browser Created**\n\n` +
953
- `**Browser ID:** \`${response.browser.dirId}\`\n` +
954
- `**Name:** ${response.browser.windowName}\n` +
955
- `**Workspace:** ${response.browser.workspaceId}\n` +
956
- `${response.browser.projectId ? `**Project:** ${response.browser.projectId}\n` : ''}` +
957
- `**Proxy:** ${response.browser.proxyConfigured ? '✅ Configured' : '❌ Not configured'}\n\n` +
958
- `*Use this browser ID with \`roxy_open_browsers\` to start the browser and get CDP endpoints for automation.*`,
959
- },
960
- ],
961
- };
962
990
  }
963
991
  async handleCreateBrowserStandard(args) {
964
992
  const params = args;
965
993
  if (!params.workspaceId) {
966
994
  throw new Error('workspaceId is required');
967
995
  }
968
- // Build configuration from standard parameters
969
- const config = BrowserCreator.buildStandardConfig(params);
970
- const finalConfig = BrowserCreator.applyDefaults(config);
971
- // Validate configuration
972
- const validation = BrowserCreator.validateConfig(finalConfig);
973
- if (!validation.valid) {
974
- throw new BrowserCreationError(`Configuration validation failed: ${validation.errors.join(', ')}`);
996
+ try {
997
+ // Build configuration from standard parameters
998
+ const config = BrowserCreator.buildStandardConfig(params);
999
+ const finalConfig = BrowserCreator.applyDefaults(config);
1000
+ // Validate configuration
1001
+ const validation = BrowserCreator.validateConfig(finalConfig);
1002
+ if (!validation.valid) {
1003
+ throw new BrowserCreationError(`Configuration validation failed: ${validation.errors.join(', ')}`);
1004
+ }
1005
+ // Create browser
1006
+ const result = await this.roxyClient.createBrowser(finalConfig);
1007
+ const response = {
1008
+ browser: {
1009
+ dirId: result.dirId,
1010
+ windowName: finalConfig.windowName || 'Standard Browser',
1011
+ workspaceId: params.workspaceId,
1012
+ projectId: params.projectId,
1013
+ os: finalConfig.os || 'Windows',
1014
+ coreVersion: finalConfig.coreVersion || LATEST_CORE_VERSION,
1015
+ proxyInfo: params.proxyInfo,
1016
+ windowSize: `${params.openWidth || '1000'}x${params.openHeight || '1000'}`,
1017
+ },
1018
+ message: `Standard browser created successfully with ID: ${result.dirId}`,
1019
+ };
1020
+ return {
1021
+ content: [
1022
+ {
1023
+ type: 'text',
1024
+ text: `✅ **Standard Browser Created**\n\n` +
1025
+ `**Browser ID:** \`${response.browser.dirId}\`\n` +
1026
+ `**Name:** ${response.browser.windowName}\n` +
1027
+ `**OS:** ${response.browser.os} ${finalConfig.osVersion || ''}\n` +
1028
+ `**Core Version:** ${response.browser.coreVersion}\n` +
1029
+ `**Window Size:** ${response.browser.windowSize}\n` +
1030
+ `**Workspace:** ${response.browser.workspaceId}\n` +
1031
+ `${response.browser.projectId ? `**Project:** ${response.browser.projectId}\n` : ''}` +
1032
+ `**Proxy:** ${response.browser.proxyInfo ? '✅ Configured' : '❌ Not configured'}\n\n` +
1033
+ `*Browser is ready for automation. Use \`roxy_open_browsers\` to start it.*`,
1034
+ },
1035
+ ],
1036
+ };
1037
+ }
1038
+ catch (error) {
1039
+ // Check for quota error specifically
1040
+ if (error instanceof RoxyApiError && error.code === 409 &&
1041
+ error.message.includes('额度不足')) {
1042
+ return {
1043
+ content: [{
1044
+ type: 'text',
1045
+ text: `❌ **浏览器创建失败 - 窗口额度不足 / Browser Creation Failed - Insufficient Profiles Quota**\n\n` +
1046
+ `**错误信息 / Error:** ${error.message}\n\n` +
1047
+ `**解决步骤 / Solution Steps:**\n` +
1048
+ `1. 打开 RoxyBrowser 应用 / Open RoxyBrowser app\n` +
1049
+ `2. 前往费用中心 / Go to Billing Center\n` +
1050
+ `3. 购买或升级窗口套餐 / Purchase or upgrade profiles plan\n` +
1051
+ `4. 或者删除不需要的浏览器窗口以释放额度 / Or delete unused browser profiles to free up quota\n` +
1052
+ `5. 等待生效后重试创建 / Retry creation after quota is available\n\n` +
1053
+ `💡 **重要提示 / Important:** 必须使用 \`roxy_delete_browsers\` 删除浏览器才能释放额度,仅关闭浏览器无法释放额度。\n` +
1054
+ `You must use \`roxy_delete_browsers\` to delete profiles to free up quota. Simply closing browsers will NOT free up quota.`,
1055
+ }],
1056
+ };
1057
+ }
1058
+ // Use enhanced error analysis for other errors
1059
+ const formattedError = ErrorAnalyzer.formatErrorForDisplay(error instanceof Error ? error : new Error('Unknown error'));
1060
+ return {
1061
+ content: [{ type: 'text', text: formattedError }],
1062
+ };
975
1063
  }
976
- // Create browser
977
- const result = await this.roxyClient.createBrowser(finalConfig);
978
- const response = {
979
- browser: {
980
- dirId: result.dirId,
981
- windowName: finalConfig.windowName || 'Standard Browser',
982
- workspaceId: params.workspaceId,
983
- projectId: params.projectId,
984
- os: finalConfig.os || 'Windows',
985
- coreVersion: finalConfig.coreVersion || '125',
986
- proxyInfo: params.proxyInfo,
987
- windowSize: `${params.openWidth || '1000'}x${params.openHeight || '1000'}`,
988
- },
989
- message: `Standard browser created successfully with ID: ${result.dirId}`,
990
- };
991
- return {
992
- content: [
993
- {
994
- type: 'text',
995
- text: `✅ **Standard Browser Created**\n\n` +
996
- `**Browser ID:** \`${response.browser.dirId}\`\n` +
997
- `**Name:** ${response.browser.windowName}\n` +
998
- `**OS:** ${response.browser.os} ${finalConfig.osVersion || ''}\n` +
999
- `**Core Version:** ${response.browser.coreVersion}\n` +
1000
- `**Window Size:** ${response.browser.windowSize}\n` +
1001
- `**Workspace:** ${response.browser.workspaceId}\n` +
1002
- `${response.browser.projectId ? `**Project:** ${response.browser.projectId}\n` : ''}` +
1003
- `**Proxy:** ${response.browser.proxyInfo ? '✅ Configured' : '❌ Not configured'}\n\n` +
1004
- `*Browser is ready for automation. Use \`roxy_open_browsers\` to start it.*`,
1005
- },
1006
- ],
1007
- };
1008
1064
  }
1009
1065
  async handleCreateBrowserAdvanced(args) {
1010
1066
  const params = args;
1011
1067
  if (!params.workspaceId) {
1012
1068
  throw new Error('workspaceId is required');
1013
1069
  }
1014
- // Build configuration from advanced parameters
1015
- const config = BrowserCreator.buildAdvancedConfig(params);
1016
- const finalConfig = BrowserCreator.applyDefaults(config);
1017
- // Validate configuration
1018
- const validation = BrowserCreator.validateConfig(finalConfig);
1019
- if (!validation.valid) {
1020
- throw new BrowserCreationError(`Configuration validation failed: ${validation.errors.join(', ')}`);
1021
- }
1022
- // Create browser
1023
- const result = await this.roxyClient.createBrowser(finalConfig);
1024
- const response = {
1025
- browser: {
1026
- dirId: result.dirId,
1027
- config: finalConfig,
1028
- },
1029
- message: `Advanced browser created successfully with ID: ${result.dirId}`,
1030
- };
1031
- // Create detailed status text
1032
- const configSummary = [
1033
- `**Browser ID:** \`${response.browser.dirId}\``,
1034
- `**Name:** ${finalConfig.windowName || 'Advanced Browser'}`,
1035
- `**OS:** ${finalConfig.os || 'Windows'} ${finalConfig.osVersion || ''}`,
1036
- `**Core Version:** ${finalConfig.coreVersion || '125'}`,
1037
- finalConfig.userAgent ? `**User Agent:** ${finalConfig.userAgent.substring(0, 50)}...` : '',
1038
- `**Search Engine:** ${finalConfig.searchEngine || 'Google'}`,
1039
- finalConfig.proxyInfo?.proxyCategory !== 'noproxy' ? `**Proxy:** ✅ ${finalConfig.proxyInfo?.proxyCategory} ${finalConfig.proxyInfo?.host}:${finalConfig.proxyInfo?.port}` : '**Proxy:** ❌ No proxy',
1040
- finalConfig.fingerInfo?.randomFingerprint ? '**Fingerprint:** 🎲 Random' : '**Fingerprint:** 🔒 Fixed',
1041
- finalConfig.defaultOpenUrl?.length ? `**Default URLs:** ${finalConfig.defaultOpenUrl.length} URL(s)` : '',
1042
- ].filter(Boolean).join('\n');
1043
- return {
1044
- content: [
1045
- {
1046
- type: 'text',
1047
- text: `✅ **Advanced Browser Created**\n\n${configSummary}\n\n` +
1048
- `*Advanced browser configured with complete control. Use \`roxy_open_browsers\` to start it.*`,
1070
+ try {
1071
+ // Build configuration from advanced parameters
1072
+ const config = BrowserCreator.buildAdvancedConfig(params);
1073
+ const finalConfig = BrowserCreator.applyDefaults(config);
1074
+ // Validate configuration
1075
+ const validation = BrowserCreator.validateConfig(finalConfig);
1076
+ if (!validation.valid) {
1077
+ throw new BrowserCreationError(`Configuration validation failed: ${validation.errors.join(', ')}`);
1078
+ }
1079
+ // Create browser
1080
+ const result = await this.roxyClient.createBrowser(finalConfig);
1081
+ const response = {
1082
+ browser: {
1083
+ dirId: result.dirId,
1084
+ config: finalConfig,
1049
1085
  },
1050
- ],
1051
- };
1086
+ message: `Advanced browser created successfully with ID: ${result.dirId}`,
1087
+ };
1088
+ // Create detailed status text
1089
+ const configSummary = [
1090
+ `**Browser ID:** \`${response.browser.dirId}\``,
1091
+ `**Name:** ${finalConfig.windowName || 'Advanced Browser'}`,
1092
+ `**OS:** ${finalConfig.os || 'Windows'} ${finalConfig.osVersion || ''}`,
1093
+ `**Core Version:** ${finalConfig.coreVersion || LATEST_CORE_VERSION}`,
1094
+ finalConfig.userAgent ? `**User Agent:** ${finalConfig.userAgent.substring(0, 50)}...` : '',
1095
+ `**Search Engine:** ${finalConfig.searchEngine || 'Google'}`,
1096
+ finalConfig.proxyInfo?.proxyCategory !== 'noproxy' ? `**Proxy:** ✅ ${finalConfig.proxyInfo?.proxyCategory} ${finalConfig.proxyInfo?.host}:${finalConfig.proxyInfo?.port}` : '**Proxy:** ❌ No proxy',
1097
+ finalConfig.fingerInfo?.randomFingerprint ? '**Fingerprint:** 🎲 Random' : '**Fingerprint:** 🔒 Fixed',
1098
+ finalConfig.defaultOpenUrl?.length ? `**Default URLs:** ${finalConfig.defaultOpenUrl.length} URL(s)` : '',
1099
+ ].filter(Boolean).join('\n');
1100
+ return {
1101
+ content: [
1102
+ {
1103
+ type: 'text',
1104
+ text: `✅ **Advanced Browser Created**\n\n${configSummary}\n\n` +
1105
+ `*Advanced browser configured with complete control. Use \`roxy_open_browsers\` to start it.*`,
1106
+ },
1107
+ ],
1108
+ };
1109
+ }
1110
+ catch (error) {
1111
+ // Check for quota error specifically
1112
+ if (error instanceof RoxyApiError && error.code === 409 &&
1113
+ error.message.includes('额度不足')) {
1114
+ return {
1115
+ content: [{
1116
+ type: 'text',
1117
+ text: `❌ **浏览器创建失败 - 窗口额度不足 / Browser Creation Failed - Insufficient Profiles Quota**\n\n` +
1118
+ `**错误信息 / Error:** ${error.message}\n\n` +
1119
+ `**解决步骤 / Solution Steps:**\n` +
1120
+ `1. 打开 RoxyBrowser 应用 / Open RoxyBrowser app\n` +
1121
+ `2. 前往费用中心 / Go to Billing Center\n` +
1122
+ `3. 购买或升级窗口套餐 / Purchase or upgrade profiles plan\n` +
1123
+ `4. 或者删除不需要的浏览器窗口以释放额度 / Or delete unused browser profiles to free up quota\n` +
1124
+ `5. 等待生效后重试创建 / Retry creation after quota is available\n\n` +
1125
+ `💡 **重要提示 / Important:** 必须使用 \`roxy_delete_browsers\` 删除浏览器才能释放额度,仅关闭浏览器无法释放额度。\n` +
1126
+ `You must use \`roxy_delete_browsers\` to delete profiles to free up quota. Simply closing browsers will NOT free up quota.`,
1127
+ }],
1128
+ };
1129
+ }
1130
+ // Use enhanced error analysis for other errors
1131
+ const formattedError = ErrorAnalyzer.formatErrorForDisplay(error instanceof Error ? error : new Error('Unknown error'));
1132
+ return {
1133
+ content: [{ type: 'text', text: formattedError }],
1134
+ };
1135
+ }
1052
1136
  }
1053
1137
  async handleValidateProxyConfig(args) {
1054
1138
  const { proxyInfo } = args;
@@ -1128,20 +1212,62 @@ class RoxyBrowserMCPServer {
1128
1212
  if (!params.workspaceId || !params.dirIds || params.dirIds.length === 0) {
1129
1213
  throw new Error('workspaceId and dirIds are required');
1130
1214
  }
1131
- const results = await this.roxyClient.openBrowsers(params.workspaceId, params.dirIds, params.args);
1215
+ const { successes, failures } = await this.roxyClient.openBrowsers(params.workspaceId, params.dirIds, params.args);
1216
+ // Build success message
1217
+ let message = '';
1218
+ if (successes.length > 0) {
1219
+ message += `✅ **Successfully opened ${successes.length} browser(s):**\n\n` +
1220
+ successes.map(result => `**Browser ${result.dirId || 'Unknown'}** (PID: ${result.pid})\n` +
1221
+ ` - CDP WebSocket: \`${result.ws}\`\n` +
1222
+ ` - HTTP Endpoint: \`${result.http}\`\n` +
1223
+ ` - Core Version: ${result.coreVersion}`).join('\n\n') +
1224
+ '\n\n**Use these WebSocket URLs with playwright-mcp:**\n' +
1225
+ '```bash\n' +
1226
+ successes.map(result => `npx @playwright/mcp@latest --cdp-endpoint "${result.ws}"`).join('\n') +
1227
+ '\n```';
1228
+ }
1229
+ // Build failure message with special handling for quota errors
1230
+ if (failures.length > 0) {
1231
+ if (successes.length > 0) {
1232
+ message += '\n\n---\n\n';
1233
+ }
1234
+ // Check if any failures are quota errors (code 101 or 409)
1235
+ const quotaErrors = failures.filter(f => f.errorCode === 101 || (f.errorCode === 409 && f.error.includes('额度不足')));
1236
+ const otherErrors = failures.filter(f => !quotaErrors.includes(f));
1237
+ if (quotaErrors.length > 0) {
1238
+ message += `❌ **Failed to open ${quotaErrors.length} browser(s) - Insufficient Profiles Quota / 窗口额度不足:**\n\n`;
1239
+ quotaErrors.forEach(failure => {
1240
+ message += ` - Browser ID: \`${failure.dirId}\`\n Error: ${failure.error}\n`;
1241
+ });
1242
+ message += '\n**解决步骤 / Solution Steps:**\n';
1243
+ message += '1. 打开 RoxyBrowser 应用 / Open RoxyBrowser app\n';
1244
+ message += '2. 前往费用中心 / Go to Billing Center\n';
1245
+ message += '3. 购买或升级窗口套餐 / Purchase or upgrade profiles plan\n';
1246
+ message += '4. 或者删除不需要的浏览器窗口以释放额度 / Or delete unused browser profiles to free up quota\n\n';
1247
+ message += '💡 **重要提示 / Important:** 必须使用 `roxy_delete_browsers` 删除浏览器才能释放额度,仅关闭浏览器无法释放额度。\n';
1248
+ message += 'You must use `roxy_delete_browsers` to delete profiles to free up quota. Simply closing browsers will NOT free up quota.';
1249
+ }
1250
+ if (otherErrors.length > 0) {
1251
+ if (quotaErrors.length > 0) {
1252
+ message += '\n\n';
1253
+ }
1254
+ message += `❌ **Failed to open ${otherErrors.length} browser(s) - Other Errors:**\n\n`;
1255
+ otherErrors.forEach(failure => {
1256
+ message += ` - Browser ID: \`${failure.dirId}\`\n`;
1257
+ message += ` Error: ${failure.error}\n`;
1258
+ message += ` Retryable: ${failure.retryable ? '✅ Yes' : '❌ No'}\n`;
1259
+ });
1260
+ }
1261
+ }
1262
+ // If all failed
1263
+ if (successes.length === 0 && failures.length > 0) {
1264
+ message = `❌ **Failed to open all ${failures.length} browser(s)**\n\n` + message;
1265
+ }
1132
1266
  return {
1133
1267
  content: [
1134
1268
  {
1135
1269
  type: 'text',
1136
- text: `Successfully opened ${results.length} browsers:\n\n` +
1137
- results.map(result => `**Browser ${result.dirId || 'Unknown'}** (PID: ${result.pid})\n` +
1138
- ` - CDP WebSocket: \`${result.ws}\`\n` +
1139
- ` - HTTP Endpoint: \`${result.http}\`\n` +
1140
- ` - Core Version: ${result.coreVersion}`).join('\n\n') +
1141
- '\n\n**Use these WebSocket URLs with playwright-mcp:**\n' +
1142
- '```bash\n' +
1143
- results.map(result => `npx @playwright/mcp@latest --cdp-endpoint "${result.ws}"`).join('\n') +
1144
- '\n```',
1270
+ text: message,
1145
1271
  },
1146
1272
  ],
1147
1273
  };
@@ -1405,20 +1531,30 @@ class RoxyBrowserMCPServer {
1405
1531
  throw new Error('workspaceId and dirId are required');
1406
1532
  }
1407
1533
  const detail = await this.roxyClient.getBrowserDetail(workspaceId, dirId);
1534
+ // Save cookie count before removing cookies to save tokens
1535
+ const cookieCount = detail.cookie?.length || 0;
1536
+ // Create a copy without cookies (cookies can be very large)
1537
+ const { cookie, ...detailWithoutCookies } = detail;
1538
+ // Create summary
1539
+ const summary = `**Browser Details Summary**\n\n` +
1540
+ `**ID:** \`${detail.dirId}\`\n` +
1541
+ `**Name:** ${detail.windowName}\n` +
1542
+ `**Sort Number:** ${detail.windowSortNum}\n` +
1543
+ `**Project:** ${detail.projectName} (ID: ${detail.projectId})\n` +
1544
+ `**OS:** ${detail.os} ${detail.osVersion}\n` +
1545
+ `**Core Version:** ${detail.coreVersion}\n` +
1546
+ `**Search Engine:** ${detail.searchEngine}\n` +
1547
+ `**Open Status:** ${detail.openStatus ? '✅ Opened' : '❌ Closed'}\n` +
1548
+ `**Cookies:** ${cookieCount} stored (excluded from response to save tokens)\n\n` +
1549
+ `**Full Details (JSON):**\n` +
1550
+ '```json\n' +
1551
+ JSON.stringify(detailWithoutCookies, null, 2) +
1552
+ '\n```';
1408
1553
  return {
1409
1554
  content: [
1410
1555
  {
1411
1556
  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'}`,
1557
+ text: summary,
1422
1558
  },
1423
1559
  ],
1424
1560
  };