@kylewadegrove/cutline-mcp-cli 0.4.2 → 0.5.1

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.
Files changed (49) hide show
  1. package/Dockerfile +11 -0
  2. package/README.md +177 -107
  3. package/dist/auth/callback.js +30 -32
  4. package/dist/auth/keychain.js +7 -15
  5. package/dist/commands/init.d.ts +4 -0
  6. package/dist/commands/init.js +246 -0
  7. package/dist/commands/login.js +39 -45
  8. package/dist/commands/logout.js +13 -19
  9. package/dist/commands/serve.d.ts +1 -0
  10. package/dist/commands/serve.js +38 -0
  11. package/dist/commands/setup.d.ts +5 -0
  12. package/dist/commands/setup.js +267 -0
  13. package/dist/commands/status.js +29 -35
  14. package/dist/commands/upgrade.js +44 -38
  15. package/dist/index.js +38 -14
  16. package/dist/servers/chunk-7FHM2GD3.js +5836 -0
  17. package/dist/servers/chunk-IVWF7VYZ.js +10086 -0
  18. package/dist/servers/chunk-JBJYSV4P.js +139 -0
  19. package/dist/servers/chunk-KMUSQOTJ.js +47 -0
  20. package/dist/servers/chunk-PD2HN2R5.js +908 -0
  21. package/dist/servers/chunk-PU7TL6S3.js +91 -0
  22. package/dist/servers/chunk-TGSEURMN.js +46 -0
  23. package/dist/servers/chunk-UBBAYTW3.js +946 -0
  24. package/dist/servers/cutline-server.js +11512 -0
  25. package/dist/servers/exploration-server.js +1030 -0
  26. package/dist/servers/graph-metrics-DCNR7JZN.js +12 -0
  27. package/dist/servers/integrations-server.js +121 -0
  28. package/dist/servers/output-server.js +120 -0
  29. package/dist/servers/pipeline-O5GJPNR4.js +20 -0
  30. package/dist/servers/premortem-handoff-XT4K3YDJ.js +10 -0
  31. package/dist/servers/premortem-server.js +958 -0
  32. package/dist/servers/score-history-HO5KRVGC.js +6 -0
  33. package/dist/servers/tools-server.js +291 -0
  34. package/dist/utils/config-store.js +13 -21
  35. package/dist/utils/config.js +2 -6
  36. package/mcpb/manifest.json +77 -0
  37. package/package.json +55 -9
  38. package/server.json +42 -0
  39. package/smithery.yaml +10 -0
  40. package/src/auth/callback.ts +0 -102
  41. package/src/auth/keychain.ts +0 -16
  42. package/src/commands/login.ts +0 -202
  43. package/src/commands/logout.ts +0 -30
  44. package/src/commands/status.ts +0 -153
  45. package/src/commands/upgrade.ts +0 -121
  46. package/src/index.ts +0 -40
  47. package/src/utils/config-store.ts +0 -46
  48. package/src/utils/config.ts +0 -65
  49. package/tsconfig.json +0 -22
package/Dockerfile ADDED
@@ -0,0 +1,11 @@
1
+ FROM node:20-slim AS base
2
+
3
+ WORKDIR /app
4
+
5
+ # Install the CLI globally from npm (includes bundled servers)
6
+ RUN npm install -g @kylewadegrove/cutline-mcp-cli@latest
7
+
8
+ # Default to the main constraints server (cutline-server.js)
9
+ # Override with: docker run ... cutline-mcp serve premortem
10
+ ENTRYPOINT ["cutline-mcp"]
11
+ CMD ["serve", "constraints"]
package/README.md CHANGED
@@ -1,173 +1,243 @@
1
- # Cutline MCP CLI
1
+ # Cutline MCP — Engineering Guardrails for Vibecoding
2
2
 
3
- Command-line tool for authenticating with Cutline MCP servers.
3
+ **Security, reliability, and scalability constraints for your coding agent.** Free code audits, 9 compliance frameworks, pre-mortem analysis, and a Red-Green-Refactor workflow — all injected directly into Cursor, Claude, Windsurf, or any MCP client.
4
4
 
