@vibekiln/cutline-mcp-cli 0.1.0 → 0.1.2
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 +2 -7
- package/dist/commands/setup.js +38 -5
- package/dist/servers/{chunk-ZVWDXO6M.js → chunk-WWTNBUIX.js} +12 -0
- package/dist/servers/cutline-server.js +7 -4
- package/dist/servers/{data-client-FPUZBUO3.js → data-client-2YBU5KRO.js} +3 -1
- package/dist/servers/exploration-server.js +1 -1
- package/dist/servers/integrations-server.js +1 -1
- package/dist/servers/output-server.js +1 -1
- package/dist/servers/premortem-server.js +1 -1
- package/dist/servers/tools-server.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,14 +27,9 @@ Download `cutline-mcp.mcpb` from the [latest release](https://github.com/kylewad
|
|
|
27
27
|
## Quick Start
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
# 1.
|
|
31
|
-
cutline-mcp login
|
|
32
|
-
|
|
33
|
-
# 2. Initialize your project (writes IDE rules)
|
|
30
|
+
# 1. Install and run setup (does login + IDE config + rules)
|
|
34
31
|
cd /path/to/your/project
|
|
35
|
-
cutline-mcp
|
|
36
|
-
|
|
37
|
-
# 3. Connect MCP servers to your IDE
|
|
32
|
+
npm install -g @vibekiln/cutline-mcp-cli@latest
|
|
38
33
|
cutline-mcp setup
|
|
39
34
|
```
|
|
40
35
|
|
package/dist/commands/setup.js
CHANGED
|
@@ -83,14 +83,39 @@ function prompt(question) {
|
|
|
83
83
|
});
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
-
function
|
|
86
|
+
function resolveServeRuntime() {
|
|
87
|
+
// Optional explicit override for advanced environments.
|
|
88
|
+
if (process.env.CUTLINE_MCP_BIN?.trim()) {
|
|
89
|
+
return {
|
|
90
|
+
command: process.env.CUTLINE_MCP_BIN.trim(),
|
|
91
|
+
argsPrefix: [],
|
|
92
|
+
source: 'binary',
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// Prefer the globally installed binary for faster/more reliable startup.
|
|
96
|
+
const voltaBin = join(homedir(), '.volta', 'bin', 'cutline-mcp');
|
|
97
|
+
if (existsSync(voltaBin)) {
|
|
98
|
+
return {
|
|
99
|
+
command: voltaBin,
|
|
100
|
+
argsPrefix: [],
|
|
101
|
+
source: 'binary',
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// Fallback for machines without a global install.
|
|
87
105
|
const voltaNpx = join(homedir(), '.volta', 'bin', 'npx');
|
|
88
106
|
const npxCommand = existsSync(voltaNpx) ? voltaNpx : 'npx';
|
|
107
|
+
return {
|
|
108
|
+
command: npxCommand,
|
|
109
|
+
argsPrefix: ['-y', '@vibekiln/cutline-mcp-cli@latest'],
|
|
110
|
+
source: 'npx',
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function buildServerConfig(runtime) {
|
|
89
114
|
const config = {};
|
|
90
115
|
for (const name of SERVER_NAMES) {
|
|
91
116
|
config[`cutline-${name}`] = {
|
|
92
|
-
command:
|
|
93
|
-
args: [
|
|
117
|
+
command: runtime.command,
|
|
118
|
+
args: [...runtime.argsPrefix, 'serve', name],
|
|
94
119
|
};
|
|
95
120
|
}
|
|
96
121
|
return config;
|
|
@@ -198,7 +223,8 @@ export async function setupCommand(options) {
|
|
|
198
223
|
catch { /* ignore parse errors */ }
|
|
199
224
|
}
|
|
200
225
|
// ── 3. Write MCP server config to IDEs ───────────────────────────────────
|
|
201
|
-
const
|
|
226
|
+
const runtime = resolveServeRuntime();
|
|
227
|
+
const serverConfig = buildServerConfig(runtime);
|
|
202
228
|
const home = homedir();
|
|
203
229
|
const ideConfigs = [
|
|
204
230
|
{ name: 'Cursor', path: join(home, '.cursor', 'mcp.json') },
|
|
@@ -217,6 +243,12 @@ export async function setupCommand(options) {
|
|
|
217
243
|
}
|
|
218
244
|
if (wroteAny) {
|
|
219
245
|
console.log(chalk.dim('\n MCP server entries merged into IDE config (existing servers preserved).\n'));
|
|
246
|
+
if (runtime.source === 'binary') {
|
|
247
|
+
console.log(chalk.dim(` Using local MCP binary: ${runtime.command}\n`));
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
console.log(chalk.dim(' Local `cutline-mcp` binary not found — using npx fallback.\n'));
|
|
251
|
+
}
|
|
220
252
|
}
|
|
221
253
|
else {
|
|
222
254
|
console.log(chalk.yellow('\n No IDE config files found. Printing config for manual setup:\n'));
|
|
@@ -231,7 +263,8 @@ export async function setupCommand(options) {
|
|
|
231
263
|
console.log(chalk.dim(' If you prefer `claude mcp add` instead of ~/.claude.json:\n'));
|
|
232
264
|
const coreServers = ['constraints', 'premortem', 'tools', 'exploration'];
|
|
233
265
|
for (const name of coreServers) {
|
|
234
|
-
|
|
266
|
+
const invocation = [runtime.command, ...runtime.argsPrefix, 'serve', name].join(' ');
|
|
267
|
+
console.log(chalk.cyan(` claude mcp add cutline-${name} -- ${invocation}`));
|
|
235
268
|
}
|
|
236
269
|
console.log();
|
|
237
270
|
// ── 6. What you can do ───────────────────────────────────────────────────
|
|
@@ -398,6 +398,17 @@ async function resolveAuthContextFree(authToken) {
|
|
|
398
398
|
function getBaseUrl(environment) {
|
|
399
399
|
return environment === "staging" ? "https://us-central1-cutline-staging.cloudfunctions.net" : "https://us-central1-cutline-prod.cloudfunctions.net";
|
|
400
400
|
}
|
|
401
|
+
function getSiteUrl(environment) {
|
|
402
|
+
return environment === "staging" ? "https://cutline-staging.web.app" : "https://thecutline.ai";
|
|
403
|
+
}
|
|
404
|
+
async function getPublicSiteUrlForCurrentAuth() {
|
|
405
|
+
const apiKeyInfo = getStoredApiKey();
|
|
406
|
+
if (apiKeyInfo?.environment) {
|
|
407
|
+
return getSiteUrl(apiKeyInfo.environment);
|
|
408
|
+
}
|
|
409
|
+
const stored = await getStoredToken();
|
|
410
|
+
return getSiteUrl(stored?.environment);
|
|
411
|
+
}
|
|
401
412
|
var cachedBaseUrl;
|
|
402
413
|
var cachedIdToken;
|
|
403
414
|
var tokenExpiresAt = 0;
|
|
@@ -982,6 +993,7 @@ export {
|
|
|
982
993
|
resolveAuthContext,
|
|
983
994
|
requirePremiumWithAutoAuth,
|
|
984
995
|
resolveAuthContextFree,
|
|
996
|
+
getPublicSiteUrlForCurrentAuth,
|
|
985
997
|
listPremortems,
|
|
986
998
|
getPremortem,
|
|
987
999
|
createPremortem,
|
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
getNodesWithEmbeddings,
|
|
50
50
|
getPersona,
|
|
51
51
|
getPremortem,
|
|
52
|
+
getPublicSiteUrlForCurrentAuth,
|
|
52
53
|
getScanRateLimit,
|
|
53
54
|
getTemplate,
|
|
54
55
|
getTestCasesForEntity,
|
|
@@ -73,7 +74,7 @@ import {
|
|
|
73
74
|
upsertEntities,
|
|
74
75
|
upsertNodes,
|
|
75
76
|
validateRequestSize
|
|
76
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-WWTNBUIX.js";
|
|
77
78
|
import {
|
|
78
79
|
GraphTraverser,
|
|
79
80
|
computeGenericGraphMetrics,
|
|
@@ -6965,7 +6966,7 @@ function deltaStr(current, previous) {
|
|
|
6965
6966
|
return " (no change)";
|
|
6966
6967
|
return diff > 0 ? ` (**+${diff}** since last scan)` : ` (**${diff}** since last scan)`;
|
|
6967
6968
|
}
|
|
6968
|
-
function formatAuditOutput(result, reportId) {
|
|
6969
|
+
function formatAuditOutput(result, reportId, publicSiteUrl = "https://thecutline.ai") {
|
|
6969
6970
|
const m = result.metrics;
|
|
6970
6971
|
const p = result.previousMetrics;
|
|
6971
6972
|
const isRescan = !!p;
|
|
@@ -7016,7 +7017,7 @@ function formatAuditOutput(result, reportId) {
|
|
|
7016
7017
|
lines.push(`### Next Steps`, ``, `No critical findings detected. Run a **deep dive** for product-specific`, `analysis with feature coverage and the generic scores as a prior.`);
|
|
7017
7018
|
}
|
|
7018
7019
|
if (reportId) {
|
|
7019
|
-
lines.push(``, `---`, ``, `**View & share this report:**
|
|
7020
|
+
lines.push(``, `---`, ``, `**View & share this report:** ${publicSiteUrl}/report/${reportId}`);
|
|
7020
7021
|
}
|
|
7021
7022
|
lines.push(``, `> Scores reflect constraint binding health \u2014 how well your codebase maps to`, `> engineering guardrails. They improve as you address findings and re-scan.`);
|
|
7022
7023
|
return lines.join("\n");
|
|
@@ -8255,6 +8256,7 @@ Why AI: ${idea.whyAI}`
|
|
|
8255
8256
|
console.error("[code_audit] Score snapshot failed (non-fatal):", e);
|
|
8256
8257
|
}
|
|
8257
8258
|
let reportId;
|
|
8259
|
+
let reportSiteUrl = "https://thecutline.ai";
|
|
8258
8260
|
try {
|
|
8259
8261
|
const saved = await saveScanReport({
|
|
8260
8262
|
metrics: {
|
|
@@ -8280,11 +8282,12 @@ Why AI: ${idea.whyAI}`
|
|
|
8280
8282
|
} : null
|
|
8281
8283
|
});
|
|
8282
8284
|
reportId = saved.id;
|
|
8285
|
+
reportSiteUrl = await getPublicSiteUrlForCurrentAuth();
|
|
8283
8286
|
} catch (e) {
|
|
8284
8287
|
console.error("[code_audit] Report persistence failed (non-fatal):", e);
|
|
8285
8288
|
}
|
|
8286
8289
|
return {
|
|
8287
|
-
content: [{ type: "text", text: formatAuditOutput(result, reportId) }]
|
|
8290
|
+
content: [{ type: "text", text: formatAuditOutput(result, reportId, reportSiteUrl) }]
|
|
8288
8291
|
};
|
|
8289
8292
|
}
|
|
8290
8293
|
const authCtx = await resolveAuthContext(args.auth_token);
|
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
getPersona,
|
|
51
51
|
getPodcastIntroductions,
|
|
52
52
|
getPremortem,
|
|
53
|
+
getPublicSiteUrlForCurrentAuth,
|
|
53
54
|
getReadinessReport,
|
|
54
55
|
getScanRateLimit,
|
|
55
56
|
getTemplate,
|
|
@@ -77,7 +78,7 @@ import {
|
|
|
77
78
|
upsertEdges,
|
|
78
79
|
upsertEntities,
|
|
79
80
|
upsertNodes
|
|
80
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-WWTNBUIX.js";
|
|
81
82
|
export {
|
|
82
83
|
addEdges,
|
|
83
84
|
addEntity,
|
|
@@ -130,6 +131,7 @@ export {
|
|
|
130
131
|
getPersona,
|
|
131
132
|
getPodcastIntroductions,
|
|
132
133
|
getPremortem,
|
|
134
|
+
getPublicSiteUrlForCurrentAuth,
|
|
133
135
|
getReadinessReport,
|
|
134
136
|
getScanRateLimit,
|
|
135
137
|
getTemplate,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
requirePremiumWithAutoAuth,
|
|
15
15
|
updateExplorationSession,
|
|
16
16
|
validateRequestSize
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-WWTNBUIX.js";
|
|
18
18
|
|
|
19
19
|
// ../mcp/dist/mcp/src/exploration-server.js
|
|
20
20
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
requirePremiumWithAutoAuth,
|
|
14
14
|
validateAuth,
|
|
15
15
|
validateRequestSize
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-WWTNBUIX.js";
|
|
17
17
|
|
|
18
18
|
// ../mcp/dist/mcp/src/integrations-server.js
|
|
19
19
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
mapErrorToMcp,
|
|
14
14
|
requirePremiumWithAutoAuth,
|
|
15
15
|
validateRequestSize
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-WWTNBUIX.js";
|
|
17
17
|
|
|
18
18
|
// ../mcp/dist/mcp/src/output-server.js
|
|
19
19
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
requirePremiumWithAutoAuth,
|
|
22
22
|
validateAuth,
|
|
23
23
|
validateRequestSize
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-WWTNBUIX.js";
|
|
25
25
|
|
|
26
26
|
// ../mcp/dist/mcp/src/tools-server.js
|
|
27
27
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
package/package.json
CHANGED