circuit-mcp 1.0.16 → 2.0.0
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/publish.sh +30 -0
- package/src/server.js +148 -170
package/package.json
CHANGED
package/publish.sh
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Publish script for circuit-mcp package
|
|
4
|
+
# Uses token to bypass 2FA
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# NPM_TOKEN=your_token ./publish.sh
|
|
8
|
+
#
|
|
9
|
+
# Or set NPM_TOKEN in your environment
|
|
10
|
+
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
# Use NPM_TOKEN from environment, or prompt if not set
|
|
14
|
+
if [ -z "$NPM_TOKEN" ]; then
|
|
15
|
+
echo "Error: NPM_TOKEN environment variable is required"
|
|
16
|
+
echo "Usage: NPM_TOKEN=your_token ./publish.sh"
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Create temporary .npmrc with token
|
|
21
|
+
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc
|
|
22
|
+
|
|
23
|
+
# Publish the package
|
|
24
|
+
npm publish --access public
|
|
25
|
+
|
|
26
|
+
# Clean up .npmrc
|
|
27
|
+
rm .npmrc
|
|
28
|
+
|
|
29
|
+
echo "✅ Published successfully!"
|
|
30
|
+
|
package/src/server.js
CHANGED
|
@@ -74,7 +74,7 @@ async function handleMessage(message, token) {
|
|
|
74
74
|
protocolVersion: '2024-11-05',
|
|
75
75
|
serverInfo: {
|
|
76
76
|
name: 'circuit-mcp',
|
|
77
|
-
version: '
|
|
77
|
+
version: '2.0.0'
|
|
78
78
|
},
|
|
79
79
|
capabilities: {
|
|
80
80
|
tools: {},
|
|
@@ -84,7 +84,6 @@ async function handleMessage(message, token) {
|
|
|
84
84
|
};
|
|
85
85
|
|
|
86
86
|
case 'initialized':
|
|
87
|
-
// No response needed for notification
|
|
88
87
|
return null;
|
|
89
88
|
|
|
90
89
|
case 'tools/list':
|
|
@@ -94,97 +93,114 @@ async function handleMessage(message, token) {
|
|
|
94
93
|
result: {
|
|
95
94
|
tools: [
|
|
96
95
|
{
|
|
97
|
-
name: '
|
|
98
|
-
description: '
|
|
96
|
+
name: 'circuit.priorities',
|
|
97
|
+
description: 'What should I work on? Get ranked priorities with confidence indicators, trends, and memory context.',
|
|
99
98
|
inputSchema: {
|
|
100
99
|
type: 'object',
|
|
101
100
|
properties: {
|
|
101
|
+
lens: {
|
|
102
|
+
type: 'string',
|
|
103
|
+
description: "Focus lens: 'volume', 'urgency', 'revenue', 'retention', 'delight', 'feature'",
|
|
104
|
+
enum: ['volume', 'urgency', 'revenue', 'retention', 'delight', 'feature'],
|
|
105
|
+
default: 'volume'
|
|
106
|
+
},
|
|
107
|
+
segment: {
|
|
108
|
+
type: 'string',
|
|
109
|
+
description: "Filter by customer segment: 'enterprise', 'smb', 'all'",
|
|
110
|
+
default: 'all'
|
|
111
|
+
},
|
|
102
112
|
limit: {
|
|
103
113
|
type: 'number',
|
|
104
|
-
description: 'Number of priorities
|
|
114
|
+
description: 'Number of priorities (default: 5, max: 20)',
|
|
115
|
+
default: 5
|
|
105
116
|
},
|
|
106
|
-
|
|
117
|
+
category: {
|
|
107
118
|
type: 'string',
|
|
108
|
-
description:
|
|
109
|
-
enum: ['
|
|
119
|
+
description: "Filter by category: 'Bug', 'Feature', 'Friction', 'Complaint', 'Praise'",
|
|
120
|
+
enum: ['Bug', 'Feature', 'Friction', 'Complaint', 'Praise']
|
|
110
121
|
}
|
|
111
122
|
}
|
|
112
123
|
}
|
|
113
124
|
},
|
|
114
125
|
{
|
|
115
|
-
name: '
|
|
116
|
-
description: 'Get the full engineering
|
|
126
|
+
name: 'circuit.brief',
|
|
127
|
+
description: 'Get the full engineering spec for a priority. Includes brief content, customer context, version history, and related memory (previous ships, outcomes).',
|
|
117
128
|
inputSchema: {
|
|
118
129
|
type: 'object',
|
|
119
130
|
properties: {
|
|
120
131
|
priority_id: {
|
|
121
132
|
type: 'string',
|
|
122
|
-
description: 'The priority ID
|
|
133
|
+
description: 'The priority ID'
|
|
123
134
|
},
|
|
124
135
|
build_id: {
|
|
125
136
|
type: 'string',
|
|
126
137
|
description: 'The build ID directly (alternative to priority_id)'
|
|
138
|
+
},
|
|
139
|
+
include_history: {
|
|
140
|
+
type: 'boolean',
|
|
141
|
+
description: 'Include version history and related memory',
|
|
142
|
+
default: true
|
|
127
143
|
}
|
|
128
144
|
}
|
|
129
145
|
}
|
|
130
146
|
},
|
|
131
147
|
{
|
|
132
|
-
name: '
|
|
133
|
-
description:
|
|
148
|
+
name: 'circuit.act',
|
|
149
|
+
description: 'Take an action in Circuit. Ship a brief, start building, correct a classification, or submit new feedback.',
|
|
134
150
|
inputSchema: {
|
|
135
151
|
type: 'object',
|
|
136
152
|
properties: {
|
|
137
|
-
|
|
153
|
+
action: {
|
|
138
154
|
type: 'string',
|
|
139
|
-
description: '
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
name: 'mark_done',
|
|
147
|
-
description: "Mark a brief as 'done' - the feature has shipped! This closes the feedback loop.",
|
|
148
|
-
inputSchema: {
|
|
149
|
-
type: 'object',
|
|
150
|
-
properties: {
|
|
151
|
-
build_id: {
|
|
155
|
+
description: "Action to take: 'build' (start building), 'ship' (mark shipped), 'correct' (fix classification), 'submit' (add feedback)",
|
|
156
|
+
enum: ['build', 'ship', 'correct', 'submit']
|
|
157
|
+
},
|
|
158
|
+
brief_id: {
|
|
152
159
|
type: 'string',
|
|
153
|
-
description:
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
required: ['build_id']
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
name: 'search_feedback',
|
|
161
|
-
description: 'Search customer feedback by keyword. Useful for understanding pain points around specific features.',
|
|
162
|
-
inputSchema: {
|
|
163
|
-
type: 'object',
|
|
164
|
-
properties: {
|
|
165
|
-
query: {
|
|
160
|
+
description: "Brief ID (for 'build' and 'ship' actions)"
|
|
161
|
+
},
|
|
162
|
+
priority_id: {
|
|
166
163
|
type: 'string',
|
|
167
|
-
description:
|
|
164
|
+
description: "Priority ID (for 'correct' action)"
|
|
168
165
|
},
|
|
169
|
-
|
|
170
|
-
type: '
|
|
171
|
-
description:
|
|
166
|
+
correction_type: {
|
|
167
|
+
type: 'string',
|
|
168
|
+
description: "What to correct (for 'correct' action): 'category'",
|
|
169
|
+
enum: ['category']
|
|
170
|
+
},
|
|
171
|
+
original: {
|
|
172
|
+
type: 'string',
|
|
173
|
+
description: 'Original value being corrected'
|
|
174
|
+
},
|
|
175
|
+
corrected: {
|
|
176
|
+
type: 'string',
|
|
177
|
+
description: 'New corrected value'
|
|
178
|
+
},
|
|
179
|
+
feedback: {
|
|
180
|
+
type: 'string',
|
|
181
|
+
description: "Feedback text (for 'submit' action)"
|
|
182
|
+
},
|
|
183
|
+
source: {
|
|
184
|
+
type: 'string',
|
|
185
|
+
description: "Feedback source (for 'submit' action)",
|
|
186
|
+
default: 'mcp'
|
|
172
187
|
}
|
|
173
188
|
},
|
|
174
|
-
required: ['
|
|
189
|
+
required: ['action']
|
|
175
190
|
}
|
|
176
191
|
},
|
|
177
192
|
{
|
|
178
|
-
name: '
|
|
179
|
-
description: '
|
|
193
|
+
name: 'circuit.ask',
|
|
194
|
+
description: 'Ask anything about your feedback data. Searches across feedback, priorities, briefs, and help articles using semantic search.',
|
|
180
195
|
inputSchema: {
|
|
181
196
|
type: 'object',
|
|
182
197
|
properties: {
|
|
183
|
-
|
|
184
|
-
type: '
|
|
185
|
-
description: '
|
|
198
|
+
question: {
|
|
199
|
+
type: 'string',
|
|
200
|
+
description: "Natural language question (e.g., 'What are enterprise customers complaining about?', 'How do briefs work?')"
|
|
186
201
|
}
|
|
187
|
-
}
|
|
202
|
+
},
|
|
203
|
+
required: ['question']
|
|
188
204
|
}
|
|
189
205
|
}
|
|
190
206
|
]
|
|
@@ -218,7 +234,7 @@ async function handleMessage(message, token) {
|
|
|
218
234
|
}
|
|
219
235
|
|
|
220
236
|
/**
|
|
221
|
-
* Format priorities
|
|
237
|
+
* Format priorities response
|
|
222
238
|
*/
|
|
223
239
|
function formatPriorities(data) {
|
|
224
240
|
if (data.message) {
|
|
@@ -231,47 +247,49 @@ function formatPriorities(data) {
|
|
|
231
247
|
|
|
232
248
|
const lines = [];
|
|
233
249
|
|
|
250
|
+
if (data.memory_applied) {
|
|
251
|
+
lines.push(`*Memory active: ${data.ships_count} ships tracked, segment: ${data.segment_affinity || 'mixed'}*\n`);
|
|
252
|
+
}
|
|
253
|
+
|
|
234
254
|
for (const p of data.priorities) {
|
|
235
|
-
// Format trend indicator like Circuit UI
|
|
236
255
|
let trendText = '';
|
|
237
256
|
if (p.trend === 'up') {
|
|
238
|
-
trendText =
|
|
257
|
+
trendText = ` ↑${p.trend_percent ? ` ${p.trend_percent}%` : ''}`;
|
|
239
258
|
} else if (p.trend === 'down') {
|
|
240
|
-
trendText =
|
|
259
|
+
trendText = ` ↓${p.trend_percent ? ` ${p.trend_percent}%` : ''}`;
|
|
241
260
|
}
|
|
242
261
|
|
|
243
|
-
// Format: #Rank. Title
|
|
244
262
|
lines.push(`**#${p.rank}. ${p.theme}**`);
|
|
245
263
|
|
|
246
|
-
// Badges row: Category | X users | Trend | Status
|
|
247
264
|
const badges = [];
|
|
248
265
|
badges.push(p.category || 'Other');
|
|
249
266
|
badges.push(`${p.volume} users`);
|
|
250
267
|
if (trendText) badges.push(trendText.trim());
|
|
251
268
|
if (p.brief_status && p.brief_status !== 'no_brief') {
|
|
252
|
-
const statusLabel = { ready: 'Ready', building: 'Building',
|
|
269
|
+
const statusLabel = { ready: 'Ready', building: 'Building', shipped: 'Shipped' }[p.brief_status];
|
|
253
270
|
if (statusLabel) badges.push(statusLabel);
|
|
254
271
|
}
|
|
272
|
+
if (p.matches_pattern) badges.push('matches pattern');
|
|
273
|
+
if (p.version) badges.push(p.version);
|
|
255
274
|
|
|
256
275
|
lines.push(badges.join(' · '));
|
|
257
276
|
|
|
258
|
-
// Key quote (customer voice)
|
|
259
277
|
if (p.key_quote) {
|
|
260
278
|
lines.push(`> "${p.key_quote}"`);
|
|
261
279
|
}
|
|
262
280
|
|
|
263
|
-
lines.push(`priority_id: \`${p.
|
|
281
|
+
lines.push(`priority_id: \`${p.priority_id}\`${p.build_id ? ` · build_id: \`${p.build_id}\`` : ''}`);
|
|
264
282
|
lines.push('');
|
|
265
283
|
}
|
|
266
284
|
|
|
267
285
|
lines.push('---');
|
|
268
|
-
lines.push('Use `
|
|
286
|
+
lines.push('Use `circuit.brief` with a priority_id to see the full engineering spec.');
|
|
269
287
|
|
|
270
288
|
return lines.join('\n');
|
|
271
289
|
}
|
|
272
290
|
|
|
273
291
|
/**
|
|
274
|
-
* Format brief
|
|
292
|
+
* Format brief response
|
|
275
293
|
*/
|
|
276
294
|
function formatBrief(data) {
|
|
277
295
|
if (data.error) {
|
|
@@ -279,50 +297,31 @@ function formatBrief(data) {
|
|
|
279
297
|
const p = data.priority;
|
|
280
298
|
let output = `# ${p.theme || 'Priority'}\n\n`;
|
|
281
299
|
output += `${p.category || 'Other'} · ${p.volume || 0} users\n\n`;
|
|
282
|
-
output += `**No brief generated yet
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
output += `${p.summary}\n\n`;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
if (p.key_quote) {
|
|
289
|
-
output += `> "${p.key_quote}"\n\n`;
|
|
300
|
+
output += `**No brief generated yet.**\n\n`;
|
|
301
|
+
if (data.suggestion) {
|
|
302
|
+
output += `${data.suggestion}\n`;
|
|
290
303
|
}
|
|
291
|
-
|
|
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.`;
|
|
300
304
|
return output;
|
|
301
305
|
}
|
|
302
306
|
return `Error: ${data.message || data.error}`;
|
|
303
307
|
}
|
|
304
308
|
|
|
305
309
|
const spec = data.spec_content || '';
|
|
306
|
-
|
|
307
|
-
// Build header like Circuit UI exports
|
|
308
|
-
// Format: # Title
|
|
309
|
-
// Priority: #X | Mentions: Y | Type: Z
|
|
310
|
-
// ---
|
|
311
|
-
// {spec content}
|
|
312
|
-
|
|
313
310
|
let output = '';
|
|
314
311
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
'ready': 'Ready',
|
|
318
|
-
'building': 'Building',
|
|
319
|
-
'done': 'Done'
|
|
320
|
-
}[data.status] || data.status;
|
|
312
|
+
const title = data.title || 'Engineering Brief';
|
|
313
|
+
output += `# ${title}\n\n`;
|
|
321
314
|
|
|
322
|
-
|
|
315
|
+
const statusText = { ready: 'Ready', building: 'Building', shipped: 'Shipped' }[data.status] || data.status;
|
|
316
|
+
const versionBadge = data.version_badge ? ` · ${data.version_badge}` : '';
|
|
317
|
+
output += `Status: ${statusText}${versionBadge}\n`;
|
|
318
|
+
|
|
319
|
+
if (data.customer_context) {
|
|
320
|
+
const ctx = data.customer_context;
|
|
321
|
+
output += `${ctx.category} · ${ctx.volume} users · ${ctx.paying_percent}% paying\n`;
|
|
322
|
+
}
|
|
323
|
+
output += '\n';
|
|
323
324
|
|
|
324
|
-
// The spec_content should already be formatted markdown
|
|
325
|
-
// Clean up any XML-style tags to proper headers
|
|
326
325
|
let cleanSpec = spec
|
|
327
326
|
.replace(/<what_to_build>/gi, '## WHAT TO BUILD\n')
|
|
328
327
|
.replace(/<\/what_to_build>/gi, '\n')
|
|
@@ -337,6 +336,19 @@ function formatBrief(data) {
|
|
|
337
336
|
|
|
338
337
|
output += cleanSpec;
|
|
339
338
|
|
|
339
|
+
if (data.related_memory && data.related_memory.length > 0) {
|
|
340
|
+
output += '\n## WHAT CIRCUIT REMEMBERS\n\n';
|
|
341
|
+
for (const mem of data.related_memory) {
|
|
342
|
+
if (mem.type === 'ship') {
|
|
343
|
+
output += `- Shipped: ${mem.theme || mem.summary || 'Related feature'}\n`;
|
|
344
|
+
} else if (mem.type === 'correction') {
|
|
345
|
+
output += `- Correction: ${mem.summary || 'Classification adjusted'}\n`;
|
|
346
|
+
} else {
|
|
347
|
+
output += `- ${mem.summary || JSON.stringify(mem)}\n`;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
340
352
|
output += `\n---\n`;
|
|
341
353
|
output += `build_id: \`${data.build_id}\``;
|
|
342
354
|
|
|
@@ -344,103 +356,76 @@ function formatBrief(data) {
|
|
|
344
356
|
}
|
|
345
357
|
|
|
346
358
|
/**
|
|
347
|
-
* Format
|
|
348
|
-
*/
|
|
349
|
-
function formatSearchResults(data) {
|
|
350
|
-
if (data.message) {
|
|
351
|
-
return data.message;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
if (!data.results || data.results.length === 0) {
|
|
355
|
-
return 'No feedback found matching your search.';
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
const lines = [`**${data.total} results found**\n`];
|
|
359
|
-
|
|
360
|
-
for (const f of data.results) {
|
|
361
|
-
lines.push(`**${f.source}** · Urgency: ${f.urgency}/5`);
|
|
362
|
-
lines.push(`> "${f.text}"`);
|
|
363
|
-
lines.push('');
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
return lines.join('\n');
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Format status change response
|
|
359
|
+
* Format act response
|
|
371
360
|
*/
|
|
372
|
-
function
|
|
361
|
+
function formatAct(data) {
|
|
373
362
|
if (data.error) {
|
|
374
363
|
return `Error: ${data.error}`;
|
|
375
364
|
}
|
|
376
365
|
|
|
377
366
|
if (data.success) {
|
|
378
|
-
|
|
367
|
+
let output = data.message;
|
|
368
|
+
if (data.memory_created) {
|
|
369
|
+
output += '\nShip memory recorded — Circuit will remember this for future briefs.';
|
|
370
|
+
}
|
|
371
|
+
return output;
|
|
379
372
|
}
|
|
380
373
|
|
|
381
374
|
return JSON.stringify(data, null, 2);
|
|
382
375
|
}
|
|
383
376
|
|
|
384
377
|
/**
|
|
385
|
-
* Format
|
|
378
|
+
* Format ask response
|
|
386
379
|
*/
|
|
387
|
-
function
|
|
380
|
+
function formatAsk(data) {
|
|
388
381
|
if (data.message) {
|
|
389
382
|
return data.message;
|
|
390
383
|
}
|
|
391
384
|
|
|
392
385
|
const lines = [];
|
|
393
386
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
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}`);
|
|
387
|
+
if (data.help_articles && data.help_articles.length > 0) {
|
|
388
|
+
lines.push('**Help Articles:**');
|
|
389
|
+
for (const a of data.help_articles) {
|
|
390
|
+
lines.push(`- **${a.title}**: ${a.content}`);
|
|
402
391
|
}
|
|
403
392
|
lines.push('');
|
|
404
393
|
}
|
|
405
394
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
lines.push(`- ${p.theme} (${p.volume} users, ${p.category})`);
|
|
395
|
+
if (data.priorities && data.priorities.length > 0) {
|
|
396
|
+
lines.push('**Related Priorities:**');
|
|
397
|
+
for (const p of data.priorities) {
|
|
398
|
+
lines.push(`- ${p.theme} (${p.category}, ${p.volume} users) — priority_id: \`${p.id}\``);
|
|
411
399
|
}
|
|
412
400
|
lines.push('');
|
|
413
401
|
}
|
|
414
402
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
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})`);
|
|
403
|
+
if (data.feedback && data.feedback.length > 0) {
|
|
404
|
+
lines.push('**Related Feedback:**');
|
|
405
|
+
for (const f of data.feedback) {
|
|
406
|
+
lines.push(`- [${f.source}] "${f.text}"`);
|
|
428
407
|
}
|
|
408
|
+
lines.push('');
|
|
429
409
|
}
|
|
430
410
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
lines.push('
|
|
434
|
-
|
|
435
|
-
|
|
411
|
+
if (data.your_patterns) {
|
|
412
|
+
const pat = data.your_patterns;
|
|
413
|
+
lines.push('**Your Patterns:**');
|
|
414
|
+
lines.push(`- Ships: ${pat.ships_count}`);
|
|
415
|
+
lines.push(`- Segment: ${pat.segment_affinity}`);
|
|
416
|
+
if (pat.top_categories) {
|
|
417
|
+
const cats = Object.entries(pat.top_categories).map(([k, v]) => `${k} (${Math.round(v * 100)}%)`).join(', ');
|
|
418
|
+
lines.push(`- Top categories: ${cats}`);
|
|
436
419
|
}
|
|
420
|
+
lines.push('');
|
|
437
421
|
}
|
|
438
422
|
|
|
439
|
-
lines.
|
|
440
|
-
|
|
441
|
-
lines.push(`View full details: ${data.circuit_url}`);
|
|
423
|
+
if (lines.length === 0) {
|
|
424
|
+
return `No results found for "${data.question}". Try rephrasing.`;
|
|
442
425
|
}
|
|
443
426
|
|
|
427
|
+
lines.push(`---\n${data.total} results found`);
|
|
428
|
+
|
|
444
429
|
return lines.join('\n');
|
|
445
430
|
}
|
|
446
431
|
|
|
@@ -451,28 +436,22 @@ async function handleToolCall(id, params, token) {
|
|
|
451
436
|
const { name, arguments: args } = params;
|
|
452
437
|
|
|
453
438
|
try {
|
|
454
|
-
// Call the Circuit MCP backend
|
|
455
439
|
const result = await callMcpApi(token, name, args || {});
|
|
456
440
|
|
|
457
|
-
// Format response based on tool type
|
|
458
441
|
let formattedText;
|
|
459
442
|
|
|
460
443
|
switch (name) {
|
|
461
|
-
case '
|
|
444
|
+
case 'circuit.priorities':
|
|
462
445
|
formattedText = formatPriorities(result);
|
|
463
446
|
break;
|
|
464
|
-
case '
|
|
447
|
+
case 'circuit.brief':
|
|
465
448
|
formattedText = formatBrief(result);
|
|
466
449
|
break;
|
|
467
|
-
case '
|
|
468
|
-
formattedText =
|
|
450
|
+
case 'circuit.act':
|
|
451
|
+
formattedText = formatAct(result);
|
|
469
452
|
break;
|
|
470
|
-
case '
|
|
471
|
-
|
|
472
|
-
formattedText = formatStatusChange(result);
|
|
473
|
-
break;
|
|
474
|
-
case 'get_insights':
|
|
475
|
-
formattedText = formatInsights(result);
|
|
453
|
+
case 'circuit.ask':
|
|
454
|
+
formattedText = formatAsk(result);
|
|
476
455
|
break;
|
|
477
456
|
default:
|
|
478
457
|
formattedText = JSON.stringify(result, null, 2);
|
|
@@ -494,4 +473,3 @@ async function handleToolCall(id, params, token) {
|
|
|
494
473
|
};
|
|
495
474
|
}
|
|
496
475
|
}
|
|
497
|
-
|