@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.
Files changed (188) hide show
  1. package/README.md +32 -96
  2. package/bin/mcp-shark.js +1 -1
  3. package/core/configs/codex.js +68 -0
  4. package/core/configs/environment.js +51 -0
  5. package/{lib/common → core}/configs/index.js +16 -1
  6. package/core/constants/Defaults.js +15 -0
  7. package/core/constants/HttpStatus.js +14 -0
  8. package/core/constants/Server.js +20 -0
  9. package/core/constants/StatusCodes.js +25 -0
  10. package/core/constants/index.js +7 -0
  11. package/core/container/DependencyContainer.js +179 -0
  12. package/core/db/init.js +33 -0
  13. package/core/index.js +10 -0
  14. package/{mcp-server/lib/common/error.js → core/libraries/ErrorLibrary.js} +4 -0
  15. package/core/libraries/LoggerLibrary.js +91 -0
  16. package/core/libraries/SerializationLibrary.js +32 -0
  17. package/core/libraries/bootstrap-logger.js +19 -0
  18. package/core/libraries/errors/ApplicationError.js +97 -0
  19. package/core/libraries/index.js +17 -0
  20. package/{mcp-server/lib → core/mcp-server}/auditor/audit.js +77 -53
  21. package/core/mcp-server/index.js +192 -0
  22. package/{mcp-server/lib → core/mcp-server}/server/external/all.js +1 -1
  23. package/core/mcp-server/server/external/config.js +75 -0
  24. package/{mcp-server/lib → core/mcp-server}/server/external/single/client.js +1 -1
  25. package/{mcp-server/lib → core/mcp-server}/server/external/single/request.js +1 -1
  26. package/{mcp-server/lib → core/mcp-server}/server/external/single/run.js +20 -11
  27. package/{mcp-server/lib → core/mcp-server}/server/external/single/transport.js +1 -1
  28. package/{mcp-server/lib → core/mcp-server}/server/internal/handlers/error.js +1 -1
  29. package/core/mcp-server/server/internal/handlers/prompts-get.js +28 -0
  30. package/core/mcp-server/server/internal/handlers/prompts-list.js +21 -0
  31. package/core/mcp-server/server/internal/handlers/resources-list.js +21 -0
  32. package/core/mcp-server/server/internal/handlers/resources-read.js +28 -0
  33. package/core/mcp-server/server/internal/handlers/tools-call.js +44 -0
  34. package/core/mcp-server/server/internal/handlers/tools-list.js +23 -0
  35. package/core/mcp-server/server/internal/run.js +53 -0
  36. package/{mcp-server/lib → core/mcp-server}/server/internal/server.js +11 -1
  37. package/core/models/ConversationFilters.js +31 -0
  38. package/core/models/ExportFormat.js +8 -0
  39. package/core/models/RequestFilters.js +43 -0
  40. package/core/models/SessionFilters.js +23 -0
  41. package/core/models/index.js +8 -0
  42. package/core/repositories/AuditRepository.js +233 -0
  43. package/core/repositories/ConversationRepository.js +182 -0
  44. package/core/repositories/PacketRepository.js +237 -0
  45. package/core/repositories/SchemaRepository.js +107 -0
  46. package/core/repositories/SessionRepository.js +59 -0
  47. package/core/repositories/StatisticsRepository.js +54 -0
  48. package/core/repositories/index.js +10 -0
  49. package/core/services/AuditService.js +144 -0
  50. package/core/services/BackupService.js +222 -0
  51. package/core/services/ConfigDetectionService.js +89 -0
  52. package/core/services/ConfigFileService.js +210 -0
  53. package/core/services/ConfigPatchingService.js +137 -0
  54. package/core/services/ConfigService.js +250 -0
  55. package/core/services/ConfigTransformService.js +178 -0
  56. package/core/services/ConversationService.js +19 -0
  57. package/core/services/ExportService.js +117 -0
  58. package/core/services/LogService.js +64 -0
  59. package/core/services/McpClientService.js +235 -0
  60. package/core/services/McpDiscoveryService.js +107 -0
  61. package/core/services/RequestService.js +56 -0
  62. package/core/services/ScanCacheService.js +242 -0
  63. package/core/services/ScanService.js +167 -0
  64. package/core/services/ServerManagementService.js +206 -0
  65. package/core/services/SessionService.js +34 -0
  66. package/core/services/SettingsService.js +163 -0
  67. package/core/services/StatisticsService.js +64 -0
  68. package/core/services/TokenService.js +94 -0
  69. package/core/services/index.js +25 -0
  70. package/core/services/parsers/ConfigParserFactory.js +113 -0
  71. package/core/services/parsers/JsonConfigParser.js +66 -0
  72. package/core/services/parsers/LegacyJsonConfigParser.js +71 -0
  73. package/core/services/parsers/TomlConfigParser.js +87 -0
  74. package/core/services/parsers/index.js +4 -0
  75. package/{ui/server → core}/utils/scan-cache/directory.js +1 -1
  76. package/core/utils/validation.js +77 -0
  77. package/package.json +14 -11
  78. package/ui/dist/assets/index-CArYxKxS.js +35 -0
  79. package/ui/dist/index.html +1 -1
  80. package/ui/server/controllers/BackupController.js +129 -0
  81. package/ui/server/controllers/ConfigController.js +92 -0
  82. package/ui/server/controllers/ConversationController.js +41 -0
  83. package/ui/server/controllers/LogController.js +44 -0
  84. package/ui/server/controllers/McpClientController.js +60 -0
  85. package/ui/server/controllers/McpDiscoveryController.js +44 -0
  86. package/ui/server/controllers/RequestController.js +129 -0
  87. package/ui/server/controllers/ScanController.js +122 -0
  88. package/ui/server/controllers/ServerManagementController.js +154 -0
  89. package/ui/server/controllers/SessionController.js +57 -0
  90. package/ui/server/controllers/SettingsController.js +24 -0
  91. package/ui/server/controllers/StatisticsController.js +54 -0
  92. package/ui/server/controllers/TokenController.js +58 -0
  93. package/ui/server/controllers/index.js +17 -0
  94. package/ui/server/routes/backups/index.js +15 -9
  95. package/ui/server/routes/composite/index.js +63 -32
  96. package/ui/server/routes/composite/servers.js +20 -15
  97. package/ui/server/routes/config.js +13 -172
  98. package/ui/server/routes/conversations.js +9 -19
  99. package/ui/server/routes/help.js +4 -3
  100. package/ui/server/routes/logs.js +14 -26
  101. package/ui/server/routes/playground.js +11 -174
  102. package/ui/server/routes/requests.js +12 -232
  103. package/ui/server/routes/sessions.js +10 -21
  104. package/ui/server/routes/settings.js +10 -192
  105. package/ui/server/routes/smartscan.js +26 -15
  106. package/ui/server/routes/statistics.js +8 -79
  107. package/ui/server/setup.js +163 -0
  108. package/ui/server/swagger/paths/backups.js +151 -0
  109. package/ui/server/swagger/paths/components.js +76 -0
  110. package/ui/server/swagger/paths/config.js +117 -0
  111. package/ui/server/swagger/paths/conversations.js +29 -0
  112. package/ui/server/swagger/paths/help.js +82 -0
  113. package/ui/server/swagger/paths/logs.js +87 -0
  114. package/ui/server/swagger/paths/playground.js +49 -0
  115. package/ui/server/swagger/paths/requests.js +178 -0
  116. package/ui/server/swagger/paths/serverManagement.js +205 -0
  117. package/ui/server/swagger/paths/sessions.js +61 -0
  118. package/ui/server/swagger/paths/settings.js +31 -0
  119. package/ui/server/swagger/paths/smartScan/discovery.js +97 -0
  120. package/ui/server/swagger/paths/smartScan/index.js +13 -0
  121. package/ui/server/swagger/paths/smartScan/scans.js +151 -0
  122. package/ui/server/swagger/paths/smartScan/token.js +71 -0
  123. package/ui/server/swagger/paths/statistics.js +40 -0
  124. package/ui/server/swagger/paths.js +38 -0
  125. package/ui/server/swagger/swagger.js +37 -0
  126. package/ui/server/utils/cleanup.js +99 -0
  127. package/ui/server/utils/config.js +18 -96
  128. package/ui/server/utils/errorHandler.js +43 -0
  129. package/ui/server/utils/logger.js +2 -2
  130. package/ui/server/utils/paths.js +27 -30
  131. package/ui/server/utils/port.js +21 -21
  132. package/ui/server/utils/process.js +18 -10
  133. package/ui/server/utils/processState.js +17 -0
  134. package/ui/server/utils/signals.js +34 -0
  135. package/ui/server/websocket/broadcast.js +33 -0
  136. package/ui/server/websocket/handler.js +52 -0
  137. package/ui/server.js +51 -230
  138. package/ui/src/App.jsx +2 -0
  139. package/ui/src/CompositeSetup.jsx +23 -9
  140. package/ui/src/PacketFilters.jsx +17 -3
  141. package/ui/src/components/AlertModal.jsx +116 -0
  142. package/ui/src/components/App/ApiDocsButton.jsx +57 -0
  143. package/ui/src/components/App/useAppState.js +43 -1
  144. package/ui/src/components/BackupList.jsx +27 -3
  145. package/ui/src/utils/requestPairing.js +35 -36
  146. package/ui/src/utils/requestUtils.js +1 -0
  147. package/lib/common/db/init.js +0 -132
  148. package/lib/common/db/logger.js +0 -349
  149. package/lib/common/db/query.js +0 -403
  150. package/lib/common/logger.js +0 -90
  151. package/mcp-server/index.js +0 -138
  152. package/mcp-server/lib/server/external/config.js +0 -57
  153. package/mcp-server/lib/server/internal/handlers/prompts-get.js +0 -20
  154. package/mcp-server/lib/server/internal/handlers/prompts-list.js +0 -13
  155. package/mcp-server/lib/server/internal/handlers/resources-list.js +0 -13
  156. package/mcp-server/lib/server/internal/handlers/resources-read.js +0 -20
  157. package/mcp-server/lib/server/internal/handlers/tools-call.js +0 -35
  158. package/mcp-server/lib/server/internal/handlers/tools-list.js +0 -15
  159. package/mcp-server/lib/server/internal/run.js +0 -37
  160. package/mcp-server/mcp-shark.js +0 -22
  161. package/ui/dist/assets/index-CFHeMNwd.js +0 -35
  162. package/ui/server/routes/backups/deleteBackup.js +0 -54
  163. package/ui/server/routes/backups/listBackups.js +0 -75
  164. package/ui/server/routes/backups/restoreBackup.js +0 -83
  165. package/ui/server/routes/backups/viewBackup.js +0 -47
  166. package/ui/server/routes/composite/setup.js +0 -129
  167. package/ui/server/routes/composite/status.js +0 -7
  168. package/ui/server/routes/composite/stop.js +0 -39
  169. package/ui/server/routes/composite/utils.js +0 -45
  170. package/ui/server/routes/smartscan/discover.js +0 -118
  171. package/ui/server/routes/smartscan/scans/clearCache.js +0 -23
  172. package/ui/server/routes/smartscan/scans/createBatchScans.js +0 -124
  173. package/ui/server/routes/smartscan/scans/createScan.js +0 -43
  174. package/ui/server/routes/smartscan/scans/getCachedResults.js +0 -52
  175. package/ui/server/routes/smartscan/scans/getScan.js +0 -42
  176. package/ui/server/routes/smartscan/scans/listScans.js +0 -25
  177. package/ui/server/routes/smartscan/scans.js +0 -13
  178. package/ui/server/routes/smartscan/token.js +0 -57
  179. package/ui/server/utils/config-update.js +0 -240
  180. package/ui/server/utils/scan-cache/all-results.js +0 -197
  181. package/ui/server/utils/scan-cache/file-operations.js +0 -107
  182. package/ui/server/utils/scan-cache/hash.js +0 -47
  183. package/ui/server/utils/scan-cache/server-operations.js +0 -85
  184. package/ui/server/utils/scan-cache.js +0 -12
  185. package/ui/server/utils/smartscan-token.js +0 -43
  186. /package/{mcp-server/lib → core/mcp-server}/server/external/kv.js +0 -0
  187. /package/{mcp-server/lib → core/mcp-server}/server/internal/handlers/common.js +0 -0
  188. /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 { deleteBackup } from './deleteBackup.js';
