@vibegrid/mcp 0.2.1 → 0.3.0-beta.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/dist/index.js +83 -7
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -35,7 +35,7 @@ var DEFAULT_AGENT_COMMANDS = {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
// ../server/src/database.ts
|
|
38
|
-
import Database from "
|
|
38
|
+
import Database from "libsql";
|
|
39
39
|
import path from "path";
|
|
40
40
|
import os from "os";
|
|
41
41
|
import fs from "fs";
|
|
@@ -120,6 +120,13 @@ function recoverCorruptDatabase() {
|
|
|
120
120
|
}
|
|
121
121
|
logger_default.warn(`[database] Database was corrupted and has been reset. Backup saved to: ${backupPath}`);
|
|
122
122
|
}
|
|
123
|
+
function dbSignalChange() {
|
|
124
|
+
try {
|
|
125
|
+
const signalPath = path.join(CONFIG_DIR, ".db-signal");
|
|
126
|
+
fs.writeFileSync(signalPath, Date.now().toString());
|
|
127
|
+
} catch {
|
|
128
|
+
}
|
|
129
|
+
}
|
|
123
130
|
function closeDatabase() {
|
|
124
131
|
if (db) {
|
|
125
132
|
db.close();
|
|
@@ -180,10 +187,23 @@ function createSchema() {
|
|
|
180
187
|
hostname TEXT NOT NULL,
|
|
181
188
|
user TEXT NOT NULL,
|
|
182
189
|
port INTEGER NOT NULL DEFAULT 22,
|
|
190
|
+
auth_method TEXT DEFAULT 'agent',
|
|
183
191
|
ssh_key_path TEXT,
|
|
192
|
+
credential_id TEXT,
|
|
193
|
+
encrypted_password TEXT,
|
|
184
194
|
ssh_options TEXT
|
|
185
195
|
);
|
|
186
196
|
|
|
197
|
+
CREATE TABLE IF NOT EXISTS ssh_keys (
|
|
198
|
+
id TEXT PRIMARY KEY,
|
|
199
|
+
label TEXT NOT NULL,
|
|
200
|
+
encrypted_private_key TEXT NOT NULL,
|
|
201
|
+
public_key TEXT,
|
|
202
|
+
certificate TEXT,
|
|
203
|
+
key_type TEXT,
|
|
204
|
+
created_at TEXT NOT NULL
|
|
205
|
+
);
|
|
206
|
+
|
|
187
207
|
CREATE TABLE IF NOT EXISTS tasks (
|
|
188
208
|
id TEXT PRIMARY KEY,
|
|
189
209
|
project_name TEXT NOT NULL,
|
|
@@ -311,6 +331,34 @@ function migrateSchema(d) {
|
|
|
311
331
|
})();
|
|
312
332
|
logger_default.info("[database] migrated schema to version 1 (workspaces)");
|
|
313
333
|
}
|
|
334
|
+
if (version < 2) {
|
|
335
|
+
d.transaction(() => {
|
|
336
|
+
const hostCols = d.prepare("PRAGMA table_info(remote_hosts)").all();
|
|
337
|
+
if (!hostCols.some((c) => c.name === "auth_method")) {
|
|
338
|
+
d.exec("ALTER TABLE remote_hosts ADD COLUMN auth_method TEXT");
|
|
339
|
+
d.exec("ALTER TABLE remote_hosts ADD COLUMN credential_id TEXT");
|
|
340
|
+
d.exec("ALTER TABLE remote_hosts ADD COLUMN encrypted_password TEXT");
|
|
341
|
+
d.exec(
|
|
342
|
+
"UPDATE remote_hosts SET auth_method = CASE WHEN ssh_key_path IS NOT NULL AND ssh_key_path != '' THEN 'key-file' ELSE 'agent' END"
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
d.exec(`
|
|
346
|
+
CREATE TABLE IF NOT EXISTS ssh_keys (
|
|
347
|
+
id TEXT PRIMARY KEY,
|
|
348
|
+
label TEXT NOT NULL,
|
|
349
|
+
encrypted_private_key TEXT NOT NULL,
|
|
350
|
+
public_key TEXT,
|
|
351
|
+
certificate TEXT,
|
|
352
|
+
key_type TEXT,
|
|
353
|
+
created_at TEXT NOT NULL
|
|
354
|
+
)
|
|
355
|
+
`);
|
|
356
|
+
d.prepare(
|
|
357
|
+
"INSERT OR REPLACE INTO schema_meta (key, value) VALUES ('schema_version', '2')"
|
|
358
|
+
).run();
|
|
359
|
+
})();
|
|
360
|
+
logger_default.info("[database] migrated schema to version 2 (ssh credential vault)");
|
|
361
|
+
}
|
|
314
362
|
}
|
|
315
363
|
function loadConfig() {
|
|
316
364
|
const d = getDb();
|
|
@@ -366,6 +414,15 @@ function loadDefaults(d) {
|
|
|
366
414
|
},
|
|
367
415
|
...map.updateChannel !== void 0 && {
|
|
368
416
|
updateChannel: map.updateChannel
|
|
417
|
+
},
|
|
418
|
+
...map.webAccessEnabled !== void 0 && {
|
|
419
|
+
webAccessEnabled: map.webAccessEnabled
|
|
420
|
+
},
|
|
421
|
+
...map.mobileAccessEnabled !== void 0 && {
|
|
422
|
+
mobileAccessEnabled: map.mobileAccessEnabled
|
|
423
|
+
},
|
|
424
|
+
...map.networkAccessEnabled !== void 0 && {
|
|
425
|
+
networkAccessEnabled: map.networkAccessEnabled
|
|
369
426
|
}
|
|
370
427
|
};
|
|
371
428
|
}
|
|
@@ -398,7 +455,10 @@ function loadRemoteHosts(d) {
|
|
|
398
455
|
hostname: r.hostname,
|
|
399
456
|
user: r.user,
|
|
400
457
|
port: r.port,
|
|
458
|
+
...r.auth_method != null && { authMethod: r.auth_method },
|
|
401
459
|
...r.ssh_key_path != null && { sshKeyPath: r.ssh_key_path },
|
|
460
|
+
...r.credential_id != null && { credentialId: r.credential_id },
|
|
461
|
+
...r.encrypted_password != null && { encryptedPassword: r.encrypted_password },
|
|
402
462
|
...r.ssh_options != null && { sshOptions: r.ssh_options }
|
|
403
463
|
}));
|
|
404
464
|
}
|
|
@@ -474,7 +534,7 @@ function saveConfig(config) {
|
|
|
474
534
|
}
|
|
475
535
|
d.prepare("DELETE FROM remote_hosts").run();
|
|
476
536
|
const insertHost = d.prepare(
|
|
477
|
-
"INSERT INTO remote_hosts (id, label, hostname, user, port, ssh_key_path, ssh_options) VALUES (?, ?, ?, ?, ?, ?, ?)"
|
|
537
|
+
"INSERT INTO remote_hosts (id, label, hostname, user, port, auth_method, ssh_key_path, credential_id, encrypted_password, ssh_options) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
|
478
538
|
);
|
|
479
539
|
for (const h of config.remoteHosts ?? []) {
|
|
480
540
|
insertHost.run(
|
|
@@ -483,7 +543,10 @@ function saveConfig(config) {
|
|
|
483
543
|
h.hostname,
|
|
484
544
|
h.user,
|
|
485
545
|
h.port,
|
|
546
|
+
h.authMethod ?? "agent",
|
|
486
547
|
h.sshKeyPath ?? null,
|
|
548
|
+
h.credentialId ?? null,
|
|
549
|
+
h.encryptedPassword ?? null,
|
|
487
550
|
h.sshOptions ?? null
|
|
488
551
|
);
|
|
489
552
|
}
|
|
@@ -955,18 +1018,19 @@ var ConfigManager = class {
|
|
|
955
1018
|
}
|
|
956
1019
|
}
|
|
957
1020
|
/**
|
|
958
|
-
* Watch
|
|
959
|
-
*
|
|
1021
|
+
* Watch for external DB writes (e.g. MCP stdio process).
|
|
1022
|
+
* Detects: .db-signal (explicit), .db-wal changes, and .db changes (post-checkpoint).
|
|
960
1023
|
*/
|
|
961
1024
|
watchDb() {
|
|
962
1025
|
if (this.dbWatcher) return;
|
|
1026
|
+
const WATCH_SUFFIXES = [".db-signal", ".db-wal", ".db"];
|
|
963
1027
|
try {
|
|
964
1028
|
this.dbWatcher = fs2.watch(DB_DIR, (eventType, filename) => {
|
|
965
|
-
if (!filename || !filename.endsWith(
|
|
1029
|
+
if (!filename || !WATCH_SUFFIXES.some((s) => filename.endsWith(s))) return;
|
|
966
1030
|
if (this.debounceTimer) clearTimeout(this.debounceTimer);
|
|
967
1031
|
this.debounceTimer = setTimeout(() => {
|
|
968
1032
|
this.notifyChanged();
|
|
969
|
-
},
|
|
1033
|
+
}, 300);
|
|
970
1034
|
});
|
|
971
1035
|
} catch {
|
|
972
1036
|
}
|
|
@@ -1092,6 +1156,7 @@ function registerTaskTools(server) {
|
|
|
1092
1156
|
...(status === "done" || status === "cancelled") && { completedAt: now }
|
|
1093
1157
|
};
|
|
1094
1158
|
dbInsertTask(task);
|
|
1159
|
+
dbSignalChange();
|
|
1095
1160
|
return { content: [{ type: "text", text: JSON.stringify(task, null, 2) }] };
|
|
1096
1161
|
}
|
|
1097
1162
|
);
|
|
@@ -1143,6 +1208,7 @@ function registerTaskTools(server) {
|
|
|
1143
1208
|
if (!isDone && wasDone) updates.completedAt = void 0;
|
|
1144
1209
|
}
|
|
1145
1210
|
dbUpdateTask(args.id, updates);
|
|
1211
|
+
dbSignalChange();
|
|
1146
1212
|
const updated = dbGetTask(args.id);
|
|
1147
1213
|
return { content: [{ type: "text", text: JSON.stringify(updated, null, 2) }] };
|
|
1148
1214
|
}
|
|
@@ -1160,6 +1226,7 @@ function registerTaskTools(server) {
|
|
|
1160
1226
|
};
|
|
1161
1227
|
}
|
|
1162
1228
|
dbDeleteTask(args.id);
|
|
1229
|
+
dbSignalChange();
|
|
1163
1230
|
return { content: [{ type: "text", text: `Deleted task: ${task.title}` }] };
|
|
1164
1231
|
}
|
|
1165
1232
|
);
|
|
@@ -1323,6 +1390,7 @@ function registerProjectTools(server) {
|
|
|
1323
1390
|
...args.icon_color && { iconColor: args.icon_color }
|
|
1324
1391
|
};
|
|
1325
1392
|
dbInsertProject(project);
|
|
1393
|
+
dbSignalChange();
|
|
1326
1394
|
return { content: [{ type: "text", text: JSON.stringify(project, null, 2) }] };
|
|
1327
1395
|
}
|
|
1328
1396
|
);
|
|
@@ -1350,6 +1418,7 @@ function registerProjectTools(server) {
|
|
|
1350
1418
|
if (args.icon !== void 0) updates.icon = args.icon;
|
|
1351
1419
|
if (args.icon_color !== void 0) updates.iconColor = args.icon_color;
|
|
1352
1420
|
dbUpdateProject(args.name, updates);
|
|
1421
|
+
dbSignalChange();
|
|
1353
1422
|
const updated = dbGetProject(args.name);
|
|
1354
1423
|
return { content: [{ type: "text", text: JSON.stringify(updated, null, 2) }] };
|
|
1355
1424
|
}
|
|
@@ -1366,6 +1435,7 @@ function registerProjectTools(server) {
|
|
|
1366
1435
|
};
|
|
1367
1436
|
}
|
|
1368
1437
|
dbDeleteProject(args.name);
|
|
1438
|
+
dbSignalChange();
|
|
1369
1439
|
return { content: [{ type: "text", text: `Deleted project: ${args.name}` }] };
|
|
1370
1440
|
}
|
|
1371
1441
|
);
|
|
@@ -1824,6 +1894,7 @@ function registerWorkflowTools(server) {
|
|
|
1824
1894
|
...args.stagger_delay_ms && { staggerDelayMs: args.stagger_delay_ms }
|
|
1825
1895
|
};
|
|
1826
1896
|
dbInsertWorkflow(workflow);
|
|
1897
|
+
dbSignalChange();
|
|
1827
1898
|
return { content: [{ type: "text", text: JSON.stringify(workflow, null, 2) }] };
|
|
1828
1899
|
}
|
|
1829
1900
|
);
|
|
@@ -1858,6 +1929,7 @@ function registerWorkflowTools(server) {
|
|
|
1858
1929
|
if (args.enabled !== void 0) updates.enabled = args.enabled;
|
|
1859
1930
|
if (args.stagger_delay_ms !== void 0) updates.staggerDelayMs = args.stagger_delay_ms;
|
|
1860
1931
|
dbUpdateWorkflow(args.id, updates);
|
|
1932
|
+
dbSignalChange();
|
|
1861
1933
|
return {
|
|
1862
1934
|
content: [{ type: "text", text: JSON.stringify({ ...workflow, ...updates }, null, 2) }]
|
|
1863
1935
|
};
|
|
@@ -1877,6 +1949,7 @@ function registerWorkflowTools(server) {
|
|
|
1877
1949
|
};
|
|
1878
1950
|
}
|
|
1879
1951
|
dbDeleteWorkflow(args.id);
|
|
1952
|
+
dbSignalChange();
|
|
1880
1953
|
return { content: [{ type: "text", text: `Deleted workflow: ${workflow.name}` }] };
|
|
1881
1954
|
}
|
|
1882
1955
|
);
|
|
@@ -2382,6 +2455,7 @@ function registerWorkspaceTools(server) {
|
|
|
2382
2455
|
...args.icon_color && { iconColor: args.icon_color }
|
|
2383
2456
|
};
|
|
2384
2457
|
dbInsertWorkspace(workspace);
|
|
2458
|
+
dbSignalChange();
|
|
2385
2459
|
return { content: [{ type: "text", text: JSON.stringify(workspace, null, 2) }] };
|
|
2386
2460
|
}
|
|
2387
2461
|
);
|
|
@@ -2409,6 +2483,7 @@ function registerWorkspaceTools(server) {
|
|
|
2409
2483
|
if (args.icon_color !== void 0) updates.iconColor = args.icon_color;
|
|
2410
2484
|
if (args.order !== void 0) updates.order = args.order;
|
|
2411
2485
|
dbUpdateWorkspace(args.id, updates);
|
|
2486
|
+
dbSignalChange();
|
|
2412
2487
|
const updated = dbListWorkspaces().find((w) => w.id === args.id);
|
|
2413
2488
|
return { content: [{ type: "text", text: JSON.stringify(updated, null, 2) }] };
|
|
2414
2489
|
}
|
|
@@ -2433,6 +2508,7 @@ function registerWorkspaceTools(server) {
|
|
|
2433
2508
|
};
|
|
2434
2509
|
}
|
|
2435
2510
|
dbDeleteWorkspace(args.id);
|
|
2511
|
+
dbSignalChange();
|
|
2436
2512
|
return { content: [{ type: "text", text: `Deleted workspace: ${workspace.name}` }] };
|
|
2437
2513
|
}
|
|
2438
2514
|
);
|
|
@@ -2460,7 +2536,7 @@ console.warn = (...args) => _origError("[mcp:warn]", ...args);
|
|
|
2460
2536
|
console.error = (...args) => _origError("[mcp:error]", ...args);
|
|
2461
2537
|
async function main() {
|
|
2462
2538
|
configManager.init();
|
|
2463
|
-
const version = true ? "0.
|
|
2539
|
+
const version = true ? "0.3.0-beta.0" : createRequire(import.meta.url)("../package.json").version;
|
|
2464
2540
|
const server = createMcpServer(version);
|
|
2465
2541
|
const transport = new StdioServerTransport();
|
|
2466
2542
|
await server.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibegrid/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-beta.0",
|
|
4
4
|
"description": "VibeGrid MCP server — task management, git, and workflow tools for AI coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
34
|
-
"
|
|
34
|
+
"libsql": "^0.5.22",
|
|
35
35
|
"pino": "^9.6.0",
|
|
36
36
|
"ws": "^8.18.0",
|
|
37
37
|
"zod": "^4.3.6"
|