@poolzin/pool-bot 2026.3.15 → 2026.3.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/agents/checkpoint-manager.js +1 -2
  3. package/dist/build-info.json +3 -3
  4. package/docs/assets-evaluation.md +418 -0
  5. package/docs/commit-evaluation-42f463de4.md +362 -0
  6. package/docs/extensions-evaluation.md +696 -0
  7. package/docs/hexstrike-evaluation.md +514 -0
  8. package/docs/implementations-summary.md +300 -0
  9. package/extensions/dexter/README.md +147 -0
  10. package/extensions/dexter/dist/agent.d.ts +44 -0
  11. package/extensions/dexter/dist/agent.js +265 -0
  12. package/extensions/dexter/dist/index.d.ts +12 -0
  13. package/extensions/dexter/dist/index.js +99 -0
  14. package/extensions/dexter/node_modules/.bin/tsc +21 -0
  15. package/extensions/dexter/node_modules/.bin/tsserver +21 -0
  16. package/extensions/dexter/package.json +33 -0
  17. package/extensions/dexter/poolbot.plugin.json +35 -0
  18. package/extensions/dexter/src/agent.ts +375 -0
  19. package/extensions/dexter/src/index.ts +129 -0
  20. package/extensions/dexter/tsconfig.json +20 -0
  21. package/extensions/hackingtool/README.md +75 -0
  22. package/extensions/hackingtool/dist/client.d.ts +34 -0
  23. package/extensions/hackingtool/dist/client.js +82 -0
  24. package/extensions/hackingtool/dist/index.d.ts +12 -0
  25. package/extensions/hackingtool/dist/index.js +163 -0
  26. package/extensions/hackingtool/dist/server-manager.d.ts +25 -0
  27. package/extensions/hackingtool/dist/server-manager.js +107 -0
  28. package/extensions/hackingtool/node_modules/.bin/tsc +21 -0
  29. package/extensions/hackingtool/node_modules/.bin/tsserver +21 -0
  30. package/extensions/hackingtool/package.json +36 -0
  31. package/extensions/hackingtool/poolbot.plugin.json +55 -0
  32. package/extensions/hackingtool/src/client.ts +120 -0
  33. package/extensions/hackingtool/src/index.ts +181 -0
  34. package/extensions/hackingtool/src/server/hackingtool_mcp.py +454 -0
  35. package/extensions/hackingtool/src/server/requirements.txt +2 -0
  36. package/extensions/hackingtool/src/server-manager.ts +128 -0
  37. package/extensions/hackingtool/tsconfig.json +20 -0
  38. package/extensions/hexstrike-ai/README.md +693 -44
  39. package/extensions/hexstrike-ai/src/client.test.ts +335 -0
  40. package/extensions/hexstrike-ai/src/server-manager.test.ts +286 -0
  41. package/package.json +1 -1
