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.
Files changed (2) hide show
  1. package/dist/cli.js +95 -25
  2. 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
- if (command === "install") {
23
- install(args.slice(1));
24
- }
25
- else if (command === "uninstall") {
26
- uninstall();
27
- }
28
- else if (command === "status") {
29
- status();
30
- }
31
- else if (command === "--help" || command === "-h") {
32
- showHelp();
33
- }
34
- else {
35
- // Default: run the server
36
- runServer(args);
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
- startReflectMCPServer({
204
- clientId: REFLECT_CLIENT_ID,
205
- port,
206
- dbPath,
207
- }).then(() => {
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
- }).catch((err) => {
279
+ }
280
+ catch (err) {
211
281
  console.error("Failed to start server:", err);
212
282
  process.exit(1);
213
- });
283
+ }
214
284
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reflect-mcp",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "MCP server for Reflect Notes - connect your notes to Claude Desktop. Just run: npx reflect-mcp",
5
5
  "type": "module",
6
6
  "main": "dist/server.js",