@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 +12 -12
- package/build/config/config-manager.js +50 -74
- package/build/index.js +6 -2
- package/package.json +1 -1
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
44
|
-
vesper --setup
|
|
39
|
+
npx -y @vespermcp/mcp-server@latest --setup
|
|
45
40
|
```
|
|
46
41
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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:
|
|
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
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
const
|
|
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" &&
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
126
|
-
(
|
|
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
|
|
169
|
-
|
|
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:
|
|
173
|
-
args:
|
|
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)
|
|
34
|
-
|
|
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
|
|
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",
|