imcp 0.0.13 → 0.0.14
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/installers/clients/ClientInstaller.js +58 -40
- package/dist/core/onboard/FeedOnboardService.d.ts +35 -0
- package/dist/core/onboard/FeedOnboardService.js +137 -0
- package/dist/core/types.d.ts +2 -1
- package/dist/core/validators/FeedValidator.d.ts +13 -0
- package/dist/core/validators/FeedValidator.js +27 -0
- package/dist/web/contract/serverContract.d.ts +64 -0
- package/dist/web/contract/serverContract.js +2 -0
- package/dist/web/public/css/onboard.css +44 -0
- package/dist/web/public/index.html +17 -13
- package/dist/web/public/js/modal/index.js +58 -0
- package/dist/web/public/js/modal/installHandler.js +227 -0
- package/dist/web/public/js/modal/installModal.js +163 -0
- package/dist/web/public/js/modal/installation.js +281 -0
- package/dist/web/public/js/modal/loadingModal.js +52 -0
- package/dist/web/public/js/modal/loadingUI.js +74 -0
- package/dist/web/public/js/modal/messageQueue.js +112 -0
- package/dist/web/public/js/modal/modalSetup.js +512 -0
- package/dist/web/public/js/modal/modalUI.js +214 -0
- package/dist/web/public/js/modal/modalUtils.js +49 -0
- package/dist/web/public/js/modal/version.js +20 -0
- package/dist/web/public/js/modal/versionUtils.js +20 -0
- package/dist/web/public/js/modal.js +25 -1041
- package/dist/web/public/js/onboard/formProcessor.js +309 -0
- package/dist/web/public/js/onboard/index.js +131 -0
- package/dist/web/public/js/onboard/state.js +32 -0
- package/dist/web/public/js/onboard/templates.js +375 -0
- package/dist/web/public/js/onboard/uiHandlers.js +196 -0
- package/dist/web/public/js/serverCategoryDetails.js +43 -17
- package/dist/web/public/onboard.html +150 -0
- package/package.json +1 -1
- package/src/core/installers/clients/ClientInstaller.ts +66 -49
- package/src/core/types.ts +2 -1
- package/src/web/public/index.html +17 -13
- package/src/web/public/js/modal/index.js +58 -0
- package/src/web/public/js/modal/installModal.js +163 -0
- package/src/web/public/js/modal/installation.js +281 -0
- package/src/web/public/js/modal/loadingModal.js +52 -0
- package/src/web/public/js/modal/messageQueue.js +112 -0
- package/src/web/public/js/modal/modalSetup.js +512 -0
- package/src/web/public/js/modal/modalUtils.js +49 -0
- package/src/web/public/js/modal/versionUtils.js +20 -0
- package/src/web/public/js/modal.js +25 -1041
- package/src/web/public/js/serverCategoryDetails.js +43 -17
|
@@ -6,6 +6,8 @@ import { DetailsWidget } from './detailsWidget.js';
|
|
|
6
6
|
const REFRESH_INTERVAL = 2000; // 2 seconds
|
|
7
7
|
let refreshTimer = null;
|
|
8
8
|
let activeDetailsWidget = null;
|
|
9
|
+
const MAX_RETRIES = 3;
|
|
10
|
+
const RETRY_DELAY = 1000;
|
|
9
11
|
|
|
10
12
|
// Start refresh timer for installation status
|
|
11
13
|
function startRefreshTimer(serverName) {
|
|
@@ -37,16 +39,28 @@ function startRefreshTimer(serverName) {
|
|
|
37
39
|
}, REFRESH_INTERVAL);
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
// Show server details
|
|
41
|
-
async function showServerDetails(serverName) {
|
|
42
|
+
// Show server details with retry mechanism
|
|
43
|
+
async function showServerDetails(serverName, retryCount = 0) {
|
|
42
44
|
console.log("Showing details for:", serverName);
|
|
43
45
|
try {
|
|
44
46
|
localStorage.setItem('lastSelectedCategory', serverName);
|
|
47
|
+
|
|
48
|
+
// If server data is not available, attempt to fetch it
|
|
49
|
+
if (allServerCategoriesData.length === 0) {
|
|
50
|
+
await fetchServerCategories();
|
|
51
|
+
}
|
|
52
|
+
|
|
45
53
|
const server = allServerCategoriesData.find(s => s.name === serverName);
|
|
46
54
|
const detailsDiv = document.getElementById('serverCategoryDetails');
|
|
47
55
|
|
|
48
56
|
if (!server) {
|
|
49
|
-
|
|
57
|
+
if (retryCount < MAX_RETRIES) {
|
|
58
|
+
console.log(`Server data not found, retrying (${retryCount + 1}/${MAX_RETRIES})...`);
|
|
59
|
+
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY));
|
|
60
|
+
await fetchServerCategories(); // Refresh the data
|
|
61
|
+
return showServerDetails(serverName, retryCount + 1);
|
|
62
|
+
}
|
|
63
|
+
throw new Error('Server data not found after retries');
|
|
50
64
|
}
|
|
51
65
|
|
|
52
66
|
detailsDiv.innerHTML = `
|
|
@@ -168,12 +182,24 @@ async function renderServersList(serverCategory) {
|
|
|
168
182
|
<div class="server-item-header">
|
|
169
183
|
<div class="flex items-center">
|
|
170
184
|
<h5 class="font-semibold text-gray-800">${mcpServer.displayName || mcpServer.name}</h5>
|
|
171
|
-
${mcpServer.repository || serverCategory.feedConfiguration?.repository ?
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
185
|
+
${mcpServer.repository || serverCategory.feedConfiguration?.repository ? (() => {
|
|
186
|
+
const repoUrl = mcpServer.repository || serverCategory.feedConfiguration?.repository;
|
|
187
|
+
const isGithub = repoUrl.toLowerCase().includes('github.com');
|
|
188
|
+
return `
|
|
189
|
+
<a href="${repoUrl}" target="_blank" class="ml-2 flex items-center">
|
|
190
|
+
<span class="text-xs px-2 py-1 bg-gray-100 rounded-md flex items-center text-gray-700 hover:bg-gray-200 transition-colors duration-200">
|
|
191
|
+
${isGithub ? `
|
|
192
|
+
<svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
193
|
+
<path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd"/>
|
|
194
|
+
</svg>
|
|
195
|
+
GitHub` : `
|
|
196
|
+
<svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
197
|
+
<path d="M21.721 12.752a9.711 9.711 0 00-.945-5.003 1.743 1.743 0 01-1.339-1.647c0-.522.236-1.01.62-1.341a9.707 9.707 0 00-3.62-2.087 1.744 1.744 0 01-2.113-1.334A9.721 9.721 0 0012 1.016 9.721 9.721 0 009.676 1.3 1.744 1.744 0 017.562 2.634a9.707 9.707 0 00-3.62 2.087 1.744 1.744 0 00-.048 2.32 9.711 9.711 0 00-.945 5.003 9.712 9.712 0 00.945 5.003 1.744 1.744 0 01.048 2.32 9.707 9.707 0 003.62 2.087 1.744 1.744 0 012.114 1.334A9.721 9.721 0 0012 22.982a9.721 9.721 0 002.324-.284 1.744 1.744 0 012.114-1.334 9.707 9.707 0 003.62-2.087 1.744 1.744 0 01.048-2.32 9.711 9.711 0 00.945-5.003z"/>
|
|
198
|
+
</svg>
|
|
199
|
+
Website`}
|
|
200
|
+
</span>
|
|
201
|
+
</a>`
|
|
202
|
+
})() : ''}
|
|
177
203
|
</div>
|
|
178
204
|
<p class="text-sm text-gray-600 mb-1">${mcpServer.description || 'No description'}</p>
|
|
179
205
|
</div>
|
|
@@ -181,20 +207,20 @@ async function renderServersList(serverCategory) {
|
|
|
181
207
|
<span class="text-xs font-semibold mb-2">Client Status:</span>
|
|
182
208
|
<div class="flex flex-wrap gap-2">
|
|
183
209
|
${availableTargets.map(client => {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
210
|
+
const status = (serverCategory.installationStatus?.serversStatus[mcpServer.name]?.installedStatus || {})[client];
|
|
211
|
+
const isInstalled = status?.status === 'completed';
|
|
212
|
+
return `
|
|
187
213
|
<span class="text-xs flex items-center ${isInstalled ? 'text-green-600 bg-green-50' : 'text-gray-600 bg-gray-50'} px-3 py-1 rounded-full shadow">
|
|
188
214
|
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
|
189
215
|
${isInstalled
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
216
|
+
? '<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>'
|
|
217
|
+
: '<path d="M7 3.5A1.5 1.5 0 018.5 2h3.879a1.5 1.5 0 011.06.44l3.122 3.12A1.5 1.5 0 0117 6.622V12.5a1.5 1.5 0 01-1.5 1.5h-1v-3.379a1.5 1.5 0 00-.44-1.06L10.94 6.44A1.5 1.5 0 009.879 6H7V3.5z M6 6h2.879A1.5 1.5 0 0110 7.5v1.379a1.5 1.5 0 01-.44 1.06L6.44 13.06A1.5 1.5 0 015.379 13H4.5A1.5 1.5 0 013 11.5V7.5A1.5 1.5 0 014.5 6H6z"></path>'
|
|
218
|
+
}
|
|
193
219
|
</svg>
|
|
194
220
|
${client}
|
|
195
221
|
</span>
|
|
196
222
|
`;
|
|
197
|
-
|
|
223
|
+
}).join('')}
|
|
198
224
|
</div>
|
|
199
225
|
</div>
|
|
200
226
|
<div class="action-buttons">
|
|
@@ -271,4 +297,4 @@ window.showServerDetails = async function (serverName) {
|
|
|
271
297
|
}
|
|
272
298
|
};
|
|
273
299
|
|
|
274
|
-
export { showServerDetails };
|
|
300
|
+
export { showServerDetails };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Onboard MCP Category - IMCP</title>
|
|
7
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
+
<link href="https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
|
|
9
|
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
10
|
+
<link rel="stylesheet" href="styles.css">
|
|
11
|
+
<link rel="stylesheet" href="css/onboard.css">
|
|
12
|
+
<link rel="stylesheet" href="css/modal.css">
|
|
13
|
+
<link rel="stylesheet" href="css/notifications.css">
|
|
14
|
+
</head>
|
|
15
|
+
<body class="bg-gray-50 min-h-screen">
|
|
16
|
+
<div class="container mx-auto px-4 py-6">
|
|
17
|
+
<div class="flex items-center justify-between mb-8">
|
|
18
|
+
<h1 class="text-3xl font-bold text-gray-900 flex items-center">
|
|
19
|
+
<i class='bx bx-server mr-3 text-blue-600'></i>
|
|
20
|
+
Onboard MCP Category
|
|
21
|
+
</h1>
|
|
22
|
+
<a href="index.html" class="text-gray-600 hover:text-gray-900 flex items-center">
|
|
23
|
+
<i class='bx bx-arrow-back mr-2'></i>
|
|
24
|
+
Back to Servers
|
|
25
|
+
</a>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-8 max-w-4xl mx-auto">
|
|
29
|
+
<!-- Tab Navigation -->
|
|
30
|
+
<div class="mb-6 border-b border-gray-200">
|
|
31
|
+
<nav class="flex space-x-8" aria-label="Tabs">
|
|
32
|
+
<button id="tab-create-category" class="py-2 px-4 text-blue-600 border-b-2 border-blue-600 font-semibold focus:outline-none" type="button">
|
|
33
|
+
Create New Server Category
|
|
34
|
+
</button>
|
|
35
|
+
<button id="tab-create-server" class="py-2 px-4 text-gray-600 border-b-2 border-transparent hover:text-blue-600 hover:border-blue-600 font-semibold focus:outline-none" type="button">
|
|
36
|
+
Create New Server in Existing Category
|
|
37
|
+
</button>
|
|
38
|
+
</nav>
|
|
39
|
+
</div>
|
|
40
|
+
<!-- Tab Panels -->
|
|
41
|
+
<div id="panel-create-category">
|
|
42
|
+
<form id="onboardForm" class="space-y-8">
|
|
43
|
+
<!-- Basic Information -->
|
|
44
|
+
<div class="space-y-4">
|
|
45
|
+
<h2 class="text-xl font-semibold text-gray-900 flex items-center mb-4">
|
|
46
|
+
<i class='bx bx-info-circle mr-2 text-blue-600'></i>
|
|
47
|
+
Basic Information
|
|
48
|
+
</h2>
|
|
49
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
50
|
+
<div>
|
|
51
|
+
<label class="block text-sm font-medium text-gray-700 mb-1">Category Name*</label>
|
|
52
|
+
<input type="text" name="name" required
|
|
53
|
+
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
54
|
+
placeholder="e.g., ai-coder-tools">
|
|
55
|
+
</div>
|
|
56
|
+
<div>
|
|
57
|
+
<label class="block text-sm font-medium text-gray-700 mb-1">Display Name*</label>
|
|
58
|
+
<input type="text" name="displayName" required
|
|
59
|
+
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
60
|
+
placeholder="e.g., Coder Tools">
|
|
61
|
+
</div>
|
|
62
|
+
<div class="md:col-span-2">
|
|
63
|
+
<label class="block text-sm font-medium text-gray-700 mb-1">Description</label>
|
|
64
|
+
<textarea name="description" rows="3"
|
|
65
|
+
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
66
|
+
placeholder="Describe the purpose and capabilities of this server category"></textarea>
|
|
67
|
+
</div>
|
|
68
|
+
<div class="md:col-span-2">
|
|
69
|
+
<label class="block text-sm font-medium text-gray-700 mb-1">Repository URL</label>
|
|
70
|
+
<input type="url" name="repository"
|
|
71
|
+
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
72
|
+
placeholder="e.g., https://github.com/organization/repository">
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
<!-- MCP Servers (with requirements merged in) -->
|
|
77
|
+
<div class="space-y-4">
|
|
78
|
+
<h2 class="text-xl font-semibold text-gray-900 flex items-center mb-4">
|
|
79
|
+
<i class='bx bx-server mr-2 text-blue-600'></i>
|
|
80
|
+
MCP Servers (Requirements managed per server)
|
|
81
|
+
</h2>
|
|
82
|
+
<div id="serversList" class="space-y-6">
|
|
83
|
+
<!-- Server configurations will be added here dynamically -->
|
|
84
|
+
</div>
|
|
85
|
+
<button type="button" onclick="addServer()"
|
|
86
|
+
class="px-4 py-2 border border-gray-300 rounded-lg text-gray-600 hover:bg-gray-50 flex items-center">
|
|
87
|
+
<i class='bx bx-plus mr-2'></i>
|
|
88
|
+
Add Server
|
|
89
|
+
</button>
|
|
90
|
+
</div>
|
|
91
|
+
<div class="flex justify-end space-x-4 pt-6 border-t">
|
|
92
|
+
<button type="button" onclick="window.location.href='index.html'"
|
|
93
|
+
class="px-6 py-2.5 border border-gray-300 rounded-lg text-gray-600 hover:bg-gray-50">
|
|
94
|
+
Cancel
|
|
95
|
+
</button>
|
|
96
|
+
<button type="submit"
|
|
97
|
+
class="px-6 py-2.5 bg-blue-600 text-white rounded-lg hover:bg-blue-700 flex items-center">
|
|
98
|
+
<i class='bx bx-save mr-2'></i>
|
|
99
|
+
Save Category
|
|
100
|
+
</button>
|
|
101
|
+
</div>
|
|
102
|
+
</form>
|
|
103
|
+
</div>
|
|
104
|
+
<div id="panel-create-server" class="hidden">
|
|
105
|
+
<form id="onboardServerForm" class="space-y-8">
|
|
106
|
+
<!-- Select Existing Category -->
|
|
107
|
+
<div class="space-y-4">
|
|
108
|
+
<h2 class="text-xl font-semibold text-gray-900 flex items-center mb-4">
|
|
109
|
+
<i class='bx bx-category mr-2 text-blue-600'></i>
|
|
110
|
+
Select Server Category
|
|
111
|
+
</h2>
|
|
112
|
+
<select id="existingCategorySelect" name="category" required
|
|
113
|
+
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
|
114
|
+
<option value="">Loading...</option>
|
|
115
|
+
</select>
|
|
116
|
+
</div>
|
|
117
|
+
<!-- MCP Server Dropdown -->
|
|
118
|
+
<div class="space-y-4">
|
|
119
|
+
<h2 class="text-xl font-semibold text-gray-900 flex items-center mb-4">
|
|
120
|
+
<i class='bx bx-server mr-2 text-blue-600'></i>
|
|
121
|
+
MCP Server
|
|
122
|
+
</h2>
|
|
123
|
+
<select id="existingServerSelect" name="server" required
|
|
124
|
+
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
|
125
|
+
<option value="">Select MCP Server</option>
|
|
126
|
+
<option value="__create_new__">Create New</option>
|
|
127
|
+
</select>
|
|
128
|
+
</div>
|
|
129
|
+
<!-- MCP Server Details (readonly or editable) -->
|
|
130
|
+
<div id="serverDetailsContainer">
|
|
131
|
+
<!-- Server details will be rendered here -->
|
|
132
|
+
</div>
|
|
133
|
+
<div class="flex justify-end space-x-4 pt-6 border-t">
|
|
134
|
+
<button type="button" onclick="window.location.href='index.html'"
|
|
135
|
+
class="px-6 py-2.5 border border-gray-300 rounded-lg text-gray-600 hover:bg-gray-50">
|
|
136
|
+
Cancel
|
|
137
|
+
</button>
|
|
138
|
+
<button type="submit"
|
|
139
|
+
class="px-6 py-2.5 bg-blue-600 text-white rounded-lg hover:bg-blue-700 flex items-center">
|
|
140
|
+
<i class='bx bx-save mr-2'></i>
|
|
141
|
+
Save Server
|
|
142
|
+
</button>
|
|
143
|
+
</div>
|
|
144
|
+
</form>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<script src="js/onboard/index.js" type="module"></script>
|
|
149
|
+
</body>
|
|
150
|
+
</html>
|
package/package.json
CHANGED
|
@@ -373,6 +373,7 @@ export class ClientInstaller {
|
|
|
373
373
|
|
|
374
374
|
// Clone the base installation configuration to avoid modifying the original serverConfig
|
|
375
375
|
const installConfig = JSON.parse(JSON.stringify(serverConfig.installation));
|
|
376
|
+
installConfig.mode = serverConfig.mode
|
|
376
377
|
const pythonEnv = options.settings?.pythonEnv;
|
|
377
378
|
let pythonDir: string | null = null;
|
|
378
379
|
|
|
@@ -606,46 +607,54 @@ export class ClientInstaller {
|
|
|
606
607
|
settings.mcpServers = {};
|
|
607
608
|
}
|
|
608
609
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
serverConfigForClient.env
|
|
610
|
+
if (installConfig.mode === 'stdio') {
|
|
611
|
+
// Special handling for Windows when command is npx for Cline and MSROO clients
|
|
612
|
+
// Use a copy to avoid modifying the passed installConfig directly if needed elsewhere
|
|
613
|
+
const serverConfigForClient = { ...installConfig };
|
|
614
|
+
if (process.platform === 'win32' &&
|
|
615
|
+
serverConfigForClient.command === 'npx' &&
|
|
616
|
+
(clientName === 'Cline' || clientName === 'MSRooCode' || clientName === 'MSROO')) {
|
|
617
|
+
// Update command to cmd
|
|
618
|
+
serverConfigForClient.command = 'cmd';
|
|
619
|
+
|
|
620
|
+
// Add /c and npx at the beginning of args
|
|
621
|
+
serverConfigForClient.args = ['/c', 'npx', ...serverConfigForClient.args];
|
|
622
|
+
|
|
623
|
+
// Add APPDATA environment variable pointing to npm directory
|
|
624
|
+
if (!serverConfigForClient.env) {
|
|
625
|
+
serverConfigForClient.env = {};
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// Dynamically get npm path and set APPDATA to it
|
|
629
|
+
const npmPath = await this.getNpmPath();
|
|
630
|
+
serverConfigForClient.env['APPDATA'] = npmPath;
|
|
631
|
+
Logger.debug(`Windows npx fix: command=${serverConfigForClient.command}, args=${serverConfigForClient.args.join(' ')}, env=${JSON.stringify(serverConfigForClient.env)}`);
|
|
632
|
+
}
|
|
633
|
+
// Convert backslashes to forward slashes in args paths
|
|
634
|
+
if (serverConfigForClient.args) {
|
|
635
|
+
serverConfigForClient.args = serverConfigForClient.args.map((arg: string) =>
|
|
636
|
+
typeof arg === 'string' ? arg.replace(/\\/g, '/') : arg
|
|
637
|
+
);
|
|
624
638
|
}
|
|
625
639
|
|
|
626
|
-
//
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
);
|
|
640
|
+
// Add or update the server configuration
|
|
641
|
+
settings.mcpServers[serverName] = {
|
|
642
|
+
command: serverConfigForClient.command,
|
|
643
|
+
args: serverConfigForClient.args,
|
|
644
|
+
env: serverConfigForClient.env,
|
|
645
|
+
autoApprove: [],
|
|
646
|
+
disabled: false,
|
|
647
|
+
alwaysAllow: []
|
|
648
|
+
};
|
|
649
|
+
Logger.debug(`Updating ${settingPath} for ${serverName}: ${JSON.stringify(settings.mcpServers[serverName])}`);
|
|
650
|
+
} else if (installConfig.mode === 'sse') {
|
|
651
|
+
// Handle SSE mode for Cline and MSRoo clients
|
|
652
|
+
settings.mcpServers[serverName] = {
|
|
653
|
+
type: 'sse',
|
|
654
|
+
url: installConfig.url
|
|
655
|
+
};
|
|
636
656
|
}
|
|
637
657
|
|
|
638
|
-
// Add or update the server configuration
|
|
639
|
-
settings.mcpServers[serverName] = {
|
|
640
|
-
command: serverConfigForClient.command,
|
|
641
|
-
args: serverConfigForClient.args,
|
|
642
|
-
env: serverConfigForClient.env,
|
|
643
|
-
autoApprove: [],
|
|
644
|
-
disabled: false,
|
|
645
|
-
alwaysAllow: []
|
|
646
|
-
};
|
|
647
|
-
Logger.debug(`Updating ${settingPath} for ${serverName}: ${JSON.stringify(settings.mcpServers[serverName])}`);
|
|
648
|
-
|
|
649
658
|
// Write the updated settings back to the file
|
|
650
659
|
await writeJsonFile(settingPath, settings);
|
|
651
660
|
}
|
|
@@ -673,20 +682,28 @@ export class ClientInstaller {
|
|
|
673
682
|
// Use a copy to avoid modifying the passed installConfig directly
|
|
674
683
|
const serverConfigForClient = { ...installConfig };
|
|
675
684
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
685
|
+
if (installConfig.mode === 'stdio') {
|
|
686
|
+
if (serverConfigForClient.args) {
|
|
687
|
+
serverConfigForClient.args = serverConfigForClient.args.map((arg: string) =>
|
|
688
|
+
typeof arg === 'string' ? arg.replace(/\\/g, '/') : arg
|
|
689
|
+
);
|
|
690
|
+
}
|
|
682
691
|
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
692
|
+
// Add or update the server configuration
|
|
693
|
+
settings.mcp.servers[serverName] = {
|
|
694
|
+
command: serverConfigForClient.command,
|
|
695
|
+
args: serverConfigForClient.args,
|
|
696
|
+
env: serverConfigForClient.env
|
|
697
|
+
};
|
|
698
|
+
Logger.debug(`Updating ${settingPath} for ${serverName}: ${JSON.stringify(settings.mcp.servers[serverName])}`);
|
|
699
|
+
}
|
|
700
|
+
else if (installConfig.mode === 'sse') {
|
|
701
|
+
// Handle SSE mode for Github Copilot
|
|
702
|
+
settings.mcp.servers[serverName] = {
|
|
703
|
+
type: 'sse',
|
|
704
|
+
url: installConfig.url
|
|
705
|
+
};
|
|
706
|
+
}
|
|
690
707
|
|
|
691
708
|
// Write the updated settings back to the file
|
|
692
709
|
await writeJsonFile(settingPath, settings);
|
package/src/core/types.ts
CHANGED
|
@@ -99,6 +99,7 @@ export interface InstallationConfig {
|
|
|
99
99
|
command: string;
|
|
100
100
|
args: string[]; // Can use ${packageSource} as template variable for installation path
|
|
101
101
|
env?: Record<string, EnvVariableConfig>; // Note the colon in property name
|
|
102
|
+
url?: string; // URL for sse mode
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
export interface DependencyConfig {
|
|
@@ -115,7 +116,7 @@ export interface DependencyConfig {
|
|
|
115
116
|
export interface McpConfig {
|
|
116
117
|
name: string;
|
|
117
118
|
description: string;
|
|
118
|
-
mode: 'stdio' | '
|
|
119
|
+
mode: 'stdio' | 'sse'; // Currently only stdio mode is supported in ai-coder-tools
|
|
119
120
|
dependencies?: DependencyConfig;
|
|
120
121
|
schemas?: string; // Path to the schema file
|
|
121
122
|
repository?: string; // Repository URL for the server
|
|
@@ -162,19 +162,23 @@
|
|
|
162
162
|
setupSearch();
|
|
163
163
|
setupModalOutsideClick();
|
|
164
164
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
165
|
+
try {
|
|
166
|
+
// First fetch categories and wait for completion
|
|
167
|
+
await fetchServerCategories();
|
|
168
|
+
|
|
169
|
+
// Check URL parameters for category
|
|
170
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
171
|
+
const categoryParam = urlParams.get('category');
|
|
172
|
+
|
|
173
|
+
// If we have a category parameter or last selected category
|
|
174
|
+
const lastSelected = categoryParam || localStorage.getItem('lastSelectedCategory');
|
|
175
|
+
|
|
176
|
+
// Only show details after data is loaded
|
|
177
|
+
if (lastSelected) {
|
|
178
|
+
await showServerDetails(lastSelected);
|
|
179
|
+
}
|
|
180
|
+
} catch (error) {
|
|
181
|
+
console.error('Error during initialization:', error);
|
|
178
182
|
}
|
|
179
183
|
});
|
|
180
184
|
</script>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Import all modal-related functionality
|
|
2
|
+
import { compareVersions } from './versionUtils.js';
|
|
3
|
+
import { delayedAppendInstallLoadingMessage } from './messageQueue.js';
|
|
4
|
+
import { showInstallLoadingModal, appendInstallLoadingMessage, hideInstallLoadingModal } from './loadingModal.js';
|
|
5
|
+
import { closeModal, setupModalOutsideClick } from './modalUtils.js';
|
|
6
|
+
import { handleBulkClientInstall, uninstallTools } from './installation.js';
|
|
7
|
+
import { showInstallModal } from './installModal.js';
|
|
8
|
+
import {
|
|
9
|
+
setupClientItems,
|
|
10
|
+
setupEnvironmentVariables,
|
|
11
|
+
setupInstallationArguments,
|
|
12
|
+
setupServerRequirements,
|
|
13
|
+
setupFormSubmitHandler
|
|
14
|
+
} from './modalSetup.js';
|
|
15
|
+
|
|
16
|
+
// Export all modal functionality
|
|
17
|
+
export {
|
|
18
|
+
// Version utilities
|
|
19
|
+
compareVersions,
|
|
20
|
+
|
|
21
|
+
// Message queue
|
|
22
|
+
delayedAppendInstallLoadingMessage,
|
|
23
|
+
|
|
24
|
+
// Loading modal
|
|
25
|
+
showInstallLoadingModal,
|
|
26
|
+
appendInstallLoadingMessage,
|
|
27
|
+
hideInstallLoadingModal,
|
|
28
|
+
|
|
29
|
+
// Modal utilities
|
|
30
|
+
closeModal,
|
|
31
|
+
setupModalOutsideClick,
|
|
32
|
+
|
|
33
|
+
// Installation
|
|
34
|
+
handleBulkClientInstall,
|
|
35
|
+
uninstallTools,
|
|
36
|
+
|
|
37
|
+
// Install modal
|
|
38
|
+
showInstallModal,
|
|
39
|
+
|
|
40
|
+
// Modal setup
|
|
41
|
+
setupClientItems,
|
|
42
|
+
setupEnvironmentVariables,
|
|
43
|
+
setupInstallationArguments,
|
|
44
|
+
setupServerRequirements,
|
|
45
|
+
setupFormSubmitHandler
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Initialize modal functionality
|
|
49
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
50
|
+
setupModalOutsideClick();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Make certain functions available globally
|
|
54
|
+
window.showInstallModal = showInstallModal;
|
|
55
|
+
window.showInstallLoadingModal = showInstallLoadingModal;
|
|
56
|
+
window.appendInstallLoadingMessage = appendInstallLoadingMessage;
|
|
57
|
+
window.hideInstallLoadingModal = hideInstallLoadingModal;
|
|
58
|
+
window.uninstallTools = uninstallTools;
|