@stacksfinder/mcp-server 1.1.0 → 1.2.0
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/LICENSE +16 -16
- package/README.md +92 -3
- package/dist/compatibility/index.d.ts +11 -0
- package/dist/compatibility/index.d.ts.map +1 -0
- package/dist/compatibility/index.js +13 -0
- package/dist/compatibility/index.js.map +1 -0
- package/dist/compatibility/rules.d.ts +29 -0
- package/dist/compatibility/rules.d.ts.map +1 -0
- package/dist/compatibility/rules.js +419 -0
- package/dist/compatibility/rules.js.map +1 -0
- package/dist/compatibility/scoring.d.ts +54 -0
- package/dist/compatibility/scoring.d.ts.map +1 -0
- package/dist/compatibility/scoring.js +209 -0
- package/dist/compatibility/scoring.js.map +1 -0
- package/dist/compatibility/types.d.ts +176 -0
- package/dist/compatibility/types.d.ts.map +1 -0
- package/dist/compatibility/types.js +26 -0
- package/dist/compatibility/types.js.map +1 -0
- package/dist/compatibility/utils.d.ts +82 -0
- package/dist/compatibility/utils.d.ts.map +1 -0
- package/dist/compatibility/utils.js +269 -0
- package/dist/compatibility/utils.js.map +1 -0
- package/dist/data/357/200/242/357/200/212cp H:bac_/303/240_guigui_v2stack_finderpackagesmcp-serversrcdatacompatibility_matrix.json H:bac_/303/240_guigui_v2stack_finderpackagesmcp-serverdistdata/357/200/242" +226 -0
- package/dist/http.d.ts +7 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +69 -0
- package/dist/http.js.map +1 -0
- package/dist/lib/mcp-compatibility/index.d.ts +33 -0
- package/dist/lib/mcp-compatibility/index.d.ts.map +1 -0
- package/dist/lib/mcp-compatibility/index.js +35 -0
- package/dist/lib/mcp-compatibility/index.js.map +1 -0
- package/dist/lib/mcp-compatibility/rules.d.ts +29 -0
- package/dist/lib/mcp-compatibility/rules.d.ts.map +1 -0
- package/dist/lib/mcp-compatibility/rules.js +419 -0
- package/dist/lib/mcp-compatibility/rules.js.map +1 -0
- package/dist/lib/mcp-compatibility/scoring.d.ts +54 -0
- package/dist/lib/mcp-compatibility/scoring.d.ts.map +1 -0
- package/dist/lib/mcp-compatibility/scoring.js +209 -0
- package/dist/lib/mcp-compatibility/scoring.js.map +1 -0
- package/dist/lib/mcp-compatibility/types.d.ts +176 -0
- package/dist/lib/mcp-compatibility/types.d.ts.map +1 -0
- package/dist/lib/mcp-compatibility/types.js +26 -0
- package/dist/lib/mcp-compatibility/types.js.map +1 -0
- package/dist/lib/mcp-compatibility/utils.d.ts +82 -0
- package/dist/lib/mcp-compatibility/utils.d.ts.map +1 -0
- package/dist/lib/mcp-compatibility/utils.js +269 -0
- package/dist/lib/mcp-compatibility/utils.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +296 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/check-compatibility.d.ts +43 -0
- package/dist/tools/check-compatibility.d.ts.map +1 -0
- package/dist/tools/check-compatibility.js +133 -0
- package/dist/tools/check-compatibility.js.map +1 -0
- package/dist/tools/project-kit/analyze-repo.d.ts +50 -0
- package/dist/tools/project-kit/analyze-repo.d.ts.map +1 -0
- package/dist/tools/project-kit/analyze-repo.js +456 -0
- package/dist/tools/project-kit/analyze-repo.js.map +1 -0
- package/dist/tools/project-kit/detect-stack.d.ts +16 -0
- package/dist/tools/project-kit/detect-stack.d.ts.map +1 -0
- package/dist/tools/project-kit/detect-stack.js +572 -0
- package/dist/tools/project-kit/detect-stack.js.map +1 -0
- package/dist/tools/project-kit/execute-installation.d.ts +50 -0
- package/dist/tools/project-kit/execute-installation.d.ts.map +1 -0
- package/dist/tools/project-kit/execute-installation.js +440 -0
- package/dist/tools/project-kit/execute-installation.js.map +1 -0
- package/dist/tools/project-kit/generate.d.ts +70 -0
- package/dist/tools/project-kit/generate.d.ts.map +1 -0
- package/dist/tools/project-kit/generate.js +455 -0
- package/dist/tools/project-kit/generate.js.map +1 -0
- package/dist/tools/project-kit/index.d.ts +18 -0
- package/dist/tools/project-kit/index.d.ts.map +1 -0
- package/dist/tools/project-kit/index.js +21 -0
- package/dist/tools/project-kit/index.js.map +1 -0
- package/dist/tools/project-kit/installation-types.d.ts +147 -0
- package/dist/tools/project-kit/installation-types.d.ts.map +1 -0
- package/dist/tools/project-kit/installation-types.js +491 -0
- package/dist/tools/project-kit/installation-types.js.map +1 -0
- package/dist/tools/project-kit/match-mcps.d.ts +67 -0
- package/dist/tools/project-kit/match-mcps.d.ts.map +1 -0
- package/dist/tools/project-kit/match-mcps.js +497 -0
- package/dist/tools/project-kit/match-mcps.js.map +1 -0
- package/dist/tools/project-kit/prepare-installation.d.ts +54 -0
- package/dist/tools/project-kit/prepare-installation.d.ts.map +1 -0
- package/dist/tools/project-kit/prepare-installation.js +382 -0
- package/dist/tools/project-kit/prepare-installation.js.map +1 -0
- package/dist/tools/project-kit/types.d.ts +200 -0
- package/dist/tools/project-kit/types.d.ts.map +1 -0
- package/dist/tools/project-kit/types.js +76 -0
- package/dist/tools/project-kit/types.js.map +1 -0
- package/dist/tools/recommend.d.ts.map +1 -1
- package/dist/tools/recommend.js +9 -4
- package/dist/tools/recommend.js.map +1 -1
- package/package.json +8 -3
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Compatibility Utilities
|
|
3
|
+
*
|
|
4
|
+
* Canonical matching utilities for consistent MCP identification.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Aliases map for common MCP name variations.
|
|
8
|
+
* Keys are normalized (lowercase, trimmed), values are canonical IDs.
|
|
9
|
+
*/
|
|
10
|
+
export const MCP_ALIASES = {
|
|
11
|
+
// Database MCPs
|
|
12
|
+
supabase: 'supabase-mcp',
|
|
13
|
+
'@supabase/mcp': 'supabase-mcp',
|
|
14
|
+
'@supabase/mcp-server': 'supabase-mcp',
|
|
15
|
+
neon: 'neon-mcp',
|
|
16
|
+
'@neondatabase/mcp': 'neon-mcp',
|
|
17
|
+
'@neondatabase/mcp-server': 'neon-mcp',
|
|
18
|
+
planetscale: 'planetscale-mcp',
|
|
19
|
+
'@planetscale/mcp': 'planetscale-mcp',
|
|
20
|
+
turso: 'turso-mcp',
|
|
21
|
+
'@tursodb/mcp': 'turso-mcp',
|
|
22
|
+
mongodb: 'mongodb-mcp',
|
|
23
|
+
'@mongodb/mcp': 'mongodb-mcp',
|
|
24
|
+
// ORM MCPs
|
|
25
|
+
prisma: 'prisma-mcp',
|
|
26
|
+
'@prisma/mcp': 'prisma-mcp',
|
|
27
|
+
drizzle: 'drizzle-mcp',
|
|
28
|
+
'drizzle-orm': 'drizzle-mcp',
|
|
29
|
+
typeorm: 'typeorm-mcp',
|
|
30
|
+
// Auth MCPs
|
|
31
|
+
clerk: 'clerk-mcp',
|
|
32
|
+
'@clerk/mcp': 'clerk-mcp',
|
|
33
|
+
auth0: 'auth0-mcp',
|
|
34
|
+
'@auth0/mcp': 'auth0-mcp',
|
|
35
|
+
'supabase-auth': 'supabase-auth-mcp',
|
|
36
|
+
lucia: 'lucia-mcp',
|
|
37
|
+
// Payments MCPs
|
|
38
|
+
stripe: 'stripe-mcp',
|
|
39
|
+
'@stripe/mcp': 'stripe-mcp',
|
|
40
|
+
paddle: 'paddle-mcp',
|
|
41
|
+
'@paddle/mcp': 'paddle-mcp',
|
|
42
|
+
lemonsqueezy: 'lemonsqueezy-mcp',
|
|
43
|
+
'lemon-squeezy': 'lemonsqueezy-mcp',
|
|
44
|
+
// Deployment MCPs
|
|
45
|
+
vercel: 'vercel-mcp',
|
|
46
|
+
'@vercel/mcp': 'vercel-mcp',
|
|
47
|
+
netlify: 'netlify-mcp',
|
|
48
|
+
'@netlify/mcp': 'netlify-mcp',
|
|
49
|
+
cloudflare: 'cloudflare-mcp',
|
|
50
|
+
'@cloudflare/mcp': 'cloudflare-mcp',
|
|
51
|
+
railway: 'railway-mcp',
|
|
52
|
+
fly: 'fly-mcp',
|
|
53
|
+
'fly.io': 'fly-mcp',
|
|
54
|
+
render: 'render-mcp',
|
|
55
|
+
// Storage MCPs
|
|
56
|
+
r2: 'r2-mcp',
|
|
57
|
+
'cloudflare-r2': 'r2-mcp',
|
|
58
|
+
s3: 's3-mcp',
|
|
59
|
+
'aws-s3': 's3-mcp',
|
|
60
|
+
uploadthing: 'uploadthing-mcp',
|
|
61
|
+
// Email MCPs
|
|
62
|
+
resend: 'resend-mcp',
|
|
63
|
+
'@resend/mcp': 'resend-mcp',
|
|
64
|
+
sendgrid: 'sendgrid-mcp',
|
|
65
|
+
postmark: 'postmark-mcp',
|
|
66
|
+
// Version Control MCPs
|
|
67
|
+
github: 'github-mcp',
|
|
68
|
+
'@github/mcp': 'github-mcp',
|
|
69
|
+
gitlab: 'gitlab-mcp',
|
|
70
|
+
'@gitlab/mcp': 'gitlab-mcp',
|
|
71
|
+
// AI MCPs
|
|
72
|
+
openai: 'openai-mcp',
|
|
73
|
+
'@openai/mcp': 'openai-mcp',
|
|
74
|
+
anthropic: 'anthropic-mcp',
|
|
75
|
+
'@anthropic/mcp': 'anthropic-mcp',
|
|
76
|
+
perplexity: 'perplexity-mcp',
|
|
77
|
+
context7: 'context7-mcp',
|
|
78
|
+
// Communication MCPs
|
|
79
|
+
slack: 'slack-mcp',
|
|
80
|
+
'@slack/mcp': 'slack-mcp',
|
|
81
|
+
discord: 'discord-mcp',
|
|
82
|
+
telegram: 'telegram-mcp',
|
|
83
|
+
// Monitoring MCPs
|
|
84
|
+
sentry: 'sentry-mcp',
|
|
85
|
+
'@sentry/mcp': 'sentry-mcp',
|
|
86
|
+
datadog: 'datadog-mcp',
|
|
87
|
+
// Testing MCPs
|
|
88
|
+
playwright: 'playwright-mcp',
|
|
89
|
+
'@playwright/mcp': 'playwright-mcp',
|
|
90
|
+
puppeteer: 'puppeteer-mcp',
|
|
91
|
+
// Documentation MCPs
|
|
92
|
+
obsidian: 'obsidian-mcp',
|
|
93
|
+
notion: 'notion-mcp',
|
|
94
|
+
confluence: 'confluence-mcp',
|
|
95
|
+
// General MCPs
|
|
96
|
+
filesystem: 'filesystem-mcp',
|
|
97
|
+
'sequential-thinking': 'sequential-thinking-mcp',
|
|
98
|
+
'brave-search': 'brave-search-mcp',
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Canonicalize an MCP ID to a consistent format.
|
|
102
|
+
*
|
|
103
|
+
* @param id - The MCP ID to canonicalize (e.g., "supabase", "@supabase/mcp")
|
|
104
|
+
* @returns The canonical ID (e.g., "supabase-mcp")
|
|
105
|
+
*/
|
|
106
|
+
export function canonicalizeMcpId(id) {
|
|
107
|
+
const normalized = id.toLowerCase().trim();
|
|
108
|
+
return MCP_ALIASES[normalized] ?? normalized;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Generate a consistent pair key for two MCPs.
|
|
112
|
+
* The key is ordered alphabetically to ensure A/B and B/A produce the same key.
|
|
113
|
+
*
|
|
114
|
+
* @param a - First MCP ID
|
|
115
|
+
* @param b - Second MCP ID
|
|
116
|
+
* @returns Pair key in format "mcpA::mcpB" (alphabetically ordered)
|
|
117
|
+
*/
|
|
118
|
+
export function pairKey(a, b) {
|
|
119
|
+
const canonA = canonicalizeMcpId(a);
|
|
120
|
+
const canonB = canonicalizeMcpId(b);
|
|
121
|
+
const [first, second] = [canonA, canonB].sort();
|
|
122
|
+
return `${first}::${second}`;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Rules indexed by pair key for O(1) lookup.
|
|
126
|
+
* Populated by initRulesIndex().
|
|
127
|
+
*/
|
|
128
|
+
let RULES_BY_PAIR = new Map();
|
|
129
|
+
/**
|
|
130
|
+
* Initialize the rules index from an array of rules.
|
|
131
|
+
* Must be called before using findRule().
|
|
132
|
+
*
|
|
133
|
+
* @param rules - Array of compatibility rules
|
|
134
|
+
*/
|
|
135
|
+
export function initRulesIndex(rules) {
|
|
136
|
+
RULES_BY_PAIR = new Map();
|
|
137
|
+
for (const rule of rules) {
|
|
138
|
+
const key = pairKey(rule.mcpA, rule.mcpB);
|
|
139
|
+
RULES_BY_PAIR.set(key, rule);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get the rules index (for testing).
|
|
144
|
+
*/
|
|
145
|
+
export function getRulesIndex() {
|
|
146
|
+
return RULES_BY_PAIR;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Find a compatibility rule for two MCPs.
|
|
150
|
+
* Order doesn't matter: findRule(A, B) === findRule(B, A)
|
|
151
|
+
*
|
|
152
|
+
* @param a - First MCP ID (can be any alias)
|
|
153
|
+
* @param b - Second MCP ID (can be any alias)
|
|
154
|
+
* @returns The matching rule, or undefined if no rule exists
|
|
155
|
+
*/
|
|
156
|
+
export function findRule(a, b) {
|
|
157
|
+
const key = pairKey(a, b);
|
|
158
|
+
return RULES_BY_PAIR.get(key);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Generate all unique pairs from an array of MCPs.
|
|
162
|
+
* Used to check all nC2 combinations.
|
|
163
|
+
*
|
|
164
|
+
* @param mcps - Array of MCP IDs
|
|
165
|
+
* @returns Array of [mcpA, mcpB] pairs
|
|
166
|
+
*/
|
|
167
|
+
export function generatePairs(mcps) {
|
|
168
|
+
const pairs = [];
|
|
169
|
+
for (let i = 0; i < mcps.length; i++) {
|
|
170
|
+
for (let j = i + 1; j < mcps.length; j++) {
|
|
171
|
+
pairs.push([mcps[i], mcps[j]]);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return pairs;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Check all pairs of MCPs for compatibility issues.
|
|
178
|
+
*
|
|
179
|
+
* @param mcps - Array of MCP IDs to check
|
|
180
|
+
* @returns Object with categorized matched rules
|
|
181
|
+
*/
|
|
182
|
+
export function checkAllPairs(mcps) {
|
|
183
|
+
const conflicts = [];
|
|
184
|
+
const redundancies = [];
|
|
185
|
+
const synergies = [];
|
|
186
|
+
const conditionals = [];
|
|
187
|
+
const pairs = generatePairs(mcps);
|
|
188
|
+
for (const [a, b] of pairs) {
|
|
189
|
+
const rule = findRule(a, b);
|
|
190
|
+
if (rule) {
|
|
191
|
+
const matched = {
|
|
192
|
+
rule,
|
|
193
|
+
inputA: a,
|
|
194
|
+
inputB: b,
|
|
195
|
+
};
|
|
196
|
+
switch (rule.status) {
|
|
197
|
+
case 'conflict':
|
|
198
|
+
conflicts.push(matched);
|
|
199
|
+
break;
|
|
200
|
+
case 'redundant':
|
|
201
|
+
redundancies.push(matched);
|
|
202
|
+
break;
|
|
203
|
+
case 'synergy':
|
|
204
|
+
synergies.push(matched);
|
|
205
|
+
break;
|
|
206
|
+
case 'conditional':
|
|
207
|
+
conditionals.push(matched);
|
|
208
|
+
break;
|
|
209
|
+
// 'compatible' - no action needed
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return { conflicts, redundancies, synergies, conditionals };
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Get suggestions based on synergy rules.
|
|
217
|
+
* If user has MCP A and rule says A+B is a synergy,
|
|
218
|
+
* suggest B if user doesn't have it.
|
|
219
|
+
*
|
|
220
|
+
* @param mcps - Array of installed MCP IDs
|
|
221
|
+
* @param allRules - All compatibility rules
|
|
222
|
+
* @returns Array of suggestions
|
|
223
|
+
*/
|
|
224
|
+
export function getSuggestions(mcps, allRules) {
|
|
225
|
+
const suggestions = [];
|
|
226
|
+
const canonicalMcps = new Set(mcps.map(canonicalizeMcpId));
|
|
227
|
+
const suggestedSet = new Set();
|
|
228
|
+
// Find synergy rules where user has one but not the other
|
|
229
|
+
for (const rule of allRules) {
|
|
230
|
+
if (rule.status !== 'synergy')
|
|
231
|
+
continue;
|
|
232
|
+
const hasA = canonicalMcps.has(rule.mcpA);
|
|
233
|
+
const hasB = canonicalMcps.has(rule.mcpB);
|
|
234
|
+
// If user has A but not B
|
|
235
|
+
if (hasA && !hasB && !suggestedSet.has(rule.mcpB)) {
|
|
236
|
+
suggestions.push({
|
|
237
|
+
mcp: rule.mcpB,
|
|
238
|
+
reason: rule.reason,
|
|
239
|
+
basedOn: rule.mcpA,
|
|
240
|
+
});
|
|
241
|
+
suggestedSet.add(rule.mcpB);
|
|
242
|
+
}
|
|
243
|
+
// If user has B but not A
|
|
244
|
+
if (hasB && !hasA && !suggestedSet.has(rule.mcpA)) {
|
|
245
|
+
suggestions.push({
|
|
246
|
+
mcp: rule.mcpA,
|
|
247
|
+
reason: rule.reason,
|
|
248
|
+
basedOn: rule.mcpB,
|
|
249
|
+
});
|
|
250
|
+
suggestedSet.add(rule.mcpA);
|
|
251
|
+
}
|
|
252
|
+
// Check suggestWhenMissing field
|
|
253
|
+
if (rule.suggestWhenMissing && (hasA || hasB)) {
|
|
254
|
+
for (const suggested of rule.suggestWhenMissing) {
|
|
255
|
+
const canonSuggested = canonicalizeMcpId(suggested);
|
|
256
|
+
if (!canonicalMcps.has(canonSuggested) && !suggestedSet.has(canonSuggested)) {
|
|
257
|
+
suggestions.push({
|
|
258
|
+
mcp: canonSuggested,
|
|
259
|
+
reason: `Pairs well with ${hasA ? rule.mcpA : rule.mcpB}`,
|
|
260
|
+
basedOn: hasA ? rule.mcpA : rule.mcpB,
|
|
261
|
+
});
|
|
262
|
+
suggestedSet.add(canonSuggested);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return suggestions;
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/lib/mcp-compatibility/utils.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiFpE;;GAEG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAsjBxC"}
|
package/dist/server.js
CHANGED
|
@@ -9,6 +9,11 @@ import { getBlueprintToolDefinition, executeGetBlueprint, GetBlueprintInputSchem
|
|
|
9
9
|
import { recommendStackDemoToolDefinition, executeRecommendStackDemo, RecommendStackDemoInputSchema } from './tools/recommend-demo.js';
|
|
10
10
|
import { setupApiKeyToolDefinition, executeSetupApiKey, SetupApiKeyInputSchema, listApiKeysToolDefinition, executeListApiKeys, revokeApiKeyToolDefinition, executeRevokeApiKey, RevokeApiKeyInputSchema } from './tools/api-keys.js';
|
|
11
11
|
import { createAuditToolDefinition, executeCreateAudit, CreateAuditInputSchema, getAuditToolDefinition, executeGetAudit, GetAuditInputSchema, listAuditsToolDefinition, executeListAudits, ListAuditsInputSchema, compareAuditsToolDefinition, executeCompareAudits, CompareAuditsInputSchema, getAuditQuotaToolDefinition, executeGetAuditQuota, getMigrationRecommendationToolDefinition, executeGetMigrationRecommendation, GetMigrationRecommendationInputSchema } from './tools/audit.js';
|
|
12
|
+
import { generateMCPKitTool, generateMCPKit, GenerateMCPKitInputSchema, analyzeRepoMcpsTool, analyzeRepo, AnalyzeRepoMCPsInputSchema, PRIORITIES, PROJECT_TYPES, SCALES } from './tools/project-kit/index.js';
|
|
13
|
+
import { prepareMCPInstallationTool, prepareMCPInstallation } from './tools/project-kit/prepare-installation.js';
|
|
14
|
+
import { executeMCPInstallationTool, executeMCPInstallation } from './tools/project-kit/execute-installation.js';
|
|
15
|
+
import { PrepareMCPInstallationInputSchema, ExecuteMCPInstallationInputSchema } from './tools/project-kit/installation-types.js';
|
|
16
|
+
import { checkCompatibilityToolDefinition, executeCheckCompatibility, CheckCompatibilityInputSchema } from './tools/check-compatibility.js';
|
|
12
17
|
import { info, debug } from './utils/logger.js';
|
|
13
18
|
/**
|
|
14
19
|
* Create and configure the MCP server.
|
|
@@ -356,7 +361,297 @@ export function createServer() {
|
|
|
356
361
|
isError
|
|
357
362
|
};
|
|
358
363
|
});
|
|
359
|
-
|
|
364
|
+
// ========================================================================
|
|
365
|
+
// PROJECT-KIT TOOLS (MCPFinder)
|
|
366
|
+
// ========================================================================
|
|
367
|
+
// Register generate_mcp_kit tool (local, no API key required)
|
|
368
|
+
server.registerTool(generateMCPKitTool.name, {
|
|
369
|
+
title: 'Generate MCP Kit',
|
|
370
|
+
description: generateMCPKitTool.description,
|
|
371
|
+
inputSchema: {
|
|
372
|
+
projectDescription: z.string().min(50).max(5000).describe('Describe your project (50-5000 chars)'),
|
|
373
|
+
priorities: z.array(z.enum(PRIORITIES)).max(3).optional().describe('Top priorities (max 3)'),
|
|
374
|
+
constraints: z.array(z.string()).optional().describe('Tech constraints (e.g., must-use-postgresql)'),
|
|
375
|
+
projectType: z.enum(PROJECT_TYPES).optional().describe('Project type (if known)'),
|
|
376
|
+
scale: z.enum(SCALES).optional().describe('Project scale (if known)')
|
|
377
|
+
}
|
|
378
|
+
}, async (args) => {
|
|
379
|
+
debug('generate_mcp_kit called', args);
|
|
380
|
+
const input = GenerateMCPKitInputSchema.parse(args);
|
|
381
|
+
const result = generateMCPKit(input);
|
|
382
|
+
return {
|
|
383
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
|
|
384
|
+
};
|
|
385
|
+
});
|
|
386
|
+
// Register analyze_repo_mcps tool (local, no API key required)
|
|
387
|
+
server.registerTool(analyzeRepoMcpsTool.name, {
|
|
388
|
+
title: 'Analyze Repository MCPs',
|
|
389
|
+
description: analyzeRepoMcpsTool.description,
|
|
390
|
+
inputSchema: {
|
|
391
|
+
includeInstalled: z.boolean().optional().describe('Include already installed MCPs (default: false)'),
|
|
392
|
+
mcpConfigPath: z.string().optional().describe('Override path to MCP configuration file'),
|
|
393
|
+
workspaceRoot: z.string().optional().describe('Override workspace root directory (default: current directory)')
|
|
394
|
+
}
|
|
395
|
+
}, async (args) => {
|
|
396
|
+
debug('analyze_repo_mcps called', args);
|
|
397
|
+
const input = AnalyzeRepoMCPsInputSchema.parse(args);
|
|
398
|
+
const result = await analyzeRepo(input);
|
|
399
|
+
// Format as markdown for better readability
|
|
400
|
+
return {
|
|
401
|
+
content: [{ type: 'text', text: formatAnalysisResult(result) }]
|
|
402
|
+
};
|
|
403
|
+
});
|
|
404
|
+
// Register prepare_mcp_installation tool (local, no API key required)
|
|
405
|
+
server.registerTool(prepareMCPInstallationTool.name, {
|
|
406
|
+
title: 'Prepare MCP Installation',
|
|
407
|
+
description: prepareMCPInstallationTool.description,
|
|
408
|
+
inputSchema: {
|
|
409
|
+
workspaceRoot: z.string().optional().describe('Workspace root directory (default: current directory)'),
|
|
410
|
+
mcpConfigPath: z.string().optional().describe('Override path to existing MCP configuration file'),
|
|
411
|
+
includeInstalled: z.boolean().optional().describe('Include already installed MCPs in the preparation (default: false)'),
|
|
412
|
+
envMcpPath: z.string().optional().describe('Path where .env-mcp will be created (default: .env-mcp in workspaceRoot)')
|
|
413
|
+
}
|
|
414
|
+
}, async (args) => {
|
|
415
|
+
debug('prepare_mcp_installation called', args);
|
|
416
|
+
const input = PrepareMCPInstallationInputSchema.parse(args);
|
|
417
|
+
const result = await prepareMCPInstallation(input);
|
|
418
|
+
return {
|
|
419
|
+
content: [{ type: 'text', text: result.message + '\n\n' + formatPreparationSummary(result) }]
|
|
420
|
+
};
|
|
421
|
+
});
|
|
422
|
+
// Register execute_mcp_installation tool (local, no API key required)
|
|
423
|
+
server.registerTool(executeMCPInstallationTool.name, {
|
|
424
|
+
title: 'Execute MCP Installation',
|
|
425
|
+
description: executeMCPInstallationTool.description,
|
|
426
|
+
inputSchema: {
|
|
427
|
+
envMcpPath: z.string().optional().describe('Path to .env-mcp file (default: .env-mcp in current directory)'),
|
|
428
|
+
targetClient: z
|
|
429
|
+
.enum(['claude-code', 'claude-desktop', 'cursor', 'vscode', 'windsurf'])
|
|
430
|
+
.optional()
|
|
431
|
+
.describe('Target IDE/client for installation (default: claude-code)'),
|
|
432
|
+
dryRun: z.boolean().optional().describe('Only generate commands without marking ready to execute (default: false)')
|
|
433
|
+
}
|
|
434
|
+
}, async (args) => {
|
|
435
|
+
debug('execute_mcp_installation called', args);
|
|
436
|
+
const input = ExecuteMCPInstallationInputSchema.parse(args);
|
|
437
|
+
const result = await executeMCPInstallation(input);
|
|
438
|
+
return {
|
|
439
|
+
content: [{ type: 'text', text: formatExecutionResult(result) }]
|
|
440
|
+
};
|
|
441
|
+
});
|
|
442
|
+
// ========================================================================
|
|
443
|
+
// COMPATIBILITY TOOL (MCP Conflict Detection)
|
|
444
|
+
// ========================================================================
|
|
445
|
+
// Register check_mcp_compatibility tool (local, no API key required)
|
|
446
|
+
server.registerTool(checkCompatibilityToolDefinition.name, {
|
|
447
|
+
title: 'Check MCP Compatibility',
|
|
448
|
+
description: checkCompatibilityToolDefinition.description,
|
|
449
|
+
inputSchema: {
|
|
450
|
+
mcps: z
|
|
451
|
+
.array(z.string().min(1))
|
|
452
|
+
.min(1)
|
|
453
|
+
.max(20)
|
|
454
|
+
.describe('Array of MCP server IDs to check compatibility between')
|
|
455
|
+
}
|
|
456
|
+
}, async (args) => {
|
|
457
|
+
debug('check_mcp_compatibility called', args);
|
|
458
|
+
const input = CheckCompatibilityInputSchema.parse(args);
|
|
459
|
+
const { text, data, isError } = executeCheckCompatibility(input);
|
|
460
|
+
return {
|
|
461
|
+
content: [
|
|
462
|
+
{ type: 'text', text },
|
|
463
|
+
{ type: 'text', text: `\n---\n\n**Structured Data:**\n\`\`\`json\n${JSON.stringify(data, null, 2)}\n\`\`\`` }
|
|
464
|
+
],
|
|
465
|
+
isError
|
|
466
|
+
};
|
|
467
|
+
});
|
|
468
|
+
info('Registered 21 tools: list_technologies, analyze_tech, compare_techs, recommend_stack_demo, recommend_stack, get_blueprint, create_blueprint, setup_api_key, list_api_keys, revoke_api_key, create_audit, get_audit, list_audits, compare_audits, get_audit_quota, get_migration_recommendation, generate_mcp_kit, analyze_repo_mcps, prepare_mcp_installation, execute_mcp_installation, check_mcp_compatibility');
|
|
360
469
|
return server;
|
|
361
470
|
}
|
|
471
|
+
// ============================================================================
|
|
472
|
+
// HELPER FUNCTIONS
|
|
473
|
+
// ============================================================================
|
|
474
|
+
/**
|
|
475
|
+
* Format analyze_repo_mcps result as readable markdown.
|
|
476
|
+
*/
|
|
477
|
+
function formatAnalysisResult(result) {
|
|
478
|
+
const lines = [];
|
|
479
|
+
lines.push('# Repository Analysis\n');
|
|
480
|
+
// Detected Stack
|
|
481
|
+
lines.push('## Detected Technologies\n');
|
|
482
|
+
const stackItems = [
|
|
483
|
+
result.detectedStack.frontend &&
|
|
484
|
+
`- **Frontend**: ${result.detectedStack.frontend.name}${result.detectedStack.frontend.version ? ` (${result.detectedStack.frontend.version})` : ''}`,
|
|
485
|
+
result.detectedStack.backend &&
|
|
486
|
+
`- **Backend**: ${result.detectedStack.backend.name}${result.detectedStack.backend.version ? ` (${result.detectedStack.backend.version})` : ''}`,
|
|
487
|
+
result.detectedStack.database &&
|
|
488
|
+
`- **Database**: ${result.detectedStack.database.name}${result.detectedStack.database.version ? ` (${result.detectedStack.database.version})` : ''}`,
|
|
489
|
+
result.detectedStack.orm &&
|
|
490
|
+
`- **ORM**: ${result.detectedStack.orm.name}${result.detectedStack.orm.version ? ` (${result.detectedStack.orm.version})` : ''}`,
|
|
491
|
+
result.detectedStack.auth &&
|
|
492
|
+
`- **Auth**: ${result.detectedStack.auth.name}${result.detectedStack.auth.version ? ` (${result.detectedStack.auth.version})` : ''}`,
|
|
493
|
+
result.detectedStack.hosting &&
|
|
494
|
+
`- **Hosting**: ${result.detectedStack.hosting.name}${result.detectedStack.hosting.version ? ` (${result.detectedStack.hosting.version})` : ''}`,
|
|
495
|
+
result.detectedStack.payments &&
|
|
496
|
+
`- **Payments**: ${result.detectedStack.payments.name}${result.detectedStack.payments.version ? ` (${result.detectedStack.payments.version})` : ''}`
|
|
497
|
+
].filter((item) => Boolean(item));
|
|
498
|
+
if (stackItems.length > 0) {
|
|
499
|
+
lines.push(...stackItems);
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
lines.push('_No technologies detected from project files._');
|
|
503
|
+
}
|
|
504
|
+
if (result.detectedStack.services.length > 0) {
|
|
505
|
+
lines.push('\n**Services**:');
|
|
506
|
+
for (const service of result.detectedStack.services) {
|
|
507
|
+
lines.push(`- ${service.name}`);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
lines.push('');
|
|
511
|
+
// Files Analyzed
|
|
512
|
+
lines.push('## Files Analyzed\n');
|
|
513
|
+
if (result.metadata.filesAnalyzed.length > 0) {
|
|
514
|
+
lines.push(result.metadata.filesAnalyzed.map((f) => `- \`${f}\``).join('\n'));
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
lines.push('_No recognized configuration files found._');
|
|
518
|
+
}
|
|
519
|
+
lines.push('');
|
|
520
|
+
// Installed MCPs
|
|
521
|
+
if (result.installedMcps.length > 0) {
|
|
522
|
+
lines.push('## Already Installed MCPs\n');
|
|
523
|
+
lines.push(result.installedMcps.map((m) => `- ${m}`).join('\n'));
|
|
524
|
+
lines.push('');
|
|
525
|
+
}
|
|
526
|
+
// Recommended MCPs
|
|
527
|
+
lines.push('## Recommended MCPs\n');
|
|
528
|
+
if (result.recommendedMcps.length === 0) {
|
|
529
|
+
lines.push('_No additional MCPs recommended. You have everything you need!_');
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
// Group by priority
|
|
533
|
+
const highPriority = result.recommendedMcps.filter((m) => m.priority === 'high');
|
|
534
|
+
const mediumPriority = result.recommendedMcps.filter((m) => m.priority === 'medium');
|
|
535
|
+
const lowPriority = result.recommendedMcps.filter((m) => m.priority === 'low');
|
|
536
|
+
if (highPriority.length > 0) {
|
|
537
|
+
lines.push('### High Priority\n');
|
|
538
|
+
for (const mcp of highPriority) {
|
|
539
|
+
lines.push(`**${mcp.name}** (\`${mcp.slug}\`)`);
|
|
540
|
+
lines.push(`- ${mcp.description}`);
|
|
541
|
+
lines.push(`- _Matched: ${mcp.matchedTech}_`);
|
|
542
|
+
lines.push('');
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
if (mediumPriority.length > 0) {
|
|
546
|
+
lines.push('### Medium Priority\n');
|
|
547
|
+
for (const mcp of mediumPriority) {
|
|
548
|
+
lines.push(`**${mcp.name}** (\`${mcp.slug}\`)`);
|
|
549
|
+
lines.push(`- ${mcp.description}`);
|
|
550
|
+
lines.push(`- _Matched: ${mcp.matchedTech}_`);
|
|
551
|
+
lines.push('');
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
if (lowPriority.length > 0) {
|
|
555
|
+
lines.push('### Low Priority\n');
|
|
556
|
+
for (const mcp of lowPriority) {
|
|
557
|
+
lines.push(`**${mcp.name}** (\`${mcp.slug}\`)`);
|
|
558
|
+
lines.push(`- ${mcp.description}`);
|
|
559
|
+
lines.push(`- _Matched: ${mcp.matchedTech}_`);
|
|
560
|
+
lines.push('');
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
// Quick Install
|
|
565
|
+
if (result.recommendedMcps.length > 0) {
|
|
566
|
+
lines.push('## Quick Install\n');
|
|
567
|
+
lines.push('Add to your Claude Desktop config (`claude_desktop_config.json`):\n');
|
|
568
|
+
lines.push('```json');
|
|
569
|
+
lines.push(JSON.stringify(result.installConfig.claudeDesktop, null, 2));
|
|
570
|
+
lines.push('```\n');
|
|
571
|
+
}
|
|
572
|
+
// Metadata
|
|
573
|
+
lines.push(`---\n_Analysis completed: ${result.metadata.analysisDate}_`);
|
|
574
|
+
return lines.join('\n');
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Format prepare_mcp_installation result summary.
|
|
578
|
+
*/
|
|
579
|
+
function formatPreparationSummary(result) {
|
|
580
|
+
const lines = [];
|
|
581
|
+
// MCPs to install grouped by priority
|
|
582
|
+
if (result.mcpsToInstall.length > 0) {
|
|
583
|
+
lines.push('## MCPs to Install\n');
|
|
584
|
+
const highPriority = result.mcpsToInstall.filter((m) => m.priority === 'high');
|
|
585
|
+
const mediumPriority = result.mcpsToInstall.filter((m) => m.priority === 'medium');
|
|
586
|
+
const lowPriority = result.mcpsToInstall.filter((m) => m.priority === 'low');
|
|
587
|
+
if (highPriority.length > 0) {
|
|
588
|
+
lines.push('### 🔴 High Priority');
|
|
589
|
+
for (const mcp of highPriority) {
|
|
590
|
+
const requiredVars = mcp.envVars.filter((v) => v.requirement === 'required').length;
|
|
591
|
+
lines.push(`- **${mcp.name}** (${requiredVars} required vars)`);
|
|
592
|
+
}
|
|
593
|
+
lines.push('');
|
|
594
|
+
}
|
|
595
|
+
if (mediumPriority.length > 0) {
|
|
596
|
+
lines.push('### 🟡 Medium Priority');
|
|
597
|
+
for (const mcp of mediumPriority) {
|
|
598
|
+
const requiredVars = mcp.envVars.filter((v) => v.requirement === 'required').length;
|
|
599
|
+
lines.push(`- **${mcp.name}** (${requiredVars} required vars)`);
|
|
600
|
+
}
|
|
601
|
+
lines.push('');
|
|
602
|
+
}
|
|
603
|
+
if (lowPriority.length > 0) {
|
|
604
|
+
lines.push('### 🟢 Low Priority');
|
|
605
|
+
for (const mcp of lowPriority) {
|
|
606
|
+
const requiredVars = mcp.envVars.filter((v) => v.requirement === 'required').length;
|
|
607
|
+
lines.push(`- **${mcp.name}** (${requiredVars} required vars)`);
|
|
608
|
+
}
|
|
609
|
+
lines.push('');
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
// Already installed
|
|
613
|
+
if (result.installedMcps.length > 0) {
|
|
614
|
+
lines.push('## Already Installed');
|
|
615
|
+
for (const mcp of result.installedMcps) {
|
|
616
|
+
lines.push(`- ✅ ${mcp}`);
|
|
617
|
+
}
|
|
618
|
+
lines.push('');
|
|
619
|
+
}
|
|
620
|
+
return lines.join('\n');
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Format execute_mcp_installation result.
|
|
624
|
+
*/
|
|
625
|
+
function formatExecutionResult(result) {
|
|
626
|
+
const lines = [];
|
|
627
|
+
lines.push(result.message);
|
|
628
|
+
lines.push('');
|
|
629
|
+
// Show aggregate command for Claude Code
|
|
630
|
+
if (result.aggregateCommand) {
|
|
631
|
+
lines.push('---\n');
|
|
632
|
+
lines.push('## Claude Code Installation\n');
|
|
633
|
+
lines.push('Run this command to install all ready MCPs:\n');
|
|
634
|
+
lines.push('```bash');
|
|
635
|
+
lines.push(result.aggregateCommand);
|
|
636
|
+
lines.push('```\n');
|
|
637
|
+
}
|
|
638
|
+
// Show JSON config for other clients
|
|
639
|
+
if (result.aggregateConfig && !result.aggregateCommand) {
|
|
640
|
+
lines.push('---\n');
|
|
641
|
+
lines.push('## JSON Configuration\n');
|
|
642
|
+
lines.push('Add this to your MCP configuration file:\n');
|
|
643
|
+
lines.push('```json');
|
|
644
|
+
lines.push(JSON.stringify(result.aggregateConfig, null, 2));
|
|
645
|
+
lines.push('```\n');
|
|
646
|
+
}
|
|
647
|
+
// Post-install instructions
|
|
648
|
+
if (result.postInstallInstructions.length > 0) {
|
|
649
|
+
lines.push('---\n');
|
|
650
|
+
lines.push('## Post-Installation\n');
|
|
651
|
+
for (const instruction of result.postInstallInstructions) {
|
|
652
|
+
lines.push(instruction);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
return lines.join('\n');
|
|
656
|
+
}
|
|
362
657
|
//# sourceMappingURL=server.js.map
|