reflect-mcp 1.0.8 → 1.0.9
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/dist/cli.js +95 -25
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -10,7 +10,62 @@ import { DEFAULT_DB_PATH, expandPath } from "./utils.js";
|
|
|
10
10
|
import * as fs from "fs";
|
|
11
11
|
import * as path from "path";
|
|
12
12
|
import * as os from "os";
|
|
13
|
+
import * as net from "net";
|
|
13
14
|
import { execSync } from "child_process";
|
|
15
|
+
/**
|
|
16
|
+
* Check if a port is in use
|
|
17
|
+
*/
|
|
18
|
+
function isPortInUse(port) {
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
const server = net.createServer();
|
|
21
|
+
server.once("error", (err) => {
|
|
22
|
+
if (err.code === "EADDRINUSE") {
|
|
23
|
+
resolve(true);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
resolve(false);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
server.once("listening", () => {
|
|
30
|
+
server.close();
|
|
31
|
+
resolve(false);
|
|
32
|
+
});
|
|
33
|
+
server.listen(port, "127.0.0.1");
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Kill any process using the specified port
|
|
38
|
+
*/
|
|
39
|
+
function killProcessOnPort(port) {
|
|
40
|
+
try {
|
|
41
|
+
// Get PID(s) using the port
|
|
42
|
+
const pids = execSync(`lsof -ti:${port}`, { encoding: "utf-8" }).trim();
|
|
43
|
+
if (pids) {
|
|
44
|
+
console.log(`⚠️ Port ${port} in use by PID(s): ${pids.replace(/\n/g, ", ")}`);
|
|
45
|
+
execSync(`lsof -ti:${port} | xargs kill -9`, { stdio: "ignore" });
|
|
46
|
+
console.log(`✅ Killed existing process(es) on port ${port}`);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// No process found on port, or kill failed - that's fine
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Ensure the port is free, killing any existing process if needed
|
|
57
|
+
*/
|
|
58
|
+
async function ensurePortFree(port) {
|
|
59
|
+
if (await isPortInUse(port)) {
|
|
60
|
+
killProcessOnPort(port);
|
|
61
|
+
// Wait a moment for the port to be released
|
|
62
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
63
|
+
// Check again
|
|
64
|
+
if (await isPortInUse(port)) {
|
|
65
|
+
throw new Error(`Port ${port} is still in use after attempting to free it`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
14
69
|
const REFLECT_CLIENT_ID = "55798f25d5a24efb95e4174fff3d219e";
|
|
15
70
|
const LAUNCH_AGENT_LABEL = "com.reflect-mcp";
|
|
16
71
|
const LAUNCH_AGENT_DIR = path.join(os.homedir(), "Library/LaunchAgents");
|
|
@@ -19,22 +74,24 @@ const LAUNCH_AGENT_PATH = path.join(LAUNCH_AGENT_DIR, `${LAUNCH_AGENT_LABEL}.pli
|
|
|
19
74
|
const args = process.argv.slice(2);
|
|
20
75
|
const command = args[0];
|
|
21
76
|
// Handle commands
|
|
22
|
-
|
|
23
|
-
install
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
uninstall
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
status
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
77
|
+
(async () => {
|
|
78
|
+
if (command === "install") {
|
|
79
|
+
await install(args.slice(1));
|
|
80
|
+
}
|
|
81
|
+
else if (command === "uninstall") {
|
|
82
|
+
uninstall();
|
|
83
|
+
}
|
|
84
|
+
else if (command === "status") {
|
|
85
|
+
status();
|
|
86
|
+
}
|
|
87
|
+
else if (command === "--help" || command === "-h") {
|
|
88
|
+
showHelp();
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// Default: run the server
|
|
92
|
+
await runServer(args);
|
|
93
|
+
}
|
|
94
|
+
})();
|
|
38
95
|
function showHelp() {
|
|
39
96
|
console.log(`
|
|
40
97
|
Reflect MCP Server - Connect your Reflect notes to Claude
|
|
@@ -60,7 +117,7 @@ Examples:
|
|
|
60
117
|
`);
|
|
61
118
|
process.exit(0);
|
|
62
119
|
}
|
|
63
|
-
function install(installArgs) {
|
|
120
|
+
async function install(installArgs) {
|
|
64
121
|
let dbPath = DEFAULT_DB_PATH;
|
|
65
122
|
let port = 3000;
|
|
66
123
|
// Parse install arguments
|
|
@@ -88,6 +145,9 @@ function install(installArgs) {
|
|
|
88
145
|
catch {
|
|
89
146
|
// Ignore errors - service might not exist yet
|
|
90
147
|
}
|
|
148
|
+
// Kill any stale processes on the port
|
|
149
|
+
killProcessOnPort(port);
|
|
150
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
91
151
|
// Create plist content
|
|
92
152
|
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
93
153
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -189,7 +249,7 @@ function status() {
|
|
|
189
249
|
}
|
|
190
250
|
console.log(`\n📝 Logs: tail -f /tmp/reflect-mcp.log`);
|
|
191
251
|
}
|
|
192
|
-
function runServer(serverArgs) {
|
|
252
|
+
async function runServer(serverArgs) {
|
|
193
253
|
let dbPath = DEFAULT_DB_PATH;
|
|
194
254
|
let port = 3000;
|
|
195
255
|
for (let i = 0; i < serverArgs.length; i++) {
|
|
@@ -200,15 +260,25 @@ function runServer(serverArgs) {
|
|
|
200
260
|
dbPath = serverArgs[i];
|
|
201
261
|
}
|
|
202
262
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
port
|
|
206
|
-
|
|
207
|
-
|
|
263
|
+
// Ensure port is free before starting
|
|
264
|
+
try {
|
|
265
|
+
await ensurePortFree(port);
|
|
266
|
+
}
|
|
267
|
+
catch (err) {
|
|
268
|
+
console.error(`❌ ${err}`);
|
|
269
|
+
process.exit(1);
|
|
270
|
+
}
|
|
271
|
+
try {
|
|
272
|
+
await startReflectMCPServer({
|
|
273
|
+
clientId: REFLECT_CLIENT_ID,
|
|
274
|
+
port,
|
|
275
|
+
dbPath,
|
|
276
|
+
});
|
|
208
277
|
console.log(`Reflect MCP Server running on http://localhost:${port}`);
|
|
209
278
|
console.log(`Database: ${dbPath}`);
|
|
210
|
-
}
|
|
279
|
+
}
|
|
280
|
+
catch (err) {
|
|
211
281
|
console.error("Failed to start server:", err);
|
|
212
282
|
process.exit(1);
|
|
213
|
-
}
|
|
283
|
+
}
|
|
214
284
|
}
|