@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,75 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { CompositeError, isError } from '#core/libraries/ErrorLibrary.js';
3
+ import { ConfigParserFactory } from '#core/services/parsers/ConfigParserFactory.js';
4
+
5
+ const DEFAULT_TYPE = 'stdio';
6
+
7
+ export class ConfigError extends CompositeError {
8
+ constructor(message, error) {
9
+ super('ConfigError', message, error);
10
+ }
11
+ }
12
+
13
+ const parserFactory = new ConfigParserFactory();
14
+
15
+ function parseConfig(configPath) {
16
+ if (!existsSync(configPath)) {
17
+ return new ConfigError(
18
+ 'Config file not found',
19
+ new Error(`Config file not found: ${configPath}`)
20
+ );
21
+ }
22
+
23
+ try {
24
+ const content = readFileSync(configPath, 'utf-8');
25
+ const parsed = parserFactory.parse(content, configPath);
26
+
27
+ if (parsed && typeof parsed === 'object') {
28
+ return parsed;
29
+ }
30
+
31
+ return new ConfigError('Invalid config file', new Error(`Invalid config file: ${configPath}`));
32
+ } catch (error) {
33
+ return new ConfigError(
34
+ 'Error parsing config',
35
+ new Error(`Error parsing config: ${configPath} - ${error.message}`)
36
+ );
37
+ }
38
+ }
39
+
40
+ export function normalizeConfig(configPath) {
41
+ const parsedConfigResult = parseConfig(configPath);
42
+ if (isError(parsedConfigResult)) {
43
+ return parsedConfigResult;
44
+ }
45
+
46
+ const normalized = parserFactory.normalizeToInternalFormat(parsedConfigResult, configPath);
47
+ if (!normalized) {
48
+ return new ConfigError('No servers found in config');
49
+ }
50
+
51
+ // Convert to flat map format expected by MCP server
52
+ const out = new Map();
53
+
54
+ // Handle normalized mcpServers format
55
+ if (normalized.mcpServers) {
56
+ for (const [name, cfg] of Object.entries(normalized.mcpServers)) {
57
+ const type = cfg.type ?? DEFAULT_TYPE;
58
+ out.set(name, { type, ...cfg });
59
+ }
60
+ }
61
+
62
+ // Handle normalized servers format (legacy)
63
+ if (normalized.servers) {
64
+ for (const [name, cfg] of Object.entries(normalized.servers)) {
65
+ const type = cfg.type ?? DEFAULT_TYPE;
66
+ out.set(name, { type, ...cfg });
67
+ }
68
+ }
69
+
70
+ if (out.size === 0) {
71
+ return new ConfigError('No servers found in config');
72
+ }
73
+
74
+ return Object.fromEntries(out);
75
+ }
@@ -1,5 +1,5 @@
1
1
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
- import { CompositeError } from '../../../common/error.js';
2
+ import { CompositeError } from '#core/libraries/ErrorLibrary.js';
3
3
 
4
4
  const DEFAULT_VERSION = '1.0.0';
5
5
  const DEFAULT_NAME = 'mcp-client';
@@ -4,7 +4,7 @@ import {
4
4
  ListToolsResultSchema,
5
5
  } from '@modelcontextprotocol/sdk/types.js';
6
6
 
7
- import { CompositeError } from '../../../common/error.js';
7
+ import { CompositeError } from '#core/libraries/ErrorLibrary.js';
8
8
  const METHOD_NOT_FOUND_CODE = '-32601';
9
9
 
10
10
  export class RequestError extends CompositeError {
@@ -1,4 +1,4 @@
1
- import { CompositeError, getErrors, isError } from '../../../common/error.js';
1
+ import { CompositeError, getErrors, isError } from '#core/libraries/ErrorLibrary.js';
2
2
  import { createClient } from './client.js';
3
3
  import * as requests from './request.js';
4
4
  import { makeTransport } from './transport.js';
@@ -10,6 +10,21 @@ export class RunError extends CompositeError {
10
10
  }
11
11
  }
12
12
 
