imcp 0.0.13 → 0.0.15

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 (157) hide show
  1. package/dist/core/ConfigurationProvider.d.ts +1 -0
  2. package/dist/core/ConfigurationProvider.js +15 -0
  3. package/dist/core/InstallationService.js +2 -7
  4. package/dist/core/MCPManager.d.ts +11 -2
  5. package/dist/core/MCPManager.js +24 -1
  6. package/dist/core/RequirementService.js +2 -8
  7. package/dist/core/installers/clients/BaseClientInstaller.d.ts +51 -0
  8. package/dist/core/installers/clients/BaseClientInstaller.js +160 -0
  9. package/dist/core/installers/clients/ClientInstaller.d.ts +16 -8
  10. package/dist/core/installers/clients/ClientInstaller.js +77 -504
  11. package/dist/core/installers/clients/ClientInstallerFactory.d.ts +19 -0
  12. package/dist/core/installers/clients/ClientInstallerFactory.js +41 -0
  13. package/dist/core/installers/clients/ClineInstaller.d.ts +18 -0
  14. package/dist/core/installers/clients/ClineInstaller.js +124 -0
  15. package/dist/core/installers/clients/GithubCopilotInstaller.d.ts +34 -0
  16. package/dist/core/installers/clients/GithubCopilotInstaller.js +162 -0
  17. package/dist/core/installers/clients/MSRooCodeInstaller.d.ts +15 -0
  18. package/dist/core/installers/clients/MSRooCodeInstaller.js +122 -0
  19. package/dist/core/installers/requirements/BaseInstaller.d.ts +11 -34
  20. package/dist/core/installers/requirements/BaseInstaller.js +5 -116
  21. package/dist/core/installers/requirements/CommandInstaller.d.ts +6 -1
  22. package/dist/core/installers/requirements/CommandInstaller.js +7 -0
  23. package/dist/core/installers/requirements/GeneralInstaller.d.ts +6 -1
  24. package/dist/core/installers/requirements/GeneralInstaller.js +9 -4
  25. package/dist/core/installers/requirements/NpmInstaller.d.ts +46 -7
  26. package/dist/core/installers/requirements/NpmInstaller.js +150 -58
  27. package/dist/core/installers/requirements/PipInstaller.d.ts +9 -0
  28. package/dist/core/installers/requirements/PipInstaller.js +66 -28
  29. package/dist/core/onboard/FeedOnboardService.d.ts +72 -0
  30. package/dist/core/onboard/FeedOnboardService.js +312 -0
  31. package/dist/core/onboard/OnboardProcessor.d.ts +79 -0
  32. package/dist/core/onboard/OnboardProcessor.js +290 -0
  33. package/dist/core/onboard/OnboardStatus.d.ts +49 -0
  34. package/dist/core/onboard/OnboardStatus.js +10 -0
  35. package/dist/core/onboard/OnboardStatusManager.d.ts +57 -0
  36. package/dist/core/onboard/OnboardStatusManager.js +176 -0
  37. package/dist/core/types.d.ts +6 -6
  38. package/dist/core/validators/FeedValidator.d.ts +20 -0
  39. package/dist/core/validators/FeedValidator.js +80 -0
  40. package/dist/core/validators/IServerValidator.d.ts +19 -0
  41. package/dist/core/validators/IServerValidator.js +2 -0
  42. package/dist/core/validators/SSEServerValidator.d.ts +15 -0
  43. package/dist/core/validators/SSEServerValidator.js +39 -0
  44. package/dist/core/validators/ServerValidatorFactory.d.ts +24 -0
  45. package/dist/core/validators/ServerValidatorFactory.js +45 -0
  46. package/dist/core/validators/StdioServerValidator.d.ts +46 -0
  47. package/dist/core/validators/StdioServerValidator.js +229 -0
  48. package/dist/services/InstallRequestValidator.d.ts +1 -1
  49. package/dist/services/ServerService.d.ts +9 -6
  50. package/dist/services/ServerService.js +18 -7
  51. package/dist/utils/adoUtils.d.ts +29 -0
  52. package/dist/utils/adoUtils.js +252 -0
  53. package/dist/utils/clientUtils.d.ts +0 -7
  54. package/dist/utils/clientUtils.js +0 -42
  55. package/dist/utils/githubUtils.d.ts +10 -0
  56. package/dist/utils/githubUtils.js +22 -0
  57. package/dist/utils/macroExpressionUtils.d.ts +38 -0
  58. package/dist/utils/macroExpressionUtils.js +116 -0
  59. package/dist/utils/osUtils.d.ts +4 -20
  60. package/dist/utils/osUtils.js +78 -23
  61. package/dist/web/contract/serverContract.d.ts +66 -0
  62. package/dist/web/contract/serverContract.js +2 -0
  63. package/dist/web/public/css/notifications.css +48 -17
  64. package/dist/web/public/css/onboard.css +107 -0
  65. package/dist/web/public/index.html +90 -18
  66. package/dist/web/public/js/api.js +3 -6
  67. package/dist/web/public/js/flights/flights.js +127 -0
  68. package/dist/web/public/js/modal/index.js +58 -0
  69. package/dist/web/public/js/modal/installHandler.js +227 -0
  70. package/dist/web/public/js/modal/installModal.js +163 -0
  71. package/dist/web/public/js/modal/installation.js +281 -0
  72. package/dist/web/public/js/modal/loadingModal.js +52 -0
  73. package/dist/web/public/js/modal/loadingUI.js +74 -0
  74. package/dist/web/public/js/modal/messageQueue.js +112 -0
  75. package/dist/web/public/js/modal/modalSetup.js +513 -0
  76. package/dist/web/public/js/modal/modalUI.js +214 -0
  77. package/dist/web/public/js/modal/modalUtils.js +49 -0
  78. package/dist/web/public/js/modal/version.js +20 -0
  79. package/dist/web/public/js/modal/versionUtils.js +20 -0
  80. package/dist/web/public/js/modal.js +25 -1041
  81. package/dist/web/public/js/notifications.js +66 -27
  82. package/dist/web/public/js/onboard/ONBOARDING_PAGE_DESIGN.md +338 -0
  83. package/dist/web/public/js/onboard/formProcessor.js +864 -0
  84. package/dist/web/public/js/onboard/index.js +374 -0
  85. package/dist/web/public/js/onboard/publishHandler.js +132 -0
  86. package/dist/web/public/js/onboard/state.js +76 -0
  87. package/dist/web/public/js/onboard/templates.js +343 -0
  88. package/dist/web/public/js/onboard/uiHandlers.js +758 -0
  89. package/dist/web/public/js/onboard/validationHandlers.js +378 -0
  90. package/dist/web/public/js/serverCategoryDetails.js +43 -17
  91. package/dist/web/public/js/serverCategoryList.js +15 -2
  92. package/dist/web/public/onboard.html +296 -0
  93. package/dist/web/public/styles.css +91 -1
  94. package/dist/web/server.d.ts +0 -10
  95. package/dist/web/server.js +131 -22
  96. package/package.json +2 -2
  97. package/src/core/ConfigurationProvider.ts +15 -0
  98. package/src/core/InstallationService.ts +2 -7
  99. package/src/core/MCPManager.ts +26 -1
  100. package/src/core/RequirementService.ts +2 -9
  101. package/src/core/installers/clients/BaseClientInstaller.ts +196 -0
  102. package/src/core/installers/clients/ClientInstaller.ts +97 -589
  103. package/src/core/installers/clients/ClientInstallerFactory.ts +46 -0
  104. package/src/core/installers/clients/ClineInstaller.ts +135 -0
  105. package/src/core/installers/clients/GithubCopilotInstaller.ts +179 -0
  106. package/src/core/installers/clients/MSRooCodeInstaller.ts +133 -0
  107. package/src/core/installers/requirements/BaseInstaller.ts +13 -136
  108. package/src/core/installers/requirements/CommandInstaller.ts +9 -1
  109. package/src/core/installers/requirements/GeneralInstaller.ts +11 -4
  110. package/src/core/installers/requirements/NpmInstaller.ts +178 -61
  111. package/src/core/installers/requirements/PipInstaller.ts +68 -29
  112. package/src/core/onboard/FeedOnboardService.ts +346 -0
  113. package/src/core/onboard/OnboardProcessor.ts +305 -0
  114. package/src/core/onboard/OnboardStatus.ts +55 -0
  115. package/src/core/onboard/OnboardStatusManager.ts +188 -0
  116. package/src/core/types.ts +6 -6
  117. package/src/core/validators/FeedValidator.ts +79 -0
  118. package/src/core/validators/IServerValidator.ts +21 -0
  119. package/src/core/validators/SSEServerValidator.ts +43 -0
  120. package/src/core/validators/ServerValidatorFactory.ts +51 -0
  121. package/src/core/validators/StdioServerValidator.ts +259 -0
  122. package/src/services/InstallRequestValidator.ts +1 -1
  123. package/src/services/ServerService.ts +22 -7
  124. package/src/utils/adoUtils.ts +291 -0
  125. package/src/utils/clientUtils.ts +0 -44
  126. package/src/utils/githubUtils.ts +24 -0
  127. package/src/utils/macroExpressionUtils.ts +121 -0
  128. package/src/utils/osUtils.ts +89 -24
  129. package/src/web/contract/serverContract.ts +74 -0
  130. package/src/web/public/css/notifications.css +48 -17
  131. package/src/web/public/css/onboard.css +107 -0
  132. package/src/web/public/index.html +90 -18
  133. package/src/web/public/js/api.js +3 -6
  134. package/src/web/public/js/flights/flights.js +127 -0
  135. package/src/web/public/js/modal/index.js +58 -0
  136. package/src/web/public/js/modal/installModal.js +163 -0
  137. package/src/web/public/js/modal/installation.js +281 -0
  138. package/src/web/public/js/modal/loadingModal.js +52 -0
  139. package/src/web/public/js/modal/messageQueue.js +112 -0
  140. package/src/web/public/js/modal/modalSetup.js +513 -0
  141. package/src/web/public/js/modal/modalUtils.js +49 -0
  142. package/src/web/public/js/modal/versionUtils.js +20 -0
  143. package/src/web/public/js/modal.js +25 -1041
  144. package/src/web/public/js/notifications.js +66 -27
  145. package/src/web/public/js/onboard/ONBOARDING_PAGE_DESIGN.md +338 -0
  146. package/src/web/public/js/onboard/formProcessor.js +864 -0
  147. package/src/web/public/js/onboard/index.js +374 -0
  148. package/src/web/public/js/onboard/publishHandler.js +132 -0
  149. package/src/web/public/js/onboard/state.js +76 -0
  150. package/src/web/public/js/onboard/templates.js +343 -0
  151. package/src/web/public/js/onboard/uiHandlers.js +758 -0
  152. package/src/web/public/js/onboard/validationHandlers.js +378 -0
  153. package/src/web/public/js/serverCategoryDetails.js +43 -17
  154. package/src/web/public/js/serverCategoryList.js +15 -2
  155. package/src/web/public/onboard.html +296 -0
  156. package/src/web/public/styles.css +91 -1
  157. package/src/web/server.ts +167 -58