2
- import { listBackups } from './listBackups.js';
3
- import { restoreBackup } from './restoreBackup.js';
4
- import { viewBackup } from './viewBackup.js';
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
- broadcastLogUpdate
34
+ _broadcastLogUpdate,
35
+ cleanup
11
36
  ) {
12
- const router = {};
37
+ const serverManagementService = container.getService('serverManagement');
38
+ const logService = container.getService('log');
39
+ const logger = container.getLibrary('logger');
13
40
 
14
- router.setup = async (req, res) => {
15
- return setup(
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
- router.stop = async (req, res, restoreOriginalConfig) => {
26
- return stop(
27
- req,
28
- res,
29
- restoreOriginalConfig,
30
- getMcpSharkProcess,
31
- setMcpSharkProcess,
32
- mcpSharkLogs,
33
- broadcastLogUpdate
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
- router.getStatus = (req, res) => {
38
- return getStatus(req, res, getMcpSharkProcess);
39
- };
56
+ const serverManagementController = new ServerManagementController(
57
+ serverManagementService,
58
+ logService,
59
+ logger
60
+ );
40
61
 
41
- router.getServers = (req, res) => {
42
- return getServers(req, res);
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 * as fs from 'node:fs';
2
- import { getMcpConfigPath } from '#common/configs';
1
+ import { StatusCodes } from '#core/constants/index.js';
3
2
 
4
- export function getServers(_req, res) {
5
- try {
6
- const mcpsJsonPath = getMcpConfigPath();
7
- if (!fs.existsSync(mcpsJsonPath)) {
8
- return res.json({ servers: [] });
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
- const configContent = fs.readFileSync(mcpsJsonPath, 'utf-8');
12
- const config = JSON.parse(configContent);
13
- const servers = config.servers ? Object.keys(config.servers) : [];
14
- res.json({ servers });
15
- } catch (error) {
16
- res.status(500).json({ error: 'Failed to get servers', details: error.message });
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
  }