13
+ function createCallTool(client, args) {
14
+ return client.callTool.bind(client)(args);
15
+ }
16
+
17
+ function createReadResource(client, resourceUri) {
18
+ return client.readResource.bind(client)(resourceUri);
19
+ }
20
+
21
+ function createGetPrompt(client, promptName, args) {
22
+ return client.getPrompt.bind(client)({
23
+ name: promptName,
24
+ arguments: args,
25
+ });
26
+ }
27
+
13
28
  export async function runExternalServer({ logger, name, config }) {
14
29
  logger.debug(`Starting external server run for server ${name} with config:`, config);
15
30
 
@@ -44,21 +59,15 @@ export async function runExternalServer({ logger, name, config }) {
44
59
  }
45
60
 
46
61
  const [{ tools }, { resources }, { prompts }] = results.map((result) => result.value);
62
+
47
63
  return {
48
64
  name,
49
65
  client,
50
66
  tools,
51
67
  resources,
52
68
  prompts,
53
- callTool: (args) => client.callTool.bind(client)(args),
54
- readResource: (resourceUri) => {
55
- return client.readResource.bind(client)(resourceUri);
56
- },
57
- getPrompt: (promptName, args) => {
58
- return client.getPrompt.bind(client)({
59
- name: promptName,
60
- arguments: args,
61
- });
62
- },
69
+ callTool: (args) => createCallTool(client, args),
70
+ readResource: (resourceUri) => createReadResource(client, resourceUri),
71
+ getPrompt: (promptName, args) => createGetPrompt(client, promptName, args),
63
72
  };
64
73
  }
@@ -2,7 +2,7 @@ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
2
2
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
3
3
  import { WebSocketClientTransport } from '@modelcontextprotocol/sdk/client/websocket.js';
4
4
 
5
- import { CompositeError } from '../../../common/error.js';
5
+ import { CompositeError } from '#core/libraries/ErrorLibrary.js';
6
6
 
