tmpa-cli 1.0.19 → 1.0.21

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.
Files changed (2) hide show
  1. package/bin/index.js +253 -37
  2. package/package.json +1 -1
package/bin/index.js CHANGED
@@ -43,6 +43,50 @@ const PROVIDERS = {
43
43
  '7': { name: 'Custom / Auto-Detect', endpoint: '', defaultModel: '' }
44
44
  };
45
45
 
46
+ // 100+ POPULAR MCP PRESETS LIST
47
+ const MCP_PRESETS = [
48
+ { id: 'custom', name: '🛠️ Custom / Lainnya', category: 'General', type: 'custom', desc: 'Input Manual Name, Target, & Key' },
49
+
50
+ // Cloud, AI & UI
51
+ { id: 'google-stitch', name: '⚡ Google Stitch', category: 'Cloud & AI', type: 'direct-api', endpoint: 'https://stitch.googleapis.com/v1', reqAuth: 'GOOGLE_STITCH_API_KEY', desc: 'UI & App Prototyping MCP by Google' },
52
+ { id: 'supabase', name: '⚡ Supabase MCP', category: 'Cloud & AI', type: 'direct-api', endpoint: 'https://api.supabase.com/mcp', reqAuth: 'SUPABASE_ACCESS_TOKEN', desc: 'Database, Auth & Storage Management' },
53
+ { id: 'cloudflare-workers', name: '☁️ Cloudflare Workers', category: 'Cloud & AI', type: 'stdio', command: 'npx -y @cloudflare/mcp-server-cloudflare', reqAuth: 'CLOUDFLARE_API_TOKEN', desc: 'Deploy & manage edge functions' },
54
+ { id: 'vercel', name: '▲ Vercel MCP', category: 'Cloud & AI', type: 'direct-api', endpoint: 'https://api.vercel.com/v1/mcp', reqAuth: 'VERCEL_TOKEN', desc: 'Manage projects & deployments' },
55
+ { id: 'railway', name: '🚂 Railway MCP', category: 'Cloud & AI', type: 'direct-api', endpoint: 'https://backboard.railway.app/mcp', reqAuth: 'RAILWAY_API_TOKEN', desc: 'Cloud infrastructure & DB runner' },
56
+ { id: 'firebase', name: '🔥 Firebase MCP', category: 'Cloud & AI', type: 'stdio', command: 'npx -y firebase-mcp-server', reqAuth: 'FIREBASE_TOKEN', desc: 'Firestore, Auth & Realtime DB' },
57
+ { id: 'huggingface', name: '🤗 HuggingFace Spaces', category: 'Cloud & AI', type: 'direct-api', endpoint: 'https://huggingface.co/api/mcp', reqAuth: 'HF_TOKEN', desc: 'Run open-source AI models & spaces' },
58
+ { id: 'replicate', name: '🌀 Replicate MCP', category: 'Cloud & AI', type: 'stdio', command: 'npx -y @replicate/mcp-server', reqAuth: 'REPLICATE_API_TOKEN', desc: 'Run image/video AI generation models' },
59
+
60
+ // Developer Tools & VCS
61
+ { id: 'github', name: '🐙 GitHub Official', category: 'Developer Tools', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-github', reqAuth: 'GITHUB_PERSONAL_ACCESS_TOKEN', desc: 'Repository, Issues, PRs & Gists' },
62
+ { id: 'gitlab', name: '🦊 GitLab MCP', category: 'Developer Tools', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-gitlab', reqAuth: 'GITLAB_PERSONAL_ACCESS_TOKEN', desc: 'GitLab projects & CI/CD pipelines' },
63
+ { id: 'postman', name: '🚀 Postman MCP', category: 'Developer Tools', type: 'stdio', command: 'npx -y @postman/mcp-server', reqAuth: 'POSTMAN_API_KEY', desc: 'API Collection testing & documentation' },
64
+ { id: 'sentry', name: '🛡️ Sentry Error Tracker', category: 'Developer Tools', type: 'stdio', command: 'npx -y @sentry/mcp-server', reqAuth: 'SENTRY_AUTH_TOKEN', desc: 'Inspect application bugs & stacktraces' },
65
+ { id: 'docker', name: '🐳 Docker Local MCP', category: 'Developer Tools', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-docker', desc: 'Manage local containers & images' },
66
+
67
+ // Databases & Storage
68
+ { id: 'postgresql', name: '🗄️ PostgreSQL', category: 'Databases', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-postgres', reqAuth: 'DATABASE_URL', desc: 'Direct SQL query execution' },
69
+ { id: 'mysql', name: '🐬 MySQL MCP', category: 'Databases', type: 'stdio', command: 'npx -y mysql-mcp-server', reqAuth: 'MYSQL_CONNECTION_STRING', desc: 'MySQL relational database runner' },
70
+ { id: 'sqlite', name: '📦 SQLite Local', category: 'Databases', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-sqlite', desc: 'Lightweight local database query tool' },
71
+ { id: 'mongodb', name: '🍃 MongoDB MCP', category: 'Databases', type: 'stdio', command: 'npx -y mongodb-mcp-server', reqAuth: 'MONGODB_URI', desc: 'NoSQL collection queries & aggregation' },
72
+ { id: 'redis', name: '🔴 Redis Cache', category: 'Databases', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-redis', reqAuth: 'REDIS_URL', desc: 'Key-value data structure store' },
73
+ { id: 'pinecone', name: '🌲 Pinecone Vector DB', category: 'Databases', type: 'direct-api', endpoint: 'https://api.pinecone.io/mcp', reqAuth: 'PINECONE_API_KEY', desc: 'Vector database for AI embeddings' },
74
+
75
+ // Search & Web Scraping
76
+ { id: 'brave-search', name: '🦁 Brave Search', category: 'Search & Scraping', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-brave-search', reqAuth: 'BRAVE_API_KEY', desc: 'Real-time global web search engine' },
77
+ { id: 'tavily', name: '🔍 Tavily AI Search', category: 'Search & Scraping', type: 'stdio', command: 'npx -y tavily-mcp', reqAuth: 'TAVILY_API_KEY', desc: 'Optimized search engine for LLMs' },
78
+ { id: 'puppeteer', name: '🌐 Puppeteer Scraper', category: 'Search & Scraping', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-puppeteer', desc: 'Headless browser web automation & screenshot' },
79
+ { id: 'firecrawl', name: '🔥 Firecrawl Scraper', category: 'Search & Scraping', type: 'direct-api', endpoint: 'https://api.firecrawl.dev/v1/mcp', reqAuth: 'FIRECRAWL_API_KEY', desc: 'Convert entire websites to clean Markdown' },
80
+ { id: 'fetch', name: '📡 Fetch HTTP Utility', category: 'Search & Scraping', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-fetch', desc: 'HTTP request & web page parser' },
81
+
82
+ // Productivity & Communication
83
+ { id: 'notion', name: '📄 Notion Workspace', category: 'Productivity', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-notion', reqAuth: 'NOTION_API_TOKEN', desc: 'Read & edit Notion pages and databases' },
84
+ { id: 'slack', name: '💬 Slack Channel', category: 'Productivity', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-slack', reqAuth: 'SLACK_BOT_TOKEN', desc: 'Send messages & read channels' },
85
+ { id: 'discord', name: '🎮 Discord Bot MCP', category: 'Productivity', type: 'stdio', command: 'npx -y discord-mcp-server', reqAuth: 'DISCORD_BOT_TOKEN', desc: 'Interact with Discord servers & channels' },
86
+ { id: 'linear', name: '📐 Linear Issue Tracker', category: 'Productivity', type: 'stdio', command: 'npx -y @linear/mcp-server', reqAuth: 'LINEAR_API_KEY', desc: 'Manage project issues & sprint cycles' },
87
+ { id: 'google-drive', name: '📁 Google Drive', category: 'Productivity', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-gdrive', reqAuth: 'GDRIVE_CLIENT_ID', desc: 'Access Drive documents & sheets' }
88
+ ];
89
+
46
90
  function loadConfig() {
47
91
  if (fs.existsSync(CONFIG_FILE)) {
48
92
  try { return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8')); } catch (e) { return {}; }
@@ -90,7 +134,7 @@ ${C.c3} ██║ ██║╚██╔╝██║██╔═══╝ █
90
134
  ${C.c4} ██║ ██║ ╚═╝ ██║██║ ██║ ██║${C.reset}
91
135
  ${C.c4} ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝${C.reset}
92
136
  ${C.darkGray}────────────────────────────────────────────────────────────${C.reset}
93
- ${C.reset}The Multi Platform AI ${C.green}[MCP Hub & Tool Engine]${C.reset}
137
+ ${C.reset}The Multi Platform AI ${C.green}[MCP Hub & Interactive Provider Engine]${C.reset}
94
138
  ${C.gray}/config | /models | /skill | /mcp | /new-mcp | /scan | /exit${C.reset}
95
139
  ${C.darkGray}────────────────────────────────────────────────────────────${C.reset}
96
140
  `);
@@ -137,11 +181,11 @@ function readResourceContent(targetPath) {
137
181
  function getActiveToolsContext(forcedTool = null) {
138
182
  if (forcedTool) {
139
183
  let rawContent = "";
140
- if (forcedTool.type === 'mcp') {
184
+ if (forcedTool.type === 'mcp' || forcedTool.type === 'stdio' || forcedTool.type === 'direct-api') {
141
185
  rawContent = `MCP Server Info:
142
186
  Name: ${forcedTool.name}
143
187
  Target/Endpoint: ${forcedTool.target}
144
- Type: ${forcedTool.mcpType || 'HTTP/SSE'}
188
+ Type: ${forcedTool.mcpType || 'stdio/api'}
145
189
  Auth Token: ${forcedTool.authToken ? 'Provided' : 'None'}`;
146
190
  } else {
147
191
  rawContent = readResourceContent(forcedTool.target);
@@ -190,7 +234,7 @@ function showMCPHub() {
190
234
  console.log(`${C.bold}Daftar MCP Server Aktif:${C.reset}`);
191
235
  keys.forEach((name, i) => {
192
236
  const m = registry.mcp[name];
193
- const typeBadge = m.type === 'remote' ? `${C.cyan}[Remote SSE/HTTP]${C.reset}` : `${C.green}[Local Stdio]${C.reset}`;
237
+ const typeBadge = m.type === 'remote' || m.type === 'direct-api' ? `${C.cyan}[${m.type}]${C.reset}` : `${C.green}[stdio]${C.reset}`;
194
238
  console.log(` ${C.yellow}${i + 1}.${C.reset} ${C.bold}${name}${C.reset} ${typeBadge}`);
195
239
  console.log(` ↳ Target: ${C.gray}${m.target}${C.reset}`);
196
240
  if (m.authToken) console.log(` ↳ Auth : ${C.green}Encrypted/Token set${C.reset}`);
@@ -200,7 +244,7 @@ function showMCPHub() {
200
244
 
201
245
  const lines = [
202
246
  `${C.bold}Command Instan MCP:${C.reset}`,
203
- `${C.yellow}/new-mcp${C.reset} 👉 Tambah MCP Server Baru (Wizard)`,
247
+ `${C.yellow}/new-mcp${C.reset} 👉 Tambah MCP Server Baru (Interactive Selector)`,
204
248
  `${C.yellow}/mcp-<nama>${C.reset} <prompt> 👉 Eksekusi MCP secara spesifik`,
205
249
  `${C.yellow}/scan${C.reset} 👉 Pindai folder .mcp otomatis`
206
250
  ];
@@ -209,52 +253,224 @@ function showMCPHub() {
209
253
  console.log('');
210
254
  }
211
255
 
212
- // WIZARD KONFIGURASI MCP BARU (/new-mcp)
213
- function createNewMCPWizard(callback) {
214
- console.log(`\n${C.cyan}=== 🛠️ SETUP MCP (MODEL CONTEXT PROTOCOL) BARU ===${C.reset}\n`);
256
+ // INTERACTIVE ARROW-KEY SELECTOR FOR TERMUX & COMPUTERS
257
+ function interactiveProviderSelector(allItems, onSelect, onCancel) {
258
+ let filteredItems = [...allItems];
259
+ let selectedIndex = 0;
260
+ let currentPage = 0;
261
+ const pageSize = 8;
262
+
263
+ const wasRaw = process.stdin.isRaw;
264
+
265
+ function cleanup() {
266
+ process.stdin.removeListener('keypress', handleKeypress);
267
+ if (process.stdin.setRawMode) process.stdin.setRawMode(wasRaw || false);
268
+ }
269
+
270
+ function renderMenu() {
271
+ console.clear();
272
+ const totalPages = Math.ceil(filteredItems.length / pageSize) || 1;
273
+ if (currentPage >= totalPages) currentPage = totalPages - 1;
274
+ if (currentPage < 0) currentPage = 0;
275
+
276
+ const startIdx = currentPage * pageSize;
277
+ const pageItems = filteredItems.slice(startIdx, startIdx + pageSize);
215
278
 
216
- rl.question(`${C.yellow}[1/4] Masukkan Nama MCP Server (misal: stitch, github, filesystem):${C.reset} `, (nameInput) => {
217
- const mcpName = nameInput.trim().toLowerCase().replace(/\s+/g, '-');
218
- if (!mcpName) {
219
- console.log(`${C.red}[x] Nama MCP tidak boleh kosong.${C.reset}\n`);
220
- return callback();
279
+ if (selectedIndex >= pageItems.length) selectedIndex = Math.max(0, pageItems.length - 1);
280
+
281
+ console.log(`${C.c4}============================================================${C.reset}`);
282
+ console.log(`${C.c4} 🔌 SETUP & INTEGRASI MCP SERVER PROVIDER ${C.reset}`);
283
+ console.log(`${C.c4}============================================================${C.reset}\n`);
284
+
285
+ if (pageItems.length === 0) {
286
+ console.log(`${C.red} Tidak ada provider yang cocok dengan pencarian.${C.reset}\n`);
287
+ } else {
288
+ pageItems.forEach((item, idx) => {
289
+ const globalNum = startIdx + idx;
290
+ const isFocused = idx === selectedIndex;
291
+ const pointer = isFocused ? `${C.cyan}❯${C.reset}` : ' ';
292
+ const numStr = globalNum.toString().padStart(2, ' ');
293
+ const badge = item.type ? `${C.gray}[${item.type}]${C.reset}` : '';
294
+ const nameStyled = isFocused ? `${C.bold}${C.green}${item.name}${C.reset}` : item.name;
295
+
296
+ console.log(`${pointer} ${C.yellow}${numStr}.${C.reset} • ${nameStyled} ${badge}`);
297
+ console.log(` ${C.darkGray}${item.desc || item.category}${C.reset}`);
298
+ });
221
299
  }
222
300
 
223
- console.log(`\n${C.cyan}Pilih Tipe Koneksi MCP:${C.reset}`);
224
- console.log(` ${C.yellow}1.${C.reset} Remote URL / SSE Endpoint (misal: https://mcp.example.com/sse)`);
225
- console.log(` ${C.yellow}2.${C.reset} Local Command / File Path (misal: npx -y @modelcontextprotocol/server-filesystem)`);
301
+ console.log(`\n${C.darkGray}────────────────────────────────────────────────────────────${C.reset}`);
302
+ console.log(`${C.cyan}Halaman ${currentPage + 1}/${totalPages}${C.reset} | Total: ${filteredItems.length} Provider`);
303
+ console.log(`${C.gray}🎮 Navigasi: [▲/▼] Panah Termux/Keyboard | [Enter] Pilih${C.reset}`);
304
+ console.log(`${C.gray}⌨️ Atau: Ketik Angka | [f] Cari Nama | [n] Next | [p] Prev | [q] Batal${C.reset}`);
305
+ console.log(`${C.darkGray}────────────────────────────────────────────────────────────${C.reset}\n`);
306
+ }
226
307
 
227
- rl.question(`\n${C.yellow}[2/4] Pilih Tipe (1/2):${C.reset} `, (typeChoice) => {
228
- const isRemote = typeChoice.trim() === '1';
308
+ readline.emitKeypressEvents(process.stdin);
309
+ if (process.stdin.setRawMode) process.stdin.setRawMode(true);
229
310
 
230
- rl.question(`${C.yellow}[3/4] Masukkan Target URL / Command Path:${C.reset} `, (targetInput) => {
231
- const target = targetInput.trim();
232
- if (!target) {
233
- console.log(`${C.red}[x] Target tidak boleh kosong.${C.reset}\n`);
234
- return callback();
235
- }
311
+ function handleKeypress(str, key) {
312
+ const totalPages = Math.ceil(filteredItems.length / pageSize) || 1;
313
+ const startIdx = currentPage * pageSize;
314
+ const pageItems = filteredItems.slice(startIdx, startIdx + pageSize);
315
+
316
+ if (key.name === 'up') {
317
+ if (selectedIndex > 0) {
318
+ selectedIndex--;
319
+ } else if (currentPage > 0) {
320
+ currentPage--;
321
+ selectedIndex = pageSize - 1;
322
+ }
323
+ renderMenu();
324
+ } else if (key.name === 'down') {
325
+ if (selectedIndex < pageItems.length - 1) {
326
+ selectedIndex++;
327
+ } else if (currentPage < totalPages - 1) {
328
+ currentPage++;
329
+ selectedIndex = 0;
330
+ }
331
+ renderMenu();
332
+ } else if (key.name === 'return') {
333
+ cleanup();
334
+ const selectedObj = pageItems[selectedIndex];
335
+ if (selectedObj) onSelect(selectedObj);
336
+ } else if (str === 'q' || str === 'Q' || (key.ctrl && key.name === 'c')) {
337
+ cleanup();
338
+ onCancel();
339
+ } else if (str === 'n' || str === 'N') {
340
+ if (currentPage < totalPages - 1) currentPage++;
341
+ selectedIndex = 0;
342
+ renderMenu();
343
+ } else if (str === 'p' || str === 'P') {
344
+ if (currentPage > 0) currentPage--;
345
+ selectedIndex = 0;
346
+ renderMenu();
347
+ } else if (str === 'f' || str === 'F') {
348
+ cleanup();
349
+ rl.question(`\n${C.yellow}[>] Ketik kata kunci pencarian provider:${C.reset} `, (query) => {
350
+ const q = query.trim().toLowerCase();
351
+ filteredItems = allItems.filter(item => item.name.toLowerCase().includes(q) || (item.desc && item.desc.toLowerCase().includes(q)));
352
+ currentPage = 0;
353
+ selectedIndex = 0;
354
+ interactiveProviderSelector(filteredItems, onSelect, onCancel);
355
+ });
356
+ } else if (!isNaN(str) && str !== ' ' && str !== '') {
357
+ cleanup();
358
+ const num = parseInt(str);
359
+ if (num >= 0 && num < allItems.length) {
360
+ onSelect(allItems[num]);
361
+ } else {
362
+ console.log(`${C.red}Nomor tidak valid.${C.reset}`);
363
+ setTimeout(() => interactiveProviderSelector(allItems, onSelect, onCancel), 800);
364
+ }
365
+ }
366
+ }
367
+
368
+ process.stdin.on('keypress', handleKeypress);
369
+ renderMenu();
370
+ }
236
371
 
237
- rl.question(`${C.yellow}[4/4] Masukkan Auth Token / API Key (Tekan Enter jika tidak ada):${C.reset} `, (tokenInput) => {
238
- const authToken = tokenInput.trim();
372
+ // WIZARD KONFIGURASI MCP BARU (/new-mcp)
373
+ function createNewMCPWizard(callback) {
374
+ interactiveProviderSelector(
375
+ MCP_PRESETS,
376
+ (selectedProvider) => {
377
+ console.clear();
378
+
379
+ // CASE 1: CUSTOM MCP INPUT MANUAL
380
+ if (selectedProvider.id === 'custom') {
381
+ console.log(`\n${C.cyan}=== 🛠️ SETUP MCP MANUAL (CUSTOM) ===${C.reset}\n`);
382
+ rl.question(`${C.yellow}[1/4] Masukkan Nama MCP Server (misal: my-mcp):${C.reset} `, (nameInput) => {
383
+ const mcpName = nameInput.trim().toLowerCase().replace(/\s+/g, '-');
384
+ if (!mcpName) {
385
+ console.log(`${C.red}[x] Nama MCP tidak boleh kosong.${C.reset}\n`);
386
+ return callback();
387
+ }
239
388
 
389
+ console.log(`\n${C.cyan}Pilih Tipe Koneksi MCP:${C.reset}`);
390
+ console.log(` ${C.yellow}1.${C.reset} Direct REST API / Endpoint`);
391
+ console.log(` ${C.yellow}2.${C.reset} Local Stdio Command / Path`);
392
+
393
+ rl.question(`\n${C.yellow}[2/4] Pilih Tipe (1/2):${C.reset} `, (typeChoice) => {
394
+ const isApi = typeChoice.trim() === '1';
395
+
396
+ rl.question(`${C.yellow}[3/4] Masukkan Target URL / Command Executable:${C.reset} `, (targetInput) => {
397
+ const target = targetInput.trim();
398
+ if (!target) {
399
+ console.log(`${C.red}[x] Target tidak boleh kosong.${C.reset}\n`);
400
+ return callback();
401
+ }
402
+
403
+ rl.question(`${C.yellow}[4/4] Masukkan Auth Token / API Key (Opsional - Press Enter to skip):${C.reset} `, (tokenInput) => {
404
+ const authToken = tokenInput.trim();
405
+
406
+ registry.mcp = registry.mcp || {};
407
+ registry.mcp[mcpName] = {
408
+ target: target,
409
+ type: isApi ? 'direct-api' : 'stdio',
410
+ authToken: authToken || null,
411
+ connectedAt: new Date().toISOString(),
412
+ status: 'Connected'
413
+ };
414
+
415
+ saveRegistry(registry);
416
+
417
+ console.log(`\n${C.green}[✔] MCP Server "${mcpName}" berhasil ditambahkan!${C.reset}`);
418
+ console.log(`${C.gray}Gunakan perintah instan: ${C.yellow}/mcp-${mcpName} <prompt kamu>${C.reset}\n`);
419
+ callback();
420
+ });
421
+ });
422
+ });
423
+ });
424
+ }
425
+ // CASE 2: PRESET PROVIDER POPULER
426
+ else {
427
+ console.log(`\n${C.cyan}=== ⚡ SETUP PROVIDER: ${selectedProvider.name} ===${C.reset}`);
428
+ console.log(`${C.gray}${selectedProvider.desc}${C.reset}\n`);
429
+
430
+ const mcpName = selectedProvider.id;
431
+
432
+ if (selectedProvider.reqAuth) {
433
+ rl.question(`${C.yellow}[>] Masukkan ${selectedProvider.reqAuth}: ${C.reset}`, (authVal) => {
434
+ const token = authVal.trim();
435
+
436
+ registry.mcp = registry.mcp || {};
437
+ registry.mcp[mcpName] = {
438
+ target: selectedProvider.endpoint || selectedProvider.command,
439
+ type: selectedProvider.type,
440
+ authToken: token || null,
441
+ connectedAt: new Date().toISOString(),
442
+ status: 'Connected'
443
+ };
444
+
445
+ saveRegistry(registry);
446
+
447
+ console.log(`\n${C.green}[✔] Preset MCP "${selectedProvider.name}" berhasil terhubung!${C.reset}`);
448
+ console.log(`${C.gray}Akses instan via: ${C.yellow}/mcp-${mcpName} <prompt kamu>${C.reset}\n`);
449
+ callback();
450
+ });
451
+ } else {
240
452
  registry.mcp = registry.mcp || {};
241
453
  registry.mcp[mcpName] = {
242
- target: target,
243
- type: isRemote ? 'remote' : 'local',
244
- authToken: authToken || null,
454
+ target: selectedProvider.endpoint || selectedProvider.command,
455
+ type: selectedProvider.type,
456
+ authToken: null,
245
457
  connectedAt: new Date().toISOString(),
246
458
  status: 'Connected'
247
459
  };
248
460
 
249
461
  saveRegistry(registry);
250
462
 
251
- console.log(`\n${C.green}[✔] MCP Server "${mcpName}" berhasil ditambahkan!${C.reset}`);
252
- console.log(`${C.gray}Gunakan perintah instan: ${C.yellow}/mcp-${mcpName} <prompt kamu>${C.reset}\n`);
463
+ console.log(`\n${C.green}[✔] Preset MCP "${selectedProvider.name}" berhasil terhubung!${C.reset}`);
464
+ console.log(`${C.gray}Akses instan via: ${C.yellow}/mcp-${mcpName} <prompt kamu>${C.reset}\n`);
253
465
  callback();
254
- });
255
- });
256
- });
257
- });
466
+ }
467
+ }
468
+ },
469
+ () => {
470
+ console.log(`\n${C.gray}Setup MCP dibatalkan.${C.reset}\n`);
471
+ callback();
472
+ }
473
+ );
258
474
  }
259
475
 
260
476
  function listSkills() {
@@ -313,7 +529,7 @@ function connectResource(inputArgs) {
313
529
  registry.mcp = registry.mcp || {};
314
530
  registry.mcp[mcpName] = {
315
531
  target: targetPath,
316
- type: targetPath.startsWith('http') ? 'remote' : 'local',
532
+ type: targetPath.startsWith('http') ? 'direct-api' : 'stdio',
317
533
  connectedAt: new Date().toISOString(),
318
534
  status: 'Connected'
319
535
  };
@@ -359,7 +575,7 @@ function scanResources() {
359
575
  registry.skills[name] = { path: fullPath, connectedAt: new Date().toISOString(), status: 'Active' };
360
576
  newDetected.push(`/skill-${name}`);
361
577
  } else if (type === 'mcp' && !registry.mcp[name]) {
362
- registry.mcp[name] = { target: fullPath, type: 'local', connectedAt: new Date().toISOString(), status: 'Connected' };
578
+ registry.mcp[name] = { target: fullPath, type: 'stdio', connectedAt: new Date().toISOString(), status: 'Connected' };
363
579
  newDetected.push(`/mcp-${name}`);
364
580
  }
365
581
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tmpa-cli",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "bin": {