5
- ## Installation
5
+ [![npm](https://img.shields.io/npm/v/@kylewadegrove/cutline-mcp-cli)](https://www.npmjs.com/package/@kylewadegrove/cutline-mcp-cli)
6
+ [![MCP Registry](https://img.shields.io/badge/MCP_Registry-ai.thecutline-blue)](https://registry.modelcontextprotocol.io)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ ## Install
10
+
11
+ ### npm (Recommended)
6
12
 
7
13
  ```bash
8
- cd functions/cutline/mcp-cli
9
- npm install
10
- npm run build
11
- npm link # Makes cutline-mcp available globally
14
+ npm install -g @kylewadegrove/cutline-mcp-cli@latest
12
15
  ```
13
16
 
14
- ## Usage
17
+ ### Docker
18
+
19
+ ```bash
20
+ docker run -i ghcr.io/kylewadegrove/cutline-mcp serve constraints
21
+ ```
15
22
 
16
- ### Login
23
+ ### Claude Desktop (.mcpb)
17
24
 
18
- Authenticate with Cutline and store credentials securely in your OS keychain:
25
+ Download `cutline-mcp.mcpb` from the [latest release](https://github.com/kylewadegrove/cutline/releases) and double-click to install.
26
+
27
+ ## Quick Start
19
28
 
20
29
  ```bash
30
+ # 1. Authenticate (email only, no password)
21
31
  cutline-mcp login
32
+
33
+ # 2. Initialize your project (writes IDE rules)
34
+ cd /path/to/your/project
35
+ cutline-mcp init
36
+
37
+ # 3. Connect MCP servers to your IDE
38
+ cutline-mcp setup
22
39
  ```
23
40
 
24
- This will:
25
- 1. Open your browser to Cutline's authentication page
26
- 2. After you log in, receive a refresh token
27
- 3. Store the token securely in your system keychain
28
- 4. Display confirmation with your email
41
+ Then ask your AI agent: **"Run an engineering audit on this codebase"**
29
42
 
30
- ### Check Status
43
+ ## What It Does
31
44
 
32
- View your current authentication status:
45
+ | Capability | Free | Premium |
46
+ |---|---|---|
47
+ | **Engineering Audit** — security, reliability, scalability scan | 3/month | Unlimited |
48
+ | **9 Compliance Frameworks** — SOC 2, PCI-DSS, HIPAA, GDPR, OWASP LLM, FedRAMP, GLBA, FERPA/COPPA | Auto-loaded | Auto-loaded |
49
+ | **Code Audit** — deep scan + RGR remediation plan | — | Unlimited |
50
+ | **Pre-Mortem Analysis** — risks, assumptions, competitive threats | — | Unlimited |
51
+ | **Constraint Graph** — product-specific NFR routing | — | Full access |
52
+ | **AI Personas** — stakeholder feedback on features | — | Full access |
53
+ | **Idea Validation** — fast-track from free web validation | — | Included |
33
54
 
34
- ```bash
35
- cutline-mcp status
36
- ```
55
+ ## 54 MCP Tools
37
56
 
38
- Shows:
39
- - Whether you're authenticated
40
- - Your email and user ID
41
- - Token expiration time
42
- - Subscription status (coming soon)
57
+ ### Free Tier
43
58
 
44
- ### Logout
59
+ | Tool | Description |
60
+ |---|---|
61
+ | `engineering_audit` | Security, reliability, and scalability scan (3/month) |
62
+ | `exploration_start` | Start a guided product idea exploration |
63
+ | `exploration_chat` | Continue an exploration conversation |
64
+ | `exploration_graduate` | Graduate top idea (teaser for free, full for premium) |
65
+ | `llm_status` | Check AI/LLM provider health |
66
+ | `perf_status` | Check MCP server performance metrics |
45
67
 
46
- Remove stored credentials:
68
+ ### Premium Tier (50+ tools)
47
69
 
48
- ```bash
49
- cutline-mcp logout
50
- ```
70
+ **Pre-Mortem & Deep Dive:** `premortem_run`, `premortem_from_idea`, `premortem_queue`, `premortem_status`, `premortem_kick`, `premortem_list`, `premortem_render_pdf`, `premortem_qa`, `premortem_regen_assumptions`, `premortem_regen_experiments`
51
71
 
52
- ## How It Works
72
+ **Personas:** `personas_list`, `personas_get`, `personas_chat`
53
73
 
54
- ### Security
74
+ **Constraint Graph:** `constraints_query`, `constraints_auto`, `constraints_ingest`, `constraints_list`, `constraints_learn`, `constraints_embed`, `constraints_semantic_query`, `constraints_ingest_persona`, `constraints_ingest_wiki`, `constraints_ingest_doc`, `constraints_heal`
55
75
 
56
- - **Keychain Storage**: Tokens are stored in your OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service)
57
- - **Refresh Tokens**: Long-lived refresh tokens are stored, not short-lived ID tokens
58
- - **Automatic Refresh**: MCP servers automatically exchange refresh tokens for fresh ID tokens
59
- - **Revocable**: Tokens can be revoked from your Cutline account settings
76
+ **Graph Operations:** `graph_ingest_requirements`, `graph_get_boundaries`, `graph_bind_codebase`, `graph_bind_confirm`, `graph_view`, `graph_conflicts`, `graph_metrics`
60
77
 
61
- ### Authentication Flow
78
+ **Code & RGR:** `code_audit`, `rgr_plan`, `rgr_complete_phase`, `export_readiness_badge`
62
79
 
63
- ```
64
- 1. User runs: cutline-mcp login
65
- 2. CLI starts local callback server on localhost:8765
66
- 3. CLI opens browser to: https://cutline.app/mcp-auth?callback=http://localhost:8765
67
- 4. User logs in to Cutline (or is already logged in)
68
- 5. Cutline redirects to: http://localhost:8765?token=REFRESH_TOKEN&email=user@example.com
69
- 6. CLI receives token and stores in keychain
70
- 7. CLI displays success message
71
- ```
80
+ **Wiki & Integrations:** `wiki_load`, `wiki_save`, `wiki_apply_edits`, `agent_chat`, `integrations_create_issues`
81
+
82
+ **Templates:** `template_list`, `template_get`, `template_create`, `template_discover`
72
83
 
73
- ### MCP Server Integration
74
-
75
- MCP servers automatically read tokens from the keychain:
76
-
77
- ```typescript
78
- // In utils.ts
79
- async function requirePremium(authToken?: string) {
80
- // Priority: explicit token > keychain > error
81
- let token = authToken;
82
-
83
- if (!token) {
84
- const refreshToken = await getStoredRefreshToken();
85
- if (refreshToken) {
86
- token = await exchangeRefreshToken(refreshToken);
87
- }
88
- }
89
-
90
- if (!token) {
91
- throw new Error("Run 'cutline-mcp login' to authenticate");
92
- }
93
-
94
- // ... validate token and subscription
95
- }
84
+ **Config:** `generate_cutline_md`
85
+
86
+ ## Commands
87
+
88
+ ### `login`
89
+
90
+ Authenticate with Cutline. Opens your browser for a quick email-only signup (no password needed). Stores credentials in your system keychain.
91
+
92
+ ```bash
93
+ cutline-mcp login
94
+ cutline-mcp login --staging # Use staging environment
95
+ cutline-mcp login --signup # Full sign-up page (email + password)
96
96
  ```
97
97
 
98
- ## Configuration
98
+ ### `init`
99
99
 
100
- ### Environment Variables
100
+ Generate IDE-specific config files for your project. Adapts to your tier:
101
101
 
102
- - `CUTLINE_AUTH_URL`: Override auth endpoint (default: `https://cutline.app/mcp-auth`)
103
- - `FIREBASE_API_KEY`: Firebase API key for token exchange
102
+ ```bash
103
+ cutline-mcp init
104
+ cutline-mcp init --project-root /path/to/project
105
+ ```
104
106
 
105
- ### Callback Port
107
+ **Free tier writes:**
108
+ - `.cursor/rules/rgr-workflow.mdc` — RGR cycle with `engineering_audit`
109
+ - `.cursor/rules/ambient-constraints.mdc` — Constraint checking guidance
110
+ - `CLAUDE.local.md` — Same instructions for Claude Code
106
111
 
107
- The CLI uses port `8765` for the OAuth callback. If this port is in use, you'll see an error. Close other applications and try again.
112
+ **Premium tier adds:**
113
+ - `.cursor/rules/cutline.mdc` — Points agent to `.cutline.md`
108
114
 
109
- ## Troubleshooting
115
+ All files are gitignored automatically.
110
116
 
111
- ### "Port 8765 is already in use"
117
+ ### `setup`
112
118
 
113
- Another application is using the callback port. Find and close it:
119
+ Print the MCP server configuration to add to your IDE.
114
120
 
115
121
  ```bash
116
- lsof -i :8765
117
- kill -9 <PID>
122
+ cutline-mcp setup
118
123
  ```
119
124
 
120
- ### "Authentication timeout"
125
+ ### `serve <server>`
121
126
 
122
- The browser didn't complete the OAuth flow within 5 minutes. Try again:
127
+ Start an MCP server (used by IDE MCP configs).
123
128
 
124
129
  ```bash
125
- cutline-mcp login
130
+ cutline-mcp serve constraints # Main server (engineering audit, constraints, graph)
131
+ cutline-mcp serve premortem # Pre-mortem and deep dive
132
+ cutline-mcp serve exploration # Idea exploration
133
+ cutline-mcp serve tools # Utility tools
134
+ cutline-mcp serve output # Export and rendering
135
+ cutline-mcp serve integrations # External integrations
126
136
  ```
127
137
 
128
- ### "Failed to refresh token"
138
+ ### `upgrade`
129
139
 
130
- Your stored token may be invalid or revoked. Log out and log in again:
140
+ Open the upgrade page and refresh your session.
131
141
 
132
142
  ```bash
133
- cutline-mcp logout
134
- cutline-mcp login
143
+ cutline-mcp upgrade
135
144
  ```
136
145
 
137
- ### Keychain Access Denied
146
+ ### `status` / `logout`
138
147
 
139
- On macOS, you may need to grant Terminal/IDE access to Keychain:
148
+ ```bash
149
+ cutline-mcp status # Check auth and subscription
150
+ cutline-mcp logout # Remove stored credentials
151
+ ```
140
152
 
141
- 1. Open Keychain Access app
142
- 2. Find "cutline-mcp" entry
143
- 3. Right-click → Get Info → Access Control
144
- 4. Add your Terminal/IDE to allowed applications
153
+ ## How It Works
154
+
155
+ ### Authentication
156
+
157
+ ```
158
+ 1. cutline-mcp login
159
+ 2. CLI starts local callback server on localhost:8765
160
+ 3. Browser opens — enter email, receive magic link, click it
161
+ 4. CLI receives token and stores it in your OS keychain
162
+ ```
163
+
164
+ Existing users who are already signed in complete automatically. Password sign-in is also available.
145
165
 
146
- ## Development
166
+ ### RGR Workflow
147
167
 
148
- ### Build
168
+ The `init` command creates rules that make your AI coding agent follow the Red-Green-Refactor cycle automatically:
169
+
170
+ 1. **Plan** — Check constraints before implementing
171
+ 2. **Implement** — Write code addressing the constraints
172
+ 3. **Verify** — Run a code audit to check coverage
173
+ 4. **Complete** — Mark the phase done to update readiness scores
174
+
175
+ ### Compliance Frameworks
176
+
177
+ Cutline auto-detects your stack and loads the appropriate compliance constraints:
178
+
179
+ | Framework | Triggers |
180
+ |---|---|
181
+ | SOC 2 | Always loaded |
182
+ | Security Baseline | Always loaded |
183
+ | PCI-DSS | Stripe, payment libs |
184
+ | HIPAA | Health/FHIR/HL7 libs |
185
+ | GDPR / CCPA | Analytics, auth libs |
186
+ | OWASP LLM Top 10 | OpenAI, LangChain, RAG |
187
+ | FedRAMP | GovCloud, FIPS |
188
+ | GLBA | Plaid, banking SDKs |
189
+ | FERPA / COPPA | Clever, Canvas, EdTech |
190
+
191
+ ## Registry Listings
192
+
193
+ ### Official MCP Registry
149
194
 
150
195
  ```bash
151
- npm run build
196
+ # Verify namespace
197
+ mcp-publisher login dns --domain thecutline.ai
198
+
199
+ # Publish
200
+ mcp-publisher publish
152
201
  ```
153
202
 
154
- ### Watch Mode
203
+ Config: [`server.json`](./server.json)
204
+
205
+ ### Smithery
206
+
207
+ Config: [`smithery.yaml`](./smithery.yaml) with [`Dockerfile`](./Dockerfile)
208
+
209
+ ### Claude Desktop Extension
155
210
 
156
211
  ```bash
157
- npm run dev
212
+ npm run build:mcpb
213
+ # → cutline-mcp.mcpb (drag into Claude Desktop)
158
214
  ```
159
215
 
160
- ### Test Locally
216
+ Config: [`mcpb/manifest.json`](./mcpb/manifest.json)
217
+
218
+ ## Troubleshooting
219
+
220
+ ### Port 8765 in use
161
221
 
162
222
  ```bash
163
- npm link
164
- cutline-mcp --help
223
+ lsof -i :8765
224
+ kill -9 <PID>
165
225
  ```
166
226
 
167
- ## Next Steps
227
+ ### Authentication timeout
228
+
229
+ The browser didn't complete within 10 minutes. Run `cutline-mcp login` again.
168
230
 
169
- - [ ] Add web app `/mcp-auth` endpoint
170
- - [ ] Implement device registration in Firestore
171
- - [ ] Add subscription status to `status` command
172
- - [ ] Publish to npm as `@cutline/mcp-cli`
173
- - [ ] Create standalone binaries for macOS/Windows/Linux
231
+ ### Failed to refresh token
232
+
233
+ ```bash
234
+ cutline-mcp logout
235
+ cutline-mcp login
236
+ ```
237
+
238
+ ### Keychain Access Denied (macOS)
239
+
240
+ 1. Open Keychain Access
241
+ 2. Find "cutline-mcp" entry
242
+ 3. Right-click → Get Info → Access Control
243
+ 4. Add your Terminal/IDE to allowed applications
@@ -1,15 +1,9 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.startCallbackServer = startCallbackServer;
7
- const express_1 = __importDefault(require("express"));
1
+ import express from 'express';
8
2
  const CALLBACK_PORT = 8765;
9
- const TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
10
- async function startCallbackServer() {
3
+ const TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes (allows time for email magic link)
4
+ export async function startCallbackServer() {
11
5
  return new Promise((resolve, reject) => {
12
- const app = (0, express_1.default)();
6
+ const app = express();
13
7
  let server;
14
8
  // Timeout handler
15
9
  const timeout = setTimeout(() => {
@@ -24,7 +18,6 @@ async function startCallbackServer() {
24
18
  res.status(400).send('Missing token parameter');
25
19
  return;
26
20
  }
27
- // Send success page
28
21
  res.send(`
29
22
  <!DOCTYPE html>
30
23
  <html>
@@ -38,36 +31,41 @@ async function startCallbackServer() {
38
31
  align-items: center;
39
32
  height: 100vh;
40
33
  margin: 0;
41
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
34
+ background: #0a0a0a;
35
+ color: #fff;
42
36
  }
43
37
  .container {
44
- background: white;
45
- padding: 3rem;
38
+ background: #111;
39
+ padding: 2.5rem;
46
40
  border-radius: 1rem;
47
- box-shadow: 0 20px 60px rgba(0,0,0,0.3);
41
+ border: 1px solid rgba(0, 255, 65, 0.2);
48
42
  text-align: center;
49
- max-width: 400px;
50
- }
51
- h1 {
52
- color: #667eea;
53
- margin-bottom: 1rem;
54
- }
55
- p {
56
- color: #666;
57
- line-height: 1.6;
58
- }
59
- .checkmark {
60
- font-size: 4rem;
61
- color: #4CAF50;
43
+ max-width: 420px;
62
44
  }
45
+ .checkmark { font-size: 3rem; margin-bottom: 0.5rem; }
46
+ h1 { color: #00ff41; font-size: 1.4rem; margin-bottom: 0.5rem; }
47
+ .email { color: #888; font-size: 0.9rem; margin-bottom: 1.5rem; }
48
+ .steps { text-align: left; margin: 1.5rem 0; padding: 1rem 1.2rem; background: rgba(0,255,65,0.05); border: 1px solid rgba(0,255,65,0.15); border-radius: 0.5rem; }
49
+ .steps h3 { font-size: 0.8rem; color: #888; margin: 0 0 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; }
50
+ .step { display: flex; align-items: flex-start; gap: 0.6rem; margin-bottom: 0.6rem; font-size: 0.85rem; color: #ccc; }
51
+ .step:last-child { margin-bottom: 0; }
52
+ .num { color: #00ff41; font-weight: 600; min-width: 1.2rem; }
53
+ code { background: rgba(255,255,255,0.1); padding: 0.15rem 0.4rem; border-radius: 3px; font-size: 0.8rem; }
54
+ .close { color: #666; font-size: 0.8rem; margin-top: 1rem; }
63
55
  </style>
64
56
  </head>
65
57
  <body>
66
58
  <div class="container">
67
- <div class="checkmark">✓</div>
68
- <h1>Authentication Successful!</h1>
69
- <p>You can now close this window and return to your terminal.</p>
70
- ${email ? `<p>Logged in as: <strong>${email}</strong></p>` : ''}
59
+ <div class="checkmark">&#10003;</div>
60
+ <h1>You're in!</h1>
61
+ ${email ? `<p class="email">${email}</p>` : ''}
62
+ <div class="steps">
63
+ <h3>Next in your terminal</h3>
64
+ <div class="step"><span class="num">1</span><span>Run <code>cutline-mcp init</code> to generate IDE rules</span></div>
65
+ <div class="step"><span class="num">2</span><span>Run <code>cutline-mcp setup</code> to connect MCP servers</span></div>
66
+ <div class="step"><span class="num">3</span><span>Ask your agent: <em>"Run an engineering audit"</em></span></div>
67
+ </div>
68
+ <p class="close">You can close this tab.</p>
71
69
  </div>
72
70
  </body>
73
71
  </html>
@@ -1,20 +1,12 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.storeRefreshToken = storeRefreshToken;
7
- exports.getRefreshToken = getRefreshToken;
8
- exports.deleteRefreshToken = deleteRefreshToken;
9
- const keytar_1 = __importDefault(require("keytar"));
1
+ import keytar from 'keytar';
10
2
  const SERVICE_NAME = 'cutline-mcp';
11
3
  const ACCOUNT_NAME = 'refresh-token';
12
- async function storeRefreshToken(token) {
13
- await keytar_1.default.setPassword(SERVICE_NAME, ACCOUNT_NAME, token);
4
+ export async function storeRefreshToken(token) {
5
+ await keytar.setPassword(SERVICE_NAME, ACCOUNT_NAME, token);
14
6
  }
15
- async function getRefreshToken() {
16
- return await keytar_1.default.getPassword(SERVICE_NAME, ACCOUNT_NAME);
7
+ export async function getRefreshToken() {
8
+ return await keytar.getPassword(SERVICE_NAME, ACCOUNT_NAME);
17
9
  }
18
- async function deleteRefreshToken() {
19
- return await keytar_1.default.deletePassword(SERVICE_NAME, ACCOUNT_NAME);
10
+ export async function deleteRefreshToken() {
11
+ return await keytar.deletePassword(SERVICE_NAME, ACCOUNT_NAME);
20
12
  }
@@ -0,0 +1,4 @@
1
+ export declare function initCommand(options: {
2
+ projectRoot?: string;
3
+ staging?: boolean;
4
+ }): Promise<void>;