@@ -0,0 +1,181 @@
1
+ import { HackingToolServerManager } from "./server-manager.js";
2
+ import { HackingToolClient } from "./client.js";
3
+
4
+ interface HackingToolConfig {
5
+ port?: number;
6
+ host?: string;
7
+ autoStart?: boolean;
8
+ token?: string;
9
+ pythonPath?: string;
10
+ }
11
+
12
+ export default async function createPlugin(
13
+ ctx: any
14
+ ): Promise<any> {
15
+ const config = ctx.config as HackingToolConfig;
16
+ const serverManager = new HackingToolServerManager({
17
+ port: config.port,
18
+ host: config.host,
19
+ pythonPath: config.pythonPath,
20
+ });
21
+
22
+ const client = new HackingToolClient({
23
+ host: config.host,
24
+ port: config.port,
25
+ token: config.token,
26
+ });
27
+
28
+ if (config.autoStart !== false) {
29
+ ctx.logger.info("Starting HackingTool MCP server...");
30
+ try {
31
+ await serverManager.start();
32
+ ctx.logger.info("HackingTool MCP server started successfully");
33
+ } catch (err) {
34
+ ctx.logger.error("Failed to start HackingTool MCP server:", err);
35
+ throw err;
36
+ }
37
+ }
38
+
39
+ ctx.cli
40
+ .command("pentest.status")
41
+ .description("Check HackingTool server status")
42
+ .action(async () => {
43
+ try {
44
+ const health = await client.health();
45
+ console.log("✅ HackingTool is running");
46
+ console.log(" Status:", health.status);
47
+ console.log(" Version:", health.version ?? "unknown");
48
+ console.log(" Uptime:", health.uptime ? `${Math.floor(health.uptime / 60)}m` : "N/A");
49
+ console.log(" Tools Available:", health.toolsAvailable);
50
+ console.log(" Active Scans:", health.activeScans);
51
+ } catch (err) {
52
+ console.error("❌ HackingTool is not running");
53
+ console.error(" Error:", err instanceof Error ? err.message : String(err));
54
+ process.exit(1);
55
+ }
56
+ });
57
+
58
+ ctx.cli
59
+ .command("pentest.tools")
60
+ .description("List available penetration testing tools")
61
+ .action(async () => {
62
+ try {
63
+ const tools = await client.getTools();
64
+ console.log("🔧 Available Penetration Testing Tools:\n");
65
+
66
+ for (const [category, toolList] of Object.entries(tools)) {
67
+ if (Array.isArray(toolList)) {
68
+ console.log(`📁 ${category.toUpperCase().replace("_", " ")}`);
69
+ for (const tool of toolList.slice(0, 10)) {
70
+ console.log(` • ${tool}`);
71
+ }
72
+ if (toolList.length > 10) {
73
+ console.log(` ... and ${toolList.length - 10} more`);
74
+ }
75
+ console.log();
76
+ } else {
77
+ console.log(`📁 ${category.toUpperCase().replace("_", " ")}`);
78
+ const subCategories = toolList as Record<string, string[]>;
79
+ for (const [subcat, subtools] of Object.entries(subCategories)) {
80
+ console.log(` ${subcat.replace("_", " ")}: ${subtools.slice(0, 5).join(", ")}`);
81
+ if (subtools.length > 5) {
82
+ console.log(` ... and ${subtools.length - 5} more`);
83
+ }
84
+ }
85
+ console.log();
86
+ }
87
+ }
88
+ } catch (err) {
89
+ console.error("❌ Failed to get tools:", err instanceof Error ? err.message : String(err));
90
+ process.exit(1);
91
+ }
92
+ });
93
+
94
+ ctx.cli
95
+ .command("pentest.scan")
96
+ .description("Run penetration testing tool")
97
+ .argument("<category>", "Tool category (e.g., information_gathering, sql_injection, web_attack)")
98
+ .argument("<tool>", "Tool name (e.g., nmap, sqlmap, dirb)")
99
+ .argument("[target]", "Target URL or IP (optional)")
100
+ .option("-o, --output <file>", "Save results to file")
101
+ .action(async (category: string, tool: string, target?: string, options?: { output?: string }) => {
102
+ try {
103
+ console.log(`🚀 Running ${tool} from ${category}...`);
104
+ if (target) {
105
+ console.log(` Target: ${target}`);
106
+ }
107
+
108
+ const result = await client.runTool(category, tool, target);
109
+ console.log(`✅ Tool execution ${result.status}`);
110
+ console.log(` Scan ID: ${result.scanId}`);
111
+
112
+ if (result.result) {
113
+ if (result.result.simulated) {
114
+ console.log(` ℹ️ ${result.result.message}`);
115
+ } else if (result.result.stdout) {
116
+ console.log("\n📊 Output:");
117
+ console.log(result.result.stdout);
118
+ } else if (result.result.error) {
119
+ console.log(` ❌ Error: ${result.result.error}`);
120
+ }
121
+ }
122
+
123
+ if (options?.output && result.result) {
124
+ const fs = await import("fs");
125
+ fs.writeFileSync(options.output, JSON.stringify(result.result, null, 2));
126
+ console.log(`\n💾 Results saved to: ${options.output}`);
127
+ }
128
+ } catch (err) {
129
+ console.error("❌ Scan failed:", err instanceof Error ? err.message : String(err));
130
+ process.exit(1);
131
+ }
132
+ });
133
+
134
+ ctx.cli
135
+ .command("pentest.scans")
136
+ .description("List active scans")
137
+ .action(async () => {
138
+ try {
139
+ const scans = await client.listScans();
140
+ if (scans.length === 0) {
141
+ console.log("ℹ️ No active scans");
142
+ return;
143
+ }
144
+
145
+ console.log("🔍 Active Scans:\n");
146
+ for (const scan of scans) {
147
+ const statusIcon = scan.status === "running" ? "🔄" : scan.status === "completed" ? "✅" : "❌";
148
+ console.log(`${statusIcon} ${scan.scanId} - ${scan.tool} (${scan.status})`);
149
+ if (scan.target) {
150
+ console.log(` Target: ${scan.target}`);
151
+ }
152
+ console.log(` Started: ${new Date((scan.startedAt || 0) * 1000).toLocaleString()}`);
153
+ console.log();
154
+ }
155
+ } catch (err) {
156
+ console.error("❌ Failed to list scans:", err instanceof Error ? err.message : String(err));
157
+ process.exit(1);
158
+ }
159
+ });
160
+
161
+ ctx.cli
162
+ .command("pentest.stop")
163
+ .description("Stop HackingTool server")
164
+ .action(async () => {
165
+ ctx.logger.info("Stopping HackingTool server...");
166
+ await serverManager.stop();
167
+ console.log("✅ HackingTool server stopped");
168
+ });
169
+
170
+ return {
171
+ name: "hackingtool",
172
+ version: "1.2.0",
173
+ async onShutdown() {
174
+ ctx.logger.info("Stopping HackingTool server...");
175
+ await serverManager.stop();
176
+ },
177
+ };
178
+ }
179
+
180
+ export { HackingToolServerManager, HackingToolClient };
181
+ export type { HackingToolConfig };
@@ -0,0 +1,454 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ HackingTool MCP Server - Security Testing Platform
4
+ Integrates 100+ security tools for penetration testing and security assessment.
5
+ """
6
+
7
+ import sys
8
+ import json
9
+ import subprocess
10
+ import os
11
+ from pathlib import Path
12
+ from typing import Any, Dict, List, Optional
13
+ import asyncio
14
+ import hashlib
15
+ import time
16
+
17
+
18
+ class HackingToolServer:
19
+ """MCP server for HackingTool security platform."""
20
+
21
+ def __init__(self, port: int = 8889, host: str = "127.0.0.1"):
22
+ self.port = port
23
+ self.host = host
24
+ self.start_time = time.time()
25
+ self.active_scans: Dict[str, Dict[str, Any]] = {}
26
+ self.tool_categories = {
27
+ "anonymity": "Anonymously Hiding Tools",
28
+ "information_gathering": "Information Gathering Tools",
29
+ "wordlist": "Wordlist Generator",
30
+ "wireless": "Wireless Attack Tools",
31
+ "sql_injection": "SQL Injection Tools",
32
+ "phishing": "Phishing Attack Tools",
33
+ "web_attack": "Web Attack Tools",
34
+ "post_exploitation": "Post Exploitation Tools",
35
+ "forensic": "Forensic Tools",
36
+ "payload": "Payload Creation Tools",
37
+ "exploit": "Exploit Framework",
38
+ "reverse_engineering": "Reverse Engineering Tools",
39
+ "ddos": "DDOS Attack Tools",
40
+ "rat": "Remote Administrator Tools",
41
+ "xss": "XSS Attack Tools",
42
+ "steganography": "Steganography Tools",
43
+ "other": "Other Tools",
44
+ }
45
+
46
+ def get_health(self) -> Dict[str, Any]:
47
+ """Get server health status."""
48
+ return {
49
+ "status": "healthy",
50
+ "version": "1.2.0",
51
+ "uptime": time.time() - self.start_time,
52
+ "active_scans": len(self.active_scans),
53
+ "tools_available": sum(len(tools) for tools in self.get_tools().values()),
54
+ }
55
+
56
+ def get_tools(self) -> Dict[str, List[str]]:
57
+ """Get available tools by category."""
58
+ return {
59
+ "anonymity": ["Anonmously Surf", "Multitor"],
60
+ "information_gathering": [
61
+ "nmap",
62
+ "Dracnmap",
63
+ "Port Scan",
64
+ "Host2IP",
65
+ "Xerosploit",
66
+ "RED HAWK",
67
+ "ReconSpider",
68
+ "IsItDown",
69
+ "Infoga",
70
+ "ReconDog",
71
+ "Striker",
72
+ "SecretFinder",
73
+ "Shodanfy",
74
+ "rang3r",
75
+ "ranger-reloaded",
76
+ "Breacher",
77
+ ],
78
+ "wordlist": [
79
+ "Cupp",
80
+ "WordlistCreator",
81
+ "Goblin WordGenerator",
82
+ "Password List",
83
+ ],
84
+ "wireless": [
85
+ "WiFi-Pumpkin",
86
+ "pixiewps",
87
+ "Bluepot",
88
+ "Fluxion",
89
+ "Wifiphisher",
90
+ "Wifite",
91
+ "EvilTwin",
92
+ "Fastssh",
93
+ "Howmanypeople",
94
+ ],
95
+ "sql_injection": [
96
+ "Sqlmap",
97
+ "NoSqlMap",
98
+ "DSSS",
99
+ "Explo",
100
+ "Blisqy",
101
+ "Leviathan",
102
+ "SQLScan",
103
+ ],
104
+ "phishing": [
105
+ "Setoolkit",
106
+ "SocialFish",
107
+ "HiddenEye",
108
+ "Evilginx2",
109
+ "I-See_You",
110
+ "SayCheese",
111
+ "QR Code Jacking",
112
+ "ShellPhish",
113
+ "BlackPhish",
114
+ ],
115
+ "web_attack": [
116
+ "Web2Attack",
117
+ "Skipfish",
118
+ "Sublist3r",
119
+ "CheckURL",
120
+ "Blazy",
121
+ "takeover",
122
+ "Dirb",
123
+ ],
124
+ "post_exploitation": ["Vegile", "HeraKeylogger"],
125
+ "forensic": [
126
+ "Autopsy",
127
+ "Wireshark",
128
+ "Bulk extractor",
129
+ "Guymager",
130
+ "Toolsley",
131
+ "Volatility3",
132
+ ],
133
+ "payload": [
134
+ "The FatRat",
135
+ "Brutal",
136
+ "Stitch",
137
+ "MSFvenom Payload Creator",
138
+ "Venom",
139
+ "Spycam",
140
+ "Mob-Droid",
141
+ "Enigma",
142
+ ],
143
+ "exploit": ["RouterSploit", "WebSploit", "Commix", "Web2Attack"],
144
+ "reverse_engineering": ["Androguard", "Apk2Gold", "JadX"],
145
+ "ddos": ["SlowLoris", "aSYNcrone", "UFOnet", "GoldenEye"],
146
+ "rat": ["Stitch", "Pyshell"],
147
+ "xss": [
148
+ "DalFox",
149
+ "XSS-LOADER",
150
+ "extended-xss-search",
151
+ "XSS-Freak",
152
+ "XSpear",
153
+ "XSSCon",
154
+ "XanXSS",
155
+ "XSStrike",
156
+ "RVuln",
157
+ "Cyclops",
158
+ ],
159
+ "steganography": [
160
+ "SteganoHide",
161
+ "StegnoCracker",
162
+ "StegoCracker",
163
+ "Whitespace",
164
+ ],
165
+ "other": {
166
+ "social_bruteforce": [
167
+ "Instagram Attack",
168
+ "AllinOne Attack",
169
+ "Facebook Attack",
170
+ "Application Checker",
171
+ ],
172
+ "android_hacking": [
173
+ "Keydroid",
174
+ "MySMS",
175
+ "Lockphish",
176
+ "DroidCam",
177
+ "EvilApp",
178
+ "HatCloud",
179
+ ],
180
+ "homograph": ["EvilURL"],
181
+ "email_verify": ["KnockMail"],
182
+ "hash_cracking": ["Hash Buster"],
183
+ "wifi_deauth": ["WifiJammer-NG", "KawaiiDeauther"],
184
+ "social_finder": [
185
+ "Social Mapper",
186
+ "finduser",
187
+ "Sherlock",
188
+ "SocialScan",
189
+ ],
190
+ "payload_injector": ["Debinject", "Pixload"],
191
+ "web_crawling": ["Gospider"],
192
+ "mix": ["Terminal Multiplexer", "Crivo"],
193
+ },
194
+ }
195
+
196
+ def run_tool(
197
+ self,
198
+ category: str,
199
+ tool_name: str,
200
+ target: Optional[str] = None,
201
+ options: Optional[Dict[str, Any]] = None,
202
+ ) -> Dict[str, Any]:
203
+ """Execute a security tool."""
204
+ scan_id = hashlib.md5(
205
+ f"{category}_{tool_name}_{time.time()}".encode()
206
+ ).hexdigest()[:12]
207
+
208
+ self.active_scans[scan_id] = {
209
+ "category": category,
210
+ "tool": tool_name,
211
+ "target": target,
212
+ "options": options or {},
213
+ "status": "running",
214
+ "started_at": time.time(),
215
+ }
216
+
217
+ try:
218
+ result = self._execute_tool(category, tool_name, target, options)
219
+ self.active_scans[scan_id]["status"] = "completed"
220
+ self.active_scans[scan_id]["completed_at"] = time.time()
221
+ self.active_scans[scan_id]["result"] = result
222
+
223
+ return {"scan_id": scan_id, "status": "completed", "result": result}
224
+ except Exception as e:
225
+ self.active_scans[scan_id]["status"] = "failed"
226
+ self.active_scans[scan_id]["error"] = str(e)
227
+
228
+ return {"scan_id": scan_id, "status": "failed", "error": str(e)}
229
+
230
+ def _execute_tool(
231
+ self,
232
+ category: str,
233
+ tool_name: str,
234
+ target: Optional[str],
235
+ options: Optional[Dict[str, Any]],
236
+ ) -> Dict[str, Any]:
237
+ """Execute the actual tool command."""
238
+ tool_lower = tool_name.lower().replace(" ", "_").replace("-", "_")
239
+
240
+ cmd_mapping = {
241
+ "nmap": lambda t: ["nmap", "-sV", "-sC", t] if t else ["nmap", "--help"],
242
+ "sqlmap": lambda t: (
243
+ ["sqlmap", "-u", t, "--batch"] if t else ["sqlmap", "--help"]
244
+ ),
245
+ "dirb": lambda t: (
246
+ ["dirb", t, "/usr/share/wordlists/dirb/common.txt"]
247
+ if t
248
+ else ["dirb", "--help"]
249
+ ),
250
+ "nikto": lambda t: ["nikto", "-h", t] if t else ["nikto", "--help"],
251
+ "gobuster": lambda t: (
252
+ [
253
+ "gobuster",
254
+ "dir",
255
+ "-u",
256
+ t,
257
+ "-w",
258
+ "/usr/share/wordlists/dirb/common.txt",
259
+ ]
260
+ if t
261
+ else ["gobuster", "--help"]
262
+ ),
263
+ "wpscan": lambda t: (
264
+ ["wpscan", "--url", t, "--enumerate", "vp,u"]
265
+ if t
266
+ else ["wpscan", "--help"]
267
+ ),
268
+ "sublist3r": lambda t: (
269
+ ["sublist3r", "-d", t] if t else ["sublist3r", "--help"]
270
+ ),
271
+ "sherlock": lambda t: ["sherlock", t] if t else ["sherlock", "--help"],
272
+ }
273
+
274
+ cmd_func = cmd_mapping.get(tool_lower)
275
+
276
+ if not cmd_func:
277
+ return {
278
+ "tool": tool_name,
279
+ "category": category,
280
+ "simulated": True,
281
+ "message": f"Tool {tool_name} would be executed (requires installation)",
282
+ "target": target,
283
+ "options": options,
284
+ }
285
+
286
+ cmd = cmd_func(target) if target else cmd_func(None)
287
+
288
+ try:
289
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
290
+
291
+ return {
292
+ "tool": tool_name,
293
+ "category": category,
294
+ "target": target,
295
+ "stdout": result.stdout,
296
+ "stderr": result.stderr,
297
+ "returncode": result.returncode,
298
+ "execution_time": time.time()
299
+ - self.active_scans.get(cmd.split()[0], {}).get(
300
+ "started_at", time.time()
301
+ ),
302
+ }
303
+ except subprocess.TimeoutExpired:
304
+ return {"tool": tool_name, "error": "Tool execution timed out (5 minutes)"}
305
+ except FileNotFoundError:
306
+ return {
307
+ "tool": tool_name,
308
+ "error": f"Tool '{tool_name}' not found. Please install it first.",
309
+ "installation_hint": f"sudo apt install {tool_lower}",
310
+ }
311
+
312
+ def get_scan_status(self, scan_id: str) -> Dict[str, Any]:
313
+ """Get status of a scan."""
314
+ if scan_id not in self.active_scans:
315
+ return {"error": f"Scan {scan_id} not found"}
316
+
317
+ scan = self.active_scans[scan_id]
318
+ return {
319
+ "scan_id": scan_id,
320
+ "status": scan["status"],
321
+ "category": scan["category"],
322
+ "tool": scan["tool"],
323
+ "target": scan.get("target"),
324
+ "started_at": scan.get("started_at"),
325
+ "completed_at": scan.get("completed_at"),
326
+ "duration": (scan.get("completed_at") or time.time())
327
+ - scan.get("started_at"),
328
+ }
329
+
330
+ def list_scans(self) -> List[Dict[str, Any]]:
331
+ """List all active scans."""
332
+ return [
333
+ {
334
+ "scan_id": scan_id,
335
+ "status": scan["status"],
336
+ "tool": scan["tool"],
337
+ "target": scan.get("target"),
338
+ "started_at": scan.get("started_at"),
339
+ }
340
+ for scan_id, scan in self.active_scans.items()
341
+ ]
342
+
343
+
344
+ def main():
345
+ """Main MCP server entry point."""
346
+ import argparse
347
+
348
+ parser = argparse.ArgumentParser(description="HackingTool MCP Server")
349
+ parser.add_argument("--port", type=int, default=8889, help="Server port")
350
+ parser.add_argument("--host", type=str, default="127.0.0.1", help="Server host")
351
+ parser.add_argument("--stdio", action="store_true", help="Use stdio transport")
352
+
353
+ args = parser.parse_args()
354
+
355
+ server = HackingToolServer(port=args.port, host=args.host)
356
+
357
+ if args.stdio:
358
+ print(
359
+ json.dumps({"status": "ready", "message": "HackingTool MCP Server ready"}),
360
+ flush=True,
361
+ )
362
+
363
+ for line in sys.stdin:
364
+ try:
365
+ request = json.loads(line.strip())
366
+ method = request.get("method")
367
+ params = request.get("params", {})
368
+
369
+ if method == "health":
370
+ response = server.get_health()
371
+ elif method == "tools":
372
+ response = server.get_tools()
373
+ elif method == "run_tool":
374
+ response = server.run_tool(
375
+ params.get("category", "other"),
376
+ params.get("tool_name"),
377
+ params.get("target"),
378
+ params.get("options"),
379
+ )
380
+ elif method == "scan_status":
381
+ response = server.get_scan_status(params.get("scan_id"))
382
+ elif method == "list_scans":
383
+ response = server.list_scans()
384
+ else:
385
+ response = {"error": f"Unknown method: {method}"}
386
+
387
+ print(json.dumps({"result": response}), flush=True)
388
+ except Exception as e:
389
+ print(json.dumps({"error": str(e)}), flush=True)
390
+ else:
391
+ from http.server import HTTPServer, BaseHTTPRequestHandler
392
+
393
+ class MCPHandler(BaseHTTPRequestHandler):
394
+ def do_POST(self):
395
+ content_length = int(self.headers.get("Content-Length", 0))
396
+ post_data = self.rfile.read(content_length)
397
+
398
+ try:
399
+ request = json.loads(post_data.decode())
400
+ method = request.get("method")
401
+ params = request.get("params", {})
402
+
403
+ if method == "health":
404
+ response = server.get_health()
405
+ elif method == "tools":
406
+ response = server.get_tools()
407
+ elif method == "run_tool":
408
+ response = server.run_tool(
409
+ params.get("category", "other"),
410
+ params.get("tool_name"),
411
+ params.get("target"),
412
+ params.get("options"),
413
+ )
414
+ elif method == "scan_status":
415
+ response = server.get_scan_status(params.get("scan_id"))
416
+ elif method == "list_scans":
417
+ response = server.list_scans()
418
+ else:
419
+ response = {"error": f"Unknown method: {method}"}
420
+
421
+ self.send_response(200)
422
+ self.send_header("Content-Type", "application/json")
423
+ self.end_headers()
424
+ self.wfile.write(json.dumps({"result": response}).encode())
425
+ except Exception as e:
426
+ self.send_response(500)
427
+ self.end_headers()
428
+ self.wfile.write(json.dumps({"error": str(e)}).encode())
429
+
430
+ def do_GET(self):
431
+ if self.path == "/health":
432
+ response = server.get_health()
433
+ elif self.path == "/tools":
434
+ response = server.get_tools()
435
+ elif self.path.startswith("/scan/"):
436
+ scan_id = self.path.split("/")[2]
437
+ response = server.get_scan_status(scan_id)
438
+ elif self.path == "/scans":
439
+ response = server.list_scans()
440
+ else:
441
+ response = {"error": "Not found"}
442
+
443
+ self.send_response(200)
444
+ self.send_header("Content-Type", "application/json")
445
+ self.end_headers()
446
+ self.wfile.write(json.dumps(response).encode())
447
+
448
+ httpd = HTTPServer((args.host, args.port), MCPHandler)
449
+ print(f"HackingTool MCP Server running on http://{args.host}:{args.port}")
450
+ httpd.serve_forever()
451
+
452
+
453
+ if __name__ == "__main__":
454
+ main()
@@ -0,0 +1,2 @@
1
+ requests>=2.28.0
2
+ flask>=2.0.0