@vespermcp/mcp-server 1.0.6 → 1.1.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/README.md CHANGED
@@ -31,23 +31,23 @@ Vesper is a Model Context Protocol (MCP) server that helps you find, analyze, an
31
31
 
32
32
  ## 📦 Installation
33
33
 
34
- ### Option A: Install via NPX (Easiest)
35
- Run the setup wizard to automatically configure Vesper for Cursor, Claude Desktop, and VS Code:
34
+ ## 🚀 Quick Start (VS Code + Copilot)
36
35
 
37
- ```bash
38
- npx @vespermcp/mcp-server@latest --setup
39
- ```
36
+ The fastest way to install Vesper and configure it for **GitHub Copilot Chat** or **Cursor** is to run the automated setup:
40
37
 
41
- ### Option B: Install Globally
42
38
  ```bash
43
- npm install -g @vespermcp/mcp-server
44
- vesper --setup
39
+ npx -y @vespermcp/mcp-server@latest --setup
45
40
  ```
46
41
 
47
- The postinstall script will automatically:
48
- - Install Python dependencies (opencv-python, librosa, etc.)
49
- - Create data directories in `~/.vesper`
50
- - Display setup instructions
42
+ 1. Select **Visual Studio Code (Settings.json)** from the list.
43
+ 2. Restart VS Code.
44
+ 3. Open Copilot Chat and look for the **MCP Servers** section.
45
+
46
+ ## 🛠️ Configuration
47
+ Vesper supports:
48
+ - **GitHub Copilot Chat**: Automated setup via `settings.json`.
49
+ - **Cursor**: Automated setup via `mcp.json`.
50
+ - **Claude Desktop**: Automated setup via `claude_desktop_config.json`.
51
51
 
52
52
  ### Manual Python Setup (if needed)
53
53
 
@@ -24,20 +24,6 @@ export class ConfigManager {
24
24
  : path.join(home, "Library", "Application Support", "Cursor", "User", "globalStorage", "rohit-gohri.cursor-mcp", "mcp.json"),
25
25
  key: "mcpServers"
26
26
  },
