wolfpack-mcp 1.0.38 → 1.0.40
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/dist/client.js +62 -32
- package/dist/index.js +309 -89
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -9,6 +9,14 @@ export class WolfpackClient {
|
|
|
9
9
|
constructor() {
|
|
10
10
|
this.api = new ApiClient();
|
|
11
11
|
}
|
|
12
|
+
/** Build a URL path with optional teamSlug query parameter. */
|
|
13
|
+
withTeamSlug(path, teamSlug) {
|
|
14
|
+
const slug = teamSlug || this.projectSlug;
|
|
15
|
+
if (!slug)
|
|
16
|
+
return path;
|
|
17
|
+
const sep = path.includes('?') ? '&' : '?';
|
|
18
|
+
return `${path}${sep}teamSlug=${encodeURIComponent(slug)}`;
|
|
19
|
+
}
|
|
12
20
|
/**
|
|
13
21
|
* Fetch and cache the project slug by verifying it exists.
|
|
14
22
|
* Uses the MCP team endpoint to validate the slug.
|
|
@@ -156,11 +164,9 @@ export class WolfpackClient {
|
|
|
156
164
|
throw error;
|
|
157
165
|
}
|
|
158
166
|
}
|
|
159
|
-
async updateWorkProgress(workItemId, description) {
|
|
167
|
+
async updateWorkProgress(workItemId, description, teamSlug) {
|
|
160
168
|
try {
|
|
161
|
-
return await this.api.put(`/work-items/${workItemId}/progress`, {
|
|
162
|
-
description,
|
|
163
|
-
});
|
|
169
|
+
return await this.api.put(this.withTeamSlug(`/work-items/${workItemId}/progress`, teamSlug), { description });
|
|
164
170
|
}
|
|
165
171
|
catch (error) {
|
|
166
172
|
if (error && typeof error === 'object' && 'status' in error && error.status === 404) {
|
|
@@ -169,9 +175,9 @@ export class WolfpackClient {
|
|
|
169
175
|
throw error;
|
|
170
176
|
}
|
|
171
177
|
}
|
|
172
|
-
async updateWorkItemStatus(workItemId, status) {
|
|
178
|
+
async updateWorkItemStatus(workItemId, status, teamSlug) {
|
|
173
179
|
try {
|
|
174
|
-
return await this.api.put(`/work-items/${workItemId}/status`, { status });
|
|
180
|
+
return await this.api.put(this.withTeamSlug(`/work-items/${workItemId}/status`, teamSlug), { status });
|
|
175
181
|
}
|
|
176
182
|
catch (error) {
|
|
177
183
|
if (error && typeof error === 'object' && 'status' in error && error.status === 404) {
|
|
@@ -180,9 +186,9 @@ export class WolfpackClient {
|
|
|
180
186
|
throw error;
|
|
181
187
|
}
|
|
182
188
|
}
|
|
183
|
-
async updateWorkItemAssignee(workItemId, data) {
|
|
189
|
+
async updateWorkItemAssignee(workItemId, data, teamSlug) {
|
|
184
190
|
try {
|
|
185
|
-
return await this.api.put(`/work-items/${workItemId}/assignee`, data);
|
|
191
|
+
return await this.api.put(this.withTeamSlug(`/work-items/${workItemId}/assignee`, teamSlug), data);
|
|
186
192
|
}
|
|
187
193
|
catch (error) {
|
|
188
194
|
if (error && typeof error === 'object' && 'status' in error && error.status === 404) {
|
|
@@ -191,9 +197,9 @@ export class WolfpackClient {
|
|
|
191
197
|
throw error;
|
|
192
198
|
}
|
|
193
199
|
}
|
|
194
|
-
async updateWorkItemTitle(workItemId, title) {
|
|
200
|
+
async updateWorkItemTitle(workItemId, title, teamSlug) {
|
|
195
201
|
try {
|
|
196
|
-
return await this.api.put(`/work-items/${workItemId}/title`, { title });
|
|
202
|
+
return await this.api.put(this.withTeamSlug(`/work-items/${workItemId}/title`, teamSlug), { title });
|
|
197
203
|
}
|
|
198
204
|
catch (error) {
|
|
199
205
|
if (error && typeof error === 'object' && 'status' in error && error.status === 404) {
|
|
@@ -202,9 +208,9 @@ export class WolfpackClient {
|
|
|
202
208
|
throw error;
|
|
203
209
|
}
|
|
204
210
|
}
|
|
205
|
-
async updateWorkItemInitiative(workItemId, radarItemId) {
|
|
211
|
+
async updateWorkItemInitiative(workItemId, radarItemId, teamSlug) {
|
|
206
212
|
try {
|
|
207
|
-
return await this.api.put(`/work-items/${workItemId}/initiative`, { radarItemId });
|
|
213
|
+
return await this.api.put(this.withTeamSlug(`/work-items/${workItemId}/initiative`, teamSlug), { radarItemId });
|
|
208
214
|
}
|
|
209
215
|
catch (error) {
|
|
210
216
|
if (error && typeof error === 'object' && 'status' in error && error.status === 404) {
|
|
@@ -213,9 +219,9 @@ export class WolfpackClient {
|
|
|
213
219
|
throw error;
|
|
214
220
|
}
|
|
215
221
|
}
|
|
216
|
-
async pullWorkItem(workItemId, data) {
|
|
222
|
+
async pullWorkItem(workItemId, data, teamSlug) {
|
|
217
223
|
try {
|
|
218
|
-
return await this.api.post(`/work-items/${workItemId}/pull`, data || {});
|
|
224
|
+
return await this.api.post(this.withTeamSlug(`/work-items/${workItemId}/pull`, teamSlug), data || {});
|
|
219
225
|
}
|
|
220
226
|
catch (error) {
|
|
221
227
|
if (error && typeof error === 'object' && 'status' in error && error.status === 404) {
|
|
@@ -224,11 +230,9 @@ export class WolfpackClient {
|
|
|
224
230
|
throw error;
|
|
225
231
|
}
|
|
226
232
|
}
|
|
227
|
-
async submitWorkItemForm(workItemId, formValues) {
|
|
233
|
+
async submitWorkItemForm(workItemId, formValues, teamSlug) {
|
|
228
234
|
try {
|
|
229
|
-
return await this.api.put(`/work-items/${workItemId}/form`, {
|
|
230
|
-
formValues,
|
|
231
|
-
});
|
|
235
|
+
return await this.api.put(this.withTeamSlug(`/work-items/${workItemId}/form`, teamSlug), { formValues });
|
|
232
236
|
}
|
|
233
237
|
catch (error) {
|
|
234
238
|
if (error && typeof error === 'object' && 'status' in error && error.status === 404) {
|
|
@@ -348,8 +352,8 @@ export class WolfpackClient {
|
|
|
348
352
|
const { teamSlug, ...rest } = data;
|
|
349
353
|
return this.api.post('/issues', { ...rest, teamSlug });
|
|
350
354
|
}
|
|
351
|
-
async updateIssue(issueId, data) {
|
|
352
|
-
return this.api.patch(`/issues/${issueId}`, data);
|
|
355
|
+
async updateIssue(issueId, data, teamSlug) {
|
|
356
|
+
return this.api.patch(this.withTeamSlug(`/issues/${issueId}`, teamSlug), data);
|
|
353
357
|
}
|
|
354
358
|
// Wiki Page methods
|
|
355
359
|
async listWikiPages(options) {
|
|
@@ -397,8 +401,8 @@ export class WolfpackClient {
|
|
|
397
401
|
const { teamSlug, ...rest } = data;
|
|
398
402
|
return this.api.post('/wiki-pages', { ...rest, teamSlug });
|
|
399
403
|
}
|
|
400
|
-
async updateWikiPage(pageId, data) {
|
|
401
|
-
return this.api.patch(`/wiki-pages/${pageId}`, data);
|
|
404
|
+
async updateWikiPage(pageId, data, teamSlug) {
|
|
405
|
+
return this.api.patch(this.withTeamSlug(`/wiki-pages/${pageId}`, teamSlug), data);
|
|
402
406
|
}
|
|
403
407
|
// Journal Entry methods
|
|
404
408
|
async listJournalEntries(options) {
|
|
@@ -446,21 +450,21 @@ export class WolfpackClient {
|
|
|
446
450
|
const { teamSlug, ...rest } = data;
|
|
447
451
|
return this.api.post('/journal-entries', { ...rest, teamSlug });
|
|
448
452
|
}
|
|
449
|
-
async updateJournalEntry(entryId, data) {
|
|
450
|
-
return this.api.patch(`/journal-entries/${entryId}`, data);
|
|
453
|
+
async updateJournalEntry(entryId, data, teamSlug) {
|
|
454
|
+
return this.api.patch(this.withTeamSlug(`/journal-entries/${entryId}`, teamSlug), data);
|
|
451
455
|
}
|
|
452
456
|
// Comment methods
|
|
453
|
-
async listWorkItemComments(workItemId) {
|
|
454
|
-
return this.api.get(`/work-items/${workItemId}/comments
|
|
457
|
+
async listWorkItemComments(workItemId, teamSlug) {
|
|
458
|
+
return this.api.get(this.withTeamSlug(`/work-items/${workItemId}/comments`, teamSlug));
|
|
455
459
|
}
|
|
456
|
-
async listIssueComments(issueId) {
|
|
457
|
-
return this.api.get(`/issues/${issueId}/comments
|
|
460
|
+
async listIssueComments(issueId, teamSlug) {
|
|
461
|
+
return this.api.get(this.withTeamSlug(`/issues/${issueId}/comments`, teamSlug));
|
|
458
462
|
}
|
|
459
|
-
async createWorkItemComment(workItemId, data) {
|
|
460
|
-
return this.api.post(`/work-items/${workItemId}/comments`, data);
|
|
463
|
+
async createWorkItemComment(workItemId, data, teamSlug) {
|
|
464
|
+
return this.api.post(this.withTeamSlug(`/work-items/${workItemId}/comments`, teamSlug), data);
|
|
461
465
|
}
|
|
462
|
-
async createIssueComment(issueId, data) {
|
|
463
|
-
return this.api.post(`/issues/${issueId}/comments`, data);
|
|
466
|
+
async createIssueComment(issueId, data, teamSlug) {
|
|
467
|
+
return this.api.post(this.withTeamSlug(`/issues/${issueId}/comments`, teamSlug), data);
|
|
464
468
|
}
|
|
465
469
|
/**
|
|
466
470
|
* Upload an image and get back a URL that can be used in markdown content.
|
|
@@ -476,6 +480,32 @@ export class WolfpackClient {
|
|
|
476
480
|
const { buffer, contentType } = await this.api.getBuffer(`/images/${team}/${filename}`);
|
|
477
481
|
return { base64: buffer.toString('base64'), mimeType: contentType };
|
|
478
482
|
}
|
|
483
|
+
// Skill methods (progressive disclosure)
|
|
484
|
+
async listSkills() {
|
|
485
|
+
return this.api.get('/skills');
|
|
486
|
+
}
|
|
487
|
+
async getSkill(name) {
|
|
488
|
+
try {
|
|
489
|
+
return await this.api.get(`/skills/${encodeURIComponent(name)}`);
|
|
490
|
+
}
|
|
491
|
+
catch (error) {
|
|
492
|
+
if (error && typeof error === 'object' && 'status' in error && error.status === 404) {
|
|
493
|
+
return null;
|
|
494
|
+
}
|
|
495
|
+
throw error;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
async getSkillResource(skillName, resourceName) {
|
|
499
|
+
try {
|
|
500
|
+
return await this.api.get(`/skills/${encodeURIComponent(skillName)}/resources/${encodeURIComponent(resourceName)}`);
|
|
501
|
+
}
|
|
502
|
+
catch (error) {
|
|
503
|
+
if (error && typeof error === 'object' && 'status' in error && error.status === 404) {
|
|
504
|
+
return null;
|
|
505
|
+
}
|
|
506
|
+
throw error;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
479
509
|
close() {
|
|
480
510
|
// No cleanup needed for API client
|
|
481
511
|
}
|
package/dist/index.js
CHANGED
|
@@ -43,6 +43,12 @@ async function checkForUpdates() {
|
|
|
43
43
|
}
|
|
44
44
|
return null;
|
|
45
45
|
}
|
|
46
|
+
// Cross-reference syntax for linking between content items in markdown fields
|
|
47
|
+
const CONTENT_LINKING_HELP = 'CROSS-REFERENCES: In any markdown content, you can link to other items using these patterns: ' +
|
|
48
|
+
'#123 or #w123 for work items, #i123 for issues, #r123 for initiatives/roadmap, ' +
|
|
49
|
+
'#j123 for journal entries, #c123 for cases, #p123 for procedures. ' +
|
|
50
|
+
'Use @username to mention team members (triggers notifications). ' +
|
|
51
|
+
'Standard markdown links also work: [link text](/project/{slug}/work-items/123).';
|
|
46
52
|
// Work Item schemas
|
|
47
53
|
// Use z.coerce.string() to handle any type coercion issues from MCP args
|
|
48
54
|
const ListWorkItemsSchema = z.object({
|
|
@@ -84,12 +90,16 @@ const ListWorkItemsSchema = z.object({
|
|
|
84
90
|
offset: z.number().optional().describe('Number of items to skip'),
|
|
85
91
|
});
|
|
86
92
|
const GetWorkItemSchema = z.object({
|
|
87
|
-
work_item_id: z.string().describe('The
|
|
93
|
+
work_item_id: z.string().describe('The refId (number) of the work item'),
|
|
88
94
|
project_slug: z.string().optional().describe('Project slug (required when looking up by refId)'),
|
|
89
95
|
});
|
|
90
96
|
const UpdateWorkProgressSchema = z.object({
|
|
91
97
|
work_item_id: z.string().describe('The ID of the work item'),
|
|
92
98
|
description: z.string().describe('Updated description/notes for the work item'),
|
|
99
|
+
project_slug: z
|
|
100
|
+
.string()
|
|
101
|
+
.optional()
|
|
102
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
93
103
|
});
|
|
94
104
|
const VALID_STATUSES = [
|
|
95
105
|
'pending',
|
|
@@ -105,6 +115,10 @@ const VALID_STATUSES = [
|
|
|
105
115
|
const UpdateWorkItemStatusSchema = z.object({
|
|
106
116
|
work_item_id: z.string().describe('The ID of the work item'),
|
|
107
117
|
status: z.enum(VALID_STATUSES).describe('New status'),
|
|
118
|
+
project_slug: z
|
|
119
|
+
.string()
|
|
120
|
+
.optional()
|
|
121
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
108
122
|
});
|
|
109
123
|
const UpdateWorkItemAssigneeSchema = z.object({
|
|
110
124
|
work_item_id: z.string().describe('The ID of the work item'),
|
|
@@ -112,10 +126,18 @@ const UpdateWorkItemAssigneeSchema = z.object({
|
|
|
112
126
|
.string()
|
|
113
127
|
.nullable()
|
|
114
128
|
.describe('User ID to assign as leading user, or null to unassign'),
|
|
129
|
+
project_slug: z
|
|
130
|
+
.string()
|
|
131
|
+
.optional()
|
|
132
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
115
133
|
});
|
|
116
134
|
const UpdateWorkItemTitleSchema = z.object({
|
|
117
135
|
work_item_id: z.string().describe('The ID of the work item'),
|
|
118
136
|
title: z.string().describe('New title for the work item'),
|
|
137
|
+
project_slug: z
|
|
138
|
+
.string()
|
|
139
|
+
.optional()
|
|
140
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
119
141
|
});
|
|
120
142
|
const UpdateWorkItemInitiativeSchema = z.object({
|
|
121
143
|
work_item_id: z.string().describe('The ID of the work item'),
|
|
@@ -123,6 +145,10 @@ const UpdateWorkItemInitiativeSchema = z.object({
|
|
|
123
145
|
.string()
|
|
124
146
|
.nullable()
|
|
125
147
|
.describe('Radar/initiative item ID to link to, or null to unlink'),
|
|
148
|
+
project_slug: z
|
|
149
|
+
.string()
|
|
150
|
+
.optional()
|
|
151
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
126
152
|
});
|
|
127
153
|
const PullWorkItemSchema = z.object({
|
|
128
154
|
work_item_id: z.string().describe('The ID of the work item to pull from backlog'),
|
|
@@ -130,10 +156,18 @@ const PullWorkItemSchema = z.object({
|
|
|
130
156
|
.string()
|
|
131
157
|
.optional()
|
|
132
158
|
.describe('User ID to assign as leading user (defaults to API key owner)'),
|
|
159
|
+
project_slug: z
|
|
160
|
+
.string()
|
|
161
|
+
.optional()
|
|
162
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
133
163
|
});
|
|
134
164
|
const SubmitWorkItemFormSchema = z.object({
|
|
135
165
|
work_item_id: z.string().describe('The ID of the work item'),
|
|
136
166
|
form_values: z.record(z.any()).describe('Key-value pairs matching formDefinition field names'),
|
|
167
|
+
project_slug: z
|
|
168
|
+
.string()
|
|
169
|
+
.optional()
|
|
170
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
137
171
|
});
|
|
138
172
|
// Radar Item (Initiative/Roadmap) schemas
|
|
139
173
|
const ListRadarItemsSchema = z.object({
|
|
@@ -147,7 +181,7 @@ const ListRadarItemsSchema = z.object({
|
|
|
147
181
|
offset: z.number().optional().describe('Number of items to skip'),
|
|
148
182
|
});
|
|
149
183
|
const GetRadarItemSchema = z.object({
|
|
150
|
-
item_id: z.string().describe('The
|
|
184
|
+
item_id: z.string().describe('The refId (number) of the radar item'),
|
|
151
185
|
project_slug: z.string().optional().describe('Project slug (required when looking up by refId)'),
|
|
152
186
|
});
|
|
153
187
|
// Issue schemas
|
|
@@ -184,7 +218,7 @@ const ListIssuesSchema = z.object({
|
|
|
184
218
|
offset: z.number().optional().describe('Number of items to skip'),
|
|
185
219
|
});
|
|
186
220
|
const GetIssueSchema = z.object({
|
|
187
|
-
issue_id: z.string().describe('The
|
|
221
|
+
issue_id: z.string().describe('The refId (number) of the issue'),
|
|
188
222
|
project_slug: z.string().optional().describe('Project slug (required when looking up by refId)'),
|
|
189
223
|
});
|
|
190
224
|
// Create schemas
|
|
@@ -229,7 +263,7 @@ const CreateIssueSchema = z.object({
|
|
|
229
263
|
actual_behavior: z.string().optional().describe('Actual behavior observed'),
|
|
230
264
|
});
|
|
231
265
|
const UpdateIssueSchema = z.object({
|
|
232
|
-
issue_id: z.string().describe('The
|
|
266
|
+
issue_id: z.string().describe('The refId (number) of the issue to update'),
|
|
233
267
|
title: z.string().optional().describe('Updated title'),
|
|
234
268
|
description: z.string().optional().describe('Updated description'),
|
|
235
269
|
status: z
|
|
@@ -239,6 +273,10 @@ const UpdateIssueSchema = z.object({
|
|
|
239
273
|
severity: z.enum(['low', 'medium', 'high', 'critical']).optional().describe('Updated severity'),
|
|
240
274
|
assigned_to_id: z.string().optional().describe('Updated assignee'),
|
|
241
275
|
closing_note: z.string().optional().describe('Closing note (when closing the issue)'),
|
|
276
|
+
project_slug: z
|
|
277
|
+
.string()
|
|
278
|
+
.optional()
|
|
279
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
242
280
|
});
|
|
243
281
|
// Wiki Page schemas
|
|
244
282
|
const ListWikiPagesSchema = z.object({
|
|
@@ -256,7 +294,7 @@ const ListWikiPagesSchema = z.object({
|
|
|
256
294
|
offset: z.number().optional().describe('Number of pages to skip'),
|
|
257
295
|
});
|
|
258
296
|
const GetWikiPageSchema = z.object({
|
|
259
|
-
page_id: z.string().describe('The page
|
|
297
|
+
page_id: z.string().describe('The page slug'),
|
|
260
298
|
});
|
|
261
299
|
const CreateWikiPageSchema = z.object({
|
|
262
300
|
project_slug: z
|
|
@@ -275,9 +313,13 @@ const CreateWikiPageSchema = z.object({
|
|
|
275
313
|
content: z.string().describe('Page content (markdown)'),
|
|
276
314
|
});
|
|
277
315
|
const UpdateWikiPageSchema = z.object({
|
|
278
|
-
page_id: z.string().describe('The page
|
|
316
|
+
page_id: z.string().describe('The page slug'),
|
|
279
317
|
title: z.string().optional().describe('Updated title'),
|
|
280
318
|
content: z.string().optional().describe('Updated content (markdown)'),
|
|
319
|
+
project_slug: z
|
|
320
|
+
.string()
|
|
321
|
+
.optional()
|
|
322
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
281
323
|
});
|
|
282
324
|
// Journal Entry schemas
|
|
283
325
|
const ListJournalEntriesSchema = z.object({
|
|
@@ -295,8 +337,8 @@ const ListJournalEntriesSchema = z.object({
|
|
|
295
337
|
offset: z.number().optional().describe('Number of entries to skip'),
|
|
296
338
|
});
|
|
297
339
|
const GetJournalEntrySchema = z.object({
|
|
298
|
-
entry_id: z.string().describe('The entry
|
|
299
|
-
project_slug: z.string().optional().describe('Project slug (required
|
|
340
|
+
entry_id: z.string().describe('The entry refId (number)'),
|
|
341
|
+
project_slug: z.string().optional().describe('Project slug (required for refId lookup)'),
|
|
300
342
|
});
|
|
301
343
|
const CreateJournalEntrySchema = z.object({
|
|
302
344
|
project_slug: z
|
|
@@ -305,27 +347,46 @@ const CreateJournalEntrySchema = z.object({
|
|
|
305
347
|
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
306
348
|
title: z.string().describe('Entry title'),
|
|
307
349
|
content: z.string().describe('Entry content (markdown)'),
|
|
308
|
-
date: z.string().optional().describe('Entry date (ISO format, defaults to now)'),
|
|
309
350
|
});
|
|
310
351
|
const UpdateJournalEntrySchema = z.object({
|
|
311
|
-
entry_id: z.string().describe('The entry
|
|
352
|
+
entry_id: z.string().describe('The entry refId (number)'),
|
|
312
353
|
title: z.string().optional().describe('Updated title'),
|
|
313
354
|
content: z.string().optional().describe('Updated content (markdown)'),
|
|
355
|
+
project_slug: z
|
|
356
|
+
.string()
|
|
357
|
+
.optional()
|
|
358
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
314
359
|
});
|
|
315
360
|
// Comment schemas
|
|
316
361
|
const ListWorkItemCommentsSchema = z.object({
|
|
317
|
-
work_item_id: z.string().describe('The work item
|
|
362
|
+
work_item_id: z.string().describe('The work item refId (number)'),
|
|
363
|
+
project_slug: z
|
|
364
|
+
.string()
|
|
365
|
+
.optional()
|
|
366
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
318
367
|
});
|
|
319
368
|
const ListIssueCommentsSchema = z.object({
|
|
320
|
-
issue_id: z.string().describe('The issue
|
|
369
|
+
issue_id: z.string().describe('The issue refId (number)'),
|
|
370
|
+
project_slug: z
|
|
371
|
+
.string()
|
|
372
|
+
.optional()
|
|
373
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
321
374
|
});
|
|
322
375
|
const CreateWorkItemCommentSchema = z.object({
|
|
323
|
-
work_item_id: z.string().describe('The work item
|
|
376
|
+
work_item_id: z.string().describe('The work item refId (number)'),
|
|
324
377
|
content: z.string().describe('Comment content (markdown)'),
|
|
378
|
+
project_slug: z
|
|
379
|
+
.string()
|
|
380
|
+
.optional()
|
|
381
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
325
382
|
});
|
|
326
383
|
const CreateIssueCommentSchema = z.object({
|
|
327
|
-
issue_id: z.string().describe('The issue
|
|
384
|
+
issue_id: z.string().describe('The issue refId (number)'),
|
|
328
385
|
content: z.string().describe('Comment content (markdown)'),
|
|
386
|
+
project_slug: z
|
|
387
|
+
.string()
|
|
388
|
+
.optional()
|
|
389
|
+
.describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
|
|
329
390
|
});
|
|
330
391
|
// Image upload schema
|
|
331
392
|
const UploadImageSchema = z.object({
|
|
@@ -343,6 +404,54 @@ const DownloadImageSchema = z.object({
|
|
|
343
404
|
.string()
|
|
344
405
|
.describe('The image URL path found in content fields (e.g. "/api/files/images/{team}/{filename}").'),
|
|
345
406
|
});
|
|
407
|
+
// Skill schemas
|
|
408
|
+
const GetSkillSchema = z.object({
|
|
409
|
+
skill_name: z.string().describe('The name of the skill to load (e.g. "deploy-app")'),
|
|
410
|
+
});
|
|
411
|
+
const GetSkillResourceSchema = z.object({
|
|
412
|
+
skill_name: z.string().describe('The name of the skill'),
|
|
413
|
+
resource_name: z.string().describe('The name of the resource file'),
|
|
414
|
+
});
|
|
415
|
+
// UUID v4 field names to remove from responses.
|
|
416
|
+
// These are internal database IDs that agents should not use.
|
|
417
|
+
// Agents should use refId (sequential int) or slug instead.
|
|
418
|
+
const UUID_FIELDS_TO_STRIP = new Set([
|
|
419
|
+
'id', // Main entity UUID - replaced by refId or slug
|
|
420
|
+
'teamId', // Internal team UUID - noise for agents
|
|
421
|
+
'workItemId', // Cross-reference UUID on Issues - noise
|
|
422
|
+
]);
|
|
423
|
+
// Fields containing user-defined data that should never be recursively processed.
|
|
424
|
+
const PASSTHROUGH_FIELDS = new Set(['formDefinition', 'formValues']);
|
|
425
|
+
// Strip UUID v4 fields from response objects so agents use refId/slug instead.
|
|
426
|
+
// Preserves Clerk user IDs (user_xxx format) and operational fields (categoryId, radarItemId).
|
|
427
|
+
function stripUuids(obj) {
|
|
428
|
+
if (obj === null || obj === undefined)
|
|
429
|
+
return obj;
|
|
430
|
+
if (Array.isArray(obj))
|
|
431
|
+
return obj.map(stripUuids);
|
|
432
|
+
if (typeof obj !== 'object')
|
|
433
|
+
return obj;
|
|
434
|
+
const record = obj;
|
|
435
|
+
const result = {};
|
|
436
|
+
for (const [key, value] of Object.entries(record)) {
|
|
437
|
+
// Skip UUID fields
|
|
438
|
+
if (UUID_FIELDS_TO_STRIP.has(key))
|
|
439
|
+
continue;
|
|
440
|
+
// Preserve user-defined data fields as-is (no recursive stripping)
|
|
441
|
+
if (PASSTHROUGH_FIELDS.has(key)) {
|
|
442
|
+
result[key] = value;
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
// Recurse into nested objects/arrays
|
|
446
|
+
if (typeof value === 'object' && value !== null) {
|
|
447
|
+
result[key] = stripUuids(value);
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
result[key] = value;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return result;
|
|
454
|
+
}
|
|
346
455
|
// Helper to detect if a work item description contains a plan
|
|
347
456
|
function hasPlan(description) {
|
|
348
457
|
if (!description)
|
|
@@ -458,7 +567,7 @@ class WolfpackMCPServer {
|
|
|
458
567
|
},
|
|
459
568
|
{
|
|
460
569
|
name: 'get_work_item',
|
|
461
|
-
description: 'Get a specific work item/task by
|
|
570
|
+
description: 'Get a specific work item/task by reference number. Returns full details including description (markdown notes). ' +
|
|
462
571
|
'Call this before updating to see current content. ' +
|
|
463
572
|
'WORKFLOW: When asked to work on an item, check its status and follow the required state transitions ' +
|
|
464
573
|
'(pending→pull first, new→doing, blocked/ready/completed/closed→new→doing, then review when done). ' +
|
|
@@ -470,11 +579,11 @@ class WolfpackMCPServer {
|
|
|
470
579
|
properties: {
|
|
471
580
|
work_item_id: {
|
|
472
581
|
type: 'string',
|
|
473
|
-
description: 'The
|
|
582
|
+
description: 'The refId (number) of the work item',
|
|
474
583
|
},
|
|
475
584
|
project_slug: {
|
|
476
585
|
type: 'string',
|
|
477
|
-
description: 'Project slug (required
|
|
586
|
+
description: 'Project slug (required for refId lookup)',
|
|
478
587
|
},
|
|
479
588
|
},
|
|
480
589
|
required: ['work_item_id'],
|
|
@@ -484,7 +593,8 @@ class WolfpackMCPServer {
|
|
|
484
593
|
name: 'update_work_progress',
|
|
485
594
|
description: 'Update work item description/notes with your progress. WORKFLOW: 1) get_work_item to read current notes 2) Modify the markdown description with new findings/progress 3) Call this with the complete updated description. The full description replaces the existing one. ' +
|
|
486
595
|
'CRITICAL: NEVER overwrite or remove the original description text. Preserve all existing content exactly as-is. Append your plan below a "---" separator. You may only modify content you previously added (your plan section). ' +
|
|
487
|
-
'BEST PRACTICE: Append a plan with markdown checkboxes (- [ ] task). Check off completed tasks (- [x] task) as you progress. Include sections for: Plan (checklist), Approach (strategy), and Notes (discoveries/decisions).'
|
|
596
|
+
'BEST PRACTICE: Append a plan with markdown checkboxes (- [ ] task). Check off completed tasks (- [x] task) as you progress. Include sections for: Plan (checklist), Approach (strategy), and Notes (discoveries/decisions). ' +
|
|
597
|
+
CONTENT_LINKING_HELP,
|
|
488
598
|
inputSchema: {
|
|
489
599
|
type: 'object',
|
|
490
600
|
properties: {
|
|
@@ -662,18 +772,18 @@ class WolfpackMCPServer {
|
|
|
662
772
|
},
|
|
663
773
|
{
|
|
664
774
|
name: 'get_radar_item',
|
|
665
|
-
description: 'Get a specific radar item (initiative) by
|
|
775
|
+
description: 'Get a specific radar item (initiative) by reference number, including its work items and participants. ' +
|
|
666
776
|
'IMAGES: Image references in the description (e.g. ``) can be viewed using the download_image tool.',
|
|
667
777
|
inputSchema: {
|
|
668
778
|
type: 'object',
|
|
669
779
|
properties: {
|
|
670
780
|
item_id: {
|
|
671
781
|
type: 'string',
|
|
672
|
-
description: 'The
|
|
782
|
+
description: 'The refId (number) of the radar item',
|
|
673
783
|
},
|
|
674
784
|
project_slug: {
|
|
675
785
|
type: 'string',
|
|
676
|
-
description: 'Project slug (required
|
|
786
|
+
description: 'Project slug (required for refId lookup)',
|
|
677
787
|
},
|
|
678
788
|
},
|
|
679
789
|
required: ['item_id'],
|
|
@@ -740,18 +850,18 @@ class WolfpackMCPServer {
|
|
|
740
850
|
},
|
|
741
851
|
{
|
|
742
852
|
name: 'get_issue',
|
|
743
|
-
description: 'Get a specific issue by
|
|
853
|
+
description: 'Get a specific issue by reference number, including comment and attachment counts. ' +
|
|
744
854
|
'IMAGES: Image references in the description (e.g. ``) can be viewed using the download_image tool.',
|
|
745
855
|
inputSchema: {
|
|
746
856
|
type: 'object',
|
|
747
857
|
properties: {
|
|
748
858
|
issue_id: {
|
|
749
859
|
type: 'string',
|
|
750
|
-
description: 'The
|
|
860
|
+
description: 'The refId (number) of the issue',
|
|
751
861
|
},
|
|
752
862
|
project_slug: {
|
|
753
863
|
type: 'string',
|
|
754
|
-
description: 'Project slug (required
|
|
864
|
+
description: 'Project slug (required for refId lookup)',
|
|
755
865
|
},
|
|
756
866
|
},
|
|
757
867
|
required: ['issue_id'],
|
|
@@ -760,7 +870,8 @@ class WolfpackMCPServer {
|
|
|
760
870
|
// Create/Update tools
|
|
761
871
|
{
|
|
762
872
|
name: 'create_work_item',
|
|
763
|
-
description: 'Create a new work item in your current project (auto-selected for single-project users, or use list_projects first for multi-project). Requires mcp:work_items:create permission.'
|
|
873
|
+
description: 'Create a new work item in your current project (auto-selected for single-project users, or use list_projects first for multi-project). Requires mcp:work_items:create permission. ' +
|
|
874
|
+
CONTENT_LINKING_HELP,
|
|
764
875
|
inputSchema: {
|
|
765
876
|
type: 'object',
|
|
766
877
|
properties: {
|
|
@@ -815,7 +926,8 @@ class WolfpackMCPServer {
|
|
|
815
926
|
},
|
|
816
927
|
{
|
|
817
928
|
name: 'create_issue',
|
|
818
|
-
description: 'Create a new issue in your current project (auto-selected for single-project users, or use list_projects first for multi-project). Requires mcp:issues:create permission.'
|
|
929
|
+
description: 'Create a new issue in your current project (auto-selected for single-project users, or use list_projects first for multi-project). Requires mcp:issues:create permission. ' +
|
|
930
|
+
CONTENT_LINKING_HELP,
|
|
819
931
|
inputSchema: {
|
|
820
932
|
type: 'object',
|
|
821
933
|
properties: {
|
|
@@ -848,11 +960,15 @@ class WolfpackMCPServer {
|
|
|
848
960
|
},
|
|
849
961
|
{
|
|
850
962
|
name: 'update_issue',
|
|
851
|
-
description: 'Update an existing issue. Requires mcp:issues:update permission.'
|
|
963
|
+
description: 'Update an existing issue. Requires mcp:issues:update permission. ' +
|
|
964
|
+
CONTENT_LINKING_HELP,
|
|
852
965
|
inputSchema: {
|
|
853
966
|
type: 'object',
|
|
854
967
|
properties: {
|
|
855
|
-
issue_id: {
|
|
968
|
+
issue_id: {
|
|
969
|
+
type: 'string',
|
|
970
|
+
description: 'The refId (number) of the issue to update',
|
|
971
|
+
},
|
|
856
972
|
title: { type: 'string', description: 'Updated title' },
|
|
857
973
|
description: { type: 'string', description: 'Updated description' },
|
|
858
974
|
status: {
|
|
@@ -904,14 +1020,14 @@ class WolfpackMCPServer {
|
|
|
904
1020
|
},
|
|
905
1021
|
{
|
|
906
1022
|
name: 'get_wiki_page',
|
|
907
|
-
description: 'Get a specific wiki/documentation page by
|
|
1023
|
+
description: 'Get a specific wiki/documentation page by slug (URL path). Returns full content in markdown. ' +
|
|
908
1024
|
'IMAGES: Image references in the content (e.g. ``) can be viewed using the download_image tool.',
|
|
909
1025
|
inputSchema: {
|
|
910
1026
|
type: 'object',
|
|
911
1027
|
properties: {
|
|
912
1028
|
page_id: {
|
|
913
1029
|
type: 'string',
|
|
914
|
-
description: 'The page
|
|
1030
|
+
description: 'The page slug (URL path like "getting-started")',
|
|
915
1031
|
},
|
|
916
1032
|
},
|
|
917
1033
|
required: ['page_id'],
|
|
@@ -919,7 +1035,8 @@ class WolfpackMCPServer {
|
|
|
919
1035
|
},
|
|
920
1036
|
{
|
|
921
1037
|
name: 'create_wiki_page',
|
|
922
|
-
description: 'Create a new wiki/documentation page. Use when user wants to "add docs", "create documentation", or "write a guide".'
|
|
1038
|
+
description: 'Create a new wiki/documentation page. Use when user wants to "add docs", "create documentation", or "write a guide". ' +
|
|
1039
|
+
CONTENT_LINKING_HELP,
|
|
923
1040
|
inputSchema: {
|
|
924
1041
|
type: 'object',
|
|
925
1042
|
properties: {
|
|
@@ -942,11 +1059,12 @@ class WolfpackMCPServer {
|
|
|
942
1059
|
},
|
|
943
1060
|
{
|
|
944
1061
|
name: 'update_wiki_page',
|
|
945
|
-
description: 'Update an existing wiki page. Requires mcp:wiki:update permission.'
|
|
1062
|
+
description: 'Update an existing wiki page. Requires mcp:wiki:update permission. ' +
|
|
1063
|
+
CONTENT_LINKING_HELP,
|
|
946
1064
|
inputSchema: {
|
|
947
1065
|
type: 'object',
|
|
948
1066
|
properties: {
|
|
949
|
-
page_id: { type: 'string', description: 'The page
|
|
1067
|
+
page_id: { type: 'string', description: 'The page slug' },
|
|
950
1068
|
title: { type: 'string', description: 'Updated title' },
|
|
951
1069
|
content: {
|
|
952
1070
|
type: 'string',
|
|
@@ -986,15 +1104,15 @@ class WolfpackMCPServer {
|
|
|
986
1104
|
},
|
|
987
1105
|
{
|
|
988
1106
|
name: 'get_journal_entry',
|
|
989
|
-
description: 'Get a specific journal/log entry by
|
|
1107
|
+
description: 'Get a specific journal/log entry by reference number. Returns full content. ' +
|
|
990
1108
|
'IMAGES: Image references in the content (e.g. ``) can be viewed using the download_image tool.',
|
|
991
1109
|
inputSchema: {
|
|
992
1110
|
type: 'object',
|
|
993
1111
|
properties: {
|
|
994
|
-
entry_id: { type: 'string', description: 'The entry
|
|
1112
|
+
entry_id: { type: 'string', description: 'The entry refId (number)' },
|
|
995
1113
|
project_slug: {
|
|
996
1114
|
type: 'string',
|
|
997
|
-
description: 'Project slug (required
|
|
1115
|
+
description: 'Project slug (required for refId lookup)',
|
|
998
1116
|
},
|
|
999
1117
|
},
|
|
1000
1118
|
required: ['entry_id'],
|
|
@@ -1002,7 +1120,8 @@ class WolfpackMCPServer {
|
|
|
1002
1120
|
},
|
|
1003
1121
|
{
|
|
1004
1122
|
name: 'create_journal_entry',
|
|
1005
|
-
description: 'Create a new journal entry (daily log, standup note, progress update). Use when user wants to "log progress", "write a standup", "add a journal entry", or "record what I did".'
|
|
1123
|
+
description: 'Create a new journal entry (daily log, standup note, progress update). Use when user wants to "log progress", "write a standup", "add a journal entry", or "record what I did". ' +
|
|
1124
|
+
CONTENT_LINKING_HELP,
|
|
1006
1125
|
inputSchema: {
|
|
1007
1126
|
type: 'object',
|
|
1008
1127
|
properties: {
|
|
@@ -1015,18 +1134,18 @@ class WolfpackMCPServer {
|
|
|
1015
1134
|
type: 'string',
|
|
1016
1135
|
description: 'Entry content (markdown)',
|
|
1017
1136
|
},
|
|
1018
|
-
date: { type: 'string', description: 'Entry date (ISO format, defaults to now)' },
|
|
1019
1137
|
},
|
|
1020
1138
|
required: ['title', 'content'],
|
|
1021
1139
|
},
|
|
1022
1140
|
},
|
|
1023
1141
|
{
|
|
1024
1142
|
name: 'update_journal_entry',
|
|
1025
|
-
description: 'Update an existing journal entry. Requires mcp:journal:update permission.'
|
|
1143
|
+
description: 'Update an existing journal entry. Requires mcp:journal:update permission. ' +
|
|
1144
|
+
CONTENT_LINKING_HELP,
|
|
1026
1145
|
inputSchema: {
|
|
1027
1146
|
type: 'object',
|
|
1028
1147
|
properties: {
|
|
1029
|
-
entry_id: { type: 'string', description: 'The entry
|
|
1148
|
+
entry_id: { type: 'string', description: 'The entry refId (number)' },
|
|
1030
1149
|
title: { type: 'string', description: 'Updated title' },
|
|
1031
1150
|
content: {
|
|
1032
1151
|
type: 'string',
|
|
@@ -1044,7 +1163,7 @@ class WolfpackMCPServer {
|
|
|
1044
1163
|
inputSchema: {
|
|
1045
1164
|
type: 'object',
|
|
1046
1165
|
properties: {
|
|
1047
|
-
work_item_id: { type: 'string', description: 'The work item
|
|
1166
|
+
work_item_id: { type: 'string', description: 'The work item refId (number)' },
|
|
1048
1167
|
},
|
|
1049
1168
|
required: ['work_item_id'],
|
|
1050
1169
|
},
|
|
@@ -1056,7 +1175,7 @@ class WolfpackMCPServer {
|
|
|
1056
1175
|
inputSchema: {
|
|
1057
1176
|
type: 'object',
|
|
1058
1177
|
properties: {
|
|
1059
|
-
issue_id: { type: 'string', description: 'The issue
|
|
1178
|
+
issue_id: { type: 'string', description: 'The issue refId (number)' },
|
|
1060
1179
|
},
|
|
1061
1180
|
required: ['issue_id'],
|
|
1062
1181
|
},
|
|
@@ -1068,11 +1187,12 @@ class WolfpackMCPServer {
|
|
|
1068
1187
|
'2) Completion summaries when moving to "review" (what was done, files changed, testing notes). ' +
|
|
1069
1188
|
'3) Important observations or decisions that should be visible in the activity history. ' +
|
|
1070
1189
|
'USE DESCRIPTION (update_work_progress) FOR: Plans, checklists, and progress tracking that need to be updated over time. ' +
|
|
1071
|
-
'Comments are typically not used in personal projects.'
|
|
1190
|
+
'Comments are typically not used in personal projects. ' +
|
|
1191
|
+
CONTENT_LINKING_HELP,
|
|
1072
1192
|
inputSchema: {
|
|
1073
1193
|
type: 'object',
|
|
1074
1194
|
properties: {
|
|
1075
|
-
work_item_id: { type: 'string', description: 'The work item
|
|
1195
|
+
work_item_id: { type: 'string', description: 'The work item refId (number)' },
|
|
1076
1196
|
content: {
|
|
1077
1197
|
type: 'string',
|
|
1078
1198
|
description: 'Comment content (markdown)',
|
|
@@ -1083,11 +1203,12 @@ class WolfpackMCPServer {
|
|
|
1083
1203
|
},
|
|
1084
1204
|
{
|
|
1085
1205
|
name: 'create_issue_comment',
|
|
1086
|
-
description: 'Add a comment to an issue. Requires mcp:comments:create permission.'
|
|
1206
|
+
description: 'Add a comment to an issue. Requires mcp:comments:create permission. ' +
|
|
1207
|
+
CONTENT_LINKING_HELP,
|
|
1087
1208
|
inputSchema: {
|
|
1088
1209
|
type: 'object',
|
|
1089
1210
|
properties: {
|
|
1090
|
-
issue_id: { type: 'string', description: 'The issue
|
|
1211
|
+
issue_id: { type: 'string', description: 'The issue refId (number)' },
|
|
1091
1212
|
content: {
|
|
1092
1213
|
type: 'string',
|
|
1093
1214
|
description: 'Comment content (markdown)',
|
|
@@ -1138,6 +1259,51 @@ class WolfpackMCPServer {
|
|
|
1138
1259
|
required: ['image_url'],
|
|
1139
1260
|
},
|
|
1140
1261
|
},
|
|
1262
|
+
// Skill tools (progressive disclosure)
|
|
1263
|
+
{
|
|
1264
|
+
name: 'list_skills',
|
|
1265
|
+
description: 'List all skills available to the current agent. Returns lean metadata (name + description) for each skill. ' +
|
|
1266
|
+
'Use get_skill to load the full instructions for a specific skill when needed.',
|
|
1267
|
+
inputSchema: {
|
|
1268
|
+
type: 'object',
|
|
1269
|
+
properties: {},
|
|
1270
|
+
},
|
|
1271
|
+
},
|
|
1272
|
+
{
|
|
1273
|
+
name: 'get_skill',
|
|
1274
|
+
description: 'Load the full instruction content for a specific skill by name. ' +
|
|
1275
|
+
"Call this when a task matches a skill's description to get detailed instructions before proceeding. " +
|
|
1276
|
+
'Also returns a list of available resources (scripts, references, assets).',
|
|
1277
|
+
inputSchema: {
|
|
1278
|
+
type: 'object',
|
|
1279
|
+
properties: {
|
|
1280
|
+
skill_name: {
|
|
1281
|
+
type: 'string',
|
|
1282
|
+
description: 'The name of the skill to load (e.g. "deploy-app")',
|
|
1283
|
+
},
|
|
1284
|
+
},
|
|
1285
|
+
required: ['skill_name'],
|
|
1286
|
+
},
|
|
1287
|
+
},
|
|
1288
|
+
{
|
|
1289
|
+
name: 'get_skill_resource',
|
|
1290
|
+
description: 'Get a specific resource file attached to a skill. ' +
|
|
1291
|
+
'Resources can be scripts, reference documents, or assets that supplement the skill instructions.',
|
|
1292
|
+
inputSchema: {
|
|
1293
|
+
type: 'object',
|
|
1294
|
+
properties: {
|
|
1295
|
+
skill_name: {
|
|
1296
|
+
type: 'string',
|
|
1297
|
+
description: 'The name of the skill',
|
|
1298
|
+
},
|
|
1299
|
+
resource_name: {
|
|
1300
|
+
type: 'string',
|
|
1301
|
+
description: 'The name of the resource file',
|
|
1302
|
+
},
|
|
1303
|
+
},
|
|
1304
|
+
required: ['skill_name', 'resource_name'],
|
|
1305
|
+
},
|
|
1306
|
+
},
|
|
1141
1307
|
],
|
|
1142
1308
|
}));
|
|
1143
1309
|
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
@@ -1183,7 +1349,7 @@ class WolfpackMCPServer {
|
|
|
1183
1349
|
limit: parsed.limit,
|
|
1184
1350
|
offset: parsed.offset,
|
|
1185
1351
|
});
|
|
1186
|
-
let text = JSON.stringify(result.items, null, 2);
|
|
1352
|
+
let text = JSON.stringify(stripUuids(result.items), null, 2);
|
|
1187
1353
|
if (result.truncated) {
|
|
1188
1354
|
text = `Note: Results truncated. Showing ${result.items.length} of ${result.total} items. Use filters or limit/offset for pagination.\n\n${text}`;
|
|
1189
1355
|
}
|
|
@@ -1195,7 +1361,7 @@ class WolfpackMCPServer {
|
|
|
1195
1361
|
const parsed = GetWorkItemSchema.parse(args);
|
|
1196
1362
|
const workItem = await this.client.getWorkItem(parsed.work_item_id, parsed.project_slug || this.client.getProjectSlug() || undefined);
|
|
1197
1363
|
if (workItem) {
|
|
1198
|
-
let text = JSON.stringify(workItem, null, 2);
|
|
1364
|
+
let text = JSON.stringify(stripUuids(workItem), null, 2);
|
|
1199
1365
|
// Add hint if no plan detected in description
|
|
1200
1366
|
if (!hasPlan(workItem.description)) {
|
|
1201
1367
|
text =
|
|
@@ -1212,13 +1378,14 @@ class WolfpackMCPServer {
|
|
|
1212
1378
|
}
|
|
1213
1379
|
case 'update_work_progress': {
|
|
1214
1380
|
const parsed = UpdateWorkProgressSchema.parse(args);
|
|
1215
|
-
const
|
|
1381
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1382
|
+
const workItem = await this.client.updateWorkProgress(parsed.work_item_id, parsed.description, teamSlug);
|
|
1216
1383
|
if (workItem) {
|
|
1217
1384
|
return {
|
|
1218
1385
|
content: [
|
|
1219
1386
|
{
|
|
1220
1387
|
type: 'text',
|
|
1221
|
-
text: `Updated description on: ${workItem.title}\n\n${JSON.stringify(workItem, null, 2)}`,
|
|
1388
|
+
text: `Updated description on: ${workItem.title}\n\n${JSON.stringify(stripUuids(workItem), null, 2)}`,
|
|
1222
1389
|
},
|
|
1223
1390
|
],
|
|
1224
1391
|
};
|
|
@@ -1229,13 +1396,14 @@ class WolfpackMCPServer {
|
|
|
1229
1396
|
}
|
|
1230
1397
|
case 'update_work_item_status': {
|
|
1231
1398
|
const parsed = UpdateWorkItemStatusSchema.parse(args);
|
|
1232
|
-
const
|
|
1399
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1400
|
+
const workItem = await this.client.updateWorkItemStatus(parsed.work_item_id, parsed.status, teamSlug);
|
|
1233
1401
|
if (workItem) {
|
|
1234
1402
|
return {
|
|
1235
1403
|
content: [
|
|
1236
1404
|
{
|
|
1237
1405
|
type: 'text',
|
|
1238
|
-
text: `Updated status of "${workItem.title}" to ${parsed.status}\n\n${JSON.stringify(workItem, null, 2)}`,
|
|
1406
|
+
text: `Updated status of "${workItem.title}" to ${parsed.status}\n\n${JSON.stringify(stripUuids(workItem), null, 2)}`,
|
|
1239
1407
|
},
|
|
1240
1408
|
],
|
|
1241
1409
|
};
|
|
@@ -1246,9 +1414,10 @@ class WolfpackMCPServer {
|
|
|
1246
1414
|
}
|
|
1247
1415
|
case 'update_work_item_assignee': {
|
|
1248
1416
|
const parsed = UpdateWorkItemAssigneeSchema.parse(args);
|
|
1417
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1249
1418
|
const workItem = await this.client.updateWorkItemAssignee(parsed.work_item_id, {
|
|
1250
1419
|
leadingUserId: parsed.leading_user_id,
|
|
1251
|
-
});
|
|
1420
|
+
}, teamSlug);
|
|
1252
1421
|
if (workItem) {
|
|
1253
1422
|
const assigneeText = parsed.leading_user_id
|
|
1254
1423
|
? `assigned to ${parsed.leading_user_id}`
|
|
@@ -1257,7 +1426,7 @@ class WolfpackMCPServer {
|
|
|
1257
1426
|
content: [
|
|
1258
1427
|
{
|
|
1259
1428
|
type: 'text',
|
|
1260
|
-
text: `Updated "${workItem.title}" - now ${assigneeText}\n\n${JSON.stringify(workItem, null, 2)}`,
|
|
1429
|
+
text: `Updated "${workItem.title}" - now ${assigneeText}\n\n${JSON.stringify(stripUuids(workItem), null, 2)}`,
|
|
1261
1430
|
},
|
|
1262
1431
|
],
|
|
1263
1432
|
};
|
|
@@ -1268,13 +1437,14 @@ class WolfpackMCPServer {
|
|
|
1268
1437
|
}
|
|
1269
1438
|
case 'update_work_item_title': {
|
|
1270
1439
|
const parsed = UpdateWorkItemTitleSchema.parse(args);
|
|
1271
|
-
const
|
|
1440
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1441
|
+
const workItem = await this.client.updateWorkItemTitle(parsed.work_item_id, parsed.title, teamSlug);
|
|
1272
1442
|
if (workItem) {
|
|
1273
1443
|
return {
|
|
1274
1444
|
content: [
|
|
1275
1445
|
{
|
|
1276
1446
|
type: 'text',
|
|
1277
|
-
text: `Updated title to "${workItem.title}"\n\n${JSON.stringify(workItem, null, 2)}`,
|
|
1447
|
+
text: `Updated title to "${workItem.title}"\n\n${JSON.stringify(stripUuids(workItem), null, 2)}`,
|
|
1278
1448
|
},
|
|
1279
1449
|
],
|
|
1280
1450
|
};
|
|
@@ -1285,7 +1455,8 @@ class WolfpackMCPServer {
|
|
|
1285
1455
|
}
|
|
1286
1456
|
case 'update_work_item_initiative': {
|
|
1287
1457
|
const parsed = UpdateWorkItemInitiativeSchema.parse(args);
|
|
1288
|
-
const
|
|
1458
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1459
|
+
const workItem = await this.client.updateWorkItemInitiative(parsed.work_item_id, parsed.radar_item_id, teamSlug);
|
|
1289
1460
|
if (workItem) {
|
|
1290
1461
|
const initiativeText = parsed.radar_item_id
|
|
1291
1462
|
? `linked to initiative ${parsed.radar_item_id}`
|
|
@@ -1294,7 +1465,7 @@ class WolfpackMCPServer {
|
|
|
1294
1465
|
content: [
|
|
1295
1466
|
{
|
|
1296
1467
|
type: 'text',
|
|
1297
|
-
text: `Updated "${workItem.title}" - ${initiativeText}\n\n${JSON.stringify(workItem, null, 2)}`,
|
|
1468
|
+
text: `Updated "${workItem.title}" - ${initiativeText}\n\n${JSON.stringify(stripUuids(workItem), null, 2)}`,
|
|
1298
1469
|
},
|
|
1299
1470
|
],
|
|
1300
1471
|
};
|
|
@@ -1305,15 +1476,16 @@ class WolfpackMCPServer {
|
|
|
1305
1476
|
}
|
|
1306
1477
|
case 'pull_work_item': {
|
|
1307
1478
|
const parsed = PullWorkItemSchema.parse(args);
|
|
1479
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1308
1480
|
const workItem = await this.client.pullWorkItem(parsed.work_item_id, {
|
|
1309
1481
|
leadingUserId: parsed.leading_user_id,
|
|
1310
|
-
});
|
|
1482
|
+
}, teamSlug);
|
|
1311
1483
|
if (workItem) {
|
|
1312
1484
|
return {
|
|
1313
1485
|
content: [
|
|
1314
1486
|
{
|
|
1315
1487
|
type: 'text',
|
|
1316
|
-
text: `Pulled "${workItem.title}" from backlog to board (status: new)\n\n${JSON.stringify(workItem, null, 2)}`,
|
|
1488
|
+
text: `Pulled "${workItem.title}" from backlog to board (status: new)\n\n${JSON.stringify(stripUuids(workItem), null, 2)}`,
|
|
1317
1489
|
},
|
|
1318
1490
|
],
|
|
1319
1491
|
};
|
|
@@ -1324,13 +1496,14 @@ class WolfpackMCPServer {
|
|
|
1324
1496
|
}
|
|
1325
1497
|
case 'submit_work_item_form': {
|
|
1326
1498
|
const parsed = SubmitWorkItemFormSchema.parse(args);
|
|
1327
|
-
const
|
|
1499
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1500
|
+
const workItem = await this.client.submitWorkItemForm(parsed.work_item_id, parsed.form_values, teamSlug);
|
|
1328
1501
|
if (workItem) {
|
|
1329
1502
|
return {
|
|
1330
1503
|
content: [
|
|
1331
1504
|
{
|
|
1332
1505
|
type: 'text',
|
|
1333
|
-
text: `Submitted form values for "${workItem.title}"\n\n${JSON.stringify(workItem, null, 2)}`,
|
|
1506
|
+
text: `Submitted form values for "${workItem.title}"\n\n${JSON.stringify(stripUuids(workItem), null, 2)}`,
|
|
1334
1507
|
},
|
|
1335
1508
|
],
|
|
1336
1509
|
};
|
|
@@ -1349,7 +1522,7 @@ class WolfpackMCPServer {
|
|
|
1349
1522
|
limit: parsed.limit,
|
|
1350
1523
|
offset: parsed.offset,
|
|
1351
1524
|
});
|
|
1352
|
-
let text = JSON.stringify(result.items, null, 2);
|
|
1525
|
+
let text = JSON.stringify(stripUuids(result.items), null, 2);
|
|
1353
1526
|
if (result.truncated) {
|
|
1354
1527
|
text = `Note: Results truncated. Showing ${result.items.length} of ${result.total} items. Use stage filter or limit/offset for pagination.\n\n${text}`;
|
|
1355
1528
|
}
|
|
@@ -1362,7 +1535,7 @@ class WolfpackMCPServer {
|
|
|
1362
1535
|
const radarItem = await this.client.getRadarItem(parsed.item_id, parsed.project_slug);
|
|
1363
1536
|
if (radarItem) {
|
|
1364
1537
|
return {
|
|
1365
|
-
content: [{ type: 'text', text: JSON.stringify(radarItem, null, 2) }],
|
|
1538
|
+
content: [{ type: 'text', text: JSON.stringify(stripUuids(radarItem), null, 2) }],
|
|
1366
1539
|
};
|
|
1367
1540
|
}
|
|
1368
1541
|
return {
|
|
@@ -1386,7 +1559,7 @@ class WolfpackMCPServer {
|
|
|
1386
1559
|
limit: parsed.limit,
|
|
1387
1560
|
offset: parsed.offset,
|
|
1388
1561
|
});
|
|
1389
|
-
let text = JSON.stringify(result.items, null, 2);
|
|
1562
|
+
let text = JSON.stringify(stripUuids(result.items), null, 2);
|
|
1390
1563
|
if (result.truncated) {
|
|
1391
1564
|
text = `Note: Results truncated. Showing ${result.items.length} of ${result.total} items. Use filters or limit/offset for pagination.\n\n${text}`;
|
|
1392
1565
|
}
|
|
@@ -1399,7 +1572,7 @@ class WolfpackMCPServer {
|
|
|
1399
1572
|
const issue = await this.client.getIssue(parsed.issue_id, parsed.project_slug);
|
|
1400
1573
|
if (issue) {
|
|
1401
1574
|
return {
|
|
1402
|
-
content: [{ type: 'text', text: JSON.stringify(issue, null, 2) }],
|
|
1575
|
+
content: [{ type: 'text', text: JSON.stringify(stripUuids(issue), null, 2) }],
|
|
1403
1576
|
};
|
|
1404
1577
|
}
|
|
1405
1578
|
return {
|
|
@@ -1424,7 +1597,7 @@ class WolfpackMCPServer {
|
|
|
1424
1597
|
content: [
|
|
1425
1598
|
{
|
|
1426
1599
|
type: 'text',
|
|
1427
|
-
text: `Created work item #${workItem.refId}: ${workItem.title}\n\n${JSON.stringify(workItem, null, 2)}`,
|
|
1600
|
+
text: `Created work item #${workItem.refId}: ${workItem.title}\n\n${JSON.stringify(stripUuids(workItem), null, 2)}`,
|
|
1428
1601
|
},
|
|
1429
1602
|
],
|
|
1430
1603
|
};
|
|
@@ -1449,13 +1622,14 @@ class WolfpackMCPServer {
|
|
|
1449
1622
|
content: [
|
|
1450
1623
|
{
|
|
1451
1624
|
type: 'text',
|
|
1452
|
-
text: `Created issue #${issue.refId}: ${issue.title}\n\n${JSON.stringify(issue, null, 2)}`,
|
|
1625
|
+
text: `Created issue #${issue.refId}: ${issue.title}\n\n${JSON.stringify(stripUuids(issue), null, 2)}`,
|
|
1453
1626
|
},
|
|
1454
1627
|
],
|
|
1455
1628
|
};
|
|
1456
1629
|
}
|
|
1457
1630
|
case 'update_issue': {
|
|
1458
1631
|
const parsed = UpdateIssueSchema.parse(args);
|
|
1632
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1459
1633
|
const issue = await this.client.updateIssue(parsed.issue_id, {
|
|
1460
1634
|
title: parsed.title,
|
|
1461
1635
|
description: parsed.description,
|
|
@@ -1463,12 +1637,12 @@ class WolfpackMCPServer {
|
|
|
1463
1637
|
severity: parsed.severity,
|
|
1464
1638
|
assignedToId: parsed.assigned_to_id,
|
|
1465
1639
|
closingNote: parsed.closing_note,
|
|
1466
|
-
});
|
|
1640
|
+
}, teamSlug);
|
|
1467
1641
|
return {
|
|
1468
1642
|
content: [
|
|
1469
1643
|
{
|
|
1470
1644
|
type: 'text',
|
|
1471
|
-
text: `Updated issue #${issue.refId}: ${issue.title}\n\n${JSON.stringify(issue, null, 2)}`,
|
|
1645
|
+
text: `Updated issue #${issue.refId}: ${issue.title}\n\n${JSON.stringify(stripUuids(issue), null, 2)}`,
|
|
1472
1646
|
},
|
|
1473
1647
|
],
|
|
1474
1648
|
};
|
|
@@ -1484,7 +1658,7 @@ class WolfpackMCPServer {
|
|
|
1484
1658
|
limit: parsed.limit,
|
|
1485
1659
|
offset: parsed.offset,
|
|
1486
1660
|
});
|
|
1487
|
-
let text = JSON.stringify(result.items, null, 2);
|
|
1661
|
+
let text = JSON.stringify(stripUuids(result.items), null, 2);
|
|
1488
1662
|
if (result.truncated) {
|
|
1489
1663
|
text = `Note: Results truncated. Showing ${result.items.length} of ${result.total} pages. Use limit/offset for pagination.\n\n${text}`;
|
|
1490
1664
|
}
|
|
@@ -1497,7 +1671,7 @@ class WolfpackMCPServer {
|
|
|
1497
1671
|
const page = await this.client.getWikiPage(parsed.page_id);
|
|
1498
1672
|
if (page) {
|
|
1499
1673
|
return {
|
|
1500
|
-
content: [{ type: 'text', text: JSON.stringify(page, null, 2) }],
|
|
1674
|
+
content: [{ type: 'text', text: JSON.stringify(stripUuids(page), null, 2) }],
|
|
1501
1675
|
};
|
|
1502
1676
|
}
|
|
1503
1677
|
return {
|
|
@@ -1516,22 +1690,23 @@ class WolfpackMCPServer {
|
|
|
1516
1690
|
content: [
|
|
1517
1691
|
{
|
|
1518
1692
|
type: 'text',
|
|
1519
|
-
text: `Created wiki page: ${page.title}\n\n${JSON.stringify(page, null, 2)}`,
|
|
1693
|
+
text: `Created wiki page: ${page.title}\n\n${JSON.stringify(stripUuids(page), null, 2)}`,
|
|
1520
1694
|
},
|
|
1521
1695
|
],
|
|
1522
1696
|
};
|
|
1523
1697
|
}
|
|
1524
1698
|
case 'update_wiki_page': {
|
|
1525
1699
|
const parsed = UpdateWikiPageSchema.parse(args);
|
|
1700
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1526
1701
|
const page = await this.client.updateWikiPage(parsed.page_id, {
|
|
1527
1702
|
title: parsed.title,
|
|
1528
1703
|
content: parsed.content,
|
|
1529
|
-
});
|
|
1704
|
+
}, teamSlug);
|
|
1530
1705
|
return {
|
|
1531
1706
|
content: [
|
|
1532
1707
|
{
|
|
1533
1708
|
type: 'text',
|
|
1534
|
-
text: `Updated wiki page: ${page.title}\n\n${JSON.stringify(page, null, 2)}`,
|
|
1709
|
+
text: `Updated wiki page: ${page.title}\n\n${JSON.stringify(stripUuids(page), null, 2)}`,
|
|
1535
1710
|
},
|
|
1536
1711
|
],
|
|
1537
1712
|
};
|
|
@@ -1547,7 +1722,7 @@ class WolfpackMCPServer {
|
|
|
1547
1722
|
limit: parsed.limit,
|
|
1548
1723
|
offset: parsed.offset,
|
|
1549
1724
|
});
|
|
1550
|
-
let text = JSON.stringify(result.items, null, 2);
|
|
1725
|
+
let text = JSON.stringify(stripUuids(result.items), null, 2);
|
|
1551
1726
|
if (result.truncated) {
|
|
1552
1727
|
text = `Note: Results truncated. Showing ${result.items.length} of ${result.total} entries. Use limit/offset for pagination.\n\n${text}`;
|
|
1553
1728
|
}
|
|
@@ -1560,7 +1735,7 @@ class WolfpackMCPServer {
|
|
|
1560
1735
|
const entry = await this.client.getJournalEntry(parsed.entry_id, parsed.project_slug);
|
|
1561
1736
|
if (entry) {
|
|
1562
1737
|
return {
|
|
1563
|
-
content: [{ type: 'text', text: JSON.stringify(entry, null, 2) }],
|
|
1738
|
+
content: [{ type: 'text', text: JSON.stringify(stripUuids(entry), null, 2) }],
|
|
1564
1739
|
};
|
|
1565
1740
|
}
|
|
1566
1741
|
return {
|
|
@@ -1572,29 +1747,29 @@ class WolfpackMCPServer {
|
|
|
1572
1747
|
const entry = await this.client.createJournalEntry({
|
|
1573
1748
|
title: parsed.title,
|
|
1574
1749
|
content: parsed.content,
|
|
1575
|
-
date: parsed.date,
|
|
1576
1750
|
teamSlug: parsed.project_slug || this.client.getProjectSlug() || undefined,
|
|
1577
1751
|
});
|
|
1578
1752
|
return {
|
|
1579
1753
|
content: [
|
|
1580
1754
|
{
|
|
1581
1755
|
type: 'text',
|
|
1582
|
-
text: `Created journal entry #${entry.refId}: ${entry.title}\n\n${JSON.stringify(entry, null, 2)}`,
|
|
1756
|
+
text: `Created journal entry #${entry.refId}: ${entry.title}\n\n${JSON.stringify(stripUuids(entry), null, 2)}`,
|
|
1583
1757
|
},
|
|
1584
1758
|
],
|
|
1585
1759
|
};
|
|
1586
1760
|
}
|
|
1587
1761
|
case 'update_journal_entry': {
|
|
1588
1762
|
const parsed = UpdateJournalEntrySchema.parse(args);
|
|
1763
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1589
1764
|
const entry = await this.client.updateJournalEntry(parsed.entry_id, {
|
|
1590
1765
|
title: parsed.title,
|
|
1591
1766
|
content: parsed.content,
|
|
1592
|
-
});
|
|
1767
|
+
}, teamSlug);
|
|
1593
1768
|
return {
|
|
1594
1769
|
content: [
|
|
1595
1770
|
{
|
|
1596
1771
|
type: 'text',
|
|
1597
|
-
text: `Updated journal entry #${entry.refId}: ${entry.title}\n\n${JSON.stringify(entry, null, 2)}`,
|
|
1772
|
+
text: `Updated journal entry #${entry.refId}: ${entry.title}\n\n${JSON.stringify(stripUuids(entry), null, 2)}`,
|
|
1598
1773
|
},
|
|
1599
1774
|
],
|
|
1600
1775
|
};
|
|
@@ -1602,42 +1777,46 @@ class WolfpackMCPServer {
|
|
|
1602
1777
|
// Comment handlers
|
|
1603
1778
|
case 'list_work_item_comments': {
|
|
1604
1779
|
const parsed = ListWorkItemCommentsSchema.parse(args);
|
|
1605
|
-
const
|
|
1780
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1781
|
+
const comments = await this.client.listWorkItemComments(parsed.work_item_id, teamSlug);
|
|
1606
1782
|
return {
|
|
1607
|
-
content: [{ type: 'text', text: JSON.stringify(comments, null, 2) }],
|
|
1783
|
+
content: [{ type: 'text', text: JSON.stringify(stripUuids(comments), null, 2) }],
|
|
1608
1784
|
};
|
|
1609
1785
|
}
|
|
1610
1786
|
case 'list_issue_comments': {
|
|
1611
1787
|
const parsed = ListIssueCommentsSchema.parse(args);
|
|
1612
|
-
const
|
|
1788
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1789
|
+
const comments = await this.client.listIssueComments(parsed.issue_id, teamSlug);
|
|
1613
1790
|
return {
|
|
1614
|
-
content: [{ type: 'text', text: JSON.stringify(comments, null, 2) }],
|
|
1791
|
+
content: [{ type: 'text', text: JSON.stringify(stripUuids(comments), null, 2) }],
|
|
1615
1792
|
};
|
|
1616
1793
|
}
|
|
1617
1794
|
case 'create_work_item_comment': {
|
|
1618
1795
|
const parsed = CreateWorkItemCommentSchema.parse(args);
|
|
1796
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1619
1797
|
const comment = await this.client.createWorkItemComment(parsed.work_item_id, {
|
|
1620
1798
|
content: parsed.content,
|
|
1621
|
-
});
|
|
1799
|
+
}, teamSlug);
|
|
1622
1800
|
return {
|
|
1623
1801
|
content: [
|
|
1624
1802
|
{
|
|
1625
1803
|
type: 'text',
|
|
1626
|
-
text: `Added comment to work item\n\n${JSON.stringify(comment, null, 2)}`,
|
|
1804
|
+
text: `Added comment to work item\n\n${JSON.stringify(stripUuids(comment), null, 2)}`,
|
|
1627
1805
|
},
|
|
1628
1806
|
],
|
|
1629
1807
|
};
|
|
1630
1808
|
}
|
|
1631
1809
|
case 'create_issue_comment': {
|
|
1632
1810
|
const parsed = CreateIssueCommentSchema.parse(args);
|
|
1811
|
+
const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
|
|
1633
1812
|
const comment = await this.client.createIssueComment(parsed.issue_id, {
|
|
1634
1813
|
content: parsed.content,
|
|
1635
|
-
});
|
|
1814
|
+
}, teamSlug);
|
|
1636
1815
|
return {
|
|
1637
1816
|
content: [
|
|
1638
1817
|
{
|
|
1639
1818
|
type: 'text',
|
|
1640
|
-
text: `Added comment to issue\n\n${JSON.stringify(comment, null, 2)}`,
|
|
1819
|
+
text: `Added comment to issue\n\n${JSON.stringify(stripUuids(comment), null, 2)}`,
|
|
1641
1820
|
},
|
|
1642
1821
|
],
|
|
1643
1822
|
};
|
|
@@ -1699,6 +1878,47 @@ class WolfpackMCPServer {
|
|
|
1699
1878
|
],
|
|
1700
1879
|
};
|
|
1701
1880
|
}
|
|
1881
|
+
// Skill handlers
|
|
1882
|
+
case 'list_skills': {
|
|
1883
|
+
const skills = await this.client.listSkills();
|
|
1884
|
+
return {
|
|
1885
|
+
content: [{ type: 'text', text: JSON.stringify(skills, null, 2) }],
|
|
1886
|
+
};
|
|
1887
|
+
}
|
|
1888
|
+
case 'get_skill': {
|
|
1889
|
+
const parsed = GetSkillSchema.parse(args);
|
|
1890
|
+
const skill = await this.client.getSkill(parsed.skill_name);
|
|
1891
|
+
if (skill) {
|
|
1892
|
+
return {
|
|
1893
|
+
content: [{ type: 'text', text: JSON.stringify(skill, null, 2) }],
|
|
1894
|
+
};
|
|
1895
|
+
}
|
|
1896
|
+
return {
|
|
1897
|
+
content: [
|
|
1898
|
+
{
|
|
1899
|
+
type: 'text',
|
|
1900
|
+
text: `Skill '${parsed.skill_name}' not found. Use list_skills to see available skills.`,
|
|
1901
|
+
},
|
|
1902
|
+
],
|
|
1903
|
+
};
|
|
1904
|
+
}
|
|
1905
|
+
case 'get_skill_resource': {
|
|
1906
|
+
const parsed = GetSkillResourceSchema.parse(args);
|
|
1907
|
+
const resource = await this.client.getSkillResource(parsed.skill_name, parsed.resource_name);
|
|
1908
|
+
if (resource) {
|
|
1909
|
+
return {
|
|
1910
|
+
content: [{ type: 'text', text: JSON.stringify(resource, null, 2) }],
|
|
1911
|
+
};
|
|
1912
|
+
}
|
|
1913
|
+
return {
|
|
1914
|
+
content: [
|
|
1915
|
+
{
|
|
1916
|
+
type: 'text',
|
|
1917
|
+
text: `Resource '${parsed.resource_name}' not found in skill '${parsed.skill_name}'.`,
|
|
1918
|
+
},
|
|
1919
|
+
],
|
|
1920
|
+
};
|
|
1921
|
+
}
|
|
1702
1922
|
default:
|
|
1703
1923
|
throw new Error(`Unknown tool: ${name}`);
|
|
1704
1924
|
}
|