7
7
  export class TransportError extends CompositeError {
8
8
  constructor(message, error) {
@@ -1,4 +1,4 @@
1
- import { CompositeError } from '../../../common/error.js';
1
+ import { CompositeError } from '#core/libraries/ErrorLibrary.js';
2
2
 
3
3
  export class InternalServerError extends CompositeError {
4
4
  constructor(message, error) {
@@ -0,0 +1,28 @@
1
+ import { getBy } from '../../external/kv.js';
2
+ import { InternalServerError } from './error.js';
3
+
4
+ async function handlePromptsGet(req, logger, mcpServers, requestedMcpServer) {
5
+ const name = req.params.name;
6
+ const promptArgs = req?.params?.arguments || {};
7
+ logger.debug('Prompt get', name, promptArgs);
8
+
9
+ const getPrompt = getBy(mcpServers, requestedMcpServer, name, 'getPrompt', promptArgs);
10
+ if (!getPrompt) {
11
+ throw new InternalServerError(`Prompt not found: ${name}`);
12
+ }
13
+
14
+ const result = await getPrompt(name, promptArgs);
15
+ logger.debug('Prompt get result', result);
16
+
17
+ return result;
18
+ }
19
+
20
+ function createPromptsGetHandlerWrapper(req, logger, mcpServers, requestedMcpServer) {
21
+ return handlePromptsGet(req, logger, mcpServers, requestedMcpServer);
22
+ }
23
+
24
+ export function createPromptsGetHandler(logger, mcpServers, requestedMcpServer) {
25
+ return async (req) => {
26
+ return createPromptsGetHandlerWrapper(req, logger, mcpServers, requestedMcpServer);
27
+ };
28
+ }
@@ -0,0 +1,21 @@
1
+ import { listAll } from '../../external/kv.js';
2
+
3
+ async function handlePromptsList(req, logger, mcpServers, requestedMcpServer) {
4
+ const path = req.path;
5
+ logger.debug('Prompts list', path);
6
+
7
+ const res = await listAll(mcpServers, requestedMcpServer, 'prompts');
8
+ const result = Array.isArray(res) ? { prompts: res } : res;
9
+
10
+ return result;
11
+ }
12
+
13
+ function createPromptsListHandlerWrapper(req, logger, mcpServers, requestedMcpServer) {
14
+ return handlePromptsList(req, logger, mcpServers, requestedMcpServer);
15
+ }
16
+
17
+ export function createPromptsListHandler(logger, mcpServers, requestedMcpServer) {
18
+ return async (req) => {
19
+ return createPromptsListHandlerWrapper(req, logger, mcpServers, requestedMcpServer);
20
+ };
21
+ }
@@ -0,0 +1,21 @@
1
+ import { listAll } from '../../external/kv.js';
2
+
3
+ async function handleResourcesList(req, logger, mcpServers, requestedMcpServer) {
4
+ const path = req.path;
5
+ logger.debug('Resources list', path);
6
+
7
+ const res = await listAll(mcpServers, requestedMcpServer, 'resources');
8
+ const result = Array.isArray(res) ? { resources: res } : res;
9
+
10
+ return result;
11
+ }
12
+
13
+ function createResourcesListHandlerWrapper(req, logger, mcpServers, requestedMcpServer) {
14
+ return handleResourcesList(req, logger, mcpServers, requestedMcpServer);
15
+ }
16
+
17
+ export function createResourcesListHandler(logger, mcpServers, requestedMcpServer) {
18
+ return async (req) => {
19
+ return createResourcesListHandlerWrapper(req, logger, mcpServers, requestedMcpServer);
20
+ };
21
+ }
@@ -0,0 +1,28 @@
1
+ import { getBy } from '../../external/kv.js';
2
+ import { InternalServerError } from './error.js';
3
+
4
+ async function handleResourcesRead(req, logger, mcpServers, requestedMcpServer) {
5
+ const path = req.path;
6
+ const uri = req.params.uri;
7
+ logger.debug('Resource read', path, uri);
8
+
9
+ const readResource = getBy(mcpServers, requestedMcpServer, uri, 'readResource');
10
+ if (!readResource) {
11
+ throw new InternalServerError(`Resource not found: ${uri}`);
12
+ }
13
+
14
+ const result = await readResource(uri);
15
+ logger.debug('Resource read result', result);
16
+
17
+ return result;
18
+ }
19
+
20
+ function createResourcesReadHandlerWrapper(req, logger, mcpServers, requestedMcpServer) {
21
+ return handleResourcesRead(req, logger, mcpServers, requestedMcpServer);
22
+ }
23
+
24
+ export function createResourcesReadHandler(logger, mcpServers, requestedMcpServer) {
25
+ return async (req) => {
26
+ return createResourcesReadHandlerWrapper(req, logger, mcpServers, requestedMcpServer);
27
+ };
28
+ }
@@ -0,0 +1,44 @@
1
+ import { getBy } from '../../external/kv.js';
2
+ import { InternalServerError } from './error.js';
3
+
4
+ const isAsyncIterable = (v) => v && typeof v[Symbol.asyncIterator] === 'function';
5
+
6
+ async function* createLoggedStream(result, logger) {
7
+ for await (const chunk of result) {
8
+ logger.debug('Tool call chunk forwarded', chunk);
9
+ yield chunk;
10
+ }
11
+ }
12
+
13
+ async function handleToolsCall(req, logger, mcpServers, requestedMcpServer) {
14
+ const path = req.path;
15
+ const { name, arguments: args } = req.params;
16
+ logger.debug('Tool call', path, name, args);
17
+
18
+ const callTool = getBy(mcpServers, requestedMcpServer, name, 'callTool', args || {});
19
+ if (!callTool) {
20
+ throw new InternalServerError(`Tool not found: ${name}`);
21
+ }
22
+
23
+ const result = await callTool({
24
+ ...req.params,
25
+ name,
26
+ });
27
+ logger.debug('Tool call result', result);
28
+
29
+ if (isAsyncIterable(result)) {
30
+ return createLoggedStream(result, logger);
31
+ }
32
+
33
+ return result;
34
+ }
35
+
36
+ function createToolsCallHandlerWrapper(req, logger, mcpServers, requestedMcpServer) {
37
+ return handleToolsCall(req, logger, mcpServers, requestedMcpServer);
38
+ }
39
+
40
+ export function createToolsCallHandler(logger, mcpServers, requestedMcpServer) {
41
+ return async (req) => {
42
+ return createToolsCallHandlerWrapper(req, logger, mcpServers, requestedMcpServer);
43
+ };
44
+ }
@@ -0,0 +1,23 @@
1
+ import { listAll } from '../../external/kv.js';
2
+
3
+ async function handleToolsList(req, logger, mcpServers, requestedMcpServer) {
4
+ const path = req.path;
5
+ logger.debug('Listing tools', path);
6
+
7
+ const res = await listAll(mcpServers, requestedMcpServer, 'tools');
8
+ logger.debug('Tools list result', JSON.stringify(res));
9
+
10
+ const result = Array.isArray(res) ? { tools: res } : res;
11
+
12
+ return result;
13
+ }
14
+
15
+ function createToolsListHandlerWrapper(req, logger, mcpServers, requestedMcpServer) {
16
+ return handleToolsList(req, logger, mcpServers, requestedMcpServer);
17
+ }
18
+
19
+ export function createToolsListHandler(logger, mcpServers, requestedMcpServer) {
20
+ return async (req) => {
21
+ return createToolsListHandlerWrapper(req, logger, mcpServers, requestedMcpServer);
22
+ };
23
+ }
@@ -0,0 +1,53 @@
1
+ import cors from 'cors';
2
+ import express from 'express';
3
+
4
+ import { withSession } from './session.js';
5
+
6
+ async function handleMcpRoute(
7
+ req,
8
+ res,
9
+ serverFactory,
10
+ withAuditRequestResponseHandler,
11
+ auditLogger
12
+ ) {
13
+ await withSession(serverFactory, withAuditRequestResponseHandler, req, res, auditLogger);
14
+ }
15
+
16
+ function handleNotFoundRoute(_req, res) {
17
+ res.status(404).json({ error: 'Not found' });
18
+ }
19
+
20
+ export function getInternalServer(serverFactory, auditLogger, withAuditRequestResponseHandler) {
21
+ const app = express();
22
+
23
+ // Parse JSON body for POST requests
24
+ app.use(express.json());
25
+ app.use(
26
+ '/mcp',
27
+ cors({
28
+ origin: ['*'],
29
+ methods: ['*'],
30
+ allowedHeaders: ['*'],
31
+ exposedHeaders: ['*'],
32
+ })
33
+ );
34
+
35
+ app.all('/mcp/*', (req, res) => {
36
+ return handleMcpRoute(req, res, serverFactory, withAuditRequestResponseHandler, auditLogger);
37
+ });
38
+
39
+ // Catch-all for other routes (404)
40
+ app.use(handleNotFoundRoute);
41
+
42
+ return app;
43
+ }
44
+
45
+ function handleServerListen(logger, port) {
46
+ logger.info(`MCP proxy HTTP server listening on http://localhost:${port}/mcp`);
47
+ }
48
+
49
+ export function runInternalServer(logger, port, app) {
50
+ app.listen(port, '0.0.0.0', () => {
51
+ handleServerListen(logger, port);
52
+ });
53
+ }
@@ -57,6 +57,16 @@ export function createInternalServer(logger, mcpServers, requestedMcpServer) {
57
57
  return server;
58
58
  }
59
59
 
60
+ function createInternalServerForRequested(logger, mcpServers, requestedMcpServer) {
61
+ return createInternalServer(logger, mcpServers, requestedMcpServer);
62
+ }
63
+
64
+ function createInternalServerFactoryWrapper(logger, mcpServers, requestedMcpServer) {
65
+ return createInternalServerForRequested(logger, mcpServers, requestedMcpServer);
66
+ }
67
+
60
68
  export function createInternalServerFactory(logger, mcpServers) {
61
- return (requestedMcpServer) => createInternalServer(logger, mcpServers, requestedMcpServer);
69
+ return (requestedMcpServer) => {
70
+ return createInternalServerFactoryWrapper(logger, mcpServers, requestedMcpServer);
71
+ };
62
72
  }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Conversation filters model
3
+ */
4
+ import { Defaults } from '../constants/Defaults.js';
5
+
6
+ export class ConversationFilters {
7
+ constructor(data = {}) {
8
+ this.sessionId = data.sessionId || null;
9
+ this.method = data.method || null;
10
+ this.status = data.status || null;
11
+ this.jsonrpcId = data.jsonrpcId || null;
12
+ this.startTime = data.startTime !== undefined ? data.startTime : null;
13
+ this.endTime = data.endTime !== undefined ? data.endTime : null;
14
+ this.limit = data.limit !== undefined ? Number.parseInt(data.limit) : Defaults.DEFAULT_LIMIT;
15
+ this.offset =
16
+ data.offset !== undefined ? Number.parseInt(data.offset) : Defaults.DEFAULT_OFFSET;
17
+ }
18
+
19
+ toRepositoryFilters() {
20
+ return {
21
+ sessionId: this.sessionId,
22
+ method: this.method,
23
+ status: this.status,
24
+ jsonrpcId: this.jsonrpcId,
25
+ startTime: this.startTime ? BigInt(this.startTime) : null,
26
+ endTime: this.endTime ? BigInt(this.endTime) : null,
27
+ limit: this.limit,
28
+ offset: this.offset,
29
+ };
30
+ }
31
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Export format enum
3
+ */
4
+ export const ExportFormat = {
5
+ JSON: 'json',
6
+ CSV: 'csv',
7
+ TXT: 'txt',
8
+ };
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Request filters model
3
+ * Used for filtering packet/request queries
4
+ */
5
+ import { Defaults } from '../constants/Defaults.js';
6
+
7
+ export class RequestFilters {
8
+ constructor(data = {}) {
9
+ this.sessionId = data.sessionId || null;
10
+ this.direction = data.direction || null;
11
+ this.method = data.method || null;
12
+ this.jsonrpcMethod = data.jsonrpcMethod || null;
13
+ this.statusCode = data.statusCode !== undefined ? data.statusCode : null;
14
+ this.jsonrpcId = data.jsonrpcId || null;
15
+ this.search = data.search || null;
16
+ this.serverName = data.serverName || null;
17
+ this.startTime = data.startTime !== undefined ? data.startTime : null;
18
+ this.endTime = data.endTime !== undefined ? data.endTime : null;
19
+ this.limit = data.limit !== undefined ? Number.parseInt(data.limit) : Defaults.DEFAULT_LIMIT;
20
+ this.offset =
21
+ data.offset !== undefined ? Number.parseInt(data.offset) : Defaults.DEFAULT_OFFSET;
22
+ }
23
+
24
+ /**
25
+ * Convert to repository filter format
26
+ */
27
+ toRepositoryFilters() {
28
+ return {
29
+ sessionId: this.sessionId,
30
+ direction: this.direction,
31
+ method: this.method,
32
+ jsonrpcMethod: this.jsonrpcMethod,
33
+ statusCode: this.statusCode,
34
+ jsonrpcId: this.jsonrpcId,
35
+ search: this.search,
36
+ serverName: this.serverName,
37
+ startTime: this.startTime ? BigInt(this.startTime) : null,
38
+ endTime: this.endTime ? BigInt(this.endTime) : null,
39
+ limit: this.limit,
40
+ offset: this.offset,
41
+ };
42
+ }
43
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Session filters model
3
+ */
4
+ import { Defaults } from '../constants/Defaults.js';
5
+
6
+ export class SessionFilters {
7
+ constructor(data = {}) {
8
+ this.startTime = data.startTime !== undefined ? data.startTime : null;
9
+ this.endTime = data.endTime !== undefined ? data.endTime : null;
10
+ this.limit = data.limit !== undefined ? Number.parseInt(data.limit) : Defaults.DEFAULT_LIMIT;
11
+ this.offset =
12
+ data.offset !== undefined ? Number.parseInt(data.offset) : Defaults.DEFAULT_OFFSET;
13
+ }
14
+
15
+ toRepositoryFilters() {
16
+ return {
17
+ startTime: this.startTime ? BigInt(this.startTime) : null,
18
+ endTime: this.endTime ? BigInt(this.endTime) : null,
19
+ limit: this.limit,
20
+ offset: this.offset,
21
+ };
22
+ }
23
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Model layer exports
3
+ * All models used for service layer communication
4
+ */
5
+ export { RequestFilters } from './RequestFilters.js';
6
+ export { SessionFilters } from './SessionFilters.js';
7
+ export { ConversationFilters } from './ConversationFilters.js';
8
+ export { ExportFormat } from './ExportFormat.js';