@ai-jshook/mcp 0.1.1 → 0.1.3
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/.env.example +36 -38
- package/README.md +471 -564
- package/dist/modules/collector/CodeCollector.d.ts +5 -0
- package/dist/modules/collector/CodeCollector.d.ts.map +1 -1
- package/dist/modules/collector/CodeCollector.js +61 -1
- package/dist/modules/collector/CodeCollector.js.map +1 -1
- package/dist/modules/emulator/templates/chrome-env.d.ts +2 -2
- package/dist/server/MCPServer.d.ts +5 -8
- package/dist/server/MCPServer.d.ts.map +1 -1
- package/dist/server/MCPServer.js +720 -693
- package/dist/server/MCPServer.js.map +1 -1
- package/dist/services/LLMService.d.ts.map +1 -1
- package/dist/services/LLMService.js +0 -1
- package/dist/services/LLMService.js.map +1 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +0 -12
- package/dist/utils/config.js.map +1 -1
- package/package.json +97 -94
- package/server.json +39 -39
- package/tsconfig.dev.json +14 -14
- package/CLAUDE.md +0 -170
- package/bun.lock +0 -1484
package/dist/server/MCPServer.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
-
import
|
|
3
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
4
4
|
import { logger } from '../utils/logger.js';
|
|
5
5
|
import { CacheManager } from '../utils/cache.js';
|
|
6
6
|
import { CodeCollector } from '../modules/collector/CodeCollector.js';
|
|
@@ -14,6 +14,11 @@ import { BrowserToolHandlers } from './BrowserToolHandlers.js';
|
|
|
14
14
|
import { DebuggerToolHandlers } from './DebuggerToolHandlers.js';
|
|
15
15
|
import { AdvancedToolHandlers } from './AdvancedToolHandlers.js';
|
|
16
16
|
import { AIHookToolHandlers } from './AIHookToolHandlers.js';
|
|
17
|
+
import { browserTools } from './BrowserToolDefinitions.js';
|
|
18
|
+
import { debuggerTools } from './DebuggerToolDefinitions.js';
|
|
19
|
+
import { advancedTools } from './AdvancedToolDefinitions.js';
|
|
20
|
+
import { aiHookTools } from './AIHookToolDefinitions.js';
|
|
21
|
+
import { tokenBudgetTools } from './TokenBudgetToolDefinitions.js';
|
|
17
22
|
import { Deobfuscator } from '../modules/deobfuscator/Deobfuscator.js';
|
|
18
23
|
import { AdvancedDeobfuscator } from '../modules/deobfuscator/AdvancedDeobfuscator.js';
|
|
19
24
|
import { ASTOptimizer } from '../modules/deobfuscator/ASTOptimizer.js';
|
|
@@ -24,6 +29,7 @@ import { CryptoDetector } from '../modules/crypto/CryptoDetector.js';
|
|
|
24
29
|
import { HookManager } from '../modules/hook/HookManager.js';
|
|
25
30
|
import { TokenBudgetManager } from '../utils/TokenBudgetManager.js';
|
|
26
31
|
import { UnifiedCacheManager } from '../utils/UnifiedCacheManager.js';
|
|
32
|
+
import { cacheTools } from './CacheToolDefinitions.js';
|
|
27
33
|
export class MCPServer {
|
|
28
34
|
server;
|
|
29
35
|
cache;
|
|
@@ -73,11 +79,15 @@ export class MCPServer {
|
|
|
73
79
|
logger.info('TokenBudgetManager initialized');
|
|
74
80
|
this.unifiedCache = UnifiedCacheManager.getInstance();
|
|
75
81
|
logger.info('UnifiedCacheManager initialized');
|
|
76
|
-
this.server = new
|
|
82
|
+
this.server = new Server({
|
|
77
83
|
name: config.mcp.name,
|
|
78
84
|
version: config.mcp.version,
|
|
85
|
+
}, {
|
|
86
|
+
capabilities: {
|
|
87
|
+
tools: {},
|
|
88
|
+
},
|
|
79
89
|
});
|
|
80
|
-
this.
|
|
90
|
+
this.setupHandlers();
|
|
81
91
|
logger.info('MCP Server initialized with tools');
|
|
82
92
|
}
|
|
83
93
|
async registerCaches() {
|
|
@@ -107,711 +117,728 @@ export class MCPServer {
|
|
|
107
117
|
logger.warn('Continuing without cache registration');
|
|
108
118
|
}
|
|
109
119
|
}
|
|
110
|
-
|
|
111
|
-
this.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
this.registerCacheTools();
|
|
118
|
-
logger.info('All MCP tools registered');
|
|
119
|
-
}
|
|
120
|
-
registerCoreTools() {
|
|
121
|
-
const server = this.server;
|
|
122
|
-
server.registerTool('collect_code', {
|
|
123
|
-
title: 'Collect Code',
|
|
124
|
-
description: 'Collect JavaScript code from a target website',
|
|
125
|
-
inputSchema: {
|
|
126
|
-
url: z.string().describe('Target website URL'),
|
|
127
|
-
includeInline: z.boolean().optional().default(true),
|
|
128
|
-
includeExternal: z.boolean().optional().default(true),
|
|
129
|
-
includeDynamic: z.boolean().optional().default(false),
|
|
130
|
-
smartMode: z.enum(['summary', 'priority', 'incremental', 'full']).optional().default('full'),
|
|
131
|
-
compress: z.boolean().optional().default(false),
|
|
132
|
-
maxTotalSize: z.number().optional().default(2097152),
|
|
133
|
-
maxFileSize: z.number().optional().default(500),
|
|
134
|
-
priorities: z.array(z.string()).optional(),
|
|
135
|
-
},
|
|
136
|
-
outputSchema: {
|
|
137
|
-
files: z.array(z.object({
|
|
138
|
-
url: z.string(),
|
|
139
|
-
type: z.string(),
|
|
140
|
-
size: z.number(),
|
|
141
|
-
content: z.string(),
|
|
142
|
-
})),
|
|
143
|
-
totalSize: z.number(),
|
|
144
|
-
collectTime: z.number(),
|
|
145
|
-
},
|
|
146
|
-
}, async (args) => {
|
|
147
|
-
const result = await this.collector.collect({
|
|
148
|
-
url: args.url,
|
|
149
|
-
includeInline: args.includeInline,
|
|
150
|
-
includeExternal: args.includeExternal,
|
|
151
|
-
includeDynamic: args.includeDynamic,
|
|
152
|
-
smartMode: args.smartMode,
|
|
153
|
-
compress: args.compress,
|
|
154
|
-
maxTotalSize: args.maxTotalSize,
|
|
155
|
-
maxFileSize: args.maxFileSize ? args.maxFileSize * 1024 : undefined,
|
|
156
|
-
priorities: args.priorities,
|
|
157
|
-
});
|
|
158
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
159
|
-
});
|
|
160
|
-
server.registerTool('search_in_scripts', {
|
|
161
|
-
title: 'Search in Scripts',
|
|
162
|
-
description: 'Search for keywords in collected scripts',
|
|
163
|
-
inputSchema: {
|
|
164
|
-
keyword: z.string().describe('Keyword to search for'),
|
|
165
|
-
isRegex: z.boolean().optional().default(false),
|
|
166
|
-
caseSensitive: z.boolean().optional().default(false),
|
|
167
|
-
contextLines: z.number().optional().default(3),
|
|
168
|
-
maxMatches: z.number().optional().default(100),
|
|
169
|
-
returnSummary: z.boolean().optional().default(false),
|
|
170
|
-
maxContextSize: z.number().optional().default(50000),
|
|
171
|
-
},
|
|
172
|
-
}, async (args) => {
|
|
173
|
-
const result = await this.handleSearchInScripts(args);
|
|
174
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
175
|
-
});
|
|
176
|
-
server.registerTool('extract_function_tree', {
|
|
177
|
-
title: 'Extract Function Tree',
|
|
178
|
-
description: 'Extract a function and its dependencies',
|
|
179
|
-
inputSchema: {
|
|
180
|
-
scriptId: z.string().describe('Script ID'),
|
|
181
|
-
functionName: z.string().describe('Name of the function to extract'),
|
|
182
|
-
maxDepth: z.number().optional().default(3),
|
|
183
|
-
maxSize: z.number().optional().default(500),
|
|
184
|
-
includeComments: z.boolean().optional().default(true),
|
|
185
|
-
},
|
|
186
|
-
}, async (args) => {
|
|
187
|
-
const result = await this.handleExtractFunctionTree(args);
|
|
188
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
189
|
-
});
|
|
190
|
-
server.registerTool('deobfuscate', {
|
|
191
|
-
title: 'Deobfuscate',
|
|
192
|
-
description: 'Deobfuscate JavaScript code',
|
|
193
|
-
inputSchema: {
|
|
194
|
-
code: z.string().describe('Obfuscated code to deobfuscate'),
|
|
195
|
-
aggressive: z.boolean().optional().default(false),
|
|
196
|
-
},
|
|
197
|
-
}, async (args) => {
|
|
198
|
-
const result = await this.handleDeobfuscate(args);
|
|
199
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
200
|
-
});
|
|
201
|
-
server.registerTool('understand_code', {
|
|
202
|
-
title: 'Understand Code',
|
|
203
|
-
description: 'Analyze and understand code structure',
|
|
204
|
-
inputSchema: {
|
|
205
|
-
code: z.string().describe('Code to analyze'),
|
|
206
|
-
context: z.record(z.string(), z.unknown()).optional(),
|
|
207
|
-
focus: z.enum(['structure', 'business', 'security', 'all']).optional().default('all'),
|
|
208
|
-
},
|
|
209
|
-
}, async (args) => {
|
|
210
|
-
const result = await this.handleUnderstandCode(args);
|
|
211
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
212
|
-
});
|
|
213
|
-
server.registerTool('detect_crypto', {
|
|
214
|
-
title: 'Detect Crypto',
|
|
215
|
-
description: 'Detect encryption algorithms in code',
|
|
216
|
-
inputSchema: {
|
|
217
|
-
code: z.string().describe('Code to analyze'),
|
|
218
|
-
},
|
|
219
|
-
}, async (args) => {
|
|
220
|
-
const result = await this.handleDetectCrypto(args);
|
|
221
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
222
|
-
});
|
|
223
|
-
server.registerTool('manage_hooks', {
|
|
224
|
-
title: 'Manage Hooks',
|
|
225
|
-
description: 'Manage JavaScript hooks',
|
|
226
|
-
inputSchema: {
|
|
227
|
-
action: z.enum(['create', 'list', 'records', 'clear']).describe('Action'),
|
|
228
|
-
target: z.string().optional(),
|
|
229
|
-
type: z.enum(['function', 'xhr', 'fetch', 'websocket', 'localstorage', 'cookie']).optional(),
|
|
230
|
-
hookAction: z.enum(['log', 'block', 'modify']).optional().default('log'),
|
|
231
|
-
customCode: z.string().optional(),
|
|
232
|
-
hookId: z.string().optional(),
|
|
233
|
-
},
|
|
234
|
-
}, async (args) => {
|
|
235
|
-
const result = await this.handleManageHooks(args);
|
|
236
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
237
|
-
});
|
|
238
|
-
server.registerTool('detect_obfuscation', {
|
|
239
|
-
title: 'Detect Obfuscation',
|
|
240
|
-
description: 'Detect obfuscation types in code',
|
|
241
|
-
inputSchema: {
|
|
242
|
-
code: z.string().describe('Code to analyze'),
|
|
243
|
-
generateReport: z.boolean().optional().default(true),
|
|
244
|
-
},
|
|
245
|
-
}, async (args) => {
|
|
246
|
-
const result = await this.handleDetectObfuscation(args);
|
|
247
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
248
|
-
});
|
|
249
|
-
server.registerTool('advanced_deobfuscate', {
|
|
250
|
-
title: 'Advanced Deobfuscate',
|
|
251
|
-
description: 'Advanced deobfuscation with VM support',
|
|
252
|
-
inputSchema: {
|
|
253
|
-
code: z.string().describe('Code to deobfuscate'),
|
|
254
|
-
detectOnly: z.boolean().optional().default(false),
|
|
255
|
-
aggressiveVM: z.boolean().optional().default(false),
|
|
256
|
-
useASTOptimization: z.boolean().optional().default(true),
|
|
257
|
-
timeout: z.number().optional().default(60000),
|
|
258
|
-
},
|
|
259
|
-
}, async (args) => {
|
|
260
|
-
const result = await this.handleAdvancedDeobfuscate(args);
|
|
261
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
262
|
-
});
|
|
263
|
-
server.registerTool('clear_collected_data', {
|
|
264
|
-
title: 'Clear Collected Data',
|
|
265
|
-
description: 'Clear all collected data',
|
|
266
|
-
inputSchema: {},
|
|
267
|
-
}, async () => {
|
|
268
|
-
const result = await this.handleClearCollectedData({});
|
|
269
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
120
|
+
setupHandlers() {
|
|
121
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
122
|
+
const tools = this.getTools();
|
|
123
|
+
logger.info(`Returning ${tools.length} tools`);
|
|
124
|
+
return {
|
|
125
|
+
tools,
|
|
126
|
+
};
|
|
270
127
|
});
|
|
271
|
-
server.
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
128
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
129
|
+
const { name, arguments: args } = request.params;
|
|
130
|
+
logger.info(`Tool called: ${name}`);
|
|
131
|
+
try {
|
|
132
|
+
const toolArgs = args || {};
|
|
133
|
+
const response = await this.executeToolWithTracking(name, toolArgs);
|
|
134
|
+
return response;
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
logger.error(`Tool execution failed: ${name}`, error);
|
|
138
|
+
return {
|
|
139
|
+
content: [
|
|
140
|
+
{
|
|
141
|
+
type: 'text',
|
|
142
|
+
text: `Error: ${error.message}`,
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
isError: true,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
278
148
|
});
|
|
279
149
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
server.registerTool('browser_close', {
|
|
295
|
-
title: 'Browser Close',
|
|
296
|
-
description: 'Close the browser',
|
|
297
|
-
inputSchema: {},
|
|
298
|
-
}, async () => {
|
|
299
|
-
const result = await this.browserHandlers.handleBrowserClose({});
|
|
300
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
301
|
-
});
|
|
302
|
-
server.registerTool('browser_status', {
|
|
303
|
-
title: 'Browser Status',
|
|
304
|
-
description: 'Get browser status',
|
|
305
|
-
inputSchema: {},
|
|
306
|
-
}, async () => {
|
|
307
|
-
const result = await this.browserHandlers.handleBrowserStatus({});
|
|
308
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
309
|
-
});
|
|
310
|
-
server.registerTool('page_navigate', {
|
|
311
|
-
title: 'Page Navigate',
|
|
312
|
-
description: 'Navigate to a URL',
|
|
313
|
-
inputSchema: {
|
|
314
|
-
url: z.string().describe('URL to navigate to'),
|
|
315
|
-
waitUntil: z.enum(['load', 'domcontentloaded', 'networkidle', 'commit']).optional().default('networkidle'),
|
|
316
|
-
},
|
|
317
|
-
}, async (args) => {
|
|
318
|
-
const result = await this.browserHandlers.handlePageNavigate(args);
|
|
319
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
320
|
-
});
|
|
321
|
-
server.registerTool('page_reload', {
|
|
322
|
-
title: 'Page Reload',
|
|
323
|
-
description: 'Reload current page',
|
|
324
|
-
inputSchema: {},
|
|
325
|
-
}, async () => {
|
|
326
|
-
const result = await this.browserHandlers.handlePageReload({});
|
|
327
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
328
|
-
});
|
|
329
|
-
server.registerTool('page_screenshot', {
|
|
330
|
-
title: 'Page Screenshot',
|
|
331
|
-
description: 'Take a screenshot of the page',
|
|
332
|
-
inputSchema: {
|
|
333
|
-
fullPage: z.boolean().optional().default(false),
|
|
334
|
-
path: z.string().optional(),
|
|
335
|
-
},
|
|
336
|
-
}, async (args) => {
|
|
337
|
-
const result = await this.browserHandlers.handlePageScreenshot(args);
|
|
338
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
339
|
-
});
|
|
340
|
-
server.registerTool('dom_query_selector', {
|
|
341
|
-
title: 'DOM Query Selector',
|
|
342
|
-
description: 'Query a single element',
|
|
343
|
-
inputSchema: {
|
|
344
|
-
selector: z.string().describe('CSS selector'),
|
|
345
|
-
},
|
|
346
|
-
}, async (args) => {
|
|
347
|
-
const result = await this.browserHandlers.handleDOMQuerySelector(args);
|
|
348
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
349
|
-
});
|
|
350
|
-
server.registerTool('dom_query_all', {
|
|
351
|
-
title: 'DOM Query All',
|
|
352
|
-
description: 'Query multiple elements',
|
|
353
|
-
inputSchema: {
|
|
354
|
-
selector: z.string().describe('CSS selector'),
|
|
355
|
-
},
|
|
356
|
-
}, async (args) => {
|
|
357
|
-
const result = await this.browserHandlers.handleDOMQueryAll(args);
|
|
358
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
359
|
-
});
|
|
360
|
-
server.registerTool('page_evaluate', {
|
|
361
|
-
title: 'Page Evaluate',
|
|
362
|
-
description: 'Execute JavaScript in page context',
|
|
363
|
-
inputSchema: {
|
|
364
|
-
script: z.string().describe('JavaScript code to execute'),
|
|
365
|
-
},
|
|
366
|
-
}, async (args) => {
|
|
367
|
-
const result = await this.browserHandlers.handlePageEvaluate(args);
|
|
368
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
369
|
-
});
|
|
370
|
-
server.registerTool('page_click', {
|
|
371
|
-
title: 'Page Click',
|
|
372
|
-
description: 'Click on an element',
|
|
373
|
-
inputSchema: {
|
|
374
|
-
selector: z.string().describe('CSS selector'),
|
|
375
|
-
delay: z.number().optional(),
|
|
376
|
-
},
|
|
377
|
-
}, async (args) => {
|
|
378
|
-
const result = await this.browserHandlers.handlePageClick(args);
|
|
379
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
380
|
-
});
|
|
381
|
-
server.registerTool('page_type', {
|
|
382
|
-
title: 'Page Type',
|
|
383
|
-
description: 'Type text into an input',
|
|
384
|
-
inputSchema: {
|
|
385
|
-
selector: z.string().describe('CSS selector'),
|
|
386
|
-
text: z.string().describe('Text to type'),
|
|
387
|
-
delay: z.number().optional(),
|
|
388
|
-
},
|
|
389
|
-
}, async (args) => {
|
|
390
|
-
const result = await this.browserHandlers.handlePageType(args);
|
|
391
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
392
|
-
});
|
|
393
|
-
server.registerTool('captcha_detect', {
|
|
394
|
-
title: 'CAPTCHA Detect',
|
|
395
|
-
description: 'Detect if page has CAPTCHA',
|
|
396
|
-
inputSchema: {},
|
|
397
|
-
}, async () => {
|
|
398
|
-
const result = await this.browserHandlers.handleCaptchaDetect({});
|
|
399
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
400
|
-
});
|
|
401
|
-
server.registerTool('captcha_wait', {
|
|
402
|
-
title: 'CAPTCHA Wait',
|
|
403
|
-
description: 'Wait for CAPTCHA to be solved',
|
|
404
|
-
inputSchema: {
|
|
405
|
-
timeout: z.number().optional().default(300000),
|
|
406
|
-
},
|
|
407
|
-
}, async (args) => {
|
|
408
|
-
const result = await this.browserHandlers.handleCaptchaWait(args);
|
|
409
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
410
|
-
});
|
|
411
|
-
server.registerTool('stealth_inject', {
|
|
412
|
-
title: 'Stealth Inject',
|
|
413
|
-
description: 'Inject anti-detection scripts',
|
|
414
|
-
inputSchema: {},
|
|
415
|
-
}, async () => {
|
|
416
|
-
const result = await this.browserHandlers.handleStealthInject({});
|
|
417
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
418
|
-
});
|
|
419
|
-
server.registerTool('console_enable', {
|
|
420
|
-
title: 'Console Enable',
|
|
421
|
-
description: 'Enable console monitoring',
|
|
422
|
-
inputSchema: {},
|
|
423
|
-
}, async () => {
|
|
424
|
-
const result = await this.browserHandlers.handleConsoleEnable({});
|
|
425
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
426
|
-
});
|
|
427
|
-
server.registerTool('console_get_logs', {
|
|
428
|
-
title: 'Console Get Logs',
|
|
429
|
-
description: 'Get captured console logs',
|
|
430
|
-
inputSchema: {},
|
|
431
|
-
}, async () => {
|
|
432
|
-
const result = await this.browserHandlers.handleConsoleGetLogs({});
|
|
433
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
434
|
-
});
|
|
435
|
-
server.registerTool('get_all_scripts', {
|
|
436
|
-
title: 'Get All Scripts',
|
|
437
|
-
description: 'Get all collected scripts',
|
|
438
|
-
inputSchema: {},
|
|
439
|
-
}, async () => {
|
|
440
|
-
const result = await this.browserHandlers.handleGetAllScripts({});
|
|
441
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
442
|
-
});
|
|
443
|
-
server.registerTool('get_script_source', {
|
|
444
|
-
title: 'Get Script Source',
|
|
445
|
-
description: 'Get source code of a script',
|
|
446
|
-
inputSchema: {
|
|
447
|
-
scriptId: z.string().describe('Script ID'),
|
|
448
|
-
},
|
|
449
|
-
}, async (args) => {
|
|
450
|
-
const result = await this.browserHandlers.handleGetScriptSource(args);
|
|
451
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
452
|
-
});
|
|
453
|
-
server.registerTool('network_enable', {
|
|
454
|
-
title: 'Network Enable',
|
|
455
|
-
description: 'Enable network monitoring',
|
|
456
|
-
inputSchema: {},
|
|
457
|
-
}, async () => {
|
|
458
|
-
const result = await this.advancedHandlers.handleNetworkEnable({});
|
|
459
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
460
|
-
});
|
|
461
|
-
server.registerTool('network_get_requests', {
|
|
462
|
-
title: 'Network Get Requests',
|
|
463
|
-
description: 'Get captured network requests',
|
|
464
|
-
inputSchema: {},
|
|
465
|
-
}, async () => {
|
|
466
|
-
const result = await this.advancedHandlers.handleNetworkGetRequests({});
|
|
467
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
468
|
-
});
|
|
150
|
+
async executeToolWithTracking(name, args) {
|
|
151
|
+
try {
|
|
152
|
+
const response = await this.executeToolInternal(name, args);
|
|
153
|
+
this.tokenBudget.recordToolCall(name, args, response);
|
|
154
|
+
return response;
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
const errorResponse = {
|
|
158
|
+
content: [{ type: 'text', text: `Error: ${error.message}` }],
|
|
159
|
+
isError: true,
|
|
160
|
+
};
|
|
161
|
+
this.tokenBudget.recordToolCall(name, args, errorResponse);
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
469
164
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
165
|
+
async executeToolInternal(name, toolArgs) {
|
|
166
|
+
switch (name) {
|
|
167
|
+
case 'get_token_budget_stats':
|
|
168
|
+
return await this.handleGetTokenBudgetStats(toolArgs);
|
|
169
|
+
case 'manual_token_cleanup':
|
|
170
|
+
return await this.handleManualTokenCleanup(toolArgs);
|
|
171
|
+
case 'reset_token_budget':
|
|
172
|
+
return await this.handleResetTokenBudget(toolArgs);
|
|
173
|
+
case 'get_cache_stats':
|
|
174
|
+
return await this.handleGetCacheStats(toolArgs);
|
|
175
|
+
case 'smart_cache_cleanup':
|
|
176
|
+
return await this.handleSmartCacheCleanup(toolArgs);
|
|
177
|
+
case 'clear_all_caches':
|
|
178
|
+
return await this.handleClearAllCaches(toolArgs);
|
|
179
|
+
case 'collect_code':
|
|
180
|
+
return await this.handleCollectCode(toolArgs);
|
|
181
|
+
case 'search_in_scripts':
|
|
182
|
+
return await this.handleSearchInScripts(toolArgs);
|
|
183
|
+
case 'extract_function_tree':
|
|
184
|
+
return await this.handleExtractFunctionTree(toolArgs);
|
|
185
|
+
case 'deobfuscate':
|
|
186
|
+
return await this.handleDeobfuscate(toolArgs);
|
|
187
|
+
case 'understand_code':
|
|
188
|
+
return await this.handleUnderstandCode(toolArgs);
|
|
189
|
+
case 'detect_crypto':
|
|
190
|
+
return await this.handleDetectCrypto(toolArgs);
|
|
191
|
+
case 'manage_hooks':
|
|
192
|
+
return await this.handleManageHooks(toolArgs);
|
|
193
|
+
case 'detect_obfuscation':
|
|
194
|
+
return await this.handleDetectObfuscation(toolArgs);
|
|
195
|
+
case 'advanced_deobfuscate':
|
|
196
|
+
return await this.handleAdvancedDeobfuscate(toolArgs);
|
|
197
|
+
case 'clear_collected_data':
|
|
198
|
+
return await this.handleClearCollectedData(toolArgs);
|
|
199
|
+
case 'get_collection_stats':
|
|
200
|
+
return await this.handleGetCollectionStats(toolArgs);
|
|
201
|
+
case 'get_detailed_data':
|
|
202
|
+
return await this.browserHandlers.handleGetDetailedData(toolArgs);
|
|
203
|
+
case 'browser_launch':
|
|
204
|
+
return await this.browserHandlers.handleBrowserLaunch(toolArgs);
|
|
205
|
+
case 'browser_close':
|
|
206
|
+
return await this.browserHandlers.handleBrowserClose(toolArgs);
|
|
207
|
+
case 'browser_status':
|
|
208
|
+
return await this.browserHandlers.handleBrowserStatus(toolArgs);
|
|
209
|
+
case 'page_navigate':
|
|
210
|
+
return await this.browserHandlers.handlePageNavigate(toolArgs);
|
|
211
|
+
case 'page_reload':
|
|
212
|
+
return await this.browserHandlers.handlePageReload(toolArgs);
|
|
213
|
+
case 'page_back':
|
|
214
|
+
return await this.browserHandlers.handlePageBack(toolArgs);
|
|
215
|
+
case 'page_forward':
|
|
216
|
+
return await this.browserHandlers.handlePageForward(toolArgs);
|
|
217
|
+
case 'dom_query_selector':
|
|
218
|
+
return await this.browserHandlers.handleDOMQuerySelector(toolArgs);
|
|
219
|
+
case 'dom_query_all':
|
|
220
|
+
return await this.browserHandlers.handleDOMQueryAll(toolArgs);
|
|
221
|
+
case 'dom_get_structure':
|
|
222
|
+
return await this.browserHandlers.handleDOMGetStructure(toolArgs);
|
|
223
|
+
case 'dom_find_clickable':
|
|
224
|
+
return await this.browserHandlers.handleDOMFindClickable(toolArgs);
|
|
225
|
+
case 'page_click':
|
|
226
|
+
return await this.browserHandlers.handlePageClick(toolArgs);
|
|
227
|
+
case 'page_type':
|
|
228
|
+
return await this.browserHandlers.handlePageType(toolArgs);
|
|
229
|
+
case 'page_select':
|
|
230
|
+
return await this.browserHandlers.handlePageSelect(toolArgs);
|
|
231
|
+
case 'page_hover':
|
|
232
|
+
return await this.browserHandlers.handlePageHover(toolArgs);
|
|
233
|
+
case 'page_scroll':
|
|
234
|
+
return await this.browserHandlers.handlePageScroll(toolArgs);
|
|
235
|
+
case 'page_wait_for_selector':
|
|
236
|
+
return await this.browserHandlers.handlePageWaitForSelector(toolArgs);
|
|
237
|
+
case 'page_evaluate':
|
|
238
|
+
return await this.browserHandlers.handlePageEvaluate(toolArgs);
|
|
239
|
+
case 'page_screenshot':
|
|
240
|
+
return await this.browserHandlers.handlePageScreenshot(toolArgs);
|
|
241
|
+
case 'get_all_scripts':
|
|
242
|
+
return await this.browserHandlers.handleGetAllScripts(toolArgs);
|
|
243
|
+
case 'get_script_source':
|
|
244
|
+
return await this.browserHandlers.handleGetScriptSource(toolArgs);
|
|
245
|
+
case 'console_enable':
|
|
246
|
+
return await this.browserHandlers.handleConsoleEnable(toolArgs);
|
|
247
|
+
case 'console_get_logs':
|
|
248
|
+
return await this.browserHandlers.handleConsoleGetLogs(toolArgs);
|
|
249
|
+
case 'console_execute':
|
|
250
|
+
return await this.browserHandlers.handleConsoleExecute(toolArgs);
|
|
251
|
+
case 'dom_get_computed_style':
|
|
252
|
+
return await this.browserHandlers.handleDOMGetComputedStyle(toolArgs);
|
|
253
|
+
case 'dom_find_by_text':
|
|
254
|
+
return await this.browserHandlers.handleDOMFindByText(toolArgs);
|
|
255
|
+
case 'dom_get_xpath':
|
|
256
|
+
return await this.browserHandlers.handleDOMGetXPath(toolArgs);
|
|
257
|
+
case 'dom_is_in_viewport':
|
|
258
|
+
return await this.browserHandlers.handleDOMIsInViewport(toolArgs);
|
|
259
|
+
case 'page_get_performance':
|
|
260
|
+
return await this.browserHandlers.handlePageGetPerformance(toolArgs);
|
|
261
|
+
case 'page_inject_script':
|
|
262
|
+
return await this.browserHandlers.handlePageInjectScript(toolArgs);
|
|
263
|
+
case 'page_set_cookies':
|
|
264
|
+
return await this.browserHandlers.handlePageSetCookies(toolArgs);
|
|
265
|
+
case 'page_get_cookies':
|
|
266
|
+
return await this.browserHandlers.handlePageGetCookies(toolArgs);
|
|
267
|
+
case 'page_clear_cookies':
|
|
268
|
+
return await this.browserHandlers.handlePageClearCookies(toolArgs);
|
|
269
|
+
case 'page_set_viewport':
|
|
270
|
+
return await this.browserHandlers.handlePageSetViewport(toolArgs);
|
|
271
|
+
case 'page_emulate_device':
|
|
272
|
+
return await this.browserHandlers.handlePageEmulateDevice(toolArgs);
|
|
273
|
+
case 'page_get_local_storage':
|
|
274
|
+
return await this.browserHandlers.handlePageGetLocalStorage(toolArgs);
|
|
275
|
+
case 'page_set_local_storage':
|
|
276
|
+
return await this.browserHandlers.handlePageSetLocalStorage(toolArgs);
|
|
277
|
+
case 'page_press_key':
|
|
278
|
+
return await this.browserHandlers.handlePagePressKey(toolArgs);
|
|
279
|
+
case 'page_get_all_links':
|
|
280
|
+
return await this.browserHandlers.handlePageGetAllLinks(toolArgs);
|
|
281
|
+
case 'captcha_detect':
|
|
282
|
+
return await this.browserHandlers.handleCaptchaDetect(toolArgs);
|
|
283
|
+
case 'captcha_wait':
|
|
284
|
+
return await this.browserHandlers.handleCaptchaWait(toolArgs);
|
|
285
|
+
case 'captcha_config':
|
|
286
|
+
return await this.browserHandlers.handleCaptchaConfig(toolArgs);
|
|
287
|
+
case 'stealth_inject':
|
|
288
|
+
return await this.browserHandlers.handleStealthInject(toolArgs);
|
|
289
|
+
case 'stealth_set_user_agent':
|
|
290
|
+
return await this.browserHandlers.handleStealthSetUserAgent(toolArgs);
|
|
291
|
+
case 'ai_hook_generate':
|
|
292
|
+
return await this.aiHookHandlers.handleAIHookGenerate(toolArgs);
|
|
293
|
+
case 'ai_hook_inject':
|
|
294
|
+
return await this.aiHookHandlers.handleAIHookInject(toolArgs);
|
|
295
|
+
case 'ai_hook_get_data':
|
|
296
|
+
return await this.aiHookHandlers.handleAIHookGetData(toolArgs);
|
|
297
|
+
case 'ai_hook_list':
|
|
298
|
+
return await this.aiHookHandlers.handleAIHookList(toolArgs);
|
|
299
|
+
case 'ai_hook_clear':
|
|
300
|
+
return await this.aiHookHandlers.handleAIHookClear(toolArgs);
|
|
301
|
+
case 'ai_hook_toggle':
|
|
302
|
+
return await this.aiHookHandlers.handleAIHookToggle(toolArgs);
|
|
303
|
+
case 'ai_hook_export':
|
|
304
|
+
return await this.aiHookHandlers.handleAIHookExport(toolArgs);
|
|
305
|
+
case 'debugger_enable':
|
|
306
|
+
return await this.debuggerHandlers.handleDebuggerEnable(toolArgs);
|
|
307
|
+
case 'debugger_disable':
|
|
308
|
+
return await this.debuggerHandlers.handleDebuggerDisable(toolArgs);
|
|
309
|
+
case 'debugger_pause':
|
|
310
|
+
return await this.debuggerHandlers.handleDebuggerPause(toolArgs);
|
|
311
|
+
case 'debugger_resume':
|
|
312
|
+
return await this.debuggerHandlers.handleDebuggerResume(toolArgs);
|
|
313
|
+
case 'debugger_step_into':
|
|
314
|
+
return await this.debuggerHandlers.handleDebuggerStepInto(toolArgs);
|
|
315
|
+
case 'debugger_step_over':
|
|
316
|
+
return await this.debuggerHandlers.handleDebuggerStepOver(toolArgs);
|
|
317
|
+
case 'debugger_step_out':
|
|
318
|
+
return await this.debuggerHandlers.handleDebuggerStepOut(toolArgs);
|
|
319
|
+
case 'breakpoint_set':
|
|
320
|
+
return await this.debuggerHandlers.handleBreakpointSet(toolArgs);
|
|
321
|
+
case 'breakpoint_remove':
|
|
322
|
+
return await this.debuggerHandlers.handleBreakpointRemove(toolArgs);
|
|
323
|
+
case 'breakpoint_list':
|
|
324
|
+
return await this.debuggerHandlers.handleBreakpointList(toolArgs);
|
|
325
|
+
case 'get_call_stack':
|
|
326
|
+
return await this.debuggerHandlers.handleGetCallStack(toolArgs);
|
|
327
|
+
case 'debugger_evaluate':
|
|
328
|
+
return await this.debuggerHandlers.handleDebuggerEvaluate(toolArgs);
|
|
329
|
+
case 'debugger_evaluate_global':
|
|
330
|
+
return await this.debuggerHandlers.handleDebuggerEvaluateGlobal(toolArgs);
|
|
331
|
+
case 'debugger_wait_for_paused':
|
|
332
|
+
return await this.debuggerHandlers.handleDebuggerWaitForPaused(toolArgs);
|
|
333
|
+
case 'debugger_get_paused_state':
|
|
334
|
+
return await this.debuggerHandlers.handleDebuggerGetPausedState(toolArgs);
|
|
335
|
+
case 'breakpoint_set_on_exception':
|
|
336
|
+
return await this.debuggerHandlers.handleBreakpointSetOnException(toolArgs);
|
|
337
|
+
case 'get_object_properties':
|
|
338
|
+
return await this.debuggerHandlers.handleGetObjectProperties(toolArgs);
|
|
339
|
+
case 'get_scope_variables_enhanced':
|
|
340
|
+
return await this.debuggerHandlers.handleGetScopeVariablesEnhanced(toolArgs);
|
|
341
|
+
case 'debugger_save_session':
|
|
342
|
+
return await this.debuggerHandlers.handleSaveSession(toolArgs);
|
|
343
|
+
case 'debugger_load_session':
|
|
344
|
+
return await this.debuggerHandlers.handleLoadSession(toolArgs);
|
|
345
|
+
case 'debugger_export_session':
|
|
346
|
+
return await this.debuggerHandlers.handleExportSession(toolArgs);
|
|
347
|
+
case 'debugger_list_sessions':
|
|
348
|
+
return await this.debuggerHandlers.handleListSessions(toolArgs);
|
|
349
|
+
case 'watch_add':
|
|
350
|
+
return await this.debuggerHandlers.handleWatchAdd(toolArgs);
|
|
351
|
+
case 'watch_remove':
|
|
352
|
+
return await this.debuggerHandlers.handleWatchRemove(toolArgs);
|
|
353
|
+
case 'watch_list':
|
|
354
|
+
return await this.debuggerHandlers.handleWatchList(toolArgs);
|
|
355
|
+
case 'watch_evaluate_all':
|
|
356
|
+
return await this.debuggerHandlers.handleWatchEvaluateAll(toolArgs);
|
|
357
|
+
case 'watch_clear_all':
|
|
358
|
+
return await this.debuggerHandlers.handleWatchClearAll(toolArgs);
|
|
359
|
+
case 'xhr_breakpoint_set':
|
|
360
|
+
return await this.debuggerHandlers.handleXHRBreakpointSet(toolArgs);
|
|
361
|
+
case 'xhr_breakpoint_remove':
|
|
362
|
+
return await this.debuggerHandlers.handleXHRBreakpointRemove(toolArgs);
|
|
363
|
+
case 'xhr_breakpoint_list':
|
|
364
|
+
return await this.debuggerHandlers.handleXHRBreakpointList(toolArgs);
|
|
365
|
+
case 'event_breakpoint_set':
|
|
366
|
+
return await this.debuggerHandlers.handleEventBreakpointSet(toolArgs);
|
|
367
|
+
case 'event_breakpoint_set_category':
|
|
368
|
+
return await this.debuggerHandlers.handleEventBreakpointSetCategory(toolArgs);
|
|
369
|
+
case 'event_breakpoint_remove':
|
|
370
|
+
return await this.debuggerHandlers.handleEventBreakpointRemove(toolArgs);
|
|
371
|
+
case 'event_breakpoint_list':
|
|
372
|
+
return await this.debuggerHandlers.handleEventBreakpointList(toolArgs);
|
|
373
|
+
case 'blackbox_add':
|
|
374
|
+
return await this.debuggerHandlers.handleBlackboxAdd(toolArgs);
|
|
375
|
+
case 'blackbox_add_common':
|
|
376
|
+
return await this.debuggerHandlers.handleBlackboxAddCommon(toolArgs);
|
|
377
|
+
case 'blackbox_list':
|
|
378
|
+
return await this.debuggerHandlers.handleBlackboxList(toolArgs);
|
|
379
|
+
case 'network_enable':
|
|
380
|
+
return await this.advancedHandlers.handleNetworkEnable(toolArgs);
|
|
381
|
+
case 'network_disable':
|
|
382
|
+
return await this.advancedHandlers.handleNetworkDisable(toolArgs);
|
|
383
|
+
case 'network_get_status':
|
|
384
|
+
return await this.advancedHandlers.handleNetworkGetStatus(toolArgs);
|
|
385
|
+
case 'network_get_requests':
|
|
386
|
+
return await this.advancedHandlers.handleNetworkGetRequests(toolArgs);
|
|
387
|
+
case 'network_get_response_body':
|
|
388
|
+
return await this.advancedHandlers.handleNetworkGetResponseBody(toolArgs);
|
|
389
|
+
case 'network_get_stats':
|
|
390
|
+
return await this.advancedHandlers.handleNetworkGetStats(toolArgs);
|
|
391
|
+
case 'performance_get_metrics':
|
|
392
|
+
return await this.advancedHandlers.handlePerformanceGetMetrics(toolArgs);
|
|
393
|
+
case 'performance_start_coverage':
|
|
394
|
+
return await this.advancedHandlers.handlePerformanceStartCoverage(toolArgs);
|
|
395
|
+
case 'performance_stop_coverage':
|
|
396
|
+
return await this.advancedHandlers.handlePerformanceStopCoverage(toolArgs);
|
|
397
|
+
case 'performance_take_heap_snapshot':
|
|
398
|
+
return await this.advancedHandlers.handlePerformanceTakeHeapSnapshot(toolArgs);
|
|
399
|
+
case 'console_get_exceptions':
|
|
400
|
+
return await this.advancedHandlers.handleConsoleGetExceptions(toolArgs);
|
|
401
|
+
case 'console_inject_script_monitor':
|
|
402
|
+
return await this.advancedHandlers.handleConsoleInjectScriptMonitor(toolArgs);
|
|
403
|
+
case 'console_inject_xhr_interceptor':
|
|
404
|
+
return await this.advancedHandlers.handleConsoleInjectXhrInterceptor(toolArgs);
|
|
405
|
+
case 'console_inject_fetch_interceptor':
|
|
406
|
+
return await this.advancedHandlers.handleConsoleInjectFetchInterceptor(toolArgs);
|
|
407
|
+
case 'console_inject_function_tracer':
|
|
408
|
+
return await this.advancedHandlers.handleConsoleInjectFunctionTracer(toolArgs);
|
|
409
|
+
default:
|
|
410
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
getTools() {
|
|
414
|
+
return [
|
|
415
|
+
{
|
|
416
|
+
name: 'collect_code',
|
|
417
|
+
description: 'Collect JavaScript code from a target website. 🆕 Supports smart collection modes: summary (fast analysis), priority (key code first), full (complete). Use summary mode for large websites to avoid token overflow.',
|
|
418
|
+
inputSchema: {
|
|
419
|
+
type: 'object',
|
|
420
|
+
properties: {
|
|
421
|
+
url: {
|
|
422
|
+
type: 'string',
|
|
423
|
+
description: 'Target website URL',
|
|
424
|
+
},
|
|
425
|
+
includeInline: {
|
|
426
|
+
type: 'boolean',
|
|
427
|
+
description: 'Include inline scripts',
|
|
428
|
+
default: true,
|
|
429
|
+
},
|
|
430
|
+
includeExternal: {
|
|
431
|
+
type: 'boolean',
|
|
432
|
+
description: 'Include external scripts',
|
|
433
|
+
default: true,
|
|
434
|
+
},
|
|
435
|
+
includeDynamic: {
|
|
436
|
+
type: 'boolean',
|
|
437
|
+
description: 'Include dynamically loaded scripts',
|
|
438
|
+
default: false,
|
|
439
|
+
},
|
|
440
|
+
smartMode: {
|
|
441
|
+
type: 'string',
|
|
442
|
+
description: '🆕 Smart collection mode: "summary" (only metadata, fastest), "priority" (key code first), "incremental" (on-demand), "full" (all code, default)',
|
|
443
|
+
enum: ['summary', 'priority', 'incremental', 'full'],
|
|
444
|
+
default: 'full',
|
|
445
|
+
},
|
|
446
|
+
compress: {
|
|
447
|
+
type: 'boolean',
|
|
448
|
+
description: '🆕 Enable gzip compression (70-90% size reduction). Compression info saved in metadata.',
|
|
449
|
+
default: false,
|
|
450
|
+
},
|
|
451
|
+
maxTotalSize: {
|
|
452
|
+
type: 'number',
|
|
453
|
+
description: '🆕 Maximum total size in bytes (default: 2MB). Used with priority/incremental modes.',
|
|
454
|
+
default: 2097152,
|
|
455
|
+
},
|
|
456
|
+
maxFileSize: {
|
|
457
|
+
type: 'number',
|
|
458
|
+
description: 'Maximum single file size in KB (default: 500KB). Files larger than this will be truncated.',
|
|
459
|
+
default: 500,
|
|
460
|
+
},
|
|
461
|
+
priorities: {
|
|
462
|
+
type: 'array',
|
|
463
|
+
description: '🆕 Priority URL patterns for priority mode (e.g., ["encrypt", "crypto", "sign"]). Files matching these patterns are collected first.',
|
|
464
|
+
items: { type: 'string' },
|
|
465
|
+
},
|
|
466
|
+
returnSummaryOnly: {
|
|
467
|
+
type: 'boolean',
|
|
468
|
+
description: '⚠️ DEPRECATED: Use smartMode="summary" instead.',
|
|
469
|
+
default: false,
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
required: ['url'],
|
|
473
|
+
},
|
|
548
474
|
},
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
475
|
+
{
|
|
476
|
+
name: 'search_in_scripts',
|
|
477
|
+
description: `🆕 Search for keywords in collected scripts. Auto-truncates large results to avoid context overflow.
|
|
478
|
+
|
|
479
|
+
Use this tool when:
|
|
480
|
+
- You need to find where a specific function/variable is defined
|
|
481
|
+
- Looking for API endpoints or encryption algorithms
|
|
482
|
+
- Searching for specific patterns in large codebases
|
|
483
|
+
|
|
484
|
+
⚠️ IMPORTANT: Large results (>50KB) automatically return summary only. Use specific keywords to reduce matches.
|
|
485
|
+
|
|
486
|
+
Example:
|
|
487
|
+
search_in_scripts(keyword="a_bogus", contextLines=5, maxMatches=50)
|
|
488
|
+
→ Returns all occurrences with surrounding code`,
|
|
489
|
+
inputSchema: {
|
|
490
|
+
type: 'object',
|
|
491
|
+
properties: {
|
|
492
|
+
keyword: {
|
|
493
|
+
type: 'string',
|
|
494
|
+
description: 'Keyword to search for (supports regex if isRegex=true)',
|
|
495
|
+
},
|
|
496
|
+
isRegex: {
|
|
497
|
+
type: 'boolean',
|
|
498
|
+
description: 'Whether the keyword is a regular expression',
|
|
499
|
+
default: false,
|
|
500
|
+
},
|
|
501
|
+
caseSensitive: {
|
|
502
|
+
type: 'boolean',
|
|
503
|
+
description: 'Whether the search is case-sensitive',
|
|
504
|
+
default: false,
|
|
505
|
+
},
|
|
506
|
+
contextLines: {
|
|
507
|
+
type: 'number',
|
|
508
|
+
description: 'Number of context lines to include before and after matches',
|
|
509
|
+
default: 3,
|
|
510
|
+
},
|
|
511
|
+
maxMatches: {
|
|
512
|
+
type: 'number',
|
|
513
|
+
description: 'Maximum number of matches to return (default: 100). Reduce this if getting summary-only results.',
|
|
514
|
+
default: 100,
|
|
515
|
+
},
|
|
516
|
+
returnSummary: {
|
|
517
|
+
type: 'boolean',
|
|
518
|
+
description: '🆕 Return summary only (match count, preview) instead of full results. Useful for large result sets.',
|
|
519
|
+
default: false,
|
|
520
|
+
},
|
|
521
|
+
maxContextSize: {
|
|
522
|
+
type: 'number',
|
|
523
|
+
description: '🆕 Maximum result size in bytes (default: 50KB). Results larger than this return summary only.',
|
|
524
|
+
default: 50000,
|
|
525
|
+
},
|
|
526
|
+
},
|
|
527
|
+
required: ['keyword'],
|
|
528
|
+
},
|
|
574
529
|
},
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
530
|
+
{
|
|
531
|
+
name: 'extract_function_tree',
|
|
532
|
+
description: `Extract a function and all its dependencies from collected scripts.
|
|
533
|
+
|
|
534
|
+
This tool solves the context overflow problem by extracting only relevant code instead of analyzing entire files.
|
|
535
|
+
|
|
536
|
+
Use this tool when:
|
|
537
|
+
- You want to analyze a specific function (e.g., "sign", "encrypt")
|
|
538
|
+
- Need to understand function dependencies
|
|
539
|
+
- Want to avoid context overflow with large files
|
|
540
|
+
|
|
541
|
+
Example workflow:
|
|
542
|
+
1. search_in_scripts(keyword="a_bogus") → Find which file contains it
|
|
543
|
+
2. extract_function_tree(functionName="sign", maxDepth=3) → Extract sign() and its dependencies
|
|
544
|
+
3. analyze_code_chunk(code=extractedCode) → Analyze the small extracted code
|
|
545
|
+
|
|
546
|
+
Returns:
|
|
547
|
+
- Complete code of the function and its dependencies
|
|
548
|
+
- Call graph showing relationships
|
|
549
|
+
- Total size (much smaller than original file)`,
|
|
550
|
+
inputSchema: {
|
|
551
|
+
type: 'object',
|
|
552
|
+
properties: {
|
|
553
|
+
scriptId: {
|
|
554
|
+
type: 'string',
|
|
555
|
+
description: 'Script ID from collect_code or search_in_scripts',
|
|
556
|
+
},
|
|
557
|
+
functionName: {
|
|
558
|
+
type: 'string',
|
|
559
|
+
description: 'Name of the function to extract',
|
|
560
|
+
},
|
|
561
|
+
maxDepth: {
|
|
562
|
+
type: 'number',
|
|
563
|
+
description: 'Maximum dependency depth to extract',
|
|
564
|
+
default: 3,
|
|
565
|
+
},
|
|
566
|
+
maxSize: {
|
|
567
|
+
type: 'number',
|
|
568
|
+
description: 'Maximum total size in KB',
|
|
569
|
+
default: 500,
|
|
570
|
+
},
|
|
571
|
+
includeComments: {
|
|
572
|
+
type: 'boolean',
|
|
573
|
+
description: 'Whether to include comments in extracted code',
|
|
574
|
+
default: true,
|
|
575
|
+
},
|
|
576
|
+
},
|
|
577
|
+
required: ['scriptId', 'functionName'],
|
|
578
|
+
},
|
|
584
579
|
},
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
580
|
+
{
|
|
581
|
+
name: 'deobfuscate',
|
|
582
|
+
description: 'AI-driven code deobfuscation',
|
|
583
|
+
inputSchema: {
|
|
584
|
+
type: 'object',
|
|
585
|
+
properties: {
|
|
586
|
+
code: {
|
|
587
|
+
type: 'string',
|
|
588
|
+
description: 'Obfuscated code to deobfuscate',
|
|
589
|
+
},
|
|
590
|
+
llm: {
|
|
591
|
+
type: 'string',
|
|
592
|
+
enum: ['gpt-4', 'claude'],
|
|
593
|
+
description: 'LLM to use for deobfuscation',
|
|
594
|
+
default: 'gpt-4',
|
|
595
|
+
},
|
|
596
|
+
aggressive: {
|
|
597
|
+
type: 'boolean',
|
|
598
|
+
description: 'Use aggressive deobfuscation',
|
|
599
|
+
default: false,
|
|
600
|
+
},
|
|
601
|
+
},
|
|
602
|
+
required: ['code'],
|
|
603
|
+
},
|
|
603
604
|
},
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
605
|
+
{
|
|
606
|
+
name: 'understand_code',
|
|
607
|
+
description: 'AI-assisted code semantic understanding',
|
|
608
|
+
inputSchema: {
|
|
609
|
+
type: 'object',
|
|
610
|
+
properties: {
|
|
611
|
+
code: {
|
|
612
|
+
type: 'string',
|
|
613
|
+
description: 'Code to analyze',
|
|
614
|
+
},
|
|
615
|
+
context: {
|
|
616
|
+
type: 'object',
|
|
617
|
+
description: 'Additional context for analysis',
|
|
618
|
+
},
|
|
619
|
+
focus: {
|
|
620
|
+
type: 'string',
|
|
621
|
+
enum: ['structure', 'business', 'security', 'all'],
|
|
622
|
+
description: 'Analysis focus',
|
|
623
|
+
default: 'all',
|
|
624
|
+
},
|
|
625
|
+
},
|
|
626
|
+
required: ['code'],
|
|
627
|
+
},
|
|
613
628
|
},
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
629
|
+
{
|
|
630
|
+
name: 'detect_crypto',
|
|
631
|
+
description: 'Detect and analyze encryption algorithms',
|
|
632
|
+
inputSchema: {
|
|
633
|
+
type: 'object',
|
|
634
|
+
properties: {
|
|
635
|
+
code: {
|
|
636
|
+
type: 'string',
|
|
637
|
+
description: 'Code to analyze for crypto algorithms',
|
|
638
|
+
},
|
|
639
|
+
},
|
|
640
|
+
required: ['code'],
|
|
641
|
+
},
|
|
623
642
|
},
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
const result = await handlers.handleConsoleGetExceptions({});
|
|
662
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
663
|
-
});
|
|
664
|
-
server.registerTool('console_inject_xhr_interceptor', {
|
|
665
|
-
title: 'Console Inject XHR Interceptor',
|
|
666
|
-
description: 'Inject XHR interceptor',
|
|
667
|
-
inputSchema: {},
|
|
668
|
-
}, async () => {
|
|
669
|
-
const result = await handlers.handleConsoleInjectXhrInterceptor({});
|
|
670
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
671
|
-
});
|
|
672
|
-
server.registerTool('console_inject_fetch_interceptor', {
|
|
673
|
-
title: 'Console Inject Fetch Interceptor',
|
|
674
|
-
description: 'Inject fetch interceptor',
|
|
675
|
-
inputSchema: {},
|
|
676
|
-
}, async () => {
|
|
677
|
-
const result = await handlers.handleConsoleInjectFetchInterceptor({});
|
|
678
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
679
|
-
});
|
|
680
|
-
server.registerTool('network_get_stats', {
|
|
681
|
-
title: 'Network Get Stats',
|
|
682
|
-
description: 'Get network statistics',
|
|
683
|
-
inputSchema: {},
|
|
684
|
-
}, async () => {
|
|
685
|
-
const result = await handlers.handleNetworkGetStats({});
|
|
686
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
687
|
-
});
|
|
688
|
-
}
|
|
689
|
-
registerAIHookTools() {
|
|
690
|
-
const server = this.server;
|
|
691
|
-
const handlers = this.aiHookHandlers;
|
|
692
|
-
server.registerTool('ai_hook_generate', {
|
|
693
|
-
title: 'AI Hook Generate',
|
|
694
|
-
description: 'Generate hook code for a request pattern',
|
|
695
|
-
inputSchema: {
|
|
696
|
-
pattern: z.string().describe('Request pattern to hook'),
|
|
643
|
+
{
|
|
644
|
+
name: 'manage_hooks',
|
|
645
|
+
description: 'Manage JavaScript hooks for runtime interception',
|
|
646
|
+
inputSchema: {
|
|
647
|
+
type: 'object',
|
|
648
|
+
properties: {
|
|
649
|
+
action: {
|
|
650
|
+
type: 'string',
|
|
651
|
+
enum: ['create', 'list', 'records', 'clear'],
|
|
652
|
+
description: 'Hook management action',
|
|
653
|
+
},
|
|
654
|
+
target: {
|
|
655
|
+
type: 'string',
|
|
656
|
+
description: 'Hook target (function name, API, etc.)',
|
|
657
|
+
},
|
|
658
|
+
type: {
|
|
659
|
+
type: 'string',
|
|
660
|
+
enum: ['function', 'xhr', 'fetch', 'websocket', 'localstorage', 'cookie'],
|
|
661
|
+
description: 'Type of hook to create',
|
|
662
|
+
},
|
|
663
|
+
hookAction: {
|
|
664
|
+
type: 'string',
|
|
665
|
+
enum: ['log', 'block', 'modify'],
|
|
666
|
+
description: 'What to do when hook is triggered',
|
|
667
|
+
default: 'log',
|
|
668
|
+
},
|
|
669
|
+
customCode: {
|
|
670
|
+
type: 'string',
|
|
671
|
+
description: 'Custom JavaScript code to execute in hook',
|
|
672
|
+
},
|
|
673
|
+
hookId: {
|
|
674
|
+
type: 'string',
|
|
675
|
+
description: 'Hook ID for records/clear actions',
|
|
676
|
+
},
|
|
677
|
+
},
|
|
678
|
+
required: ['action'],
|
|
679
|
+
},
|
|
697
680
|
},
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
681
|
+
{
|
|
682
|
+
name: 'detect_obfuscation',
|
|
683
|
+
description: 'Detect obfuscation types in JavaScript code (supports 2024-2025 latest techniques)',
|
|
684
|
+
inputSchema: {
|
|
685
|
+
type: 'object',
|
|
686
|
+
properties: {
|
|
687
|
+
code: {
|
|
688
|
+
type: 'string',
|
|
689
|
+
description: 'Code to analyze for obfuscation',
|
|
690
|
+
},
|
|
691
|
+
generateReport: {
|
|
692
|
+
type: 'boolean',
|
|
693
|
+
description: 'Generate detailed report',
|
|
694
|
+
default: true,
|
|
695
|
+
},
|
|
696
|
+
},
|
|
697
|
+
required: ['code'],
|
|
698
|
+
},
|
|
707
699
|
},
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
700
|
+
{
|
|
701
|
+
name: 'advanced_deobfuscate',
|
|
702
|
+
description: 'Advanced deobfuscation supporting VM protection, invisible unicode, control flow flattening, etc.',
|
|
703
|
+
inputSchema: {
|
|
704
|
+
type: 'object',
|
|
705
|
+
properties: {
|
|
706
|
+
code: {
|
|
707
|
+
type: 'string',
|
|
708
|
+
description: 'Obfuscated code to deobfuscate',
|
|
709
|
+
},
|
|
710
|
+
detectOnly: {
|
|
711
|
+
type: 'boolean',
|
|
712
|
+
description: 'Only detect obfuscation types without deobfuscating',
|
|
713
|
+
default: false,
|
|
714
|
+
},
|
|
715
|
+
aggressiveVM: {
|
|
716
|
+
type: 'boolean',
|
|
717
|
+
description: 'Use aggressive VM deobfuscation (experimental)',
|
|
718
|
+
default: false,
|
|
719
|
+
},
|
|
720
|
+
useASTOptimization: {
|
|
721
|
+
type: 'boolean',
|
|
722
|
+
description: 'Apply AST-based optimizations',
|
|
723
|
+
default: true,
|
|
724
|
+
},
|
|
725
|
+
timeout: {
|
|
726
|
+
type: 'number',
|
|
727
|
+
description: 'Timeout in milliseconds',
|
|
728
|
+
default: 60000,
|
|
729
|
+
},
|
|
730
|
+
},
|
|
731
|
+
required: ['code'],
|
|
732
|
+
},
|
|
725
733
|
},
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
inputSchema: {},
|
|
734
|
-
}, async () => {
|
|
735
|
-
const result = await handlers.handleAIHookClear({});
|
|
736
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
737
|
-
});
|
|
738
|
-
server.registerTool('ai_hook_toggle', {
|
|
739
|
-
title: 'AI Hook Toggle',
|
|
740
|
-
description: 'Toggle hook on/off',
|
|
741
|
-
inputSchema: {
|
|
742
|
-
hookId: z.string().describe('Hook ID'),
|
|
743
|
-
enabled: z.boolean().describe('Enable or disable'),
|
|
734
|
+
{
|
|
735
|
+
name: 'clear_collected_data',
|
|
736
|
+
description: '🧹 Clear all collected data (file cache, compression cache, collected URLs). Use this when switching to a new website to avoid data interference.',
|
|
737
|
+
inputSchema: {
|
|
738
|
+
type: 'object',
|
|
739
|
+
properties: {},
|
|
740
|
+
},
|
|
744
741
|
},
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
inputSchema: {
|
|
753
|
-
format: z.enum(['json', 'har']).optional().default('json'),
|
|
742
|
+
{
|
|
743
|
+
name: 'get_collection_stats',
|
|
744
|
+
description: '📊 Get statistics about collected data (cache stats, compression stats, collected URLs count).',
|
|
745
|
+
inputSchema: {
|
|
746
|
+
type: 'object',
|
|
747
|
+
properties: {},
|
|
748
|
+
},
|
|
754
749
|
},
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
750
|
+
...browserTools,
|
|
751
|
+
...debuggerTools,
|
|
752
|
+
...advancedTools,
|
|
753
|
+
...aiHookTools,
|
|
754
|
+
...tokenBudgetTools,
|
|
755
|
+
...cacheTools,
|
|
756
|
+
];
|
|
759
757
|
}
|
|
760
|
-
|
|
761
|
-
const
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
758
|
+
async handleCollectCode(args) {
|
|
759
|
+
const returnSummaryOnly = args.returnSummaryOnly ?? false;
|
|
760
|
+
let smartMode = args.smartMode;
|
|
761
|
+
if (returnSummaryOnly && !smartMode) {
|
|
762
|
+
smartMode = 'summary';
|
|
763
|
+
}
|
|
764
|
+
const result = await this.collector.collect({
|
|
765
|
+
url: args.url,
|
|
766
|
+
includeInline: args.includeInline,
|
|
767
|
+
includeExternal: args.includeExternal,
|
|
768
|
+
includeDynamic: args.includeDynamic,
|
|
769
|
+
smartMode: smartMode,
|
|
770
|
+
compress: args.compress,
|
|
771
|
+
maxTotalSize: args.maxTotalSize,
|
|
772
|
+
maxFileSize: args.maxFileSize ? args.maxFileSize * 1024 : undefined,
|
|
773
|
+
priorities: args.priorities,
|
|
774
|
+
});
|
|
775
|
+
if (returnSummaryOnly) {
|
|
776
|
+
logger.info('📋 Returning summary only (user requested)');
|
|
777
|
+
return {
|
|
778
|
+
content: [
|
|
779
|
+
{
|
|
780
|
+
type: 'text',
|
|
781
|
+
text: JSON.stringify({
|
|
782
|
+
mode: 'summary',
|
|
783
|
+
totalSize: result.totalSize,
|
|
784
|
+
totalSizeKB: (result.totalSize / 1024).toFixed(2),
|
|
785
|
+
filesCount: result.files.length,
|
|
786
|
+
collectTime: result.collectTime,
|
|
787
|
+
summary: result.files.map(f => ({
|
|
788
|
+
url: f.url,
|
|
789
|
+
type: f.type,
|
|
790
|
+
size: f.size,
|
|
791
|
+
sizeKB: (f.size / 1024).toFixed(2),
|
|
792
|
+
truncated: f.metadata?.truncated || false,
|
|
793
|
+
preview: f.content.substring(0, 200) + '...',
|
|
794
|
+
})),
|
|
795
|
+
hint: 'Use get_script_source tool to fetch specific files',
|
|
796
|
+
}, null, 2),
|
|
797
|
+
},
|
|
798
|
+
],
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
const totalSize = result.totalSize;
|
|
802
|
+
const MAX_SAFE_SIZE = 1 * 1024 * 1024;
|
|
803
|
+
if (totalSize > MAX_SAFE_SIZE) {
|
|
804
|
+
logger.warn(`⚠️ Total code size (${(totalSize / 1024).toFixed(2)} KB) exceeds safe limit (${MAX_SAFE_SIZE / 1024} KB), auto-switching to summary mode`);
|
|
805
|
+
return {
|
|
806
|
+
content: [
|
|
807
|
+
{
|
|
808
|
+
type: 'text',
|
|
809
|
+
text: JSON.stringify({
|
|
810
|
+
warning: '⚠️ Code size too large for full response - auto-switched to summary mode',
|
|
811
|
+
totalSize,
|
|
812
|
+
totalSizeKB: (totalSize / 1024).toFixed(2),
|
|
813
|
+
filesCount: result.files.length,
|
|
814
|
+
collectTime: result.collectTime,
|
|
815
|
+
summary: result.files.map(f => ({
|
|
816
|
+
url: f.url,
|
|
817
|
+
type: f.type,
|
|
818
|
+
size: f.size,
|
|
819
|
+
sizeKB: (f.size / 1024).toFixed(2),
|
|
820
|
+
truncated: f.metadata?.truncated || false,
|
|
821
|
+
preview: f.content.substring(0, 200) + '...',
|
|
822
|
+
})),
|
|
823
|
+
recommendations: [
|
|
824
|
+
'1. Use get_script_source to fetch specific files',
|
|
825
|
+
'2. Filter files by URL pattern (e.g., files containing "encrypt" or "api")',
|
|
826
|
+
'3. Use returnSummaryOnly=true parameter to explicitly request summary mode',
|
|
827
|
+
'4. Enable caching to speed up repeated requests',
|
|
828
|
+
],
|
|
829
|
+
}, null, 2),
|
|
830
|
+
},
|
|
831
|
+
],
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
return {
|
|
835
|
+
content: [
|
|
836
|
+
{
|
|
837
|
+
type: 'text',
|
|
838
|
+
text: JSON.stringify(result, null, 2),
|
|
839
|
+
},
|
|
840
|
+
],
|
|
841
|
+
};
|
|
815
842
|
}
|
|
816
843
|
async handleSearchInScripts(args) {
|
|
817
844
|
const { ScriptManager } = await import('../modules/debugger/ScriptManager.js');
|