@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 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. Authenticate (email only, no password)
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 init
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
 
@@ -83,14 +83,39 @@ function prompt(question) {
83
83
  });
84
84
  });
85
85
  }
86
- function buildServerConfig() {
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: npxCommand,
93
- args: ['-y', '@vibekiln/cutline-mcp-cli@latest', 'serve', name],
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 serverConfig = buildServerConfig();
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
- console.log(chalk.cyan(` claude mcp add cutline-${name} -- npx -y @vibekiln/cutline-mcp-cli serve ${name}`));
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-ZVWDXO6M.js";
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:** https://thecutline.ai/report/${reportId}`);
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-ZVWDXO6M.js";
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-ZVWDXO6M.js";
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-ZVWDXO6M.js";
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-ZVWDXO6M.js";
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";
@@ -27,7 +27,7 @@ import {
27
27
  updatePremortem,
28
28
  validateAuth,
29
29
  validateRequestSize
30
- } from "./chunk-ZVWDXO6M.js";
30
+ } from "./chunk-WWTNBUIX.js";
31
31
 
32
32
  // ../mcp/dist/mcp/src/premortem-server.js
33
33
  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-ZVWDXO6M.js";
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibekiln/cutline-mcp-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "CLI and MCP servers for Cutline — authenticate, then run constraint-aware MCP servers in Cursor or any MCP client.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",