imcp 0.0.16 → 0.0.18

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 (151) hide show
  1. package/dist/cli/commands/install.js +2 -2
  2. package/dist/cli/commands/list.js +2 -2
  3. package/dist/cli/commands/serve.js +3 -2
  4. package/dist/core/RequirementService.d.ts +0 -12
  5. package/dist/core/RequirementService.js +0 -24
  6. package/dist/core/installers/clients/BaseClientInstaller.d.ts +26 -3
  7. package/dist/core/installers/clients/BaseClientInstaller.js +121 -0
  8. package/dist/core/installers/clients/ClientInstaller.d.ts +1 -1
  9. package/dist/core/installers/clients/ClientInstaller.js +1 -1
  10. package/dist/core/installers/clients/ClientInstallerFactory.js +1 -1
  11. package/dist/core/installers/clients/ClineInstaller.d.ts +1 -6
  12. package/dist/core/installers/clients/ClineInstaller.js +1 -94
  13. package/dist/core/installers/clients/ExtensionInstaller.js +1 -1
  14. package/dist/core/installers/clients/GithubCopilotInstaller.d.ts +1 -6
  15. package/dist/core/installers/clients/GithubCopilotInstaller.js +1 -94
  16. package/dist/core/installers/clients/MSRooCodeInstaller.d.ts +1 -5
  17. package/dist/core/installers/clients/MSRooCodeInstaller.js +1 -94
  18. package/dist/core/installers/requirements/BaseInstaller.d.ts +1 -1
  19. package/dist/core/installers/requirements/BaseInstaller.js +1 -1
  20. package/dist/core/installers/requirements/CommandInstaller.d.ts +1 -1
  21. package/dist/core/installers/requirements/CommandInstaller.js +1 -1
  22. package/dist/core/installers/requirements/GeneralInstaller.d.ts +1 -1
  23. package/dist/core/installers/requirements/InstallerFactory.d.ts +1 -1
  24. package/dist/core/installers/requirements/NpmInstaller.d.ts +1 -1
  25. package/dist/core/installers/requirements/NpmInstaller.js +1 -1
  26. package/dist/core/installers/requirements/PipInstaller.d.ts +1 -1
  27. package/dist/core/installers/requirements/RequirementInstaller.d.ts +1 -1
  28. package/dist/core/loaders/ConfigurationLoader.d.ts +35 -0
  29. package/dist/core/loaders/ConfigurationLoader.js +257 -0
  30. package/dist/core/loaders/ConfigurationProvider.d.ts +38 -0
  31. package/dist/core/loaders/ConfigurationProvider.js +384 -0
  32. package/dist/core/loaders/ServerSchemaLoader.d.ts +22 -0
  33. package/dist/core/loaders/ServerSchemaLoader.js +109 -0
  34. package/dist/core/loaders/ServerSchemaProvider.d.ts +14 -0
  35. package/dist/core/loaders/ServerSchemaProvider.js +90 -0
  36. package/dist/core/metadatas/constants.d.ts +47 -0
  37. package/dist/core/metadatas/constants.js +94 -0
  38. package/dist/core/metadatas/types.d.ts +167 -0
  39. package/dist/core/metadatas/types.js +16 -0
  40. package/dist/core/onboard/FeedOnboardService.d.ts +15 -8
  41. package/dist/core/onboard/FeedOnboardService.js +215 -130
  42. package/dist/core/onboard/OnboardProcessor.d.ts +8 -2
  43. package/dist/core/onboard/OnboardProcessor.js +53 -9
  44. package/dist/core/onboard/OnboardStatus.d.ts +7 -2
  45. package/dist/core/onboard/OnboardStatusManager.d.ts +71 -25
  46. package/dist/core/onboard/OnboardStatusManager.js +231 -47
  47. package/dist/core/validators/FeedValidator.d.ts +8 -3
  48. package/dist/core/validators/FeedValidator.js +61 -7
  49. package/dist/core/validators/IServerValidator.d.ts +1 -1
  50. package/dist/core/validators/SSEServerValidator.d.ts +1 -1
  51. package/dist/core/validators/ServerValidatorFactory.d.ts +1 -1
  52. package/dist/core/validators/StdioServerValidator.d.ts +1 -1
  53. package/dist/core/validators/StdioServerValidator.js +85 -33
  54. package/dist/index.d.ts +3 -3
  55. package/dist/index.js +3 -3
  56. package/dist/services/InstallationService.d.ts +50 -0
  57. package/dist/services/InstallationService.js +350 -0
  58. package/dist/services/MCPManager.d.ts +29 -0
  59. package/dist/services/MCPManager.js +192 -0
  60. package/dist/services/RequirementService.d.ts +40 -0
  61. package/dist/services/RequirementService.js +110 -0
  62. package/dist/services/ServerService.d.ts +2 -2
  63. package/dist/services/ServerService.js +6 -6
  64. package/dist/utils/adoUtils.d.ts +2 -2
  65. package/dist/utils/adoUtils.js +1 -1
  66. package/dist/utils/feedUtils.js +1 -1
  67. package/dist/utils/githubUtils.d.ts +1 -1
  68. package/dist/utils/githubUtils.js +1 -1
  69. package/dist/utils/logger.d.ts +2 -0
  70. package/dist/utils/logger.js +11 -1
  71. package/dist/utils/macroExpressionUtils.d.ts +1 -1
  72. package/dist/utils/osUtils.d.ts +1 -1
  73. package/dist/utils/osUtils.js +1 -1
  74. package/dist/web/contract/serverContract.d.ts +1 -1
  75. package/dist/web/public/index.html +1 -3
  76. package/dist/web/public/js/api.js +2 -80
  77. package/dist/web/public/js/modal/installation.js +1 -1
  78. package/dist/web/public/js/onboard/ONBOARDING_PAGE_DESIGN.md +41 -9
  79. package/dist/web/public/js/onboard/formProcessor.js +200 -34
  80. package/dist/web/public/js/onboard/index.js +2 -2
  81. package/dist/web/public/js/onboard/publishHandler.js +30 -22
  82. package/dist/web/public/js/onboard/templates.js +34 -40
  83. package/dist/web/public/js/onboard/uiHandlers.js +175 -84
  84. package/dist/web/public/js/onboard/validationHandlers.js +147 -64
  85. package/dist/web/public/js/serverCategoryDetails.js +19 -4
  86. package/dist/web/public/js/serverCategoryList.js +13 -1
  87. package/dist/web/public/onboard.html +1 -1
  88. package/dist/web/server.js +21 -8
  89. package/package.json +1 -1
  90. package/src/cli/commands/install.ts +3 -3
  91. package/src/cli/commands/list.ts +2 -2
  92. package/src/cli/commands/serve.ts +3 -2
  93. package/src/cli/index.ts +1 -1
  94. package/src/core/installers/clients/BaseClientInstaller.ts +134 -3
  95. package/src/core/installers/clients/ClientInstaller.ts +3 -3
  96. package/src/core/installers/clients/ClientInstallerFactory.ts +1 -1
  97. package/src/core/installers/clients/ClineInstaller.ts +1 -101
  98. package/src/core/installers/clients/ExtensionInstaller.ts +1 -1
  99. package/src/core/installers/clients/GithubCopilotInstaller.ts +1 -101
  100. package/src/core/installers/clients/MSRooCodeInstaller.ts +1 -102
  101. package/src/core/installers/requirements/BaseInstaller.ts +2 -2
  102. package/src/core/installers/requirements/CommandInstaller.ts +1 -1
  103. package/src/core/installers/requirements/GeneralInstaller.ts +1 -1
  104. package/src/core/installers/requirements/InstallerFactory.ts +1 -1
  105. package/src/core/installers/requirements/NpmInstaller.ts +12 -12
  106. package/src/core/installers/requirements/PipInstaller.ts +1 -1
  107. package/src/core/installers/requirements/RequirementInstaller.ts +1 -1
  108. package/src/core/{ConfigurationLoader.ts → loaders/ConfigurationLoader.ts} +31 -7
  109. package/src/core/{ConfigurationProvider.ts → loaders/ConfigurationProvider.ts} +18 -10
  110. package/src/core/loaders/ServerSchemaLoader.ts +117 -0
  111. package/src/core/loaders/ServerSchemaProvider.ts +99 -0
  112. package/src/core/{types.ts → metadatas/types.ts} +3 -2
  113. package/src/core/onboard/FeedOnboardService.ts +270 -146
  114. package/src/core/onboard/OnboardProcessor.ts +60 -11
  115. package/src/core/onboard/OnboardStatus.ts +7 -2
  116. package/src/core/onboard/OnboardStatusManager.ts +270 -43
  117. package/src/core/validators/FeedValidator.ts +65 -9
  118. package/src/core/validators/IServerValidator.ts +1 -1
  119. package/src/core/validators/SSEServerValidator.ts +2 -2
  120. package/src/core/validators/ServerValidatorFactory.ts +1 -1
  121. package/src/core/validators/StdioServerValidator.ts +86 -34
  122. package/src/index.ts +3 -3
  123. package/src/{core → services}/InstallationService.ts +5 -5
  124. package/src/{core → services}/MCPManager.ts +10 -5
  125. package/src/{core → services}/RequirementService.ts +2 -31
  126. package/src/services/ServerService.ts +7 -7
  127. package/src/utils/adoUtils.ts +3 -3
  128. package/src/utils/feedUtils.ts +2 -2
  129. package/src/utils/githubUtils.ts +2 -2
  130. package/src/utils/logger.ts +13 -1
  131. package/src/utils/macroExpressionUtils.ts +1 -1
  132. package/src/utils/osUtils.ts +4 -4
  133. package/src/web/contract/serverContract.ts +2 -2
  134. package/src/web/public/index.html +1 -3
  135. package/src/web/public/js/api.js +2 -80
  136. package/src/web/public/js/modal/installation.js +1 -1
  137. package/src/web/public/js/onboard/ONBOARDING_PAGE_DESIGN.md +41 -9
  138. package/src/web/public/js/onboard/formProcessor.js +200 -34
  139. package/src/web/public/js/onboard/index.js +2 -2
  140. package/src/web/public/js/onboard/publishHandler.js +30 -22
  141. package/src/web/public/js/onboard/templates.js +34 -40
  142. package/src/web/public/js/onboard/uiHandlers.js +175 -84
  143. package/src/web/public/js/onboard/validationHandlers.js +147 -64
  144. package/src/web/public/js/serverCategoryDetails.js +19 -4
  145. package/src/web/public/js/serverCategoryList.js +13 -1
  146. package/src/web/public/onboard.html +1 -1
  147. package/src/web/server.ts +30 -14
  148. package/src/core/ServerSchemaLoader.ts +0 -48
  149. package/src/core/ServerSchemaProvider.ts +0 -137
  150. package/src/services/InstallRequestValidator.ts +0 -112
  151. /package/src/core/{constants.ts → metadatas/constants.ts} +0 -0
