@mcp-shark/mcp-shark 1.5.4 → 1.5.6
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/README.md +32 -96
- package/bin/mcp-shark.js +1 -1
- package/core/configs/codex.js +68 -0
- package/core/configs/environment.js +51 -0
- package/{lib/common → core}/configs/index.js +16 -1
- package/core/constants/Defaults.js +15 -0
- package/core/constants/HttpStatus.js +14 -0
- package/core/constants/Server.js +20 -0
- package/core/constants/StatusCodes.js +25 -0
- package/core/constants/index.js +7 -0
- package/core/container/DependencyContainer.js +179 -0
- package/core/db/init.js +33 -0
- package/core/index.js +10 -0
- package/{mcp-server/lib/common/error.js → core/libraries/ErrorLibrary.js} +4 -0
- package/core/libraries/LoggerLibrary.js +91 -0
- package/core/libraries/SerializationLibrary.js +32 -0
- package/core/libraries/bootstrap-logger.js +19 -0
- package/core/libraries/errors/ApplicationError.js +97 -0
- package/core/libraries/index.js +17 -0
- package/{mcp-server/lib → core/mcp-server}/auditor/audit.js +77 -53
- package/core/mcp-server/index.js +192 -0
- package/{mcp-server/lib → core/mcp-server}/server/external/all.js +1 -1
- package/core/mcp-server/server/external/config.js +75 -0
- package/{mcp-server/lib → core/mcp-server}/server/external/single/client.js +1 -1
- package/{mcp-server/lib → core/mcp-server}/server/external/single/request.js +1 -1
- package/{mcp-server/lib → core/mcp-server}/server/external/single/run.js +20 -11
- package/{mcp-server/lib → core/mcp-server}/server/external/single/transport.js +1 -1
- package/{mcp-server/lib → core/mcp-server}/server/internal/handlers/error.js +1 -1
- package/core/mcp-server/server/internal/handlers/prompts-get.js +28 -0
- package/core/mcp-server/server/internal/handlers/prompts-list.js +21 -0
- package/core/mcp-server/server/internal/handlers/resources-list.js +21 -0
- package/core/mcp-server/server/internal/handlers/resources-read.js +28 -0
- package/core/mcp-server/server/internal/handlers/tools-call.js +44 -0
- package/core/mcp-server/server/internal/handlers/tools-list.js +23 -0
- package/core/mcp-server/server/internal/run.js +53 -0
- package/{mcp-server/lib → core/mcp-server}/server/internal/server.js +11 -1
- package/core/models/ConversationFilters.js +31 -0
- package/core/models/ExportFormat.js +8 -0
- package/core/models/RequestFilters.js +43 -0
- package/core/models/SessionFilters.js +23 -0
- package/core/models/index.js +8 -0
- package/core/repositories/AuditRepository.js +233 -0
- package/core/repositories/ConversationRepository.js +182 -0
- package/core/repositories/PacketRepository.js +237 -0
- package/core/repositories/SchemaRepository.js +107 -0
- package/core/repositories/SessionRepository.js +59 -0
- package/core/repositories/StatisticsRepository.js +54 -0
- package/core/repositories/index.js +10 -0
- package/core/services/AuditService.js +144 -0
- package/core/services/BackupService.js +222 -0
- package/core/services/ConfigDetectionService.js +89 -0
- package/core/services/ConfigFileService.js +210 -0
- package/core/services/ConfigPatchingService.js +137 -0
- package/core/services/ConfigService.js +250 -0
- package/core/services/ConfigTransformService.js +178 -0
- package/core/services/ConversationService.js +19 -0
- package/core/services/ExportService.js +117 -0
- package/core/services/LogService.js +64 -0
- package/core/services/McpClientService.js +235 -0
- package/core/services/McpDiscoveryService.js +107 -0
- package/core/services/RequestService.js +56 -0
- package/core/services/ScanCacheService.js +242 -0
- package/core/services/ScanService.js +167 -0
- package/core/services/ServerManagementService.js +206 -0
- package/core/services/SessionService.js +34 -0
- package/core/services/SettingsService.js +163 -0
- package/core/services/StatisticsService.js +64 -0
- package/core/services/TokenService.js +94 -0
- package/core/services/index.js +25 -0
- package/core/services/parsers/ConfigParserFactory.js +113 -0
- package/core/services/parsers/JsonConfigParser.js +66 -0
- package/core/services/parsers/LegacyJsonConfigParser.js +71 -0
- package/core/services/parsers/TomlConfigParser.js +87 -0
- package/core/services/parsers/index.js +4 -0
- package/{ui/server → core}/utils/scan-cache/directory.js +1 -1
- package/core/utils/validation.js +77 -0
- package/package.json +14 -11
- package/ui/dist/assets/index-CArYxKxS.js +35 -0
- package/ui/dist/index.html +1 -1
- package/ui/server/controllers/BackupController.js +129 -0
- package/ui/server/controllers/ConfigController.js +92 -0
- package/ui/server/controllers/ConversationController.js +41 -0
- package/ui/server/controllers/LogController.js +44 -0
- package/ui/server/controllers/McpClientController.js +60 -0
- package/ui/server/controllers/McpDiscoveryController.js +44 -0
- package/ui/server/controllers/RequestController.js +129 -0
- package/ui/server/controllers/ScanController.js +122 -0
- package/ui/server/controllers/ServerManagementController.js +154 -0
- package/ui/server/controllers/SessionController.js +57 -0
- package/ui/server/controllers/SettingsController.js +24 -0
- package/ui/server/controllers/StatisticsController.js +54 -0
- package/ui/server/controllers/TokenController.js +58 -0
- package/ui/server/controllers/index.js +17 -0
- package/ui/server/routes/backups/index.js +15 -9
- package/ui/server/routes/composite/index.js +63 -32
- package/ui/server/routes/composite/servers.js +20 -15
- package/ui/server/routes/config.js +13 -172
- package/ui/server/routes/conversations.js +9 -19
- package/ui/server/routes/help.js +4 -3
- package/ui/server/routes/logs.js +14 -26
- package/ui/server/routes/playground.js +11 -174
- package/ui/server/routes/requests.js +12 -232
- package/ui/server/routes/sessions.js +10 -21
- package/ui/server/routes/settings.js +10 -192
- package/ui/server/routes/smartscan.js +26 -15
- package/ui/server/routes/statistics.js +8 -79
- package/ui/server/setup.js +163 -0
- package/ui/server/swagger/paths/backups.js +151 -0
- package/ui/server/swagger/paths/components.js +76 -0
- package/ui/server/swagger/paths/config.js +117 -0
- package/ui/server/swagger/paths/conversations.js +29 -0
- package/ui/server/swagger/paths/help.js +82 -0
- package/ui/server/swagger/paths/logs.js +87 -0
- package/ui/server/swagger/paths/playground.js +49 -0
- package/ui/server/swagger/paths/requests.js +178 -0
- package/ui/server/swagger/paths/serverManagement.js +205 -0
- package/ui/server/swagger/paths/sessions.js +61 -0
- package/ui/server/swagger/paths/settings.js +31 -0
- package/ui/server/swagger/paths/smartScan/discovery.js +97 -0
- package/ui/server/swagger/paths/smartScan/index.js +13 -0
- package/ui/server/swagger/paths/smartScan/scans.js +151 -0
- package/ui/server/swagger/paths/smartScan/token.js +71 -0
- package/ui/server/swagger/paths/statistics.js +40 -0
- package/ui/server/swagger/paths.js +38 -0
- package/ui/server/swagger/swagger.js +37 -0
- package/ui/server/utils/cleanup.js +99 -0
- package/ui/server/utils/config.js +18 -96
- package/ui/server/utils/errorHandler.js +43 -0
- package/ui/server/utils/logger.js +2 -2
- package/ui/server/utils/paths.js +27 -30
- package/ui/server/utils/port.js +21 -21
- package/ui/server/utils/process.js +18 -10
- package/ui/server/utils/processState.js +17 -0
- package/ui/server/utils/signals.js +34 -0
- package/ui/server/websocket/broadcast.js +33 -0
- package/ui/server/websocket/handler.js +52 -0
- package/ui/server.js +51 -230
- package/ui/src/App.jsx +2 -0
- package/ui/src/CompositeSetup.jsx +23 -9
- package/ui/src/PacketFilters.jsx +17 -3
- package/ui/src/components/AlertModal.jsx +116 -0
- package/ui/src/components/App/ApiDocsButton.jsx +57 -0
- package/ui/src/components/App/useAppState.js +43 -1
- package/ui/src/components/BackupList.jsx +27 -3
- package/ui/src/utils/requestPairing.js +35 -36
- package/ui/src/utils/requestUtils.js +1 -0
- package/lib/common/db/init.js +0 -132
- package/lib/common/db/logger.js +0 -349
- package/lib/common/db/query.js +0 -403
- package/lib/common/logger.js +0 -90
- package/mcp-server/index.js +0 -138
- package/mcp-server/lib/server/external/config.js +0 -57
- package/mcp-server/lib/server/internal/handlers/prompts-get.js +0 -20
- package/mcp-server/lib/server/internal/handlers/prompts-list.js +0 -13
- package/mcp-server/lib/server/internal/handlers/resources-list.js +0 -13
- package/mcp-server/lib/server/internal/handlers/resources-read.js +0 -20
- package/mcp-server/lib/server/internal/handlers/tools-call.js +0 -35
- package/mcp-server/lib/server/internal/handlers/tools-list.js +0 -15
- package/mcp-server/lib/server/internal/run.js +0 -37
- package/mcp-server/mcp-shark.js +0 -22
- package/ui/dist/assets/index-CFHeMNwd.js +0 -35
- package/ui/server/routes/backups/deleteBackup.js +0 -54
- package/ui/server/routes/backups/listBackups.js +0 -75
- package/ui/server/routes/backups/restoreBackup.js +0 -83
- package/ui/server/routes/backups/viewBackup.js +0 -47
- package/ui/server/routes/composite/setup.js +0 -129
- package/ui/server/routes/composite/status.js +0 -7
- package/ui/server/routes/composite/stop.js +0 -39
- package/ui/server/routes/composite/utils.js +0 -45
- package/ui/server/routes/smartscan/discover.js +0 -118
- package/ui/server/routes/smartscan/scans/clearCache.js +0 -23
- package/ui/server/routes/smartscan/scans/createBatchScans.js +0 -124
- package/ui/server/routes/smartscan/scans/createScan.js +0 -43
- package/ui/server/routes/smartscan/scans/getCachedResults.js +0 -52
- package/ui/server/routes/smartscan/scans/getScan.js +0 -42
- package/ui/server/routes/smartscan/scans/listScans.js +0 -25
- package/ui/server/routes/smartscan/scans.js +0 -13
- package/ui/server/routes/smartscan/token.js +0 -57
- package/ui/server/utils/config-update.js +0 -240
- package/ui/server/utils/scan-cache/all-results.js +0 -197
- package/ui/server/utils/scan-cache/file-operations.js +0 -107
- package/ui/server/utils/scan-cache/hash.js +0 -47
- package/ui/server/utils/scan-cache/server-operations.js +0 -85
- package/ui/server/utils/scan-cache.js +0 -12
- package/ui/server/utils/smartscan-token.js +0 -43
- /package/{mcp-server/lib → core/mcp-server}/server/external/kv.js +0 -0
- /package/{mcp-server/lib → core/mcp-server}/server/internal/handlers/common.js +0 -0
- /package/{mcp-server/lib → core/mcp-server}/server/internal/session.js +0 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { StatusCodes } from '#core/constants/index.js';
|
|
2
|
+
import { handleError, handleValidationError } from '../utils/errorHandler.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Controller for server management HTTP endpoints
|
|
6
|
+
*/
|
|
7
|
+
export class ServerManagementController {
|
|
8
|
+
constructor(serverManagementService, logService, logger) {
|
|
9
|
+
this.serverManagementService = serverManagementService;
|
|
10
|
+
this.logService = logService;
|
|
11
|
+
this.logger = logger;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Add log entry
|
|
16
|
+
*/
|
|
17
|
+
_addLogEntry(type, message) {
|
|
18
|
+
const timestamp = new Date().toISOString();
|
|
19
|
+
const log = { timestamp, type, line: message };
|
|
20
|
+
this.logService.addLog(log);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
setup = async (req, res) => {
|
|
24
|
+
try {
|
|
25
|
+
this.logger?.debug({ body: req.body }, 'Setup request received');
|
|
26
|
+
const { filePath, fileContent, selectedServices } = req.body;
|
|
27
|
+
|
|
28
|
+
if (!filePath && !fileContent) {
|
|
29
|
+
return handleValidationError(
|
|
30
|
+
'Either filePath or fileContent is required',
|
|
31
|
+
res,
|
|
32
|
+
this.logger
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const setupResult = await this.serverManagementService.setup({
|
|
37
|
+
filePath,
|
|
38
|
+
fileContent,
|
|
39
|
+
selectedServices,
|
|
40
|
+
port: 9851,
|
|
41
|
+
onError: (err) => {
|
|
42
|
+
this._addLogEntry('error', `Failed to start mcp-shark server: ${err.message}`);
|
|
43
|
+
throw err;
|
|
44
|
+
},
|
|
45
|
+
onReady: () => {
|
|
46
|
+
this._addLogEntry('info', 'MCP Shark server is ready!');
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
if (!setupResult.success) {
|
|
51
|
+
const statusCode =
|
|
52
|
+
setupResult.error === 'File not found' ? StatusCodes.NOT_FOUND : StatusCodes.BAD_REQUEST;
|
|
53
|
+
return res.status(statusCode).json(setupResult);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Add log entries for setup process
|
|
57
|
+
this._addLogEntry('info', '[UI Server] Starting MCP-Shark server as library...');
|
|
58
|
+
|
|
59
|
+
if (setupResult.warning) {
|
|
60
|
+
this._addLogEntry('warn', `[WARNING] ${setupResult.warning}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
res.json(setupResult);
|
|
64
|
+
} catch (error) {
|
|
65
|
+
const timestamp = new Date().toISOString();
|
|
66
|
+
const errorLog = {
|
|
67
|
+
timestamp,
|
|
68
|
+
type: 'error',
|
|
69
|
+
line: `[ERROR] Failed to setup mcp-shark server: ${error.message}`,
|
|
70
|
+
};
|
|
71
|
+
this.logService.addLog(errorLog);
|
|
72
|
+
handleError(error, res, this.logger, 'Error setting up mcp-shark server');
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
stop = async (_req, res) => {
|
|
77
|
+
try {
|
|
78
|
+
const stopped = await this.serverManagementService.stopServer();
|
|
79
|
+
const restored = this.configService.restoreOriginalConfig();
|
|
80
|
+
|
|
81
|
+
if (stopped) {
|
|
82
|
+
if (restored) {
|
|
83
|
+
const timestamp = new Date().toISOString();
|
|
84
|
+
const restoreLog = {
|
|
85
|
+
timestamp,
|
|
86
|
+
type: 'stdout',
|
|
87
|
+
line: '[RESTORE] Restored original config',
|
|
88
|
+
};
|
|
89
|
+
this.logService.addLog(restoreLog);
|
|
90
|
+
}
|
|
91
|
+
res.json({
|
|
92
|
+
success: true,
|
|
93
|
+
message: 'MCP Shark server stopped and config restored',
|
|
94
|
+
});
|
|
95
|
+
} else {
|
|
96
|
+
res.json({ success: true, message: 'MCP Shark server was not running' });
|
|
97
|
+
}
|
|
98
|
+
} catch (error) {
|
|
99
|
+
handleError(error, res, this.logger, 'Error stopping server');
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
getStatus = (_req, res) => {
|
|
104
|
+
try {
|
|
105
|
+
const status = this.serverManagementService.getServerStatus();
|
|
106
|
+
res.json(status);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
handleError(error, res, this.logger, 'Error getting server status');
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* GET /api/mcp-server/status
|
|
114
|
+
* Check if the MCP server (gateway) is running
|
|
115
|
+
* This endpoint specifically indicates whether the MCP gateway server is active
|
|
116
|
+
* so users can know if they should focus on the traffic page
|
|
117
|
+
*/
|
|
118
|
+
getMcpServerStatus = (_req, res) => {
|
|
119
|
+
try {
|
|
120
|
+
const status = this.serverManagementService.getServerStatus();
|
|
121
|
+
res.json({
|
|
122
|
+
running: status.running,
|
|
123
|
+
message: status.running
|
|
124
|
+
? 'MCP server (gateway) is running and ready to receive traffic'
|
|
125
|
+
: 'MCP server (gateway) is not running. Start the server to begin capturing traffic.',
|
|
126
|
+
});
|
|
127
|
+
} catch (error) {
|
|
128
|
+
handleError(error, res, this.logger, 'Error getting MCP server status');
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
shutdown = async (_req, res) => {
|
|
133
|
+
try {
|
|
134
|
+
if (!this.cleanup) {
|
|
135
|
+
return res.status(StatusCodes.SERVICE_UNAVAILABLE).json({
|
|
136
|
+
error: 'ServiceUnavailableError',
|
|
137
|
+
message: 'Shutdown not available',
|
|
138
|
+
details: 'Cleanup function not configured',
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const result = await this.serverManagementService.shutdown(this.cleanup);
|
|
143
|
+
|
|
144
|
+
res.json(result);
|
|
145
|
+
|
|
146
|
+
// Give time for response to be sent before process exits
|
|
147
|
+
setTimeout(() => {
|
|
148
|
+
process.exit(0);
|
|
149
|
+
}, 100);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
handleError(error, res, this.logger, 'Error shutting down application');
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Defaults } from '#core/constants/Defaults.js';
|
|
2
|
+
import { StatusCodes } from '#core/constants/StatusCodes.js';
|
|
3
|
+
import { SessionFilters } from '#core/models/SessionFilters.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Controller for session-related HTTP endpoints
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export class SessionController {
|
|
10
|
+
constructor(sessionService, serializationLib, logger) {
|
|
11
|
+
this.sessionService = sessionService;
|
|
12
|
+
this.serializationLib = serializationLib;
|
|
13
|
+
this.logger = logger;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* GET /api/sessions
|
|
18
|
+
*/
|
|
19
|
+
getSessions(req, res) {
|
|
20
|
+
try {
|
|
21
|
+
const filters = new SessionFilters({
|
|
22
|
+
startTime: req.query.startTime || null,
|
|
23
|
+
endTime: req.query.endTime || null,
|
|
24
|
+
limit: req.query.limit,
|
|
25
|
+
offset: req.query.offset,
|
|
26
|
+
});
|
|
27
|
+
const sessions = this.sessionService.getSessions(filters);
|
|
28
|
+
const serialized = this.serializationLib.serializeBigInt(sessions);
|
|
29
|
+
res.json(serialized);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
this.logger.error({ error: error.message }, 'Error in getSessions');
|
|
32
|
+
res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
|
|
33
|
+
error: 'Failed to query sessions',
|
|
34
|
+
details: error.message,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* GET /api/sessions/:sessionId/requests
|
|
41
|
+
*/
|
|
42
|
+
getSessionRequests(req, res) {
|
|
43
|
+
try {
|
|
44
|
+
const sessionId = req.params.sessionId;
|
|
45
|
+
const limit = req.query.limit || Defaults.DEFAULT_SESSION_LIMIT;
|
|
46
|
+
const requests = this.sessionService.getSessionRequests(sessionId, limit);
|
|
47
|
+
const serialized = this.serializationLib.serializeBigInt(requests);
|
|
48
|
+
res.json(serialized);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
this.logger.error({ error: error.message }, 'Error in getSessionRequests');
|
|
51
|
+
res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
|
|
52
|
+
error: 'Failed to get session requests',
|
|
53
|
+
details: error.message,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { StatusCodes } from '#core/constants/index.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Controller for settings HTTP endpoints
|
|
5
|
+
*/
|
|
6
|
+
export class SettingsController {
|
|
7
|
+
constructor(settingsService, logger) {
|
|
8
|
+
this.settingsService = settingsService;
|
|
9
|
+
this.logger = logger;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
getSettings = (_req, res) => {
|
|
13
|
+
try {
|
|
14
|
+
const settings = this.settingsService.getSettings();
|
|
15
|
+
res.json(settings);
|
|
16
|
+
} catch (error) {
|
|
17
|
+
this.logger?.error({ error: error.message }, 'Error getting settings');
|
|
18
|
+
res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
|
|
19
|
+
error: 'Failed to get settings',
|
|
20
|
+
details: error.message,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { StatusCodes } from '#core/constants/StatusCodes.js';
|
|
2
|
+
import { RequestFilters } from '#core/models/RequestFilters.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Controller for statistics-related HTTP endpoints
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export class StatisticsController {
|
|
9
|
+
constructor(statisticsService, serializationLib, logger) {
|
|
10
|
+
this.statisticsService = statisticsService;
|
|
11
|
+
this.serializationLib = serializationLib;
|
|
12
|
+
this.logger = logger;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Sanitize search parameter
|
|
17
|
+
*/
|
|
18
|
+
_sanitizeSearch(value) {
|
|
19
|
+
if (value !== undefined && value !== null) {
|
|
20
|
+
const trimmed = String(value).trim();
|
|
21
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* GET /api/statistics
|
|
28
|
+
*/
|
|
29
|
+
getStatistics(req, res) {
|
|
30
|
+
try {
|
|
31
|
+
const filters = new RequestFilters({
|
|
32
|
+
sessionId: req.query.sessionId ? String(req.query.sessionId).trim() : null,
|
|
33
|
+
direction: req.query.direction ? String(req.query.direction).trim() : null,
|
|
34
|
+
method: req.query.method ? String(req.query.method).trim() : null,
|
|
35
|
+
jsonrpcMethod: req.query.jsonrpcMethod ? String(req.query.jsonrpcMethod).trim() : null,
|
|
36
|
+
statusCode: req.query.statusCode ? Number.parseInt(req.query.statusCode) : null,
|
|
37
|
+
jsonrpcId: req.query.jsonrpcId ? String(req.query.jsonrpcId).trim() : null,
|
|
38
|
+
search: this._sanitizeSearch(req.query.search),
|
|
39
|
+
serverName: req.query.serverName ? String(req.query.serverName).trim() : null,
|
|
40
|
+
startTime: req.query.startTime || null,
|
|
41
|
+
endTime: req.query.endTime || null,
|
|
42
|
+
});
|
|
43
|
+
const stats = this.statisticsService.getStatistics(filters);
|
|
44
|
+
const serialized = this.serializationLib.serializeBigInt(stats);
|
|
45
|
+
res.json(serialized);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
this.logger.error({ error: error.message }, 'Error in getStatistics');
|
|
48
|
+
res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
|
|
49
|
+
error: 'Failed to get statistics',
|
|
50
|
+
details: error.message,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { StatusCodes } from '#core/constants/index.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Controller for Smart Scan token HTTP endpoints
|
|
5
|
+
*/
|
|
6
|
+
export class TokenController {
|
|
7
|
+
constructor(tokenService, logger) {
|
|
8
|
+
this.tokenService = tokenService;
|
|
9
|
+
this.logger = logger;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
getToken = (_req, res) => {
|
|
13
|
+
try {
|
|
14
|
+
const token = this.tokenService.readToken();
|
|
15
|
+
return res.json({
|
|
16
|
+
success: true,
|
|
17
|
+
token: token || null,
|
|
18
|
+
});
|
|
19
|
+
} catch (error) {
|
|
20
|
+
this.logger?.error({ error: error.message }, 'Error reading Smart Scan token');
|
|
21
|
+
return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
|
|
22
|
+
error: 'Failed to read token',
|
|
23
|
+
message: error.message,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
saveToken = (req, res) => {
|
|
29
|
+
try {
|
|
30
|
+
const { token } = req.body;
|
|
31
|
+
|
|
32
|
+
if (token === undefined) {
|
|
33
|
+
return res.status(StatusCodes.BAD_REQUEST).json({
|
|
34
|
+
error: 'Token is required',
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const success = this.tokenService.writeToken(token);
|
|
39
|
+
|
|
40
|
+
if (!success) {
|
|
41
|
+
return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
|
|
42
|
+
error: 'Failed to save token',
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return res.json({
|
|
47
|
+
success: true,
|
|
48
|
+
message: 'Token saved successfully',
|
|
49
|
+
});
|
|
50
|
+
} catch (error) {
|
|
51
|
+
this.logger?.error({ error: error.message }, 'Error saving Smart Scan token');
|
|
52
|
+
return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
|
|
53
|
+
error: 'Failed to save token',
|
|
54
|
+
message: error.message,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Controller layer exports
|
|
3
|
+
* Controllers handle HTTP concerns: extraction, sanitization, serialization, formatting
|
|
4
|
+
*/
|
|
5
|
+
export { RequestController } from './RequestController.js';
|
|
6
|
+
export { SessionController } from './SessionController.js';
|
|
7
|
+
export { ConversationController } from './ConversationController.js';
|
|
8
|
+
export { StatisticsController } from './StatisticsController.js';
|
|
9
|
+
export { ConfigController } from './ConfigController.js';
|
|
10
|
+
export { BackupController } from './BackupController.js';
|
|
11
|
+
export { LogController } from './LogController.js';
|
|
12
|
+
export { ScanController } from './ScanController.js';
|
|
13
|
+
export { McpDiscoveryController } from './McpDiscoveryController.js';
|
|
14
|
+
export { McpClientController } from './McpClientController.js';
|
|
15
|
+
export { TokenController } from './TokenController.js';
|
|
16
|
+
export { SettingsController } from './SettingsController.js';
|
|
17
|
+
export { ServerManagementController } from './ServerManagementController.js';
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { BackupController } from '#ui/server/controllers/index.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create backup routes
|
|
5
|
+
* Routes delegate to BackupController which calls BackupService
|
|
6
|
+
*/
|
|
7
|
+
export function createBackupRoutes(container) {
|
|
8
|
+
const backupService = container.getService('backup');
|
|
9
|
+
const serverManagementService = container.getService('serverManagement');
|
|
10
|
+
const logger = container.getLibrary('logger');
|
|
11
|
+
const backupController = new BackupController(backupService, serverManagementService, logger);
|
|
5
12
|
|
|
6
|
-
export function createBackupRoutes() {
|
|
7
13
|
const router = {};
|
|
8
14
|
|
|
9
|
-
router.listBackups = listBackups;
|
|
10
|
-
router.restoreBackup = restoreBackup;
|
|
11
|
-
router.viewBackup = viewBackup;
|
|
12
|
-
router.deleteBackup = deleteBackup;
|
|
15
|
+
router.listBackups = backupController.listBackups;
|
|
16
|
+
router.restoreBackup = backupController.restoreBackup;
|
|
17
|
+
router.viewBackup = backupController.viewBackup;
|
|
18
|
+
router.deleteBackup = backupController.deleteBackup;
|
|
13
19
|
|
|
14
20
|
return router;
|
|
15
21
|
}
|
|
@@ -1,46 +1,77 @@
|
|
|
1
|
+
import { ServerManagementController } from '#ui/server/controllers/index.js';
|
|
1
2
|
import { getServers } from './servers.js';
|
|
2
|
-
import { setup } from './setup.js';
|
|
3
|
-
import { getStatus } from './status.js';
|
|
4
|
-
import { stop } from './stop.js';
|
|
5
3
|
|
|
4
|
+
function getServerInstanceWrapper(getMcpSharkProcess, originalGetInstance) {
|
|
5
|
+
return getMcpSharkProcess() || originalGetInstance();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function createGetServerInstance(getMcpSharkProcess, originalGetInstance) {
|
|
9
|
+
return () => {
|
|
10
|
+
return getServerInstanceWrapper(getMcpSharkProcess, originalGetInstance);
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function setServerInstanceWrapper(setMcpSharkProcess, serverManagementService, instance) {
|
|
15
|
+
setMcpSharkProcess(instance);
|
|
16
|
+
serverManagementService.serverInstance = instance;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function createSetServerInstance(setMcpSharkProcess, serverManagementService) {
|
|
20
|
+
return (instance) => {
|
|
21
|
+
setServerInstanceWrapper(setMcpSharkProcess, serverManagementService, instance);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Create composite routes
|
|
27
|
+
* Routes delegate to controllers which call services
|
|
28
|
+
*/
|
|
6
29
|
export function createCompositeRoutes(
|
|
30
|
+
container,
|
|
7
31
|
getMcpSharkProcess,
|
|
8
32
|
setMcpSharkProcess,
|
|
9
33
|
mcpSharkLogs,
|
|
10
|
-
|
|
34
|
+
_broadcastLogUpdate,
|
|
35
|
+
cleanup
|
|
11
36
|
) {
|
|
12
|
-
const
|
|
37
|
+
const serverManagementService = container.getService('serverManagement');
|
|
38
|
+
const logService = container.getService('log');
|
|
39
|
+
const logger = container.getLibrary('logger');
|
|
13
40
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
req,
|
|
17
|
-
res,
|
|
18
|
-
getMcpSharkProcess,
|
|
19
|
-
setMcpSharkProcess,
|
|
20
|
-
mcpSharkLogs,
|
|
21
|
-
broadcastLogUpdate
|
|
22
|
-
);
|
|
23
|
-
};
|
|
41
|
+
// Initialize log service with the log array
|
|
42
|
+
logService.initialize(mcpSharkLogs);
|
|
24
43
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
44
|
+
// Set server instance getter/setter
|
|
45
|
+
const originalGetInstance =
|
|
46
|
+
serverManagementService.getServerInstance.bind(serverManagementService);
|
|
47
|
+
serverManagementService.getServerInstance = createGetServerInstance(
|
|
48
|
+
getMcpSharkProcess,
|
|
49
|
+
originalGetInstance
|
|
50
|
+
);
|
|
51
|
+
serverManagementService.setServerInstance = createSetServerInstance(
|
|
52
|
+
setMcpSharkProcess,
|
|
53
|
+
serverManagementService
|
|
54
|
+
);
|
|
36
55
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
56
|
+
const serverManagementController = new ServerManagementController(
|
|
57
|
+
serverManagementService,
|
|
58
|
+
logService,
|
|
59
|
+
logger
|
|
60
|
+
);
|
|
40
61
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
62
|
+
// Set cleanup function for shutdown endpoint
|
|
63
|
+
if (cleanup) {
|
|
64
|
+
serverManagementController.cleanup = cleanup;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const router = {};
|
|
68
|
+
|
|
69
|
+
router.setup = serverManagementController.setup;
|
|
70
|
+
router.stop = serverManagementController.stop;
|
|
71
|
+
router.getStatus = serverManagementController.getStatus;
|
|
72
|
+
router.getMcpServerStatus = serverManagementController.getMcpServerStatus;
|
|
73
|
+
router.shutdown = serverManagementController.shutdown;
|
|
74
|
+
router.getServers = getServers(container);
|
|
44
75
|
|
|
45
76
|
return router;
|
|
46
77
|
}
|
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { getMcpConfigPath } from '#common/configs';
|
|
1
|
+
import { StatusCodes } from '#core/constants/index.js';
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Get servers from config
|
|
5
|
+
* Uses ConfigService via ConfigController
|
|
6
|
+
*/
|
|
7
|
+
export function getServers(container) {
|
|
8
|
+
const configService = container.getService('config');
|
|
9
|
+
const logger = container.getLibrary('logger');
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
return (_req, res) => {
|
|
12
|
+
try {
|
|
13
|
+
const servers = configService.getServersFromConfig();
|
|
14
|
+
res.json({ servers });
|
|
15
|
+
} catch (error) {
|
|
16
|
+
logger.error({ error: error.message }, 'Error getting servers');
|
|
17
|
+
res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
|
|
18
|
+
error: 'Failed to get servers',
|
|
19
|
+
details: error.message,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
};
|
|
18
23
|
}
|