targetprocess-mcp-server 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/build/config.js +0 -0
- package/build/handlers/add_comment.js +14 -0
- package/build/handlers/create_bug.js +14 -0
- package/build/handlers/create_feature.js +14 -0
- package/build/handlers/create_task.js +14 -0
- package/build/handlers/create_user_story.js +14 -0
- package/build/handlers/get_bug_comments.js +45 -0
- package/build/handlers/get_bug_content.js +37 -0
- package/build/handlers/get_card_current_status.js +23 -0
- package/build/handlers/get_commit_message.js +42 -0
- package/build/handlers/get_current_releases.js +20 -0
- package/build/handlers/get_feature_user_stories.js +23 -0
- package/build/handlers/get_in_progress_tasks_and_bugs.js +35 -0
- package/build/handlers/get_logged_in_user.js +23 -0
- package/build/handlers/get_my_time_logs.js +20 -0
- package/build/handlers/get_projects.js +23 -0
- package/build/handlers/get_release_bugs.js +20 -0
- package/build/handlers/get_release_features.js +20 -0
- package/build/handlers/get_release_open_bugs.js +20 -0
- package/build/handlers/get_release_open_user_stories.js +20 -0
- package/build/handlers/get_release_user_stories.js +20 -0
- package/build/handlers/get_teams.js +41 -0
- package/build/handlers/get_user_by_id.js +14 -0
- package/build/handlers/get_user_story_bugs.js +23 -0
- package/build/handlers/get_user_story_comments.js +45 -0
- package/build/handlers/get_user_story_content.js +44 -0
- package/build/handlers/get_users.js +20 -0
- package/build/handlers/list_my_bugs.js +23 -0
- package/build/handlers/list_my_user_stories.js +23 -0
- package/build/handlers/log_time.js +14 -0
- package/build/handlers/update_bug.js +14 -0
- package/build/handlers/update_user_story_sub_state.js +14 -0
- package/build/index.js +94 -859
- package/build/tp.js +25 -0
- package/build/types.js +0 -0
- package/package.json +12 -7
package/build/index.js
CHANGED
|
@@ -5,6 +5,37 @@ import { JSDOM } from "jsdom";
|
|
|
5
5
|
import { TpClient } from "./tp.js";
|
|
6
6
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
7
|
import { config } from "./config.js";
|
|
8
|
+
import { handleGetProjects } from "./handlers/get_projects.js";
|
|
9
|
+
import { handleGetUserById } from "./handlers/get_user_by_id.js";
|
|
10
|
+
import { handleGetCurrentReleases } from "./handlers/get_current_releases.js";
|
|
11
|
+
import { handleGetBugContent } from "./handlers/get_bug_content.js";
|
|
12
|
+
import { handleGetLoggedInUser } from "./handlers/get_logged_in_user.js";
|
|
13
|
+
import { handleGetUserStoryContent } from "./handlers/get_user_story_content.js";
|
|
14
|
+
import { handleGetCommitMessage } from "./handlers/get_commit_message.js";
|
|
15
|
+
import { handleGetReleaseUserStories } from "./handlers/get_release_user_stories.js";
|
|
16
|
+
import { handleGetReleaseBugs } from "./handlers/get_release_bugs.js";
|
|
17
|
+
import { handleGetReleaseFeatures } from "./handlers/get_release_features.js";
|
|
18
|
+
import { handleGetReleaseOpenBugs } from "./handlers/get_release_open_bugs.js";
|
|
19
|
+
import { handleGetReleaseOpenUserStories } from "./handlers/get_release_open_user_stories.js";
|
|
20
|
+
import { handleGetUsers } from "./handlers/get_users.js";
|
|
21
|
+
import { handleGetTeams, handleGetTeamsAndTeamAssignments } from "./handlers/get_teams.js";
|
|
22
|
+
import { handleAddComment } from "./handlers/add_comment.js";
|
|
23
|
+
import { handleGetUserStoryComments } from "./handlers/get_user_story_comments.js";
|
|
24
|
+
import { handleGetBugComments } from "./handlers/get_bug_comments.js";
|
|
25
|
+
import { handleCreateBug } from "./handlers/create_bug.js";
|
|
26
|
+
import { handleCreateUserStory } from "./handlers/create_user_story.js";
|
|
27
|
+
import { handleCreateFeature } from "./handlers/create_feature.js";
|
|
28
|
+
import { handleCreateTask } from "./handlers/create_task.js";
|
|
29
|
+
import { handleUpdateBug } from "./handlers/update_bug.js";
|
|
30
|
+
import { handleGetInProgressTasksAndBugs } from "./handlers/get_in_progress_tasks_and_bugs.js";
|
|
31
|
+
import { handleListMyUserStories } from "./handlers/list_my_user_stories.js";
|
|
32
|
+
import { handleListMyBugs } from "./handlers/list_my_bugs.js";
|
|
33
|
+
import { handleLogTime } from "./handlers/log_time.js";
|
|
34
|
+
import { handleGetMyTimeLogs } from "./handlers/get_my_time_logs.js";
|
|
35
|
+
import { handleGetFeatureUserStories } from "./handlers/get_feature_user_stories.js";
|
|
36
|
+
import { handleGetUserStoryBugs } from "./handlers/get_user_story_bugs.js";
|
|
37
|
+
import { handleGetCardCurrentStatus } from "./handlers/get_card_current_status.js";
|
|
38
|
+
import { handleUpdateUserStorySubState } from "./handlers/update_user_story_sub_state.js";
|
|
8
39
|
const server = new McpServer({
|
|
9
40
|
name: "tp",
|
|
10
41
|
version: "1.0.0"
|
|
@@ -32,80 +63,11 @@ server.registerTool('get_user_story_content', {
|
|
|
32
63
|
.max(6)
|
|
33
64
|
.describe('TP (or tp) ID (e.g. 145789)')
|
|
34
65
|
},
|
|
35
|
-
}, async ({ id }) =>
|
|
36
|
-
const userStory = await tp.getUserStory(id);
|
|
37
|
-
if (!userStory) {
|
|
38
|
-
return {
|
|
39
|
-
content: [{
|
|
40
|
-
type: 'text',
|
|
41
|
-
text: `Failed to get user story, id: ${id}\n JSON: ${JSON.stringify(userStory, null, 2)}`
|
|
42
|
-
}],
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
const description = userStory.Description || '';
|
|
46
|
-
if (!description) {
|
|
47
|
-
return {
|
|
48
|
-
content: [{
|
|
49
|
-
type: "text",
|
|
50
|
-
text: `No description for ${id} tp card`,
|
|
51
|
-
}],
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
let userStoryResults = {
|
|
55
|
-
name: userStory.Name,
|
|
56
|
-
id: userStory.Id,
|
|
57
|
-
description: '',
|
|
58
|
-
feature: userStory.Feature?.Name,
|
|
59
|
-
featureId: userStory.Feature?.Id,
|
|
60
|
-
customFields: userStory.CustomFields,
|
|
61
|
-
};
|
|
62
|
-
try {
|
|
63
|
-
const dom = new JSDOM(`<html><body><div id="content">${description}</div></body></html>`);
|
|
64
|
-
const descriptionText = dom.window.document.getElementById('content')?.textContent;
|
|
65
|
-
if (descriptionText) {
|
|
66
|
-
userStoryResults.description = descriptionText;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
console.error("Error parsing user story description:", error);
|
|
71
|
-
console.error("Returning user story without description");
|
|
72
|
-
}
|
|
73
|
-
return {
|
|
74
|
-
content: [{
|
|
75
|
-
type: 'text',
|
|
76
|
-
text: JSON.stringify(userStoryResults)
|
|
77
|
-
}],
|
|
78
|
-
};
|
|
79
|
-
});
|
|
66
|
+
}, async ({ id }) => handleGetUserStoryContent(tp, id));
|
|
80
67
|
server.registerTool('get_current_releases', {
|
|
81
68
|
title: 'Get current releases',
|
|
82
69
|
description: 'Get current releases',
|
|
83
|
-
}, async (
|
|
84
|
-
const releases = await tp.getCurrentReleases();
|
|
85
|
-
if (!releases) {
|
|
86
|
-
return {
|
|
87
|
-
content: [{
|
|
88
|
-
type: 'text',
|
|
89
|
-
text: `Failed to get current releases, JSON: ${JSON.stringify(releases, null, 2)}`
|
|
90
|
-
}],
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
const items = releases.Items || [];
|
|
94
|
-
if (items.length == 0) {
|
|
95
|
-
return {
|
|
96
|
-
content: [{
|
|
97
|
-
type: "text",
|
|
98
|
-
text: `No releases found`,
|
|
99
|
-
}],
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
return {
|
|
103
|
-
content: [{
|
|
104
|
-
type: 'text',
|
|
105
|
-
text: JSON.stringify(items)
|
|
106
|
-
}],
|
|
107
|
-
};
|
|
108
|
-
});
|
|
70
|
+
}, async () => handleGetCurrentReleases(tp));
|
|
109
71
|
server.registerTool('get_release_user_stories', {
|
|
110
72
|
title: 'Get release user stories',
|
|
111
73
|
description: 'Get release user stories',
|
|
@@ -117,32 +79,7 @@ server.registerTool('get_release_user_stories', {
|
|
|
117
79
|
.optional()
|
|
118
80
|
.describe('Number of results to return, default is 50'),
|
|
119
81
|
},
|
|
120
|
-
}, async ({ name, results }) =>
|
|
121
|
-
const release = await tp.getReleaseUserStories({ name, results });
|
|
122
|
-
if (!release) {
|
|
123
|
-
return {
|
|
124
|
-
content: [{
|
|
125
|
-
type: 'text',
|
|
126
|
-
text: `Failed to get ${name} release user stories, JSON: ${JSON.stringify(release, null, 2)}`
|
|
127
|
-
}],
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
const items = release.Items || [];
|
|
131
|
-
if (items.length == 0) {
|
|
132
|
-
return {
|
|
133
|
-
content: [{
|
|
134
|
-
type: "text",
|
|
135
|
-
text: `No release user stories found`,
|
|
136
|
-
}],
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
return {
|
|
140
|
-
content: [{
|
|
141
|
-
type: 'text',
|
|
142
|
-
text: JSON.stringify(items)
|
|
143
|
-
}],
|
|
144
|
-
};
|
|
145
|
-
});
|
|
82
|
+
}, async ({ name, results }) => handleGetReleaseUserStories(tp, name, results));
|
|
146
83
|
server.registerTool('get_release_bugs', {
|
|
147
84
|
title: 'Get release bugs',
|
|
148
85
|
description: 'Get release bugs',
|
|
@@ -154,32 +91,7 @@ server.registerTool('get_release_bugs', {
|
|
|
154
91
|
.optional()
|
|
155
92
|
.describe('Number of results to return, default is 100'),
|
|
156
93
|
},
|
|
157
|
-
}, async ({ name, results }) =>
|
|
158
|
-
const release = await tp.getReleaseBugs({ name, results });
|
|
159
|
-
if (!release) {
|
|
160
|
-
return {
|
|
161
|
-
content: [{
|
|
162
|
-
type: 'text',
|
|
163
|
-
text: `Failed to get ${name} release bugs, JSON: ${JSON.stringify(release, null, 2)}`
|
|
164
|
-
}],
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
const items = release.Items || [];
|
|
168
|
-
if (items.length == 0) {
|
|
169
|
-
return {
|
|
170
|
-
content: [{
|
|
171
|
-
type: "text",
|
|
172
|
-
text: `No release bugs found`,
|
|
173
|
-
}],
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
return {
|
|
177
|
-
content: [{
|
|
178
|
-
type: 'text',
|
|
179
|
-
text: JSON.stringify(items)
|
|
180
|
-
}],
|
|
181
|
-
};
|
|
182
|
-
});
|
|
94
|
+
}, async ({ name, results }) => handleGetReleaseBugs(tp, name, results));
|
|
183
95
|
server.registerTool('get_release_features', {
|
|
184
96
|
title: 'Get release features',
|
|
185
97
|
description: 'Get release features',
|
|
@@ -191,32 +103,7 @@ server.registerTool('get_release_features', {
|
|
|
191
103
|
.optional()
|
|
192
104
|
.describe('Number of results to return, default is 100'),
|
|
193
105
|
},
|
|
194
|
-
}, async ({ name, results }) =>
|
|
195
|
-
const release = await tp.getReleaseFeatures({ name, results });
|
|
196
|
-
if (!release) {
|
|
197
|
-
return {
|
|
198
|
-
content: [{
|
|
199
|
-
type: 'text',
|
|
200
|
-
text: `Failed to get ${name} release features, JSON: ${JSON.stringify(release, null, 2)}`
|
|
201
|
-
}],
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
const items = release.Items || [];
|
|
205
|
-
if (items.length == 0) {
|
|
206
|
-
return {
|
|
207
|
-
content: [{
|
|
208
|
-
type: "text",
|
|
209
|
-
text: `No release features found`,
|
|
210
|
-
}],
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
return {
|
|
214
|
-
content: [{
|
|
215
|
-
type: 'text',
|
|
216
|
-
text: JSON.stringify(items)
|
|
217
|
-
}],
|
|
218
|
-
};
|
|
219
|
-
});
|
|
106
|
+
}, async ({ name, results }) => handleGetReleaseFeatures(tp, name, results));
|
|
220
107
|
server.registerTool('get_release_user_stories_with_description', {
|
|
221
108
|
title: 'Get release user stories with description',
|
|
222
109
|
description: `Get release user stories with description in the response.
|
|
@@ -229,32 +116,7 @@ server.registerTool('get_release_user_stories_with_description', {
|
|
|
229
116
|
withDescription: z.boolean()
|
|
230
117
|
.describe('Include description in the response'),
|
|
231
118
|
},
|
|
232
|
-
}, async ({ name, withDescription }) =>
|
|
233
|
-
const release = await tp.getReleaseUserStories({ name, withDescription });
|
|
234
|
-
if (!release) {
|
|
235
|
-
return {
|
|
236
|
-
content: [{
|
|
237
|
-
type: 'text',
|
|
238
|
-
text: `Failed to get ${name} release user stories, JSON: ${JSON.stringify(release, null, 2)}`
|
|
239
|
-
}],
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
const items = release.Items || [];
|
|
243
|
-
if (items.length == 0) {
|
|
244
|
-
return {
|
|
245
|
-
content: [{
|
|
246
|
-
type: "text",
|
|
247
|
-
text: `No release user stories found`,
|
|
248
|
-
}],
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
return {
|
|
252
|
-
content: [{
|
|
253
|
-
type: 'text',
|
|
254
|
-
text: JSON.stringify(items)
|
|
255
|
-
}],
|
|
256
|
-
};
|
|
257
|
-
});
|
|
119
|
+
}, async ({ name, withDescription }) => handleGetReleaseUserStories(tp, name, undefined, withDescription));
|
|
258
120
|
server.registerTool('get_release_open_bugs', {
|
|
259
121
|
title: 'Get release active bugs',
|
|
260
122
|
description: `Get release active bugs (bugs that are not closed, done, passed, ready to deploy)`,
|
|
@@ -268,32 +130,7 @@ server.registerTool('get_release_open_bugs', {
|
|
|
268
130
|
withDescription: z.boolean()
|
|
269
131
|
.describe('Include description in the response'),
|
|
270
132
|
},
|
|
271
|
-
}, async ({ name, results, withDescription }) =>
|
|
272
|
-
const release = await tp.getReleaseOpenBugs({ name, results, withDescription });
|
|
273
|
-
if (!release) {
|
|
274
|
-
return {
|
|
275
|
-
content: [{
|
|
276
|
-
type: 'text',
|
|
277
|
-
text: `Failed to get ${name} release bugs, JSON: ${JSON.stringify(release, null, 2)}`
|
|
278
|
-
}],
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
const items = release.Items || [];
|
|
282
|
-
if (items.length == 0) {
|
|
283
|
-
return {
|
|
284
|
-
content: [{
|
|
285
|
-
type: "text",
|
|
286
|
-
text: `No release bugs found`,
|
|
287
|
-
}],
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
return {
|
|
291
|
-
content: [{
|
|
292
|
-
type: 'text',
|
|
293
|
-
text: JSON.stringify(items)
|
|
294
|
-
}],
|
|
295
|
-
};
|
|
296
|
-
});
|
|
133
|
+
}, async ({ name, results, withDescription }) => handleGetReleaseOpenBugs(tp, name, results, withDescription));
|
|
297
134
|
server.registerTool('get_release_open_user_stories', {
|
|
298
135
|
title: 'Get release active user stories',
|
|
299
136
|
description: `Get release active user stories (user stories that are not closed, done, passed, ready to deploy)`,
|
|
@@ -307,32 +144,7 @@ server.registerTool('get_release_open_user_stories', {
|
|
|
307
144
|
withDescription: z.boolean()
|
|
308
145
|
.describe('Include description in the response'),
|
|
309
146
|
},
|
|
310
|
-
}, async ({ name, results, withDescription }) =>
|
|
311
|
-
const release = await tp.getReleaseOpenUserStories({ name, results, withDescription });
|
|
312
|
-
if (!release) {
|
|
313
|
-
return {
|
|
314
|
-
content: [{
|
|
315
|
-
type: 'text',
|
|
316
|
-
text: `Failed to get ${name} release user stories, JSON: ${JSON.stringify(release, null, 2)}`
|
|
317
|
-
}],
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
const items = release.Items || [];
|
|
321
|
-
if (items.length == 0) {
|
|
322
|
-
return {
|
|
323
|
-
content: [{
|
|
324
|
-
type: "text",
|
|
325
|
-
text: `No release user stories found`,
|
|
326
|
-
}],
|
|
327
|
-
};
|
|
328
|
-
}
|
|
329
|
-
return {
|
|
330
|
-
content: [{
|
|
331
|
-
type: 'text',
|
|
332
|
-
text: JSON.stringify(items)
|
|
333
|
-
}],
|
|
334
|
-
};
|
|
335
|
-
});
|
|
147
|
+
}, async ({ name, results, withDescription }) => handleGetReleaseOpenUserStories(tp, name, results, withDescription));
|
|
336
148
|
server.registerTool('search_tp_cards', {
|
|
337
149
|
title: 'Search TP cards by keyword or phrase in description',
|
|
338
150
|
description: `Searches TP cards (UserStories or Bugs) by keyword or phrase or partial keyphrase in Card Description e.g. "Text Element", "Font field"
|
|
@@ -394,47 +206,7 @@ server.registerTool('get_bug_content', {
|
|
|
394
206
|
.max(6)
|
|
395
207
|
.describe('Bug card ID (e.g. 145789)')
|
|
396
208
|
},
|
|
397
|
-
}, async ({ id }) =>
|
|
398
|
-
const bug = await tp.getBug(id);
|
|
399
|
-
if (!bug) {
|
|
400
|
-
return {
|
|
401
|
-
content: [{
|
|
402
|
-
type: 'text',
|
|
403
|
-
text: `Failed to get bug, id: ${id}\n JSON: ${JSON.stringify(bug, null, 2)}`
|
|
404
|
-
}],
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
let bugResult = {
|
|
408
|
-
name: bug.Name,
|
|
409
|
-
id: bug.Id,
|
|
410
|
-
description: '',
|
|
411
|
-
origin: ''
|
|
412
|
-
};
|
|
413
|
-
try {
|
|
414
|
-
const dom = new JSDOM(`<html><body><div id="content">${bug.Description}</div></body></html>`);
|
|
415
|
-
const descriptionText = dom.window.document.getElementById('content')?.textContent;
|
|
416
|
-
if (descriptionText) {
|
|
417
|
-
bugResult.description = descriptionText;
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
catch (error) {
|
|
421
|
-
console.error("Error parsing bug description:", error);
|
|
422
|
-
console.error("Returning bug without description");
|
|
423
|
-
}
|
|
424
|
-
try {
|
|
425
|
-
bugResult.origin = bug.CustomFields?.find((field) => field?.Value === "Origin")?.Value;
|
|
426
|
-
}
|
|
427
|
-
catch (error) {
|
|
428
|
-
console.error("Error parsing bug origin:", error);
|
|
429
|
-
console.error("Returning bug without origin");
|
|
430
|
-
}
|
|
431
|
-
return {
|
|
432
|
-
content: [{
|
|
433
|
-
type: 'text',
|
|
434
|
-
text: JSON.stringify(bugResult)
|
|
435
|
-
}],
|
|
436
|
-
};
|
|
437
|
-
});
|
|
209
|
+
}, async ({ id }) => handleGetBugContent(tp, id));
|
|
438
210
|
server.registerTool('get_user_by_id', {
|
|
439
211
|
title: 'Get user by id',
|
|
440
212
|
description: 'Get user by id',
|
|
@@ -442,52 +214,11 @@ server.registerTool('get_user_by_id', {
|
|
|
442
214
|
id: z.string()
|
|
443
215
|
.describe('User email'),
|
|
444
216
|
},
|
|
445
|
-
}, async ({ id }) =>
|
|
446
|
-
const user = await tp.getUser(id);
|
|
447
|
-
if (!user) {
|
|
448
|
-
return {
|
|
449
|
-
content: [{
|
|
450
|
-
type: 'text',
|
|
451
|
-
text: `Failed to get user, id: ${id}\n JSON: ${JSON.stringify(user, null, 2)}`
|
|
452
|
-
}],
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
return {
|
|
456
|
-
content: [{
|
|
457
|
-
type: 'text',
|
|
458
|
-
text: JSON.stringify(user)
|
|
459
|
-
}],
|
|
460
|
-
};
|
|
461
|
-
});
|
|
217
|
+
}, async ({ id }) => handleGetUserById(tp, id));
|
|
462
218
|
server.registerTool('get_users', {
|
|
463
219
|
title: 'Get users',
|
|
464
220
|
description: 'Get all users',
|
|
465
|
-
}, async () =>
|
|
466
|
-
const response = await tp.getUsers();
|
|
467
|
-
if (!response) {
|
|
468
|
-
return {
|
|
469
|
-
content: [{
|
|
470
|
-
type: 'text',
|
|
471
|
-
text: `Failed to get users, JSON: ${JSON.stringify(response, null, 2)}`
|
|
472
|
-
}],
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
const items = response.Items || [];
|
|
476
|
-
if (items.length === 0) {
|
|
477
|
-
return {
|
|
478
|
-
content: [{
|
|
479
|
-
type: 'text',
|
|
480
|
-
text: `No users found`,
|
|
481
|
-
}],
|
|
482
|
-
};
|
|
483
|
-
}
|
|
484
|
-
return {
|
|
485
|
-
content: [{
|
|
486
|
-
type: 'text',
|
|
487
|
-
text: JSON.stringify(items)
|
|
488
|
-
}],
|
|
489
|
-
};
|
|
490
|
-
});
|
|
221
|
+
}, async () => handleGetUsers(tp));
|
|
491
222
|
server.registerTool('add_comment_with_user', {
|
|
492
223
|
title: 'Adds provided content to TP card (user story) as a comment',
|
|
493
224
|
description: `Adds provided content as a comment to the specified tp card by id, e.g. 145789 and mentions the user in the comment
|
|
@@ -553,34 +284,7 @@ server.registerTool('add_comment', {
|
|
|
553
284
|
comment: z.string()
|
|
554
285
|
.describe('Comment content to add'),
|
|
555
286
|
},
|
|
556
|
-
}, async ({ id, comment }) =>
|
|
557
|
-
try {
|
|
558
|
-
const addCommentResponse = await tp.addComment(id, comment);
|
|
559
|
-
if (!addCommentResponse) {
|
|
560
|
-
return {
|
|
561
|
-
content: [{
|
|
562
|
-
type: 'text',
|
|
563
|
-
text: `Failed to add comment to user story, id: ${id}\n JSON: ${JSON.stringify(addCommentResponse, null, 2)}`
|
|
564
|
-
}]
|
|
565
|
-
};
|
|
566
|
-
}
|
|
567
|
-
return {
|
|
568
|
-
content: [{
|
|
569
|
-
type: 'text',
|
|
570
|
-
text: JSON.stringify(addCommentResponse)
|
|
571
|
-
}],
|
|
572
|
-
};
|
|
573
|
-
}
|
|
574
|
-
catch (error) {
|
|
575
|
-
console.error("Error adding comment to user story:", error);
|
|
576
|
-
return {
|
|
577
|
-
content: [{
|
|
578
|
-
type: 'text',
|
|
579
|
-
text: `Failed to add comment to user story, id: ${id}\n Error: ${error}`
|
|
580
|
-
}]
|
|
581
|
-
};
|
|
582
|
-
}
|
|
583
|
-
});
|
|
287
|
+
}, async ({ id, comment }) => handleAddComment(tp, id, comment));
|
|
584
288
|
server.registerTool('get_user_story_comments', {
|
|
585
289
|
title: 'Get user story comments',
|
|
586
290
|
description: 'Get comments for a TP user story by its ID',
|
|
@@ -594,54 +298,7 @@ server.registerTool('get_user_story_comments', {
|
|
|
594
298
|
.optional()
|
|
595
299
|
.describe('Number of comments to return, default is 25'),
|
|
596
300
|
},
|
|
597
|
-
}, async ({ id, results }) =>
|
|
598
|
-
const response = await tp.getUserStoryComments(id, results);
|
|
599
|
-
if (!response) {
|
|
600
|
-
return {
|
|
601
|
-
content: [{
|
|
602
|
-
type: 'text',
|
|
603
|
-
text: `Failed to get comments for user story id: ${id}`
|
|
604
|
-
}],
|
|
605
|
-
};
|
|
606
|
-
}
|
|
607
|
-
const items = response.Items || [];
|
|
608
|
-
if (items.length === 0) {
|
|
609
|
-
return {
|
|
610
|
-
content: [{
|
|
611
|
-
type: 'text',
|
|
612
|
-
text: `No comments found for user story id: ${id}`,
|
|
613
|
-
}],
|
|
614
|
-
};
|
|
615
|
-
}
|
|
616
|
-
let parsedItems = [];
|
|
617
|
-
try {
|
|
618
|
-
parsedItems = items.map((item) => {
|
|
619
|
-
const dom = new JSDOM(`<html><body><div id="content">${item.Description}</div></body></html>`);
|
|
620
|
-
const descriptionText = dom.window.document.getElementById('content')?.textContent;
|
|
621
|
-
return {
|
|
622
|
-
id: item.Id,
|
|
623
|
-
description: descriptionText,
|
|
624
|
-
createDate: item.CreateDate,
|
|
625
|
-
owner: item.Owner.FullName,
|
|
626
|
-
};
|
|
627
|
-
});
|
|
628
|
-
}
|
|
629
|
-
catch (error) {
|
|
630
|
-
console.error("Error parsing user story comments:", error);
|
|
631
|
-
return {
|
|
632
|
-
content: [{
|
|
633
|
-
type: 'text',
|
|
634
|
-
text: `Failed to parse user story comments for user story id: ${id}`,
|
|
635
|
-
}],
|
|
636
|
-
};
|
|
637
|
-
}
|
|
638
|
-
return {
|
|
639
|
-
content: [{
|
|
640
|
-
type: 'text',
|
|
641
|
-
text: JSON.stringify(parsedItems)
|
|
642
|
-
}],
|
|
643
|
-
};
|
|
644
|
-
});
|
|
301
|
+
}, async ({ id, results }) => handleGetUserStoryComments(tp, id, results));
|
|
645
302
|
server.registerTool('get_bug_comments', {
|
|
646
303
|
title: 'Get bug comments',
|
|
647
304
|
description: 'Get comments for a TP bug by its ID',
|
|
@@ -655,54 +312,7 @@ server.registerTool('get_bug_comments', {
|
|
|
655
312
|
.optional()
|
|
656
313
|
.describe('Number of comments to return, default is 25'),
|
|
657
314
|
},
|
|
658
|
-
}, async ({ id, results }) =>
|
|
659
|
-
const response = await tp.getBugComments(id, results);
|
|
660
|
-
if (!response) {
|
|
661
|
-
return {
|
|
662
|
-
content: [{
|
|
663
|
-
type: 'text',
|
|
664
|
-
text: `Failed to get comments for bug id: ${id}`
|
|
665
|
-
}],
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
const items = response.Items || [];
|
|
669
|
-
if (items.length === 0) {
|
|
670
|
-
return {
|
|
671
|
-
content: [{
|
|
672
|
-
type: 'text',
|
|
673
|
-
text: `No comments found for bug id: ${id}`,
|
|
674
|
-
}],
|
|
675
|
-
};
|
|
676
|
-
}
|
|
677
|
-
let parsedItems = [];
|
|
678
|
-
try {
|
|
679
|
-
parsedItems = items.map((item) => {
|
|
680
|
-
const dom = new JSDOM(`<html><body><div id="content">${item.Description}</div></body></html>`);
|
|
681
|
-
const descriptionText = dom.window.document.getElementById('content')?.textContent;
|
|
682
|
-
return {
|
|
683
|
-
id: item.Id,
|
|
684
|
-
description: descriptionText,
|
|
685
|
-
createDate: item.CreateDate,
|
|
686
|
-
owner: item.Owner.FullName,
|
|
687
|
-
};
|
|
688
|
-
});
|
|
689
|
-
}
|
|
690
|
-
catch (error) {
|
|
691
|
-
console.error("Error parsing bug comments:", error);
|
|
692
|
-
return {
|
|
693
|
-
content: [{
|
|
694
|
-
type: 'text',
|
|
695
|
-
text: `Failed to parse bug comments for bug id: ${id}`,
|
|
696
|
-
}],
|
|
697
|
-
};
|
|
698
|
-
}
|
|
699
|
-
return {
|
|
700
|
-
content: [{
|
|
701
|
-
type: 'text',
|
|
702
|
-
text: JSON.stringify(parsedItems)
|
|
703
|
-
}],
|
|
704
|
-
};
|
|
705
|
-
});
|
|
315
|
+
}, async ({ id, results }) => handleGetBugComments(tp, id, results));
|
|
706
316
|
server.registerTool('create_bug_based_on_card', {
|
|
707
317
|
title: 'Create a new bug card based on provided card id',
|
|
708
318
|
description: `Create a new bug card based on provided card id that summarizes the problem in concise, descriptive manner answering questions What? Where? When?, and content explaining what happened in detail.
|
|
@@ -810,23 +420,29 @@ server.registerTool('update_bug', {
|
|
|
810
420
|
.optional()
|
|
811
421
|
.describe('Optional Entity State ID — if user gave a state name, resolve it via "get_bug_workflows" first; defaults to "Done"'),
|
|
812
422
|
},
|
|
813
|
-
}, async ({ id, title, bugContent, origin, projectId, teamId, entityStateId }) => {
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
423
|
+
}, async ({ id, title, bugContent, origin, projectId, teamId, entityStateId }) => handleUpdateBug(tp, { id, title, bugContent, origin, projectId, teamId, entityStateId }));
|
|
424
|
+
server.registerTool('update_user_story_state', {
|
|
425
|
+
title: 'Update a user story card sub state',
|
|
426
|
+
description: `Update a user story card sub state with data provided from user input.
|
|
427
|
+
CRITICAL WORKFLOW: Before calling this tool, you MUST follow these steps:
|
|
428
|
+
1) call "get_user_story_content" to find the matching team, assigned (responsible) team and their IDs
|
|
429
|
+
1) call "get_user_story_workflows" to find matching state and use its ID in entityStateId`,
|
|
430
|
+
inputSchema: {
|
|
431
|
+
id: z.string()
|
|
432
|
+
.min(5)
|
|
433
|
+
.max(6)
|
|
434
|
+
.describe('User story card ID (e.g. 145789)'),
|
|
435
|
+
entityStateId: z.string()
|
|
436
|
+
.optional()
|
|
437
|
+
.describe('Entity state ID, resolve it via "get_user_story_workflows" first'),
|
|
438
|
+
teamId: z.string()
|
|
439
|
+
.optional()
|
|
440
|
+
.describe('Team ID, resolve it via "get_teams" first'),
|
|
441
|
+
teamAssignmentId: z.string()
|
|
442
|
+
.optional()
|
|
443
|
+
.describe('Team Assignment ID, resolve it via "get_user_story_content" first'),
|
|
444
|
+
},
|
|
445
|
+
}, async ({ id, teamId, teamAssignmentId, entityStateId }) => handleUpdateUserStorySubState(tp, { id, teamId, teamAssignmentId, entityStateId }));
|
|
830
446
|
server.registerTool('update_user_story', {
|
|
831
447
|
title: 'Update a user story card',
|
|
832
448
|
description: `Update a user story card with data provided from user input.
|
|
@@ -910,23 +526,7 @@ server.registerTool('create_bug', {
|
|
|
910
526
|
.optional()
|
|
911
527
|
.describe('Optional Entity State ID — if user gave a state name, resolve it via "get_bug_workflows" first; defaults to "Done"'),
|
|
912
528
|
},
|
|
913
|
-
}, async ({ title, bugContent, origin, projectId, teamId, entityStateId }) => {
|
|
914
|
-
const bugResponse = await tp.createBugOnly({ title, bugContent, origin, projectId, teamId, entityStateId });
|
|
915
|
-
if (!bugResponse) {
|
|
916
|
-
return {
|
|
917
|
-
content: [{
|
|
918
|
-
type: 'text',
|
|
919
|
-
text: `Failed to create bug "${title}"\n JSON: ${JSON.stringify(bugResponse, null, 2)}`
|
|
920
|
-
}]
|
|
921
|
-
};
|
|
922
|
-
}
|
|
923
|
-
return {
|
|
924
|
-
content: [{
|
|
925
|
-
type: 'text',
|
|
926
|
-
text: JSON.stringify(bugResponse)
|
|
927
|
-
}],
|
|
928
|
-
};
|
|
929
|
-
});
|
|
529
|
+
}, async ({ title, bugContent, origin, projectId, teamId, entityStateId }) => handleCreateBug(tp, { title, bugContent, origin, projectId, teamId, entityStateId }));
|
|
930
530
|
server.registerTool('create_user_story', {
|
|
931
531
|
title: 'Create a new user story',
|
|
932
532
|
description: `Create a new user story in Targetprocess.`,
|
|
@@ -953,23 +553,7 @@ server.registerTool('create_user_story', {
|
|
|
953
553
|
.optional()
|
|
954
554
|
.describe('Optional Team ID — defaults to TP_TEAM_ID from config'),
|
|
955
555
|
},
|
|
956
|
-
}, async ({ title, description, featureId, releaseId, projectId, teamId }) => {
|
|
957
|
-
const userStoryResponse = await tp.createUserStory({ title, description, featureId, releaseId, projectId, teamId });
|
|
958
|
-
if (!userStoryResponse) {
|
|
959
|
-
return {
|
|
960
|
-
content: [{
|
|
961
|
-
type: 'text',
|
|
962
|
-
text: `Failed to create user story "${title}"\n JSON: ${JSON.stringify(userStoryResponse, null, 2)}`
|
|
963
|
-
}]
|
|
964
|
-
};
|
|
965
|
-
}
|
|
966
|
-
return {
|
|
967
|
-
content: [{
|
|
968
|
-
type: 'text',
|
|
969
|
-
text: JSON.stringify(userStoryResponse)
|
|
970
|
-
}],
|
|
971
|
-
};
|
|
972
|
-
});
|
|
556
|
+
}, async ({ title, description, featureId, releaseId, projectId, teamId }) => handleCreateUserStory(tp, { title, description, featureId, releaseId, projectId, teamId }));
|
|
973
557
|
server.registerTool('create_feature', {
|
|
974
558
|
title: 'Create a new feature',
|
|
975
559
|
description: `Create a new Feature in Targetprocess.`,
|
|
@@ -991,28 +575,12 @@ server.registerTool('create_feature', {
|
|
|
991
575
|
.describe('Optional Release ID to link this feature to (e.g. 145200)'),
|
|
992
576
|
projectId: z.string()
|
|
993
577
|
.optional()
|
|
994
|
-
.describe('Optional Project ID — defaults to TP_PROJECT_ID from config'),
|
|
995
|
-
teamId: z.string()
|
|
996
|
-
.optional()
|
|
997
|
-
.describe('Optional Team ID — defaults to TP_TEAM_ID from config'),
|
|
998
|
-
},
|
|
999
|
-
}, async ({ title, description, epicId, releaseId, projectId, teamId }) => {
|
|
1000
|
-
const featureResponse = await tp.createFeature({ title, description, epicId, releaseId, projectId, teamId });
|
|
1001
|
-
if (!featureResponse) {
|
|
1002
|
-
return {
|
|
1003
|
-
content: [{
|
|
1004
|
-
type: 'text',
|
|
1005
|
-
text: `Failed to create feature "${title}"\n JSON: ${JSON.stringify(featureResponse, null, 2)}`
|
|
1006
|
-
}]
|
|
1007
|
-
};
|
|
1008
|
-
}
|
|
1009
|
-
return {
|
|
1010
|
-
content: [{
|
|
1011
|
-
type: 'text',
|
|
1012
|
-
text: JSON.stringify(featureResponse)
|
|
1013
|
-
}],
|
|
1014
|
-
};
|
|
1015
|
-
});
|
|
578
|
+
.describe('Optional Project ID — defaults to TP_PROJECT_ID from config'),
|
|
579
|
+
teamId: z.string()
|
|
580
|
+
.optional()
|
|
581
|
+
.describe('Optional Team ID — defaults to TP_TEAM_ID from config'),
|
|
582
|
+
},
|
|
583
|
+
}, async ({ title, description, epicId, releaseId, projectId, teamId }) => handleCreateFeature(tp, { title, description, epicId, releaseId, projectId, teamId }));
|
|
1016
584
|
server.registerTool('create_test_plan', {
|
|
1017
585
|
title: 'Create a new test plan linked to a TP card',
|
|
1018
586
|
description: `Create a new test plan linked to a UserStory, Bug, or Feature. Name and Project are required by the API; Description, StartDate, and EndDate are optional.`,
|
|
@@ -1146,32 +714,7 @@ server.registerTool('get_feature_user_stories', {
|
|
|
1146
714
|
.max(6)
|
|
1147
715
|
.describe('TP feature ID (e.g. 145636)'),
|
|
1148
716
|
},
|
|
1149
|
-
}, async ({ id }) =>
|
|
1150
|
-
const response = await tp.getFeatureUserStories(id);
|
|
1151
|
-
if (!response) {
|
|
1152
|
-
return {
|
|
1153
|
-
content: [{
|
|
1154
|
-
type: 'text',
|
|
1155
|
-
text: `Failed to get user stories for feature id: ${id}`
|
|
1156
|
-
}],
|
|
1157
|
-
};
|
|
1158
|
-
}
|
|
1159
|
-
const items = response.items || [];
|
|
1160
|
-
if (items.length === 0) {
|
|
1161
|
-
return {
|
|
1162
|
-
content: [{
|
|
1163
|
-
type: 'text',
|
|
1164
|
-
text: `No user stories found in outer items for feature id: ${id}`,
|
|
1165
|
-
}],
|
|
1166
|
-
};
|
|
1167
|
-
}
|
|
1168
|
-
return {
|
|
1169
|
-
content: [{
|
|
1170
|
-
type: 'text',
|
|
1171
|
-
text: JSON.stringify(items)
|
|
1172
|
-
}],
|
|
1173
|
-
};
|
|
1174
|
-
});
|
|
717
|
+
}, async ({ id }) => handleGetFeatureUserStories(tp, id));
|
|
1175
718
|
server.registerTool('get_user_story_bugs', {
|
|
1176
719
|
title: 'Get user story bugs',
|
|
1177
720
|
description: 'Get bugs linked to a TP user story by its ID',
|
|
@@ -1181,119 +724,23 @@ server.registerTool('get_user_story_bugs', {
|
|
|
1181
724
|
.max(6)
|
|
1182
725
|
.describe('TP user story ID (e.g. 145789)'),
|
|
1183
726
|
},
|
|
1184
|
-
}, async ({ id }) =>
|
|
1185
|
-
const response = await tp.getUserStoryBugs(id);
|
|
1186
|
-
if (!response) {
|
|
1187
|
-
return {
|
|
1188
|
-
content: [{
|
|
1189
|
-
type: 'text',
|
|
1190
|
-
text: `Failed to get bugs for user story id: ${id}`
|
|
1191
|
-
}],
|
|
1192
|
-
};
|
|
1193
|
-
}
|
|
1194
|
-
const items = response.items || [];
|
|
1195
|
-
if (items.length === 0) {
|
|
1196
|
-
return {
|
|
1197
|
-
content: [{
|
|
1198
|
-
type: 'text',
|
|
1199
|
-
text: `No bugs found for user story id: ${id}`,
|
|
1200
|
-
}],
|
|
1201
|
-
};
|
|
1202
|
-
}
|
|
1203
|
-
return {
|
|
1204
|
-
content: [{
|
|
1205
|
-
type: 'text',
|
|
1206
|
-
text: JSON.stringify(items)
|
|
1207
|
-
}],
|
|
1208
|
-
};
|
|
1209
|
-
});
|
|
727
|
+
}, async ({ id }) => handleGetUserStoryBugs(tp, id));
|
|
1210
728
|
server.registerTool('get_projects', {
|
|
1211
729
|
title: 'Get projects',
|
|
1212
730
|
description: 'Get all Targetprocess projects',
|
|
1213
|
-
}, async (
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
type: 'text',
|
|
1219
|
-
text: `Failed to get projects, JSON: ${JSON.stringify(response, null, 2)}`
|
|
1220
|
-
}],
|
|
1221
|
-
};
|
|
1222
|
-
}
|
|
1223
|
-
const items = response.Items || [];
|
|
1224
|
-
if (items.length === 0) {
|
|
1225
|
-
return {
|
|
1226
|
-
content: [{
|
|
1227
|
-
type: 'text',
|
|
1228
|
-
text: `No projects found`,
|
|
1229
|
-
}],
|
|
1230
|
-
};
|
|
1231
|
-
}
|
|
1232
|
-
return {
|
|
1233
|
-
content: [{
|
|
1234
|
-
type: 'text',
|
|
1235
|
-
text: JSON.stringify(items.map((p) => ({ id: p.Id, name: p.Name })))
|
|
1236
|
-
}],
|
|
1237
|
-
};
|
|
1238
|
-
});
|
|
731
|
+
}, async () => handleGetProjects(tp));
|
|
732
|
+
server.registerTool('get_teams_and_team_assignments', {
|
|
733
|
+
title: 'Get teams and team assignments',
|
|
734
|
+
description: 'Get all Targetprocess teams and team assignments',
|
|
735
|
+
}, async () => handleGetTeamsAndTeamAssignments(tp));
|
|
1239
736
|
server.registerTool('get_teams', {
|
|
1240
737
|
title: 'Get teams',
|
|
1241
738
|
description: 'Get all Targetprocess teams',
|
|
1242
|
-
}, async (
|
|
1243
|
-
const response = await tp.getTeams();
|
|
1244
|
-
if (!response) {
|
|
1245
|
-
return {
|
|
1246
|
-
content: [{
|
|
1247
|
-
type: 'text',
|
|
1248
|
-
text: `Failed to get teams, JSON: ${JSON.stringify(response, null, 2)}`
|
|
1249
|
-
}],
|
|
1250
|
-
};
|
|
1251
|
-
}
|
|
1252
|
-
const items = response.Items || [];
|
|
1253
|
-
if (items.length === 0) {
|
|
1254
|
-
return {
|
|
1255
|
-
content: [{
|
|
1256
|
-
type: 'text',
|
|
1257
|
-
text: `No teams found`,
|
|
1258
|
-
}],
|
|
1259
|
-
};
|
|
1260
|
-
}
|
|
1261
|
-
return {
|
|
1262
|
-
content: [{
|
|
1263
|
-
type: 'text',
|
|
1264
|
-
text: JSON.stringify(items.map((t) => ({ id: t.Id, name: t.Name })))
|
|
1265
|
-
}],
|
|
1266
|
-
};
|
|
1267
|
-
});
|
|
739
|
+
}, async () => handleGetTeams(tp));
|
|
1268
740
|
server.registerTool('get_logged_in_user', {
|
|
1269
741
|
title: 'Get logged in user',
|
|
1270
742
|
description: 'Get logged in user',
|
|
1271
|
-
}, async () =>
|
|
1272
|
-
const ctx = await tp.getContext();
|
|
1273
|
-
if (!ctx) {
|
|
1274
|
-
return {
|
|
1275
|
-
content: [{
|
|
1276
|
-
type: 'text',
|
|
1277
|
-
text: `Failed to get context, JSON: ${JSON.stringify(ctx, null, 2)}`
|
|
1278
|
-
}],
|
|
1279
|
-
};
|
|
1280
|
-
}
|
|
1281
|
-
const loggedInUser = ctx.LoggedUser;
|
|
1282
|
-
if (!loggedInUser) {
|
|
1283
|
-
return {
|
|
1284
|
-
content: [{
|
|
1285
|
-
type: 'text',
|
|
1286
|
-
text: `Failed to get logged in user in this context, JSON: ${JSON.stringify(ctx, null, 2)}`
|
|
1287
|
-
}],
|
|
1288
|
-
};
|
|
1289
|
-
}
|
|
1290
|
-
return {
|
|
1291
|
-
content: [{
|
|
1292
|
-
type: 'text',
|
|
1293
|
-
text: JSON.stringify(loggedInUser)
|
|
1294
|
-
}],
|
|
1295
|
-
};
|
|
1296
|
-
});
|
|
743
|
+
}, async () => handleGetLoggedInUser(tp));
|
|
1297
744
|
server.registerTool('get_user_story_test_cases', {
|
|
1298
745
|
title: 'Get test cases for TP UserStory card',
|
|
1299
746
|
description: `Fetches a TP UserStory Linked Test Plan and fetches its Test Cases by provided card ID.`,
|
|
@@ -1613,8 +1060,7 @@ server.registerTool('get_user_story_workflows', {
|
|
|
1613
1060
|
id: w.id,
|
|
1614
1061
|
processId: w.workflow.process.id,
|
|
1615
1062
|
entityType: w.entityType.name,
|
|
1616
|
-
|
|
1617
|
-
entitySubStates: w.subEntityStates.map((es) => ({
|
|
1063
|
+
entityStates: w.subEntityStates.map((es) => ({
|
|
1618
1064
|
id: es.id,
|
|
1619
1065
|
name: es.name,
|
|
1620
1066
|
})),
|
|
@@ -1639,32 +1085,7 @@ server.registerTool('get_card_current_status', {
|
|
|
1639
1085
|
.optional()
|
|
1640
1086
|
.describe('Type of the TP card — UserStory, Bug, or Feature (default: UserStory)'),
|
|
1641
1087
|
},
|
|
1642
|
-
}, async ({ id, resourceType = 'UserStory' }) =>
|
|
1643
|
-
const response = await tp.getCardStatus(id, resourceType);
|
|
1644
|
-
if (!response) {
|
|
1645
|
-
return {
|
|
1646
|
-
content: [{
|
|
1647
|
-
type: 'text',
|
|
1648
|
-
text: `Failed to get card status for ${resourceType} id: ${id}`
|
|
1649
|
-
}],
|
|
1650
|
-
};
|
|
1651
|
-
}
|
|
1652
|
-
const items = response.items || [];
|
|
1653
|
-
if (items.length === 0) {
|
|
1654
|
-
return {
|
|
1655
|
-
content: [{
|
|
1656
|
-
type: 'text',
|
|
1657
|
-
text: `No status data found for ${resourceType} id: ${id}`,
|
|
1658
|
-
}],
|
|
1659
|
-
};
|
|
1660
|
-
}
|
|
1661
|
-
return {
|
|
1662
|
-
content: [{
|
|
1663
|
-
type: 'text',
|
|
1664
|
-
text: JSON.stringify(items[0])
|
|
1665
|
-
}],
|
|
1666
|
-
};
|
|
1667
|
-
});
|
|
1088
|
+
}, async ({ id, resourceType = 'UserStory' }) => handleGetCardCurrentStatus(tp, id, resourceType));
|
|
1668
1089
|
server.registerTool('get_in_progress_tasks_and_bugs', {
|
|
1669
1090
|
title: 'Get in-progress tasks and bugs for a user',
|
|
1670
1091
|
description: 'Get all Tasks and Bugs currently in "In Progress" state assigned to a given user ID',
|
|
@@ -1672,44 +1093,7 @@ server.registerTool('get_in_progress_tasks_and_bugs', {
|
|
|
1672
1093
|
userId: z.string()
|
|
1673
1094
|
.describe('Targetprocess user ID (e.g. 123)'),
|
|
1674
1095
|
},
|
|
1675
|
-
}, async ({ userId }) =>
|
|
1676
|
-
const result = await tp.getInProgressTasksAndBugs(userId);
|
|
1677
|
-
const tasks = result.tasks.map((t) => ({
|
|
1678
|
-
type: 'Task',
|
|
1679
|
-
id: t.Id,
|
|
1680
|
-
name: t.Name,
|
|
1681
|
-
state: t.EntityState?.Name,
|
|
1682
|
-
userStoryId: t.UserStory?.Id,
|
|
1683
|
-
userStoryName: t.UserStory?.Name,
|
|
1684
|
-
featureId: t.UserStory?.Feature?.Id,
|
|
1685
|
-
featureName: t.UserStory?.Feature?.Name,
|
|
1686
|
-
}));
|
|
1687
|
-
const bugs = result.bugs.map((b) => ({
|
|
1688
|
-
type: 'Bug',
|
|
1689
|
-
id: b.Id,
|
|
1690
|
-
name: b.Name,
|
|
1691
|
-
state: b.EntityState?.Name,
|
|
1692
|
-
userStoryId: b.UserStory?.Id,
|
|
1693
|
-
userStoryName: b.UserStory?.Name,
|
|
1694
|
-
featureId: b.UserStory?.Feature?.Id ?? b.Feature?.Id,
|
|
1695
|
-
featureName: b.UserStory?.Feature?.Name ?? b.Feature?.Name,
|
|
1696
|
-
}));
|
|
1697
|
-
const items = [...tasks, ...bugs];
|
|
1698
|
-
if (items.length === 0) {
|
|
1699
|
-
return {
|
|
1700
|
-
content: [{
|
|
1701
|
-
type: 'text',
|
|
1702
|
-
text: `No in-progress tasks or bugs found for user ID: ${userId}`,
|
|
1703
|
-
}],
|
|
1704
|
-
};
|
|
1705
|
-
}
|
|
1706
|
-
return {
|
|
1707
|
-
content: [{
|
|
1708
|
-
type: 'text',
|
|
1709
|
-
text: JSON.stringify(items),
|
|
1710
|
-
}],
|
|
1711
|
-
};
|
|
1712
|
-
});
|
|
1096
|
+
}, async ({ userId }) => handleGetInProgressTasksAndBugs(tp, userId));
|
|
1713
1097
|
server.registerTool('create_task', {
|
|
1714
1098
|
title: 'Create a new task',
|
|
1715
1099
|
description: 'Create a new task linked to a user story.',
|
|
@@ -1724,23 +1108,7 @@ server.registerTool('create_task', {
|
|
|
1724
1108
|
.optional()
|
|
1725
1109
|
.describe('Task description (optional)'),
|
|
1726
1110
|
},
|
|
1727
|
-
}, async ({ title, userStoryId, description }) => {
|
|
1728
|
-
const taskResponse = await tp.createTask({ title, userStoryId, description });
|
|
1729
|
-
if (!taskResponse) {
|
|
1730
|
-
return {
|
|
1731
|
-
content: [{
|
|
1732
|
-
type: 'text',
|
|
1733
|
-
text: `Failed to create task "${title}"\n JSON: ${JSON.stringify(taskResponse, null, 2)}`
|
|
1734
|
-
}]
|
|
1735
|
-
};
|
|
1736
|
-
}
|
|
1737
|
-
return {
|
|
1738
|
-
content: [{
|
|
1739
|
-
type: 'text',
|
|
1740
|
-
text: JSON.stringify(taskResponse)
|
|
1741
|
-
}],
|
|
1742
|
-
};
|
|
1743
|
-
});
|
|
1111
|
+
}, async ({ title, userStoryId, description }) => handleCreateTask(tp, { title, userStoryId, description }));
|
|
1744
1112
|
server.registerTool('get_commit_message', {
|
|
1745
1113
|
title: 'Get commit message for a task or bug',
|
|
1746
1114
|
description: `Returns the formatted commit message string for a given task or bug ID.
|
|
@@ -1754,49 +1122,7 @@ Formats:
|
|
|
1754
1122
|
type: z.enum(['task', 'bug'])
|
|
1755
1123
|
.describe('Whether the ID refers to a task or a bug'),
|
|
1756
1124
|
},
|
|
1757
|
-
}, async ({ id, type }) =>
|
|
1758
|
-
if (type === 'task') {
|
|
1759
|
-
const task = await tp.getTask(id);
|
|
1760
|
-
if (!task) {
|
|
1761
|
-
return {
|
|
1762
|
-
content: [{ type: 'text', text: `Failed to get task with id: ${id}` }],
|
|
1763
|
-
};
|
|
1764
|
-
}
|
|
1765
|
-
const userStory = task.UserStory;
|
|
1766
|
-
const feature = userStory?.Feature;
|
|
1767
|
-
if (!userStory) {
|
|
1768
|
-
return {
|
|
1769
|
-
content: [{ type: 'text', text: `Task ${id} has no linked user story` }],
|
|
1770
|
-
};
|
|
1771
|
-
}
|
|
1772
|
-
const prefix = feature
|
|
1773
|
-
? `F#${feature.Id} US#${userStory.Id} T#${task.Id}`
|
|
1774
|
-
: `US#${userStory.Id} T#${task.Id}`;
|
|
1775
|
-
return {
|
|
1776
|
-
content: [{ type: 'text', text: `${prefix} ${task.Name}` }],
|
|
1777
|
-
};
|
|
1778
|
-
}
|
|
1779
|
-
// type === 'bug'
|
|
1780
|
-
const bug = await tp.getBugWithRelations(id);
|
|
1781
|
-
if (!bug) {
|
|
1782
|
-
return {
|
|
1783
|
-
content: [{ type: 'text', text: `Failed to get bug with id: ${id}` }],
|
|
1784
|
-
};
|
|
1785
|
-
}
|
|
1786
|
-
const userStory = bug.UserStory;
|
|
1787
|
-
const feature = userStory?.Feature ?? bug.Feature;
|
|
1788
|
-
if (!userStory) {
|
|
1789
|
-
return {
|
|
1790
|
-
content: [{ type: 'text', text: `B#${bug.Id} ${bug.Name}` }],
|
|
1791
|
-
};
|
|
1792
|
-
}
|
|
1793
|
-
const prefix = feature
|
|
1794
|
-
? `F#${feature.Id} US#${userStory.Id} B#${bug.Id}`
|
|
1795
|
-
: `US#${userStory.Id} B#${bug.Id}`;
|
|
1796
|
-
return {
|
|
1797
|
-
content: [{ type: 'text', text: `${prefix} ${bug.Name}` }],
|
|
1798
|
-
};
|
|
1799
|
-
});
|
|
1125
|
+
}, async ({ id, type }) => handleGetCommitMessage(tp, id, type));
|
|
1800
1126
|
server.registerTool('list_my_user_stories', {
|
|
1801
1127
|
title: 'List my user stories',
|
|
1802
1128
|
description: 'List User Stories assigned to me. Use this to get an overview of current work. Optionally filter by state.',
|
|
@@ -1813,32 +1139,7 @@ server.registerTool('list_my_user_stories', {
|
|
|
1813
1139
|
.optional()
|
|
1814
1140
|
.describe('Pagination offset, default is 0'),
|
|
1815
1141
|
},
|
|
1816
|
-
}, async ({ state, take, skip }) => {
|
|
1817
|
-
const response = await tp.getMyUserStories({ state, take, skip });
|
|
1818
|
-
if (!response) {
|
|
1819
|
-
return {
|
|
1820
|
-
content: [{
|
|
1821
|
-
type: 'text',
|
|
1822
|
-
text: `Failed to get user stories, JSON: ${JSON.stringify(response, null, 2)}`
|
|
1823
|
-
}],
|
|
1824
|
-
};
|
|
1825
|
-
}
|
|
1826
|
-
const items = response.Items || [];
|
|
1827
|
-
if (items.length === 0) {
|
|
1828
|
-
return {
|
|
1829
|
-
content: [{
|
|
1830
|
-
type: 'text',
|
|
1831
|
-
text: `No user stories assigned to you${state ? ` with state "${state}"` : ''}`,
|
|
1832
|
-
}],
|
|
1833
|
-
};
|
|
1834
|
-
}
|
|
1835
|
-
return {
|
|
1836
|
-
content: [{
|
|
1837
|
-
type: 'text',
|
|
1838
|
-
text: JSON.stringify(items)
|
|
1839
|
-
}],
|
|
1840
|
-
};
|
|
1841
|
-
});
|
|
1142
|
+
}, async ({ state, take, skip }) => handleListMyUserStories(tp, { state, take, skip }));
|
|
1842
1143
|
server.registerTool('list_my_bugs', {
|
|
1843
1144
|
title: 'List my bugs',
|
|
1844
1145
|
description: 'List Bugs assigned to me. Optionally filter by state.',
|
|
@@ -1855,32 +1156,7 @@ server.registerTool('list_my_bugs', {
|
|
|
1855
1156
|
.optional()
|
|
1856
1157
|
.describe('Pagination offset, default is 0'),
|
|
1857
1158
|
},
|
|
1858
|
-
}, async ({ state, take, skip }) => {
|
|
1859
|
-
const response = await tp.getMyBugs({ state, take, skip });
|
|
1860
|
-
if (!response) {
|
|
1861
|
-
return {
|
|
1862
|
-
content: [{
|
|
1863
|
-
type: 'text',
|
|
1864
|
-
text: `Failed to get bugs, JSON: ${JSON.stringify(response, null, 2)}`
|
|
1865
|
-
}],
|
|
1866
|
-
};
|
|
1867
|
-
}
|
|
1868
|
-
const items = response.Items || [];
|
|
1869
|
-
if (items.length === 0) {
|
|
1870
|
-
return {
|
|
1871
|
-
content: [{
|
|
1872
|
-
type: 'text',
|
|
1873
|
-
text: `No bugs assigned to you${state ? ` with state "${state}"` : ''}`,
|
|
1874
|
-
}],
|
|
1875
|
-
};
|
|
1876
|
-
}
|
|
1877
|
-
return {
|
|
1878
|
-
content: [{
|
|
1879
|
-
type: 'text',
|
|
1880
|
-
text: JSON.stringify(items)
|
|
1881
|
-
}],
|
|
1882
|
-
};
|
|
1883
|
-
});
|
|
1159
|
+
}, async ({ state, take, skip }) => handleListMyBugs(tp, { state, take, skip }));
|
|
1884
1160
|
server.registerTool('log_time', {
|
|
1885
1161
|
title: 'Log time on a Task, User Story, or Bug',
|
|
1886
1162
|
description: 'Log time spent working on a Task, User Story, or Bug. Call this after completing a task or at the end of a work session.',
|
|
@@ -1900,23 +1176,7 @@ server.registerTool('log_time', {
|
|
|
1900
1176
|
.optional()
|
|
1901
1177
|
.describe('ISO date string, defaults to today (e.g. "2024-05-21")'),
|
|
1902
1178
|
},
|
|
1903
|
-
}, async ({ entityId, entityType, hours, description, date }) => {
|
|
1904
|
-
const response = await tp.logTime({ entityId, entityType, hours, description, date });
|
|
1905
|
-
if (!response) {
|
|
1906
|
-
return {
|
|
1907
|
-
content: [{
|
|
1908
|
-
type: 'text',
|
|
1909
|
-
text: `Failed to log time on ${entityType} id: ${entityId}`
|
|
1910
|
-
}],
|
|
1911
|
-
};
|
|
1912
|
-
}
|
|
1913
|
-
return {
|
|
1914
|
-
content: [{
|
|
1915
|
-
type: 'text',
|
|
1916
|
-
text: JSON.stringify(response)
|
|
1917
|
-
}],
|
|
1918
|
-
};
|
|
1919
|
-
});
|
|
1179
|
+
}, async ({ entityId, entityType, hours, description, date }) => handleLogTime(tp, { entityId, entityType, hours, description, date }));
|
|
1920
1180
|
server.registerTool('get_my_time_logs', {
|
|
1921
1181
|
title: 'Get my recent time log entries',
|
|
1922
1182
|
description: 'Get recent time log entries submitted by me.',
|
|
@@ -1926,32 +1186,7 @@ server.registerTool('get_my_time_logs', {
|
|
|
1926
1186
|
.optional()
|
|
1927
1187
|
.describe('Number of entries to return, default is 25'),
|
|
1928
1188
|
},
|
|
1929
|
-
}, async ({ take }) =>
|
|
1930
|
-
const response = await tp.getMyTimeLogs(take);
|
|
1931
|
-
if (!response) {
|
|
1932
|
-
return {
|
|
1933
|
-
content: [{
|
|
1934
|
-
type: 'text',
|
|
1935
|
-
text: `Failed to get time logs, JSON: ${JSON.stringify(response, null, 2)}`
|
|
1936
|
-
}],
|
|
1937
|
-
};
|
|
1938
|
-
}
|
|
1939
|
-
const items = response.Items || [];
|
|
1940
|
-
if (items.length === 0) {
|
|
1941
|
-
return {
|
|
1942
|
-
content: [{
|
|
1943
|
-
type: 'text',
|
|
1944
|
-
text: `No time logs found`,
|
|
1945
|
-
}],
|
|
1946
|
-
};
|
|
1947
|
-
}
|
|
1948
|
-
return {
|
|
1949
|
-
content: [{
|
|
1950
|
-
type: 'text',
|
|
1951
|
-
text: JSON.stringify(items)
|
|
1952
|
-
}],
|
|
1953
|
-
};
|
|
1954
|
-
});
|
|
1189
|
+
}, async ({ take }) => handleGetMyTimeLogs(tp, take));
|
|
1955
1190
|
async function main() {
|
|
1956
1191
|
const transport = new StdioServerTransport();
|
|
1957
1192
|
await server.connect(transport);
|