smilenexus-mcp 1.0.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/cli.mjs +119 -0
- package/package.json +9 -0
package/cli.mjs
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
const command = args[0];
|
|
8
|
+
|
|
9
|
+
if (command === 'install' || command === 'install-codex' || command === 'install-agy') {
|
|
10
|
+
const customUrl = args[1];
|
|
11
|
+
console.log(`\n========================================`);
|
|
12
|
+
console.log(` smileNexus MCP Auto-Installer`);
|
|
13
|
+
console.log(`========================================\n`);
|
|
14
|
+
|
|
15
|
+
if (command === 'install') {
|
|
16
|
+
const defaultUrl = customUrl || "https://smile-nexus.kantapon-r.workers.dev/mcp/sse";
|
|
17
|
+
let configPath;
|
|
18
|
+
|
|
19
|
+
if (process.platform === 'darwin') {
|
|
20
|
+
configPath = path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
21
|
+
} else if (process.platform === 'win32') {
|
|
22
|
+
configPath = path.join(os.homedir(), 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json');
|
|
23
|
+
} else {
|
|
24
|
+
console.log('Unsupported OS for auto-install. Please configure manually using the JSON provided in the UI.');
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
let config = { mcpServers: {} };
|
|
30
|
+
if (fs.existsSync(configPath)) {
|
|
31
|
+
config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
config.mcpServers = config.mcpServers || {};
|
|
35
|
+
config.mcpServers.smileNexus = {
|
|
36
|
+
command: "npx",
|
|
37
|
+
args: ["-y", "smilenexus-mcp"],
|
|
38
|
+
env: {
|
|
39
|
+
"SMILENEXUS_URL": defaultUrl
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const dir = path.dirname(configPath);
|
|
44
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
45
|
+
|
|
46
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
47
|
+
console.log(`✅ Successfully added smileNexus to Claude Desktop!`);
|
|
48
|
+
console.log(`Config updated at: ${configPath}`);
|
|
49
|
+
console.log(`Please restart Claude Desktop for the changes to take effect.`);
|
|
50
|
+
} catch (err) {
|
|
51
|
+
console.error(`❌ Failed to update Claude config: ${err.message}`);
|
|
52
|
+
console.log(`Please configure manually using the JSON provided in the UI.`);
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
console.log(`Auto-install for ${command} is coming soon!`);
|
|
56
|
+
console.log(`Please configure manually using the instructions in the UI.`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
process.exit(0);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ---------------------------------------------------------
|
|
63
|
+
// Proxy Logic (stdio <-> HTTP)
|
|
64
|
+
// ---------------------------------------------------------
|
|
65
|
+
const MCP_URL = process.env.SMILENEXUS_URL ?? "https://smile-nexus-dev.kantapon-r.workers.dev/mcp/sse";
|
|
66
|
+
|
|
67
|
+
let buf = "";
|
|
68
|
+
let pending = 0;
|
|
69
|
+
let stdinDone = false;
|
|
70
|
+
process.stdin.setEncoding("utf8");
|
|
71
|
+
|
|
72
|
+
process.stdin.on("data", (chunk) => {
|
|
73
|
+
buf += chunk;
|
|
74
|
+
let idx;
|
|
75
|
+
while ((idx = buf.indexOf("\n")) !== -1) {
|
|
76
|
+
const line = buf.slice(0, idx).trim();
|
|
77
|
+
buf = buf.slice(idx + 1);
|
|
78
|
+
if (line) handle(line);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
process.stdin.on("end", () => {
|
|
83
|
+
stdinDone = true;
|
|
84
|
+
if (pending === 0) process.exit(0);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
async function handle(line) {
|
|
88
|
+
let msg;
|
|
89
|
+
try {
|
|
90
|
+
msg = JSON.parse(line);
|
|
91
|
+
} catch {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
pending++;
|
|
96
|
+
try {
|
|
97
|
+
const res = await fetch(MCP_URL, {
|
|
98
|
+
method: "POST",
|
|
99
|
+
headers: { "content-type": "application/json" },
|
|
100
|
+
body: JSON.stringify(msg),
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
if (res.status !== 202) {
|
|
104
|
+
const json = await res.json();
|
|
105
|
+
process.stdout.write(JSON.stringify(json) + "\n");
|
|
106
|
+
}
|
|
107
|
+
} catch (err) {
|
|
108
|
+
process.stdout.write(
|
|
109
|
+
JSON.stringify({
|
|
110
|
+
jsonrpc: "2.0",
|
|
111
|
+
id: msg?.id ?? null,
|
|
112
|
+
error: { code: -32603, message: String(err) },
|
|
113
|
+
}) + "\n",
|
|
114
|
+
);
|
|
115
|
+
} finally {
|
|
116
|
+
pending--;
|
|
117
|
+
if (stdinDone && pending === 0) process.exit(0);
|
|
118
|
+
}
|
|
119
|
+
}
|