mrmainspring 0.1.5 → 0.1.6
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/cli.js +10 -2
- package/dist/client-setup.d.ts +8 -0
- package/dist/client-setup.js +113 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3,6 +3,7 @@ import { dirname, join } from "node:path";
|
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { loadConfig } from "./config.js";
|
|
6
|
+
import { setupAllClients, formatClientSetupReport } from "./client-setup.js";
|
|
6
7
|
import { ensureGrimoireMasterKey, loadLocalEnvFile, resolveEnvPath } from "./env-file.js";
|
|
7
8
|
import { getDefaultMainspringPaths } from "./paths.js";
|
|
8
9
|
const _pkgRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
@@ -58,8 +59,15 @@ export function runCliCommand(args) {
|
|
|
58
59
|
if (command === "setup") {
|
|
59
60
|
const result = initializeLocalSetup();
|
|
60
61
|
process.stdout.write(formatInitResult(result));
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
const clientResults = setupAllClients();
|
|
63
|
+
const report = formatClientSetupReport(clientResults);
|
|
64
|
+
if (report) {
|
|
65
|
+
process.stdout.write(report);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
process.stdout.write("\nNo MCP clients detected. Paste this into your client config manually:\n\n");
|
|
69
|
+
process.stdout.write(`${formatMcpConfig()}\n`);
|
|
70
|
+
}
|
|
63
71
|
return true;
|
|
64
72
|
}
|
|
65
73
|
if (command === "doctor") {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type ClientSetupResult = {
|
|
2
|
+
name: string;
|
|
3
|
+
configPath: string;
|
|
4
|
+
status: "written" | "already-set" | "not-installed" | "error";
|
|
5
|
+
error?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function setupAllClients(env?: NodeJS.ProcessEnv): ClientSetupResult[];
|
|
8
|
+
export declare function formatClientSetupReport(results: ClientSetupResult[]): string;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
const MAINSPRING_ENTRY = {
|
|
5
|
+
command: "npx",
|
|
6
|
+
args: ["-y", "mrmainspring"]
|
|
7
|
+
};
|
|
8
|
+
const CLIENTS = [
|
|
9
|
+
// Claude Desktop
|
|
10
|
+
{ name: "Claude Desktop", path: "~/Library/Application Support/Claude/claude_desktop_config.json", platforms: ["darwin"], format: "standard" },
|
|
11
|
+
{ name: "Claude Desktop", path: "%APPDATA%/Claude/claude_desktop_config.json", platforms: ["win32"], format: "standard" },
|
|
12
|
+
{ name: "Claude Desktop", path: "~/.config/Claude/claude_desktop_config.json", platforms: ["linux"], format: "standard" },
|
|
13
|
+
// Claude Code CLI
|
|
14
|
+
{ name: "Claude Code", path: "~/.claude/settings.json", platforms: ["darwin", "linux", "win32"], format: "standard" },
|
|
15
|
+
// Cursor
|
|
16
|
+
{ name: "Cursor", path: "~/.cursor/mcp.json", platforms: ["darwin", "linux"], format: "standard" },
|
|
17
|
+
{ name: "Cursor", path: "%USERPROFILE%/.cursor/mcp.json", platforms: ["win32"], format: "standard" },
|
|
18
|
+
// Windsurf
|
|
19
|
+
{ name: "Windsurf", path: "~/.codeium/windsurf/mcp_config.json", platforms: ["darwin", "linux", "win32"], format: "standard" },
|
|
20
|
+
// Zed
|
|
21
|
+
{ name: "Zed", path: "~/.config/zed/settings.json", platforms: ["darwin", "linux"], format: "zed" },
|
|
22
|
+
];
|
|
23
|
+
function expandPath(p, env) {
|
|
24
|
+
return p
|
|
25
|
+
.replace(/^~/, homedir())
|
|
26
|
+
.replace(/%APPDATA%/gi, env.APPDATA ?? "")
|
|
27
|
+
.replace(/%USERPROFILE%/gi, env.USERPROFILE ?? homedir());
|
|
28
|
+
}
|
|
29
|
+
function isInstalled(configPath) {
|
|
30
|
+
return existsSync(dirname(configPath)) || existsSync(configPath);
|
|
31
|
+
}
|
|
32
|
+
function readJson(path) {
|
|
33
|
+
if (!existsSync(path))
|
|
34
|
+
return {};
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function alreadySet(json, format) {
|
|
43
|
+
if (format === "zed") {
|
|
44
|
+
return !!json.context_servers?.mainspring;
|
|
45
|
+
}
|
|
46
|
+
return !!json.mcpServers?.mainspring;
|
|
47
|
+
}
|
|
48
|
+
function mergeConfig(json, format) {
|
|
49
|
+
if (format === "zed") {
|
|
50
|
+
return {
|
|
51
|
+
...json,
|
|
52
|
+
context_servers: {
|
|
53
|
+
...(json.context_servers ?? {}),
|
|
54
|
+
mainspring: { command: { path: "npx", args: ["-y", "mrmainspring"] } }
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
...json,
|
|
60
|
+
mcpServers: {
|
|
61
|
+
...(json.mcpServers ?? {}),
|
|
62
|
+
mainspring: MAINSPRING_ENTRY
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export function setupAllClients(env = process.env) {
|
|
67
|
+
const plat = process.platform;
|
|
68
|
+
const results = [];
|
|
69
|
+
const seen = new Set();
|
|
70
|
+
for (const client of CLIENTS) {
|
|
71
|
+
if (!client.platforms.includes(plat))
|
|
72
|
+
continue;
|
|
73
|
+
const configPath = expandPath(client.path, env);
|
|
74
|
+
const key = `${client.name}:${configPath}`;
|
|
75
|
+
if (seen.has(key))
|
|
76
|
+
continue;
|
|
77
|
+
seen.add(key);
|
|
78
|
+
if (!isInstalled(configPath)) {
|
|
79
|
+
results.push({ name: client.name, configPath, status: "not-installed" });
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const json = readJson(configPath);
|
|
84
|
+
if (alreadySet(json, client.format)) {
|
|
85
|
+
results.push({ name: client.name, configPath, status: "already-set" });
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
mkdirSync(dirname(configPath), { recursive: true });
|
|
89
|
+
writeFileSync(configPath, JSON.stringify(mergeConfig(json, client.format), null, 2) + "\n", "utf8");
|
|
90
|
+
results.push({ name: client.name, configPath, status: "written" });
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
results.push({ name: client.name, configPath, status: "error", error: String(e) });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return results;
|
|
97
|
+
}
|
|
98
|
+
export function formatClientSetupReport(results) {
|
|
99
|
+
const active = results.filter(r => r.status !== "not-installed");
|
|
100
|
+
if (active.length === 0)
|
|
101
|
+
return "";
|
|
102
|
+
const lines = ["\nMCP clients configured:"];
|
|
103
|
+
for (const r of active) {
|
|
104
|
+
if (r.status === "written")
|
|
105
|
+
lines.push(` [ok] ${r.name} → ${r.configPath}`);
|
|
106
|
+
else if (r.status === "already-set")
|
|
107
|
+
lines.push(` [ok] ${r.name} → already configured`);
|
|
108
|
+
else
|
|
109
|
+
lines.push(` [warn] ${r.name} → ${r.error}`);
|
|
110
|
+
}
|
|
111
|
+
lines.push("\nRestart any open MCP clients to load the server.");
|
|
112
|
+
return lines.join("\n") + "\n";
|
|
113
|
+
}
|
package/package.json
CHANGED