@softerist/heuristic-mcp 2.1.3 → 2.1.5

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/README.md CHANGED
@@ -126,15 +126,7 @@ Install globally via npm:
126
126
  npm install -g @softerist/heuristic-mcp
127
127
  ```
128
128
 
129
- To update to the latest version:
130
-
131
- ```bash
132
- npm update -g @softerist/heuristic-mcp
133
- ```
134
-
135
- ## Configuration
136
-
137
- Add to your MCP configuration file. The location depends on your IDE and OS:
129
+ That's it! The installer will automatically detect your IDE (Antigravity, Claude, Cursor) and configure it for you.
138
130
 
139
131
  | IDE | OS | Config Path |
140
132
  | -------------------- | ------- | ----------------------------------------------------------------- |
@@ -176,6 +168,36 @@ Add the server configuration to the `mcpServers` object in your config file:
176
168
  }
177
169
  ```
178
170
 
171
+ ### Troubleshooting
172
+
173
+ If for some reason the server isn't detected automatically, you can trigger the registration manually:
174
+
175
+ ```bash
176
+ heuristic-mcp --register
177
+ ```
178
+
179
+ ### Starting and Stopping
180
+
181
+ If you need to restart the server or kill a zombie process:
182
+
183
+ **Stop the server:**
184
+
185
+ ```bash
186
+ heuristic-mcp --stop
187
+ ```
188
+
189
+ *(This kills any running instances of the server)*
190
+
191
+ **Start/Enable the server:**
192
+
193
+ ```bash
194
+ heuristic-mcp --start
195
+ ```
196
+
197
+ *(This re-runs the configuration step to ensure it is enabled in your IDE)*
198
+
199
+ ---
200
+
179
201
  ## Environment Variables
180
202
 
181
203
  Override configuration settings via environment variables in your MCP config:
@@ -0,0 +1,45 @@
1
+ import { exec } from 'child_process';
2
+ import util from 'util';
3
+ const execPromise = util.promisify(exec);
4
+
5
+ export async function stop() {
6
+ console.log('[Lifecycle] Stopping Heuristic MCP servers...');
7
+ try {
8
+ const platform = process.platform;
9
+ let command = '';
10
+
11
+ if (platform === 'win32') {
12
+ // Windows: Use wmic to find node processes running our script
13
+ command = `wmic process where "CommandLine like '%heuristic-mcp/index.js%'" delete`;
14
+ } else {
15
+ // Unix/Linux/Mac: Use pkill to find the process matching the script path
16
+ // We exclude the current process to avoid suicide if we are running from the same script
17
+ // however, usually the CLI runner is a different PID than the server.
18
+ command = `pkill -f "heuristic-mcp/index.js"`;
19
+ }
20
+
21
+ await execPromise(command);
22
+ console.log('[Lifecycle] ✅ Stopped all running instances.');
23
+ } catch (error) {
24
+ // pkill returns non-zero if no process found, which is fine
25
+ if (error.code === 1 || error.message.includes('No Instance(s) Available')) {
26
+ console.log('[Lifecycle] No running instances found.');
27
+ } else {
28
+ // Don't fail hard, just warn
29
+ console.warn(`[Lifecycle] Note: Could not stop server (it might not be running). Detail: ${error.message}`);
30
+ }
31
+ }
32
+ }
33
+
34
+ export async function start() {
35
+ console.log('[Lifecycle] Ensuring server is configured...');
36
+ // Re-use the registration logic to ensure the config is present and correct
37
+ try {
38
+ const { register } = await import('./register.js');
39
+ await register();
40
+ console.log('[Lifecycle] ✅ Configuration checked.');
41
+ console.log('[Lifecycle] To start the server, please reload your IDE window or restart the IDE.');
42
+ } catch (err) {
43
+ console.error(`[Lifecycle] Failed to configure server: ${err.message}`);
44
+ }
45
+ }
@@ -0,0 +1,121 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import os from 'os';
4
+ import { fileURLToPath } from 'url';
5
+
6
+ // Helper to expand ~ and %vars%
7
+ function expandPath(p) {
8
+ if (p.startsWith('~/')) {
9
+ return path.join(os.homedir(), p.slice(2));
10
+ }
11
+
12
+ if (process.platform === 'win32') {
13
+ return p.replace(/%([^%]+)%/g, (_, n) => process.env[n] || '%' + n + '%');
14
+ }
15
+
16
+ return p;
17
+ }
18
+
19
+ // Known config paths for different IDEs
20
+ function getConfigPaths() {
21
+ const platform = process.platform;
22
+ const home = os.homedir();
23
+ const paths = [];
24
+
25
+ // Antigravity
26
+ if (platform === 'win32') {
27
+ paths.push({
28
+ name: 'Antigravity',
29
+ path: expandPath('%USERPROFILE%\\.gemini\\antigravity\\mcp_config.json')
30
+ });
31
+ } else {
32
+ paths.push({
33
+ name: 'Antigravity',
34
+ path: expandPath('~/.gemini/antigravity/mcp_config.json')
35
+ });
36
+ }
37
+
38
+ // Claude Desktop
39
+ if (platform === 'darwin') {
40
+ paths.push({
41
+ name: 'Claude Desktop',
42
+ path: expandPath('~/Library/Application Support/Claude/claude_desktop_config.json')
43
+ });
44
+ } else if (platform === 'win32') {
45
+ paths.push({
46
+ name: 'Claude Desktop',
47
+ path: expandPath('%APPDATA%\\Claude\\claude_desktop_config.json')
48
+ });
49
+ }
50
+
51
+ // Cursor (Cascade) - Settings are usually in settings.json but MCP might have a specific spot?
52
+ // Cursor often uses VS Code's settings.json for some things, but explicit MCP support varies.
53
+ // For now, we'll stick to Antigravity and Claude as confirmed targets.
54
+ // NOTE: If Cursor adds a specific mcp_config, add it here.
55
+
56
+ return paths;
57
+ }
58
+
59
+ export async function register(filter = null) {
60
+ const binaryPath = process.execPath; // The node binary
61
+ const scriptPath = fileURLToPath(new URL('../index.js', import.meta.url)); // Absolute path to index.js
62
+
63
+ const serverConfig = {
64
+ command: binaryPath,
65
+ args: [scriptPath, "--workspace", "${workspaceFolder}"],
66
+ disabled: false,
67
+ autoRegistered: true // Marker to know we did this
68
+ };
69
+
70
+ const configPaths = getConfigPaths();
71
+ let registeredCount = 0;
72
+
73
+ console.log(`[Auto-Register] Detecting IDE configurations...`);
74
+
75
+ for (const { name, path: configPath } of configPaths) {
76
+ if (filter && name.toLowerCase() !== filter.toLowerCase()) {
77
+ continue;
78
+ }
79
+
80
+ try {
81
+ // Check if file exists
82
+ try {
83
+ await fs.access(configPath);
84
+ } catch {
85
+ console.log(`[Auto-Register] Skipped ${name}: Config file not found at ${configPath}`);
86
+ continue;
87
+ }
88
+
89
+ // Read config
90
+ const content = await fs.readFile(configPath, 'utf-8');
91
+ let config = {};
92
+ try {
93
+ config = JSON.parse(content);
94
+ } catch (e) {
95
+ console.error(`[Auto-Register] Error parsing ${name} config: ${e.message}`);
96
+ continue;
97
+ }
98
+
99
+ // Init mcpServers if missing
100
+ if (!config.mcpServers) {
101
+ config.mcpServers = {};
102
+ }
103
+
104
+ // Inject configuration
105
+ config.mcpServers['heuristic-mcp'] = serverConfig;
106
+
107
+ // Write back
108
+ await fs.writeFile(configPath, JSON.stringify(config, null, 2));
109
+ console.log(`[Auto-Register] ✅ Successfully registered with ${name}`);
110
+ registeredCount++;
111
+
112
+ } catch (err) {
113
+ console.error(`[Auto-Register] Failed to register with ${name}: ${err.message}`);
114
+ }
115
+ }
116
+
117
+ if (registeredCount === 0) {
118
+ console.log(`[Auto-Register] No compatible IDE configurations found to update.`);
119
+ console.log(`[Auto-Register] Manual Config:\n${JSON.stringify({ mcpServers: { "heuristic-mcp": serverConfig } }, null, 2)}`);
120
+ }
121
+ }
package/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { stop, start } from "./features/lifecycle.js";
3
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
5
  import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