@@ -1,5 +1,8 @@
1
+ import fs from 'fs/promises';
1
2
  import { serverValidatorFactory } from "./ServerValidatorFactory.js";
2
3
  import { Logger } from "../../utils/logger.js";
4
+ import { onboardStatusManager } from "../onboard/OnboardStatusManager.js";
5
+ import { OnboardingProcessStatus } from "../onboard/OnboardStatus.js";
3
6
  /**
4
7
  * Validates feed configurations to ensure they meet required criteria
5
8
  */
@@ -7,12 +10,16 @@ export class FeedValidator {
7
10
  /**
8
11
  * Validates a feed configuration
9
12
  * @param config The feed configuration to validate
13
+ * @param categoryName The name of the category (feed name) for status updates
14
+ * @param operationType The type of operation for status updates
10
15
  * @returns true if valid, throws error if invalid
11
16
  */
12
- validate(config) {
17
+ async validate(config, categoryName, operationType) {
13
18
  try {
19
+ await onboardStatusManager.recordStep(categoryName, operationType, `Starting feed validation for '${config.name}'`);
14
20
  Logger.debug(`Validating feed configuration: ${config.name}`);
15
21
  // Validate required fields
22
+ await onboardStatusManager.recordStep(categoryName, operationType, `Validating required fields for '${config.name}'`);
16
23
  if (!config.name)
17
24
  throw new Error('Feed name is required');
18
25
  if (!config.displayName)
@@ -20,11 +27,13 @@ export class FeedValidator {
20
27
  if (!config.description)
21
28
  throw new Error('Feed description is required');
22
29
  // Validate MCP servers array
30
+ await onboardStatusManager.recordStep(categoryName, operationType, `Validating MCP servers array for '${config.name}'`);
23
31
  if (!Array.isArray(config.mcpServers) || config.mcpServers.length === 0) {
24
32
  throw new Error('Feed must contain at least one MCP server');
25
33
  }
26
34
  // Validate requirements if present
27
35
  if (config.requirements) {
36
+ await onboardStatusManager.recordStep(categoryName, operationType, `Validating requirements for '${config.name}'`);
28
37
  for (const req of config.requirements) {
29
38
  if (!req.name)
30
39
  throw new Error('Requirement name is required');
@@ -34,12 +43,14 @@ export class FeedValidator {
34
43
  throw new Error('Requirement version is required');
35
44
  }
36
45
  }
46
+ await onboardStatusManager.recordStep(categoryName, operationType, `Feed validation successful for '${config.name}'`, undefined, OnboardingProcessStatus.VALIDATING); // Still in progress until all servers validated
37
47
  Logger.debug(`Feed configuration validation successful: ${config.name}`);
38
48
  return true;
39
49
  }
40
50
  catch (error) {
41
- const errorMsg = `Feed validation failed: ${error instanceof Error ? error.message : String(error)}`;
51
+ const errorMsg = `Feed validation failed for '${config.name}': ${error instanceof Error ? error.message : String(error)}`;
42
52
  Logger.error(errorMsg);
53
+ await onboardStatusManager.recordStep(categoryName, operationType, `Feed validation failed for '${config.name}'`, undefined, OnboardingProcessStatus.FAILED, errorMsg);
43
54
  throw new Error(errorMsg);
44
55
  }
45
56
  }
@@ -47,12 +58,18 @@ export class FeedValidator {
47
58
  * Validates a single MCP server configuration using the appropriate validator
48
59
  * @param server The MCP server configuration to validate
49
60
  * @param config The feed configuration containing shared requirements
61
+ * @param categoryName The name of the category (feed name) for status updates
62
+ * @param operationType The type of operation for status updates
50
63
  * @returns true if valid, throws error if invalid
51
64
  */
52
- async validateServer(server, config) {
65
+ async validateServer(server, config, categoryName, operationType) {
66
+ const feedName = config.name; // categoryName is the feedName in this context
67
+ const serverDisplayName = server.name;
53
68
  try {
54
- Logger.debug(`Validating server configuration: ${server.name}`);
69
+ await onboardStatusManager.recordStep(categoryName, operationType, `Starting server validation for '${serverDisplayName}' in feed '${feedName}'`, server.name);
70
+ Logger.debug(`Validating server configuration: ${serverDisplayName} in feed ${feedName}`);
55
71
  // Validate basic required fields
72
+ await onboardStatusManager.recordStep(categoryName, operationType, `Validating basic fields for server '${serverDisplayName}'`, server.name);
56
73
  if (!server.name)
57
74
  throw new Error('Server name is required');
58
75
  if (!server.description)
@@ -61,16 +78,53 @@ export class FeedValidator {
61
78
  throw new Error('Server mode is required');
62
79
  if (!server.installation)
63
80
  throw new Error('Server installation configuration is required');
81
+ // Validate schema file existence if schemas is defined
82
+ if (server.schemas) {
83
+ await onboardStatusManager.recordStep(categoryName, operationType, `Validating schema file for server '${serverDisplayName}'`, server.name);
84
+ try {
85
+ // Assuming server.schemas is a relative path from the project root or a path that needs to be resolved.
86
+ // For now, let's assume it's relative to the feed file's location or an absolute path.
87
+ // If it's relative to the feed file, we might need the feed file's path.
88
+ // For simplicity, let's assume it's a path that can be directly accessed.
89
+ // If the schema path is relative to the feed config file, this logic will need adjustment.
90
+ // For now, we'll treat it as a path that `fs.access` can check.
91
+ // It's more likely that schema paths are relative to the feed definition file itself.
92
+ // However, the task description implies `server.schemas` is a path to be checked.
93
+ // Let's assume for now it's a path that should exist.
94
+ // If the schemas are stored within the repo, their paths would be relative to the repo root.
95
+ // During validation, we might not have the repo context directly here.
96
+ // This needs clarification on how schema paths are resolved during validation.
97
+ // For now, we'll proceed with a direct check.
98
+ // If the schema is part of the feed package, its path might be relative to the package root.
99
+ // Let's assume the path is resolvable from the current working directory or is absolute.
100
+ // This part might need refinement based on where schema files are expected to be.
101
+ // The task implies `server.schemas` is a string path.
102
+ const schemaPath = server.schemas; // This path needs to be correctly resolved.
103
+ // If it's relative to the feed file, we need that context.
104
+ // For now, we'll assume it's a path that can be checked.
105
+ // This might be an issue if it's relative to a file not yet in the repo.
106
+ // Let's assume it's a path that should be resolvable.
107
+ await fs.access(schemaPath);
108
+ Logger.debug(`Schema file ${schemaPath} exists for server ${serverDisplayName}`);
109
+ }
110
+ catch (fileAccessError) {
111
+ throw new Error(`Schema file '${server.schemas}' not found for server '${serverDisplayName}'.`);
112
+ }
113
+ }
64
114
  // Get the appropriate validator for this server type
115
+ await onboardStatusManager.recordStep(categoryName, operationType, `Obtaining specific validator for server '${serverDisplayName}'`, server.name);
65
116
  const validator = serverValidatorFactory.getValidatorForServer(server);
66
117
  // Perform mode-specific validation with feed config
67
- await validator.validateServer(server, config);
68
- Logger.debug(`Server configuration validation successful: ${server.name}`);
118
+ await onboardStatusManager.recordStep(categoryName, operationType, `Performing mode-specific validation for server '${serverDisplayName}'`, server.name);
119
+ await validator.validateServer(server, config); // This internal call won't have status updates unless modified too
120
+ await onboardStatusManager.recordStep(categoryName, operationType, `Server validation successful for '${serverDisplayName}'`, server.name, OnboardingProcessStatus.VALIDATING); // Still in progress until all servers validated
121
+ Logger.debug(`Server configuration validation successful: ${serverDisplayName}`);
69
122
  return true;
70
123
  }
71
124
  catch (error) {
72
- const errorMsg = `Server validation failed: ${error instanceof Error ? error.message : String(error)}`;
125
+ const errorMsg = `Server validation failed for '${serverDisplayName}' in feed '${feedName}': ${error instanceof Error ? error.message : String(error)}`;
73
126
  Logger.error(errorMsg);
127
+ await onboardStatusManager.recordStep(categoryName, operationType, `Server validation failed for '${serverDisplayName}'`, server.name, OnboardingProcessStatus.FAILED, errorMsg);
74
128
  throw new Error(errorMsg);
75
129
  }
76
130
  }
@@ -1,4 +1,4 @@
1
- import { McpConfig, FeedConfiguration } from "../types.js";
1
+ import { McpConfig, FeedConfiguration } from "../metadatas/types.js";
2
2
  /**
3
3
  * Interface for MCP server configuration validators
4
4
  * Defines common validation operations for server configurations
@@ -1,4 +1,4 @@
1
- import { McpConfig, FeedConfiguration } from "../types.js";
1
+ import { McpConfig, FeedConfiguration } from "../metadatas/types.js";
2
2
  import { IServerValidator } from "./IServerValidator.js";
3
3
  /**
4
4
  * Validates MCP server configurations for SSE mode
@@ -1,4 +1,4 @@
1
- import { McpConfig } from "../types.js";
1
+ import { McpConfig } from "../metadatas/types.js";
2
2
  import { IServerValidator, ValidatorType } from "./IServerValidator.js";
3
3
  /**
4
4
  * Factory class for managing server validator instances
@@ -1,4 +1,4 @@
1
- import { McpConfig, FeedConfiguration } from "../types.js";
1
+ import { McpConfig, FeedConfiguration } from "../metadatas/types.js";
2
2
  import { IServerValidator } from "./IServerValidator.js";
3
3
  /**
4
4
  * Validates MCP server configurations for stdio mode
@@ -4,7 +4,7 @@ import { exec, spawn } from 'child_process';
4
4
  import util from 'util';
5
5
  import { MACRO_EXPRESSIONS, resolveNpmModulePath } from "../../utils/macroExpressionUtils.js";
6
6
  import { getSystemPythonPackageDirectory } from "../../utils/osUtils.js";
7
- import { SETTINGS_DIR } from "../constants.js";
7
+ import { SETTINGS_DIR } from "../metadatas/constants.js";
8
8
  import path from "path";
9
9
  const execPromise = util.promisify(exec);
10
10
  /**
@@ -91,7 +91,9 @@ export class StdioServerValidator {
91
91
  // Resolve npm module paths in arguments
92
92
  Logger.debug('Resolving npm module paths in arguments');
93
93
  const npmPath = requirement ? this._getRequirementFolderPath(requirement) : undefined;
94
- finalArgs = args.map(arg => arg.replace(MACRO_EXPRESSIONS.NPMPATH, resolveNpmModulePath(npmPath)));
94
+ finalArgs = args.map(arg => arg
95
+ .replace(MACRO_EXPRESSIONS.NPMPATH, resolveNpmModulePath(npmPath))
96
+ .replace(/\\/g, '/'));
95
97
  Logger.debug(`Resolved npm arguments: ${finalArgs.join(' ')}`);
96
98
  }
97
99
  else if (command === 'python' || command === 'python3') {
@@ -109,54 +111,104 @@ export class StdioServerValidator {
109
111
  }
110
112
  }
111
113
  return await new Promise((resolve, reject) => {
112
- Logger.debug(`Starting process with command: ${command} ${finalArgs.join(' ')}`);
113
- // Set timeout for server startup test
114
- const timeout = setTimeout(() => {
115
- const msg = 'Server startup test timed out after 10 seconds';
116
- Logger.error(msg);
117
- serverProcess.kill();
118
- reject(new Error(msg));
119
- }, 20000);
120
- // Start the server process
114
+ Logger.debug(`Starting process for server test with command: ${command} ${finalArgs.join(' ')}`);
115
+ const timeoutDuration = 20000; // 20 seconds for server startup test
121
116
  const serverProcess = spawn(command, finalArgs, {
122
- stdio: ['ignore', 'pipe', 'pipe'],
117
+ stdio: ['ignore', 'pipe', 'pipe'], // stdin, stdout, stderr
123
118
  shell: true
124
119
  });
125
- let output = '';
126
- let errorOutput = '';
127
- // Collect stdout
120
+ let stdoutData = '';
121
+ let stderrData = '';
122
+ let settled = false;
123
+ const cleanupAndResolve = (value) => {
124
+ if (settled)
125
+ return;
126
+ settled = true;
127
+ clearTimeout(timeoutId);
128
+ serverProcess.stdout.removeAllListeners();
129
+ serverProcess.stderr.removeAllListeners();
130
+ serverProcess.removeAllListeners('exit');
131
+ serverProcess.removeAllListeners('error');
132
+ if (serverProcess.exitCode === null && !serverProcess.killed) {
133
+ serverProcess.kill();
134
+ }
135
+ resolve(value);
136
+ };
137
+ const cleanupAndReject = (err) => {
138
+ if (settled)
139
+ return;
140
+ settled = true;
141
+ clearTimeout(timeoutId);
142
+ serverProcess.stdout.removeAllListeners();
143
+ serverProcess.stderr.removeAllListeners();
144
+ serverProcess.removeAllListeners('exit');
145
+ serverProcess.removeAllListeners('error');
146
+ if (serverProcess.exitCode === null && !serverProcess.killed) {
147
+ serverProcess.kill();
148
+ }
149
+ reject(err);
150
+ };
151
+ const timeoutId = setTimeout(() => {
152
+ if (settled)
153
+ return;
154
+ if (serverProcess.exitCode === null) { // Process is still running
155
+ Logger.debug(`Server startup test: Process still running after ${timeoutDuration / 1000} seconds. Considering it successful.`);
156
+ Logger.debug(`Collected stdout:\n${stdoutData}`);
157
+ Logger.debug(`Collected stderr:\n${stderrData}`);
158
+ cleanupAndResolve(true);
159
+ }
160
+ else {
161
+ // Process exited before timeout, 'exit' handler should have caught it.
162
+ // This is a fallback or race condition handling.
163
+ const msg = `Server startup test: Process exited with code ${serverProcess.exitCode} before timeout completed.`;
164
+ Logger.error(msg);
165
+ Logger.debug(`Collected stdout:\n${stdoutData}`);
166
+ Logger.error(`Collected stderr:\n${stderrData}`); // Log stderr as error here
167
+ cleanupAndReject(new Error(msg + ` Stderr: ${stderrData}`));
168
+ }
169
+ }, timeoutDuration);
128
170
  serverProcess.stdout.on('data', (data) => {
129
- output += data.toString();
130
- // If we see any output, consider it a success
131
- clearTimeout(timeout);
132
- serverProcess.kill();
133
- resolve(true);
171
+ const messageChunk = data.toString();
172
+ stdoutData += messageChunk;
173
+ Logger.debug(`Server stdout: ${messageChunk.trim()}`);
134
174
  });
135
- // Collect stderr
136
175
  serverProcess.stderr.on('data', (data) => {
137
- errorOutput += data.toString();
176
+ const messageChunk = data.toString();
177
+ stderrData += messageChunk;
178
+ // Log stderr, but it doesn't automatically mean failure.
179
+ // The exit code or an 'error' event will determine failure.
180
+ Logger.debug(`Server stderr: ${messageChunk.trim()}`);
138
181
  });
139
- // Handle process exit
140
- serverProcess.on('exit', (code) => {
141
- clearTimeout(timeout);
142
- if (code !== null && code !== 0) {
143
- const msg = `Server startup failed with code ${code}: ${errorOutput}`;
182
+ serverProcess.on('exit', (code, signal) => {
183
+ if (settled)
184
+ return;
185
+ Logger.debug(`Server process exited with code ${code}, signal: ${signal}.`);
186
+ Logger.debug(`Final stdout:\n${stdoutData}`);
187
+ Logger.debug(`Final stderr:\n${stderrData}`);
188
+ if (code === 0) {
189
+ cleanupAndResolve(true);
190
+ }
191
+ else {
192
+ const msg = `Server process exited with non-zero code ${code} or signal ${signal}. Stderr: ${stderrData.trim()}`;
144
193
  Logger.error(msg);
145
- reject(new Error(msg));
194
+ cleanupAndReject(new Error(msg));
146
195
  }
147
196
  });
148
- // Handle process error
149
197
  serverProcess.on('error', (error) => {
150
- clearTimeout(timeout);
151
- const msg = `Server startup error: ${error.message}`;
198
+ if (settled)
199
+ return;
200
+ const msg = `Server process failed to start or encountered an error: ${error.message}.`;
152
201
  Logger.error(msg);
153
- reject(error);
202
+ Logger.debug(`Stdout at error:\n${stdoutData}`);
203
+ Logger.error(`Stderr at error:\n${stderrData}`);
204
+ cleanupAndReject(new Error(`${msg} Stderr: ${stderrData.trim()}`));
154
205
  });
155
206
  });
156
207
  }
157
208
  catch (error) {
158
- const msg = `Failed to test server startup: ${error instanceof Error ? error.message : String(error)}`;
209
+ const msg = `Failed to test server startup (outer catch): ${error instanceof Error ? error.message : String(error)}`;
159
210
  Logger.error(msg);
211
+ // Ensure the error thrown is an instance of Error
160
212
  throw error instanceof Error ? error : new Error(msg);
161
213
  }
162
214
  }
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- export { MCPServerCategory, ServerCategoryListOptions, ServerInstallOptions, ServerUninstallOptions, ServerOperationResult, MCPConfiguration, MCPEvent, MCPEventData, RequirementConfig, RequirementStatus, RegistryConfig } from './core/types.js';
2
- export { MCPManager, mcpManager } from './core/MCPManager.js';
1
+ export { MCPServerCategory, ServerCategoryListOptions, ServerInstallOptions, ServerUninstallOptions, ServerOperationResult, MCPConfiguration, MCPEvent, MCPEventData, RequirementConfig, RequirementStatus, RegistryConfig } from './core/metadatas/types.js';
2
+ export { MCPManager, mcpManager } from './services/MCPManager.js';
3
3
  export { ServerService, serverService } from './services/ServerService.js';
4
- export { RequirementService, requirementService } from './core/RequirementService.js';
4
+ export { RequirementService, requirementService } from './services/RequirementService.js';
5
5
  export { RequirementInstaller, BaseInstaller, NpmInstaller, PipInstaller, GeneralInstaller, InstallerFactory, createInstallerFactory } from './core/installers/index.js';
6
6
  export { startWebServer } from './web/server.js';
7
7
  export declare const VERSION = "0.0.1";
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  // Public types
2
- export { MCPEvent } from './core/types.js';
2
+ export { MCPEvent } from './core/metadatas/types.js';
3
3
  // Core functionality
4
- export { MCPManager, mcpManager } from './core/MCPManager.js';
4
+ export { MCPManager, mcpManager } from './services/MCPManager.js';
5
5
  // Services
6
6
  export { ServerService, serverService } from './services/ServerService.js';
7
- export { RequirementService, requirementService } from './core/RequirementService.js';
7
+ export { RequirementService, requirementService } from './services/RequirementService.js';
8
8
  // Installer interfaces and implementations
9
9
  export { BaseInstaller, NpmInstaller, PipInstaller, GeneralInstaller, InstallerFactory, createInstallerFactory } from './core/installers/index.js';
10
10
  // Web server
@@ -0,0 +1,50 @@
1
+ import { ServerInstallOptions, ServerOperationResult } from '../core/metadatas/types.js';
2
+ /**
3
+ * Handles the actual installation process for an MCP server.
4
+ */
5
+ export declare class InstallationService {
6
+ private activeInstallations;
7
+ private installerFactory;
8
+ constructor();
9
+ private generateOperationId;
10
+ /**
11
+ * Installs a server based on the provided options and feed configuration.
12
+ * @param serverName The name of the server to install.
13
+ * @param options The installation options.
14
+ * @returns A result object indicating success or failure.
15
+ */
16
+ install(categoryName: string, serverName: string, options: ServerInstallOptions): Promise<ServerOperationResult>;
17
+ /**
18
+ * Process requirement updates specified in serverInstallOptions
19
+ * All updates are processed in parallel for maximum efficiency
20
+ * @param categoryName The category name
21
+ * @param serverName The server name
22
+ * @param requirements The requirements to update
23
+ */
24
+ private processRequirementUpdates;
25
+ /**
26
+ * Checks and installs requirements for a server if needed
27
+ * @param categoryName The category name
28
+ * @param serverName The server name
29
+ * @param options The installation options
30
+ * @returns A failure result if requirements check fails, null if requirements are satisfied
31
+ */
32
+ private checkAndInstallRequirements;
33
+ /**
34
+ * Installs requirements in background without blocking the main thread
35
+ * Requirements with the same order are installed in parallel
36
+ */
37
+ private installRequirementsInBackground;
38
+ /**
39
+ * Helper to update requirement status for failure case
40
+ */
41
+ private updateRequirementFailureStatus;
42
+ /**
43
+ * Helper to update requirement status for in-progress case
44
+ */
45
+ private updateRequirementProgressStatus;
46
+ /**
47
+ * Helper to update requirement status for completion case
48
+ */
49
+ private updateRequirementCompletionStatus;
50
+ }