mrmainspring 0.1.8 → 0.2.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/cli.d.ts +1 -1
- package/dist/cli.js +115 -10
- package/dist/client-setup.d.ts +8 -0
- package/dist/client-setup.js +39 -0
- package/dist/index.js +1 -1
- package/package.json +2 -1
package/dist/cli.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ type InitResult = {
|
|
|
3
3
|
dataDir: string;
|
|
4
4
|
logsDir: string;
|
|
5
5
|
};
|
|
6
|
-
export declare function runCliCommand(args: string[]): boolean
|
|
6
|
+
export declare function runCliCommand(args: string[]): Promise<boolean>;
|
|
7
7
|
export declare function initializeLocalSetup(env?: NodeJS.ProcessEnv): InitResult;
|
|
8
8
|
export declare function formatMcpConfig(): string;
|
|
9
9
|
export {};
|
package/dist/cli.js
CHANGED
|
@@ -2,8 +2,9 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
+
import * as clack from "@clack/prompts";
|
|
5
6
|
import { loadConfig } from "./config.js";
|
|
6
|
-
import { setupAllClients, formatClientSetupReport } from "./client-setup.js";
|
|
7
|
+
import { detectClients, configureClients, setupAllClients, formatClientSetupReport } from "./client-setup.js";
|
|
7
8
|
import { ensureGrimoireMasterKey, loadLocalEnvFile, resolveEnvPath } from "./env-file.js";
|
|
8
9
|
import { getDefaultMainspringPaths } from "./paths.js";
|
|
9
10
|
const _pkgRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
@@ -34,7 +35,7 @@ Advanced users can still set SIGIL_ENV_FILE, SIGIL_DATA_DIR, Supabase, Casper,
|
|
|
34
35
|
and x402 env vars. No env vars are required for local memory, Grimoire, audit,
|
|
35
36
|
or payment preflight tools.
|
|
36
37
|
`;
|
|
37
|
-
export function runCliCommand(args) {
|
|
38
|
+
export async function runCliCommand(args) {
|
|
38
39
|
const [command, target] = args;
|
|
39
40
|
if (!command || command === "stdio" || command === "server" || command === "mcp") {
|
|
40
41
|
return false;
|
|
@@ -57,16 +58,28 @@ export function runCliCommand(args) {
|
|
|
57
58
|
return true;
|
|
58
59
|
}
|
|
59
60
|
if (command === "setup") {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const clientResults = setupAllClients();
|
|
63
|
-
const report = formatClientSetupReport(clientResults);
|
|
64
|
-
if (report) {
|
|
65
|
-
process.stdout.write(report);
|
|
61
|
+
if (process.stdin.isTTY) {
|
|
62
|
+
await runInteractiveSetup();
|
|
66
63
|
}
|
|
67
64
|
else {
|
|
68
|
-
|
|
69
|
-
process.stdout.write(
|
|
65
|
+
const result = initializeLocalSetup();
|
|
66
|
+
process.stdout.write(formatInitResult(result));
|
|
67
|
+
const clientResults = setupAllClients();
|
|
68
|
+
const report = formatClientSetupReport(clientResults);
|
|
69
|
+
if (report) {
|
|
70
|
+
process.stdout.write(report);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
process.stdout.write("\nNo MCP clients detected automatically.\n" +
|
|
74
|
+
"Add this to your MCP client config (Claude Desktop, Cursor, Windsurf, Zed, VS Code, Continue, or any MCP host):\n\n");
|
|
75
|
+
process.stdout.write(`${formatMcpConfig()}\n`);
|
|
76
|
+
process.stdout.write("\nConfig file locations:\n" +
|
|
77
|
+
" Claude Desktop ~/Library/Application Support/Claude/claude_desktop_config.json\n" +
|
|
78
|
+
" Cursor ~/.cursor/mcp.json\n" +
|
|
79
|
+
" Windsurf ~/.codeium/windsurf/mcp_config.json\n" +
|
|
80
|
+
" Zed ~/.config/zed/settings.json (context_servers format)\n" +
|
|
81
|
+
" VS Code ~/.vscode/mcp.json\n\n");
|
|
82
|
+
}
|
|
70
83
|
}
|
|
71
84
|
return true;
|
|
72
85
|
}
|
|
@@ -85,6 +98,98 @@ export function runCliCommand(args) {
|
|
|
85
98
|
process.exitCode = 1;
|
|
86
99
|
return true;
|
|
87
100
|
}
|
|
101
|
+
async function runInteractiveSetup() {
|
|
102
|
+
clack.intro("Mr Mainspring — setup");
|
|
103
|
+
const result = initializeLocalSetup();
|
|
104
|
+
clack.log.success(`Local files ready\n Config: ${result.envFile}\n Data: ${result.dataDir}`);
|
|
105
|
+
const clients = detectClients();
|
|
106
|
+
const installed = clients.filter(c => c.installed);
|
|
107
|
+
const notInstalled = clients.filter(c => !c.installed);
|
|
108
|
+
let selected;
|
|
109
|
+
if (installed.length === 0) {
|
|
110
|
+
clack.log.warn("No MCP clients detected on this machine.");
|
|
111
|
+
clack.log.info("Add this JSON to your client config manually:\n\n" +
|
|
112
|
+
formatMcpConfig() + "\n\n" +
|
|
113
|
+
" Claude Desktop ~/Library/Application Support/Claude/claude_desktop_config.json\n" +
|
|
114
|
+
" Cursor ~/.cursor/mcp.json\n" +
|
|
115
|
+
" Windsurf ~/.codeium/windsurf/mcp_config.json\n" +
|
|
116
|
+
" Zed ~/.config/zed/settings.json\n" +
|
|
117
|
+
" VS Code ~/.vscode/mcp.json");
|
|
118
|
+
clack.outro("Restart your client after updating the config.");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const choices = await clack.multiselect({
|
|
122
|
+
message: "Which MCP clients should we configure?",
|
|
123
|
+
options: [
|
|
124
|
+
...installed.map(c => ({
|
|
125
|
+
value: c,
|
|
126
|
+
label: c.name,
|
|
127
|
+
hint: c.configPath,
|
|
128
|
+
selected: true
|
|
129
|
+
})),
|
|
130
|
+
...notInstalled.map(c => ({
|
|
131
|
+
value: c,
|
|
132
|
+
label: c.name,
|
|
133
|
+
hint: "not found",
|
|
134
|
+
selected: false
|
|
135
|
+
}))
|
|
136
|
+
],
|
|
137
|
+
required: false
|
|
138
|
+
});
|
|
139
|
+
if (clack.isCancel(choices)) {
|
|
140
|
+
clack.cancel("Setup cancelled.");
|
|
141
|
+
process.exitCode = 1;
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
selected = choices;
|
|
145
|
+
if (selected.length === 0) {
|
|
146
|
+
clack.log.warn("No clients selected — nothing configured.");
|
|
147
|
+
clack.outro("Run mainspring setup again when ready.");
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const configResults = configureClients(selected.filter(c => c.installed));
|
|
151
|
+
const written = configResults.filter(r => r.status === "written").map(r => r.name);
|
|
152
|
+
const alreadySet = configResults.filter(r => r.status === "already-set").map(r => r.name);
|
|
153
|
+
const errors = configResults.filter(r => r.status === "error");
|
|
154
|
+
if (written.length > 0)
|
|
155
|
+
clack.log.success(`Configured: ${written.join(", ")}`);
|
|
156
|
+
if (alreadySet.length > 0)
|
|
157
|
+
clack.log.info(`Already configured: ${alreadySet.join(", ")}`);
|
|
158
|
+
for (const e of errors)
|
|
159
|
+
clack.log.error(`${e.name}: ${e.error}`);
|
|
160
|
+
const wantCasper = await clack.confirm({
|
|
161
|
+
message: "Enable Casper on-chain anchoring?",
|
|
162
|
+
initialValue: false
|
|
163
|
+
});
|
|
164
|
+
if (clack.isCancel(wantCasper)) {
|
|
165
|
+
clack.cancel("Setup cancelled.");
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (wantCasper) {
|
|
169
|
+
clack.log.info("Add to your .env file:\n\n" +
|
|
170
|
+
" CASPER_ENABLE_REAL_SUBMISSION=true\n" +
|
|
171
|
+
" CASPER_RPC_URL=https://node.testnet.casper.network/rpc\n" +
|
|
172
|
+
" CASPER_ACCOUNT_KEY_PATH=./keys/your-key.pem\n\n" +
|
|
173
|
+
"Then restart your MCP client.");
|
|
174
|
+
}
|
|
175
|
+
const wantX402 = await clack.confirm({
|
|
176
|
+
message: "Enable x402 micropayments?",
|
|
177
|
+
initialValue: false
|
|
178
|
+
});
|
|
179
|
+
if (clack.isCancel(wantX402)) {
|
|
180
|
+
clack.cancel("Setup cancelled.");
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (wantX402) {
|
|
184
|
+
clack.log.info("Add to your .env file:\n\n" +
|
|
185
|
+
" X402_ENABLE_REAL_SETTLEMENT=true\n" +
|
|
186
|
+
" X402_SETTLEMENT_MODE=casper-cli\n" +
|
|
187
|
+
" X402_BUYER_ACCOUNT_HASH=account-hash-<64 hex chars>\n" +
|
|
188
|
+
" CASPER_ENABLE_REAL_SUBMISSION=true\n\n" +
|
|
189
|
+
"Get your account hash: casper-client account-address --public-key <your-pubkey-hex>");
|
|
190
|
+
}
|
|
191
|
+
clack.outro("Restart your MCP clients to load the server.");
|
|
192
|
+
}
|
|
88
193
|
export function initializeLocalSetup(env = process.env) {
|
|
89
194
|
const paths = getDefaultMainspringPaths(env);
|
|
90
195
|
const envFile = env.SIGIL_ENV_FILE?.trim() ? resolveEnvPath(env) : paths.envFile;
|
package/dist/client-setup.d.ts
CHANGED
|
@@ -4,5 +4,13 @@ export type ClientSetupResult = {
|
|
|
4
4
|
status: "written" | "already-set" | "not-installed" | "error";
|
|
5
5
|
error?: string;
|
|
6
6
|
};
|
|
7
|
+
export type ClientDetection = {
|
|
8
|
+
name: string;
|
|
9
|
+
configPath: string;
|
|
10
|
+
installed: boolean;
|
|
11
|
+
format: "standard" | "zed" | "continue";
|
|
12
|
+
};
|
|
13
|
+
export declare function detectClients(env?: NodeJS.ProcessEnv): ClientDetection[];
|
|
14
|
+
export declare function configureClients(selected: ClientDetection[], env?: NodeJS.ProcessEnv): ClientSetupResult[];
|
|
7
15
|
export declare function setupAllClients(env?: NodeJS.ProcessEnv): ClientSetupResult[];
|
|
8
16
|
export declare function formatClientSetupReport(results: ClientSetupResult[]): string;
|
package/dist/client-setup.js
CHANGED
|
@@ -82,6 +82,45 @@ function mergeConfig(json, format) {
|
|
|
82
82
|
}
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
+
export function detectClients(env = process.env) {
|
|
86
|
+
const plat = process.platform;
|
|
87
|
+
const seen = new Set();
|
|
88
|
+
const results = [];
|
|
89
|
+
for (const client of CLIENTS) {
|
|
90
|
+
if (!client.platforms.includes(plat))
|
|
91
|
+
continue;
|
|
92
|
+
const configPath = expandPath(client.path, env);
|
|
93
|
+
const key = `${client.name}:${configPath}`;
|
|
94
|
+
if (seen.has(key))
|
|
95
|
+
continue;
|
|
96
|
+
seen.add(key);
|
|
97
|
+
results.push({ name: client.name, configPath, installed: isInstalled(configPath), format: client.format });
|
|
98
|
+
}
|
|
99
|
+
return results;
|
|
100
|
+
}
|
|
101
|
+
export function configureClients(selected, env = process.env) {
|
|
102
|
+
const results = [];
|
|
103
|
+
for (const client of selected) {
|
|
104
|
+
if (!client.installed) {
|
|
105
|
+
results.push({ name: client.name, configPath: client.configPath, status: "not-installed" });
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
const json = readJson(client.configPath);
|
|
110
|
+
if (alreadySet(json, client.format)) {
|
|
111
|
+
results.push({ name: client.name, configPath: client.configPath, status: "already-set" });
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
mkdirSync(dirname(client.configPath), { recursive: true });
|
|
115
|
+
writeFileSync(client.configPath, JSON.stringify(mergeConfig(json, client.format), null, 2) + "\n", "utf8");
|
|
116
|
+
results.push({ name: client.name, configPath: client.configPath, status: "written" });
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
results.push({ name: client.name, configPath: client.configPath, status: "error", error: String(e) });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return results;
|
|
123
|
+
}
|
|
85
124
|
export function setupAllClients(env = process.env) {
|
|
86
125
|
const plat = process.platform;
|
|
87
126
|
const results = [];
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { loadConfig } from "./config.js";
|
|
|
5
5
|
import { ensureGrimoireMasterKey, loadLocalEnvFile } from "./env-file.js";
|
|
6
6
|
import { createSigilServer } from "./server.js";
|
|
7
7
|
async function main() {
|
|
8
|
-
if (runCliCommand(process.argv.slice(2))) {
|
|
8
|
+
if (await runCliCommand(process.argv.slice(2))) {
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
11
|
loadLocalEnvFile();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mrmainspring",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Mr Mainspring MCP backend with memory, Grimoire policies, audit, Casper anchoring, and x402 settlement boundaries.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"x402:signer": "tsx scripts/x402-signer-sidecar.ts"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
+
"@clack/prompts": "^1.5.1",
|
|
50
51
|
"@modelcontextprotocol/sdk": "^1.13.0",
|
|
51
52
|
"zod": "^3.25.76"
|
|
52
53
|
},
|