@yassinello/create-mymcp 0.2.0 → 0.3.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/index.mjs +223 -31
- package/package.json +29 -29
package/index.mjs
CHANGED
|
@@ -48,7 +48,7 @@ async function confirm(msg, defaultYes = true) {
|
|
|
48
48
|
return answer === "y" || answer === "yes";
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
/**
|
|
51
|
+
/** Strip surrounding quotes and trim whitespace */
|
|
52
52
|
function cleanPath(input) {
|
|
53
53
|
return input.trim().replace(/^["']|["']$/g, "");
|
|
54
54
|
}
|
|
@@ -56,13 +56,143 @@ function cleanPath(input) {
|
|
|
56
56
|
/** Check if a directory exists and is non-empty */
|
|
57
57
|
function isDirNonEmpty(dir) {
|
|
58
58
|
try {
|
|
59
|
-
|
|
60
|
-
return entries.length > 0;
|
|
59
|
+
return readdirSync(dir).length > 0;
|
|
61
60
|
} catch {
|
|
62
61
|
return false;
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Clean a credential value:
|
|
67
|
+
* - Strip "KEY=" prefix if user pasted "GOOGLE_CLIENT_ID=value"
|
|
68
|
+
* - Return null for non-values like "NA", "N/A", "none", "skip", "-", ""
|
|
69
|
+
*/
|
|
70
|
+
function cleanCredential(value, expectedKey) {
|
|
71
|
+
let cleaned = value.trim();
|
|
72
|
+
|
|
73
|
+
// Strip "KEY=" prefix if user pasted the whole line
|
|
74
|
+
const prefixPattern = new RegExp(`^${expectedKey}\\s*=\\s*`, "i");
|
|
75
|
+
cleaned = cleaned.replace(prefixPattern, "");
|
|
76
|
+
|
|
77
|
+
// Also strip any generic KEY= prefix (e.g., user pasted from .env)
|
|
78
|
+
cleaned = cleaned.replace(/^[A-Z_]+=/, "");
|
|
79
|
+
|
|
80
|
+
// Detect non-values
|
|
81
|
+
const skipValues = ["na", "n/a", "none", "skip", "-", "no", ""];
|
|
82
|
+
if (skipValues.includes(cleaned.toLowerCase())) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return cleaned;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Normalize a timezone input:
|
|
91
|
+
* - "Paris" → "Europe/Paris"
|
|
92
|
+
* - "New York" → "America/New_York"
|
|
93
|
+
* - "UTC" → "UTC"
|
|
94
|
+
*/
|
|
95
|
+
const TIMEZONE_SHORTCUTS = {
|
|
96
|
+
paris: "Europe/Paris",
|
|
97
|
+
london: "Europe/London",
|
|
98
|
+
berlin: "Europe/Berlin",
|
|
99
|
+
amsterdam: "Europe/Amsterdam",
|
|
100
|
+
brussels: "Europe/Brussels",
|
|
101
|
+
madrid: "Europe/Madrid",
|
|
102
|
+
rome: "Europe/Rome",
|
|
103
|
+
lisbon: "Europe/Lisbon",
|
|
104
|
+
zurich: "Europe/Zurich",
|
|
105
|
+
tokyo: "Asia/Tokyo",
|
|
106
|
+
shanghai: "Asia/Shanghai",
|
|
107
|
+
singapore: "Asia/Singapore",
|
|
108
|
+
dubai: "Asia/Dubai",
|
|
109
|
+
mumbai: "Asia/Kolkata",
|
|
110
|
+
sydney: "Australia/Sydney",
|
|
111
|
+
auckland: "Pacific/Auckland",
|
|
112
|
+
"new york": "America/New_York",
|
|
113
|
+
"new_york": "America/New_York",
|
|
114
|
+
"los angeles": "America/Los_Angeles",
|
|
115
|
+
"los_angeles": "America/Los_Angeles",
|
|
116
|
+
chicago: "America/Chicago",
|
|
117
|
+
denver: "America/Denver",
|
|
118
|
+
toronto: "America/Toronto",
|
|
119
|
+
"sao paulo": "America/Sao_Paulo",
|
|
120
|
+
"são paulo": "America/Sao_Paulo",
|
|
121
|
+
montreal: "America/Montreal",
|
|
122
|
+
utc: "UTC",
|
|
123
|
+
gmt: "UTC",
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
function normalizeTimezone(input) {
|
|
127
|
+
const lower = input.trim().toLowerCase();
|
|
128
|
+
if (TIMEZONE_SHORTCUTS[lower]) return TIMEZONE_SHORTCUTS[lower];
|
|
129
|
+
// If it already looks like a valid IANA timezone (contains /), return as-is
|
|
130
|
+
if (input.includes("/")) return input.trim();
|
|
131
|
+
// Default
|
|
132
|
+
return input.trim();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Normalize a locale input:
|
|
137
|
+
* - "fr" → "fr-FR"
|
|
138
|
+
* - "en" → "en-US"
|
|
139
|
+
* - "de" → "de-DE"
|
|
140
|
+
*/
|
|
141
|
+
const LOCALE_SHORTCUTS = {
|
|
142
|
+
fr: "fr-FR",
|
|
143
|
+
en: "en-US",
|
|
144
|
+
de: "de-DE",
|
|
145
|
+
es: "es-ES",
|
|
146
|
+
it: "it-IT",
|
|
147
|
+
pt: "pt-PT",
|
|
148
|
+
nl: "nl-NL",
|
|
149
|
+
ja: "ja-JP",
|
|
150
|
+
zh: "zh-CN",
|
|
151
|
+
ko: "ko-KR",
|
|
152
|
+
ar: "ar-SA",
|
|
153
|
+
ru: "ru-RU",
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
function normalizeLocale(input) {
|
|
157
|
+
const trimmed = input.trim();
|
|
158
|
+
const lower = trimmed.toLowerCase();
|
|
159
|
+
if (LOCALE_SHORTCUTS[lower]) return LOCALE_SHORTCUTS[lower];
|
|
160
|
+
return trimmed;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Extract owner/repo from a GitHub URL or return as-is
|
|
165
|
+
* - "https://github.com/Yassinello/obsidyass" → "Yassinello/obsidyass"
|
|
166
|
+
* - "Yassinello/obsidyass" → "Yassinello/obsidyass"
|
|
167
|
+
*/
|
|
168
|
+
function normalizeGitHubRepo(input) {
|
|
169
|
+
const cleaned = input.trim().replace(/\/+$/, ""); // strip trailing slashes
|
|
170
|
+
const urlMatch = cleaned.match(/github\.com\/([^/]+\/[^/]+)/);
|
|
171
|
+
if (urlMatch) return urlMatch[1];
|
|
172
|
+
return cleaned;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Slugify a project name for Vercel:
|
|
177
|
+
* - Lowercase, replace spaces with dashes, strip invalid chars
|
|
178
|
+
*/
|
|
179
|
+
function slugify(name) {
|
|
180
|
+
return name
|
|
181
|
+
.toLowerCase()
|
|
182
|
+
.replace(/\s+/g, "-")
|
|
183
|
+
.replace(/[^a-z0-9._-]/g, "")
|
|
184
|
+
.replace(/---+/g, "--") // Vercel doesn't allow ---
|
|
185
|
+
.slice(0, 100);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Mask a secret for display: show first 4 chars, then ***
|
|
190
|
+
*/
|
|
191
|
+
function maskSecret(value) {
|
|
192
|
+
if (value.length <= 8) return "****";
|
|
193
|
+
return value.slice(0, 4) + "****" + value.slice(-4);
|
|
194
|
+
}
|
|
195
|
+
|
|
66
196
|
// ── Pack definitions ─────────────────────────────────────────────────
|
|
67
197
|
|
|
68
198
|
const PACKS = [
|
|
@@ -76,12 +206,13 @@ const PACKS = [
|
|
|
76
206
|
prompt: "Google OAuth Client ID",
|
|
77
207
|
help: "https://console.cloud.google.com/apis/credentials",
|
|
78
208
|
},
|
|
79
|
-
{ key: "GOOGLE_CLIENT_SECRET", prompt: "Google OAuth Client Secret" },
|
|
209
|
+
{ key: "GOOGLE_CLIENT_SECRET", prompt: "Google OAuth Client Secret", sensitive: true },
|
|
80
210
|
{
|
|
81
211
|
key: "GOOGLE_REFRESH_TOKEN",
|
|
82
212
|
prompt: "Google OAuth Refresh Token",
|
|
83
213
|
help: "Run the OAuth flow after deploy at /api/auth/google",
|
|
84
214
|
optional: true,
|
|
215
|
+
sensitive: true,
|
|
85
216
|
},
|
|
86
217
|
],
|
|
87
218
|
},
|
|
@@ -94,10 +225,13 @@ const PACKS = [
|
|
|
94
225
|
key: "GITHUB_PAT",
|
|
95
226
|
prompt: "GitHub PAT (with repo scope)",
|
|
96
227
|
help: "https://github.com/settings/tokens",
|
|
228
|
+
sensitive: true,
|
|
97
229
|
},
|
|
98
230
|
{
|
|
99
231
|
key: "GITHUB_REPO",
|
|
100
|
-
prompt: "GitHub repo
|
|
232
|
+
prompt: "GitHub repo",
|
|
233
|
+
example: "owner/repo or https://github.com/owner/repo",
|
|
234
|
+
transform: normalizeGitHubRepo,
|
|
101
235
|
},
|
|
102
236
|
],
|
|
103
237
|
},
|
|
@@ -110,12 +244,14 @@ const PACKS = [
|
|
|
110
244
|
key: "BROWSERBASE_API_KEY",
|
|
111
245
|
prompt: "Browserbase API key",
|
|
112
246
|
help: "https://browserbase.com",
|
|
247
|
+
sensitive: true,
|
|
113
248
|
},
|
|
114
249
|
{ key: "BROWSERBASE_PROJECT_ID", prompt: "Browserbase Project ID" },
|
|
115
250
|
{
|
|
116
251
|
key: "OPENROUTER_API_KEY",
|
|
117
252
|
prompt: "OpenRouter API key",
|
|
118
253
|
help: "https://openrouter.ai/keys",
|
|
254
|
+
sensitive: true,
|
|
119
255
|
},
|
|
120
256
|
],
|
|
121
257
|
},
|
|
@@ -128,6 +264,7 @@ const PACKS = [
|
|
|
128
264
|
key: "SLACK_BOT_TOKEN",
|
|
129
265
|
prompt: "Slack Bot User OAuth Token",
|
|
130
266
|
help: "https://api.slack.com/apps → OAuth & Permissions",
|
|
267
|
+
sensitive: true,
|
|
131
268
|
},
|
|
132
269
|
],
|
|
133
270
|
},
|
|
@@ -140,6 +277,7 @@ const PACKS = [
|
|
|
140
277
|
key: "NOTION_API_KEY",
|
|
141
278
|
prompt: "Notion Internal Integration Token",
|
|
142
279
|
help: "https://www.notion.so/my-integrations",
|
|
280
|
+
sensitive: true,
|
|
143
281
|
},
|
|
144
282
|
],
|
|
145
283
|
},
|
|
@@ -152,6 +290,7 @@ const PACKS = [
|
|
|
152
290
|
key: "COMPOSIO_API_KEY",
|
|
153
291
|
prompt: "Composio API key",
|
|
154
292
|
help: "https://composio.dev → Settings",
|
|
293
|
+
sensitive: true,
|
|
155
294
|
},
|
|
156
295
|
],
|
|
157
296
|
},
|
|
@@ -179,10 +318,10 @@ async function main() {
|
|
|
179
318
|
step("1/5", "Project setup");
|
|
180
319
|
|
|
181
320
|
const defaultDir = "mymcp";
|
|
321
|
+
info(`Just type a folder name, or a full path. Default: ${defaultDir}`);
|
|
182
322
|
const rawInput = (await ask(` Project directory [${defaultDir}]: `)).trim();
|
|
183
323
|
const cleaned = cleanPath(rawInput) || defaultDir;
|
|
184
324
|
|
|
185
|
-
// If it's already absolute, use as-is; otherwise resolve relative to CWD
|
|
186
325
|
const projectDir = isAbsolute(cleaned) ? cleaned : resolve(cleaned);
|
|
187
326
|
const projectName = projectDir.split(/[/\\]/).pop();
|
|
188
327
|
|
|
@@ -216,7 +355,6 @@ async function main() {
|
|
|
216
355
|
process.exit(1);
|
|
217
356
|
}
|
|
218
357
|
|
|
219
|
-
// Set up upstream remote for easy updates
|
|
220
358
|
run(`git -C "${projectDir}" remote rename origin upstream`);
|
|
221
359
|
ok("Cloned and upstream remote configured");
|
|
222
360
|
info("Run `npm run update` to pull updates anytime");
|
|
@@ -224,6 +362,7 @@ async function main() {
|
|
|
224
362
|
// ── Step 3: Pick packs ───────────────────────────────────────────
|
|
225
363
|
|
|
226
364
|
step("3/5", "Choose your tool packs");
|
|
365
|
+
info("Press Enter to accept the default (shown in uppercase).");
|
|
227
366
|
log("");
|
|
228
367
|
|
|
229
368
|
const selectedPacks = [];
|
|
@@ -245,39 +384,69 @@ async function main() {
|
|
|
245
384
|
// ── Step 4: Collect credentials ──────────────────────────────────
|
|
246
385
|
|
|
247
386
|
step("4/5", "Configure credentials");
|
|
387
|
+
info("Paste just the value — not the KEY=value format.");
|
|
388
|
+
info("Type 'skip' or press Enter on optional fields to skip.");
|
|
248
389
|
|
|
249
390
|
const envVars = {};
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
ok(`MCP_AUTH_TOKEN generated: ${envVars.MCP_AUTH_TOKEN.slice(0, 8)}...`);
|
|
391
|
+
const mcpToken = randomBytes(32).toString("hex");
|
|
392
|
+
envVars.MCP_AUTH_TOKEN = mcpToken;
|
|
393
|
+
ok(`MCP_AUTH_TOKEN generated: ${maskSecret(mcpToken)}`);
|
|
254
394
|
|
|
255
395
|
// Instance settings
|
|
256
396
|
log("");
|
|
257
|
-
const
|
|
258
|
-
const
|
|
397
|
+
const tzRaw = (await ask(` Timezone (e.g. Europe/Paris, Tokyo, UTC) [UTC]: `)).trim() || "UTC";
|
|
398
|
+
const tz = normalizeTimezone(tzRaw);
|
|
399
|
+
if (tz !== tzRaw && tzRaw.toLowerCase() !== "utc") {
|
|
400
|
+
info(`Normalized to: ${tz}`);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const localeRaw = (await ask(` Locale (e.g. fr, en-US, de) [en-US]: `)).trim() || "en-US";
|
|
404
|
+
const locale = normalizeLocale(localeRaw);
|
|
405
|
+
if (locale !== localeRaw) {
|
|
406
|
+
info(`Normalized to: ${locale}`);
|
|
407
|
+
}
|
|
408
|
+
|
|
259
409
|
const displayName = (await ask(` Display name [User]: `)).trim() || "User";
|
|
410
|
+
|
|
260
411
|
envVars.MYMCP_TIMEZONE = tz;
|
|
261
412
|
envVars.MYMCP_LOCALE = locale;
|
|
262
413
|
envVars.MYMCP_DISPLAY_NAME = displayName;
|
|
263
414
|
|
|
264
415
|
// Pack credentials
|
|
416
|
+
const packStatus = []; // Track for recap
|
|
417
|
+
|
|
265
418
|
for (const pack of selectedPacks) {
|
|
266
419
|
log("");
|
|
267
420
|
log(` ${BOLD}${pack.name}${RESET}`);
|
|
421
|
+
let allSet = true;
|
|
422
|
+
|
|
268
423
|
for (const v of pack.vars) {
|
|
269
424
|
if (v.help) info(v.help);
|
|
270
|
-
if (v.
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
425
|
+
if (v.example) info(`Format: ${v.example}`);
|
|
426
|
+
if (v.optional) info("(optional — press Enter to skip)");
|
|
427
|
+
|
|
428
|
+
const rawValue = (await ask(` ${v.prompt}: `)).trim();
|
|
429
|
+
const cleaned = cleanCredential(rawValue, v.key);
|
|
430
|
+
|
|
431
|
+
if (cleaned) {
|
|
432
|
+
// Apply transform if defined (e.g., GitHub URL → owner/repo)
|
|
433
|
+
const finalValue = v.transform ? v.transform(cleaned) : cleaned;
|
|
434
|
+
envVars[v.key] = finalValue;
|
|
435
|
+
|
|
436
|
+
if (v.sensitive) {
|
|
437
|
+
ok(`${v.key} set (${maskSecret(finalValue)})`);
|
|
438
|
+
} else {
|
|
439
|
+
ok(`${v.key} = ${finalValue}`);
|
|
440
|
+
}
|
|
441
|
+
} else if (v.optional) {
|
|
442
|
+
info(`${v.key} skipped`);
|
|
443
|
+
} else {
|
|
278
444
|
warn(`${v.key} skipped — ${pack.name} pack won't activate until set`);
|
|
445
|
+
allSet = false;
|
|
279
446
|
}
|
|
280
447
|
}
|
|
448
|
+
|
|
449
|
+
packStatus.push({ name: pack.name, active: allSet });
|
|
281
450
|
}
|
|
282
451
|
|
|
283
452
|
// ── Write .env ───────────────────────────────────────────────────
|
|
@@ -285,11 +454,9 @@ async function main() {
|
|
|
285
454
|
const envPath = join(projectDir, ".env");
|
|
286
455
|
const envExamplePath = join(projectDir, ".env.example");
|
|
287
456
|
|
|
288
|
-
// Read .env.example as base, then overlay collected values
|
|
289
457
|
let envContent = "# MyMCP — Generated by create-mymcp\n";
|
|
290
458
|
envContent += `# Created: ${new Date().toISOString().split("T")[0]}\n\n`;
|
|
291
459
|
|
|
292
|
-
// Track which vars we've written so we don't duplicate
|
|
293
460
|
const writtenVars = new Set();
|
|
294
461
|
|
|
295
462
|
if (existsSync(envExamplePath)) {
|
|
@@ -306,7 +473,6 @@ async function main() {
|
|
|
306
473
|
}
|
|
307
474
|
}
|
|
308
475
|
|
|
309
|
-
// Append any remaining vars not in .env.example
|
|
310
476
|
for (const [key, value] of Object.entries(envVars)) {
|
|
311
477
|
if (!writtenVars.has(key)) {
|
|
312
478
|
envContent += `${key}=${value}\n`;
|
|
@@ -320,7 +486,6 @@ async function main() {
|
|
|
320
486
|
|
|
321
487
|
step("5/5", "Install & deploy");
|
|
322
488
|
|
|
323
|
-
// Install dependencies
|
|
324
489
|
log("");
|
|
325
490
|
info("Installing dependencies...");
|
|
326
491
|
const installResult = spawnSync("npm", ["install"], {
|
|
@@ -342,6 +507,8 @@ async function main() {
|
|
|
342
507
|
false
|
|
343
508
|
);
|
|
344
509
|
|
|
510
|
+
let deploySucceeded = false;
|
|
511
|
+
|
|
345
512
|
if (deployVercel) {
|
|
346
513
|
if (!hasCommand("vercel")) {
|
|
347
514
|
info("Installing Vercel CLI...");
|
|
@@ -351,16 +518,24 @@ async function main() {
|
|
|
351
518
|
});
|
|
352
519
|
}
|
|
353
520
|
|
|
521
|
+
// Slugify project name for Vercel
|
|
522
|
+
const vercelName = slugify(projectName);
|
|
523
|
+
if (vercelName !== projectName) {
|
|
524
|
+
info(`Vercel project name: ${vercelName} (slugified from "${projectName}")`);
|
|
525
|
+
}
|
|
526
|
+
|
|
354
527
|
log("");
|
|
355
528
|
info("Running vercel deploy...");
|
|
356
|
-
const vercelResult = spawnSync("vercel", ["--yes"], {
|
|
529
|
+
const vercelResult = spawnSync("vercel", ["--yes", "--name", vercelName], {
|
|
357
530
|
cwd: projectDir,
|
|
358
531
|
stdio: "inherit",
|
|
359
532
|
shell: true,
|
|
533
|
+
env: { ...process.env, NO_UPDATE_NOTIFIER: "1" },
|
|
360
534
|
});
|
|
361
535
|
|
|
362
536
|
if (vercelResult.status === 0) {
|
|
363
537
|
ok("Deployed to Vercel!");
|
|
538
|
+
deploySucceeded = true;
|
|
364
539
|
log("");
|
|
365
540
|
warn("Don't forget to add your env vars in the Vercel dashboard:");
|
|
366
541
|
info("Vercel → Project Settings → Environment Variables");
|
|
@@ -376,19 +551,36 @@ async function main() {
|
|
|
376
551
|
log(`${BOLD} ╔══════════════════════════════════════════╗${RESET}`);
|
|
377
552
|
log(`${BOLD} ║ ${GREEN}Setup complete!${RESET}${BOLD} ║${RESET}`);
|
|
378
553
|
log(`${BOLD} ╚══════════════════════════════════════════╝${RESET}`);
|
|
554
|
+
|
|
555
|
+
// Recap table
|
|
556
|
+
log("");
|
|
557
|
+
log(` ${BOLD}Pack status:${RESET}`);
|
|
558
|
+
for (const ps of packStatus) {
|
|
559
|
+
const icon = ps.active ? `${GREEN}✓${RESET}` : `${YELLOW}○${RESET}`;
|
|
560
|
+
const status = ps.active ? "ready" : "needs credentials";
|
|
561
|
+
log(` ${icon} ${ps.name} — ${status}`);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// Packs not selected
|
|
565
|
+
const selectedIds = new Set(selectedPacks.map((p) => p.id));
|
|
566
|
+
const skippedPacks = PACKS.filter((p) => !selectedIds.has(p.id));
|
|
567
|
+
for (const sp of skippedPacks) {
|
|
568
|
+
log(` ${DIM}– ${sp.name} — not selected${RESET}`);
|
|
569
|
+
}
|
|
570
|
+
|
|
379
571
|
log("");
|
|
380
572
|
log(` ${BOLD}Next steps:${RESET}`);
|
|
381
573
|
log("");
|
|
382
574
|
log(` ${CYAN}cd ${projectName}${RESET}`);
|
|
383
|
-
if (!
|
|
384
|
-
log(` ${CYAN}npm run dev${RESET} ${DIM}# Start locally${RESET}`);
|
|
385
|
-
log(` ${CYAN}vercel${RESET} ${DIM}# Deploy to Vercel${RESET}`);
|
|
575
|
+
if (!deploySucceeded) {
|
|
576
|
+
log(` ${CYAN}npm run dev${RESET} ${DIM}# Start locally at http://localhost:3000${RESET}`);
|
|
577
|
+
log(` ${CYAN}vercel${RESET} ${DIM}# Deploy to Vercel when ready${RESET}`);
|
|
386
578
|
}
|
|
387
|
-
log(` ${
|
|
579
|
+
log(` ${DIM}Then visit: http://localhost:3000/setup${RESET}`);
|
|
388
580
|
log("");
|
|
389
581
|
log(` ${BOLD}Connect to Claude Desktop / Claude Code:${RESET}`);
|
|
390
582
|
log(` ${DIM}Endpoint: https://your-app.vercel.app/api/mcp${RESET}`);
|
|
391
|
-
log(` ${DIM}Token:
|
|
583
|
+
log(` ${DIM}Token: ${maskSecret(mcpToken)}${RESET}`);
|
|
392
584
|
log("");
|
|
393
585
|
log(` ${BOLD}Stay up to date:${RESET}`);
|
|
394
586
|
log(` ${CYAN}npm run update${RESET}`);
|
package/package.json
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@yassinello/create-mymcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Set up your personal MCP server in minutes — interactive installer for MyMCP",
|
|
5
|
-
"bin": {
|
|
6
|
-
"create-mymcp": "./index.mjs"
|
|
7
|
-
},
|
|
8
|
-
"keywords": [
|
|
9
|
-
"mcp",
|
|
10
|
-
"create",
|
|
11
|
-
"installer",
|
|
12
|
-
"claude",
|
|
13
|
-
"chatgpt",
|
|
14
|
-
"ai",
|
|
15
|
-
"model-context-protocol"
|
|
16
|
-
],
|
|
17
|
-
"repository": {
|
|
18
|
-
"type": "git",
|
|
19
|
-
"url": "https://github.com/Yassinello/mymcp",
|
|
20
|
-
"directory": "create-mymcp"
|
|
21
|
-
},
|
|
22
|
-
"license": "MIT",
|
|
23
|
-
"engines": {
|
|
24
|
-
"node": ">=18"
|
|
25
|
-
},
|
|
26
|
-
"files": [
|
|
27
|
-
"index.mjs"
|
|
28
|
-
]
|
|
29
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@yassinello/create-mymcp",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Set up your personal MCP server in minutes — interactive installer for MyMCP",
|
|
5
|
+
"bin": {
|
|
6
|
+
"create-mymcp": "./index.mjs"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"mcp",
|
|
10
|
+
"create",
|
|
11
|
+
"installer",
|
|
12
|
+
"claude",
|
|
13
|
+
"chatgpt",
|
|
14
|
+
"ai",
|
|
15
|
+
"model-context-protocol"
|
|
16
|
+
],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/Yassinello/mymcp",
|
|
20
|
+
"directory": "create-mymcp"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"index.mjs"
|
|
28
|
+
]
|
|
29
|
+
}
|