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.
- package/package.json +1 -1
- package/src/auth.js +20 -19
- package/src/index.js +124 -16
package/package.json
CHANGED
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
|
-
|
|
108
|
-
|
|
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:
|
|
144
|
+
background: #F5F1EA;
|
|
143
145
|
min-height: 100vh;
|
|
144
146
|
display: flex;
|
|
145
147
|
align-items: center;
|
|
146
148
|
justify-content: center;
|
|
147
|
-
color:
|
|
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:
|
|
156
|
+
font-size: 48px;
|
|
155
157
|
margin-bottom: 24px;
|
|
156
158
|
}
|
|
157
159
|
h1 {
|
|
158
|
-
font-size:
|
|
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:
|
|
165
|
-
color: rgba(
|
|
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:
|
|
170
|
+
margin-top: 24px;
|
|
170
171
|
font-size: 14px;
|
|
171
|
-
color: rgba(
|
|
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"
|
|
178
|
-
<h1>Connected to Circuit
|
|
179
|
-
<p>You can close this window
|
|
180
|
-
<p class="hint">
|
|
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(),
|
|
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')}
|
|
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('
|
|
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.
|
|
122
|
-
console.log(chalk.
|
|
123
|
-
console.log(chalk.white('
|
|
124
|
-
console.log(chalk.dim('
|
|
125
|
-
|
|
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
|
-
|
|
215
|
+
}
|
|
216
|
+
}
|
|
134
217
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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.
|
|
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() {
|