circuit-mcp 1.0.14 → 1.0.16

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/README.md +47 -32
  2. package/package.json +20 -5
  3. package/src/server.js +92 -3
package/README.md CHANGED
@@ -2,11 +2,13 @@
2
2
 
3
3
  Connect [Circuit](https://withcircuit.com) to Cursor and Claude Code via MCP (Model Context Protocol).
4
4
 
5
+ **Circuit** transforms customer feedback into engineering specs. The MCP brings your priorities and briefs directly into your AI coding assistant.
6
+
5
7
  ## Quick Start
6
8
 
7
9
  ### Cursor
8
10
 
9
- Add to your Cursor settings (`Cmd+Shift+P` → "Cursor Settings: Open User Settings"):
11
+ Add to `~/.cursor/mcp.json`:
10
12
 
11
13
  ```json
12
14
  {
@@ -21,62 +23,75 @@ Add to your Cursor settings (`Cmd+Shift+P` → "Cursor Settings: Open User Setti
21
23
 
22
24
  ### Claude Code
23
25
 
24
- Run this command:
25
-
26
26
  ```bash
27
27
  claude mcp add circuit -- npx circuit-mcp
28
28
  ```
29
29
 
30
30
  ## First Run
31
31
 
32
- On first use, Circuit will open your browser to authenticate. After signing in, your token is cached locally at `~/.circuit/token.json`.
32
+ On first use, Circuit opens your browser to authenticate. Your token is cached at `~/.circuit/token.json`.
33
33
 
34
34
  ```
35
- ╭──────────────────────────────────╮
36
- │ ⚡ Circuit MCP │
37
- ╰──────────────────────────────────╯
35
+ Circuit MCP
38
36
 
39
37
  First time setup - let's connect your account.
40
-
41
38
  Opening browser to authenticate...
42
39
 
43
- Connected!
40
+ Connected!
44
41
  ```
45
42
 
46
- ## Commands
43
+ ## Available Tools
47
44
 
48
- ```bash
49
- # Start MCP server (used by Cursor/Claude)
50
- npx circuit-mcp
45
+ | Tool | Description |
46
+ |------|-------------|
47
+ | `get_priorities` | Get top customer priorities ranked by volume, urgency, or sentiment |
48
+ | `get_brief` | Get the engineering spec for a priority (what to build, why, done criteria) |
49
+ | `search_feedback` | Search raw customer feedback by keyword |
50
+ | `start_building` | Mark a brief as "building" - you're working on it |
51
+ | `mark_done` | Mark a brief as "done" - it shipped! |
51
52
 
52
- # Show setup instructions
53
- npx circuit-mcp setup
53
+ ## Example Usage
54
54
 
55
- # Re-authenticate
56
- npx circuit-mcp auth
55
+ Ask your AI assistant:
57
56
 
58
- # Log out (clear stored token)
59
- npx circuit-mcp logout
60
- ```
57
+ > "What are my top 5 priorities?"
61
58
 
62
- ## Available Tools
59
+ > "Get the brief for priority #1"
63
60
 
64
- Once connected, your AI coding assistant can use these tools:
61
+ > "Search feedback about login issues"
65
62
 
66
- | Tool | Description |
67
- |------|-------------|
68
- | `get_priorities` | Get top customer feedback priorities |
69
- | `get_brief` | Get the engineering brief for a priority |
70
- | `get_feedback` | Get raw customer feedback items |
63
+ > "Mark that brief as done"
71
64
 
72
- ### Example Usage in Cursor/Claude
65
+ ## Commands
73
66
 
74
- > "What are the top 5 customer priorities?"
67
+ ```bash
68
+ npx circuit-mcp # Start MCP server (used by Cursor/Claude)
69
+ npx circuit-mcp setup # Show setup instructions
70
+ npx circuit-mcp auth # Re-authenticate
71
+ npx circuit-mcp logout # Clear stored token
72
+ ```
73
+
74
+ ## How It Works
75
+
76
+ ```
77
+ Circuit (app.withcircuit.com)
78
+
79
+ │ Feedback → Priorities → Briefs
80
+
81
+
82
+ Circuit MCP ◄─── Cursor / Claude Code
83
+
84
+ │ get_priorities, get_brief, etc.
85
+
86
+
87
+ Your AI assistant has context
88
+ ```
75
89
 
76
- > "Get the brief for priority #1 and help me implement it"
90
+ ## Links
77
91
 
78
- > "Show me recent feedback about authentication issues"
92
+ - [Circuit](https://withcircuit.com) - Customer feedback intelligence
93
+ - [MCP Protocol](https://modelcontextprotocol.io) - Model Context Protocol spec
79
94
 
80
95
  ## License
81
96
 
82
- MIT
97
+ Proprietary - © Circuit (withcircuit.com)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "circuit-mcp",
3
- "version": "1.0.14",
4
- "description": "Circuit MCP server for Cursor and Claude Code",
3
+ "version": "1.0.16",
4
+ "description": "Connect Circuit to Cursor and Claude Code - bring customer priorities and engineering briefs into your AI coding assistant",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "circuit-mcp": "./bin/circuit-mcp.js"
@@ -13,13 +13,28 @@
13
13
  "keywords": [
14
14
  "circuit",
15
15
  "mcp",
16
+ "model-context-protocol",
16
17
  "cursor",
17
18
  "claude",
19
+ "claude-code",
18
20
  "ai",
19
- "feedback"
21
+ "feedback",
22
+ "priorities",
23
+ "engineering",
24
+ "specs",
25
+ "customer-feedback"
20
26
  ],
21
- "author": "Circuit",
22
- "license": "MIT",
27
+ "author": "Circuit <hello@withcircuit.com>",
28
+ "license": "UNLICENSED",
29
+ "homepage": "https://withcircuit.com",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/CatherineWilliamsTreloar/Circuit.git",
33
+ "directory": "circuit-mcp"
34
+ },
35
+ "bugs": {
36
+ "url": "https://github.com/CatherineWilliamsTreloar/Circuit/issues"
37
+ },
23
38
  "dependencies": {
24
39
  "chalk": "^5.3.0",
25
40
  "open": "^10.1.0"
package/src/server.js CHANGED
@@ -173,6 +173,19 @@ async function handleMessage(message, token) {
173
173
  },
174
174
  required: ['query']
175
175
  }
176
+ },
177
+ {
178
+ name: 'get_insights',
179
+ description: 'Get high-level insights and patterns across your priorities. Identifies themes, trends, and strategic recommendations.',
180
+ inputSchema: {
181
+ type: 'object',
182
+ properties: {
183
+ limit: {
184
+ type: 'number',
185
+ description: 'Number of priorities to analyze (default: 10)'
186
+ }
187
+ }
188
+ }
176
189
  }
177
190
  ]
178
191
  }
@@ -230,11 +243,15 @@ function formatPriorities(data) {
230
243
  // Format: #Rank. Title
231
244
  lines.push(`**#${p.rank}. ${p.theme}**`);
232
245
 
233
- // Badges row: Category | X users | Trend
246
+ // Badges row: Category | X users | Trend | Status
234
247
  const badges = [];
235
248
  badges.push(p.category || 'Other');
236
249
  badges.push(`${p.volume} users`);
237
250
  if (trendText) badges.push(trendText.trim());
251
+ if (p.brief_status && p.brief_status !== 'no_brief') {
252
+ const statusLabel = { ready: 'Ready', building: 'Building', done: 'Done' }[p.brief_status];
253
+ if (statusLabel) badges.push(statusLabel);
254
+ }
238
255
 
239
256
  lines.push(badges.join(' · '));
240
257
 
@@ -272,8 +289,14 @@ function formatBrief(data) {
272
289
  output += `> "${p.key_quote}"\n\n`;
273
290
  }
274
291
 
275
- output += `---\n`;
276
- output += data.suggestion;
292
+ output += `---\n\n`;
293
+
294
+ // Include deep link to Circuit
295
+ if (data.circuit_url) {
296
+ output += `**Generate brief:** ${data.circuit_url}\n\n`;
297
+ }
298
+
299
+ output += `Or I can help you draft implementation notes based on the customer feedback above.`;
277
300
  return output;
278
301
  }
