circuit-mcp 1.0.6 → 1.0.8

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 (3) hide show
  1. package/package.json +1 -1
  2. package/src/auth.js +20 -19
  3. package/src/index.js +124 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "circuit-mcp",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Circuit MCP server for Cursor and Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
package/src/auth.js CHANGED
@@ -100,12 +100,14 @@ export async function authenticate() {
100
100
  // Store token
101
101
  await storeToken(token);
102
102
 
103
- // Send success page
103
+ // Send success page and close after response is fully sent
104
104
  res.writeHead(200, { 'Content-Type': 'text/html' });
105
- res.end(getSuccessPage());
106
-
107
- server.close();
108
- resolve(token);
105
+ res.end(getSuccessPage(), () => {
106
+ setTimeout(() => {
107
+ server.close();
108
+ resolve(token);
109
+ }, 100);
110
+ });
109
111
  }
110
112
  });
111
113
 
@@ -139,47 +141,46 @@ function getSuccessPage() {
139
141
  * { margin: 0; padding: 0; box-sizing: border-box; }
140
142
  body {
141
143
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
142
- background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
144
+ background: #F5F1EA;
143
145
  min-height: 100vh;
144
146
  display: flex;
145
147
  align-items: center;
146
148
  justify-content: center;
147
- color: white;
149
+ color: #1C1A18;
148
150
  }
149
151
  .container {
150
152
  text-align: center;
151
153
  padding: 48px;
152
154
  }
153
155
  .icon {
154
- font-size: 64px;
156
+ font-size: 48px;
155
157
  margin-bottom: 24px;
156
158
  }
157
159
  h1 {
158
- font-size: 32px;
160
+ font-size: 24px;
159
161
  font-weight: 600;
160
162
  margin-bottom: 16px;
161
- color: #6366F1;
162
163
  }
163
164
  p {
164
- font-size: 18px;
165
- color: rgba(255,255,255,0.7);
165
+ font-size: 16px;
166
+ color: rgba(28,26,24,0.6);
166
167
  margin-bottom: 8px;
167
168
  }
168
169
  .hint {
169
- margin-top: 32px;
170
+ margin-top: 24px;
170
171
  font-size: 14px;
171
- color: rgba(255,255,255,0.5);
172
+ color: rgba(28,26,24,0.4);
172
173
  }
173
174
  </style>
174
175
  </head>
175
176
  <body>
176
177
  <div class="container">
177
- <div class="icon">⚡</div>
178
- <h1>Connected to Circuit!</h1>
179
- <p>You can close this window and return to your terminal.</p>
180
- <p class="hint">Circuit is now ready to use in Cursor or Claude Code.</p>
178
+ <div class="icon">◉</div>
179
+ <h1>Connected to Circuit</h1>
180
+ <p>You can close this window.</p>
181
+ <p class="hint">Return to your terminal to continue.</p>
181
182
  </div>
182
- <script>setTimeout(() => window.close(), 3000);</script>
183
+ <script>setTimeout(() => window.close(), 2000);</script>
183
184
  </body>
184
185
  </html>`;
185
186
  }
package/src/index.js CHANGED
@@ -1,4 +1,9 @@
1
1
  import chalk from 'chalk';
2
+ import readline from 'readline';
3
+ import fs from 'fs/promises';
4
+ import path from 'path';
5
+ import os from 'os';
6
+ import { execSync } from 'child_process';
2
7
  import { authenticate, getStoredToken } from './auth.js';
3
8
  import { startMcpServer } from './server.js';
4
9
  import { showBanner, showSuccess, showError, showSpinner } from './ui.js';
@@ -47,7 +52,7 @@ function showHelp() {
47
52
 
48
53
  console.log(chalk.white.bold(' Commands:\n'));
49
54
  console.log(` ${chalk.cyan('npx circuit-mcp')} Start MCP server`);
50
- console.log(` ${chalk.cyan('npx circuit-mcp setup')} Show setup instructions`);
55
+ console.log(` ${chalk.cyan('npx circuit-mcp setup')} Configure Cursor or Claude Code`);
51
56
  console.log(` ${chalk.cyan('npx circuit-mcp auth')} Re-authenticate`);
52
57
  console.log(` ${chalk.cyan('npx circuit-mcp logout')} Clear stored token`);
53
58
  console.log(` ${chalk.cyan('npx circuit-mcp fix')} Troubleshooting guide`);
@@ -110,34 +115,137 @@ function showTroubleshoot() {
110
115
  console.log(chalk.dim(' Or visit: https://withcircuit.com/help\n'));
111
116
  }
112
117
 
118
+ // Helper to prompt user for input
119
+ function prompt(question) {
120
+ return new Promise((resolve) => {
121
+ const rl = readline.createInterface({
122
+ input: process.stdin,
123
+ output: process.stdout
124
+ });
125
+ rl.question(question, (answer) => {
126
+ rl.close();
127
+ resolve(answer.trim());
128
+ });
129
+ });
130
+ }
131
+
132
+ // Configure Cursor by writing to ~/.cursor/mcp.json
133
+ async function configureCursor() {
134
+ const configPath = path.join(os.homedir(), '.cursor', 'mcp.json');
135
+ const circuitConfig = {
136
+ command: 'npx',
137
+ args: ['circuit-mcp']
138
+ };
139
+
140
+ try {
141
+ // Ensure .cursor directory exists
142
+ await fs.mkdir(path.dirname(configPath), { recursive: true });
143
+
144
+ let config = { mcpServers: {} };
145
+
146
+ // Try to read existing config
147
+ try {
148
+ const existing = await fs.readFile(configPath, 'utf-8');
149
+ config = JSON.parse(existing);
150
+ if (!config.mcpServers) {
151
+ config.mcpServers = {};
152
+ }
153
+ } catch {
154
+ // File doesn't exist, use default
155
+ }
156
+
157
+ // Add Circuit
158
+ config.mcpServers.circuit = circuitConfig;
159
+
160
+ // Write config
161
+ await fs.writeFile(configPath, JSON.stringify(config, null, 2));
162
+ return true;
163
+ } catch (err) {
164
+ return false;
165
+ }
166
+ }
167
+
168
+ // Configure Claude Code by running the CLI command
169
+ function configureClaudeCode() {
170
+ try {
171
+ execSync('claude mcp add circuit -- npx circuit-mcp', {
172
+ stdio: 'pipe',
173
+ timeout: 10000
174
+ });
175
+ return true;
176
+ } catch (err) {
177
+ // Command might fail if claude CLI not installed
178
+ return false;
179
+ }
180
+ }
181
+
113
182
  async function runSetup() {
114
183
  showBanner();
115
184
 
116
185
  console.log(chalk.white.bold(' Welcome to Circuit!\n'));
117
- console.log(chalk.dim(' Connect your AI coding tool to start building from customer feedback.\n'));
186
+ console.log(chalk.dim(' Let\'s connect Circuit to your AI coding tool.\n'));
118
187
 
119
188
  console.log(chalk.dim(' ─────────────────────────────────────────\n'));
120
189
 
121
- console.log(chalk.cyan.bold(' Cursor\n'));
122
- console.log(chalk.dim(' 1. Open your MCP config file:\n'));
123
- console.log(chalk.white(' open ~/.cursor/mcp.json\n'));
124
- console.log(chalk.dim(' 2. Add this to the file:\n'));
125
- console.log(chalk.white(` {
190
+ console.log(chalk.white(' Which tool are you using?\n'));
191
+ console.log(chalk.white(' 1. Cursor'));
192
+ console.log(chalk.white(' 2. Claude Code'));
193
+ console.log(chalk.dim(' 3. Both\n'));
194
+
195
+ const choice = await prompt(chalk.cyan(' Enter 1, 2, or 3: '));
196
+
197
+ console.log();
198
+
199
+ if (choice === '1' || choice === '3') {
200
+ console.log(chalk.dim(' Setting up Cursor...\n'));
201
+
202
+ const success = await configureCursor();
203
+
204
+ if (success) {
205
+ showSuccess('Added Circuit to ~/.cursor/mcp.json');
206
+ console.log(chalk.dim(' Restart Cursor to activate.\n'));
207
+ } else {
208
+ showError('Could not update Cursor config automatically.');
209
+ console.log(chalk.dim(' Add this to ~/.cursor/mcp.json manually:\n'));
210
+ console.log(chalk.white(` {
126
211
  "mcpServers": {
127
- "circuit": {
128
- "command": "npx",
129
- "args": ["circuit-mcp"]
130
- }
212
+ "circuit": { "command": "npx", "args": ["circuit-mcp"] }
131
213
  }
132
214
  }\n`));
133
- console.log(chalk.dim(' 3. Restart Cursor\n'));
215
+ }
216
+ }
134
217
 
135
- console.log(chalk.cyan.bold(' Claude Code\n'));
136
- console.log(chalk.dim(' Run this in your terminal:\n'));
137
- console.log(chalk.white(' claude mcp add circuit -- npx circuit-mcp\n'));
218
+ if (choice === '2' || choice === '3') {
219
+ console.log(chalk.dim(' Setting up Claude Code...\n'));
220
+
221
+ const success = configureClaudeCode();
222
+
223
+ if (success) {
224
+ showSuccess('Added Circuit to Claude Code');
225
+ console.log(chalk.dim(' Restart Claude Code to activate.\n'));
226
+ } else {
227
+ showError('Could not run claude CLI automatically.');
228
+ console.log(chalk.dim(' Run this command manually:\n'));
229
+ console.log(chalk.white(' claude mcp add circuit -- npx circuit-mcp\n'));
230
+ }
231
+ }
232
+
233
+ if (!['1', '2', '3'].includes(choice)) {
234
+ console.log(chalk.dim(' No worries! Here are the manual steps:\n'));
235
+ console.log(chalk.cyan.bold(' Cursor'));
236
+ console.log(chalk.dim(' Add to ~/.cursor/mcp.json:'));
237
+ console.log(chalk.white(' { "mcpServers": { "circuit": { "command": "npx", "args": ["circuit-mcp"] } } }\n'));
238
+ console.log(chalk.cyan.bold(' Claude Code'));
239
+ console.log(chalk.dim(' Run:'));
240
+ console.log(chalk.white(' claude mcp add circuit -- npx circuit-mcp\n'));
241
+ return;
242
+ }
138
243
 
139
244
  console.log(chalk.dim(' ─────────────────────────────────────────\n'));
140
- console.log(chalk.dim(' Circuit will prompt you to sign in on first use.\n'));
245
+ console.log(chalk.white.bold(' Almost done!\n'));
246
+ console.log(chalk.dim(' When you restart your editor, Circuit will'));
247
+ console.log(chalk.dim(' prompt you to sign in on first use.\n'));
248
+ console.log(chalk.dim(' That\'s it. You\'re all set.\n'));
141
249
  }
142
250
 
143
251
  async function runAuth() {