imcp 0.0.1
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/.github/ISSUE_TEMPLATE/JitAccess.yml +28 -0
- package/.github/acl/access.yml +20 -0
- package/.github/compliance/inventory.yml +5 -0
- package/.github/policies/jit.yml +19 -0
- package/README.md +137 -0
- package/dist/cli/commands/install.d.ts +2 -0
- package/dist/cli/commands/install.js +105 -0
- package/dist/cli/commands/list.d.ts +2 -0
- package/dist/cli/commands/list.js +90 -0
- package/dist/cli/commands/pull.d.ts +2 -0
- package/dist/cli/commands/pull.js +17 -0
- package/dist/cli/commands/serve.d.ts +2 -0
- package/dist/cli/commands/serve.js +32 -0
- package/dist/cli/commands/start.d.ts +2 -0
- package/dist/cli/commands/start.js +32 -0
- package/dist/cli/commands/sync.d.ts +2 -0
- package/dist/cli/commands/sync.js +17 -0
- package/dist/cli/commands/uninstall.d.ts +2 -0
- package/dist/cli/commands/uninstall.js +39 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +114 -0
- package/dist/core/ConfigurationProvider.d.ts +31 -0
- package/dist/core/ConfigurationProvider.js +416 -0
- package/dist/core/InstallationService.d.ts +17 -0
- package/dist/core/InstallationService.js +144 -0
- package/dist/core/MCPManager.d.ts +17 -0
- package/dist/core/MCPManager.js +98 -0
- package/dist/core/RequirementService.d.ts +45 -0
- package/dist/core/RequirementService.js +123 -0
- package/dist/core/constants.d.ts +29 -0
- package/dist/core/constants.js +55 -0
- package/dist/core/installers/BaseInstaller.d.ts +73 -0
- package/dist/core/installers/BaseInstaller.js +247 -0
- package/dist/core/installers/ClientInstaller.d.ts +17 -0
- package/dist/core/installers/ClientInstaller.js +307 -0
- package/dist/core/installers/CommandInstaller.d.ts +36 -0
- package/dist/core/installers/CommandInstaller.js +170 -0
- package/dist/core/installers/GeneralInstaller.d.ts +32 -0
- package/dist/core/installers/GeneralInstaller.js +87 -0
- package/dist/core/installers/InstallerFactory.d.ts +52 -0
- package/dist/core/installers/InstallerFactory.js +95 -0
- package/dist/core/installers/NpmInstaller.d.ts +25 -0
- package/dist/core/installers/NpmInstaller.js +123 -0
- package/dist/core/installers/PipInstaller.d.ts +25 -0
- package/dist/core/installers/PipInstaller.js +114 -0
- package/dist/core/installers/RequirementInstaller.d.ts +32 -0
- package/dist/core/installers/RequirementInstaller.js +3 -0
- package/dist/core/installers/index.d.ts +6 -0
- package/dist/core/installers/index.js +7 -0
- package/dist/core/types.d.ts +152 -0
- package/dist/core/types.js +16 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +19 -0
- package/dist/services/InstallRequestValidator.d.ts +21 -0
- package/dist/services/InstallRequestValidator.js +99 -0
- package/dist/services/ServerService.d.ts +47 -0
- package/dist/services/ServerService.js +145 -0
- package/dist/utils/UpdateCheckTracker.d.ts +39 -0
- package/dist/utils/UpdateCheckTracker.js +80 -0
- package/dist/utils/clientUtils.d.ts +29 -0
- package/dist/utils/clientUtils.js +105 -0
- package/dist/utils/feedUtils.d.ts +5 -0
- package/dist/utils/feedUtils.js +29 -0
- package/dist/utils/githubAuth.d.ts +1 -0
- package/dist/utils/githubAuth.js +123 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.js +90 -0
- package/dist/utils/osUtils.d.ts +16 -0
- package/dist/utils/osUtils.js +235 -0
- package/dist/web/public/css/modal.css +250 -0
- package/dist/web/public/css/notifications.css +70 -0
- package/dist/web/public/index.html +157 -0
- package/dist/web/public/js/api.js +213 -0
- package/dist/web/public/js/modal.js +572 -0
- package/dist/web/public/js/notifications.js +99 -0
- package/dist/web/public/js/serverCategoryDetails.js +210 -0
- package/dist/web/public/js/serverCategoryList.js +82 -0
- package/dist/web/public/modal.html +61 -0
- package/dist/web/public/styles.css +155 -0
- package/dist/web/server.d.ts +5 -0
- package/dist/web/server.js +150 -0
- package/package.json +53 -0
- package/src/cli/commands/install.ts +140 -0
- package/src/cli/commands/list.ts +112 -0
- package/src/cli/commands/pull.ts +16 -0
- package/src/cli/commands/serve.ts +37 -0
- package/src/cli/commands/uninstall.ts +54 -0
- package/src/cli/index.ts +127 -0
- package/src/core/ConfigurationProvider.ts +489 -0
- package/src/core/InstallationService.ts +173 -0
- package/src/core/MCPManager.ts +134 -0
- package/src/core/RequirementService.ts +147 -0
- package/src/core/constants.ts +61 -0
- package/src/core/installers/BaseInstaller.ts +292 -0
- package/src/core/installers/ClientInstaller.ts +423 -0
- package/src/core/installers/CommandInstaller.ts +185 -0
- package/src/core/installers/GeneralInstaller.ts +89 -0
- package/src/core/installers/InstallerFactory.ts +109 -0
- package/src/core/installers/NpmInstaller.ts +128 -0
- package/src/core/installers/PipInstaller.ts +121 -0
- package/src/core/installers/RequirementInstaller.ts +38 -0
- package/src/core/installers/index.ts +9 -0
- package/src/core/types.ts +163 -0
- package/src/index.ts +44 -0
- package/src/services/InstallRequestValidator.ts +112 -0
- package/src/services/ServerService.ts +181 -0
- package/src/utils/UpdateCheckTracker.ts +86 -0
- package/src/utils/clientUtils.ts +112 -0
- package/src/utils/feedUtils.ts +31 -0
- package/src/utils/githubAuth.ts +142 -0
- package/src/utils/logger.ts +101 -0
- package/src/utils/osUtils.ts +250 -0
- package/src/web/public/css/modal.css +250 -0
- package/src/web/public/css/notifications.css +70 -0
- package/src/web/public/index.html +157 -0
- package/src/web/public/js/api.js +213 -0
- package/src/web/public/js/modal.js +572 -0
- package/src/web/public/js/notifications.js +99 -0
- package/src/web/public/js/serverCategoryDetails.js +210 -0
- package/src/web/public/js/serverCategoryList.js +82 -0
- package/src/web/public/modal.html +61 -0
- package/src/web/public/styles.css +155 -0
- package/src/web/server.ts +195 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Temporary administrator access request
|
|
2
|
+
description: Request for temporary repository administrator access to this repository, a.k.a Just-in-Time (JIT) access.
|
|
3
|
+
title: "JIT Request"
|
|
4
|
+
labels: ["jit"]
|
|
5
|
+
assignees:
|
|
6
|
+
- gimsvc_microsoft
|
|
7
|
+
-
|
|
8
|
+
body:
|
|
9
|
+
- type: markdown
|
|
10
|
+
attributes:
|
|
11
|
+
value: |
|
|
12
|
+
:closed_lock_with_key: Permanent repository administrator access is not allowed as per Microsoft security policy. You can use this form to request for temporary administrator access to this repository.
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: justification
|
|
15
|
+
attributes:
|
|
16
|
+
label: Justification
|
|
17
|
+
description: Describe the actions that you will perform with your temporary administrator access.
|
|
18
|
+
placeholder: I need to create secrets.
|
|
19
|
+
validations:
|
|
20
|
+
required: true
|
|
21
|
+
- type: dropdown
|
|
22
|
+
id: duration
|
|
23
|
+
attributes:
|
|
24
|
+
label: Duration (hours)
|
|
25
|
+
description: How long do you need access for? The duration you select is in hours.
|
|
26
|
+
options:
|
|
27
|
+
- 1
|
|
28
|
+
- 2
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Documentation for ACL policy: https://aka.ms/gim/docs/policy/acl
|
|
2
|
+
|
|
3
|
+
name: Access control list
|
|
4
|
+
description: List of teams and their permission levels
|
|
5
|
+
resource: repository
|
|
6
|
+
where:
|
|
7
|
+
configuration:
|
|
8
|
+
manageAccess:
|
|
9
|
+
- team: aicodervteam
|
|
10
|
+
role: Triage
|
|
11
|
+
- member: hod
|
|
12
|
+
role: Maintain
|
|
13
|
+
- member: penwa
|
|
14
|
+
role: Maintain
|
|
15
|
+
- member: anthu
|
|
16
|
+
role: Maintain
|
|
17
|
+
- member: enbaowang
|
|
18
|
+
role: Maintain
|
|
19
|
+
- member: xinli7
|
|
20
|
+
role: Maintain
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Documentation for JIT policy: https://aka.ms/gim/docs/policy/jit
|
|
2
|
+
|
|
3
|
+
# metadata
|
|
4
|
+
id: id
|
|
5
|
+
name: JIT_Access
|
|
6
|
+
description: Policy for admin JIT for repos in this org
|
|
7
|
+
|
|
8
|
+
# filters
|
|
9
|
+
resource: repository
|
|
10
|
+
|
|
11
|
+
# primitive configuration
|
|
12
|
+
configuration:
|
|
13
|
+
jitAccess:
|
|
14
|
+
enabled: true
|
|
15
|
+
maxHours: 2
|
|
16
|
+
approvers:
|
|
17
|
+
role: Maintain
|
|
18
|
+
requestors:
|
|
19
|
+
role: Write
|
package/README.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# IMCP
|
|
2
|
+
|
|
3
|
+
IMCP (Install Model Context Protocol) is a unified MCP management project that provides the ability to list, install, and manage MCP servers based on unified feeds.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
IMCP is a command-line tool that simplifies the management of Model Context Protocol (MCP) servers. It allows you to:
|
|
8
|
+
|
|
9
|
+
- Discover available MCP servers from configurable feeds
|
|
10
|
+
- Install servers with specific configurations
|
|
11
|
+
- Manage server installations
|
|
12
|
+
- Run a local web interface to manage your MCP servers
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g imcp
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Commands
|
|
21
|
+
|
|
22
|
+
### Global Options
|
|
23
|
+
|
|
24
|
+
- `--verbose`: Show detailed logs for all commands
|
|
25
|
+
|
|
26
|
+
### serve
|
|
27
|
+
|
|
28
|
+
Starts a local web interface for managing MCP servers.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
imcp serve [options]
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Options:
|
|
35
|
+
- `-p, --port <port>`: Port to run the server on (default: 3000)
|
|
36
|
+
|
|
37
|
+
Example:
|
|
38
|
+
```bash
|
|
39
|
+
# Start the web interface on port 8080
|
|
40
|
+
imcp serve --port 8080
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### list
|
|
44
|
+
|
|
45
|
+
Lists all available MCP servers from configured feeds.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
imcp list [options]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Options:
|
|
52
|
+
- `--pull`: Sync with remote feeds before listing
|
|
53
|
+
|
|
54
|
+
Example:
|
|
55
|
+
```bash
|
|
56
|
+
# List servers after syncing with remote feeds
|
|
57
|
+
imcp list --pull
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### install
|
|
61
|
+
|
|
62
|
+
Installs specific MCP servers.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
imcp install [options]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Options:
|
|
69
|
+
- `--category <category>`: Server category (required)
|
|
70
|
+
- `--name <name>`: Server name to install (required)
|
|
71
|
+
- `--force`: Force installation even if server already exists
|
|
72
|
+
- `--clients <clients>`: Target clients (semicolon separated). Supported values: Cline, MSRooCode, GithubCopilot
|
|
73
|
+
- `--envs <envs>`: Environment variables (semicolon separated key=value pairs)
|
|
74
|
+
|
|
75
|
+
Examples:
|
|
76
|
+
```bash
|
|
77
|
+
# Install a server
|
|
78
|
+
imcp install --category ai-coder-tools --name github-tools
|
|
79
|
+
|
|
80
|
+
# Install with specific client targets
|
|
81
|
+
imcp install --category ai-coder-tools --name github-tools --clients "MSRooCode;GithubCopilot"
|
|
82
|
+
|
|
83
|
+
# Install with environment variables
|
|
84
|
+
imcp install --category ai-coder-tools --name github-tools --envs "GITHUB_TOKEN=abc123;API_KEY=xyz789"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### pull
|
|
88
|
+
|
|
89
|
+
Pulls MCP server configurations from remote feed sources to update local feeds.
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
imcp pull
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Example:
|
|
96
|
+
```bash
|
|
97
|
+
# Update local feeds with the latest server configurations
|
|
98
|
+
imcp pull
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Development
|
|
102
|
+
|
|
103
|
+
### Prerequisites
|
|
104
|
+
|
|
105
|
+
- Node.js
|
|
106
|
+
- npm
|
|
107
|
+
|
|
108
|
+
### Setup
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# Clone the repository
|
|
112
|
+
git clone <repository-url>
|
|
113
|
+
cd imcp
|
|
114
|
+
|
|
115
|
+
# Install dependencies
|
|
116
|
+
npm install
|
|
117
|
+
|
|
118
|
+
# Build the project
|
|
119
|
+
npm run build
|
|
120
|
+
|
|
121
|
+
# Run in development mode
|
|
122
|
+
npm run dev
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Scripts
|
|
126
|
+
|
|
127
|
+
- `npm run build`: Builds the project and copies necessary files
|
|
128
|
+
- `npm run dev`: Runs TypeScript in watch mode
|
|
129
|
+
- `npm run start`: Starts the web server
|
|
130
|
+
- `npm run dev:server`: Starts the development server with hot reloading
|
|
131
|
+
- `npm run test`: Runs tests
|
|
132
|
+
- `npm run lint`: Lints the source code
|
|
133
|
+
- `npm run format`: Formats the source code
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
MIT
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { serverService } from '../../services/ServerService.js';
|
|
3
|
+
import { Logger } from '../../utils/logger.js';
|
|
4
|
+
import { hasLocalFeeds } from '../../utils/feedUtils.js';
|
|
5
|
+
import { SUPPORTED_CLIENT_NAMES } from '../../core/constants.js';
|
|
6
|
+
export function createInstallCommand() {
|
|
7
|
+
return new Command('install')
|
|
8
|
+
.description('Install specific MCP servers')
|
|
9
|
+
.addHelpText('after', `
|
|
10
|
+
Examples:
|
|
11
|
+
# Install a server
|
|
12
|
+
$ imcp install --category ai-coder-tools --name github-tools
|
|
13
|
+
|
|
14
|
+
# Install with specific client targets (semicolon separated)
|
|
15
|
+
$ imcp install --category ai-coder-tools --name github-tools --clients "MSRooCode;GithubCopilot"
|
|
16
|
+
|
|
17
|
+
# Install with environment variables
|
|
18
|
+
$ imcp install --category ai-coder-tools --name github-tools --envs "GITHUB_TOKEN=abc123;API_KEY=xyz789"
|
|
19
|
+
`)
|
|
20
|
+
.requiredOption('--category <category>', 'Server category')
|
|
21
|
+
.requiredOption('--name <name>', 'Server name to install')
|
|
22
|
+
.option('--force', 'Force installation even if server already exists', false)
|
|
23
|
+
.option('--clients <clients>', 'Target clients (semicolon separated). Supported values: Cline, MSRooCode, GithubCopilot. If not specified, installs for all clients')
|
|
24
|
+
.option('--envs <envs>', 'Environment variables (semicolon separated key=value pairs)')
|
|
25
|
+
.action(async (options) => {
|
|
26
|
+
try {
|
|
27
|
+
// Check for local feeds existence at the start
|
|
28
|
+
const feedsExist = await hasLocalFeeds();
|
|
29
|
+
if (!feedsExist) {
|
|
30
|
+
Logger.log('Local feeds not found, syncing from remote...');
|
|
31
|
+
await serverService.syncFeeds();
|
|
32
|
+
}
|
|
33
|
+
const { category, name, verbose, force, clients, envs } = options;
|
|
34
|
+
Logger.debug(`Install options: ${JSON.stringify({ category, name, force, verbose, clients, envs })}`);
|
|
35
|
+
const serverName = name.trim();
|
|
36
|
+
Logger.debug(`Server name: ${serverName}`);
|
|
37
|
+
if (!await serverService.validateServerName(category, serverName)) {
|
|
38
|
+
Logger.error('Invalid server name or category provided', {
|
|
39
|
+
category,
|
|
40
|
+
serverName
|
|
41
|
+
});
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
// Parse and validate clients
|
|
45
|
+
const parsedClients = clients ? clients.split(';')
|
|
46
|
+
.map((c) => c.trim())
|
|
47
|
+
.filter(Boolean)
|
|
48
|
+
.map((c) => {
|
|
49
|
+
const clientName = c.toLowerCase();
|
|
50
|
+
const validClient = SUPPORTED_CLIENT_NAMES.find((name) => name.toLowerCase() === clientName);
|
|
51
|
+
if (!validClient) {
|
|
52
|
+
Logger.error(`Invalid client name: ${c}`);
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return validClient;
|
|
56
|
+
})
|
|
57
|
+
.filter((c) => c !== null) : undefined;
|
|
58
|
+
if (parsedClients && parsedClients.length > 0) {
|
|
59
|
+
Logger.debug(`Target clients: ${JSON.stringify(parsedClients)}`);
|
|
60
|
+
}
|
|
61
|
+
// Parse environment variables
|
|
62
|
+
const parsedEnvs = {};
|
|
63
|
+
if (envs) {
|
|
64
|
+
const pairs = envs.split(';');
|
|
65
|
+
for (const pair of pairs) {
|
|
66
|
+
const [key, value] = pair.split('=').map((s) => s.trim());
|
|
67
|
+
if (key && value) {
|
|
68
|
+
parsedEnvs[key] = value;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
Logger.error(`Invalid environment variable format: ${pair}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (Object.keys(parsedEnvs).length > 0) {
|
|
76
|
+
Logger.debug(`Environment variables: ${JSON.stringify(parsedEnvs)}`);
|
|
77
|
+
}
|
|
78
|
+
Logger.log(`Installing server: ${serverName}`);
|
|
79
|
+
const installOptions = {
|
|
80
|
+
force: options.force,
|
|
81
|
+
...(parsedClients?.length && { targetClients: parsedClients }),
|
|
82
|
+
...(Object.keys(parsedEnvs).length > 0 && { env: parsedEnvs })
|
|
83
|
+
};
|
|
84
|
+
const results = [await serverService.installMcpServer(category, serverName, installOptions)];
|
|
85
|
+
const { success, messages } = serverService.formatOperationResults(results);
|
|
86
|
+
messages.forEach((message) => {
|
|
87
|
+
if (success) {
|
|
88
|
+
Logger.log(`✓ ${message}`);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
Logger.error(`✗ ${message}`);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
if (!success) {
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
100
|
+
Logger.error('Installation failed:', message);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { LOCAL_FEEDS_DIR } from '../../core/constants.js';
|
|
5
|
+
import { mcpManager } from '../../core/MCPManager.js';
|
|
6
|
+
import { Logger } from '../../utils/logger.js';
|
|
7
|
+
export function createListCommand() {
|
|
8
|
+
return new Command('list')
|
|
9
|
+
.description('List all available MCP servers from feeds')
|
|
10
|
+
.option('--pull', 'Sync with remote feeds before listing')
|
|
11
|
+
.action(async (options) => {
|
|
12
|
+
try {
|
|
13
|
+
Logger.debug({
|
|
14
|
+
action: 'list_command_started',
|
|
15
|
+
options
|
|
16
|
+
});
|
|
17
|
+
// If sync flag is provided, try to sync first
|
|
18
|
+
if (options.pull) {
|
|
19
|
+
try {
|
|
20
|
+
await mcpManager.syncFeeds();
|
|
21
|
+
}
|
|
22
|
+
catch (syncError) {
|
|
23
|
+
Logger.error('Failed to sync feeds, falling back to local feeds', syncError);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
Logger.debug({
|
|
27
|
+
action: 'ensuring_feeds_directory',
|
|
28
|
+
path: LOCAL_FEEDS_DIR
|
|
29
|
+
});
|
|
30
|
+
// Ensure feeds directory exists
|
|
31
|
+
await fs.mkdir(LOCAL_FEEDS_DIR, { recursive: true });
|
|
32
|
+
// Read all json files from feeds directory
|
|
33
|
+
Logger.debug('Reading feed files from directory...');
|
|
34
|
+
const files = await fs.readdir(LOCAL_FEEDS_DIR);
|
|
35
|
+
const jsonFiles = files.filter(file => file.endsWith('.json'));
|
|
36
|
+
Logger.debug({
|
|
37
|
+
action: 'found_feed_files',
|
|
38
|
+
count: jsonFiles.length,
|
|
39
|
+
files: jsonFiles
|
|
40
|
+
});
|
|
41
|
+
const feeds = [];
|
|
42
|
+
// Process each json file
|
|
43
|
+
for (const file of jsonFiles) {
|
|
44
|
+
Logger.debug(`Processing feed file: ${file}`);
|
|
45
|
+
try {
|
|
46
|
+
const filePath = path.join(LOCAL_FEEDS_DIR, file);
|
|
47
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
48
|
+
const feedConfig = JSON.parse(content);
|
|
49
|
+
Logger.debug({
|
|
50
|
+
action: 'processing_feed',
|
|
51
|
+
file,
|
|
52
|
+
feedName: feedConfig.name,
|
|
53
|
+
serverCount: feedConfig.mcpServers?.length ?? 0
|
|
54
|
+
});
|
|
55
|
+
// Extract only needed information
|
|
56
|
+
const simplifiedFeed = {
|
|
57
|
+
name: feedConfig.name,
|
|
58
|
+
displayName: feedConfig.displayName,
|
|
59
|
+
description: feedConfig.description,
|
|
60
|
+
mcpServers: feedConfig.mcpServers.map((server) => ({
|
|
61
|
+
name: server.name,
|
|
62
|
+
description: server.description
|
|
63
|
+
}))
|
|
64
|
+
};
|
|
65
|
+
feeds.push(simplifiedFeed);
|
|
66
|
+
Logger.debug(`Successfully processed feed: ${feedConfig.name}`);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
Logger.error(`Failed to process feed file: ${file}`, error);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (feeds.length === 0) {
|
|
73
|
+
Logger.log('No feeds found.');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
Logger.debug({
|
|
77
|
+
action: 'completed_processing',
|
|
78
|
+
totalFeeds: feeds.length,
|
|
79
|
+
totalServers: feeds.reduce((acc, feed) => acc + feed.mcpServers.length, 0)
|
|
80
|
+
});
|
|
81
|
+
// Output as formatted JSON
|
|
82
|
+
console.log(JSON.stringify(feeds, null, 2));
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
Logger.error('Failed to list servers', error);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { serverService } from '../../services/ServerService.js';
|
|
3
|
+
export function createPullCommand() {
|
|
4
|
+
return new Command('pull')
|
|
5
|
+
.description('Pull MCP server configurations from remote feed source')
|
|
6
|
+
.action(async () => {
|
|
7
|
+
try {
|
|
8
|
+
await serverService.syncFeeds();
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
12
|
+
console.error('Error syncing configurations:', message);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=pull.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { startWebServer } from '../../web/server.js';
|
|
3
|
+
import { mcpManager } from '../../core/MCPManager.js';
|
|
4
|
+
export function createServeCommand() {
|
|
5
|
+
return new Command('serve')
|
|
6
|
+
.description('Serve local web interface')
|
|
7
|
+
.option('-p, --port <port>', 'Port to run the server on', '3000')
|
|
8
|
+
.action(async (options) => {
|
|
9
|
+
try {
|
|
10
|
+
// Sync feeds before start the local UI
|
|
11
|
+
await mcpManager.syncFeeds();
|
|
12
|
+
// Ensure MCP manager is initialized before starting the web server
|
|
13
|
+
await mcpManager.initialize();
|
|
14
|
+
const port = parseInt(options.port, 10);
|
|
15
|
+
if (isNaN(port) || port < 1 || port > 65535) {
|
|
16
|
+
throw new Error('Invalid port number');
|
|
17
|
+
}
|
|
18
|
+
await startWebServer(port);
|
|
19
|
+
// The server is running, keep the process alive
|
|
20
|
+
process.on('SIGINT', () => {
|
|
21
|
+
console.log('\nShutting down server...');
|
|
22
|
+
process.exit(0);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
27
|
+
console.error('Failed to start web server:', message);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { startWebServer } from '../../web/server.js';
|
|
3
|
+
import { mcpManager } from '../../core/MCPManager.js';
|
|
4
|
+
export function createStartCommand() {
|
|
5
|
+
return new Command('start')
|
|
6
|
+
.description('Start local web interface')
|
|
7
|
+
.option('-p, --port <port>', 'Port to run the server on', '3000')
|
|
8
|
+
.action(async (options) => {
|
|
9
|
+
try {
|
|
10
|
+
// Sync feeds before start the local UI
|
|
11
|
+
await mcpManager.syncFeeds();
|
|
12
|
+
// Ensure MCP manager is initialized before starting the web server
|
|
13
|
+
await mcpManager.initialize();
|
|
14
|
+
const port = parseInt(options.port, 10);
|
|
15
|
+
if (isNaN(port) || port < 1 || port > 65535) {
|
|
16
|
+
throw new Error('Invalid port number');
|
|
17
|
+
}
|
|
18
|
+
await startWebServer(port);
|
|
19
|
+
// The server is running, keep the process alive
|
|
20
|
+
process.on('SIGINT', () => {
|
|
21
|
+
console.log('\nShutting down server...');
|
|
22
|
+
process.exit(0);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
27
|
+
console.error('Failed to start web server:', message);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { serverService } from '../../services/ServerService.js';
|
|
3
|
+
export function createSyncCommand() {
|
|
4
|
+
return new Command('sync')
|
|
5
|
+
.description('Sync MCP server configurations from remote feed source')
|
|
6
|
+
.action(async () => {
|
|
7
|
+
try {
|
|
8
|
+
await serverService.syncFeeds();
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
12
|
+
console.error('Error syncing configurations:', message);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { serverService } from '../../services/ServerService.js';
|
|
3
|
+
export function createUninstallCommand() {
|
|
4
|
+
return new Command('uninstall')
|
|
5
|
+
.description('Uninstall specific MCP servers')
|
|
6
|
+
.requiredOption('--category <category>', '--names <names>', 'Server names (semicolon separated)')
|
|
7
|
+
.option('--remove-data', 'Remove all associated data', false)
|
|
8
|
+
.action(async (options) => {
|
|
9
|
+
try {
|
|
10
|
+
const serverNames = options.names.split(';').map((name) => name.trim());
|
|
11
|
+
if (!serverService.validateServerName(options.category, serverNames)) {
|
|
12
|
+
console.error('Invalid server names provided');
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
console.log(`Uninstalling servers: ${serverNames.join(', ')}`);
|
|
16
|
+
const results = await Promise.all(serverNames.map((serverName) => serverService.uninstallMcpServer(options.category, serverName, {
|
|
17
|
+
removeData: options.removeData,
|
|
18
|
+
})));
|
|
19
|
+
const { success, messages } = serverService.formatOperationResults(results);
|
|
20
|
+
messages.forEach(message => {
|
|
21
|
+
if (success) {
|
|
22
|
+
console.log(`✓ ${message}`);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
console.error(`✗ ${message}`);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
if (!success) {
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
34
|
+
console.error('Uninstallation failed:', message);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=uninstall.js.map
|