@roxybrowser/openapi 1.0.10-beta.0 → 1.0.10-beta.2
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/cli.cjs +3113 -0
- package/lib/cli.cjs.map +1 -0
- package/lib/cli.d.cts +1 -0
- package/lib/cli.d.ts +0 -5
- package/lib/cli.js +3102 -42
- package/lib/cli.js.map +1 -1
- package/lib/index.cjs +3097 -0
- package/lib/index.cjs.map +1 -0
- package/lib/{modules/browser.d.ts → index.d.cts} +2949 -15
- package/lib/index.d.ts +5452 -10
- package/lib/index.js +3052 -156
- package/lib/index.js.map +1 -1
- package/package.json +8 -5
- package/lib/cli.d.ts.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/modules/account.d.ts +0 -491
- package/lib/modules/account.d.ts.map +0 -1
- package/lib/modules/account.js +0 -442
- package/lib/modules/account.js.map +0 -1
- package/lib/modules/browser.d.ts.map +0 -1
- package/lib/modules/browser.js +0 -1502
- package/lib/modules/browser.js.map +0 -1
- package/lib/modules/other.d.ts +0 -102
- package/lib/modules/other.d.ts.map +0 -1
- package/lib/modules/other.js +0 -194
- package/lib/modules/other.js.map +0 -1
- package/lib/modules/proxy.d.ts +0 -576
- package/lib/modules/proxy.d.ts.map +0 -1
- package/lib/modules/proxy.js +0 -724
- package/lib/modules/proxy.js.map +0 -1
- package/lib/types.d.ts +0 -1195
- package/lib/types.d.ts.map +0 -1
- package/lib/types.js +0 -366
- package/lib/types.js.map +0 -1
- package/lib/utils/index.d.ts +0 -31
- package/lib/utils/index.d.ts.map +0 -1
- package/lib/utils/index.js +0 -71
- package/lib/utils/index.js.map +0 -1
package/lib/cli.cjs
ADDED
|
@@ -0,0 +1,3113 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var commander = require('commander');
|
|
5
|
+
var index_js = require('@modelcontextprotocol/sdk/server/index.js');
|
|
6
|
+
var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
|
|
7
|
+
var types_js = require('@modelcontextprotocol/sdk/types.js');
|
|
8
|
+
|
|
9
|
+
// src/types.ts
|
|
10
|
+
var ConfigError = class extends Error {
|
|
11
|
+
constructor(message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = "ConfigError";
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/utils/index.ts
|
|
18
|
+
var DEFAULT_CONFIG = {
|
|
19
|
+
apiHost: "http://127.0.0.1:50000",
|
|
20
|
+
timeout: 3e4
|
|
21
|
+
};
|
|
22
|
+
var ENV_KEYS = {
|
|
23
|
+
apiHost: "ROXY_API_HOST",
|
|
24
|
+
apiKey: "ROXY_API_KEY",
|
|
25
|
+
timeout: "ROXY_TIMEOUT"
|
|
26
|
+
};
|
|
27
|
+
function resolveConfig() {
|
|
28
|
+
const envHost = process.env[ENV_KEYS.apiHost];
|
|
29
|
+
const envKey = process.env[ENV_KEYS.apiKey];
|
|
30
|
+
const envTimeout = process.env[ENV_KEYS.timeout];
|
|
31
|
+
return {
|
|
32
|
+
apiHost: envHost ?? DEFAULT_CONFIG.apiHost,
|
|
33
|
+
apiKey: envKey ?? "",
|
|
34
|
+
timeout: envTimeout != null && envTimeout !== "" ? Number.parseInt(envTimeout, 10) : DEFAULT_CONFIG.timeout
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function requireConfig() {
|
|
38
|
+
const config = resolveConfig();
|
|
39
|
+
if (!config.apiKey || config.apiKey.trim() === "") {
|
|
40
|
+
throw new ConfigError(
|
|
41
|
+
"API key is required. Set ROXY_API_KEY or pass --api-key. Get your key from RoxyBrowser: API \u2192 API\u914D\u7F6E \u2192 API Key"
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
return config;
|
|
45
|
+
}
|
|
46
|
+
async function request(endpoint, options = {}) {
|
|
47
|
+
const config = requireConfig();
|
|
48
|
+
const url = `${config.apiHost.replace(/\/$/, "")}${endpoint}`;
|
|
49
|
+
const controller = new AbortController();
|
|
50
|
+
const timeoutId = setTimeout(() => controller.abort(), config.timeout);
|
|
51
|
+
try {
|
|
52
|
+
const response = await fetch(url, {
|
|
53
|
+
...options,
|
|
54
|
+
headers: {
|
|
55
|
+
"Content-Type": "application/json",
|
|
56
|
+
"token": config.apiKey,
|
|
57
|
+
...options.headers
|
|
58
|
+
},
|
|
59
|
+
signal: controller.signal
|
|
60
|
+
});
|
|
61
|
+
clearTimeout(timeoutId);
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
const responseText = await response.text().catch(() => "Unknown error");
|
|
64
|
+
throw new Error(
|
|
65
|
+
`HTTP ${response.status}: ${response.statusText} ${responseText}`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
const result = await response.json();
|
|
69
|
+
return result;
|
|
70
|
+
} catch (error) {
|
|
71
|
+
clearTimeout(timeoutId);
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// src/modules/account.ts
|
|
77
|
+
var ListAccounts = class {
|
|
78
|
+
name = "roxy_list_accounts";
|
|
79
|
+
description = "Get list of accounts (platform credentials) in specified workspace";
|
|
80
|
+
inputSchema = {
|
|
81
|
+
type: "object",
|
|
82
|
+
properties: {
|
|
83
|
+
workspaceId: {
|
|
84
|
+
type: "number",
|
|
85
|
+
description: "Workspace ID"
|
|
86
|
+
},
|
|
87
|
+
accountId: {
|
|
88
|
+
type: "number",
|
|
89
|
+
description: "Account ID to filter by"
|
|
90
|
+
},
|
|
91
|
+
pageIndex: {
|
|
92
|
+
type: "number",
|
|
93
|
+
description: "Page index for pagination (default: 1)",
|
|
94
|
+
default: 1
|
|
95
|
+
},
|
|
96
|
+
pageSize: {
|
|
97
|
+
type: "number",
|
|
98
|
+
description: "Number of items per page (default: 15)",
|
|
99
|
+
default: 15
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
required: ["workspaceId"]
|
|
103
|
+
};
|
|
104
|
+
get schema() {
|
|
105
|
+
return {
|
|
106
|
+
name: this.name,
|
|
107
|
+
description: this.description,
|
|
108
|
+
inputSchema: this.inputSchema
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
async handle(params) {
|
|
112
|
+
const searchParams = new URLSearchParams();
|
|
113
|
+
searchParams.append("workspaceId", params.workspaceId.toString());
|
|
114
|
+
if (params.accountId)
|
|
115
|
+
searchParams.append("accountId", params.accountId.toString());
|
|
116
|
+
if (params.pageIndex)
|
|
117
|
+
searchParams.append("page_index", params.pageIndex.toString());
|
|
118
|
+
if (params.pageSize)
|
|
119
|
+
searchParams.append("page_size", params.pageSize.toString());
|
|
120
|
+
const result = await request(`/account/list?${searchParams}`, {
|
|
121
|
+
method: "GET"
|
|
122
|
+
});
|
|
123
|
+
const data = result.data;
|
|
124
|
+
let text = "";
|
|
125
|
+
if (result.code !== 0) {
|
|
126
|
+
text = `\u274C **Failed to list accounts:**
|
|
127
|
+
|
|
128
|
+
error message: ${result.msg}`;
|
|
129
|
+
} else {
|
|
130
|
+
text = `Found ${data.total} accounts in workspace ${params.workspaceId}:
|
|
131
|
+
|
|
132
|
+
${data.rows.map(
|
|
133
|
+
(account) => `**${account.platformName}** (ID: ${account.id})
|
|
134
|
+
- Username: ${account.platformUserName}
|
|
135
|
+
- Platform URL: ${account.platformUrl}
|
|
136
|
+
- Remarks: ${account.platformRemarks || "N/A"}
|
|
137
|
+
- Created: ${account.createTime}`
|
|
138
|
+
).join("\n\n")}`;
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
content: [
|
|
142
|
+
{
|
|
143
|
+
type: "text",
|
|
144
|
+
text
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
var CreateAccount = class {
|
|
151
|
+
name = "roxy_create_account";
|
|
152
|
+
description = "Create a new platform account with credentials";
|
|
153
|
+
inputSchema = {
|
|
154
|
+
type: "object",
|
|
155
|
+
properties: {
|
|
156
|
+
workspaceId: {
|
|
157
|
+
type: "number",
|
|
158
|
+
description: "Workspace ID"
|
|
159
|
+
},
|
|
160
|
+
platformUrl: {
|
|
161
|
+
type: "string",
|
|
162
|
+
description: "Business platform URL (e.g., https://www.tiktok.com/)"
|
|
163
|
+
},
|
|
164
|
+
platformUserName: {
|
|
165
|
+
type: "string",
|
|
166
|
+
description: "Account username"
|
|
167
|
+
},
|
|
168
|
+
platformPassword: {
|
|
169
|
+
type: "string",
|
|
170
|
+
description: "Account password"
|
|
171
|
+
},
|
|
172
|
+
platformEfa: {
|
|
173
|
+
type: "string",
|
|
174
|
+
description: "Account EFA"
|
|
175
|
+
},
|
|
176
|
+
platformCookies: {
|
|
177
|
+
type: "array",
|
|
178
|
+
description: "Account cookies",
|
|
179
|
+
items: {
|
|
180
|
+
type: "object",
|
|
181
|
+
properties: {
|
|
182
|
+
name: { type: "string" },
|
|
183
|
+
value: { type: "string" },
|
|
184
|
+
domain: { type: "string" }
|
|
185
|
+
},
|
|
186
|
+
required: ["name", "value", "domain"]
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
platformName: {
|
|
190
|
+
type: "string",
|
|
191
|
+
description: "Platform name"
|
|
192
|
+
},
|
|
193
|
+
platformRemarks: {
|
|
194
|
+
type: "string",
|
|
195
|
+
description: "Platform remarks/notes"
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
required: ["workspaceId", "platformUrl", "platformUserName", "platformPassword"]
|
|
199
|
+
};
|
|
200
|
+
get schema() {
|
|
201
|
+
return {
|
|
202
|
+
name: this.name,
|
|
203
|
+
description: this.description,
|
|
204
|
+
inputSchema: this.inputSchema
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
async handle(params) {
|
|
208
|
+
if (!params.workspaceId || !params.platformUrl || !params.platformUserName || !params.platformPassword) {
|
|
209
|
+
return {
|
|
210
|
+
content: [
|
|
211
|
+
{
|
|
212
|
+
type: "text",
|
|
213
|
+
text: "\u274C **Failed to create account:**\n\n workspaceId, platformUrl, platformUserName, and platformPassword are required"
|
|
214
|
+
}
|
|
215
|
+
]
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
const { workspaceId, ...accountData } = params;
|
|
219
|
+
const result = await request("/account/create", {
|
|
220
|
+
method: "POST",
|
|
221
|
+
body: JSON.stringify({ workspaceId, ...accountData })
|
|
222
|
+
});
|
|
223
|
+
let text = "";
|
|
224
|
+
if (result.code !== 0) {
|
|
225
|
+
text = `\u274C **Failed to create account:**
|
|
226
|
+
|
|
227
|
+
error message: ${result.msg}`;
|
|
228
|
+
} else {
|
|
229
|
+
text = `\u2705 **Account Created Successfully**
|
|
230
|
+
|
|
231
|
+
**Platform:** ${params.platformName || params.platformUrl}
|
|
232
|
+
**Username:** ${params.platformUserName}
|
|
233
|
+
**Platform URL:** ${params.platformUrl}${params.platformRemarks ? `
|
|
234
|
+
**Remarks:** ${params.platformRemarks}` : ""}${params.platformEfa ? `
|
|
235
|
+
**EFA:** ${params.platformEfa}` : ""}${params.platformCookies && params.platformCookies.length > 0 ? `
|
|
236
|
+
**Cookies:** ${params.platformCookies.length} cookie(s)` : ""}
|
|
237
|
+
|
|
238
|
+
*Account has been created successfully.*`;
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
content: [
|
|
242
|
+
{
|
|
243
|
+
type: "text",
|
|
244
|
+
text
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
var BatchCreateAccounts = class {
|
|
251
|
+
name = "roxy_batch_create_accounts";
|
|
252
|
+
description = "Batch create multiple platform accounts";
|
|
253
|
+
inputSchema = {
|
|
254
|
+
type: "object",
|
|
255
|
+
properties: {
|
|
256
|
+
workspaceId: {
|
|
257
|
+
type: "number",
|
|
258
|
+
description: "Workspace ID"
|
|
259
|
+
},
|
|
260
|
+
accountList: {
|
|
261
|
+
type: "array",
|
|
262
|
+
description: "Array of account configurations",
|
|
263
|
+
items: {
|
|
264
|
+
type: "object",
|
|
265
|
+
properties: {
|
|
266
|
+
platformUrl: { type: "string" },
|
|
267
|
+
platformUserName: { type: "string" },
|
|
268
|
+
platformPassword: { type: "string" },
|
|
269
|
+
platformEfa: { type: "string" },
|
|
270
|
+
platformCookies: {
|
|
271
|
+
type: "array",
|
|
272
|
+
items: {
|
|
273
|
+
type: "object",
|
|
274
|
+
properties: {
|
|
275
|
+
name: { type: "string" },
|
|
276
|
+
value: { type: "string" },
|
|
277
|
+
domain: { type: "string" }
|
|
278
|
+
},
|
|
279
|
+
required: ["name", "value", "domain"]
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
platformName: { type: "string" },
|
|
283
|
+
platformRemarks: { type: "string" }
|
|
284
|
+
},
|
|
285
|
+
required: ["platformUrl", "platformUserName", "platformPassword"]
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
required: ["workspaceId", "accountList"]
|
|
290
|
+
};
|
|
291
|
+
get schema() {
|
|
292
|
+
return {
|
|
293
|
+
name: this.name,
|
|
294
|
+
description: this.description,
|
|
295
|
+
inputSchema: this.inputSchema
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
async handle(params) {
|
|
299
|
+
if (!params.workspaceId || !params.accountList || params.accountList.length === 0) {
|
|
300
|
+
return {
|
|
301
|
+
content: [
|
|
302
|
+
{
|
|
303
|
+
type: "text",
|
|
304
|
+
text: "\u274C **Failed to batch create accounts:**\n\n workspaceId and accountList are required"
|
|
305
|
+
}
|
|
306
|
+
]
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
const { workspaceId, accountList } = params;
|
|
310
|
+
const result = await request("/account/batch_create", {
|
|
311
|
+
method: "POST",
|
|
312
|
+
body: JSON.stringify({ workspaceId, accountList })
|
|
313
|
+
});
|
|
314
|
+
let text = "";
|
|
315
|
+
if (result.code !== 0) {
|
|
316
|
+
text = `\u274C **Failed to batch create accounts:**
|
|
317
|
+
|
|
318
|
+
error message: ${result.msg}`;
|
|
319
|
+
} else {
|
|
320
|
+
text = `\u2705 **Batch Account Creation Successful**
|
|
321
|
+
|
|
322
|
+
**Count:** ${params.accountList.length} account(s)
|
|
323
|
+
**Workspace:** ${params.workspaceId}
|
|
324
|
+
|
|
325
|
+
*All accounts have been created successfully.*`;
|
|
326
|
+
}
|
|
327
|
+
return {
|
|
328
|
+
content: [
|
|
329
|
+
{
|
|
330
|
+
type: "text",
|
|
331
|
+
text
|
|
332
|
+
}
|
|
333
|
+
]
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
var ModifyAccount = class {
|
|
338
|
+
name = "roxy_modify_account";
|
|
339
|
+
description = "Modify/update an existing platform account";
|
|
340
|
+
inputSchema = {
|
|
341
|
+
type: "object",
|
|
342
|
+
properties: {
|
|
343
|
+
workspaceId: {
|
|
344
|
+
type: "number",
|
|
345
|
+
description: "Workspace ID"
|
|
346
|
+
},
|
|
347
|
+
id: {
|
|
348
|
+
type: "number",
|
|
349
|
+
description: "Account ID to modify"
|
|
350
|
+
},
|
|
351
|
+
platformUrl: {
|
|
352
|
+
type: "string",
|
|
353
|
+
description: "Business platform URL"
|
|
354
|
+
},
|
|
355
|
+
platformUserName: {
|
|
356
|
+
type: "string",
|
|
357
|
+
description: "Account username"
|
|
358
|
+
},
|
|
359
|
+
platformPassword: {
|
|
360
|
+
type: "string",
|
|
361
|
+
description: "Account password"
|
|
362
|
+
},
|
|
363
|
+
platformEfa: {
|
|
364
|
+
type: "string",
|
|
365
|
+
description: "Account EFA"
|
|
366
|
+
},
|
|
367
|
+
platformCookies: {
|
|
368
|
+
type: "array",
|
|
369
|
+
description: "Account cookies",
|
|
370
|
+
items: {
|
|
371
|
+
type: "object",
|
|
372
|
+
properties: {
|
|
373
|
+
name: { type: "string" },
|
|
374
|
+
value: { type: "string" },
|
|
375
|
+
domain: { type: "string" }
|
|
376
|
+
},
|
|
377
|
+
required: ["name", "value", "domain"]
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
platformName: {
|
|
381
|
+
type: "string",
|
|
382
|
+
description: "Platform name"
|
|
383
|
+
},
|
|
384
|
+
platformRemarks: {
|
|
385
|
+
type: "string",
|
|
386
|
+
description: "Platform remarks/notes"
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
required: ["workspaceId", "id"]
|
|
390
|
+
};
|
|
391
|
+
get schema() {
|
|
392
|
+
return {
|
|
393
|
+
name: this.name,
|
|
394
|
+
description: this.description,
|
|
395
|
+
inputSchema: this.inputSchema
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
async handle(params) {
|
|
399
|
+
if (!params.workspaceId || !params.id) {
|
|
400
|
+
return {
|
|
401
|
+
content: [
|
|
402
|
+
{
|
|
403
|
+
type: "text",
|
|
404
|
+
text: "\u274C **Failed to modify account:**\n\n workspaceId and id are required"
|
|
405
|
+
}
|
|
406
|
+
]
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
const { workspaceId, ...accountData } = params;
|
|
410
|
+
const result = await request("/account/modify", {
|
|
411
|
+
method: "POST",
|
|
412
|
+
body: JSON.stringify({ workspaceId, ...accountData })
|
|
413
|
+
});
|
|
414
|
+
let text = "";
|
|
415
|
+
if (result.code !== 0) {
|
|
416
|
+
text = `\u274C **Failed to modify account:**
|
|
417
|
+
|
|
418
|
+
error message: ${result.msg}`;
|
|
419
|
+
} else {
|
|
420
|
+
text = `\u2705 **Account Modified Successfully**
|
|
421
|
+
|
|
422
|
+
**Account ID:** ${params.id}${params.platformName ? `
|
|
423
|
+
**Platform:** ${params.platformName}` : ""}${params.platformUrl ? `
|
|
424
|
+
**Platform URL:** ${params.platformUrl}` : ""}${params.platformUserName ? `
|
|
425
|
+
**Username:** ${params.platformUserName}` : ""}${params.platformRemarks ? `
|
|
426
|
+
**Remarks:** ${params.platformRemarks}` : ""}
|
|
427
|
+
|
|
428
|
+
*Account configuration has been updated.*`;
|
|
429
|
+
}
|
|
430
|
+
return {
|
|
431
|
+
content: [
|
|
432
|
+
{
|
|
433
|
+
type: "text",
|
|
434
|
+
text
|
|
435
|
+
}
|
|
436
|
+
]
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
var DeleteAccounts = class {
|
|
441
|
+
name = "roxy_delete_accounts";
|
|
442
|
+
description = "Delete one or more platform accounts";
|
|
443
|
+
inputSchema = {
|
|
444
|
+
type: "object",
|
|
445
|
+
properties: {
|
|
446
|
+
workspaceId: {
|
|
447
|
+
type: "number",
|
|
448
|
+
description: "Workspace ID"
|
|
449
|
+
},
|
|
450
|
+
ids: {
|
|
451
|
+
type: "array",
|
|
452
|
+
items: { type: "number" },
|
|
453
|
+
description: "Array of account IDs to delete"
|
|
454
|
+
}
|
|
455
|
+
},
|
|
456
|
+
required: ["workspaceId", "ids"]
|
|
457
|
+
};
|
|
458
|
+
get schema() {
|
|
459
|
+
return {
|
|
460
|
+
name: this.name,
|
|
461
|
+
description: this.description,
|
|
462
|
+
inputSchema: this.inputSchema
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
async handle(params) {
|
|
466
|
+
if (!params.workspaceId || !params.ids || params.ids.length === 0) {
|
|
467
|
+
return {
|
|
468
|
+
content: [
|
|
469
|
+
{
|
|
470
|
+
type: "text",
|
|
471
|
+
text: "\u274C **Failed to delete accounts:**\n\n workspaceId and ids are required"
|
|
472
|
+
}
|
|
473
|
+
]
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
const { workspaceId, ids } = params;
|
|
477
|
+
const result = await request("/account/delete", {
|
|
478
|
+
method: "POST",
|
|
479
|
+
body: JSON.stringify({ workspaceId, ids })
|
|
480
|
+
});
|
|
481
|
+
let text = "";
|
|
482
|
+
if (result.code !== 0) {
|
|
483
|
+
text = `\u274C **Failed to delete accounts:**
|
|
484
|
+
|
|
485
|
+
error message: ${result.msg}`;
|
|
486
|
+
} else {
|
|
487
|
+
text = `\u2705 **Accounts Deleted Successfully**
|
|
488
|
+
|
|
489
|
+
**Count:** ${params.ids.length} account(s)
|
|
490
|
+
**Workspace:** ${params.workspaceId}
|
|
491
|
+
|
|
492
|
+
**Deleted Account IDs:**
|
|
493
|
+
${params.ids.map((id, index) => ` ${index + 1}. ${id}`).join("\n")}
|
|
494
|
+
|
|
495
|
+
\u26A0\uFE0F **Warning:** Deleted accounts cannot be recovered.`;
|
|
496
|
+
}
|
|
497
|
+
return {
|
|
498
|
+
content: [
|
|
499
|
+
{
|
|
500
|
+
type: "text",
|
|
501
|
+
text
|
|
502
|
+
}
|
|
503
|
+
]
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
var listAccounts = new ListAccounts();
|
|
508
|
+
var createAccount = new CreateAccount();
|
|
509
|
+
var batchCreateAccounts = new BatchCreateAccounts();
|
|
510
|
+
var modifyAccount = new ModifyAccount();
|
|
511
|
+
var deleteAccounts = new DeleteAccounts();
|
|
512
|
+
|
|
513
|
+
// src/modules/proxy.ts
|
|
514
|
+
var channelList = [
|
|
515
|
+
{
|
|
516
|
+
label: "IPRust.io",
|
|
517
|
+
type: "checkChannel",
|
|
518
|
+
value: "http://iprust.io/ip.json"
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
label: "IP-API",
|
|
522
|
+
type: "checkChannel",
|
|
523
|
+
value: "http://pro.ip-api.com/json?key=c1ulk9X5j8NKqTV"
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
label: "IP123.in",
|
|
527
|
+
type: "checkChannel",
|
|
528
|
+
value: "http://ip123.in/ip.json"
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
label: "IPinfo",
|
|
532
|
+
type: "checkChannel",
|
|
533
|
+
value: "http://ipinfo.io"
|
|
534
|
+
}
|
|
535
|
+
];
|
|
536
|
+
var ProxyList = class {
|
|
537
|
+
name = "roxy_list_proxies";
|
|
538
|
+
/**
|
|
539
|
+
* 仅当用户没有指定商店时调用
|
|
540
|
+
*/
|
|
541
|
+
description = "Get list of proxy configurations. If you want to get the list of proxies configurations you've bought, please use `roxy_store_proxies`.";
|
|
542
|
+
inputSchema = {
|
|
543
|
+
type: "object",
|
|
544
|
+
properties: {
|
|
545
|
+
workspaceId: {
|
|
546
|
+
type: "number",
|
|
547
|
+
description: "Workspace ID"
|
|
548
|
+
},
|
|
549
|
+
id: {
|
|
550
|
+
type: "number",
|
|
551
|
+
description: "Filter by proxy ID"
|
|
552
|
+
},
|
|
553
|
+
pageIndex: {
|
|
554
|
+
type: "number",
|
|
555
|
+
description: "Page index for pagination (default: 1)",
|
|
556
|
+
default: 1
|
|
557
|
+
},
|
|
558
|
+
pageSize: {
|
|
559
|
+
type: "number",
|
|
560
|
+
description: "Number of items per page (default: 15)",
|
|
561
|
+
default: 15
|
|
562
|
+
}
|
|
563
|
+
},
|
|
564
|
+
required: ["workspaceId"]
|
|
565
|
+
};
|
|
566
|
+
get schema() {
|
|
567
|
+
return {
|
|
568
|
+
name: this.name,
|
|
569
|
+
description: this.description,
|
|
570
|
+
inputSchema: this.inputSchema
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
async handle(params) {
|
|
574
|
+
const searchParams = new URLSearchParams();
|
|
575
|
+
searchParams.append("workspaceId", params.workspaceId);
|
|
576
|
+
if (params.id)
|
|
577
|
+
searchParams.append("id", params.id);
|
|
578
|
+
if (params.page_index)
|
|
579
|
+
searchParams.append("page_index", params.pageIndex);
|
|
580
|
+
if (params.page_size)
|
|
581
|
+
searchParams.append("page_size", params.pageSize);
|
|
582
|
+
if (!params.workspaceId) {
|
|
583
|
+
throw new Error("workspaceId is required");
|
|
584
|
+
}
|
|
585
|
+
const result = await request(`/proxy/list?${searchParams}`);
|
|
586
|
+
let text = "";
|
|
587
|
+
if (result.code === 0) {
|
|
588
|
+
const data = result.data;
|
|
589
|
+
const proxyListText = data.rows.length > 0 ? data.rows.map((proxy, index) => {
|
|
590
|
+
const statusText = proxy.checkStatus === 1 ? "\u2705 available" : proxy.checkStatus === 2 ? "\u274C unavailable" : "\u23F3 not checked";
|
|
591
|
+
const name = `proxy (id: ${proxy.id}) ${proxy.remark ? `remark: ${proxy.remark}` : ""}`;
|
|
592
|
+
const location = proxy.lastCountry ? `${proxy.lastCity || ""}${proxy.lastCity && proxy.lastCountry ? ", " : ""}${proxy.lastCountry}` : null;
|
|
593
|
+
let baseInfo = `${index + 1}. ${statusText} **${name}**
|
|
594
|
+
protocol: ${proxy.protocol || "N/A"}
|
|
595
|
+
ipType: ${proxy.ipType || "N/A"}
|
|
596
|
+
bind profile count: ${proxy.bindCount || "N/A"}
|
|
597
|
+
Detection channel: ${proxy.checkChannel || "N/A"}`;
|
|
598
|
+
const ipInfo = [];
|
|
599
|
+
if (proxy.host && proxy.port) {
|
|
600
|
+
ipInfo.push(...[proxy.host, ":", proxy.port]);
|
|
601
|
+
if (proxy.proxyUserName && proxy.proxyPassword) {
|
|
602
|
+
ipInfo.push(...["@", proxy.proxyUserName, ":", proxy.proxyPassword]);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
if (location) {
|
|
606
|
+
baseInfo += `
|
|
607
|
+
${ipInfo.length > 0 ? `${ipInfo.join("")}
|
|
608
|
+
` : ""}
|
|
609
|
+
\u{1F4CD} ${location}`;
|
|
610
|
+
}
|
|
611
|
+
return baseInfo;
|
|
612
|
+
}).join("\n\n") : "";
|
|
613
|
+
text = `\u{1F4CB} **proxy list** (total: ${data.total})
|
|
614
|
+
|
|
615
|
+
${proxyListText}`;
|
|
616
|
+
} else {
|
|
617
|
+
text = `\u274C **get proxy list failed**
|
|
618
|
+
|
|
619
|
+
${result.msg}`;
|
|
620
|
+
}
|
|
621
|
+
return { content: [{ type: "text", text }] };
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
var ProxyStore = class {
|
|
625
|
+
name = "roxy_store_proxies";
|
|
626
|
+
description = "Get list of proxy configurations in the Proxy Store";
|
|
627
|
+
inputSchema = {
|
|
628
|
+
type: "object",
|
|
629
|
+
properties: {
|
|
630
|
+
workspaceId: {
|
|
631
|
+
type: "number",
|
|
632
|
+
description: "Workspace ID"
|
|
633
|
+
},
|
|
634
|
+
pageIndex: {
|
|
635
|
+
type: "number",
|
|
636
|
+
description: "Page index for pagination (default: 1)",
|
|
637
|
+
default: 1
|
|
638
|
+
},
|
|
639
|
+
pageSize: {
|
|
640
|
+
type: "number",
|
|
641
|
+
description: "Number of items per page (default: 15)",
|
|
642
|
+
default: 15
|
|
643
|
+
},
|
|
644
|
+
type: {
|
|
645
|
+
type: "number",
|
|
646
|
+
description: "Type of proxies to get (0: list_use, 1: available_list)",
|
|
647
|
+
default: 0
|
|
648
|
+
}
|
|
649
|
+
},
|
|
650
|
+
required: ["workspaceId"]
|
|
651
|
+
};
|
|
652
|
+
get schema() {
|
|
653
|
+
return {
|
|
654
|
+
name: this.name,
|
|
655
|
+
description: this.description,
|
|
656
|
+
inputSchema: this.inputSchema
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
async handle(params) {
|
|
660
|
+
const searchParams = new URLSearchParams();
|
|
661
|
+
searchParams.append("workspaceId", params.workspaceId.toString());
|
|
662
|
+
if (params.page_index)
|
|
663
|
+
searchParams.append("page_index", params.page_index.toString());
|
|
664
|
+
if (params.page_size)
|
|
665
|
+
searchParams.append("page_size", params.page_size.toString());
|
|
666
|
+
if (params.type)
|
|
667
|
+
searchParams.append("type", params.type.toString());
|
|
668
|
+
const result = await request(`/proxy/bought_list?${searchParams}`);
|
|
669
|
+
let text = "";
|
|
670
|
+
if (result.code === 0) {
|
|
671
|
+
const data = result.data;
|
|
672
|
+
const proxyListText = data.rows.length > 0 ? data.rows.map((proxy, index) => {
|
|
673
|
+
const statusText = proxy.checkStatus === 1 ? "\u2705 available" : proxy.checkStatus === 2 ? "\u274C unavailable" : "\u23F3 not checked";
|
|
674
|
+
const name = `proxy (id: ${proxy.id}) ${proxy.remark ? `remark: ${proxy.remark}` : ""}`;
|
|
675
|
+
const location = proxy.lastCountry ? `${proxy.lastCity || ""}${proxy.lastCity && proxy.lastCountry ? ", " : ""}${proxy.lastCountry}` : null;
|
|
676
|
+
let baseInfo = `${index + 1}. ${statusText} **${name}**
|
|
677
|
+
protocol: ${proxy.protocol || "N/A"}
|
|
678
|
+
ipType: ${proxy.ipType || "N/A"}
|
|
679
|
+
bind profile count: ${proxy.bindCount || "N/A"}
|
|
680
|
+
Detection channel: ${proxy.checkChannel || "N/A"}
|
|
681
|
+
expire date: ${proxy.expireDate}`;
|
|
682
|
+
const ipInfo = [proxy.host, ":", proxy.port];
|
|
683
|
+
if (proxy.proxyUserName) {
|
|
684
|
+
ipInfo.push(...[proxy.proxyUserName, "@", proxy.proxyPassword]);
|
|
685
|
+
}
|
|
686
|
+
if (location) {
|
|
687
|
+
baseInfo += `
|
|
688
|
+
${ipInfo.join("")}
|
|
689
|
+
\u{1F4CD} ${location}`;
|
|
690
|
+
}
|
|
691
|
+
return baseInfo;
|
|
692
|
+
}).join("\n\n") : "";
|
|
693
|
+
text = `\u{1F4CB} **proxy store** (total: ${data.total})
|
|
694
|
+
|
|
695
|
+
${proxyListText}`;
|
|
696
|
+
} else {
|
|
697
|
+
text = `\u274C **get proxy store failed**
|
|
698
|
+
|
|
699
|
+
${result.msg}`;
|
|
700
|
+
}
|
|
701
|
+
return { content: [{ type: "text", text }] };
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
var CreateProxy = class {
|
|
705
|
+
name = "roxy_create_proxy";
|
|
706
|
+
description = "Create a new proxy configuration with automatic IP detection";
|
|
707
|
+
inputSchema = {
|
|
708
|
+
type: "object",
|
|
709
|
+
properties: {
|
|
710
|
+
workspaceId: {
|
|
711
|
+
type: "number",
|
|
712
|
+
description: "Workspace ID"
|
|
713
|
+
},
|
|
714
|
+
protocol: {
|
|
715
|
+
type: "string",
|
|
716
|
+
enum: ["HTTP", "HTTPS", "SOCKS5", "SSH"],
|
|
717
|
+
description: "Proxy protocol type"
|
|
718
|
+
},
|
|
719
|
+
host: {
|
|
720
|
+
type: "string",
|
|
721
|
+
description: "Proxy host/IP address"
|
|
722
|
+
},
|
|
723
|
+
port: {
|
|
724
|
+
type: "string",
|
|
725
|
+
description: "Proxy port"
|
|
726
|
+
},
|
|
727
|
+
proxyUserName: {
|
|
728
|
+
type: "string",
|
|
729
|
+
description: "Proxy username"
|
|
730
|
+
},
|
|
731
|
+
proxyPassword: {
|
|
732
|
+
type: "string",
|
|
733
|
+
description: "Proxy password"
|
|
734
|
+
},
|
|
735
|
+
ipType: {
|
|
736
|
+
type: "string",
|
|
737
|
+
enum: ["IPV4", "IPV6"],
|
|
738
|
+
description: "IP type (default: IPV4)"
|
|
739
|
+
},
|
|
740
|
+
checkChannel: {
|
|
741
|
+
type: "string",
|
|
742
|
+
enum: channelList.map((item) => item.label),
|
|
743
|
+
description: "IP detection channel (default: IP123.in)"
|
|
744
|
+
},
|
|
745
|
+
refreshUrl: {
|
|
746
|
+
type: "string",
|
|
747
|
+
description: "Refresh URL for dynamic proxies"
|
|
748
|
+
},
|
|
749
|
+
remark: {
|
|
750
|
+
type: "string",
|
|
751
|
+
description: "Proxy remark/notes"
|
|
752
|
+
}
|
|
753
|
+
},
|
|
754
|
+
required: ["workspaceId", "protocol", "host", "port"]
|
|
755
|
+
};
|
|
756
|
+
get schema() {
|
|
757
|
+
return {
|
|
758
|
+
name: this.name,
|
|
759
|
+
description: this.description,
|
|
760
|
+
inputSchema: this.inputSchema
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
async handle(params) {
|
|
764
|
+
if (!params.workspaceId || !params.protocol || !params.host || !params.port) {
|
|
765
|
+
return {
|
|
766
|
+
content: [
|
|
767
|
+
{
|
|
768
|
+
type: "text",
|
|
769
|
+
text: "\u274C **Failed to create proxy:**\n\n workspaceId, protocol, host, and port are required"
|
|
770
|
+
}
|
|
771
|
+
]
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
const { workspaceId, ipType = "IPV4", checkChannel = "IP123.in", ...proxyData } = params;
|
|
775
|
+
const proxyParams = {
|
|
776
|
+
workspaceId,
|
|
777
|
+
...proxyData,
|
|
778
|
+
ipType,
|
|
779
|
+
checkChannel: checkChannel ? channelList.find((item) => item.label === checkChannel)?.value : null,
|
|
780
|
+
proxyCategory: params.protocol
|
|
781
|
+
};
|
|
782
|
+
const result = await request("/proxy/create", {
|
|
783
|
+
method: "POST",
|
|
784
|
+
body: JSON.stringify(proxyParams)
|
|
785
|
+
});
|
|
786
|
+
let text = "";
|
|
787
|
+
if (result.code !== 0) {
|
|
788
|
+
if (result.data) {
|
|
789
|
+
text = `\u274C **Failed to create proxy:**
|
|
790
|
+
|
|
791
|
+
error message: ${result.msg}
|
|
792
|
+
|
|
793
|
+
${result.data.map((item) => ` - index: ${item.index}, error message: ${item.msg.join(", ")}`).join("\n")}`;
|
|
794
|
+
} else {
|
|
795
|
+
text = `\u274C **Failed to create proxy:**
|
|
796
|
+
|
|
797
|
+
error message: ${result.msg}`;
|
|
798
|
+
}
|
|
799
|
+
} else {
|
|
800
|
+
text = `\u2705 **Proxy Created Successfully**
|
|
801
|
+
|
|
802
|
+
**Protocol:** ${params.protocol}
|
|
803
|
+
**Host:** ${params.host}:${params.port}${params.proxyUserName ? `
|
|
804
|
+
**Username:** ${params.proxyUserName}` : ""}${params.remark ? `
|
|
805
|
+
**Remark:** ${params.remark}` : ""}${params.checkChannel ? `
|
|
806
|
+
**Check Channel:** ${params.checkChannel}` : ""}
|
|
807
|
+
|
|
808
|
+
*Proxy configuration created. IP detection will be performed automatically.*`;
|
|
809
|
+
}
|
|
810
|
+
return {
|
|
811
|
+
content: [
|
|
812
|
+
{
|
|
813
|
+
type: "text",
|
|
814
|
+
text
|
|
815
|
+
}
|
|
816
|
+
]
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
var BatchCreateProxies = class {
|
|
821
|
+
name = "roxy_batch_create_proxies";
|
|
822
|
+
description = "Batch create multiple proxy configurations";
|
|
823
|
+
inputSchema = {
|
|
824
|
+
type: "object",
|
|
825
|
+
properties: {
|
|
826
|
+
workspaceId: {
|
|
827
|
+
type: "number",
|
|
828
|
+
description: "Workspace ID"
|
|
829
|
+
},
|
|
830
|
+
// checkChannel: {
|
|
831
|
+
// type: 'string',
|
|
832
|
+
// enum: channelList.map(item => item.label),
|
|
833
|
+
// description: 'Default IP detection channel for all proxies',
|
|
834
|
+
// },
|
|
835
|
+
proxyList: {
|
|
836
|
+
type: "array",
|
|
837
|
+
description: "Array of proxy configurations",
|
|
838
|
+
items: {
|
|
839
|
+
type: "object",
|
|
840
|
+
properties: {
|
|
841
|
+
protocol: { type: "string", enum: ["HTTP", "HTTPS", "SOCKS5", "SSH"] },
|
|
842
|
+
host: { type: "string" },
|
|
843
|
+
port: { type: "string" },
|
|
844
|
+
proxyUserName: { type: "string" },
|
|
845
|
+
proxyPassword: { type: "string" },
|
|
846
|
+
ipType: { type: "string", enum: ["IPV4", "IPV6"] },
|
|
847
|
+
checkChannel: { type: "string", enum: channelList.map((item) => item.label) },
|
|
848
|
+
refreshUrl: { type: "string" },
|
|
849
|
+
remark: { type: "string" }
|
|
850
|
+
},
|
|
851
|
+
required: ["protocol", "host", "port"]
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
},
|
|
855
|
+
required: ["workspaceId", "proxyList"]
|
|
856
|
+
};
|
|
857
|
+
get schema() {
|
|
858
|
+
return {
|
|
859
|
+
name: this.name,
|
|
860
|
+
description: this.description,
|
|
861
|
+
inputSchema: this.inputSchema
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
async handle(params) {
|
|
865
|
+
if (!params.workspaceId || !params.proxyList || params.proxyList.length === 0) {
|
|
866
|
+
return {
|
|
867
|
+
content: [
|
|
868
|
+
{
|
|
869
|
+
type: "text",
|
|
870
|
+
text: "\u274C **Failed to batch create proxies:**\n\n workspaceId and proxyList are required"
|
|
871
|
+
}
|
|
872
|
+
]
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
const { workspaceId, proxyList: proxyList2 } = params;
|
|
876
|
+
proxyList2.forEach((item) => {
|
|
877
|
+
item.ipType = item.ipType ? item.ipType : "IPV4";
|
|
878
|
+
item.checkChannel = item.checkChannel ? channelList.find((channel) => channel.label === item.checkChannel)?.value : null;
|
|
879
|
+
});
|
|
880
|
+
const result = await request("/proxy/batch_create", {
|
|
881
|
+
method: "POST",
|
|
882
|
+
body: JSON.stringify({ workspaceId, proxyList: proxyList2 })
|
|
883
|
+
});
|
|
884
|
+
let text = "";
|
|
885
|
+
if (result.code !== 0) {
|
|
886
|
+
if (result.data) {
|
|
887
|
+
text = `\u274C **Failed to batch create proxies:**
|
|
888
|
+
|
|
889
|
+
error message: ${result.msg}
|
|
890
|
+
|
|
891
|
+
${result.data.map((item) => ` - index: ${item.index}, error message: ${item.msg.join(", ")}`).join("\n")}`;
|
|
892
|
+
} else {
|
|
893
|
+
text = `\u274C **Failed to batch create proxies:**
|
|
894
|
+
|
|
895
|
+
error message: ${result.msg}`;
|
|
896
|
+
}
|
|
897
|
+
} else {
|
|
898
|
+
text = `\u2705 **Batch Proxy Creation Successful**
|
|
899
|
+
|
|
900
|
+
**Count:** ${params.proxyList.length} proxy/proxies
|
|
901
|
+
**Workspace:** ${params.workspaceId}${params.checkChannel ? `
|
|
902
|
+
**Default Check Channel:** ${params.checkChannel}` : ""}
|
|
903
|
+
|
|
904
|
+
*All proxies have been created. IP detection will be performed automatically.*`;
|
|
905
|
+
}
|
|
906
|
+
return {
|
|
907
|
+
content: [
|
|
908
|
+
{
|
|
909
|
+
type: "text",
|
|
910
|
+
text
|
|
911
|
+
}
|
|
912
|
+
]
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
};
|
|
916
|
+
var DetectProxy = class {
|
|
917
|
+
name = "roxy_detect_proxy";
|
|
918
|
+
description = "Detect/test a proxy configuration and update its IP information";
|
|
919
|
+
inputSchema = {
|
|
920
|
+
type: "object",
|
|
921
|
+
properties: {
|
|
922
|
+
workspaceId: {
|
|
923
|
+
type: "number",
|
|
924
|
+
description: "Workspace ID"
|
|
925
|
+
},
|
|
926
|
+
id: {
|
|
927
|
+
type: "number",
|
|
928
|
+
description: "Proxy ID to detect"
|
|
929
|
+
}
|
|
930
|
+
},
|
|
931
|
+
required: ["workspaceId", "id"]
|
|
932
|
+
};
|
|
933
|
+
get schema() {
|
|
934
|
+
return {
|
|
935
|
+
name: this.name,
|
|
936
|
+
description: this.description,
|
|
937
|
+
inputSchema: this.inputSchema
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
async handle(params) {
|
|
941
|
+
if (!params.workspaceId || !params.id) {
|
|
942
|
+
return {
|
|
943
|
+
content: [
|
|
944
|
+
{
|
|
945
|
+
type: "text",
|
|
946
|
+
text: "\u274C **Failed to detect proxy:**\n\n workspaceId and id are required"
|
|
947
|
+
}
|
|
948
|
+
]
|
|
949
|
+
};
|
|
950
|
+
}
|
|
951
|
+
const { workspaceId, id } = params;
|
|
952
|
+
const result = await request("/proxy/detect", {
|
|
953
|
+
method: "POST",
|
|
954
|
+
body: JSON.stringify({ workspaceId, id })
|
|
955
|
+
});
|
|
956
|
+
let text = "";
|
|
957
|
+
if (result.code !== 0) {
|
|
958
|
+
text = `\u274C **Failed to detect proxy:**
|
|
959
|
+
|
|
960
|
+
error message: ${result.msg}`;
|
|
961
|
+
} else {
|
|
962
|
+
const data = result.data;
|
|
963
|
+
if (data) {
|
|
964
|
+
text = `\u2705 **Proxy Detection ${data.checkStatus === 1 ? "Success" : data.checkStatus === 2 ? "Failed" : ""}**
|
|
965
|
+
|
|
966
|
+
**ip address:** ${data.lastIp}
|
|
967
|
+
**country:** ${data.lastCountry}
|
|
968
|
+
**city:** ${data.lastCity}
|
|
969
|
+
**timezone:** ${data.timezone ? data.timezone : "N/A"}
|
|
970
|
+
`;
|
|
971
|
+
} else {
|
|
972
|
+
text = `\u2705 **Proxy Detection Started**
|
|
973
|
+
|
|
974
|
+
**Proxy ID:** ${params.id}
|
|
975
|
+
**Workspace:** ${params.workspaceId}
|
|
976
|
+
|
|
977
|
+
*Proxy detection is in progress. This may take a few seconds. Use \`roxy_list_proxies\` | \`roxy_store_proxies\` to check the updated status.*
|
|
978
|
+
`;
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
return {
|
|
982
|
+
content: [
|
|
983
|
+
{
|
|
984
|
+
type: "text",
|
|
985
|
+
text
|
|
986
|
+
}
|
|
987
|
+
]
|
|
988
|
+
};
|
|
989
|
+
}
|
|
990
|
+
};
|
|
991
|
+
var ModifyProxy = class {
|
|
992
|
+
name = "roxy_modify_proxy";
|
|
993
|
+
description = "Modify/update an existing proxy configuration";
|
|
994
|
+
inputSchema = {
|
|
995
|
+
type: "object",
|
|
996
|
+
properties: {
|
|
997
|
+
workspaceId: {
|
|
998
|
+
type: "number",
|
|
999
|
+
description: "Workspace ID"
|
|
1000
|
+
},
|
|
1001
|
+
id: {
|
|
1002
|
+
type: "number",
|
|
1003
|
+
description: "Proxy ID to modify"
|
|
1004
|
+
},
|
|
1005
|
+
protocol: {
|
|
1006
|
+
type: "string",
|
|
1007
|
+
enum: ["HTTP", "HTTPS", "SOCKS5", "SSH"],
|
|
1008
|
+
description: "Proxy protocol type"
|
|
1009
|
+
},
|
|
1010
|
+
host: {
|
|
1011
|
+
type: "string",
|
|
1012
|
+
description: "Proxy host/IP address"
|
|
1013
|
+
},
|
|
1014
|
+
port: {
|
|
1015
|
+
type: "string",
|
|
1016
|
+
description: "Proxy port"
|
|
1017
|
+
},
|
|
1018
|
+
proxyUserName: {
|
|
1019
|
+
type: "string",
|
|
1020
|
+
description: "Proxy username"
|
|
1021
|
+
},
|
|
1022
|
+
proxyPassword: {
|
|
1023
|
+
type: "string",
|
|
1024
|
+
description: "Proxy password"
|
|
1025
|
+
},
|
|
1026
|
+
ipType: {
|
|
1027
|
+
type: "string",
|
|
1028
|
+
enum: ["IPV4", "IPV6"],
|
|
1029
|
+
description: "IP type"
|
|
1030
|
+
},
|
|
1031
|
+
checkChannel: {
|
|
1032
|
+
type: "string",
|
|
1033
|
+
enum: channelList.map((item) => item.label),
|
|
1034
|
+
description: "IP detection channel"
|
|
1035
|
+
},
|
|
1036
|
+
refreshUrl: {
|
|
1037
|
+
type: "string",
|
|
1038
|
+
description: "Refresh URL for dynamic proxies"
|
|
1039
|
+
},
|
|
1040
|
+
remark: {
|
|
1041
|
+
type: "string",
|
|
1042
|
+
description: "Proxy remark/notes"
|
|
1043
|
+
}
|
|
1044
|
+
},
|
|
1045
|
+
required: ["workspaceId", "id"]
|
|
1046
|
+
};
|
|
1047
|
+
get schema() {
|
|
1048
|
+
return {
|
|
1049
|
+
name: this.name,
|
|
1050
|
+
description: this.description,
|
|
1051
|
+
inputSchema: this.inputSchema
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
async handle(params) {
|
|
1055
|
+
if (!params.workspaceId || !params.id) {
|
|
1056
|
+
return {
|
|
1057
|
+
content: [
|
|
1058
|
+
{
|
|
1059
|
+
type: "text",
|
|
1060
|
+
text: "\u274C **Failed to modify proxy:**\n\n workspaceId and id are required"
|
|
1061
|
+
}
|
|
1062
|
+
]
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
const { workspaceId, checkChannel = "IPRust.io", ...proxyData } = params;
|
|
1066
|
+
const proxyParams = {
|
|
1067
|
+
workspaceId,
|
|
1068
|
+
...proxyData,
|
|
1069
|
+
checkChannel: checkChannel ? channelList.find((item) => item.label === checkChannel)?.value : null,
|
|
1070
|
+
proxyCategory: params.protocol
|
|
1071
|
+
};
|
|
1072
|
+
const result = await request("/proxy/modify", {
|
|
1073
|
+
method: "POST",
|
|
1074
|
+
body: JSON.stringify(proxyParams)
|
|
1075
|
+
});
|
|
1076
|
+
let text = "";
|
|
1077
|
+
if (result.code !== 0) {
|
|
1078
|
+
text = `\u274C **Failed to modify proxy:**
|
|
1079
|
+
|
|
1080
|
+
error message: ${result.msg}`;
|
|
1081
|
+
} else {
|
|
1082
|
+
text = `\u2705 **Proxy Modified Successfully**
|
|
1083
|
+
|
|
1084
|
+
**Proxy ID:** ${params.id}${params.protocol ? `
|
|
1085
|
+
**Protocol:** ${params.protocol}` : ""}${params.host ? `
|
|
1086
|
+
**Host:** ${params.host}${params.port ? `:${params.port}` : ""}` : ""}${params.remark ? `
|
|
1087
|
+
**Remark:** ${params.remark}` : ""}
|
|
1088
|
+
|
|
1089
|
+
*Proxy configuration has been updated. Use \`roxy_detect_proxy\` to test the new configuration.*`;
|
|
1090
|
+
}
|
|
1091
|
+
return {
|
|
1092
|
+
content: [
|
|
1093
|
+
{
|
|
1094
|
+
type: "text",
|
|
1095
|
+
text
|
|
1096
|
+
}
|
|
1097
|
+
]
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
};
|
|
1101
|
+
var DeleteProxies = class {
|
|
1102
|
+
name = "roxy_delete_proxies";
|
|
1103
|
+
description = "Delete one or more proxy configurations";
|
|
1104
|
+
inputSchema = {
|
|
1105
|
+
type: "object",
|
|
1106
|
+
properties: {
|
|
1107
|
+
workspaceId: {
|
|
1108
|
+
type: "number",
|
|
1109
|
+
description: "Workspace ID"
|
|
1110
|
+
},
|
|
1111
|
+
ids: {
|
|
1112
|
+
type: "array",
|
|
1113
|
+
items: { type: "number" },
|
|
1114
|
+
description: "Array of proxy IDs to delete"
|
|
1115
|
+
}
|
|
1116
|
+
},
|
|
1117
|
+
required: ["workspaceId", "ids"]
|
|
1118
|
+
};
|
|
1119
|
+
get schema() {
|
|
1120
|
+
return {
|
|
1121
|
+
name: this.name,
|
|
1122
|
+
description: this.description,
|
|
1123
|
+
inputSchema: this.inputSchema
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
async handle(params) {
|
|
1127
|
+
if (!params.workspaceId || !params.ids || params.ids.length === 0) {
|
|
1128
|
+
return {
|
|
1129
|
+
content: [
|
|
1130
|
+
{
|
|
1131
|
+
type: "text",
|
|
1132
|
+
text: "\u274C **Failed to delete proxies:**\n\n workspaceId and ids are required"
|
|
1133
|
+
}
|
|
1134
|
+
]
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
const { workspaceId, ids } = params;
|
|
1138
|
+
const result = await request("/proxy/delete", {
|
|
1139
|
+
method: "POST",
|
|
1140
|
+
body: JSON.stringify({ workspaceId, ids })
|
|
1141
|
+
});
|
|
1142
|
+
let text = "";
|
|
1143
|
+
if (result.code !== 0) {
|
|
1144
|
+
text = `\u274C **Failed to delete proxies:**
|
|
1145
|
+
|
|
1146
|
+
error message: ${result.msg}`;
|
|
1147
|
+
} else {
|
|
1148
|
+
text = `\u2705 **Proxies Deleted Successfully**
|
|
1149
|
+
|
|
1150
|
+
**Count:** ${params.ids.length} proxy/proxies
|
|
1151
|
+
**Workspace:** ${params.workspaceId}
|
|
1152
|
+
|
|
1153
|
+
**Deleted Proxy IDs:**
|
|
1154
|
+
${params.ids.map((id, index) => ` ${index + 1}. ${id}`).join("\n")}
|
|
1155
|
+
|
|
1156
|
+
\u26A0\uFE0F **Warning:** Deleted proxies cannot be recovered.`;
|
|
1157
|
+
}
|
|
1158
|
+
return {
|
|
1159
|
+
content: [
|
|
1160
|
+
{
|
|
1161
|
+
type: "text",
|
|
1162
|
+
text
|
|
1163
|
+
}
|
|
1164
|
+
]
|
|
1165
|
+
};
|
|
1166
|
+
}
|
|
1167
|
+
};
|
|
1168
|
+
var proxyList = new ProxyList();
|
|
1169
|
+
var proxyStore = new ProxyStore();
|
|
1170
|
+
var createProxy = new CreateProxy();
|
|
1171
|
+
var batchCreateProxies = new BatchCreateProxies();
|
|
1172
|
+
var detectProxy = new DetectProxy();
|
|
1173
|
+
var modifyProxy = new ModifyProxy();
|
|
1174
|
+
var deleteProxies = new DeleteProxies();
|
|
1175
|
+
|
|
1176
|
+
// src/modules/browser.ts
|
|
1177
|
+
var osversion_windows = [
|
|
1178
|
+
{
|
|
1179
|
+
label: "11",
|
|
1180
|
+
type: "osVersion-Windows",
|
|
1181
|
+
value: "11"
|
|
1182
|
+
},
|
|
1183
|
+
{
|
|
1184
|
+
label: "10",
|
|
1185
|
+
type: "osVersion-Windows",
|
|
1186
|
+
value: "10"
|
|
1187
|
+
},
|
|
1188
|
+
{
|
|
1189
|
+
label: "8",
|
|
1190
|
+
type: "osVersion-Windows",
|
|
1191
|
+
value: "8"
|
|
1192
|
+
},
|
|
1193
|
+
{
|
|
1194
|
+
label: "7",
|
|
1195
|
+
type: "osVersion-Windows",
|
|
1196
|
+
value: "7"
|
|
1197
|
+
}
|
|
1198
|
+
];
|
|
1199
|
+
var osversion_macos = [
|
|
1200
|
+
{
|
|
1201
|
+
label: "15.3.2",
|
|
1202
|
+
type: "osVersion-macOS",
|
|
1203
|
+
value: "15.3.2"
|
|
1204
|
+
},
|
|
1205
|
+
{
|
|
1206
|
+
label: "15.3.1",
|
|
1207
|
+
type: "osVersion-macOS",
|
|
1208
|
+
value: "15.3.1"
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
label: "15.3",
|
|
1212
|
+
type: "osVersion-macOS",
|
|
1213
|
+
value: "15.3"
|
|
1214
|
+
},
|
|
1215
|
+
{
|
|
1216
|
+
label: "15.2",
|
|
1217
|
+
type: "osVersion-macOS",
|
|
1218
|
+
value: "15.2"
|
|
1219
|
+
},
|
|
1220
|
+
{
|
|
1221
|
+
label: "15.1",
|
|
1222
|
+
type: "osVersion-macOS",
|
|
1223
|
+
value: "15.1"
|
|
1224
|
+
},
|
|
1225
|
+
{
|
|
1226
|
+
label: "15.0.1",
|
|
1227
|
+
type: "osVersion-macOS",
|
|
1228
|
+
value: "15.0.1"
|
|
1229
|
+
},
|
|
1230
|
+
{
|
|
1231
|
+
label: "15.0",
|
|
1232
|
+
type: "osVersion-macOS",
|
|
1233
|
+
value: "15.0"
|
|
1234
|
+
},
|
|
1235
|
+
{
|
|
1236
|
+
label: "14.7.4",
|
|
1237
|
+
type: "osVersion-macOS",
|
|
1238
|
+
value: "14.7.4"
|
|
1239
|
+
},
|
|
1240
|
+
{
|
|
1241
|
+
label: "14.7.3",
|
|
1242
|
+
type: "osVersion-macOS",
|
|
1243
|
+
value: "14.7.3"
|
|
1244
|
+
},
|
|
1245
|
+
{
|
|
1246
|
+
label: "14.7.2",
|
|
1247
|
+
type: "osVersion-macOS",
|
|
1248
|
+
value: "14.7.2"
|
|
1249
|
+
},
|
|
1250
|
+
{
|
|
1251
|
+
label: "14.7.1",
|
|
1252
|
+
type: "osVersion-macOS",
|
|
1253
|
+
value: "14.7.1"
|
|
1254
|
+
},
|
|
1255
|
+
{
|
|
1256
|
+
label: "14.7",
|
|
1257
|
+
type: "osVersion-macOS",
|
|
1258
|
+
value: "14.7"
|
|
1259
|
+
},
|
|
1260
|
+
{
|
|
1261
|
+
label: "14.6.1",
|
|
1262
|
+
type: "osVersion-macOS",
|
|
1263
|
+
value: "14.6.1"
|
|
1264
|
+
},
|
|
1265
|
+
{
|
|
1266
|
+
label: "14.6",
|
|
1267
|
+
type: "osVersion-macOS",
|
|
1268
|
+
value: "14.6"
|
|
1269
|
+
},
|
|
1270
|
+
{
|
|
1271
|
+
label: "14.5",
|
|
1272
|
+
type: "osVersion-macOS",
|
|
1273
|
+
value: "14.5"
|
|
1274
|
+
},
|
|
1275
|
+
{
|
|
1276
|
+
label: "14.4.1",
|
|
1277
|
+
type: "osVersion-macOS",
|
|
1278
|
+
value: "14.4.1"
|
|
1279
|
+
},
|
|
1280
|
+
{
|
|
1281
|
+
label: "14.4",
|
|
1282
|
+
type: "osVersion-macOS",
|
|
1283
|
+
value: "14.4"
|
|
1284
|
+
},
|
|
1285
|
+
{
|
|
1286
|
+
label: "14.3.1",
|
|
1287
|
+
type: "osVersion-macOS",
|
|
1288
|
+
value: "14.3.1"
|
|
1289
|
+
},
|
|
1290
|
+
{
|
|
1291
|
+
label: "14.3",
|
|
1292
|
+
type: "osVersion-macOS",
|
|
1293
|
+
value: "14.3"
|
|
1294
|
+
},
|
|
1295
|
+
{
|
|
1296
|
+
label: "14.2.1",
|
|
1297
|
+
type: "osVersion-macOS",
|
|
1298
|
+
value: "14.2.1"
|
|
1299
|
+
},
|
|
1300
|
+
{
|
|
1301
|
+
label: "14.2",
|
|
1302
|
+
type: "osVersion-macOS",
|
|
1303
|
+
value: "14.2"
|
|
1304
|
+
},
|
|
1305
|
+
{
|
|
1306
|
+
label: "14.1",
|
|
1307
|
+
type: "osVersion-macOS",
|
|
1308
|
+
value: "14.1"
|
|
1309
|
+
},
|
|
1310
|
+
{
|
|
1311
|
+
label: "13.7.4",
|
|
1312
|
+
type: "osVersion-macOS",
|
|
1313
|
+
value: "13.7.4"
|
|
1314
|
+
},
|
|
1315
|
+
{
|
|
1316
|
+
label: "13.7.3",
|
|
1317
|
+
type: "osVersion-macOS",
|
|
1318
|
+
value: "13.7.3"
|
|
1319
|
+
},
|
|
1320
|
+
{
|
|
1321
|
+
label: "13.7.2",
|
|
1322
|
+
type: "osVersion-macOS",
|
|
1323
|
+
value: "13.7.2"
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
label: "13.7.1",
|
|
1327
|
+
type: "osVersion-macOS",
|
|
1328
|
+
value: "13.7.1"
|
|
1329
|
+
},
|
|
1330
|
+
{
|
|
1331
|
+
label: "13.7",
|
|
1332
|
+
type: "osVersion-macOS",
|
|
1333
|
+
value: "13.7"
|
|
1334
|
+
},
|
|
1335
|
+
{
|
|
1336
|
+
label: "ALL",
|
|
1337
|
+
type: "osVersion-macOS",
|
|
1338
|
+
value: "ALL"
|
|
1339
|
+
}
|
|
1340
|
+
];
|
|
1341
|
+
var osversion_linux = [
|
|
1342
|
+
{
|
|
1343
|
+
label: "ALL",
|
|
1344
|
+
type: "osVersion-Linux",
|
|
1345
|
+
value: "ALL"
|
|
1346
|
+
}
|
|
1347
|
+
];
|
|
1348
|
+
var osversion_android = [
|
|
1349
|
+
{
|
|
1350
|
+
label: "15",
|
|
1351
|
+
type: "osVersion-Android",
|
|
1352
|
+
value: "15"
|
|
1353
|
+
},
|
|
1354
|
+
{
|
|
1355
|
+
label: "14",
|
|
1356
|
+
type: "osVersion-Android",
|
|
1357
|
+
value: "14"
|
|
1358
|
+
},
|
|
1359
|
+
{
|
|
1360
|
+
label: "13",
|
|
1361
|
+
type: "osVersion-Android",
|
|
1362
|
+
value: "13"
|
|
1363
|
+
},
|
|
1364
|
+
{
|
|
1365
|
+
label: "12",
|
|
1366
|
+
type: "osVersion-Android",
|
|
1367
|
+
value: "12"
|
|
1368
|
+
},
|
|
1369
|
+
{
|
|
1370
|
+
label: "11",
|
|
1371
|
+
type: "osVersion-Android",
|
|
1372
|
+
value: "11"
|
|
1373
|
+
},
|
|
1374
|
+
{
|
|
1375
|
+
label: "10",
|
|
1376
|
+
type: "osVersion-Android",
|
|
1377
|
+
value: "10"
|
|
1378
|
+
},
|
|
1379
|
+
{
|
|
1380
|
+
label: "9",
|
|
1381
|
+
type: "osVersion-Android",
|
|
1382
|
+
value: "9"
|
|
1383
|
+
}
|
|
1384
|
+
];
|
|
1385
|
+
var osversion_ios = [
|
|
1386
|
+
{
|
|
1387
|
+
label: "18.2",
|
|
1388
|
+
type: "osVersion-IOS",
|
|
1389
|
+
value: "18.2"
|
|
1390
|
+
},
|
|
1391
|
+
{
|
|
1392
|
+
label: "18.1",
|
|
1393
|
+
type: "osVersion-IOS",
|
|
1394
|
+
value: "18.1"
|
|
1395
|
+
},
|
|
1396
|
+
{
|
|
1397
|
+
label: "18.0",
|
|
1398
|
+
type: "osVersion-IOS",
|
|
1399
|
+
value: "18.0"
|
|
1400
|
+
},
|
|
1401
|
+
{
|
|
1402
|
+
label: "17.0",
|
|
1403
|
+
type: "osVersion-IOS",
|
|
1404
|
+
value: "17.0"
|
|
1405
|
+
},
|
|
1406
|
+
{
|
|
1407
|
+
label: "16.6",
|
|
1408
|
+
type: "osVersion-IOS",
|
|
1409
|
+
value: "16.6"
|
|
1410
|
+
},
|
|
1411
|
+
{
|
|
1412
|
+
label: "16.5",
|
|
1413
|
+
type: "osVersion-IOS",
|
|
1414
|
+
value: "16.5"
|
|
1415
|
+
},
|
|
1416
|
+
{
|
|
1417
|
+
label: "16.4",
|
|
1418
|
+
type: "osVersion-IOS",
|
|
1419
|
+
value: "16.4"
|
|
1420
|
+
},
|
|
1421
|
+
{
|
|
1422
|
+
label: "16.3",
|
|
1423
|
+
type: "osVersion-IOS",
|
|
1424
|
+
value: "16.3"
|
|
1425
|
+
},
|
|
1426
|
+
{
|
|
1427
|
+
label: "16.2",
|
|
1428
|
+
type: "osVersion-IOS",
|
|
1429
|
+
value: "16.2"
|
|
1430
|
+
},
|
|
1431
|
+
{
|
|
1432
|
+
label: "16.1",
|
|
1433
|
+
type: "osVersion-IOS",
|
|
1434
|
+
value: "16.1"
|
|
1435
|
+
},
|
|
1436
|
+
{
|
|
1437
|
+
label: "16.0",
|
|
1438
|
+
type: "osVersion-IOS",
|
|
1439
|
+
value: "16.0"
|
|
1440
|
+
},
|
|
1441
|
+
{
|
|
1442
|
+
label: "15.7",
|
|
1443
|
+
type: "osVersion-IOS",
|
|
1444
|
+
value: "15.7"
|
|
1445
|
+
},
|
|
1446
|
+
{
|
|
1447
|
+
label: "15.6",
|
|
1448
|
+
type: "osVersion-IOS",
|
|
1449
|
+
value: "15.6"
|
|
1450
|
+
},
|
|
1451
|
+
{
|
|
1452
|
+
label: "15.5",
|
|
1453
|
+
type: "osVersion-IOS",
|
|
1454
|
+
value: "15.5"
|
|
1455
|
+
},
|
|
1456
|
+
{
|
|
1457
|
+
label: "15.4",
|
|
1458
|
+
type: "osVersion-IOS",
|
|
1459
|
+
value: "15.4"
|
|
1460
|
+
},
|
|
1461
|
+
{
|
|
1462
|
+
label: "15.3",
|
|
1463
|
+
type: "osVersion-IOS",
|
|
1464
|
+
value: "15.3"
|
|
1465
|
+
},
|
|
1466
|
+
{
|
|
1467
|
+
label: "15.2",
|
|
1468
|
+
type: "osVersion-IOS",
|
|
1469
|
+
value: "15.2"
|
|
1470
|
+
},
|
|
1471
|
+
{
|
|
1472
|
+
label: "15.1",
|
|
1473
|
+
type: "osVersion-IOS",
|
|
1474
|
+
value: "15.1"
|
|
1475
|
+
},
|
|
1476
|
+
{
|
|
1477
|
+
label: "15.0",
|
|
1478
|
+
type: "osVersion-IOS",
|
|
1479
|
+
value: "15.0"
|
|
1480
|
+
},
|
|
1481
|
+
{
|
|
1482
|
+
label: "14.7",
|
|
1483
|
+
type: "osVersion-IOS",
|
|
1484
|
+
value: "14.7"
|
|
1485
|
+
},
|
|
1486
|
+
{
|
|
1487
|
+
label: "14.6",
|
|
1488
|
+
type: "osVersion-IOS",
|
|
1489
|
+
value: "14.6"
|
|
1490
|
+
},
|
|
1491
|
+
{
|
|
1492
|
+
label: "14.5",
|
|
1493
|
+
type: "osVersion-IOS",
|
|
1494
|
+
value: "14.5"
|
|
1495
|
+
},
|
|
1496
|
+
{
|
|
1497
|
+
label: "14.4",
|
|
1498
|
+
type: "osVersion-IOS",
|
|
1499
|
+
value: "14.4"
|
|
1500
|
+
},
|
|
1501
|
+
{
|
|
1502
|
+
label: "14.3",
|
|
1503
|
+
type: "osVersion-IOS",
|
|
1504
|
+
value: "14.3"
|
|
1505
|
+
},
|
|
1506
|
+
{
|
|
1507
|
+
label: "14.2",
|
|
1508
|
+
type: "osVersion-IOS",
|
|
1509
|
+
value: "14.2"
|
|
1510
|
+
},
|
|
1511
|
+
{
|
|
1512
|
+
label: "14.1",
|
|
1513
|
+
type: "osVersion-IOS",
|
|
1514
|
+
value: "14.1"
|
|
1515
|
+
},
|
|
1516
|
+
{
|
|
1517
|
+
label: "14.0",
|
|
1518
|
+
type: "osVersion-IOS",
|
|
1519
|
+
value: "14.0"
|
|
1520
|
+
}
|
|
1521
|
+
];
|
|
1522
|
+
var coreVersion = [
|
|
1523
|
+
{
|
|
1524
|
+
label: "RoxyChrome 144",
|
|
1525
|
+
type: "coreVersion",
|
|
1526
|
+
value: "144"
|
|
1527
|
+
},
|
|
1528
|
+
{
|
|
1529
|
+
label: "RoxyChrome 143",
|
|
1530
|
+
type: "coreVersion",
|
|
1531
|
+
value: "143"
|
|
1532
|
+
},
|
|
1533
|
+
{
|
|
1534
|
+
label: "RoxyChrome 142",
|
|
1535
|
+
type: "coreVersion",
|
|
1536
|
+
value: "142"
|
|
1537
|
+
},
|
|
1538
|
+
{
|
|
1539
|
+
label: "RoxyChrome 141",
|
|
1540
|
+
type: "coreVersion",
|
|
1541
|
+
value: "141"
|
|
1542
|
+
},
|
|
1543
|
+
{
|
|
1544
|
+
label: "RoxyChrome 140",
|
|
1545
|
+
type: "coreVersion",
|
|
1546
|
+
value: "140"
|
|
1547
|
+
},
|
|
1548
|
+
{
|
|
1549
|
+
label: "RoxyChrome 139",
|
|
1550
|
+
type: "coreVersion",
|
|
1551
|
+
value: "139"
|
|
1552
|
+
},
|
|
1553
|
+
{
|
|
1554
|
+
label: "RoxyChrome 138",
|
|
1555
|
+
type: "coreVersion",
|
|
1556
|
+
value: "138"
|
|
1557
|
+
},
|
|
1558
|
+
{
|
|
1559
|
+
label: "RoxyChrome 137",
|
|
1560
|
+
type: "coreVersion",
|
|
1561
|
+
value: "137"
|
|
1562
|
+
},
|
|
1563
|
+
{
|
|
1564
|
+
label: "RoxyChrome 136",
|
|
1565
|
+
type: "coreVersion",
|
|
1566
|
+
value: "136"
|
|
1567
|
+
},
|
|
1568
|
+
{
|
|
1569
|
+
label: "RoxyChrome 135",
|
|
1570
|
+
type: "coreVersion",
|
|
1571
|
+
value: "135"
|
|
1572
|
+
},
|
|
1573
|
+
{
|
|
1574
|
+
label: "RoxyChrome 133",
|
|
1575
|
+
type: "coreVersion",
|
|
1576
|
+
value: "133"
|
|
1577
|
+
},
|
|
1578
|
+
{
|
|
1579
|
+
label: "RoxyChrome 130",
|
|
1580
|
+
type: "coreVersion",
|
|
1581
|
+
value: "130"
|
|
1582
|
+
},
|
|
1583
|
+
{
|
|
1584
|
+
label: "RoxyChrome 125",
|
|
1585
|
+
type: "coreVersion",
|
|
1586
|
+
value: "125"
|
|
1587
|
+
},
|
|
1588
|
+
{
|
|
1589
|
+
label: "RoxyChrome 117",
|
|
1590
|
+
type: "coreVersion",
|
|
1591
|
+
value: "117"
|
|
1592
|
+
},
|
|
1593
|
+
{
|
|
1594
|
+
label: "RoxyChrome 109",
|
|
1595
|
+
type: "coreVersion",
|
|
1596
|
+
value: "109"
|
|
1597
|
+
}
|
|
1598
|
+
];
|
|
1599
|
+
function osVersionString() {
|
|
1600
|
+
return `Windows: ${osversion_windows.map((item) => item.value).join(",")}; macOS: ${osversion_macos.map((item) => item.value).join(",")}; Linux: ${osversion_linux.map((item) => item.value).join(",")}; Android: ${osversion_android.map((item) => item.value).join(",")}; IOS: ${osversion_ios.map((item) => item.value).join(",")}`;
|
|
1601
|
+
}
|
|
1602
|
+
var CreateBrowser = class {
|
|
1603
|
+
name = "roxy_create_browser";
|
|
1604
|
+
description = "Create a browser with complete configuration control - for expert users needing full parameter access";
|
|
1605
|
+
inputSchema = {
|
|
1606
|
+
type: "object",
|
|
1607
|
+
properties: {
|
|
1608
|
+
workspaceId: {
|
|
1609
|
+
type: "number",
|
|
1610
|
+
description: "Workspace ID"
|
|
1611
|
+
},
|
|
1612
|
+
windowName: {
|
|
1613
|
+
type: "string",
|
|
1614
|
+
description: "Browser window name"
|
|
1615
|
+
},
|
|
1616
|
+
coreVersion: {
|
|
1617
|
+
type: "string",
|
|
1618
|
+
enum: coreVersion.map((item) => item.value),
|
|
1619
|
+
description: "Browser core version. If not provided, the latest available core version will be used."
|
|
1620
|
+
},
|
|
1621
|
+
os: {
|
|
1622
|
+
type: "string",
|
|
1623
|
+
enum: ["Windows", "macOS", "Linux", "IOS", "Android"],
|
|
1624
|
+
description: "Operating system (default: Windows)"
|
|
1625
|
+
},
|
|
1626
|
+
osVersion: {
|
|
1627
|
+
type: "string",
|
|
1628
|
+
description: osVersionString()
|
|
1629
|
+
},
|
|
1630
|
+
userAgent: {
|
|
1631
|
+
type: "string",
|
|
1632
|
+
description: "Custom user agent"
|
|
1633
|
+
},
|
|
1634
|
+
cookie: {
|
|
1635
|
+
type: "array",
|
|
1636
|
+
description: "Cookie list",
|
|
1637
|
+
items: { type: "object" }
|
|
1638
|
+
},
|
|
1639
|
+
searchEngine: {
|
|
1640
|
+
type: "string",
|
|
1641
|
+
enum: ["Google", "Microsoft Bing", "Yahoo", "Yandex", "DuckDuckGo"],
|
|
1642
|
+
description: "Default search engine"
|
|
1643
|
+
},
|
|
1644
|
+
labelIds: {
|
|
1645
|
+
type: "array",
|
|
1646
|
+
items: { type: "number" },
|
|
1647
|
+
description: "Label IDs to assign"
|
|
1648
|
+
},
|
|
1649
|
+
defaultOpenUrl: {
|
|
1650
|
+
type: "array",
|
|
1651
|
+
items: { type: "string" },
|
|
1652
|
+
description: "URLs to open by default"
|
|
1653
|
+
},
|
|
1654
|
+
windowRemark: {
|
|
1655
|
+
type: "string",
|
|
1656
|
+
description: "Window remarks/notes"
|
|
1657
|
+
},
|
|
1658
|
+
projectId: {
|
|
1659
|
+
type: "number",
|
|
1660
|
+
description: "Project ID"
|
|
1661
|
+
},
|
|
1662
|
+
windowPlatformList: {
|
|
1663
|
+
type: "array",
|
|
1664
|
+
items: {
|
|
1665
|
+
type: "object",
|
|
1666
|
+
properties: {
|
|
1667
|
+
// 平台账号id,非必传,通过平台账号列表接口【roxy_list_accounts】获取,可以判定已在平台账号列表中的账号,有该参数时其他参数不需要传。
|
|
1668
|
+
id: { type: "number", description: "Platform account ID, which can be obtained from [roxy_list_accounts] (field: id). Used to bind an account that already exists in the platform account list. If this parameter is provided, other parameters do not need to be passed." },
|
|
1669
|
+
platformUrl: { type: "string", description: "Platform URL" },
|
|
1670
|
+
platformUserName: { type: "string", description: "Platform username" },
|
|
1671
|
+
platformPassword: { type: "string", description: "Platform password" },
|
|
1672
|
+
platformEfa: { type: "string", description: "Platform EFA" },
|
|
1673
|
+
platformRemarks: { type: "string", description: "Platform remarks" }
|
|
1674
|
+
}
|
|
1675
|
+
},
|
|
1676
|
+
description: "Platform account information"
|
|
1677
|
+
},
|
|
1678
|
+
proxyInfo: {
|
|
1679
|
+
type: "object",
|
|
1680
|
+
description: "Complete proxy configuration object",
|
|
1681
|
+
properties: {
|
|
1682
|
+
// 如果有 moduleId ,则其他参数不可传递 (moduleId 可通过 roxy_list_proxies 或 roxy_store_proxies 获取) 优先使用该参数来绑定代理IP
|
|
1683
|
+
moduleId: { type: "number", description: `If moduleId is provided, no other parameters may be passed. (moduleId can be obtained via ${proxyList.name} or ${proxyStore.name}. field: id) Priority to use this parameter to bind proxy IP` },
|
|
1684
|
+
proxyMethod: { type: "string", enum: ["custom", "choose", "api"] },
|
|
1685
|
+
proxyCategory: { type: "string", enum: ["noproxy", "HTTP", "HTTPS", "SOCKS5", "SSH"] },
|
|
1686
|
+
ipType: { type: "string", enum: ["IPV4", "IPV6"] },
|
|
1687
|
+
protocol: { type: "string", enum: ["HTTP", "HTTPS", "SOCKS5"] },
|
|
1688
|
+
host: { type: "string" },
|
|
1689
|
+
port: { type: "string" },
|
|
1690
|
+
proxyUserName: { type: "string" },
|
|
1691
|
+
proxyPassword: { type: "string" },
|
|
1692
|
+
refreshUrl: { type: "string" },
|
|
1693
|
+
checkChannel: { type: "string", enum: ["IPRust.io", "IP-API", "IP123.in"] }
|
|
1694
|
+
}
|
|
1695
|
+
},
|
|
1696
|
+
fingerInfo: {
|
|
1697
|
+
type: "object",
|
|
1698
|
+
description: "Complete fingerprint configuration",
|
|
1699
|
+
properties: {
|
|
1700
|
+
// Language and timezone
|
|
1701
|
+
isLanguageBaseIp: { type: "boolean", description: "Follow IP for browser language" },
|
|
1702
|
+
language: { type: "string", description: "Custom browser language" },
|
|
1703
|
+
isDisplayLanguageBaseIp: { type: "boolean", description: "Follow IP for display language" },
|
|
1704
|
+
displayLanguage: { type: "string", description: "Custom display language" },
|
|
1705
|
+
isTimeZone: { type: "boolean", description: "Follow IP for timezone" },
|
|
1706
|
+
timeZone: { type: "string", description: "Custom timezone" },
|
|
1707
|
+
// Geolocation
|
|
1708
|
+
position: { type: "number", enum: [0, 1, 2], description: "Geolocation prompt: 0=ask, 1=allow, 2=deny" },
|
|
1709
|
+
isPositionBaseIp: { type: "boolean", description: "Follow IP for geolocation" },
|
|
1710
|
+
longitude: { type: "string", description: "Custom longitude" },
|
|
1711
|
+
latitude: { type: "string", description: "Custom latitude" },
|
|
1712
|
+
precisionPos: { type: "string", description: "Precision in meters" },
|
|
1713
|
+
// Media settings
|
|
1714
|
+
forbidAudio: { type: "boolean", description: "Enable/disable sound" },
|
|
1715
|
+
forbidImage: { type: "boolean", description: "Enable/disable image loading" },
|
|
1716
|
+
forbiddenPictureSize: { type: "number", description: "Image load size threshold (bytes). When forbidImage is false, set forbiddenPictureSize = 0 to disable all image loading. Default 0." },
|
|
1717
|
+
forbidMedia: { type: "boolean", description: "Enable/disable video playback" },
|
|
1718
|
+
// Window settings
|
|
1719
|
+
openWidth: { type: "string", description: "Window width" },
|
|
1720
|
+
openHeight: { type: "string", description: "Window height" },
|
|
1721
|
+
openBookmarks: { type: "boolean", description: "Enable bookmarks" },
|
|
1722
|
+
positionSwitch: { type: "boolean", description: "Window position switch" },
|
|
1723
|
+
windowRatioPosition: { type: "string", description: "Window position ratio" },
|
|
1724
|
+
isDisplayName: { type: "boolean", description: "Show window name in title bar" },
|
|
1725
|
+
// Sync settings
|
|
1726
|
+
syncBookmark: { type: "boolean", description: "Sync bookmarks" },
|
|
1727
|
+
syncHistory: { type: "boolean", description: "Sync history" },
|
|
1728
|
+
syncTab: { type: "boolean", description: "Sync tabs" },
|
|
1729
|
+
syncCookie: { type: "boolean", description: "Sync cookies" },
|
|
1730
|
+
syncExtensions: { type: "boolean", description: "Sync extensions" },
|
|
1731
|
+
syncPassword: { type: "boolean", description: "Sync saved passwords" },
|
|
1732
|
+
syncIndexedDb: { type: "boolean", description: "Sync IndexedDB" },
|
|
1733
|
+
syncLocalStorage: { type: "boolean", description: "Sync LocalStorage" },
|
|
1734
|
+
// Cleanup settings
|
|
1735
|
+
clearCacheFile: { type: "boolean", description: "Clear cache files on startup" },
|
|
1736
|
+
clearCookie: { type: "boolean", description: "Clear cookies on startup" },
|
|
1737
|
+
clearLocalStorage: { type: "boolean", description: "Clear LocalStorage on startup" },
|
|
1738
|
+
// Advanced settings
|
|
1739
|
+
randomFingerprint: { type: "boolean", description: "Generate random fingerprint" },
|
|
1740
|
+
forbidSavePassword: { type: "boolean", description: "Disable password save prompts" },
|
|
1741
|
+
stopOpenNet: { type: "boolean", description: "Stop opening if network fails" },
|
|
1742
|
+
stopOpenIP: { type: "boolean", description: "Stop opening if IP changes" },
|
|
1743
|
+
stopOpenPosition: { type: "boolean", description: "Stop opening if IP location changes" },
|
|
1744
|
+
openWorkbench: { type: "number", enum: [0, 1, 2], description: "Open workbench: 0=close, 1=open, 2=follow app" },
|
|
1745
|
+
// Display settings
|
|
1746
|
+
resolutionType: { type: "boolean", description: "Custom resolution vs follow system" },
|
|
1747
|
+
resolutionX: { type: "string", description: "Custom resolution width" },
|
|
1748
|
+
resolutionY: { type: "string", description: "Custom resolution height" },
|
|
1749
|
+
fontType: { type: "boolean", description: "Random fonts vs system fonts" },
|
|
1750
|
+
// Browser fingerprint settings
|
|
1751
|
+
webRTC: { type: "number", enum: [0, 1, 2], description: "WebRTC: 0=replace, 1=real, 2=disable" },
|
|
1752
|
+
webGL: { type: "boolean", description: "WebGL: random vs real" },
|
|
1753
|
+
webGLInfo: { type: "boolean", description: "WebGL info: custom vs real" },
|
|
1754
|
+
webGLManufacturer: { type: "string", description: "Custom WebGL manufacturer" },
|
|
1755
|
+
webGLRender: { type: "string", description: "Custom WebGL renderer" },
|
|
1756
|
+
webGpu: { type: "string", enum: ["webgl", "real", "block"], description: "WebGPU setting" },
|
|
1757
|
+
canvas: { type: "boolean", description: "Canvas: random vs real" },
|
|
1758
|
+
audioContext: { type: "boolean", description: "AudioContext: random vs real" },
|
|
1759
|
+
speechVoices: { type: "boolean", description: "Speech Voices: random vs real" },
|
|
1760
|
+
doNotTrack: { type: "boolean", description: "Enable Do Not Track" },
|
|
1761
|
+
clientRects: { type: "boolean", description: "ClientRects: random vs real" },
|
|
1762
|
+
deviceInfo: { type: "boolean", description: "Media devices: random vs real" },
|
|
1763
|
+
deviceNameSwitch: { type: "boolean", description: "Device names: random vs real" },
|
|
1764
|
+
macInfo: { type: "boolean", description: "MAC address: custom vs real" },
|
|
1765
|
+
// Hardware settings
|
|
1766
|
+
hardwareConcurrent: { type: "string", description: "Hardware concurrency" },
|
|
1767
|
+
deviceMemory: { type: "string", description: "Device memory" },
|
|
1768
|
+
// Security settings
|
|
1769
|
+
disableSsl: { type: "boolean", description: "SSL fingerprint settings" },
|
|
1770
|
+
disableSslList: { type: "array", items: { type: "string" }, description: "SSL feature list" },
|
|
1771
|
+
portScanProtect: { type: "boolean", description: "Port scan protection" },
|
|
1772
|
+
portScanList: { type: "string", description: "Port scan whitelist" },
|
|
1773
|
+
useGpu: { type: "boolean", description: "Use GPU acceleration" },
|
|
1774
|
+
sandboxPermission: { type: "boolean", description: "Disable sandbox" },
|
|
1775
|
+
startupParam: { type: "string", description: "Browser startup parameters (--headless=new startup headless)" }
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
},
|
|
1779
|
+
required: ["workspaceId"]
|
|
1780
|
+
};
|
|
1781
|
+
get schema() {
|
|
1782
|
+
return {
|
|
1783
|
+
name: this.name,
|
|
1784
|
+
description: this.description,
|
|
1785
|
+
inputSchema: this.inputSchema
|
|
1786
|
+
};
|
|
1787
|
+
}
|
|
1788
|
+
async handle(params) {
|
|
1789
|
+
const result = await request("/browser/create", {
|
|
1790
|
+
method: "POST",
|
|
1791
|
+
body: JSON.stringify(params)
|
|
1792
|
+
});
|
|
1793
|
+
const data = result.data;
|
|
1794
|
+
let text = "";
|
|
1795
|
+
if (result.code !== 0) {
|
|
1796
|
+
text = `\u274C **Failed to create browser:**
|
|
1797
|
+
|
|
1798
|
+
error message: ${result.msg}`;
|
|
1799
|
+
} else {
|
|
1800
|
+
text = `\u2705 **Simple Browser Created**
|
|
1801
|
+
|
|
1802
|
+
**Browser ID:** \`${data.dirId}\`
|
|
1803
|
+
*Use this browser ID with \`roxy_open_browsers\` to start the browser and get CDP endpoints for automation.*`;
|
|
1804
|
+
}
|
|
1805
|
+
return {
|
|
1806
|
+
content: [
|
|
1807
|
+
{
|
|
1808
|
+
type: "text",
|
|
1809
|
+
text
|
|
1810
|
+
}
|
|
1811
|
+
]
|
|
1812
|
+
};
|
|
1813
|
+
}
|
|
1814
|
+
};
|
|
1815
|
+
var createBrowser = new CreateBrowser();
|
|
1816
|
+
var BatchCreateBrowsers = class {
|
|
1817
|
+
name = "roxy_batch_create_browsers";
|
|
1818
|
+
description = "Create multiple browsers in batch by passing an array of browser configurations";
|
|
1819
|
+
inputSchema = {
|
|
1820
|
+
type: "object",
|
|
1821
|
+
properties: {
|
|
1822
|
+
browsers: {
|
|
1823
|
+
type: "array",
|
|
1824
|
+
description: "Array of browser configuration objects to create",
|
|
1825
|
+
items: {
|
|
1826
|
+
type: "object",
|
|
1827
|
+
properties: createBrowser.inputSchema.properties,
|
|
1828
|
+
required: ["workspaceId"]
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
},
|
|
1832
|
+
required: ["browsers"]
|
|
1833
|
+
};
|
|
1834
|
+
get schema() {
|
|
1835
|
+
return {
|
|
1836
|
+
name: this.name,
|
|
1837
|
+
description: this.description,
|
|
1838
|
+
inputSchema: this.inputSchema
|
|
1839
|
+
};
|
|
1840
|
+
}
|
|
1841
|
+
async handle(params) {
|
|
1842
|
+
if (!Array.isArray(params.browsers) || params.browsers.length === 0) {
|
|
1843
|
+
return {
|
|
1844
|
+
content: [
|
|
1845
|
+
{
|
|
1846
|
+
type: "text",
|
|
1847
|
+
text: "\u274C **Failed to create browsers:**\n\n browsers array is required and must not be empty"
|
|
1848
|
+
}
|
|
1849
|
+
]
|
|
1850
|
+
};
|
|
1851
|
+
}
|
|
1852
|
+
const results = [];
|
|
1853
|
+
const createPromises = params.browsers.map(async (browserParams, index) => {
|
|
1854
|
+
try {
|
|
1855
|
+
const result = await request("/browser/create", {
|
|
1856
|
+
method: "POST",
|
|
1857
|
+
body: JSON.stringify(browserParams)
|
|
1858
|
+
});
|
|
1859
|
+
if (result.code !== 0) {
|
|
1860
|
+
return {
|
|
1861
|
+
index,
|
|
1862
|
+
success: false,
|
|
1863
|
+
error: result.msg
|
|
1864
|
+
};
|
|
1865
|
+
}
|
|
1866
|
+
return {
|
|
1867
|
+
index,
|
|
1868
|
+
success: true,
|
|
1869
|
+
dirId: result.data?.dirId
|
|
1870
|
+
};
|
|
1871
|
+
} catch (error) {
|
|
1872
|
+
return {
|
|
1873
|
+
index,
|
|
1874
|
+
success: false,
|
|
1875
|
+
error: error.message || "Unknown error"
|
|
1876
|
+
};
|
|
1877
|
+
}
|
|
1878
|
+
});
|
|
1879
|
+
const createResults = await Promise.all(createPromises);
|
|
1880
|
+
results.push(...createResults);
|
|
1881
|
+
const successResults = results.filter((r) => r.success);
|
|
1882
|
+
const failureResults = results.filter((r) => !r.success);
|
|
1883
|
+
const successText = successResults.length > 0 ? `\u2705 **Successfully created ${successResults.length} browsers**
|
|
1884
|
+
|
|
1885
|
+
${successResults.map(
|
|
1886
|
+
(r) => ` - #${r.index + 1}${r.dirId ? ` (ID: \`${r.dirId}\`)` : ""}`
|
|
1887
|
+
).join("\n")}` : "";
|
|
1888
|
+
const failureText = failureResults.length > 0 ? `\u274C **Failed to create ${failureResults.length} browsers:**
|
|
1889
|
+
|
|
1890
|
+
${failureResults.map(
|
|
1891
|
+
(r) => ` - #${r.index + 1}: ${r.error}`
|
|
1892
|
+
).join("\n")}` : "";
|
|
1893
|
+
const summaryLines = [
|
|
1894
|
+
`**Total Requests:** ${results.length}`,
|
|
1895
|
+
`**Success:** ${successResults.length}`,
|
|
1896
|
+
`**Failed:** ${failureResults.length}`,
|
|
1897
|
+
"",
|
|
1898
|
+
...[successText, failureText].filter(Boolean)
|
|
1899
|
+
];
|
|
1900
|
+
const summaryText = summaryLines.join("\n");
|
|
1901
|
+
return {
|
|
1902
|
+
content: [
|
|
1903
|
+
{
|
|
1904
|
+
type: "text",
|
|
1905
|
+
text: summaryText
|
|
1906
|
+
}
|
|
1907
|
+
]
|
|
1908
|
+
};
|
|
1909
|
+
}
|
|
1910
|
+
};
|
|
1911
|
+
var batchCreateBrowsers = new BatchCreateBrowsers();
|
|
1912
|
+
var UpdateBrowser = class {
|
|
1913
|
+
name = "roxy_update_browser";
|
|
1914
|
+
description = "Update a browser with complete configuration control - for expert users needing full parameter access";
|
|
1915
|
+
inputSchema = {
|
|
1916
|
+
type: "object",
|
|
1917
|
+
properties: {
|
|
1918
|
+
...createBrowser.inputSchema.properties
|
|
1919
|
+
},
|
|
1920
|
+
required: ["workspaceId", "dirId"]
|
|
1921
|
+
};
|
|
1922
|
+
get schema() {
|
|
1923
|
+
return {
|
|
1924
|
+
name: this.name,
|
|
1925
|
+
description: this.description,
|
|
1926
|
+
inputSchema: this.inputSchema
|
|
1927
|
+
};
|
|
1928
|
+
}
|
|
1929
|
+
async handle(params) {
|
|
1930
|
+
const result = await request("/browser/mdf", {
|
|
1931
|
+
method: "POST",
|
|
1932
|
+
body: JSON.stringify(params)
|
|
1933
|
+
});
|
|
1934
|
+
let text = "";
|
|
1935
|
+
if (result.code !== 0) {
|
|
1936
|
+
text = `\u274C **Failed to update browser:**
|
|
1937
|
+
|
|
1938
|
+
error message: ${result.msg}`;
|
|
1939
|
+
} else {
|
|
1940
|
+
text = "\u2705 **Browser Updated Successfully**";
|
|
1941
|
+
}
|
|
1942
|
+
return {
|
|
1943
|
+
content: [
|
|
1944
|
+
{
|
|
1945
|
+
type: "text",
|
|
1946
|
+
text
|
|
1947
|
+
}
|
|
1948
|
+
]
|
|
1949
|
+
};
|
|
1950
|
+
}
|
|
1951
|
+
};
|
|
1952
|
+
var OpenBrowser = class {
|
|
1953
|
+
name = "roxy_open_browsers";
|
|
1954
|
+
description = "Open one or multiple browsers and return their CDP WebSocket endpoints for automation";
|
|
1955
|
+
inputSchema = {
|
|
1956
|
+
type: "object",
|
|
1957
|
+
properties: {
|
|
1958
|
+
workspaceId: {
|
|
1959
|
+
type: "number",
|
|
1960
|
+
description: "Workspace ID"
|
|
1961
|
+
},
|
|
1962
|
+
dirIds: {
|
|
1963
|
+
type: "array",
|
|
1964
|
+
items: { type: "string" },
|
|
1965
|
+
description: "Array of browser directory IDs to open"
|
|
1966
|
+
},
|
|
1967
|
+
forceOpen: {
|
|
1968
|
+
type: "boolean",
|
|
1969
|
+
// 即使浏览器已被其他用户打开,还是强制打开
|
|
1970
|
+
description: "Force open browser even if it is already opened by other users (default: true)",
|
|
1971
|
+
default: true
|
|
1972
|
+
},
|
|
1973
|
+
args: {
|
|
1974
|
+
type: "array",
|
|
1975
|
+
items: { type: "string" },
|
|
1976
|
+
description: "Optional browser startup arguments (--headless=new startup headless)"
|
|
1977
|
+
}
|
|
1978
|
+
},
|
|
1979
|
+
required: ["workspaceId", "dirIds"]
|
|
1980
|
+
};
|
|
1981
|
+
get schema() {
|
|
1982
|
+
return {
|
|
1983
|
+
name: this.name,
|
|
1984
|
+
description: this.description,
|
|
1985
|
+
inputSchema: this.inputSchema
|
|
1986
|
+
};
|
|
1987
|
+
}
|
|
1988
|
+
async handle(params) {
|
|
1989
|
+
const { workspaceId, dirIds, forceOpen = true, args } = params;
|
|
1990
|
+
if (!workspaceId || !Array.isArray(dirIds) || dirIds.length === 0) {
|
|
1991
|
+
return {
|
|
1992
|
+
content: [
|
|
1993
|
+
{
|
|
1994
|
+
type: "text",
|
|
1995
|
+
text: "\u274C **Failed to open browsers:**\n\n workspaceId and dirIds are required, and dirIds must not be empty"
|
|
1996
|
+
}
|
|
1997
|
+
]
|
|
1998
|
+
};
|
|
1999
|
+
}
|
|
2000
|
+
const results = [];
|
|
2001
|
+
const openPromises = dirIds.map(async (dirId) => {
|
|
2002
|
+
try {
|
|
2003
|
+
const result = await request("/browser/open", {
|
|
2004
|
+
method: "POST",
|
|
2005
|
+
body: JSON.stringify({
|
|
2006
|
+
workspaceId,
|
|
2007
|
+
dirId,
|
|
2008
|
+
forceOpen,
|
|
2009
|
+
args
|
|
2010
|
+
})
|
|
2011
|
+
});
|
|
2012
|
+
if (result.code !== 0) {
|
|
2013
|
+
return {
|
|
2014
|
+
dirId,
|
|
2015
|
+
success: false,
|
|
2016
|
+
error: result.msg
|
|
2017
|
+
};
|
|
2018
|
+
}
|
|
2019
|
+
return {
|
|
2020
|
+
dirId,
|
|
2021
|
+
success: true,
|
|
2022
|
+
data: result.data
|
|
2023
|
+
};
|
|
2024
|
+
} catch (error) {
|
|
2025
|
+
return {
|
|
2026
|
+
dirId,
|
|
2027
|
+
success: false,
|
|
2028
|
+
error: error.message || "Unknown error"
|
|
2029
|
+
};
|
|
2030
|
+
}
|
|
2031
|
+
});
|
|
2032
|
+
const openResults = await Promise.all(openPromises);
|
|
2033
|
+
results.push(...openResults);
|
|
2034
|
+
const successResults = results.filter((r) => r.success);
|
|
2035
|
+
const failureResults = results.filter((r) => !r.success);
|
|
2036
|
+
const successText = successResults.length > 0 ? [
|
|
2037
|
+
`\u2705 **Successfully opened ${successResults.length} browser(s):**`,
|
|
2038
|
+
"",
|
|
2039
|
+
...successResults.map((r) => {
|
|
2040
|
+
const data = r.data || {};
|
|
2041
|
+
return [
|
|
2042
|
+
`**Browser ${data.dirId || r.dirId || "Unknown"}** (PID:${data.pid ?? "Unknown"})`,
|
|
2043
|
+
` - CDP WebSocket: \`${data.ws ?? "N/A"}\``,
|
|
2044
|
+
` - HTTP Endpoint: \`${data.http ?? "N/A"}\``,
|
|
2045
|
+
` - Core Version: ${data.coreVersion ?? "Unknown"}`
|
|
2046
|
+
].join("\n");
|
|
2047
|
+
})
|
|
2048
|
+
].join("\n") : "";
|
|
2049
|
+
const failureText = failureResults.length > 0 ? [
|
|
2050
|
+
`\u274C **Failed to open ${failureResults.length} browser(s):**`,
|
|
2051
|
+
"",
|
|
2052
|
+
...failureResults.map(
|
|
2053
|
+
(r) => ` - ${r.dirId}: ${r.error}`
|
|
2054
|
+
)
|
|
2055
|
+
].join("\n") : "";
|
|
2056
|
+
const summaryLines = [
|
|
2057
|
+
`**Workspace:** ${workspaceId}`,
|
|
2058
|
+
`**Total Requests:** ${results.length}`,
|
|
2059
|
+
`**Success:** ${successResults.length}`,
|
|
2060
|
+
`**Failed:** ${failureResults.length}`,
|
|
2061
|
+
"",
|
|
2062
|
+
...[successText, failureText].filter(Boolean)
|
|
2063
|
+
];
|
|
2064
|
+
const summaryText = summaryLines.join("\n");
|
|
2065
|
+
return {
|
|
2066
|
+
content: [
|
|
2067
|
+
{
|
|
2068
|
+
type: "text",
|
|
2069
|
+
text: summaryText
|
|
2070
|
+
}
|
|
2071
|
+
]
|
|
2072
|
+
};
|
|
2073
|
+
}
|
|
2074
|
+
};
|
|
2075
|
+
var ListBrowsers = class {
|
|
2076
|
+
name = "roxy_list_browsers";
|
|
2077
|
+
description = "Get list of browsers in specified workspace/project";
|
|
2078
|
+
inputSchema = {
|
|
2079
|
+
type: "object",
|
|
2080
|
+
properties: {
|
|
2081
|
+
workspaceId: {
|
|
2082
|
+
type: "number",
|
|
2083
|
+
description: "Workspace ID"
|
|
2084
|
+
},
|
|
2085
|
+
projectIds: {
|
|
2086
|
+
type: "string",
|
|
2087
|
+
description: "Comma-separated project IDs"
|
|
2088
|
+
},
|
|
2089
|
+
windowName: {
|
|
2090
|
+
type: "string",
|
|
2091
|
+
description: "Filter by browser window name"
|
|
2092
|
+
},
|
|
2093
|
+
pageIndex: {
|
|
2094
|
+
type: "number",
|
|
2095
|
+
description: "Page index for pagination (default: 1)",
|
|
2096
|
+
default: 1
|
|
2097
|
+
},
|
|
2098
|
+
pageSize: {
|
|
2099
|
+
type: "number",
|
|
2100
|
+
description: "Number of items per page (default: 15)",
|
|
2101
|
+
default: 15
|
|
2102
|
+
}
|
|
2103
|
+
},
|
|
2104
|
+
required: ["workspaceId"]
|
|
2105
|
+
};
|
|
2106
|
+
get schema() {
|
|
2107
|
+
return {
|
|
2108
|
+
name: this.name,
|
|
2109
|
+
description: this.description,
|
|
2110
|
+
inputSchema: this.inputSchema
|
|
2111
|
+
};
|
|
2112
|
+
}
|
|
2113
|
+
async handle(params) {
|
|
2114
|
+
const searchParams = new URLSearchParams();
|
|
2115
|
+
searchParams.append("workspaceId", params.workspaceId.toString());
|
|
2116
|
+
if (params.projectIds)
|
|
2117
|
+
searchParams.append("projectIds", params.projectIds);
|
|
2118
|
+
if (params.windowName)
|
|
2119
|
+
searchParams.append("windowName", params.windowName);
|
|
2120
|
+
if (params.pageIndex)
|
|
2121
|
+
searchParams.append("page_index", params.pageIndex.toString());
|
|
2122
|
+
if (params.pageSize)
|
|
2123
|
+
searchParams.append("page_size", params.pageSize.toString());
|
|
2124
|
+
const result = await request(`/browser/list_v3?${searchParams}`, {
|
|
2125
|
+
method: "GET"
|
|
2126
|
+
});
|
|
2127
|
+
const data = result.data;
|
|
2128
|
+
let text = "";
|
|
2129
|
+
if (result.code !== 0) {
|
|
2130
|
+
text = `\u274C **Failed to list browsers:**
|
|
2131
|
+
|
|
2132
|
+
error message: ${result.msg}`;
|
|
2133
|
+
} else {
|
|
2134
|
+
text = `Found ${data.total} browsers in workspace ${params.workspaceId}:
|
|
2135
|
+
|
|
2136
|
+
${data.rows.map(
|
|
2137
|
+
(browser) => `**${browser.windowName || "Unnamed"}** (ID: ${browser.dirId})
|
|
2138
|
+
- Project: ${browser.projectId}
|
|
2139
|
+
- Sort: ${browser.sortNum}
|
|
2140
|
+
- OS: ${browser.os}
|
|
2141
|
+
- Status: ${browser.status}`
|
|
2142
|
+
).join("\n\n")}`;
|
|
2143
|
+
}
|
|
2144
|
+
return {
|
|
2145
|
+
content: [
|
|
2146
|
+
{
|
|
2147
|
+
type: "text",
|
|
2148
|
+
text
|
|
2149
|
+
}
|
|
2150
|
+
]
|
|
2151
|
+
};
|
|
2152
|
+
}
|
|
2153
|
+
};
|
|
2154
|
+
var CloseBrowsers = class {
|
|
2155
|
+
name = "roxy_close_browsers";
|
|
2156
|
+
description = "Close multiple browsers by their directory IDs";
|
|
2157
|
+
inputSchema = {
|
|
2158
|
+
type: "object",
|
|
2159
|
+
properties: {
|
|
2160
|
+
dirIds: {
|
|
2161
|
+
type: "array",
|
|
2162
|
+
items: { type: "string" },
|
|
2163
|
+
description: "Array of browser directory IDs to close"
|
|
2164
|
+
}
|
|
2165
|
+
},
|
|
2166
|
+
required: ["dirIds"]
|
|
2167
|
+
};
|
|
2168
|
+
get schema() {
|
|
2169
|
+
return {
|
|
2170
|
+
name: this.name,
|
|
2171
|
+
description: this.description,
|
|
2172
|
+
inputSchema: this.inputSchema
|
|
2173
|
+
};
|
|
2174
|
+
}
|
|
2175
|
+
async handle(params) {
|
|
2176
|
+
if (!params.dirIds || params.dirIds.length === 0) {
|
|
2177
|
+
return {
|
|
2178
|
+
content: [
|
|
2179
|
+
{
|
|
2180
|
+
type: "text",
|
|
2181
|
+
text: "\u274C **Failed to close browsers:**\n\n dirIds are required"
|
|
2182
|
+
}
|
|
2183
|
+
]
|
|
2184
|
+
};
|
|
2185
|
+
}
|
|
2186
|
+
const results = [];
|
|
2187
|
+
const closePromises = params.dirIds.map(async (dirId) => {
|
|
2188
|
+
try {
|
|
2189
|
+
const result = await request("/browser/close", {
|
|
2190
|
+
method: "POST",
|
|
2191
|
+
body: JSON.stringify({ dirId })
|
|
2192
|
+
});
|
|
2193
|
+
if (result.code !== 0) {
|
|
2194
|
+
return { dirId, success: false, error: result.msg };
|
|
2195
|
+
}
|
|
2196
|
+
return { dirId, success: true };
|
|
2197
|
+
} catch (error) {
|
|
2198
|
+
return { dirId, success: false, error: error.message || "Unknown error" };
|
|
2199
|
+
}
|
|
2200
|
+
});
|
|
2201
|
+
const closeResults = await Promise.all(closePromises);
|
|
2202
|
+
results.push(...closeResults);
|
|
2203
|
+
const successCount = results.filter((r) => r.success).length;
|
|
2204
|
+
const failureCount = results.filter((r) => !r.success).length;
|
|
2205
|
+
const successText = successCount > 0 ? `\u2705 Successfully closed ${successCount} browsers` : "";
|
|
2206
|
+
const failureText = failureCount > 0 ? `\u274C Failed to close ${failureCount} browsers:
|
|
2207
|
+
${results.filter((r) => !r.success).map(
|
|
2208
|
+
(r) => ` - ${r.dirId}: ${r.error}`
|
|
2209
|
+
).join("\n")}` : "";
|
|
2210
|
+
return {
|
|
2211
|
+
content: [
|
|
2212
|
+
{
|
|
2213
|
+
type: "text",
|
|
2214
|
+
text: [successText, failureText].filter(Boolean).join("\n\n")
|
|
2215
|
+
}
|
|
2216
|
+
]
|
|
2217
|
+
};
|
|
2218
|
+
}
|
|
2219
|
+
};
|
|
2220
|
+
var DeleteBrowsers = class {
|
|
2221
|
+
name = "roxy_delete_browsers";
|
|
2222
|
+
description = "Delete multiple browsers permanently by their directory IDs";
|
|
2223
|
+
inputSchema = {
|
|
2224
|
+
type: "object",
|
|
2225
|
+
properties: {
|
|
2226
|
+
workspaceId: {
|
|
2227
|
+
type: "number",
|
|
2228
|
+
description: "Workspace ID"
|
|
2229
|
+
},
|
|
2230
|
+
dirIds: {
|
|
2231
|
+
type: "array",
|
|
2232
|
+
items: { type: "string" },
|
|
2233
|
+
description: "Array of browser directory IDs to delete"
|
|
2234
|
+
}
|
|
2235
|
+
},
|
|
2236
|
+
required: ["workspaceId", "dirIds"]
|
|
2237
|
+
};
|
|
2238
|
+
get schema() {
|
|
2239
|
+
return {
|
|
2240
|
+
name: this.name,
|
|
2241
|
+
description: this.description,
|
|
2242
|
+
inputSchema: this.inputSchema
|
|
2243
|
+
};
|
|
2244
|
+
}
|
|
2245
|
+
async handle(params) {
|
|
2246
|
+
if (!params.workspaceId || !params.dirIds || params.dirIds.length === 0) {
|
|
2247
|
+
return {
|
|
2248
|
+
content: [
|
|
2249
|
+
{
|
|
2250
|
+
type: "text",
|
|
2251
|
+
text: "\u274C **Failed to delete browsers:**\n\n workspaceId and dirIds are required"
|
|
2252
|
+
}
|
|
2253
|
+
]
|
|
2254
|
+
};
|
|
2255
|
+
}
|
|
2256
|
+
const result = await request("/browser/delete", {
|
|
2257
|
+
method: "POST",
|
|
2258
|
+
body: JSON.stringify({
|
|
2259
|
+
workspaceId: params.workspaceId,
|
|
2260
|
+
dirIds: params.dirIds,
|
|
2261
|
+
isSoftDelete: true
|
|
2262
|
+
})
|
|
2263
|
+
});
|
|
2264
|
+
let text = "";
|
|
2265
|
+
if (result.code !== 0) {
|
|
2266
|
+
text = `\u274C **Browser Deletion Failed**
|
|
2267
|
+
|
|
2268
|
+
**Error:** ${result.msg}
|
|
2269
|
+
**Workspace:** ${params.workspaceId}
|
|
2270
|
+
**Failed Browsers:** ${params.dirIds.length}
|
|
2271
|
+
|
|
2272
|
+
**Browser IDs:**
|
|
2273
|
+
${params.dirIds.map((dirId, index) => ` ${index + 1}. \`${dirId}\``).join("\n")}`;
|
|
2274
|
+
} else {
|
|
2275
|
+
text = `\u2705 **Browsers Deleted Successfully**
|
|
2276
|
+
|
|
2277
|
+
**Count:** ${params.dirIds.length} browser(s)
|
|
2278
|
+
**Workspace:** ${params.workspaceId}
|
|
2279
|
+
|
|
2280
|
+
**Deleted Browsers:**
|
|
2281
|
+
${params.dirIds.map((dirId, index) => ` ${index + 1}. \`${dirId}\``).join("\n")}`;
|
|
2282
|
+
}
|
|
2283
|
+
return {
|
|
2284
|
+
content: [
|
|
2285
|
+
{
|
|
2286
|
+
type: "text",
|
|
2287
|
+
text
|
|
2288
|
+
}
|
|
2289
|
+
]
|
|
2290
|
+
};
|
|
2291
|
+
}
|
|
2292
|
+
};
|
|
2293
|
+
var GetBrowserDetail = class {
|
|
2294
|
+
name = "roxy_get_browser_detail";
|
|
2295
|
+
description = "Get detailed information for a specific browser window";
|
|
2296
|
+
inputSchema = {
|
|
2297
|
+
type: "object",
|
|
2298
|
+
properties: {
|
|
2299
|
+
workspaceId: {
|
|
2300
|
+
type: "number",
|
|
2301
|
+
description: "Workspace ID"
|
|
2302
|
+
},
|
|
2303
|
+
dirId: {
|
|
2304
|
+
type: "string",
|
|
2305
|
+
description: "Browser directory ID"
|
|
2306
|
+
}
|
|
2307
|
+
},
|
|
2308
|
+
required: ["workspaceId", "dirId"]
|
|
2309
|
+
};
|
|
2310
|
+
get schema() {
|
|
2311
|
+
return {
|
|
2312
|
+
name: this.name,
|
|
2313
|
+
description: this.description,
|
|
2314
|
+
inputSchema: this.inputSchema
|
|
2315
|
+
};
|
|
2316
|
+
}
|
|
2317
|
+
async handle(params) {
|
|
2318
|
+
if (!params.workspaceId || !params.dirId) {
|
|
2319
|
+
return {
|
|
2320
|
+
content: [
|
|
2321
|
+
{
|
|
2322
|
+
type: "text",
|
|
2323
|
+
text: "\u274C **Failed to get browser detail:**\n\n workspaceId and dirId are required"
|
|
2324
|
+
}
|
|
2325
|
+
]
|
|
2326
|
+
};
|
|
2327
|
+
}
|
|
2328
|
+
const searchParams = new URLSearchParams();
|
|
2329
|
+
searchParams.append("workspaceId", params.workspaceId.toString());
|
|
2330
|
+
searchParams.append("dirId", params.dirId);
|
|
2331
|
+
const result = await request(`/browser/detail?${searchParams}`, {
|
|
2332
|
+
method: "GET"
|
|
2333
|
+
});
|
|
2334
|
+
let text = "";
|
|
2335
|
+
if (result.code !== 0) {
|
|
2336
|
+
text = `\u274C **Failed to get browser detail:**
|
|
2337
|
+
|
|
2338
|
+
error message: ${result.msg}`;
|
|
2339
|
+
} else {
|
|
2340
|
+
const detail = result.data.rows && result.data.rows.length > 0 ? result.data.rows[0] : null;
|
|
2341
|
+
if (!detail) {
|
|
2342
|
+
text = "\u274C **Browser not found or no data returned**";
|
|
2343
|
+
} else {
|
|
2344
|
+
const cookieCount = detail.cookie?.length || 0;
|
|
2345
|
+
const { cookie: _cookie, ...detailWithoutCookies } = detail;
|
|
2346
|
+
text = `**Browser Details Summary**
|
|
2347
|
+
|
|
2348
|
+
**ID:** \`${detail.dirId}\`
|
|
2349
|
+
**Name:** ${detail.windowName}
|
|
2350
|
+
**Sort Number:** ${detail.windowSortNum}
|
|
2351
|
+
**Project:** ${detail.projectName} (ID: ${detail.projectId})
|
|
2352
|
+
**OS:** ${detail.os} ${detail.osVersion}
|
|
2353
|
+
**Core Version:** ${detail.coreVersion}
|
|
2354
|
+
**Search Engine:** ${detail.searchEngine}
|
|
2355
|
+
**Open Status:** ${detail.openStatus ? "\u2705 Opened" : "\u274C Closed"}
|
|
2356
|
+
**Cookies:** ${cookieCount} stored (excluded from response to save tokens)
|
|
2357
|
+
|
|
2358
|
+
**Full Details (JSON):**
|
|
2359
|
+
\`\`\`json
|
|
2360
|
+
${JSON.stringify(detailWithoutCookies, null, 2)}
|
|
2361
|
+
\`\`\``;
|
|
2362
|
+
}
|
|
2363
|
+
}
|
|
2364
|
+
return {
|
|
2365
|
+
content: [
|
|
2366
|
+
{
|
|
2367
|
+
type: "text",
|
|
2368
|
+
text
|
|
2369
|
+
}
|
|
2370
|
+
]
|
|
2371
|
+
};
|
|
2372
|
+
}
|
|
2373
|
+
};
|
|
2374
|
+
var ClearLocalCache = class {
|
|
2375
|
+
name = "roxy_clear_local_cache";
|
|
2376
|
+
description = "Clear local cache for specified browsers";
|
|
2377
|
+
inputSchema = {
|
|
2378
|
+
type: "object",
|
|
2379
|
+
properties: {
|
|
2380
|
+
dirIds: {
|
|
2381
|
+
type: "array",
|
|
2382
|
+
items: { type: "string" },
|
|
2383
|
+
description: "Array of browser directory IDs"
|
|
2384
|
+
}
|
|
2385
|
+
},
|
|
2386
|
+
required: ["dirIds"]
|
|
2387
|
+
};
|
|
2388
|
+
get schema() {
|
|
2389
|
+
return {
|
|
2390
|
+
name: this.name,
|
|
2391
|
+
description: this.description,
|
|
2392
|
+
inputSchema: this.inputSchema
|
|
2393
|
+
};
|
|
2394
|
+
}
|
|
2395
|
+
async handle(params) {
|
|
2396
|
+
if (!params.dirIds || params.dirIds.length === 0) {
|
|
2397
|
+
return {
|
|
2398
|
+
content: [
|
|
2399
|
+
{
|
|
2400
|
+
type: "text",
|
|
2401
|
+
text: "\u274C **Failed to clear local cache:**\n\n dirIds are required"
|
|
2402
|
+
}
|
|
2403
|
+
]
|
|
2404
|
+
};
|
|
2405
|
+
}
|
|
2406
|
+
const result = await request("/browser/clear_local_cache", {
|
|
2407
|
+
method: "POST",
|
|
2408
|
+
body: JSON.stringify({ dirIds: params.dirIds })
|
|
2409
|
+
});
|
|
2410
|
+
let text = "";
|
|
2411
|
+
if (result.code !== 0) {
|
|
2412
|
+
text = `\u274C **Failed to clear local cache:**
|
|
2413
|
+
|
|
2414
|
+
error message: ${result.msg}`;
|
|
2415
|
+
} else {
|
|
2416
|
+
text = `\u2705 **Local Cache Cleared**
|
|
2417
|
+
|
|
2418
|
+
**Browser Count:** ${params.dirIds.length}
|
|
2419
|
+
|
|
2420
|
+
**Browser IDs:**
|
|
2421
|
+
${params.dirIds.map((id, index) => ` ${index + 1}. \`${id}\``).join("\n")}`;
|
|
2422
|
+
}
|
|
2423
|
+
return {
|
|
2424
|
+
content: [
|
|
2425
|
+
{
|
|
2426
|
+
type: "text",
|
|
2427
|
+
text
|
|
2428
|
+
}
|
|
2429
|
+
]
|
|
2430
|
+
};
|
|
2431
|
+
}
|
|
2432
|
+
};
|
|
2433
|
+
var ClearServerCache = class {
|
|
2434
|
+
name = "roxy_clear_server_cache";
|
|
2435
|
+
description = "Clear server-side cache for specified browsers";
|
|
2436
|
+
inputSchema = {
|
|
2437
|
+
type: "object",
|
|
2438
|
+
properties: {
|
|
2439
|
+
workspaceId: {
|
|
2440
|
+
type: "number",
|
|
2441
|
+
description: "Workspace ID"
|
|
2442
|
+
},
|
|
2443
|
+
dirIds: {
|
|
2444
|
+
type: "array",
|
|
2445
|
+
items: { type: "string" },
|
|
2446
|
+
description: "Array of browser directory IDs"
|
|
2447
|
+
}
|
|
2448
|
+
},
|
|
2449
|
+
required: ["workspaceId", "dirIds"]
|
|
2450
|
+
};
|
|
2451
|
+
get schema() {
|
|
2452
|
+
return {
|
|
2453
|
+
name: this.name,
|
|
2454
|
+
description: this.description,
|
|
2455
|
+
inputSchema: this.inputSchema
|
|
2456
|
+
};
|
|
2457
|
+
}
|
|
2458
|
+
async handle(params) {
|
|
2459
|
+
if (!params.workspaceId || !params.dirIds || params.dirIds.length === 0) {
|
|
2460
|
+
return {
|
|
2461
|
+
content: [
|
|
2462
|
+
{
|
|
2463
|
+
type: "text",
|
|
2464
|
+
text: "\u274C **Failed to clear server cache:**\n\n workspaceId and dirIds are required"
|
|
2465
|
+
}
|
|
2466
|
+
]
|
|
2467
|
+
};
|
|
2468
|
+
}
|
|
2469
|
+
const result = await request("/browser/clear_server_cache", {
|
|
2470
|
+
method: "POST",
|
|
2471
|
+
body: JSON.stringify({
|
|
2472
|
+
workspaceId: params.workspaceId,
|
|
2473
|
+
dirIds: params.dirIds
|
|
2474
|
+
})
|
|
2475
|
+
});
|
|
2476
|
+
let text = "";
|
|
2477
|
+
if (result.code !== 0) {
|
|
2478
|
+
text = `\u274C **Failed to clear server cache:**
|
|
2479
|
+
|
|
2480
|
+
error message: ${result.msg}`;
|
|
2481
|
+
} else {
|
|
2482
|
+
text = `\u2705 **Server Cache Cleared**
|
|
2483
|
+
|
|
2484
|
+
**Workspace:** ${params.workspaceId}
|
|
2485
|
+
**Browser Count:** ${params.dirIds.length}
|
|
2486
|
+
|
|
2487
|
+
**Browser IDs:**
|
|
2488
|
+
${params.dirIds.map((id, index) => ` ${index + 1}. \`${id}\``).join("\n")}`;
|
|
2489
|
+
}
|
|
2490
|
+
return {
|
|
2491
|
+
content: [
|
|
2492
|
+
{
|
|
2493
|
+
type: "text",
|
|
2494
|
+
text
|
|
2495
|
+
}
|
|
2496
|
+
]
|
|
2497
|
+
};
|
|
2498
|
+
}
|
|
2499
|
+
};
|
|
2500
|
+
var RandomFingerprint = class {
|
|
2501
|
+
name = "roxy_random_fingerprint";
|
|
2502
|
+
description = "Randomize browser fingerprint for a specific browser";
|
|
2503
|
+
inputSchema = {
|
|
2504
|
+
type: "object",
|
|
2505
|
+
properties: {
|
|
2506
|
+
workspaceId: {
|
|
2507
|
+
type: "number",
|
|
2508
|
+
description: "Workspace ID"
|
|
2509
|
+
},
|
|
2510
|
+
dirId: {
|
|
2511
|
+
type: "string",
|
|
2512
|
+
description: "Browser directory ID"
|
|
2513
|
+
}
|
|
2514
|
+
},
|
|
2515
|
+
required: ["workspaceId", "dirId"]
|
|
2516
|
+
};
|
|
2517
|
+
get schema() {
|
|
2518
|
+
return {
|
|
2519
|
+
name: this.name,
|
|
2520
|
+
description: this.description,
|
|
2521
|
+
inputSchema: this.inputSchema
|
|
2522
|
+
};
|
|
2523
|
+
}
|
|
2524
|
+
async handle(params) {
|
|
2525
|
+
if (!params.workspaceId || !params.dirId) {
|
|
2526
|
+
return {
|
|
2527
|
+
content: [
|
|
2528
|
+
{
|
|
2529
|
+
type: "text",
|
|
2530
|
+
text: "\u274C **Failed to randomize fingerprint:**\n\n workspaceId and dirId are required"
|
|
2531
|
+
}
|
|
2532
|
+
]
|
|
2533
|
+
};
|
|
2534
|
+
}
|
|
2535
|
+
const result = await request("/browser/random_env", {
|
|
2536
|
+
method: "POST",
|
|
2537
|
+
body: JSON.stringify({
|
|
2538
|
+
workspaceId: params.workspaceId,
|
|
2539
|
+
dirId: params.dirId
|
|
2540
|
+
})
|
|
2541
|
+
});
|
|
2542
|
+
let text = "";
|
|
2543
|
+
if (result.code !== 0) {
|
|
2544
|
+
text = `\u274C **Failed to randomize fingerprint:**
|
|
2545
|
+
|
|
2546
|
+
error message: ${result.msg}`;
|
|
2547
|
+
} else {
|
|
2548
|
+
text = `\u2705 **Browser Fingerprint Randomized**
|
|
2549
|
+
|
|
2550
|
+
**Browser ID:** \`${params.dirId}\`
|
|
2551
|
+
**Workspace:** ${params.workspaceId}
|
|
2552
|
+
|
|
2553
|
+
*Browser fingerprint has been randomized. Restart the browser to apply changes.*`;
|
|
2554
|
+
}
|
|
2555
|
+
return {
|
|
2556
|
+
content: [
|
|
2557
|
+
{
|
|
2558
|
+
type: "text",
|
|
2559
|
+
text
|
|
2560
|
+
}
|
|
2561
|
+
]
|
|
2562
|
+
};
|
|
2563
|
+
}
|
|
2564
|
+
};
|
|
2565
|
+
var ListLabels = class {
|
|
2566
|
+
name = "roxy_list_labels";
|
|
2567
|
+
description = "Get list of labels in specified workspace";
|
|
2568
|
+
inputSchema = {
|
|
2569
|
+
type: "object",
|
|
2570
|
+
properties: {
|
|
2571
|
+
workspaceId: {
|
|
2572
|
+
type: "number",
|
|
2573
|
+
description: "Workspace ID"
|
|
2574
|
+
}
|
|
2575
|
+
},
|
|
2576
|
+
required: ["workspaceId"]
|
|
2577
|
+
};
|
|
2578
|
+
get schema() {
|
|
2579
|
+
return {
|
|
2580
|
+
name: this.name,
|
|
2581
|
+
description: this.description,
|
|
2582
|
+
inputSchema: this.inputSchema
|
|
2583
|
+
};
|
|
2584
|
+
}
|
|
2585
|
+
async handle(params) {
|
|
2586
|
+
if (!params.workspaceId) {
|
|
2587
|
+
return {
|
|
2588
|
+
content: [
|
|
2589
|
+
{
|
|
2590
|
+
type: "text",
|
|
2591
|
+
text: "\u274C **Failed to list labels:**\n\n workspaceId is required"
|
|
2592
|
+
}
|
|
2593
|
+
]
|
|
2594
|
+
};
|
|
2595
|
+
}
|
|
2596
|
+
const searchParams = new URLSearchParams();
|
|
2597
|
+
searchParams.append("workspaceId", params.workspaceId.toString());
|
|
2598
|
+
const result = await request(`/browser/label?${searchParams}`, {
|
|
2599
|
+
method: "GET"
|
|
2600
|
+
});
|
|
2601
|
+
let text = "";
|
|
2602
|
+
if (result.code !== 0) {
|
|
2603
|
+
text = `\u274C **Failed to list labels:**
|
|
2604
|
+
|
|
2605
|
+
error message: ${result.msg}`;
|
|
2606
|
+
} else {
|
|
2607
|
+
const labels = result.data || [];
|
|
2608
|
+
text = `Found ${labels.length} labels in workspace ${params.workspaceId}:
|
|
2609
|
+
|
|
2610
|
+
${labels.map(
|
|
2611
|
+
(label) => `**${label.name}** (ID: ${label.id})
|
|
2612
|
+
- Color: ${label.color}`
|
|
2613
|
+
).join("\n\n")}`;
|
|
2614
|
+
}
|
|
2615
|
+
return {
|
|
2616
|
+
content: [
|
|
2617
|
+
{
|
|
2618
|
+
type: "text",
|
|
2619
|
+
text
|
|
2620
|
+
}
|
|
2621
|
+
]
|
|
2622
|
+
};
|
|
2623
|
+
}
|
|
2624
|
+
};
|
|
2625
|
+
var GetConnectionInfo = class {
|
|
2626
|
+
name = "roxy_get_connection_info";
|
|
2627
|
+
description = "Get connection information (CDP endpoints, PIDs) for currently opened browsers";
|
|
2628
|
+
inputSchema = {
|
|
2629
|
+
type: "object",
|
|
2630
|
+
properties: {
|
|
2631
|
+
dirIds: {
|
|
2632
|
+
type: "array",
|
|
2633
|
+
items: { type: "string" },
|
|
2634
|
+
description: "Array of browser directory IDs to query (optional, returns all if not specified)"
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
};
|
|
2638
|
+
get schema() {
|
|
2639
|
+
return {
|
|
2640
|
+
name: this.name,
|
|
2641
|
+
description: this.description,
|
|
2642
|
+
inputSchema: this.inputSchema
|
|
2643
|
+
};
|
|
2644
|
+
}
|
|
2645
|
+
async handle(params) {
|
|
2646
|
+
const searchParams = new URLSearchParams();
|
|
2647
|
+
if (params.dirIds && params.dirIds.length > 0) {
|
|
2648
|
+
searchParams.append("dirIds", params.dirIds.join(","));
|
|
2649
|
+
}
|
|
2650
|
+
const queryString = searchParams.toString();
|
|
2651
|
+
const endpoint = queryString ? `/browser/connection_info?${queryString}` : "/browser/connection_info";
|
|
2652
|
+
const result = await request(endpoint, {
|
|
2653
|
+
method: "GET"
|
|
2654
|
+
});
|
|
2655
|
+
let text = "";
|
|
2656
|
+
if (result.code !== 0) {
|
|
2657
|
+
text = `\u274C **Failed to get connection info:**
|
|
2658
|
+
|
|
2659
|
+
error message: ${result.msg}`;
|
|
2660
|
+
} else {
|
|
2661
|
+
const connections = result.data || [];
|
|
2662
|
+
if (connections.length === 0) {
|
|
2663
|
+
text = "\u26A0\uFE0F No opened browsers found.\n\nUse `roxy_open_browsers` to open browsers first.";
|
|
2664
|
+
} else {
|
|
2665
|
+
text = `Found ${connections.length} opened browser(s):
|
|
2666
|
+
|
|
2667
|
+
${connections.map(
|
|
2668
|
+
(conn) => `**${conn.windowName || "Unnamed"}** (${conn.dirId})
|
|
2669
|
+
- PID: ${conn.pid}
|
|
2670
|
+
- CDP WebSocket: \`${conn.ws}\`
|
|
2671
|
+
- HTTP Endpoint: \`${conn.http}\`
|
|
2672
|
+
- Core Version: ${conn.coreVersion}
|
|
2673
|
+
- Driver: ${conn.driver}`
|
|
2674
|
+
).join("\n\n")}`;
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2677
|
+
return {
|
|
2678
|
+
content: [
|
|
2679
|
+
{
|
|
2680
|
+
type: "text",
|
|
2681
|
+
text
|
|
2682
|
+
}
|
|
2683
|
+
]
|
|
2684
|
+
};
|
|
2685
|
+
}
|
|
2686
|
+
};
|
|
2687
|
+
var openBrowser = new OpenBrowser();
|
|
2688
|
+
var updateBrowser = new UpdateBrowser();
|
|
2689
|
+
var listBrowsers = new ListBrowsers();
|
|
2690
|
+
var closeBrowsers = new CloseBrowsers();
|
|
2691
|
+
var deleteBrowsers = new DeleteBrowsers();
|
|
2692
|
+
var getBrowserDetail = new GetBrowserDetail();
|
|
2693
|
+
var clearLocalCache = new ClearLocalCache();
|
|
2694
|
+
var clearServerCache = new ClearServerCache();
|
|
2695
|
+
var randomFingerprint = new RandomFingerprint();
|
|
2696
|
+
var listLabels = new ListLabels();
|
|
2697
|
+
var getConnectionInfo = new GetConnectionInfo();
|
|
2698
|
+
|
|
2699
|
+
// src/modules/other.ts
|
|
2700
|
+
var ListWorkspaces = class {
|
|
2701
|
+
name = "roxy_list_workspaces";
|
|
2702
|
+
description = "Get list of all workspaces and their projects from RoxyBrowser";
|
|
2703
|
+
inputSchema = {
|
|
2704
|
+
type: "object",
|
|
2705
|
+
properties: {
|
|
2706
|
+
pageIndex: {
|
|
2707
|
+
type: "number",
|
|
2708
|
+
description: "Page index for pagination (default: 1)",
|
|
2709
|
+
default: 1
|
|
2710
|
+
},
|
|
2711
|
+
pageSize: {
|
|
2712
|
+
type: "number",
|
|
2713
|
+
description: "Number of items per page (default: 15)",
|
|
2714
|
+
default: 15
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
};
|
|
2718
|
+
get schema() {
|
|
2719
|
+
return {
|
|
2720
|
+
name: this.name,
|
|
2721
|
+
description: this.description,
|
|
2722
|
+
inputSchema: this.inputSchema
|
|
2723
|
+
};
|
|
2724
|
+
}
|
|
2725
|
+
async handle(params) {
|
|
2726
|
+
const { pageIndex = 1, pageSize = 15 } = params || {};
|
|
2727
|
+
const searchParams = new URLSearchParams();
|
|
2728
|
+
searchParams.append("page_index", pageIndex.toString());
|
|
2729
|
+
searchParams.append("page_size", pageSize.toString());
|
|
2730
|
+
const result = await request(`/browser/workspace?${searchParams}`, {
|
|
2731
|
+
method: "GET"
|
|
2732
|
+
});
|
|
2733
|
+
let text = "";
|
|
2734
|
+
if (result.code !== 0) {
|
|
2735
|
+
text = `\u274C **Failed to list workspaces:**
|
|
2736
|
+
|
|
2737
|
+
error message: ${result.msg}`;
|
|
2738
|
+
} else {
|
|
2739
|
+
const data = result.data;
|
|
2740
|
+
text = `Found ${data.total} workspaces:
|
|
2741
|
+
|
|
2742
|
+
${data.rows.map(
|
|
2743
|
+
(ws) => `**${ws.workspaceName}** (ID: ${ws.id})
|
|
2744
|
+
${ws.project_details.map(
|
|
2745
|
+
(proj) => ` - ${proj.projectName} (ID: ${proj.projectId})`
|
|
2746
|
+
).join("\n")}`
|
|
2747
|
+
).join("\n\n")}`;
|
|
2748
|
+
}
|
|
2749
|
+
return {
|
|
2750
|
+
content: [
|
|
2751
|
+
{
|
|
2752
|
+
type: "text",
|
|
2753
|
+
text
|
|
2754
|
+
}
|
|
2755
|
+
]
|
|
2756
|
+
};
|
|
2757
|
+
}
|
|
2758
|
+
};
|
|
2759
|
+
var HealthCheck = class {
|
|
2760
|
+
name = "roxy_health_check";
|
|
2761
|
+
description = "Check if the target server is alive and healthy. This tool performs a health check to verify server connectivity and status.";
|
|
2762
|
+
inputSchema = {
|
|
2763
|
+
type: "object",
|
|
2764
|
+
properties: {
|
|
2765
|
+
includeWorkspaceCheck: {
|
|
2766
|
+
type: "boolean",
|
|
2767
|
+
description: "Include workspace connectivity tests (optional, default: true)",
|
|
2768
|
+
default: true
|
|
2769
|
+
},
|
|
2770
|
+
includeBrowserCheck: {
|
|
2771
|
+
type: "boolean",
|
|
2772
|
+
description: "Include browser availability checks (optional, default: true)",
|
|
2773
|
+
default: true
|
|
2774
|
+
},
|
|
2775
|
+
verbose: {
|
|
2776
|
+
type: "boolean",
|
|
2777
|
+
description: "Include detailed diagnostic information (optional, default: false)",
|
|
2778
|
+
default: false
|
|
2779
|
+
}
|
|
2780
|
+
}
|
|
2781
|
+
};
|
|
2782
|
+
get schema() {
|
|
2783
|
+
return {
|
|
2784
|
+
name: this.name,
|
|
2785
|
+
description: this.description,
|
|
2786
|
+
inputSchema: this.inputSchema
|
|
2787
|
+
};
|
|
2788
|
+
}
|
|
2789
|
+
async handle(params) {
|
|
2790
|
+
const { includeWorkspaceCheck = true, includeBrowserCheck = true, verbose = false } = params || {};
|
|
2791
|
+
let healthStatus = "unknown";
|
|
2792
|
+
let healthError = "";
|
|
2793
|
+
try {
|
|
2794
|
+
const healthResult = await request("/health", {
|
|
2795
|
+
method: "GET"
|
|
2796
|
+
});
|
|
2797
|
+
if (healthResult.code === 0 || healthResult.code === void 0) {
|
|
2798
|
+
healthStatus = "healthy";
|
|
2799
|
+
} else {
|
|
2800
|
+
healthStatus = "unhealthy";
|
|
2801
|
+
healthError = healthResult.msg || "Health check failed";
|
|
2802
|
+
}
|
|
2803
|
+
} catch (error) {
|
|
2804
|
+
healthStatus = "unhealthy";
|
|
2805
|
+
healthError = error.message || "Failed to connect to server";
|
|
2806
|
+
}
|
|
2807
|
+
let text = `## \u{1F50D} \u5065\u5EB7\u68C0\u67E5\u62A5\u544A / Health Check Report
|
|
2808
|
+
|
|
2809
|
+
`;
|
|
2810
|
+
text += `### \u{1F310} \u670D\u52A1\u5668\u72B6\u6001 / Server Status
|
|
2811
|
+
`;
|
|
2812
|
+
text += `- **\u670D\u52A1\u5668\u8FDE\u63A5 / Server Connection**: ${healthStatus === "healthy" ? "\u2705 \u6B63\u5E38" : "\u274C \u5F02\u5E38"}
|
|
2813
|
+
`;
|
|
2814
|
+
if (healthStatus !== "healthy" && healthError) {
|
|
2815
|
+
text += `- **\u9519\u8BEF\u4FE1\u606F / Error**: ${healthError}
|
|
2816
|
+
`;
|
|
2817
|
+
}
|
|
2818
|
+
if (includeWorkspaceCheck && healthStatus === "healthy") {
|
|
2819
|
+
try {
|
|
2820
|
+
const workspaceResult = await request("/browser/workspace?page_index=1&page_size=5", {
|
|
2821
|
+
method: "GET"
|
|
2822
|
+
});
|
|
2823
|
+
if (workspaceResult.code === 0) {
|
|
2824
|
+
const workspaces = workspaceResult.data;
|
|
2825
|
+
text += `
|
|
2826
|
+
### \u{1F4C1} \u5DE5\u4F5C\u533A\u4FE1\u606F / Workspace Information
|
|
2827
|
+
`;
|
|
2828
|
+
text += `- **\u53EF\u7528\u5DE5\u4F5C\u533A / Available Workspaces**: ${workspaces.total}
|
|
2829
|
+
`;
|
|
2830
|
+
if (workspaces.rows && workspaces.rows.length > 0) {
|
|
2831
|
+
text += `- **\u5DE5\u4F5C\u533A\u8BE6\u60C5 / Workspace Details**:
|
|
2832
|
+
`;
|
|
2833
|
+
workspaces.rows.slice(0, 3).forEach((ws) => {
|
|
2834
|
+
const projectCount = ws.project_details?.length || 0;
|
|
2835
|
+
text += ` - ${ws.workspaceName} (ID: ${ws.id}) - ${projectCount} projects
|
|
2836
|
+
`;
|
|
2837
|
+
});
|
|
2838
|
+
if (workspaces.total > 3) {
|
|
2839
|
+
text += ` - ... and ${workspaces.total - 3} more
|
|
2840
|
+
`;
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2843
|
+
} else {
|
|
2844
|
+
text += `
|
|
2845
|
+
### \u{1F4C1} \u5DE5\u4F5C\u533A\u4FE1\u606F / Workspace Information
|
|
2846
|
+
`;
|
|
2847
|
+
text += `- **\u72B6\u6001**: \u26A0\uFE0F \u65E0\u6CD5\u83B7\u53D6\u5DE5\u4F5C\u533A\u4FE1\u606F
|
|
2848
|
+
`;
|
|
2849
|
+
text += `- **\u9519\u8BEF**: ${workspaceResult.msg}
|
|
2850
|
+
`;
|
|
2851
|
+
}
|
|
2852
|
+
} catch (error) {
|
|
2853
|
+
text += `
|
|
2854
|
+
### \u{1F4C1} \u5DE5\u4F5C\u533A\u4FE1\u606F / Workspace Information
|
|
2855
|
+
`;
|
|
2856
|
+
text += `- **\u72B6\u6001**: \u274C \u65E0\u6CD5\u83B7\u53D6\u5DE5\u4F5C\u533A\u4FE1\u606F
|
|
2857
|
+
`;
|
|
2858
|
+
text += `- **\u9519\u8BEF**: ${error.message || "Unknown error"}
|
|
2859
|
+
`;
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
if (includeBrowserCheck && healthStatus === "healthy") {
|
|
2863
|
+
try {
|
|
2864
|
+
const workspaceResult = await request("/browser/workspace?page_index=1&page_size=1", {
|
|
2865
|
+
method: "GET"
|
|
2866
|
+
});
|
|
2867
|
+
if (workspaceResult.code === 0 && workspaceResult.data.rows && workspaceResult.data.rows.length > 0) {
|
|
2868
|
+
const firstWorkspace = workspaceResult.data.rows[0];
|
|
2869
|
+
const browserResult = await request(`/browser/list_v3?workspaceId=${firstWorkspace.id}&page_index=1&page_size=5`, {
|
|
2870
|
+
method: "GET"
|
|
2871
|
+
});
|
|
2872
|
+
if (browserResult.code === 0) {
|
|
2873
|
+
const browsers = browserResult.data;
|
|
2874
|
+
text += `
|
|
2875
|
+
### \u{1F310} \u6D4F\u89C8\u5668\u4FE1\u606F / Browser Information
|
|
2876
|
+
`;
|
|
2877
|
+
text += `- **\u5DE5\u4F5C\u533A / Workspace**: ${firstWorkspace.workspaceName} (ID: ${firstWorkspace.id})
|
|
2878
|
+
`;
|
|
2879
|
+
text += `- **\u6D4F\u89C8\u5668\u603B\u6570 / Total Browsers**: ${browsers.total}
|
|
2880
|
+
`;
|
|
2881
|
+
if (browsers.rows && browsers.rows.length > 0) {
|
|
2882
|
+
text += `- **\u6D4F\u89C8\u5668\u793A\u4F8B / Browser Examples**:
|
|
2883
|
+
`;
|
|
2884
|
+
browsers.rows.slice(0, 3).forEach((browser) => {
|
|
2885
|
+
text += ` - ${browser.windowName || "Unnamed"} (ID: ${browser.dirId}) - ${browser.status}
|
|
2886
|
+
`;
|
|
2887
|
+
});
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
} catch (error) {
|
|
2892
|
+
text += `
|
|
2893
|
+
### \u{1F310} \u6D4F\u89C8\u5668\u4FE1\u606F / Browser Information
|
|
2894
|
+
`;
|
|
2895
|
+
text += `- **\u72B6\u6001**: \u26A0\uFE0F \u65E0\u6CD5\u83B7\u53D6\u6D4F\u89C8\u5668\u4FE1\u606F
|
|
2896
|
+
`;
|
|
2897
|
+
text += `- **\u9519\u8BEF**: ${error.message || "Unknown error"}
|
|
2898
|
+
`;
|
|
2899
|
+
}
|
|
2900
|
+
}
|
|
2901
|
+
if (verbose && healthStatus === "healthy") {
|
|
2902
|
+
text += `
|
|
2903
|
+
### \u{1F4CA} \u8BE6\u7EC6\u4FE1\u606F / Detailed Information
|
|
2904
|
+
`;
|
|
2905
|
+
text += `- **\u5065\u5EB7\u68C0\u67E5\u65F6\u95F4 / Check Time**: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
2906
|
+
`;
|
|
2907
|
+
text += `- **\u68C0\u67E5\u6A21\u5F0F / Check Mode**: ${includeWorkspaceCheck ? "Workspace + " : ""}${includeBrowserCheck ? "Browser" : ""}
|
|
2908
|
+
`;
|
|
2909
|
+
}
|
|
2910
|
+
return {
|
|
2911
|
+
content: [
|
|
2912
|
+
{
|
|
2913
|
+
type: "text",
|
|
2914
|
+
text
|
|
2915
|
+
}
|
|
2916
|
+
]
|
|
2917
|
+
};
|
|
2918
|
+
}
|
|
2919
|
+
};
|
|
2920
|
+
var listWorkspaces = new ListWorkspaces();
|
|
2921
|
+
var healthCheck = new HealthCheck();
|
|
2922
|
+
|
|
2923
|
+
// src/index.ts
|
|
2924
|
+
var TOOLS = [
|
|
2925
|
+
listBrowsers.schema,
|
|
2926
|
+
batchCreateBrowsers.schema,
|
|
2927
|
+
createBrowser.schema,
|
|
2928
|
+
openBrowser.schema,
|
|
2929
|
+
updateBrowser.schema,
|
|
2930
|
+
closeBrowsers.schema,
|
|
2931
|
+
deleteBrowsers.schema,
|
|
2932
|
+
getBrowserDetail.schema,
|
|
2933
|
+
clearLocalCache.schema,
|
|
2934
|
+
clearServerCache.schema,
|
|
2935
|
+
randomFingerprint.schema,
|
|
2936
|
+
listLabels.schema,
|
|
2937
|
+
getConnectionInfo.schema,
|
|
2938
|
+
proxyList.schema,
|
|
2939
|
+
proxyStore.schema,
|
|
2940
|
+
createProxy.schema,
|
|
2941
|
+
batchCreateProxies.schema,
|
|
2942
|
+
detectProxy.schema,
|
|
2943
|
+
modifyProxy.schema,
|
|
2944
|
+
deleteProxies.schema,
|
|
2945
|
+
// getDetectChannels.schema,
|
|
2946
|
+
listAccounts.schema,
|
|
2947
|
+
createAccount.schema,
|
|
2948
|
+
batchCreateAccounts.schema,
|
|
2949
|
+
modifyAccount.schema,
|
|
2950
|
+
deleteAccounts.schema,
|
|
2951
|
+
listWorkspaces.schema,
|
|
2952
|
+
healthCheck.schema
|
|
2953
|
+
];
|
|
2954
|
+
var RoxyBrowserMCPServer = class {
|
|
2955
|
+
server;
|
|
2956
|
+
constructor() {
|
|
2957
|
+
this.server = new index_js.Server(
|
|
2958
|
+
{
|
|
2959
|
+
name: "roxybrowser-openapi-mcp",
|
|
2960
|
+
version: "1.0.0"
|
|
2961
|
+
},
|
|
2962
|
+
{
|
|
2963
|
+
capabilities: {
|
|
2964
|
+
tools: {}
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2967
|
+
);
|
|
2968
|
+
this.setupHandlers();
|
|
2969
|
+
}
|
|
2970
|
+
setupHandlers() {
|
|
2971
|
+
this.server.setRequestHandler(types_js.ListToolsRequestSchema, async () => ({
|
|
2972
|
+
tools: TOOLS
|
|
2973
|
+
}));
|
|
2974
|
+
this.server.setRequestHandler(types_js.CallToolRequestSchema, async (request2) => {
|
|
2975
|
+
const { name, arguments: args } = request2.params;
|
|
2976
|
+
try {
|
|
2977
|
+
switch (name) {
|
|
2978
|
+
// 浏览器相关
|
|
2979
|
+
case listBrowsers.name:
|
|
2980
|
+
return await listBrowsers.handle(args);
|
|
2981
|
+
case createBrowser.name:
|
|
2982
|
+
return await createBrowser.handle(args);
|
|
2983
|
+
case openBrowser.name:
|
|
2984
|
+
return await openBrowser.handle(args);
|
|
2985
|
+
case updateBrowser.name:
|
|
2986
|
+
return await updateBrowser.handle(args);
|
|
2987
|
+
case closeBrowsers.name:
|
|
2988
|
+
return await closeBrowsers.handle(args);
|
|
2989
|
+
case deleteBrowsers.name:
|
|
2990
|
+
return await deleteBrowsers.handle(args);
|
|
2991
|
+
case batchCreateBrowsers.name:
|
|
2992
|
+
return await batchCreateBrowsers.handle(args);
|
|
2993
|
+
case listLabels.name:
|
|
2994
|
+
return await listLabels.handle(args);
|
|
2995
|
+
case getConnectionInfo.name:
|
|
2996
|
+
return await getConnectionInfo.handle(args);
|
|
2997
|
+
case randomFingerprint.name:
|
|
2998
|
+
return await randomFingerprint.handle(args);
|
|
2999
|
+
case clearLocalCache.name:
|
|
3000
|
+
return await clearLocalCache.handle(args);
|
|
3001
|
+
case clearServerCache.name:
|
|
3002
|
+
return await clearServerCache.handle(args);
|
|
3003
|
+
case getBrowserDetail.name:
|
|
3004
|
+
return await getBrowserDetail.handle(args);
|
|
3005
|
+
// 账号相关
|
|
3006
|
+
case listAccounts.name:
|
|
3007
|
+
return await listAccounts.handle(args);
|
|
3008
|
+
case createAccount.name:
|
|
3009
|
+
return await createAccount.handle(args);
|
|
3010
|
+
case batchCreateAccounts.name:
|
|
3011
|
+
return await batchCreateAccounts.handle(args);
|
|
3012
|
+
case modifyAccount.name:
|
|
3013
|
+
return await modifyAccount.handle(args);
|
|
3014
|
+
case deleteAccounts.name:
|
|
3015
|
+
return await deleteAccounts.handle(args);
|
|
3016
|
+
// 代理相关
|
|
3017
|
+
case proxyList.name:
|
|
3018
|
+
return await proxyList.handle(args);
|
|
3019
|
+
case proxyStore.name:
|
|
3020
|
+
return await proxyStore.handle(args);
|
|
3021
|
+
case createProxy.name:
|
|
3022
|
+
return await createProxy.handle(args);
|
|
3023
|
+
case batchCreateProxies.name:
|
|
3024
|
+
return await batchCreateProxies.handle(args);
|
|
3025
|
+
case detectProxy.name:
|
|
3026
|
+
return await detectProxy.handle(args);
|
|
3027
|
+
case modifyProxy.name:
|
|
3028
|
+
return await modifyProxy.handle(args);
|
|
3029
|
+
case deleteProxies.name:
|
|
3030
|
+
return await deleteProxies.handle(args);
|
|
3031
|
+
// 空间列表
|
|
3032
|
+
case listWorkspaces.name:
|
|
3033
|
+
return await listWorkspaces.handle(args);
|
|
3034
|
+
// 健康检查
|
|
3035
|
+
case healthCheck.name:
|
|
3036
|
+
return await healthCheck.handle(args);
|
|
3037
|
+
default:
|
|
3038
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
3039
|
+
}
|
|
3040
|
+
} catch (error) {
|
|
3041
|
+
return {
|
|
3042
|
+
content: [
|
|
3043
|
+
{
|
|
3044
|
+
type: "text",
|
|
3045
|
+
text: error instanceof Error ? error.message : "Unknown error"
|
|
3046
|
+
}
|
|
3047
|
+
]
|
|
3048
|
+
};
|
|
3049
|
+
}
|
|
3050
|
+
});
|
|
3051
|
+
}
|
|
3052
|
+
async run() {
|
|
3053
|
+
console.error("\u{1F680} Starting RoxyBrowser MCP Server...");
|
|
3054
|
+
const transport = new stdio_js.StdioServerTransport();
|
|
3055
|
+
await this.server.connect(transport);
|
|
3056
|
+
console.error("\u2705 RoxyBrowser MCP Server is running");
|
|
3057
|
+
}
|
|
3058
|
+
};
|
|
3059
|
+
async function runServer() {
|
|
3060
|
+
const server = new RoxyBrowserMCPServer();
|
|
3061
|
+
await server.run();
|
|
3062
|
+
}
|
|
3063
|
+
|
|
3064
|
+
// src/cli.ts
|
|
3065
|
+
var PKG_VERSION = "1.0.9";
|
|
3066
|
+
var program = new commander.Command();
|
|
3067
|
+
program.name("roxy-browser-mcp").description("RoxyBrowser MCP Server - Model Context Protocol server for RoxyBrowser automation").version(PKG_VERSION, "-V, --version", "Show version").option(
|
|
3068
|
+
"-H, --api-host <url>",
|
|
3069
|
+
"RoxyBrowser API base URL",
|
|
3070
|
+
process.env.ROXY_API_HOST ?? "http://127.0.0.1:50000"
|
|
3071
|
+
).option(
|
|
3072
|
+
"-k, --api-key <key>",
|
|
3073
|
+
"API key (or set ROXY_API_KEY)",
|
|
3074
|
+
process.env.ROXY_API_KEY ?? ""
|
|
3075
|
+
).option(
|
|
3076
|
+
"-t, --timeout <ms>",
|
|
3077
|
+
"Request timeout in milliseconds",
|
|
3078
|
+
(v) => v != null && v !== "" ? Number.parseInt(v, 10) : 3e4,
|
|
3079
|
+
process.env.ROXY_TIMEOUT != null ? Number(process.env.ROXY_TIMEOUT) : 3e4
|
|
3080
|
+
).addHelpText(
|
|
3081
|
+
"after",
|
|
3082
|
+
`
|
|
3083
|
+
Environment (used when option not passed):
|
|
3084
|
+
ROXY_API_HOST API base URL (default: http://127.0.0.1:50000)
|
|
3085
|
+
ROXY_API_KEY API key (required)
|
|
3086
|
+
ROXY_TIMEOUT Timeout in ms (default: 30000)
|
|
3087
|
+
|
|
3088
|
+
Examples:
|
|
3089
|
+
roxy-browser-mcp --api-key "your-key"
|
|
3090
|
+
roxy-browser-mcp -k "your-key" -H http://127.0.0.1:50000
|
|
3091
|
+
ROXY_API_KEY=your-key roxy-browser-mcp
|
|
3092
|
+
`
|
|
3093
|
+
);
|
|
3094
|
+
async function main() {
|
|
3095
|
+
program.parse();
|
|
3096
|
+
const opts = program.opts();
|
|
3097
|
+
if (opts.apiHost != null && opts.apiHost !== "") process.env.ROXY_API_HOST = opts.apiHost;
|
|
3098
|
+
if (opts.apiKey != null && opts.apiKey !== "") process.env.ROXY_API_KEY = opts.apiKey;
|
|
3099
|
+
if (opts.timeout != null) process.env.ROXY_TIMEOUT = String(opts.timeout);
|
|
3100
|
+
try {
|
|
3101
|
+
await runServer();
|
|
3102
|
+
} catch (error) {
|
|
3103
|
+
if (error instanceof ConfigError) {
|
|
3104
|
+
console.error(`\u274C Configuration Error: ${error.message}`);
|
|
3105
|
+
process.exit(1);
|
|
3106
|
+
}
|
|
3107
|
+
console.error("\u274C Unexpected error:", error);
|
|
3108
|
+
process.exit(1);
|
|
3109
|
+
}
|
|
3110
|
+
}
|
|
3111
|
+
main();
|
|
3112
|
+
//# sourceMappingURL=cli.cjs.map
|
|
3113
|
+
//# sourceMappingURL=cli.cjs.map
|