@lil2good/nubis-mcp-server 1.0.53 → 1.0.57
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/build/index.js +256 -576
- package/package.json +1 -1
- package/src/index.ts +294 -778
package/build/index.js
CHANGED
|
@@ -21,98 +21,7 @@ const server = new mcp_js_1.McpServer({
|
|
|
21
21
|
tools: {},
|
|
22
22
|
},
|
|
23
23
|
});
|
|
24
|
-
//
|
|
25
|
-
// Formatting Helpers
|
|
26
|
-
// ============================================================================
|
|
27
|
-
const BOARD_LABELS = {
|
|
28
|
-
'backlog': '📋 Backlog',
|
|
29
|
-
'bugs': '🐛 Bugs',
|
|
30
|
-
'priority': '⚡ Priority',
|
|
31
|
-
'in-progress': '🔄 In Progress',
|
|
32
|
-
'reviewing': '👀 Reviewing',
|
|
33
|
-
'completed': '✅ Completed'
|
|
34
|
-
};
|
|
35
|
-
function formatBoard(board) {
|
|
36
|
-
return BOARD_LABELS[board] || board;
|
|
37
|
-
}
|
|
38
|
-
function formatApiUsage(usage) {
|
|
39
|
-
return `📊 **API Usage:** ${usage.remaining_calls}/${usage.total_limit} calls remaining`;
|
|
40
|
-
}
|
|
41
|
-
function formatTask(task, options = {}) {
|
|
42
|
-
const lines = [
|
|
43
|
-
`## ${task.title}`,
|
|
44
|
-
'',
|
|
45
|
-
`| Property | Value |`,
|
|
46
|
-
`|----------|-------|`,
|
|
47
|
-
`| **ID** | \`${task.id}\` |`,
|
|
48
|
-
`| **Number** | #${task.task_number} |`,
|
|
49
|
-
`| **Board** | ${formatBoard(task.board)} |`,
|
|
50
|
-
`| **Bolt** | ${task.bolt?.name || '_Unassigned_'} |`,
|
|
51
|
-
];
|
|
52
|
-
if (task.parent_task_id) {
|
|
53
|
-
lines.push(`| **Parent Task** | \`${task.parent_task_id}\` |`);
|
|
54
|
-
}
|
|
55
|
-
// Description
|
|
56
|
-
lines.push('', '### Description', task.description || '_No description provided_');
|
|
57
|
-
// GitHub info
|
|
58
|
-
if (task.github_file_path || task.github_repo_name) {
|
|
59
|
-
lines.push('', '### GitHub', `- **Repo:** ${task.github_repo_name || '_Not set_'}`, `- **Path:** \`${task.github_file_path || '_Not set_'}\``, `- **Type:** ${task.github_item_type || '_Not set_'}`);
|
|
60
|
-
}
|
|
61
|
-
// Blockers
|
|
62
|
-
if (task.pm_task_blockers && task.pm_task_blockers.length > 0) {
|
|
63
|
-
lines.push('', '### ⚠️ Blockers', ...task.pm_task_blockers.map(b => `- \`${b.blocker_task_id}\``));
|
|
64
|
-
}
|
|
65
|
-
// Detailed view includes subtasks and comments
|
|
66
|
-
if (options.detailed) {
|
|
67
|
-
if (task.subtasks && task.subtasks.length > 0) {
|
|
68
|
-
const flatSubtasks = Array.isArray(task.subtasks[0]) ? task.subtasks[0] : task.subtasks;
|
|
69
|
-
if (flatSubtasks.length > 0) {
|
|
70
|
-
lines.push('', '### Subtasks');
|
|
71
|
-
flatSubtasks.forEach((sub) => {
|
|
72
|
-
lines.push(`- [${sub.board === 'completed' ? 'x' : ' '}] **${sub.title}** (\`${sub.id}\`) - ${formatBoard(sub.board)}`);
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
if (task.comments && task.comments.length > 0) {
|
|
77
|
-
const flatComments = Array.isArray(task.comments[0]) ? task.comments[0] : task.comments;
|
|
78
|
-
if (flatComments.length > 0) {
|
|
79
|
-
lines.push('', '### Comments');
|
|
80
|
-
flatComments.forEach((c) => {
|
|
81
|
-
lines.push(`- ${c.content}`);
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
if (task.context) {
|
|
86
|
-
lines.push('', '### Context', task.context);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
// Images
|
|
90
|
-
if (task.images && task.images.length > 0) {
|
|
91
|
-
lines.push('', '### Images');
|
|
92
|
-
task.images.forEach((img, i) => {
|
|
93
|
-
lines.push(`${i + 1}. ${img.url}`);
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
return lines.join('\n');
|
|
97
|
-
}
|
|
98
|
-
function formatTaskCompact(task) {
|
|
99
|
-
const blockerNote = task.pm_task_blockers && task.pm_task_blockers.length > 0
|
|
100
|
-
? ` ⚠️ ${task.pm_task_blockers.length} blocker(s)`
|
|
101
|
-
: '';
|
|
102
|
-
return [
|
|
103
|
-
`### #${task.task_number}: ${task.title}${blockerNote}`,
|
|
104
|
-
`**ID:** \`${task.id}\` | **Board:** ${formatBoard(task.board)} | **Bolt:** ${task.bolt?.name || '_None_'}`,
|
|
105
|
-
task.description ? `> ${task.description.substring(0, 150)}${task.description.length > 150 ? '...' : ''}` : '',
|
|
106
|
-
task.github_file_path ? `📁 \`${task.github_file_path}\`` : '',
|
|
107
|
-
'---'
|
|
108
|
-
].filter(Boolean).join('\n');
|
|
109
|
-
}
|
|
110
|
-
function formatBolt(bolt) {
|
|
111
|
-
return `- **${bolt.name}** (\`${bolt.id}\`)${bolt.description ? `: ${bolt.description}` : ''}`;
|
|
112
|
-
}
|
|
113
|
-
// ============================================================================
|
|
114
|
-
// Middleware Helper
|
|
115
|
-
// ============================================================================
|
|
24
|
+
// Helper to get results from middleware
|
|
116
25
|
async function getResultsFromMiddleware({ endpoint, schema }) {
|
|
117
26
|
const response = await fetch('https://mcp-server.nubis.app/' + endpoint, {
|
|
118
27
|
method: 'POST',
|
|
@@ -127,269 +36,287 @@ async function getResultsFromMiddleware({ endpoint, schema }) {
|
|
|
127
36
|
});
|
|
128
37
|
if (!response.ok) {
|
|
129
38
|
const errorData = await response.json();
|
|
130
|
-
throw new Error(errorData.error || 'Failed to fetch from middleware');
|
|
39
|
+
throw new Error(errorData.error || 'Failed to fetch tasks from middleware');
|
|
131
40
|
}
|
|
41
|
+
// Return the full JSON response (including api_usage, user, etc.)
|
|
132
42
|
const json = await response.json();
|
|
133
43
|
if (!json.data)
|
|
134
44
|
throw new Error('No data returned from middleware');
|
|
135
45
|
return json;
|
|
136
46
|
}
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
// ============================================================================
|
|
140
|
-
/**
|
|
141
|
-
* Get Boltz
|
|
142
|
-
*/
|
|
143
|
-
server.tool("get_boltz", "Fetch all boltz (project branches) for the workspace. Use this to get bolt IDs for filtering tasks or assigning tasks to specific boltz.", async () => {
|
|
47
|
+
// Get Boltz -> to save IDs for use in tasks later
|
|
48
|
+
server.tool("get_boltz", "Fetch all boltz for a workspace", async () => {
|
|
144
49
|
const json = await getResultsFromMiddleware({
|
|
145
50
|
endpoint: 'get_boltz',
|
|
146
51
|
schema: {}
|
|
147
52
|
});
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
`# Boltz (${boltz.length} total)`,
|
|
151
|
-
'',
|
|
152
|
-
...boltz.map(formatBolt),
|
|
153
|
-
'',
|
|
154
|
-
'---',
|
|
155
|
-
formatApiUsage(json.api_usage)
|
|
156
|
-
].join('\n');
|
|
53
|
+
if (!json.data)
|
|
54
|
+
throw new Error('No data returned from middleware');
|
|
157
55
|
return {
|
|
158
|
-
content: [
|
|
56
|
+
content: [
|
|
57
|
+
{
|
|
58
|
+
type: "text",
|
|
59
|
+
text: JSON.stringify(json.data),
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
type: "text",
|
|
63
|
+
text: `Always provide API Usage information separately. Usage: ${JSON.stringify(json.api_usage)}`,
|
|
64
|
+
}
|
|
65
|
+
],
|
|
159
66
|
};
|
|
160
67
|
});
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
board: zod_1.z.enum(['bugs', 'backlog', 'priority', 'in-progress', 'reviewing', 'completed']).optional().describe("Filter by board/status"),
|
|
167
|
-
bolt_id: zod_1.z.string().optional().describe("Filter by bolt ID (use get_boltz to find bolt IDs)"),
|
|
68
|
+
// Get Tasks -> Get tasks for a workspace
|
|
69
|
+
server.tool("get_tasks", "Get tasks for a workspace, including subtasks, boltz, and github details/file paths", {
|
|
70
|
+
limit: zod_1.z.number().optional().default(5),
|
|
71
|
+
board: zod_1.z.enum(['bugs', 'backlog', 'priority', 'in-progress', 'reviewing', 'completed']).optional(),
|
|
72
|
+
bolt_id: zod_1.z.string().optional(),
|
|
168
73
|
}, async ({ limit, board, bolt_id }) => {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
74
|
+
try {
|
|
75
|
+
const json = await getResultsFromMiddleware({
|
|
76
|
+
endpoint: 'get_tasks',
|
|
77
|
+
schema: {
|
|
78
|
+
board,
|
|
79
|
+
bolt_id,
|
|
80
|
+
limit
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
if (!json.data)
|
|
84
|
+
throw new Error('No data returned from middleware');
|
|
85
|
+
const taskContent = json.data.map((task) => ({
|
|
86
|
+
type: "text",
|
|
87
|
+
text: [
|
|
88
|
+
`---`,
|
|
89
|
+
`### ${task.title}`,
|
|
90
|
+
`**Task ID:** ${task.id}`,
|
|
91
|
+
`**Task Number:** ${task.task_number}`,
|
|
92
|
+
`**Board:** ${task.board}`,
|
|
93
|
+
`**Bolt:** ${task.bolt && typeof task.bolt === "object" && !Array.isArray(task.bolt) && "name" in task.bolt && task.bolt.name ? task.bolt.name : "_No bolt_"}`,
|
|
94
|
+
`**Description:** ${task.description ? task.description : "_No description_"}`,
|
|
95
|
+
`**Path Type:** ${task.github_item_type ? task.github_item_type : "_No file path type_"}`,
|
|
96
|
+
`**File Path:** ${task.github_file_path ? task.github_file_path : "_No file path_"}`,
|
|
97
|
+
`**Repo Name:** ${task.github_repo_name ? task.github_repo_name : "_No repo name_"}`,
|
|
98
|
+
`**Blockers:** ${task.pm_task_blockers && task.pm_task_blockers.length > 0 ? task.pm_task_blockers.map(blocker => blocker.blocker_task_id).join(', ') : "_No blockers_"}`,
|
|
99
|
+
task.images && task.images.length > 0
|
|
100
|
+
? task.images.map((image) => image.url).join('\n')
|
|
101
|
+
: "_No images_",
|
|
102
|
+
`---`,
|
|
103
|
+
].join('\n\n'),
|
|
104
|
+
}));
|
|
105
|
+
// Append quota and user info as additional content
|
|
106
|
+
taskContent.push({
|
|
107
|
+
type: "text",
|
|
108
|
+
text: `Always provide API Usage information separately. Usage: ${JSON.stringify(json.api_usage)}`,
|
|
109
|
+
});
|
|
110
|
+
return {
|
|
111
|
+
content: taskContent,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
116
|
+
throw new Error(errorMessage);
|
|
117
|
+
}
|
|
189
118
|
});
|
|
190
119
|
/**
|
|
191
|
-
* Get Task Details
|
|
120
|
+
* Get Task Details -> Get a task by ID
|
|
192
121
|
*/
|
|
193
|
-
server.tool("get_task_details", "Get
|
|
194
|
-
taskID: zod_1.z.string()
|
|
122
|
+
server.tool("get_task_details", "Get a task by ID", {
|
|
123
|
+
taskID: zod_1.z.string(),
|
|
195
124
|
}, async ({ taskID }) => {
|
|
196
125
|
const json = await getResultsFromMiddleware({
|
|
197
126
|
endpoint: 'get_task',
|
|
198
|
-
schema: {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const formatted = [
|
|
202
|
-
formatTask(task, { detailed: true }),
|
|
203
|
-
'',
|
|
204
|
-
'---',
|
|
205
|
-
formatApiUsage(json.api_usage)
|
|
206
|
-
].join('\n');
|
|
207
|
-
return {
|
|
208
|
-
content: [{ type: "text", text: formatted }],
|
|
209
|
-
};
|
|
210
|
-
});
|
|
211
|
-
/**
|
|
212
|
-
* Get Task Context
|
|
213
|
-
*/
|
|
214
|
-
server.tool("get_task_context", "Retrieve the context/notes stored for a specific task. Context contains additional information, implementation notes, or progress updates added during task work.", {
|
|
215
|
-
taskID: zod_1.z.string().describe("The UUID of the task"),
|
|
216
|
-
}, async ({ taskID }) => {
|
|
217
|
-
const json = await getResultsFromMiddleware({
|
|
218
|
-
endpoint: 'get_task_context',
|
|
219
|
-
schema: { taskID }
|
|
127
|
+
schema: {
|
|
128
|
+
taskID
|
|
129
|
+
}
|
|
220
130
|
});
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
`# Task Context`,
|
|
224
|
-
`**Task ID:** \`${taskID}\``,
|
|
225
|
-
'',
|
|
226
|
-
'---',
|
|
227
|
-
'',
|
|
228
|
-
context || '_No context has been added to this task yet._',
|
|
229
|
-
'',
|
|
230
|
-
'---',
|
|
231
|
-
formatApiUsage(json.api_usage)
|
|
232
|
-
].join('\n');
|
|
131
|
+
if (!json.data)
|
|
132
|
+
throw new Error('No data returned from middleware');
|
|
233
133
|
return {
|
|
234
|
-
content: [
|
|
134
|
+
content: [
|
|
135
|
+
{
|
|
136
|
+
type: "text",
|
|
137
|
+
text: JSON.stringify(json.data),
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
type: "text",
|
|
141
|
+
text: `Always provide API Usage information separately. Usage: ${JSON.stringify(json.api_usage)}`,
|
|
142
|
+
}
|
|
143
|
+
],
|
|
235
144
|
};
|
|
236
145
|
});
|
|
146
|
+
//add_context_to_pm_task
|
|
237
147
|
/**
|
|
238
|
-
*
|
|
148
|
+
* Always ADD CONTEXT TO PM TASK
|
|
239
149
|
*/
|
|
240
|
-
server.tool("add_context_to_task", "Add
|
|
241
|
-
taskID: zod_1.z.string()
|
|
242
|
-
context: zod_1.z.string()
|
|
150
|
+
server.tool("add_context_to_task", "Add context to a task", {
|
|
151
|
+
taskID: zod_1.z.string(),
|
|
152
|
+
context: zod_1.z.string(),
|
|
243
153
|
}, async ({ taskID, context }) => {
|
|
244
154
|
const json = await getResultsFromMiddleware({
|
|
245
155
|
endpoint: 'add_context_to_task',
|
|
246
|
-
schema: {
|
|
156
|
+
schema: {
|
|
157
|
+
taskID,
|
|
158
|
+
context
|
|
159
|
+
}
|
|
247
160
|
});
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
'',
|
|
251
|
-
`**Task ID:** \`${taskID}\``,
|
|
252
|
-
'',
|
|
253
|
-
'**Context:**',
|
|
254
|
-
context,
|
|
255
|
-
'',
|
|
256
|
-
'---',
|
|
257
|
-
formatApiUsage(json.api_usage)
|
|
258
|
-
].join('\n');
|
|
161
|
+
if (!json.data)
|
|
162
|
+
throw new Error('No data returned from middleware');
|
|
259
163
|
return {
|
|
260
|
-
content: [
|
|
164
|
+
content: [
|
|
165
|
+
{
|
|
166
|
+
type: "text",
|
|
167
|
+
text: JSON.stringify({ taskID, context }),
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
type: "text",
|
|
171
|
+
text: `Always provide API Usage information separately. Usage: ${JSON.stringify({ taskID, context })}`,
|
|
172
|
+
}
|
|
173
|
+
],
|
|
261
174
|
};
|
|
262
175
|
});
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
server.tool("get_task_images", "Retrieve all images/attachments associated with a task. Returns image URLs that can be viewed or referenced.", {
|
|
267
|
-
taskID: zod_1.z.string().describe("The UUID of the task"),
|
|
176
|
+
// Get Task Images -> Get images for a task
|
|
177
|
+
server.tool("get_task_images", "Get/View images for a task", {
|
|
178
|
+
taskID: zod_1.z.string(),
|
|
268
179
|
}, async ({ taskID }) => {
|
|
269
180
|
const json = await getResultsFromMiddleware({
|
|
270
181
|
endpoint: 'get_task_images',
|
|
271
|
-
schema: {
|
|
182
|
+
schema: {
|
|
183
|
+
taskID
|
|
184
|
+
}
|
|
272
185
|
});
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
`# Task Images`,
|
|
276
|
-
`**Task ID:** \`${taskID}\``,
|
|
277
|
-
'',
|
|
278
|
-
images.length > 0
|
|
279
|
-
? images.map((img, i) => `${i + 1}. ${img.url}`).join('\n')
|
|
280
|
-
: '_No images attached to this task._',
|
|
281
|
-
'',
|
|
282
|
-
'---',
|
|
283
|
-
formatApiUsage(json.api_usage)
|
|
284
|
-
].join('\n');
|
|
186
|
+
if (!json.data)
|
|
187
|
+
throw new Error('No data returned from middleware');
|
|
285
188
|
return {
|
|
286
|
-
content: [
|
|
189
|
+
content: [
|
|
190
|
+
{
|
|
191
|
+
type: "text",
|
|
192
|
+
text: JSON.stringify(json.data),
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
type: "text",
|
|
196
|
+
text: `Always provide API Usage information separately. Usage: ${JSON.stringify(json.api_usage)}`,
|
|
197
|
+
}
|
|
198
|
+
],
|
|
287
199
|
};
|
|
288
200
|
});
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
server.tool("work_on_task", "Start working on a task. This checks for blockers and returns full task details. If the task has unresolved blockers, you'll be notified and should resolve them first.", {
|
|
293
|
-
taskID: zod_1.z.string().describe("The UUID of the task to work on"),
|
|
201
|
+
// Work on Task -> Work on a task
|
|
202
|
+
server.tool("work_on_task", "Work on a task", {
|
|
203
|
+
taskID: zod_1.z.string(),
|
|
294
204
|
}, async ({ taskID }) => {
|
|
295
|
-
// Step 1: Fetch task details
|
|
205
|
+
// Step 1: Fetch task details
|
|
296
206
|
const taskData = await getResultsFromMiddleware({
|
|
297
207
|
endpoint: 'get_task',
|
|
298
208
|
schema: { taskID }
|
|
299
209
|
});
|
|
300
|
-
|
|
210
|
+
if (!taskData.data)
|
|
211
|
+
throw new Error('No data returned from middleware');
|
|
301
212
|
// Step 2: Check for blockers
|
|
302
|
-
if (Array.isArray(
|
|
303
|
-
const blockerIds = task.pm_task_blockers.map(b => `\`${b.blocker_task_id}\``).join(', ');
|
|
304
|
-
const formatted = [
|
|
305
|
-
`⚠️ **Cannot Work on Task - Blockers Detected**`,
|
|
306
|
-
'',
|
|
307
|
-
`**Task:** ${task.title}`,
|
|
308
|
-
`**Task ID:** \`${taskID}\``,
|
|
309
|
-
'',
|
|
310
|
-
`### Blocking Tasks`,
|
|
311
|
-
`The following tasks must be completed first: ${blockerIds}`,
|
|
312
|
-
'',
|
|
313
|
-
'**Suggested Actions:**',
|
|
314
|
-
'- Use `get_task_details` on each blocker to understand what needs to be done',
|
|
315
|
-
'- Complete or remove the blocking tasks before proceeding',
|
|
316
|
-
'',
|
|
317
|
-
'---',
|
|
318
|
-
formatApiUsage(taskData.api_usage)
|
|
319
|
-
].join('\n');
|
|
213
|
+
if (Array.isArray(taskData.data.pm_task_blockers) && taskData.data.pm_task_blockers.length > 0) {
|
|
320
214
|
return {
|
|
321
|
-
content: [
|
|
215
|
+
content: [
|
|
216
|
+
{
|
|
217
|
+
type: "text",
|
|
218
|
+
text: `Task ${taskID} cannot be worked on because it has blockers: ${taskData.data.pm_task_blockers.map((b) => b.blocker_task_id).join(', ')}. Please resolve all blockers before proceeding.`,
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
type: "text",
|
|
222
|
+
text: `API Usage: ${JSON.stringify(taskData.api_usage)}`,
|
|
223
|
+
}
|
|
224
|
+
],
|
|
322
225
|
};
|
|
323
226
|
}
|
|
324
|
-
|
|
227
|
+
;
|
|
325
228
|
const json = await getResultsFromMiddleware({
|
|
326
229
|
endpoint: 'work_on_task',
|
|
327
|
-
schema: {
|
|
230
|
+
schema: {
|
|
231
|
+
taskID
|
|
232
|
+
}
|
|
328
233
|
});
|
|
329
|
-
const workTask = json.data;
|
|
330
|
-
const suggestedActions = [];
|
|
331
|
-
if (workTask.board !== 'in-progress') {
|
|
332
|
-
suggestedActions.push(`- Move task to "in-progress" using \`move_task\``);
|
|
333
|
-
}
|
|
334
|
-
if (workTask.subtasks && workTask.subtasks.length > 0) {
|
|
335
|
-
suggestedActions.push(`- Review ${workTask.subtasks.length} subtask(s)`);
|
|
336
|
-
}
|
|
337
|
-
suggestedActions.push('- Add context with `add_context_to_task` as you make progress', '- When done, move to "reviewing" or "completed"');
|
|
338
|
-
const formatted = [
|
|
339
|
-
`🚀 **Ready to Work**`,
|
|
340
|
-
'',
|
|
341
|
-
formatTask(workTask, { detailed: true }),
|
|
342
|
-
'',
|
|
343
|
-
'### 💡 Suggested Actions',
|
|
344
|
-
...suggestedActions,
|
|
345
|
-
'',
|
|
346
|
-
'---',
|
|
347
|
-
formatApiUsage(json.api_usage)
|
|
348
|
-
].join('\n');
|
|
349
234
|
return {
|
|
350
|
-
content: [
|
|
235
|
+
content: [
|
|
236
|
+
{
|
|
237
|
+
type: "text",
|
|
238
|
+
text: `You are assisting with task management in Nubis. Your task is to work on the user's requested task based on the following details:\n\n**Task Instruction**: Process and update the task with the provided information.\n\n**Task ID**: ${taskID}\n\n**Task Details**: \n ${JSON.stringify(json.data, null, 2).replace(/"/g, '').replace(/:/g, ': ').replace(/},/g, ',\n')}\n \n Please analyze the details, perform the requested action (e.g., update description, add subtask), and return a response indicating the action taken.`,
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
type: "text",
|
|
242
|
+
user: "NUBIS",
|
|
243
|
+
text: `Prompt user to move this task to 'in-progress' if it is not already in progress.`,
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
type: "text",
|
|
247
|
+
user: "NUBIS",
|
|
248
|
+
text: `API Usage: ${JSON.stringify(json.api_usage)}`,
|
|
249
|
+
}
|
|
250
|
+
],
|
|
351
251
|
};
|
|
352
252
|
});
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
253
|
+
// Explain setup and what user needs to do for feature to be implemented
|
|
254
|
+
/* server.tool(
|
|
255
|
+
"explain_setup",
|
|
256
|
+
"Explain setup and what needs to be done for feature to be implemented",
|
|
257
|
+
{
|
|
258
|
+
taskID: z.string(),
|
|
259
|
+
},
|
|
260
|
+
async ({ taskID }) => {
|
|
261
|
+
const json = await getResultsFromMiddleware({
|
|
262
|
+
endpoint: 'explain_setup',
|
|
263
|
+
schema: {
|
|
264
|
+
taskID
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
if (!json.data) throw new Error('No data returned from middleware');
|
|
269
|
+
return {
|
|
270
|
+
content: [
|
|
271
|
+
{
|
|
272
|
+
type: "text",
|
|
273
|
+
text: `You are assisting with task management in Nubis. Your task is to explain the setup and what needs to be done for feature to be implemented.\n \n **Task Instruction**: Explain the setup and what needs to be done for feature to be implemented.\n **Task Details**: \n ${JSON.stringify(json.data, null, 2).replace(/"/g, '').replace(/:/g, ': ').replace(/},/g, ',\n')}\n \n Please analyze the feature and return a response indicating the action that needs to be taken.`,
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
type: "text",
|
|
277
|
+
text: `Always provide API Usage information separately. Usage: ${JSON.stringify(json.api_usage)}`,
|
|
278
|
+
}
|
|
279
|
+
],
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
); */
|
|
283
|
+
// Move Task -> Move a task to ['backlog', 'priority', 'in-progress','reviewing', 'completed']
|
|
284
|
+
server.tool("move_task", "Move a task to ['backlog', 'priority', 'in-progress','reviewing', 'completed']", {
|
|
285
|
+
taskID: zod_1.z.string(),
|
|
286
|
+
board: zod_1.z.enum(['backlog', 'priority', 'in-progress', 'reviewing', 'completed']),
|
|
359
287
|
}, async ({ taskID, board }) => {
|
|
360
288
|
const json = await getResultsFromMiddleware({
|
|
361
289
|
endpoint: 'move_task',
|
|
362
|
-
schema: {
|
|
290
|
+
schema: {
|
|
291
|
+
taskID,
|
|
292
|
+
board
|
|
293
|
+
}
|
|
363
294
|
});
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
`✅ **Task Moved Successfully**`,
|
|
367
|
-
'',
|
|
368
|
-
`| Property | Value |`,
|
|
369
|
-
`|----------|-------|`,
|
|
370
|
-
`| **Task** | ${task.title} |`,
|
|
371
|
-
`| **ID** | \`${taskID}\` |`,
|
|
372
|
-
`| **New Status** | ${formatBoard(board)} |`,
|
|
373
|
-
'',
|
|
374
|
-
'---',
|
|
375
|
-
formatApiUsage(json.api_usage)
|
|
376
|
-
].join('\n');
|
|
295
|
+
if (!json.data)
|
|
296
|
+
throw new Error('No data returned from middleware');
|
|
377
297
|
return {
|
|
378
|
-
content: [
|
|
298
|
+
content: [
|
|
299
|
+
{
|
|
300
|
+
type: "text",
|
|
301
|
+
text: `Task ${taskID} has been moved to ${board}`,
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
type: "text",
|
|
305
|
+
text: `API Usage: ${JSON.stringify(json.api_usage)}`,
|
|
306
|
+
}
|
|
307
|
+
],
|
|
379
308
|
};
|
|
380
309
|
});
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
github_repo_name: zod_1.z.string().optional().describe("Repository name (e.g., owner/repo)"),
|
|
392
|
-
bolt_id: zod_1.z.string().optional().describe("Bolt ID to assign (use get_boltz to find IDs)")
|
|
310
|
+
// Create Task -> Create a new task
|
|
311
|
+
server.tool("create_task", "Create a new task or subtask (parent_task_id is required for subtasks)", {
|
|
312
|
+
title: zod_1.z.string(),
|
|
313
|
+
description: zod_1.z.string().optional(),
|
|
314
|
+
board: zod_1.z.enum(['backlog', 'bugs', 'in-progress', 'priority', 'reviewing', 'completed']).optional().default('backlog'),
|
|
315
|
+
parent_task_id: zod_1.z.string().optional(),
|
|
316
|
+
github_item_type: zod_1.z.string().optional(), // file or dir
|
|
317
|
+
github_file_path: zod_1.z.string().optional(), // src/components/modal
|
|
318
|
+
github_repo_name: zod_1.z.string().optional(), // Atomlaunch/atom_frontend
|
|
319
|
+
bolt_id: zod_1.z.string().optional()
|
|
393
320
|
}, async ({ title, description, board, parent_task_id, github_item_type, github_file_path, github_repo_name, bolt_id }) => {
|
|
394
321
|
const json = await getResultsFromMiddleware({
|
|
395
322
|
endpoint: 'create_task',
|
|
@@ -404,44 +331,32 @@ server.tool("create_task", "Create a new task or subtask. For subtasks, provide
|
|
|
404
331
|
bolt_id
|
|
405
332
|
}
|
|
406
333
|
});
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
`✅ **Task Created Successfully**`,
|
|
410
|
-
'',
|
|
411
|
-
`| Property | Value |`,
|
|
412
|
-
`|----------|-------|`,
|
|
413
|
-
`| **Title** | ${task.title} |`,
|
|
414
|
-
`| **ID** | \`${task.id}\` |`,
|
|
415
|
-
`| **Number** | #${task.task_number} |`,
|
|
416
|
-
`| **Board** | ${formatBoard(task.board)} |`,
|
|
417
|
-
];
|
|
418
|
-
if (parent_task_id) {
|
|
419
|
-
lines.push(`| **Parent Task** | \`${parent_task_id}\` |`);
|
|
420
|
-
}
|
|
421
|
-
if (bolt_id) {
|
|
422
|
-
lines.push(`| **Bolt** | \`${bolt_id}\` |`);
|
|
423
|
-
}
|
|
424
|
-
if (github_file_path) {
|
|
425
|
-
lines.push(`| **GitHub Path** | \`${github_file_path}\` |`);
|
|
426
|
-
}
|
|
427
|
-
lines.push('', '---', formatApiUsage(json.api_usage));
|
|
334
|
+
if (!json.data)
|
|
335
|
+
throw new Error('No data returned from middleware');
|
|
428
336
|
return {
|
|
429
|
-
content: [
|
|
337
|
+
content: [
|
|
338
|
+
{
|
|
339
|
+
type: "text",
|
|
340
|
+
text: JSON.stringify(json.data),
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
type: "text",
|
|
344
|
+
text: `API Usage: ${JSON.stringify(json.api_usage)}`,
|
|
345
|
+
}
|
|
346
|
+
],
|
|
430
347
|
};
|
|
431
348
|
});
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
github_file_path: zod_1.z.string().optional().describe("Path to file or directory"),
|
|
444
|
-
github_repo_name: zod_1.z.string().optional().describe("Repository name"),
|
|
349
|
+
// Update Task -> Update an existing task
|
|
350
|
+
server.tool("update_task", "Update an existing task (title, description, bolt_id, parent_task_id)", {
|
|
351
|
+
taskID: zod_1.z.string(),
|
|
352
|
+
title: zod_1.z.string().optional(),
|
|
353
|
+
description: zod_1.z.string().optional(),
|
|
354
|
+
board: zod_1.z.enum(['backlog', 'bugs', 'in-progress', 'priority', 'reviewing', 'completed']).optional(),
|
|
355
|
+
bolt_id: zod_1.z.string().optional(),
|
|
356
|
+
parent_task_id: zod_1.z.string().optional(),
|
|
357
|
+
github_item_type: zod_1.z.string().optional(),
|
|
358
|
+
github_file_path: zod_1.z.string().optional(),
|
|
359
|
+
github_repo_name: zod_1.z.string().optional(),
|
|
445
360
|
}, async ({ taskID, title, description, board, bolt_id, parent_task_id, github_item_type, github_file_path, github_repo_name }) => {
|
|
446
361
|
const json = await getResultsFromMiddleware({
|
|
447
362
|
endpoint: 'update_task',
|
|
@@ -457,257 +372,22 @@ server.tool("update_task", "Update an existing task's properties. You can modify
|
|
|
457
372
|
github_repo_name
|
|
458
373
|
}
|
|
459
374
|
});
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
if (title)
|
|
463
|
-
updatedFields.push('title');
|
|
464
|
-
if (description)
|
|
465
|
-
updatedFields.push('description');
|
|
466
|
-
if (board)
|
|
467
|
-
updatedFields.push('board');
|
|
468
|
-
if (bolt_id)
|
|
469
|
-
updatedFields.push('bolt');
|
|
470
|
-
if (parent_task_id)
|
|
471
|
-
updatedFields.push('parent task');
|
|
472
|
-
if (github_file_path || github_repo_name || github_item_type)
|
|
473
|
-
updatedFields.push('GitHub integration');
|
|
474
|
-
const formatted = [
|
|
475
|
-
`✅ **Task Updated Successfully**`,
|
|
476
|
-
'',
|
|
477
|
-
`**Updated fields:** ${updatedFields.join(', ') || 'none'}`,
|
|
478
|
-
'',
|
|
479
|
-
formatTask(task),
|
|
480
|
-
'',
|
|
481
|
-
'---',
|
|
482
|
-
formatApiUsage(json.api_usage)
|
|
483
|
-
].join('\n');
|
|
484
|
-
return {
|
|
485
|
-
content: [{ type: "text", text: formatted }],
|
|
486
|
-
};
|
|
487
|
-
});
|
|
488
|
-
/**
|
|
489
|
-
* Delete Task
|
|
490
|
-
*/
|
|
491
|
-
server.tool("delete_task", "Permanently delete a task and all its related data (subtasks, comments, blockers, labels, assignments). This action cannot be undone.", {
|
|
492
|
-
taskID: zod_1.z.string().describe("The UUID of the task to delete"),
|
|
493
|
-
}, async ({ taskID }) => {
|
|
494
|
-
const json = await getResultsFromMiddleware({
|
|
495
|
-
endpoint: 'delete_task',
|
|
496
|
-
schema: { taskID }
|
|
497
|
-
});
|
|
498
|
-
const formatted = [
|
|
499
|
-
`🗑️ **Task Deleted Successfully**`,
|
|
500
|
-
'',
|
|
501
|
-
`**Task ID:** \`${taskID}\``,
|
|
502
|
-
'',
|
|
503
|
-
'The task and all related data (subtasks, comments, blockers, labels, assignments) have been permanently removed.',
|
|
504
|
-
'',
|
|
505
|
-
'---',
|
|
506
|
-
formatApiUsage(json.api_usage)
|
|
507
|
-
].join('\n');
|
|
508
|
-
return {
|
|
509
|
-
content: [{ type: "text", text: formatted }],
|
|
510
|
-
};
|
|
511
|
-
});
|
|
512
|
-
function formatComment(comment) {
|
|
513
|
-
const author = comment.user?.full_name || 'Unknown';
|
|
514
|
-
const editedTag = comment.is_edited ? ' _(edited)_' : '';
|
|
515
|
-
const date = new Date(comment.created_at).toLocaleString();
|
|
516
|
-
return [
|
|
517
|
-
`**${author}** · ${date}${editedTag}`,
|
|
518
|
-
`> ${comment.content}`,
|
|
519
|
-
`_ID: \`${comment.id}\`_`,
|
|
520
|
-
].join('\n');
|
|
521
|
-
}
|
|
522
|
-
/**
|
|
523
|
-
* Get Comments
|
|
524
|
-
*/
|
|
525
|
-
server.tool("get_comments", "Retrieve all comments for a specific task. Returns comments with author information, timestamps, and edit status.", {
|
|
526
|
-
taskID: zod_1.z.string().describe("The UUID of the task"),
|
|
527
|
-
}, async ({ taskID }) => {
|
|
528
|
-
const json = await getResultsFromMiddleware({
|
|
529
|
-
endpoint: 'get_comments',
|
|
530
|
-
schema: { taskID }
|
|
531
|
-
});
|
|
532
|
-
const comments = json.data;
|
|
533
|
-
const formatted = [
|
|
534
|
-
`# Task Comments`,
|
|
535
|
-
`**Task ID:** \`${taskID}\``,
|
|
536
|
-
`**Total:** ${comments.length} comment(s)`,
|
|
537
|
-
'',
|
|
538
|
-
'---',
|
|
539
|
-
'',
|
|
540
|
-
comments.length > 0
|
|
541
|
-
? comments.map(formatComment).join('\n\n')
|
|
542
|
-
: '_No comments yet._',
|
|
543
|
-
'',
|
|
544
|
-
'---',
|
|
545
|
-
formatApiUsage(json.api_usage)
|
|
546
|
-
].join('\n');
|
|
547
|
-
return {
|
|
548
|
-
content: [{ type: "text", text: formatted }],
|
|
549
|
-
};
|
|
550
|
-
});
|
|
551
|
-
/**
|
|
552
|
-
* Create Comment
|
|
553
|
-
*/
|
|
554
|
-
server.tool("create_comment", "Add a comment to a task. Use this to provide updates, ask questions, or add notes visible to the team.", {
|
|
555
|
-
taskID: zod_1.z.string().describe("The UUID of the task to comment on"),
|
|
556
|
-
content: zod_1.z.string().describe("The comment text"),
|
|
557
|
-
parent_id: zod_1.z.string().optional().describe("Parent comment ID for replies (optional)"),
|
|
558
|
-
}, async ({ taskID, content, parent_id }) => {
|
|
559
|
-
const json = await getResultsFromMiddleware({
|
|
560
|
-
endpoint: 'create_comment',
|
|
561
|
-
schema: { taskID, content, parent_id }
|
|
562
|
-
});
|
|
563
|
-
const comment = json.data;
|
|
564
|
-
const formatted = [
|
|
565
|
-
`✅ **Comment Added**`,
|
|
566
|
-
'',
|
|
567
|
-
formatComment(comment),
|
|
568
|
-
'',
|
|
569
|
-
'---',
|
|
570
|
-
formatApiUsage(json.api_usage)
|
|
571
|
-
].join('\n');
|
|
572
|
-
return {
|
|
573
|
-
content: [{ type: "text", text: formatted }],
|
|
574
|
-
};
|
|
575
|
-
});
|
|
576
|
-
/**
|
|
577
|
-
* Update Comment
|
|
578
|
-
*/
|
|
579
|
-
server.tool("update_comment", "Edit an existing comment. Only the comment author can edit their own comments.", {
|
|
580
|
-
commentID: zod_1.z.string().describe("The UUID of the comment to edit"),
|
|
581
|
-
content: zod_1.z.string().describe("The new comment text"),
|
|
582
|
-
}, async ({ commentID, content }) => {
|
|
583
|
-
const json = await getResultsFromMiddleware({
|
|
584
|
-
endpoint: 'update_comment',
|
|
585
|
-
schema: { commentID, content }
|
|
586
|
-
});
|
|
587
|
-
const formatted = [
|
|
588
|
-
`✅ **Comment Updated**`,
|
|
589
|
-
'',
|
|
590
|
-
`**Comment ID:** \`${commentID}\``,
|
|
591
|
-
`**New content:** ${content}`,
|
|
592
|
-
'',
|
|
593
|
-
'---',
|
|
594
|
-
formatApiUsage(json.api_usage)
|
|
595
|
-
].join('\n');
|
|
596
|
-
return {
|
|
597
|
-
content: [{ type: "text", text: formatted }],
|
|
598
|
-
};
|
|
599
|
-
});
|
|
600
|
-
/**
|
|
601
|
-
* Delete Comment
|
|
602
|
-
*/
|
|
603
|
-
server.tool("delete_comment", "Delete a comment and all its replies. Only the comment author can delete their own comments.", {
|
|
604
|
-
commentID: zod_1.z.string().describe("The UUID of the comment to delete"),
|
|
605
|
-
}, async ({ commentID }) => {
|
|
606
|
-
const json = await getResultsFromMiddleware({
|
|
607
|
-
endpoint: 'delete_comment',
|
|
608
|
-
schema: { commentID }
|
|
609
|
-
});
|
|
610
|
-
const formatted = [
|
|
611
|
-
`🗑️ **Comment Deleted**`,
|
|
612
|
-
'',
|
|
613
|
-
`**Comment ID:** \`${commentID}\``,
|
|
614
|
-
'',
|
|
615
|
-
'---',
|
|
616
|
-
formatApiUsage(json.api_usage)
|
|
617
|
-
].join('\n');
|
|
618
|
-
return {
|
|
619
|
-
content: [{ type: "text", text: formatted }],
|
|
620
|
-
};
|
|
621
|
-
});
|
|
622
|
-
function formatBlockerTask(task) {
|
|
623
|
-
return `#${task.task_number}: ${task.title} (${formatBoard(task.board)}) - \`${task.id}\``;
|
|
624
|
-
}
|
|
625
|
-
/**
|
|
626
|
-
* Get Blockers
|
|
627
|
-
*/
|
|
628
|
-
server.tool("get_blockers", "Get blocker relationships for a task. Shows both tasks that block this task and tasks that this task blocks.", {
|
|
629
|
-
taskID: zod_1.z.string().describe("The UUID of the task"),
|
|
630
|
-
}, async ({ taskID }) => {
|
|
631
|
-
const json = await getResultsFromMiddleware({
|
|
632
|
-
endpoint: 'get_blockers',
|
|
633
|
-
schema: { taskID }
|
|
634
|
-
});
|
|
635
|
-
const { blockers, blocking } = json.data;
|
|
636
|
-
const formatted = [
|
|
637
|
-
`# Task Blockers`,
|
|
638
|
-
`**Task ID:** \`${taskID}\``,
|
|
639
|
-
'',
|
|
640
|
-
'### ⛔ Blocked By (must complete first)',
|
|
641
|
-
blockers.length > 0
|
|
642
|
-
? blockers.map(b => `- ${formatBlockerTask(b.blocker)}`).join('\n')
|
|
643
|
-
: '_No blockers - task is ready to work on_',
|
|
644
|
-
'',
|
|
645
|
-
'### 🚧 Blocking (waiting on this task)',
|
|
646
|
-
blocking.length > 0
|
|
647
|
-
? blocking.map(b => `- ${formatBlockerTask(b.blocked)}`).join('\n')
|
|
648
|
-
: '_Not blocking any tasks_',
|
|
649
|
-
'',
|
|
650
|
-
'---',
|
|
651
|
-
formatApiUsage(json.api_usage)
|
|
652
|
-
].join('\n');
|
|
653
|
-
return {
|
|
654
|
-
content: [{ type: "text", text: formatted }],
|
|
655
|
-
};
|
|
656
|
-
});
|
|
657
|
-
/**
|
|
658
|
-
* Add Blocker
|
|
659
|
-
*/
|
|
660
|
-
server.tool("add_blocker", "Create a blocker dependency between tasks. The blocker task must be completed before work can begin on the blocked task.", {
|
|
661
|
-
taskID: zod_1.z.string().describe("The UUID of the task that will be blocked"),
|
|
662
|
-
blockerTaskID: zod_1.z.string().describe("The UUID of the task that blocks (must be completed first)"),
|
|
663
|
-
}, async ({ taskID, blockerTaskID }) => {
|
|
664
|
-
const json = await getResultsFromMiddleware({
|
|
665
|
-
endpoint: 'add_blocker',
|
|
666
|
-
schema: { taskID, blockerTaskID }
|
|
667
|
-
});
|
|
668
|
-
const { blocked_task, blocker_task } = json.data;
|
|
669
|
-
const formatted = [
|
|
670
|
-
`✅ **Blocker Added**`,
|
|
671
|
-
'',
|
|
672
|
-
`**#${blocker_task.task_number}: ${blocker_task.title}**`,
|
|
673
|
-
`↓ _blocks_ ↓`,
|
|
674
|
-
`**#${blocked_task.task_number}: ${blocked_task.title}**`,
|
|
675
|
-
'',
|
|
676
|
-
`The blocker task must be completed before work can begin on the blocked task.`,
|
|
677
|
-
'',
|
|
678
|
-
'---',
|
|
679
|
-
formatApiUsage(json.api_usage)
|
|
680
|
-
].join('\n');
|
|
681
|
-
return {
|
|
682
|
-
content: [{ type: "text", text: formatted }],
|
|
683
|
-
};
|
|
684
|
-
});
|
|
685
|
-
/**
|
|
686
|
-
* Remove Blocker
|
|
687
|
-
*/
|
|
688
|
-
server.tool("remove_blocker", "Remove a blocker dependency between tasks. Use this when a blocker is no longer relevant or was added in error.", {
|
|
689
|
-
taskID: zod_1.z.string().describe("The UUID of the blocked task"),
|
|
690
|
-
blockerTaskID: zod_1.z.string().describe("The UUID of the blocking task to remove"),
|
|
691
|
-
}, async ({ taskID, blockerTaskID }) => {
|
|
692
|
-
const json = await getResultsFromMiddleware({
|
|
693
|
-
endpoint: 'remove_blocker',
|
|
694
|
-
schema: { taskID, blockerTaskID }
|
|
695
|
-
});
|
|
696
|
-
const formatted = [
|
|
697
|
-
`✅ **Blocker Removed**`,
|
|
698
|
-
'',
|
|
699
|
-
`Task \`${taskID}\` is no longer blocked by \`${blockerTaskID}\``,
|
|
700
|
-
'',
|
|
701
|
-
'---',
|
|
702
|
-
formatApiUsage(json.api_usage)
|
|
703
|
-
].join('\n');
|
|
375
|
+
if (!json.data)
|
|
376
|
+
throw new Error('No data returned from middleware');
|
|
704
377
|
return {
|
|
705
|
-
content: [
|
|
378
|
+
content: [
|
|
379
|
+
{
|
|
380
|
+
type: "text",
|
|
381
|
+
text: JSON.stringify(json.data),
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
type: "text",
|
|
385
|
+
text: `API Usage: ${JSON.stringify(json.api_usage)}`,
|
|
386
|
+
}
|
|
387
|
+
],
|
|
706
388
|
};
|
|
707
389
|
});
|
|
708
|
-
//
|
|
709
|
-
// Start Server
|
|
710
|
-
// ============================================================================
|
|
390
|
+
// Start server
|
|
711
391
|
async function main() {
|
|
712
392
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
713
393
|
await server.connect(transport);
|