5
6
  import { pipeline } from "@xenova/transformers";
@@ -19,10 +20,33 @@ import * as IndexCodebaseFeature from "./features/index-codebase.js";
19
20
  import * as HybridSearchFeature from "./features/hybrid-search.js";
20
21
  import * as ClearCacheFeature from "./features/clear-cache.js";
21
22
  import * as FindSimilarCodeFeature from "./features/find-similar-code.js";
22
- import * as AnnConfigFeature from "./features/ann-config.js";
23
+ import { register } from "./features/register.js";
23
24
 
24
25
  // Parse workspace from command line arguments
25
26
  const args = process.argv.slice(2);
27
+
28
+ if (args.includes('--stop')) {
29
+ await stop();
30
+ process.exit(0);
31
+ }
32
+
33
+ if (args.includes('--start')) {
34
+ await start();
35
+ process.exit(0);
36
+ }
37
+
38
+ // Check if --register flag is present
39
+ if (args.includes('--register')) {
40
+ // Extract optional filter (e.g. --register antigravity)
41
+ const filterIndex = args.indexOf('--register');
42
+ const filter = args[filterIndex + 1] && !args[filterIndex + 1].startsWith('-')
43
+ ? args[filterIndex + 1]
44
+ : null;
45
+
46
+ await register(filter);
47
+ process.exit(0);
48
+ }
49
+
26
50
  const workspaceIndex = args.findIndex(arg => arg.startsWith('--workspace'));
27
51
  let workspaceDir = null;
28
52
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softerist/heuristic-mcp",
3
- "version": "2.1.3",
3
+ "version": "2.1.5",
4
4
  "description": "An enhanced MCP server providing intelligent semantic code search with find-similar-code, recency ranking, and improved chunking. Fork of smart-coding-mcp.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -12,7 +12,8 @@
12
12
  "dev": "node --watch index.js",
13
13
  "test": "vitest run",
14
14
  "test:watch": "vitest",
15
- "clear-cache": "node scripts/clear-cache.js"
15
+ "clear-cache": "node scripts/clear-cache.js",
16
+ "postinstall": "node index.js --register"
16
17
  },
17
18
  "keywords": [
18
19
  "mcp",