279
302
  return `Error: ${data.message || data.error}`;
@@ -358,6 +381,69 @@ function formatStatusChange(data) {
358
381
  return JSON.stringify(data, null, 2);
359
382
  }
360
383
 
384
+ /**
385
+ * Format insights for display
386
+ */
387
+ function formatInsights(data) {
388
+ if (data.message) {
389
+ return data.message;
390
+ }
391
+
392
+ const lines = [];
393
+
394
+ lines.push(`## Insights from ${data.analyzed} priorities\n`);
395
+ lines.push(`**Total feedback volume:** ${data.total_feedback_volume} mentions\n`);
396
+
397
+ // Category breakdown
398
+ if (data.category_breakdown) {
399
+ lines.push('**Category breakdown:**');
400
+ for (const [cat, count] of Object.entries(data.category_breakdown)) {
401
+ lines.push(`- ${cat}: ${count}`);
402
+ }
403
+ lines.push('');
404
+ }
405
+
406
+ // Top 3 by volume
407
+ if (data.top_3_by_volume && data.top_3_by_volume.length > 0) {
408
+ lines.push('**Top priorities by volume:**');
409
+ for (const p of data.top_3_by_volume) {
410
+ lines.push(`- ${p.theme} (${p.volume} users, ${p.category})`);
411
+ }
412
+ lines.push('');
413
+ }
414
+
415
+ // Trends
416
+ if (data.trending_up && data.trending_up.length > 0) {
417
+ lines.push(`**Trending up:** ${data.trending_up.join(', ')}`);
418
+ }
419
+ if (data.trending_down && data.trending_down.length > 0) {
420
+ lines.push(`**Trending down:** ${data.trending_down.join(', ')}`);
421
+ }
422
+
423
+ // High urgency
424
+ if (data.high_urgency && data.high_urgency.length > 0) {
425
+ lines.push('\n**High urgency items:**');
426
+ for (const h of data.high_urgency) {
427
+ lines.push(`- ${h.theme} (urgency: ${h.urgency})`);
428
+ }
429
+ }
430
+
431
+ // Recommendations
432
+ if (data.recommendations && data.recommendations.length > 0) {
433
+ lines.push('\n**Recommendations:**');
434
+ for (const r of data.recommendations) {
435
+ lines.push(`- ${r}`);
436
+ }
437
+ }
438
+
439
+ lines.push('\n---');
440
+ if (data.circuit_url) {
441
+ lines.push(`View full details: ${data.circuit_url}`);
442
+ }
443
+
444
+ return lines.join('\n');
445
+ }
446
+
361
447
  /**
362
448
  * Handle tool calls
363
449
  */
@@ -385,6 +471,9 @@ async function handleToolCall(id, params, token) {
385
471
  case 'mark_done':
386
472
  formattedText = formatStatusChange(result);
387
473
  break;
474
+ case 'get_insights':
475
+ formattedText = formatInsights(result);
476
+ break;
388
477
  default:
389
478
  formattedText = JSON.stringify(result, null, 2);
390
479
  }