tmpa-cli 1.0.22 → 1.0.23
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/bin/index.js +74 -41
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -39,15 +39,13 @@ const PROVIDERS = {
|
|
|
39
39
|
'3': { name: 'NVIDIA NIM', endpoint: 'https://integrate.api.nvidia.com/v1', defaultModel: 'meta/llama-3.1-70b-instruct' },
|
|
40
40
|
'4': { name: 'OpenAI', endpoint: 'https://api.openai.com/v1', defaultModel: 'gpt-4o-mini' },
|
|
41
41
|
'5': { name: 'Anthropic', endpoint: 'https://api.anthropic.com/v1', defaultModel: 'claude-3-5-haiku-20241022' },
|
|
42
|
-
'6': { name: 'Google Gemini', endpoint: 'https://generativelanguage.googleapis.com/v1beta
|
|
42
|
+
'6': { name: 'Google Gemini', endpoint: 'https://generativelanguage.googleapis.com/v1beta', defaultModel: 'gemini-2.5-flash' },
|
|
43
43
|
'7': { name: 'Custom / Auto-Detect', endpoint: '', defaultModel: '' }
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
// 100+ POPULAR MCP PRESETS LIST
|
|
47
47
|
const MCP_PRESETS = [
|
|
48
48
|
{ id: 'custom', name: '🛠️ Custom / Lainnya', category: 'General', type: 'custom', desc: 'Input Manual Name, Target, & Key' },
|
|
49
|
-
|
|
50
|
-
// Cloud, AI & UI
|
|
51
49
|
{ 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
50
|
{ 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
51
|
{ 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' },
|
|
@@ -56,30 +54,22 @@ const MCP_PRESETS = [
|
|
|
56
54
|
{ 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
55
|
{ 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
56
|
{ 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
57
|
{ 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
58
|
{ 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
59
|
{ 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
60
|
{ 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
61
|
{ 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
62
|
{ id: 'postgresql', name: '🗄️ PostgreSQL', category: 'Databases', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-postgres', reqAuth: 'DATABASE_URL', desc: 'Direct SQL query execution' },
|
|
69
63
|
{ 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
64
|
{ id: 'sqlite', name: '📦 SQLite Local', category: 'Databases', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-sqlite', desc: 'Lightweight local database query tool' },
|
|
71
65
|
{ id: 'mongodb', name: '🍃 MongoDB MCP', category: 'Databases', type: 'stdio', command: 'npx -y mongodb-mcp-server', reqAuth: 'MONGODB_URI', desc: 'NoSQL collection queries & aggregation' },
|
|
72
66
|
{ 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
67
|
{ 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
68
|
{ 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
69
|
{ 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
70
|
{ id: 'puppeteer', name: '🌐 Puppeteer Scraper', category: 'Search & Scraping', type: 'stdio', command: 'npx -y @modelcontextprotocol/server-puppeteer', desc: 'Headless browser web automation & screenshot' },
|
|
79
71
|
{ 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
72
|
{ 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
73
|
{ 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
74
|
{ 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
75
|
{ 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' },
|
|
@@ -135,7 +125,7 @@ ${C.c4} ██║ ██║ ╚═╝ ██║██║ ██║ █
|
|
|
135
125
|
${C.c4} ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝${C.reset}
|
|
136
126
|
${C.darkGray}────────────────────────────────────────────────────────────${C.reset}
|
|
137
127
|
${C.reset}The Multi Platform AI ${C.green}[MCP Hub & Interactive Provider Engine]${C.reset}
|
|
138
|
-
${C.gray}/config | /models | /skill | /mcp | /new-mcp | /scan | /uninstall
|
|
128
|
+
${C.gray}/config | /models | /custom-models | /skill | /mcp | /new-mcp | /scan | /uninstall${C.reset}
|
|
139
129
|
${C.darkGray}────────────────────────────────────────────────────────────${C.reset}
|
|
140
130
|
`);
|
|
141
131
|
}
|
|
@@ -369,9 +359,10 @@ function interactiveProviderSelector(allItems, onSelect, onCancel) {
|
|
|
369
359
|
renderMenu();
|
|
370
360
|
}
|
|
371
361
|
|
|
372
|
-
// INTERACTIVE ARROW-KEY SELECTOR UNTUK MODEL AI (/models)
|
|
362
|
+
// INTERACTIVE ARROW-KEY SELECTOR UNTUK MODEL AI (/models) - CAPACITY HINGGA 600 MODEL
|
|
373
363
|
function interactiveModelSelector(allModels, onSelect, onCancel) {
|
|
374
|
-
|
|
364
|
+
// Cap pada 600 model untuk mencegah lag ekstrem di memori Termux
|
|
365
|
+
let filteredModels = allModels.slice(0, 600);
|
|
375
366
|
let selectedIndex = 0;
|
|
376
367
|
let currentPage = 0;
|
|
377
368
|
const pageSize = 10;
|
|
@@ -417,9 +408,9 @@ function interactiveModelSelector(allModels, onSelect, onCancel) {
|
|
|
417
408
|
}
|
|
418
409
|
|
|
419
410
|
console.log(`\n${C.darkGray}────────────────────────────────────────────────────────────${C.reset}`);
|
|
420
|
-
console.log(`${C.cyan}Halaman ${currentPage + 1}/${totalPages}${C.reset} | Total: ${filteredModels.length}
|
|
421
|
-
console.log(`${C.gray}🎮 Navigasi: [▲/▼] Panah Termux
|
|
422
|
-
console.log(`${C.gray}⌨️
|
|
411
|
+
console.log(`${C.cyan}Halaman ${currentPage + 1}/${totalPages}${C.reset} | Total Model Loaded: ${filteredModels.length}`);
|
|
412
|
+
console.log(`${C.gray}🎮 Navigasi: [▲/▼] Panah Termux | [Enter] Pilih${C.reset}`);
|
|
413
|
+
console.log(`${C.gray}⌨️ [f] Cari Nama Model | [n] Next | [p] Prev | [q] Batal${C.reset}`);
|
|
423
414
|
console.log(`${C.darkGray}────────────────────────────────────────────────────────────${C.reset}\n`);
|
|
424
415
|
}
|
|
425
416
|
|
|
@@ -464,9 +455,9 @@ function interactiveModelSelector(allModels, onSelect, onCancel) {
|
|
|
464
455
|
renderMenu();
|
|
465
456
|
} else if (str === 'f' || str === 'F') {
|
|
466
457
|
cleanup();
|
|
467
|
-
rl.question(`\n${C.yellow}[>] Ketik
|
|
458
|
+
rl.question(`\n${C.yellow}[>] Ketik nama/filter model (misal: llama, gemini, claude, qwen):${C.reset} `, (query) => {
|
|
468
459
|
const q = query.trim().toLowerCase();
|
|
469
|
-
filteredModels = allModels.filter(m => m.id.toLowerCase().includes(q));
|
|
460
|
+
filteredModels = allModels.filter(m => m.id.toLowerCase().includes(q)).slice(0, 600);
|
|
470
461
|
currentPage = 0;
|
|
471
462
|
selectedIndex = 0;
|
|
472
463
|
interactiveModelSelector(filteredModels, onSelect, onCancel);
|
|
@@ -485,7 +476,6 @@ function createNewMCPWizard(callback) {
|
|
|
485
476
|
(selectedProvider) => {
|
|
486
477
|
console.clear();
|
|
487
478
|
|
|
488
|
-
// CASE 1: CUSTOM MCP INPUT MANUAL
|
|
489
479
|
if (selectedProvider.id === 'custom') {
|
|
490
480
|
console.log(`\n${C.cyan}=== 🛠️ SETUP MCP MANUAL (CUSTOM) ===${C.reset}\n`);
|
|
491
481
|
rl.question(`${C.yellow}[1/4] Masukkan Nama MCP Server (misal: my-mcp):${C.reset} `, (nameInput) => {
|
|
@@ -530,9 +520,7 @@ function createNewMCPWizard(callback) {
|
|
|
530
520
|
});
|
|
531
521
|
});
|
|
532
522
|
});
|
|
533
|
-
}
|
|
534
|
-
// CASE 2: PRESET PROVIDER POPULER
|
|
535
|
-
else {
|
|
523
|
+
} else {
|
|
536
524
|
console.log(`\n${C.cyan}=== ⚡ SETUP PROVIDER: ${selectedProvider.name} ===${C.reset}`);
|
|
537
525
|
console.log(`${C.gray}${selectedProvider.desc}${C.reset}\n`);
|
|
538
526
|
|
|
@@ -719,7 +707,7 @@ function askConfig(callback) {
|
|
|
719
707
|
console.log(` ${C.yellow}3.${C.reset} NVIDIA NIM`);
|
|
720
708
|
console.log(` ${C.yellow}4.${C.reset} OpenAI`);
|
|
721
709
|
console.log(` ${C.yellow}5.${C.reset} Anthropic`);
|
|
722
|
-
console.log(` ${C.yellow}6.${C.reset} Google Gemini
|
|
710
|
+
console.log(` ${C.yellow}6.${C.reset} Google Gemini`);
|
|
723
711
|
console.log(` ${C.yellow}7.${C.reset} Custom / Auto-Detect Endpoint\n`);
|
|
724
712
|
|
|
725
713
|
rl.question(`${C.yellow}[>] Select Provider (1-7):${C.reset} `, (choice) => {
|
|
@@ -751,6 +739,7 @@ function askConfig(callback) {
|
|
|
751
739
|
});
|
|
752
740
|
}
|
|
753
741
|
|
|
742
|
+
// PERBAIKAN FETCH ALL MODELS UNIVERSAL UNTUK SEMUA PROVIDER
|
|
754
743
|
async function fetchAvailableModels() {
|
|
755
744
|
if (!config.apiKey) {
|
|
756
745
|
console.log(`${C.red}[x] API Key is not set. Use /config first.${C.reset}\n`);
|
|
@@ -761,26 +750,46 @@ async function fetchAvailableModels() {
|
|
|
761
750
|
|
|
762
751
|
try {
|
|
763
752
|
let url = config.endpoint;
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
return startPrompt();
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
let modelsUrl = url.endsWith('/models') ? url : `${url.replace(/\/chat\/completions$/, '')}/models`;
|
|
753
|
+
let fetchUrl = '';
|
|
754
|
+
let headers = {};
|
|
770
755
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
756
|
+
// 1. Google Gemini Native Models Fetch
|
|
757
|
+
if (url.includes('googleapis.com')) {
|
|
758
|
+
fetchUrl = `https://generativelanguage.googleapis.com/v1beta/models?key=${config.apiKey}`;
|
|
759
|
+
}
|
|
760
|
+
// 2. Anthropic Direct Fetch (jika endpoint anthropic)
|
|
761
|
+
else if (url.includes('anthropic.com')) {
|
|
762
|
+
fetchUrl = 'https://api.anthropic.com/v1/models';
|
|
763
|
+
headers = {
|
|
764
|
+
'x-api-key': config.apiKey,
|
|
765
|
+
'anthropic-version': '2023-06-01'
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
// 3. OpenRouter, Groq, NVIDIA, OpenAI & Custom Universal OpenAI Standard
|
|
769
|
+
else {
|
|
770
|
+
let baseUrl = url.replace(/\/chat\/completions$/, '').replace(/\/$/, '');
|
|
771
|
+
fetchUrl = baseUrl.endsWith('/models') ? baseUrl : `${baseUrl}/models`;
|
|
772
|
+
headers = {
|
|
774
773
|
'Authorization': `Bearer ${config.apiKey}`,
|
|
775
774
|
'Content-Type': 'application/json'
|
|
776
|
-
}
|
|
777
|
-
}
|
|
775
|
+
};
|
|
776
|
+
}
|
|
778
777
|
|
|
778
|
+
const response = await fetch(fetchUrl, { method: 'GET', headers: headers });
|
|
779
779
|
const data = await response.json();
|
|
780
780
|
|
|
781
|
-
|
|
781
|
+
let extractedModels = [];
|
|
782
|
+
|
|
783
|
+
// Parsing fleksibel dari berbagai bentuk JSON provider
|
|
784
|
+
if (data.data && Array.isArray(data.data)) {
|
|
785
|
+
extractedModels = data.data.map(m => ({ id: typeof m === 'string' ? m : (m.id || m.name) }));
|
|
786
|
+
} else if (data.models && Array.isArray(data.models)) {
|
|
787
|
+
extractedModels = data.models.map(m => ({ id: typeof m === 'string' ? m : (m.name?.replace('models/', '') || m.id) }));
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
if (extractedModels.length > 0) {
|
|
782
791
|
interactiveModelSelector(
|
|
783
|
-
|
|
792
|
+
extractedModels,
|
|
784
793
|
(selectedModelId) => {
|
|
785
794
|
config.model = selectedModelId;
|
|
786
795
|
saveConfig(config);
|
|
@@ -795,15 +804,37 @@ async function fetchAvailableModels() {
|
|
|
795
804
|
}
|
|
796
805
|
);
|
|
797
806
|
} else {
|
|
798
|
-
console.log(`${C.red}[x]
|
|
807
|
+
console.log(`${C.red}[x] Gagal mengambil daftar model secara otomatis dari ${config.provider}.${C.reset}`);
|
|
808
|
+
console.log(`${C.yellow}💡 Tips: Gunakan perintah ${C.bold}/custom-models${C.reset}${C.yellow} untuk menginput nama model secara manual dengan presisi.${C.reset}\n`);
|
|
799
809
|
startPrompt();
|
|
800
810
|
}
|
|
801
811
|
} catch (err) {
|
|
802
|
-
console.log(`${C.red}[x] Error fetching models: ${err.message}${C.reset}
|
|
812
|
+
console.log(`${C.red}[x] Error fetching models: ${err.message}${C.reset}`);
|
|
813
|
+
console.log(`${C.yellow}💡 Kamu bisa menggunakan perintah ${C.bold}/custom-models${C.reset}${C.yellow} untuk memasukkan nama model manual.${C.reset}\n`);
|
|
803
814
|
startPrompt();
|
|
804
815
|
}
|
|
805
816
|
}
|
|
806
817
|
|
|
818
|
+
// PERINTAH BARU: /custom-models UNTUK PRESISI NAMA MODEL
|
|
819
|
+
function handleCustomModels() {
|
|
820
|
+
console.log(`\n${C.cyan}=== 🎯 SET CUSTOM MODEL (PRESISI HIGH-PRECISION) ===${C.reset}`);
|
|
821
|
+
console.log(`${C.gray}Provider Aktif : ${C.yellow}${config.provider || 'Belum diatur'}${C.reset}`);
|
|
822
|
+
console.log(`${C.gray}Model Saat Ini : ${C.green}${config.model || 'Belum diatur'}${C.reset}\n`);
|
|
823
|
+
|
|
824
|
+
rl.question(`${C.yellow}[>] Masukkan ID / Nama Model secara presisi sesuai provider:${C.reset} `, (inputModel) => {
|
|
825
|
+
const cleanModel = inputModel.trim();
|
|
826
|
+
if (!cleanModel) {
|
|
827
|
+
console.log(`${C.red}[x] Nama model tidak boleh kosong.${C.reset}\n`);
|
|
828
|
+
return startPrompt();
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
config.model = cleanModel;
|
|
832
|
+
saveConfig(config);
|
|
833
|
+
console.log(`\n${C.green}[✔] Model berhasil diperbarui secara presisi ke: ${C.bold}${config.model}${C.reset}\n`);
|
|
834
|
+
startPrompt();
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
|
|
807
838
|
async function handleChat(prompt, forcedTool = null) {
|
|
808
839
|
if (!config.apiKey) {
|
|
809
840
|
console.log(`${C.yellow}[!] API Key is not set.${C.reset}`);
|
|
@@ -825,7 +856,8 @@ async function handleChat(prompt, forcedTool = null) {
|
|
|
825
856
|
const fullPrompt = (prompt || "Jalankan instruksi tool ini.") + toolsContext;
|
|
826
857
|
|
|
827
858
|
if (url.includes('googleapis.com')) {
|
|
828
|
-
|
|
859
|
+
const activeModel = config.model || 'gemini-2.5-flash';
|
|
860
|
+
url = `https://generativelanguage.googleapis.com/v1beta/models/${activeModel}:generateContent?key=${config.apiKey}`;
|
|
829
861
|
bodyData = { contents: [{ parts: [{ text: fullPrompt }] }] };
|
|
830
862
|
} else {
|
|
831
863
|
if (!url.endsWith('/chat/completions')) {
|
|
@@ -848,7 +880,6 @@ async function handleChat(prompt, forcedTool = null) {
|
|
|
848
880
|
|
|
849
881
|
let aiResponse = "";
|
|
850
882
|
|
|
851
|
-
// DUKUNGAN UNTUK REASONING MODELS & STANDAR OPENAI/GEMINI
|
|
852
883
|
if (data.choices && data.choices[0] && data.choices[0].message) {
|
|
853
884
|
const msg = data.choices[0].message;
|
|
854
885
|
aiResponse = msg.content || msg.reasoning || msg.reasoning_content || "";
|
|
@@ -908,6 +939,8 @@ function startPrompt() {
|
|
|
908
939
|
askConfig(() => startPrompt());
|
|
909
940
|
} else if (cmd === '/models') {
|
|
910
941
|
fetchAvailableModels();
|
|
942
|
+
} else if (cmd === '/custom-models') {
|
|
943
|
+
handleCustomModels();
|
|
911
944
|
} else if (cmd === '/skill' || cmd === '/skills') {
|
|
912
945
|
listSkills();
|
|
913
946
|
startPrompt();
|