27
- "vscode-cline": {
28
- name: "VS Code (Cline)",
29
- path: isWin
30
- ? path.join(appData, "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json")
31
- : path.join(home, "Library", "Application Support", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json"),
32
- key: "mcpServers"
33
- },
34
- "vscode-roo-code": {
35
- name: "VS Code (Roo Code)",
36
- path: isWin
37
- ? path.join(appData, "Code", "User", "globalStorage", "RooVeterans.roo-cline", "settings", "cline_mcp_settings.json")
38
- : path.join(home, "Library", "Application Support", "Code", "User", "globalStorage", "RooVeterans.roo-cline", "settings", "cline_mcp_settings.json"),
39
- key: "mcpServers"
40
- },
41
27
  "cursor-project": {
42
28
  name: "Cursor (Project-specific)",
43
29
  path: path.join(process.cwd(), ".cursor", "mcp.json"),
@@ -45,26 +31,16 @@ export class ConfigManager {
45
31
  },
46
32
  "vscode-copilot": {
47
33
  name: "VS Code (Copilot)",
48
- path: path.join(home, ".copilot", "mcp-config.json"),
34
+ path: isWin
35
+ ? path.join(appData, "Code", "User", "globalStorage", "github.copilot-chat", "mcp.json")
36
+ : path.join(home, "Library", "Application Support", "Code", "User", "globalStorage", "github.copilot-chat", "mcp.json"),
49
37
  key: "mcpServers"
50
38
  },
51
39
  "vscode-global": {
52
40
  name: "VS Code (Standard MCP)",
53
41
  path: isWin
54
- ? path.join(appData, "Code", "User", "mcp.json")
55
- : path.join(home, "Library", "Application Support", "Code", "User", "mcp.json"),
56
- key: "mcpServers"
57
- },
58
- "vscode-project": {
59
- name: "VS Code (Project-specific)",
60
- path: path.join(process.cwd(), ".vscode", "mcp.json"),
61
- key: "mcpServers"
62
- },
63
- "vscode-insiders": {
64
- name: "VS Code Insiders",
65
- path: isWin
66
- ? path.join(appData, "Code - Insiders", "User", "mcp.json")
67
- : path.join(home, "Library", "Application Support", "Code - Insiders", "User", "mcp.json"),
42
+ ? path.join(appData, "Code", "User", "globalStorage", "mcp-servers", "mcp.json")
43
+ : path.join(home, "Library", "Application Support", "Code", "User", "globalStorage", "mcp-servers", "mcp.json"),
68
44
  key: "mcpServers"
69
45
  },
70
46
  "vscode-settings": {
@@ -73,11 +49,6 @@ export class ConfigManager {
73
49
  ? path.join(appData, "Code", "User", "settings.json")
74
50
  : path.join(home, "Library", "Application Support", "Code", "User", "settings.json"),
75
51
  key: "github.copilot.chat.mcp.servers"
76
- },
77
- "vscode-root": {
78
- name: "VS Code (Workspace Root)",
79
- path: path.join(process.cwd(), "mcp.json"),
80
- key: "mcpServers"
81
52
  }
82
53
  };
83
54
  }
@@ -89,45 +60,23 @@ export class ConfigManager {
89
60
  const home = this.getHomeDir();
90
61
  for (const [key, cp] of Object.entries(paths)) {
91
62
  const isClaude = key === "claude-desktop";
92
- const isCursor = key === "cursor";
63
+ const isCursor = key === "cursor" || key === "cursor-project";
93
64
  const isVSCode = key.startsWith("vscode");
94
65
  const isCopilot = key === "vscode-copilot";
95
- const isStandard = key === "vscode-global";
96
- const isSettings = key === "vscode-settings";
97
- const isRoot = key === "vscode-root";
98
- const hasClaudeFolder = fs.existsSync(path.join(appData, "Claude"));
99
- const hasCursorFolder = fs.existsSync(path.join(appData, "Cursor")) || fs.existsSync(path.join(home, ".cursor"));
100
- const hasCodeFolder = fs.existsSync(path.join(appData, "Code")) || fs.existsSync(path.join(home, ".vscode"));
101
- const hasInsidersFolder = fs.existsSync(path.join(appData, "Code - Insiders"));
102
- const hasCopilotFolder = fs.existsSync(path.join(home, ".copilot"));
103
- if (process.env.VESPER_DEBUG) {
104
- console.log(`[Debug] Checking ${key}:`);
105
- console.log(` - Config Path: ${cp.path} (${fs.existsSync(cp.path) ? "EXISTS" : "MISSING"})`);
106
- if (isClaude)
107
- console.log(` - Claude Folder: ${path.join(appData, "Claude")} (${hasClaudeFolder ? "EXISTS" : "MISSING"})`);
108
- if (isCursor)
109
- console.log(` - Cursor Folder: ${path.join(appData, "Cursor")} (${hasCursorFolder ? "EXISTS" : "MISSING"})`);
110
- if (isVSCode)
111
- console.log(` - Code Folder: ${path.join(appData, "Code")} (${hasCodeFolder ? "EXISTS" : "MISSING"})`);
112
- if (isCopilot)
113
- console.log(` - Copilot Folder: ${path.join(this.getHomeDir(), ".copilot")} (${hasCopilotFolder ? "EXISTS" : "MISSING"})`);
114
- }
115
- const isCurrentIDE = (isCursor && (termProgram.includes("cursor") || (termProgram === "vscode" && hasCursorFolder))) ||
66
+ const isMac = process.platform === "darwin";
67
+ const hasClaudeFolder = fs.existsSync(path.join(appData, "Claude")) || (isMac && fs.existsSync(path.join(home, "Library", "Application Support", "Claude")));
68
+ const hasCursorFolder = fs.existsSync(path.join(appData, "Cursor")) || fs.existsSync(path.join(home, ".cursor")) || (isMac && fs.existsSync(path.join(home, "Library", "Application Support", "Cursor")));
69
+ const hasCodeFolder = fs.existsSync(path.join(appData, "Code")) || fs.existsSync(path.join(home, ".vscode")) || (isMac && fs.existsSync(path.join(home, "Library", "Application Support", "Code")));
70
+ const hasCopilotFolder = hasCodeFolder || fs.existsSync(path.join(home, ".copilot"));
71
+ const isCurrentIDE = (isCursor && termProgram.includes("cursor")) ||
116
72
  (isClaude && termProgram.includes("claude")) ||
117
- (isVSCode && termProgram === "vscode" && (hasCodeFolder || hasInsidersFolder)) ||
118
- (isCopilot && hasCopilotFolder) ||
119
- (isStandard && termProgram === "vscode") ||
120
- (isSettings && termProgram === "vscode");
121
- // Also check if the config file actually exists OR the root folder exists
122
- const shouldDetectByFolder = (isClaude && hasClaudeFolder) ||
73
+ (isVSCode && termProgram === "vscode" && hasCodeFolder);
74
+ // Detection logic
75
+ if ((isClaude && hasClaudeFolder) ||
123
76
  (isCursor && hasCursorFolder) ||
124
77
  (isVSCode && hasCodeFolder) ||
125
- (key === "vscode-insiders" && hasInsidersFolder) ||
126
- (isCopilot && hasCopilotFolder) ||
127
- (isStandard && hasCodeFolder) ||
128
- (isSettings && hasCodeFolder) ||
129
- (isRoot && fs.existsSync(process.cwd()));
130
- if (shouldDetectByFolder || fs.existsSync(cp.path) || isCurrentIDE || key === "cursor-project" || key === "vscode-project" || key === "vscode-root") {
78
+ isCurrentIDE ||
79
+ fs.existsSync(cp.path)) {
131
80
  let displayName = cp.name;
132
81
  if (isCurrentIDE) {
133
82
  displayName += " (Current Terminal)";
@@ -137,6 +86,28 @@ export class ConfigManager {
137
86
  }
138
87
  return detected.filter((v, i, a) => a.findIndex(t => t.path === v.path) === i);
139
88
  }
89
+ getVesperExecutableConfig() {
90
+ const isWin = process.platform === "win32";
91
+ // Try to find absolute paths for maximum reliability in VS Code/Copilot
92
+ try {
93
+ const nodeExe = process.execPath;
94
+ // index.js is in build/index.js relative to ConfigManager in build/config/config-manager.js
95
+ const vesperScript = path.resolve(__dirname, "../../index.js");
96
+ if (fs.existsSync(vesperScript)) {
97
+ return {
98
+ command: nodeExe,
99
+ args: [vesperScript]
100
+ };
101
+ }
102
+ }
103
+ catch (e) {
104
+ // Fallback to npx
105
+ }
106
+ return {
107
+ command: isWin ? "npx.cmd" : "npx",
108
+ args: ["-y", "@vespermcp/mcp-server@latest"]
109
+ };
110
+ }
140
111
  async installTo(configPath) {
141
112
  try {
142
113
  console.log(`[Vesper Setup] Installing to ${configPath.name} at ${configPath.path}...`);
@@ -165,21 +136,26 @@ export class ConfigManager {
165
136
  }
166
137
  const lastKey = keys[keys.length - 1];
167
138
  const mcpServers = current[lastKey] || {};
168
- // Use the portable npx command as requested
169
- // We use both 'vesper' (clean) and 'vespermcp' (legacy/alias) for compatibility
170
- const isWin = process.platform === "win32";
139
+ // Use the most robust command format available (absolute paths if running from npx/installed)
140
+ const vesperExec = this.getVesperExecutableConfig();
171
141
  const serverConfig = {
172
- command: isWin ? "npx.cmd" : "npx",
173
- args: ["-y", "@vespermcp/mcp-server@latest"],
142
+ command: vesperExec.command,
143
+ args: vesperExec.args,
174
144
  env: {
175
145
  "HF_TOKEN": "YOUR_HUGGINGFACE_TOKEN_HERE",
176
- // Empty by default to avoid clutter, user can add if needed
177
146
  }
178
147
  };
179
148
  mcpServers["vesper"] = serverConfig;
180
149
  // Also add alias for easy upgrading
181
150
  mcpServers["@vespermcp/mcp-server"] = serverConfig;
182
151
  current[lastKey] = mcpServers;
152
+ // If we are writing to settings.json or a copilot-specific file, sync to native mcp.servers key too
153
+ if (configPath.key.includes("copilot") || configPath.path.includes("settings.json")) {
154
+ if (!config["mcp.servers"])
155
+ config["mcp.servers"] = {};
156
+ config["mcp.servers"]["vesper"] = serverConfig;
157
+ config["mcp.servers"]["@vespermcp/mcp-server"] = serverConfig;
158
+ }
183
159
  const content = JSON.stringify(config, null, 2);
184
160
  if (process.env.VESPER_DEBUG) {
185
161
  console.log(`[Vesper Setup] Writing to ${configPath.path}:`);
package/build/index.js CHANGED
@@ -25,13 +25,15 @@ import { MediaAnalyzer } from "./quality/media-analyzer.js";
25
25
  import { QualityOrchestrator } from "./quality/quality-orchestrator.js";
26
26
  import { ConfigManager } from "./config/config-manager.js";
27
27
  import { Selector } from "./utils/selector.js";
28
+ import os from "os";
28
29
  // Determine absolute paths relative to the compiled script
29
30
  const __filename = fileURLToPath(import.meta.url);
30
31
  const __dirname = path.dirname(__filename);
31
32
  // appRoot: Where the source code/scripts are (inside node_modules or source)
32
33
  const appRoot = path.join(__dirname, "..");
33
- // dataRoot: Where database and user data live (in user home) to prevent data loss on update and running from node_modules
34
- const homeDir = process.env.HOME || process.env.USERPROFILE || appRoot;
34
+ // dataRoot: Where database and user data live (in user home)
35
+ // Use os.homedir() as it's more reliable than env vars
36
+ const homeDir = os.homedir() || process.env.HOME || process.env.USERPROFILE || appRoot;
35
37
  const dataRoot = path.join(homeDir, ".vesper");
36
38
  // Ensure data directory exists
37
39
  if (!fs.existsSync(dataRoot))
@@ -39,6 +41,8 @@ if (!fs.existsSync(dataRoot))
39
41
  const dbPath = path.join(dataRoot, "data", "metadata.db");
40
42
  const vectorPath = path.join(dataRoot, "data", "vectors.json");
41
43
  const errorLogPath = path.join(dataRoot, "vesper_errors.log");
44
+ console.error(`[Vesper] Data directory: ${dataRoot}`);
45
+ console.error(`[Vesper] Database path: ${dbPath}`);
42
46
  function logError(err, context) {
43
47
  const timestamp = new Date().toISOString();
44
48
  const stack = err.stack || String(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vespermcp/mcp-server",
3
- "version": "1.0.6",
3
+ "version": "1.1.0",
4
4
  "description": "AI-powered dataset discovery, quality analysis, and preparation MCP server with multimodal support (text, image, audio, video)",
5
5
  "type": "module",
6
6
  "main": "build/index.js",