@@ -0,0 +1,80 @@
1
+ import { serverValidatorFactory } from "./ServerValidatorFactory.js";
2
+ import { Logger } from "../../utils/logger.js";
3
+ /**
4
+ * Validates feed configurations to ensure they meet required criteria
5
+ */
6
+ export class FeedValidator {
7
+ /**
8
+ * Validates a feed configuration
9
+ * @param config The feed configuration to validate
10
+ * @returns true if valid, throws error if invalid
11
+ */
12
+ validate(config) {
13
+ try {
14
+ Logger.debug(`Validating feed configuration: ${config.name}`);
15
+ // Validate required fields
16
+ if (!config.name)
17
+ throw new Error('Feed name is required');
18
+ if (!config.displayName)
19
+ throw new Error('Feed display name is required');
20
+ if (!config.description)
21
+ throw new Error('Feed description is required');
22
+ // Validate MCP servers array
23
+ if (!Array.isArray(config.mcpServers) || config.mcpServers.length === 0) {
24
+ throw new Error('Feed must contain at least one MCP server');
25
+ }
26
+ // Validate requirements if present
27
+ if (config.requirements) {
28
+ for (const req of config.requirements) {
29
+ if (!req.name)
30
+ throw new Error('Requirement name is required');
31
+ if (!req.type)
32
+ throw new Error('Requirement type is required');
33
+ if (!req.version)
34
+ throw new Error('Requirement version is required');
35
+ }
36
+ }
37
+ Logger.debug(`Feed configuration validation successful: ${config.name}`);
38
+ return true;
39
+ }
40
+ catch (error) {
41
+ const errorMsg = `Feed validation failed: ${error instanceof Error ? error.message : String(error)}`;
42
+ Logger.error(errorMsg);
43
+ throw new Error(errorMsg);
44
+ }
45
+ }
46
+ /**
47
+ * Validates a single MCP server configuration using the appropriate validator
48
+ * @param server The MCP server configuration to validate
49
+ * @param config The feed configuration containing shared requirements
50
+ * @returns true if valid, throws error if invalid
51
+ */
52
+ async validateServer(server, config) {
53
+ try {
54
+ Logger.debug(`Validating server configuration: ${server.name}`);
55
+ // Validate basic required fields
56
+ if (!server.name)
57
+ throw new Error('Server name is required');
58
+ if (!server.description)
59
+ throw new Error('Server description is required');
60
+ if (!server.mode)
61
+ throw new Error('Server mode is required');
62
+ if (!server.installation)
63
+ throw new Error('Server installation configuration is required');
64
+ // Get the appropriate validator for this server type
65
+ const validator = serverValidatorFactory.getValidatorForServer(server);
66
+ // Perform mode-specific validation with feed config
67
+ await validator.validateServer(server, config);
68
+ Logger.debug(`Server configuration validation successful: ${server.name}`);
69
+ return true;
70
+ }
71
+ catch (error) {
72
+ const errorMsg = `Server validation failed: ${error instanceof Error ? error.message : String(error)}`;
73
+ Logger.error(errorMsg);
74
+ throw new Error(errorMsg);
75
+ }
76
+ }
77
+ }
78
+ // Export singleton instance
79
+ export const feedValidator = new FeedValidator();
80
+ //# sourceMappingURL=FeedValidator.js.map
@@ -0,0 +1,19 @@
1
+ import { McpConfig, FeedConfiguration } from "../types.js";
2
+ /**
3
+ * Interface for MCP server configuration validators
4
+ * Defines common validation operations for server configurations
5
+ */
6
+ export interface IServerValidator {
7
+ /**
8
+ * Validates a specific MCP server configuration
9
+ * Implementation varies based on server mode (stdio/sse)
10
+ * @param server The MCP server configuration to validate
11
+ * @param config The feed configuration containing shared requirements
12
+ * @returns true if valid, throws error if invalid
13
+ */
14
+ validateServer(server: McpConfig, config: FeedConfiguration): Promise<boolean>;
15
+ }
16
+ /**
17
+ * Valid validator types for MCP servers
18
+ */
19
+ export type ValidatorType = 'stdio' | 'sse';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=IServerValidator.js.map
@@ -0,0 +1,15 @@
1
+ import { McpConfig, FeedConfiguration } from "../types.js";
2
+ import { IServerValidator } from "./IServerValidator.js";
3
+ /**
4
+ * Validates MCP server configurations for SSE mode
5
+ */
6
+ export declare class SSEServerValidator implements IServerValidator {
7
+ /**
8
+ * Validates SSE-specific MCP server configuration
9
+ * Checks installation URL, requirements, and environment variables
10
+ * @param server The MCP server configuration to validate
11
+ * @param config The feed configuration containing shared requirements
12
+ * @returns true if valid, throws error if invalid
13
+ */
14
+ validateServer(server: McpConfig, config: FeedConfiguration): Promise<boolean>;
15
+ }
@@ -0,0 +1,39 @@
1
+ import { Logger } from "../../utils/logger.js";
2
+ /**
3
+ * Validates MCP server configurations for SSE mode
4
+ */
5
+ export class SSEServerValidator {
6
+ /**
7
+ * Validates SSE-specific MCP server configuration
8
+ * Checks installation URL, requirements, and environment variables
9
+ * @param server The MCP server configuration to validate
10
+ * @param config The feed configuration containing shared requirements
11
+ * @returns true if valid, throws error if invalid
12
+ */
13
+ async validateServer(server, config) {
14
+ try {
15
+ Logger.debug(`Validating SSE server configuration: ${server.name}`);
16
+ if (!server.installation?.url) {
17
+ throw new Error('SSE server URL is required in installation configuration');
18
+ }
19
+ try {
20
+ new URL(server.installation.url);
21
+ }
22
+ catch (e) {
23
+ throw new Error(`Invalid SSE server URL: ${server.installation.url}`);
24
+ }
25
+ // Validate server mode
26
+ if (server.mode !== 'sse') {
27
+ throw new Error(`Invalid server mode for SSE validator: ${server.mode}`);
28
+ }
29
+ // Additional SSE-specific validation will be implemented later
30
+ return true;
31
+ }
32
+ catch (error) {
33
+ const errorMsg = `Server validation failed: ${error instanceof Error ? error.message : String(error)}`;
34
+ Logger.error(errorMsg);
35
+ throw new Error(errorMsg);
36
+ }
37
+ }
38
+ }
39
+ //# sourceMappingURL=SSEServerValidator.js.map
@@ -0,0 +1,24 @@
1
+ import { McpConfig } from "../types.js";
2
+ import { IServerValidator, ValidatorType } from "./IServerValidator.js";
3
+ /**
4
+ * Factory class for managing server validator instances
5
+ * Maintains a singleton map of validators by type
6
+ */
7
+ export declare class ServerValidatorFactory {
8
+ private static validators;
9
+ constructor();
10
+ /**
11
+ * Gets the appropriate validator for the given server mode
12
+ * @param mode The server mode to get validator for
13
+ * @returns IServerValidator instance for the specified mode
14
+ * @throws Error if server mode is not supported
15
+ */
16
+ getValidator(mode: ValidatorType): IServerValidator;
17
+ /**
18
+ * Gets the appropriate validator for the given server config
19
+ * @param serverConfig MCP server configuration
20
+ * @returns IServerValidator instance appropriate for the server mode
21
+ */
22
+ getValidatorForServer(serverConfig: McpConfig): IServerValidator;
23
+ }
24
+ export declare const serverValidatorFactory: ServerValidatorFactory;
@@ -0,0 +1,45 @@
1
+ import { StdioServerValidator } from "./StdioServerValidator.js";
2
+ import { SSEServerValidator } from "./SSEServerValidator.js";
3
+ import { Logger } from "../../utils/logger.js";
4
+ /**
5
+ * Factory class for managing server validator instances
6
+ * Maintains a singleton map of validators by type
7
+ */
8
+ export class ServerValidatorFactory {
9
+ static validators = new Map();
10
+ constructor() {
11
+ // Initialize validators if not already done
12
+ if (ServerValidatorFactory.validators.size === 0) {
13
+ Logger.debug('Initializing server validators');
14
+ ServerValidatorFactory.validators.set('stdio', new StdioServerValidator());
15
+ ServerValidatorFactory.validators.set('sse', new SSEServerValidator());
16
+ }
17
+ }
18
+ /**
19
+ * Gets the appropriate validator for the given server mode
20
+ * @param mode The server mode to get validator for
21
+ * @returns IServerValidator instance for the specified mode
22
+ * @throws Error if server mode is not supported
23
+ */
24
+ getValidator(mode) {
25
+ const validator = ServerValidatorFactory.validators.get(mode);
26
+ if (!validator) {
27
+ const error = `Unsupported MCP server mode: ${mode}`;
28
+ Logger.error(error);
29
+ throw new Error(error);
30
+ }
31
+ Logger.debug(`Retrieved ${mode} validator`);
32
+ return validator;
33
+ }
34
+ /**
35
+ * Gets the appropriate validator for the given server config
36
+ * @param serverConfig MCP server configuration
37
+ * @returns IServerValidator instance appropriate for the server mode
38
+ */
39
+ getValidatorForServer(serverConfig) {
40
+ return this.getValidator(serverConfig.mode);
41
+ }
42
+ }
43
+ // Export singleton instance
44
+ export const serverValidatorFactory = new ServerValidatorFactory();
45
+ //# sourceMappingURL=ServerValidatorFactory.js.map
@@ -0,0 +1,46 @@
1
+ import { McpConfig, FeedConfiguration } from "../types.js";
2
+ import { IServerValidator } from "./IServerValidator.js";
3
+ /**
4
+ * Validates MCP server configurations for stdio mode
5
+ */
6
+ export declare class StdioServerValidator implements IServerValidator {
7
+ private installerFactory;
8
+ /**
9
+ * Tests if a command exists and is executable
10
+ * @param command The command to test
11
+ * @returns true if command exists and is executable
12
+ */
13
+ private isCommandExecutable;
14
+ /**
15
+ * Generates a dedicated folder path for a requirement.
16
+ * @param requirement The requirement configuration.
17
+ * @returns The path to the requirement's dedicated folder.
18
+ * @private
19
+ */
20
+ private _getRequirementFolderPath;
21
+ /**
22
+ * Validates and installs a requirement if needed
23
+ * @param requirement The requirement config to validate and install
24
+ * @returns true if requirement is successfully installed/validated
25
+ */
26
+ private validateRequirement;
27
+ /**
28
+ * Tests if a server can be started successfully with proper path resolution
29
+ * @param command The command to start the server
30
+ * @param args The command line arguments
31
+ * @returns Promise<boolean> true if server starts successfully, false otherwise
32
+ *
33
+ * Handles special cases:
34
+ * - For node commands: resolves ${NPMPATH} in arguments using resolveNpmModulePath
35
+ * - For python/python3 commands: resolves ${PYTHON_PACKAGE} in arguments using system Python packages
36
+ */
37
+ private testServerStartup;
38
+ /**
39
+ * Validates stdio-specific MCP server configuration
40
+ * Checks command, arguments, dependencies and required environment variables
41
+ * @param server The MCP server configuration to validate
42
+ * @param config The feed configuration containing shared requirements
43
+ * @returns true if valid, throws error if invalid
44
+ */
45
+ validateServer(server: McpConfig, config: FeedConfiguration): Promise<boolean>;
46
+ }
@@ -0,0 +1,229 @@
1
+ import { Logger } from "../../utils/logger.js";
2
+ import { createInstallerFactory } from "../installers/index.js";
3
+ import { exec, spawn } from 'child_process';
4
+ import util from 'util';
5
+ import { MACRO_EXPRESSIONS, resolveNpmModulePath } from "../../utils/macroExpressionUtils.js";
6
+ import { getSystemPythonPackageDirectory } from "../../utils/osUtils.js";
7
+ import { SETTINGS_DIR } from "../constants.js";
8
+ import path from "path";
9
+ const execPromise = util.promisify(exec);
10
+ /**
11
+ * Validates MCP server configurations for stdio mode
12
+ */
13
+ export class StdioServerValidator {
14
+ installerFactory = createInstallerFactory();
15
+ /**
16
+ * Tests if a command exists and is executable
17
+ * @param command The command to test
18
+ * @returns true if command exists and is executable
19
+ */
20
+ async isCommandExecutable(command) {
21
+ try {
22
+ Logger.debug(`Testing if command is executable: ${command}`);
23
+ const testCmd = process.platform === 'win32' ?
24
+ `where ${command}` :
25
+ `command -v ${command}`;
26
+ await execPromise(testCmd);
27
+ return true;
28
+ }
29
+ catch (error) {
30
+ Logger.debug(`Command not found: ${command}`);
31
+ return false;
32
+ }
33
+ }
34
+ /**
35
+ * Generates a dedicated folder path for a requirement.
36
+ * @param requirement The requirement configuration.
37
+ * @returns The path to the requirement's dedicated folder.
38
+ * @private
39
+ */
40
+ _getRequirementFolderPath(requirement) {
41
+ return path.join(SETTINGS_DIR, 'onboard', 'npm_requirements', requirement.name, requirement.version.includes('latest') ? 'latest' : requirement.version);
42
+ }
43
+ /**
44
+ * Validates and installs a requirement if needed
45
+ * @param requirement The requirement config to validate and install
46
+ * @returns true if requirement is successfully installed/validated
47
+ */
48
+ async validateRequirement(requirement) {
49
+ try {
50
+ Logger.debug(`Validating/installing requirement: ${requirement.name}`);
51
+ const installer = this.installerFactory.getInstaller(requirement);
52
+ if (!installer) {
53
+ const msg = `No installer found for requirement type: ${requirement.type}`;
54
+ Logger.error(msg);
55
+ throw new Error(msg);
56
+ }
57
+ const targetDir = this._getRequirementFolderPath(requirement);
58
+ const status = await installer.install(requirement, { settings: { folderName: targetDir } });
59
+ if (!status.installed) {
60
+ const msg = `Failed to install requirement ${requirement.name}: ${status.error || 'Unknown error'}`;
61
+ Logger.error(msg);
62
+ throw new Error(msg);
63
+ }
64
+ Logger.debug(`Requirement ${requirement.name} is valid and installed`);
65
+ return true;
66
+ }
67
+ catch (error) {
68
+ const errorMsg = `Error validating/installing requirement ${requirement.name}: ${error instanceof Error ? error.message : String(error)}`;
69
+ Logger.error(errorMsg);
70
+ throw error instanceof Error ? error : new Error(errorMsg);
71
+ }
72
+ }
73
+ /**
74
+ * Tests if a server can be started successfully with proper path resolution
75
+ * @param command The command to start the server
76
+ * @param args The command line arguments
77
+ * @returns Promise<boolean> true if server starts successfully, false otherwise
78
+ *
79
+ * Handles special cases:
80
+ * - For node commands: resolves ${NPMPATH} in arguments using resolveNpmModulePath
81
+ * - For python/python3 commands: resolves ${PYTHON_PACKAGE} in arguments using system Python packages
82
+ */
83
+ async testServerStartup(command, args, requirement) {
84
+ try {
85
+ // Log initial command and args
86
+ Logger.debug(`Testing server startup with command: ${command}`);
87
+ Logger.debug(`Original arguments: ${args.join(' ')}`);
88
+ // Handle path resolution based on command type
89
+ let finalArgs = [...args];
90
+ if (command === 'node') {
91
+ // Resolve npm module paths in arguments
92
+ Logger.debug('Resolving npm module paths in arguments');
93
+ const npmPath = requirement ? this._getRequirementFolderPath(requirement) : undefined;
94
+ finalArgs = args.map(arg => arg.replace(MACRO_EXPRESSIONS.NPMPATH, resolveNpmModulePath(npmPath)));
95
+ Logger.debug(`Resolved npm arguments: ${finalArgs.join(' ')}`);
96
+ }
97
+ else if (command === 'python' || command === 'python3') {
98
+ // Resolve Python package paths in arguments
99
+ Logger.debug('Resolving Python package paths in arguments');
100
+ const pythonDir = await getSystemPythonPackageDirectory();
101
+ if (pythonDir) {
102
+ finalArgs = args.map(arg => arg.includes('${PYTHON_PACKAGE}') ? arg.replace('${PYTHON_PACKAGE}', pythonDir) : arg);
103
+ Logger.debug(`Resolved Python arguments: ${finalArgs.join(' ')}`);
104
+ }
105
+ else {
106
+ const msg = 'Could not resolve system Python package directory';
107
+ Logger.error(msg);
108
+ throw new Error(msg);
109
+ }
110
+ }
111
+ 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
121
+ const serverProcess = spawn(command, finalArgs, {
122
+ stdio: ['ignore', 'pipe', 'pipe'],
123
+ shell: true
124
+ });
125
+ let output = '';
126
+ let errorOutput = '';
127
+ // Collect stdout
128
+ 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);
134
+ });
135
+ // Collect stderr
136
+ serverProcess.stderr.on('data', (data) => {
137
+ errorOutput += data.toString();
138
+ });
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}`;
144
+ Logger.error(msg);
145
+ reject(new Error(msg));
146
+ }
147
+ });
148
+ // Handle process error
149
+ serverProcess.on('error', (error) => {
150
+ clearTimeout(timeout);
151
+ const msg = `Server startup error: ${error.message}`;
152
+ Logger.error(msg);
153
+ reject(error);
154
+ });
155
+ });
156
+ }
157
+ catch (error) {
158
+ const msg = `Failed to test server startup: ${error instanceof Error ? error.message : String(error)}`;
159
+ Logger.error(msg);
160
+ throw error instanceof Error ? error : new Error(msg);
161
+ }
162
+ }
163
+ /**
164
+ * Validates stdio-specific MCP server configuration
165
+ * Checks command, arguments, dependencies and required environment variables
166
+ * @param server The MCP server configuration to validate
167
+ * @param config The feed configuration containing shared requirements
168
+ * @returns true if valid, throws error if invalid
169
+ */
170
+ async validateServer(server, config) {
171
+ try {
172
+ Logger.debug(`Validating stdio server configuration: ${server.name}`);
173
+ // Check required installation command
174
+ if (!server.installation?.command) {
175
+ throw new Error('Server command is required in installation configuration');
176
+ }
177
+ // Validate server mode
178
+ if (server.mode !== 'stdio') {
179
+ throw new Error(`Invalid server mode for stdio validator: ${server.mode}`);
180
+ }
181
+ // Parse command and arguments
182
+ const fullCommand = server.installation.command;
183
+ const [baseCommand, ...defaultArgs] = fullCommand.split(' ');
184
+ const args = [...defaultArgs, ...(server.installation.args || [])];
185
+ // Validate command exists and is executable
186
+ const isExecutable = await this.isCommandExecutable(baseCommand);
187
+ if (!isExecutable) {
188
+ throw new Error(`Command not found or not executable: ${baseCommand}`);
189
+ }
190
+ // Validate required environment variables if specified
191
+ const envVars = server.installation.env;
192
+ if (envVars) {
193
+ for (const [name, varConfig] of Object.entries(envVars)) {
194
+ if (varConfig.Required && !varConfig.Default && !process.env[name]) {
195
+ throw new Error(`Required environment variable not set: ${name}`);
196
+ }
197
+ }
198
+ }
199
+ // Validate dependencies if specified
200
+ if (server.dependencies?.requirements) {
201
+ Logger.debug(`Validating ${server.dependencies.requirements.length} requirements`);
202
+ for (const req of server.dependencies.requirements) {
203
+ const reqConfig = config.requirements?.find(r => r.name === req.name) || {
204
+ name: req.name,
205
+ version: req.version,
206
+ type: 'npm' // Default to npm if not specified
207
+ };
208
+ const isValid = await this.validateRequirement(reqConfig);
209
+ if (!isValid) {
210
+ throw new Error(`Dependency validation failed for: ${req.name}`);
211
+ }
212
+ }
213
+ }
214
+ // Test server startup
215
+ const serverStarted = await this.testServerStartup(baseCommand, args, config.requirements?.find(r => r.type === 'npm'));
216
+ if (!serverStarted) {
217
+ throw new Error(`Failed to start server with command: ${fullCommand} ${args.join(' ')}`);
218
+ }
219
+ Logger.debug(`Stdio server validation successful: ${server.name}`);
220
+ return true;
221
+ }
222
+ catch (error) {
223
+ const errorMsg = `Server validation failed: ${error instanceof Error ? error.message : String(error)}`;
224
+ Logger.error(errorMsg);
225
+ throw new Error(errorMsg);
226
+ }
227
+ }
228
+ }
229
+ //# sourceMappingURL=StdioServerValidator.js.map
@@ -1,5 +1,5 @@
1
1
  import { ServerInstallOptions } from '../core/types.js';
2
- import { InstallServersRequestBody } from '../web/server.js';
2
+ import { InstallServersRequestBody } from '../web/contract/serverContract.js';
3
3
  export declare class InstallRequestValidator {
4
4
  private serverFeedConfigs;
5
5
  private feedDirectory;
@@ -1,5 +1,6 @@
1
1
  import { ServerSchema } from '../core/ServerSchemaProvider.js';
2
- import { MCPServerCategory, ServerInstallOptions, ServerCategoryListOptions, ServerOperationResult, ServerUninstallOptions } from '../core/types.js';
2
+ import { MCPServerCategory, ServerInstallOptions, ServerCategoryListOptions, ServerOperationResult, ServerUninstallOptions, FeedConfiguration } from '../core/types.js';
3
+ import { OperationStatus } from '../core/onboard/OnboardStatus.js';
3
4
  /**
4
5
  * ServerService provides a unified interface for server management operations.
5
6
  * This layer handles business logic that's shared between the CLI and web interface.
@@ -25,13 +26,8 @@ export declare class ServerService {
25
26
  getServerSchema(categoryName: string, serverName: string): Promise<ServerSchema | undefined>;
26
27
  /**
27
28
  * Installs a specific mcp tool for a server.
28
- * TODO: This might require enhancing MCPManager to handle category-specific installs.
29
29
  */
30
30
  installMcpServer(category: string, serverName: string, options?: ServerInstallOptions): Promise<ServerOperationResult>;
31
- /**
32
- * Installs a specific mcp tool for a server.
33
- * TODO: This might require enhancing MCPManager to handle category-specific installs.
34
- */
35
31
  /**
36
32
  * Uninstall MCP server from specified client targets
37
33
  * @param category The server category
@@ -54,5 +50,12 @@ export declare class ServerService {
54
50
  * Syncs MCP server configurations from remote feed source
55
51
  */
56
52
  syncFeeds(): Promise<void>;
53
+ /**
54
+ * Onboards a new feed configuration
55
+ * @param config Feed configuration to onboard
56
+ */
57
+ onboardFeed(config: FeedConfiguration): Promise<OperationStatus & {
58
+ feedConfiguration?: FeedConfiguration;
59
+ }>;
57
60
  }
58
61
  export declare const serverService: ServerService;
@@ -113,10 +113,8 @@ export class ServerService {
113
113
  }
114
114
  /**
115
115
  * Installs a specific mcp tool for a server.
116
- * TODO: This might require enhancing MCPManager to handle category-specific installs.
117
116
  */
118
- async installMcpServer(category, serverName, options = {} // Reuse ServerInstallOptions for env etc.
119
- ) {
117
+ async installMcpServer(category, serverName, options = {}) {
120
118
  Logger.debug(`Installing MCP server: ${JSON.stringify({ category, serverName, options })}`);
121
119
  try {
122
120
  const result = await mcpManager.installServer(category, serverName, options);
@@ -128,10 +126,6 @@ export class ServerService {
128
126
  throw error;
129
127
  }
130
128
  }
131
- /**
132
- * Installs a specific mcp tool for a server.
133
- * TODO: This might require enhancing MCPManager to handle category-specific installs.
134
- */
135
129
  /**
136
130
  * Uninstall MCP server from specified client targets
137
131
  * @param category The server category
@@ -185,6 +179,23 @@ export class ServerService {
185
179
  async syncFeeds() {
186
180
  return mcpManager.syncFeeds();
187
181
  }
182
+ /**
183
+ * Onboards a new feed configuration
184
+ * @param config Feed configuration to onboard
185
+ */
186
+ async onboardFeed(config) {
187
+ try {
188
+ const result = await mcpManager.onboardFeed(config);
189
+ // Log based on the operation status, e.g., if it's pending or succeeded.
190
+ // The actual "success" of onboarding is a multi-step process (PR creation, merge).
191
+ Logger.log(`Feed onboarding process for '${config.name}' initiated with status: ${result.status}, ID: ${result.onboardingId}`);
192
+ return result;
193
+ }
194
+ catch (error) {
195
+ Logger.error(`Failed to initiate feed onboarding for '${config.name}':`, error);
196
+ throw error; // Or return a specific error status object
197
+ }
198
+ }
188
199
  }
189
200
  // Export a singleton instance
190
201
  export const serverService = new ServerService();
@@ -0,0 +1,29 @@
1
+ import { RequirementConfig, RegistryConfig } from '../core/types.js';
2
+ export interface AdoArtifactResult {
3
+ type: 'npm' | 'pip';
4
+ package: string;
5
+ registryUrl: string;
6
+ folderPath?: string;
7
+ version: string;
8
+ }
9
+ /**
10
+ * Handles fetching and setting up an Azure DevOps artifact.
11
+ * @param requirement The requirement configuration.
12
+ * @param registry The Azure DevOps artifacts registry configuration.
13
+ * @param pythonCommand Optional Python command (e.g., 'python', 'python3') for pip operations.
14
+ * @param targetDir Optional target directory for npm artifact setup. If not provided, a default will be used.
15
+ * @returns A promise that resolves with the artifact details.
16
+ */
17
+ export declare function handleArtifact(requirement: RequirementConfig, registry: RegistryConfig['artifacts'], pythonCommand?: string, // Default to 'python' if not provided
18
+ targetDir?: string): Promise<AdoArtifactResult>;
19
+ /**
20
+ * Get the latest version of an artifact from Azure DevOps.
21
+ * This is a simplified implementation and might require further enhancements for robust authentication and error handling.
22
+ * @param execPromise The promise-based exec function.
23
+ * @param requirement The requirement configuration.
24
+ * @param registry The Azure DevOps artifacts registry configuration.
25
+ * @param options Optional server install options (e.g., for pythonCommand).
26
+ * @returns The latest version string, or undefined if not found or an error occurs.
27
+ */
28
+ export declare function getArtifactLatestVersion(requirement: RequirementConfig, registry: RegistryConfig['artifacts'], options?: import('../core/types.js').ServerInstallOptions, // Added import for ServerInstallOptions
29
+ targetDir?: string): Promise<string | undefined>;