imcp 0.0.14 → 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.
- package/dist/core/ConfigurationProvider.d.ts +1 -0
- package/dist/core/ConfigurationProvider.js +15 -0
- package/dist/core/InstallationService.js +2 -7
- package/dist/core/MCPManager.d.ts +11 -2
- package/dist/core/MCPManager.js +24 -1
- package/dist/core/RequirementService.js +2 -8
- package/dist/core/installers/clients/BaseClientInstaller.d.ts +51 -0
- package/dist/core/installers/clients/BaseClientInstaller.js +160 -0
- package/dist/core/installers/clients/ClientInstaller.d.ts +16 -8
- package/dist/core/installers/clients/ClientInstaller.js +80 -525
- package/dist/core/installers/clients/ClientInstallerFactory.d.ts +19 -0
- package/dist/core/installers/clients/ClientInstallerFactory.js +41 -0
- package/dist/core/installers/clients/ClineInstaller.d.ts +18 -0
- package/dist/core/installers/clients/ClineInstaller.js +124 -0
- package/dist/core/installers/clients/GithubCopilotInstaller.d.ts +34 -0
- package/dist/core/installers/clients/GithubCopilotInstaller.js +162 -0
- package/dist/core/installers/clients/MSRooCodeInstaller.d.ts +15 -0
- package/dist/core/installers/clients/MSRooCodeInstaller.js +122 -0
- package/dist/core/installers/requirements/BaseInstaller.d.ts +11 -34
- package/dist/core/installers/requirements/BaseInstaller.js +5 -116
- package/dist/core/installers/requirements/CommandInstaller.d.ts +6 -1
- package/dist/core/installers/requirements/CommandInstaller.js +7 -0
- package/dist/core/installers/requirements/GeneralInstaller.d.ts +6 -1
- package/dist/core/installers/requirements/GeneralInstaller.js +9 -4
- package/dist/core/installers/requirements/NpmInstaller.d.ts +46 -7
- package/dist/core/installers/requirements/NpmInstaller.js +150 -58
- package/dist/core/installers/requirements/PipInstaller.d.ts +9 -0
- package/dist/core/installers/requirements/PipInstaller.js +66 -28
- package/dist/core/onboard/FeedOnboardService.d.ts +50 -13
- package/dist/core/onboard/FeedOnboardService.js +263 -88
- package/dist/core/onboard/OnboardProcessor.d.ts +79 -0
- package/dist/core/onboard/OnboardProcessor.js +290 -0
- package/dist/core/onboard/OnboardStatus.d.ts +49 -0
- package/dist/core/onboard/OnboardStatus.js +10 -0
- package/dist/core/onboard/OnboardStatusManager.d.ts +57 -0
- package/dist/core/onboard/OnboardStatusManager.js +176 -0
- package/dist/core/types.d.ts +4 -5
- package/dist/core/validators/FeedValidator.d.ts +8 -1
- package/dist/core/validators/FeedValidator.js +60 -7
- package/dist/core/validators/IServerValidator.d.ts +19 -0
- package/dist/core/validators/IServerValidator.js +2 -0
- package/dist/core/validators/SSEServerValidator.d.ts +15 -0
- package/dist/core/validators/SSEServerValidator.js +39 -0
- package/dist/core/validators/ServerValidatorFactory.d.ts +24 -0
- package/dist/core/validators/ServerValidatorFactory.js +45 -0
- package/dist/core/validators/StdioServerValidator.d.ts +46 -0
- package/dist/core/validators/StdioServerValidator.js +229 -0
- package/dist/services/InstallRequestValidator.d.ts +1 -1
- package/dist/services/ServerService.d.ts +9 -6
- package/dist/services/ServerService.js +18 -7
- package/dist/utils/adoUtils.d.ts +29 -0
- package/dist/utils/adoUtils.js +252 -0
- package/dist/utils/clientUtils.d.ts +0 -7
- package/dist/utils/clientUtils.js +0 -42
- package/dist/utils/githubUtils.d.ts +10 -0
- package/dist/utils/githubUtils.js +22 -0
- package/dist/utils/macroExpressionUtils.d.ts +38 -0
- package/dist/utils/macroExpressionUtils.js +116 -0
- package/dist/utils/osUtils.d.ts +4 -20
- package/dist/utils/osUtils.js +78 -23
- package/dist/web/contract/serverContract.d.ts +3 -1
- package/dist/web/public/css/notifications.css +48 -17
- package/dist/web/public/css/onboard.css +66 -3
- package/dist/web/public/index.html +84 -16
- package/dist/web/public/js/api.js +3 -6
- package/dist/web/public/js/flights/flights.js +127 -0
- package/dist/web/public/js/modal/modalSetup.js +3 -2
- package/dist/web/public/js/notifications.js +66 -27
- package/dist/web/public/js/onboard/ONBOARDING_PAGE_DESIGN.md +338 -0
- package/dist/web/public/js/onboard/formProcessor.js +810 -255
- package/dist/web/public/js/onboard/index.js +328 -85
- package/dist/web/public/js/onboard/publishHandler.js +132 -0
- package/dist/web/public/js/onboard/state.js +61 -17
- package/dist/web/public/js/onboard/templates.js +217 -249
- package/dist/web/public/js/onboard/uiHandlers.js +679 -117
- package/dist/web/public/js/onboard/validationHandlers.js +378 -0
- package/dist/web/public/js/serverCategoryList.js +15 -2
- package/dist/web/public/onboard.html +191 -45
- package/dist/web/public/styles.css +91 -1
- package/dist/web/server.d.ts +0 -10
- package/dist/web/server.js +131 -22
- package/package.json +2 -2
- package/src/core/ConfigurationProvider.ts +15 -0
- package/src/core/InstallationService.ts +2 -7
- package/src/core/MCPManager.ts +26 -1
- package/src/core/RequirementService.ts +2 -9
- package/src/core/installers/clients/BaseClientInstaller.ts +196 -0
- package/src/core/installers/clients/ClientInstaller.ts +97 -606
- package/src/core/installers/clients/ClientInstallerFactory.ts +46 -0
- package/src/core/installers/clients/ClineInstaller.ts +135 -0
- package/src/core/installers/clients/GithubCopilotInstaller.ts +179 -0
- package/src/core/installers/clients/MSRooCodeInstaller.ts +133 -0
- package/src/core/installers/requirements/BaseInstaller.ts +13 -136
- package/src/core/installers/requirements/CommandInstaller.ts +9 -1
- package/src/core/installers/requirements/GeneralInstaller.ts +11 -4
- package/src/core/installers/requirements/NpmInstaller.ts +178 -61
- package/src/core/installers/requirements/PipInstaller.ts +68 -29
- package/src/core/onboard/FeedOnboardService.ts +346 -0
- package/src/core/onboard/OnboardProcessor.ts +305 -0
- package/src/core/onboard/OnboardStatus.ts +55 -0
- package/src/core/onboard/OnboardStatusManager.ts +188 -0
- package/src/core/types.ts +4 -5
- package/src/core/validators/FeedValidator.ts +79 -0
- package/src/core/validators/IServerValidator.ts +21 -0
- package/src/core/validators/SSEServerValidator.ts +43 -0
- package/src/core/validators/ServerValidatorFactory.ts +51 -0
- package/src/core/validators/StdioServerValidator.ts +259 -0
- package/src/services/InstallRequestValidator.ts +1 -1
- package/src/services/ServerService.ts +22 -7
- package/src/utils/adoUtils.ts +291 -0
- package/src/utils/clientUtils.ts +0 -44
- package/src/utils/githubUtils.ts +24 -0
- package/src/utils/macroExpressionUtils.ts +121 -0
- package/src/utils/osUtils.ts +89 -24
- package/src/web/contract/serverContract.ts +74 -0
- package/src/web/public/css/notifications.css +48 -17
- package/src/web/public/css/onboard.css +107 -0
- package/src/web/public/index.html +84 -16
- package/src/web/public/js/api.js +3 -6
- package/src/web/public/js/flights/flights.js +127 -0
- package/src/web/public/js/modal/modalSetup.js +3 -2
- package/src/web/public/js/notifications.js +66 -27
- package/src/web/public/js/onboard/ONBOARDING_PAGE_DESIGN.md +338 -0
- package/src/web/public/js/onboard/formProcessor.js +864 -0
- package/src/web/public/js/onboard/index.js +374 -0
- package/src/web/public/js/onboard/publishHandler.js +132 -0
- package/src/web/public/js/onboard/state.js +76 -0
- package/src/web/public/js/onboard/templates.js +343 -0
- package/src/web/public/js/onboard/uiHandlers.js +758 -0
- package/src/web/public/js/onboard/validationHandlers.js +378 -0
- package/src/web/public/js/serverCategoryList.js +15 -2
- package/src/web/public/onboard.html +296 -0
- package/src/web/public/styles.css +91 -1
- package/src/web/server.ts +167 -58
|
@@ -24,6 +24,7 @@ export declare class ConfigurationProvider {
|
|
|
24
24
|
updateServerStatus(categoryName: string, serverName: string, status: MCPServerStatus): Promise<boolean>;
|
|
25
25
|
updateServerOperationStatus(categoryName: string, serverName: string, clientName: string, operationStatus: OperationStatus): Promise<boolean>;
|
|
26
26
|
isRequirementsReady(categoryName: string, serverName: string): Promise<boolean>;
|
|
27
|
+
GetServerRequirementStatus(categoryName: string, serverName: string): Promise<RequirementStatus[]>;
|
|
27
28
|
isServerReady(categoryName: string, serverName: string, clients: string[]): Promise<boolean>;
|
|
28
29
|
syncFeeds(): Promise<void>;
|
|
29
30
|
private loadFeedsIntoConfiguration;
|
|
@@ -216,6 +216,21 @@ export class ConfigurationProvider {
|
|
|
216
216
|
});
|
|
217
217
|
});
|
|
218
218
|
}
|
|
219
|
+
async GetServerRequirementStatus(categoryName, serverName) {
|
|
220
|
+
return await this.withLock(async () => {
|
|
221
|
+
// Inline getServerCategory logic
|
|
222
|
+
const category = this.configuration.localServerCategories.find(s => s.name === categoryName);
|
|
223
|
+
if (!category?.feedConfiguration)
|
|
224
|
+
return [];
|
|
225
|
+
const serverConfig = category.feedConfiguration.mcpServers.find(s => s.name === serverName);
|
|
226
|
+
if (!serverConfig?.dependencies?.requirements)
|
|
227
|
+
return [];
|
|
228
|
+
const requirementNames = serverConfig.dependencies.requirements.map(r => r.name);
|
|
229
|
+
return requirementNames
|
|
230
|
+
.map(name => category?.installationStatus?.requirementsStatus[name])
|
|
231
|
+
.filter(x => x !== undefined);
|
|
232
|
+
});
|
|
233
|
+
}
|
|
219
234
|
async isServerReady(categoryName, serverName, clients) {
|
|
220
235
|
return await this.withLock(async () => {
|
|
221
236
|
// Inline the logic from getServerStatus and getInstallationStatus to avoid nested lock
|
|
@@ -118,20 +118,15 @@ export class InstallationService {
|
|
|
118
118
|
message: `Updating ${reqToUpdate.name} from ${currentStatus.version || 'unknown'} to ${reqToUpdate.version}`
|
|
119
119
|
}
|
|
120
120
|
});
|
|
121
|
-
// Create updated requirement config with new version
|
|
122
|
-
const updatedReqConfig = {
|
|
123
|
-
...reqConfig,
|
|
124
|
-
version: reqToUpdate.version
|
|
125
|
-
};
|
|
126
121
|
// For pip requirements, check if we have a stored pythonEnv
|
|
127
|
-
if (
|
|
122
|
+
if (reqConfig.type === 'pip' && currentStatus.pythonEnv && !options?.settings?.pythonEnv) {
|
|
128
123
|
options = {
|
|
129
124
|
...options,
|
|
130
125
|
settings: { ...options?.settings, pythonEnv: currentStatus.pythonEnv }
|
|
131
126
|
};
|
|
132
127
|
}
|
|
133
128
|
// Update the requirement with options for pip environment
|
|
134
|
-
const updatedStatus = await requirementService.updateRequirement(
|
|
129
|
+
const updatedStatus = await requirementService.updateRequirement(reqConfig, reqToUpdate.version, options);
|
|
135
130
|
// Update requirement status
|
|
136
131
|
await configProvider.updateRequirementStatus(categoryName, reqToUpdate.name, {
|
|
137
132
|
...updatedStatus,
|
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import { MCPEvent, MCPEventData, MCPServerCategory, ServerInstallOptions, ServerCategoryListOptions, ServerOperationResult, ServerUninstallOptions } from './types.js';
|
|
2
|
+
import { MCPEvent, MCPEventData, MCPServerCategory, ServerInstallOptions, ServerCategoryListOptions, ServerOperationResult, ServerUninstallOptions, FeedConfiguration } from './types.js';
|
|
3
|
+
import { OperationStatus } from './onboard/OnboardStatus.js';
|
|
3
4
|
export declare class MCPManager extends EventEmitter {
|
|
4
5
|
private installationService;
|
|
5
6
|
private configProvider;
|
|
7
|
+
private feedOnboardService;
|
|
6
8
|
constructor();
|
|
7
9
|
syncFeeds(): Promise<void>;
|
|
8
10
|
initialize(feedFile?: string): Promise<void>;
|
|
9
11
|
listServerCategories(options?: ServerCategoryListOptions): Promise<MCPServerCategory[]>;
|
|
10
|
-
getFeedConfiguration(categoryName: string): Promise<
|
|
12
|
+
getFeedConfiguration(categoryName: string): Promise<FeedConfiguration | undefined>;
|
|
11
13
|
getServerMcpConfig(categoryName: string, serverName: string): Promise<import("./types.js").McpConfig | undefined>;
|
|
12
14
|
installServer(categoryName: string, serverName: string, requestOptions?: ServerInstallOptions): Promise<ServerOperationResult>;
|
|
13
15
|
uninstallServer(categoryName: string, serverName: string, options?: ServerUninstallOptions): Promise<ServerOperationResult>;
|
|
14
16
|
updateRequirement(categoryName: string, serverName: string, requirementName: string, updateVersion: string): Promise<ServerOperationResult>;
|
|
17
|
+
/**
|
|
18
|
+
* Onboards a new feed configuration
|
|
19
|
+
* @param config The feed configuration to onboard
|
|
20
|
+
*/
|
|
21
|
+
onboardFeed(config: FeedConfiguration): Promise<OperationStatus & {
|
|
22
|
+
feedConfiguration?: FeedConfiguration;
|
|
23
|
+
}>;
|
|
15
24
|
emit<E extends MCPEvent>(event: E, data: MCPEventData[E]): boolean;
|
|
16
25
|
on<E extends MCPEvent>(event: E, listener: (data: MCPEventData[E]) => void): this;
|
|
17
26
|
off<E extends MCPEvent>(event: E, listener: (data: MCPEventData[E]) => void): this;
|
package/dist/core/MCPManager.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
2
|
import { ConfigurationProvider } from './ConfigurationProvider.js';
|
|
3
3
|
import { InstallationService } from './InstallationService.js';
|
|
4
|
-
import { MCPEvent } from './types.js';
|
|
4
|
+
import { MCPEvent, } from './types.js';
|
|
5
|
+
import { Logger } from '../utils/logger.js';
|
|
6
|
+
import { FeedOnboardService } from './onboard/FeedOnboardService.js';
|
|
5
7
|
export class MCPManager extends EventEmitter {
|
|
6
8
|
installationService;
|
|
7
9
|
configProvider;
|
|
10
|
+
feedOnboardService;
|
|
8
11
|
constructor() {
|
|
9
12
|
super();
|
|
10
13
|
this.configProvider = ConfigurationProvider.getInstance();
|
|
11
14
|
this.installationService = new InstallationService();
|
|
15
|
+
this.feedOnboardService = new FeedOnboardService();
|
|
12
16
|
}
|
|
13
17
|
async syncFeeds() {
|
|
14
18
|
await this.configProvider.syncFeeds();
|
|
@@ -149,6 +153,25 @@ export class MCPManager extends EventEmitter {
|
|
|
149
153
|
};
|
|
150
154
|
}
|
|
151
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Onboards a new feed configuration
|
|
158
|
+
* @param config The feed configuration to onboard
|
|
159
|
+
*/
|
|
160
|
+
async onboardFeed(config) {
|
|
161
|
+
try {
|
|
162
|
+
const result = await this.feedOnboardService.onboardFeed(config);
|
|
163
|
+
// After successful onboarding initiation, sync feeds to get the latest changes
|
|
164
|
+
// Syncing should ideally happen after the PR is merged, but for now,
|
|
165
|
+
// syncing here makes the new (pending) category available locally if needed.
|
|
166
|
+
// Consider if syncFeeds should be conditional based on operation status or handled differently.
|
|
167
|
+
await this.syncFeeds();
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
Logger.error('Failed to onboard feed in MCPManager:', error);
|
|
172
|
+
throw error; // Rethrow or handle by returning a failed OperationStatus
|
|
173
|
+
}
|
|
174
|
+
}
|
|
152
175
|
// Type-safe event emitter methods
|
|
153
176
|
emit(event, data) {
|
|
154
177
|
return super.emit(event, data);
|
|
@@ -73,7 +73,7 @@ export class RequirementService {
|
|
|
73
73
|
// Create an updated requirement with the new version
|
|
74
74
|
const updatedRequirement = {
|
|
75
75
|
...requirement,
|
|
76
|
-
version: updateVersion
|
|
76
|
+
version: requirement.version.includes('latest') ? requirement.version : updateVersion,
|
|
77
77
|
};
|
|
78
78
|
// Install the updated version
|
|
79
79
|
return await this.installerFactory.install(updatedRequirement, options);
|
|
@@ -110,7 +110,7 @@ export class RequirementService {
|
|
|
110
110
|
}
|
|
111
111
|
// Validate registry configuration if provided
|
|
112
112
|
if (requirement.registry) {
|
|
113
|
-
const { githubRelease, artifacts
|
|
113
|
+
const { githubRelease, artifacts } = requirement.registry;
|
|
114
114
|
// Validate GitHub release configuration
|
|
115
115
|
if (githubRelease) {
|
|
116
116
|
if (!githubRelease.repository) {
|
|
@@ -126,12 +126,6 @@ export class RequirementService {
|
|
|
126
126
|
throw new Error('Registry URL is required for artifacts registry');
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
|
-
// Validate local registry configuration
|
|
130
|
-
if (local) {
|
|
131
|
-
if (!local.localPath) {
|
|
132
|
-
throw new Error('Local path is required for local registry');
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
129
|
}
|
|
136
130
|
}
|
|
137
131
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { OperationStatus, McpConfig, ServerInstallOptions } from '../../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Base class for client installers with shared functionality
|
|
4
|
+
*/
|
|
5
|
+
export declare abstract class BaseClientInstaller {
|
|
6
|
+
/**
|
|
7
|
+
* Generate a unique operation ID for tracking installations
|
|
8
|
+
*/
|
|
9
|
+
protected generateOperationId(): string;
|
|
10
|
+
/**
|
|
11
|
+
* Set up installation configuration with environment variables and arguments
|
|
12
|
+
* Handles Python environment configuration if specified
|
|
13
|
+
*/
|
|
14
|
+
protected setupInstallConfig(serverConfig: McpConfig, options: ServerInstallOptions): Promise<any>;
|
|
15
|
+
/**
|
|
16
|
+
* Resolves and replaces known macro expressions (e.g., ${PYTHON_PACKAGE}, ${NPMPATH}, ${BROWSER_PATH})
|
|
17
|
+
* in the provided configuration object's 'args' and 'env' properties.
|
|
18
|
+
* This method directly mutates the finalConfig object.
|
|
19
|
+
* @param finalConfig The configuration object to modify.
|
|
20
|
+
* @param options Server installation options which may contain settings like pythonEnv or npmPath.
|
|
21
|
+
*/
|
|
22
|
+
private _resolveConfigMacros;
|
|
23
|
+
/**
|
|
24
|
+
* Handle NPX commands for Windows platform
|
|
25
|
+
*/
|
|
26
|
+
protected handleWindowsNpx(config: any): Promise<any>;
|
|
27
|
+
/**
|
|
28
|
+
* Initialize settings object with client-specific structure
|
|
29
|
+
* Override in child classes to provide custom initialization
|
|
30
|
+
*/
|
|
31
|
+
protected initializeSettings(settings: any): void;
|
|
32
|
+
/**
|
|
33
|
+
* Handle stdio mode configuration
|
|
34
|
+
* Override in child classes to provide custom stdio configuration
|
|
35
|
+
*/
|
|
36
|
+
protected handleStdioMode(settings: any, serverName: string, finalConfig: any): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Handle SSE mode configuration
|
|
39
|
+
* Override in child classes to provide custom SSE configuration
|
|
40
|
+
*/
|
|
41
|
+
protected handleSseMode(settings: any, serverName: string, installConfig: any): void;
|
|
42
|
+
/**
|
|
43
|
+
* Get the NPM path on Windows
|
|
44
|
+
*/
|
|
45
|
+
private getNpmPath;
|
|
46
|
+
/**
|
|
47
|
+
* Abstract methods that must be implemented by client-specific installers
|
|
48
|
+
*/
|
|
49
|
+
abstract install(serverConfig: McpConfig, options: ServerInstallOptions): Promise<OperationStatus>;
|
|
50
|
+
abstract setupClientSettings(settingPath: string, serverName: string, installConfig: any): Promise<void>;
|
|
51
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { Logger } from '../../../utils/logger.js';
|
|
2
|
+
import { exec } from 'child_process';
|
|
3
|
+
import { promisify } from 'util';
|
|
4
|
+
import { MACRO_EXPRESSIONS, MacroResolverFunctions } from '../../../utils/macroExpressionUtils.js';
|
|
5
|
+
const execAsync = promisify(exec);
|
|
6
|
+
/**
|
|
7
|
+
* Base class for client installers with shared functionality
|
|
8
|
+
*/
|
|
9
|
+
export class BaseClientInstaller {
|
|
10
|
+
/**
|
|
11
|
+
* Generate a unique operation ID for tracking installations
|
|
12
|
+
*/
|
|
13
|
+
generateOperationId() {
|
|
14
|
+
return `install-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Set up installation configuration with environment variables and arguments
|
|
18
|
+
* Handles Python environment configuration if specified
|
|
19
|
+
*/
|
|
20
|
+
async setupInstallConfig(serverConfig, options) {
|
|
21
|
+
const finalConfig = { ...serverConfig.installation };
|
|
22
|
+
finalConfig.mode = serverConfig.mode;
|
|
23
|
+
// Handle command line arguments
|
|
24
|
+
if (options.args && options.args.length > 0) {
|
|
25
|
+
Logger.debug(`Using args from ServerInstallOptions: ${options.args.join(' ')}`);
|
|
26
|
+
finalConfig.args = options.args;
|
|
27
|
+
}
|
|
28
|
+
// Handle environment variables
|
|
29
|
+
const baseEnv = finalConfig.env || {};
|
|
30
|
+
const defaultEnv = {};
|
|
31
|
+
for (const [key, config] of Object.entries(baseEnv)) {
|
|
32
|
+
const envConfig = config;
|
|
33
|
+
if (envConfig.Default) {
|
|
34
|
+
defaultEnv[key] = envConfig.Default;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
finalConfig.env = { ...defaultEnv, ...(options.env || {}) };
|
|
38
|
+
// Handle macro expressions
|
|
39
|
+
await this._resolveConfigMacros(finalConfig, options);
|
|
40
|
+
Logger.debug(`Final installation config: ${JSON.stringify(finalConfig)}`);
|
|
41
|
+
return finalConfig;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolves and replaces known macro expressions (e.g., ${PYTHON_PACKAGE}, ${NPMPATH}, ${BROWSER_PATH})
|
|
45
|
+
* in the provided configuration object's 'args' and 'env' properties.
|
|
46
|
+
* This method directly mutates the finalConfig object.
|
|
47
|
+
* @param finalConfig The configuration object to modify.
|
|
48
|
+
* @param options Server installation options which may contain settings like pythonEnv or npmPath.
|
|
49
|
+
*/
|
|
50
|
+
async _resolveConfigMacros(finalConfig, options) {
|
|
51
|
+
for (const macro of Object.values(MACRO_EXPRESSIONS)) {
|
|
52
|
+
const isMacroInArgs = finalConfig.args?.some((arg) => typeof arg === 'string' && arg.includes(macro));
|
|
53
|
+
const isMacroInEnv = Object.values(finalConfig.env || {}).some(value => typeof value === 'string' && value.includes(macro));
|
|
54
|
+
if (!isMacroInArgs && !isMacroInEnv) {
|
|
55
|
+
Logger.debug(`Macro ${macro} not found in args or env, skipping resolution.`);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const resolver = MacroResolverFunctions[macro];
|
|
59
|
+
if (resolver) {
|
|
60
|
+
const resolvedValue = await resolver(finalConfig, options);
|
|
61
|
+
if (resolvedValue !== undefined) {
|
|
62
|
+
// Replace in args
|
|
63
|
+
if (finalConfig.args) {
|
|
64
|
+
const originalArgsString = finalConfig.args.join(' ');
|
|
65
|
+
finalConfig.args = finalConfig.args.map((arg) => typeof arg === 'string' && arg.includes(macro)
|
|
66
|
+
? arg.replace(new RegExp(macro.replace(/[${}]/g, '\\$&'), 'g'), resolvedValue)
|
|
67
|
+
: arg);
|
|
68
|
+
if (finalConfig.args.join(' ') !== originalArgsString) {
|
|
69
|
+
Logger.debug(`Args after ${macro} ('${resolvedValue}') replacement: ${finalConfig.args.join(' ')}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Replace in env
|
|
73
|
+
if (finalConfig.env) {
|
|
74
|
+
const originalEnvJson = JSON.stringify(finalConfig.env);
|
|
75
|
+
for (const key in finalConfig.env) {
|
|
76
|
+
if (typeof finalConfig.env[key] === 'string' && finalConfig.env[key].includes(macro)) {
|
|
77
|
+
finalConfig.env[key] = finalConfig.env[key].replace(new RegExp(macro.replace(/[${}]/g, '\\$&'), 'g'), resolvedValue);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (JSON.stringify(finalConfig.env) !== originalEnvJson) {
|
|
81
|
+
Logger.debug(`Env after ${macro} ('${resolvedValue}') replacement: ${JSON.stringify(finalConfig.env)}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
Logger.debug(`Could not resolve value for macro: ${macro}. It will not be replaced.`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Handle NPX commands for Windows platform
|
|
93
|
+
*/
|
|
94
|
+
async handleWindowsNpx(config) {
|
|
95
|
+
if (process.platform === 'win32' && config.command === 'npx') {
|
|
96
|
+
const npmPath = await this.getNpmPath();
|
|
97
|
+
return {
|
|
98
|
+
...config,
|
|
99
|
+
command: 'cmd',
|
|
100
|
+
args: ['/c', 'npx', ...config.args],
|
|
101
|
+
env: {
|
|
102
|
+
...config.env,
|
|
103
|
+
'APPDATA': npmPath
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return config;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Initialize settings object with client-specific structure
|
|
111
|
+
* Override in child classes to provide custom initialization
|
|
112
|
+
*/
|
|
113
|
+
initializeSettings(settings) {
|
|
114
|
+
if (!settings.mcpServers) {
|
|
115
|
+
settings.mcpServers = {};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Handle stdio mode configuration
|
|
120
|
+
* Override in child classes to provide custom stdio configuration
|
|
121
|
+
*/
|
|
122
|
+
async handleStdioMode(settings, serverName, finalConfig) {
|
|
123
|
+
// Convert backslashes to forward slashes in args
|
|
124
|
+
if (finalConfig.args) {
|
|
125
|
+
finalConfig.args = finalConfig.args.map((arg) => typeof arg === 'string' ? arg.replace(/\\/g, '/') : arg);
|
|
126
|
+
}
|
|
127
|
+
settings.mcpServers[serverName] = {
|
|
128
|
+
command: finalConfig.command,
|
|
129
|
+
args: finalConfig.args,
|
|
130
|
+
env: finalConfig.env,
|
|
131
|
+
autoApprove: [],
|
|
132
|
+
disabled: false,
|
|
133
|
+
alwaysAllow: []
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Handle SSE mode configuration
|
|
138
|
+
* Override in child classes to provide custom SSE configuration
|
|
139
|
+
*/
|
|
140
|
+
handleSseMode(settings, serverName, installConfig) {
|
|
141
|
+
settings.mcpServers[serverName] = {
|
|
142
|
+
type: 'sse',
|
|
143
|
+
url: installConfig.url
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get the NPM path on Windows
|
|
148
|
+
*/
|
|
149
|
+
async getNpmPath() {
|
|
150
|
+
try {
|
|
151
|
+
const { stdout } = await execAsync('powershell -Command "get-command npm | Select-Object -ExpandProperty Source"');
|
|
152
|
+
return stdout.trim().replace(/\\npm\.cmd$/, '');
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
Logger.error('Error getting npm path:', error);
|
|
156
|
+
return 'C:\\Program Files\\nodejs';
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=BaseClientInstaller.js.map
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { ServerOperationResult, ServerInstallOptions } from '../../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Main client installer class that orchestrates client installation process
|
|
4
|
+
* Handles requirements checking and delegates to specific client installers
|
|
5
|
+
*/
|
|
2
6
|
export declare class ClientInstaller {
|
|
3
7
|
private categoryName;
|
|
4
8
|
private serverName;
|
|
@@ -6,18 +10,22 @@ export declare class ClientInstaller {
|
|
|
6
10
|
private configProvider;
|
|
7
11
|
private operationStatuses;
|
|
8
12
|
constructor(categoryName: string, serverName: string, clients: string[]);
|
|
13
|
+
/**
|
|
14
|
+
* Generate a unique operation ID for tracking installations
|
|
15
|
+
*/
|
|
9
16
|
private generateOperationId;
|
|
10
|
-
private getNpmPath;
|
|
11
17
|
/**
|
|
12
|
-
* Check if
|
|
13
|
-
*
|
|
14
|
-
|
|
18
|
+
* Check if server requirements are ready
|
|
19
|
+
* Waits for requirements to be ready with timeout
|
|
20
|
+
*/
|
|
21
|
+
private checkRequirements;
|
|
22
|
+
/**
|
|
23
|
+
* Install client with requirements checking
|
|
15
24
|
*/
|
|
16
|
-
private isCommandAvailable;
|
|
17
25
|
private installClient;
|
|
18
26
|
private processInstallation;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Install all specified clients
|
|
29
|
+
*/
|
|
22
30
|
install(options: ServerInstallOptions): Promise<ServerOperationResult>;
|
|
23
31
|
}
|