targetprocess-mcp-server 1.0.6 → 1.0.8
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 +28 -9
- package/build/index.js +132 -7
- package/build/tp.js +31 -2
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -36,12 +36,12 @@ It acts as a **bridge between LLM agents and the Targetprocess API**, providing:
|
|
|
36
36
|
---
|
|
37
37
|
|
|
38
38
|
## Installation
|
|
39
|
-
### Local
|
|
39
|
+
### Local Installation for Development
|
|
40
40
|
```json
|
|
41
41
|
{
|
|
42
42
|
"mcpServers": {
|
|
43
43
|
"targetprocess": {
|
|
44
|
-
"command": "/Users/
|
|
44
|
+
"command": "/Users/xxx/.config/nvm/versions/node/v22.14.0/bin/node",
|
|
45
45
|
"args": [
|
|
46
46
|
"/path/to/repository"
|
|
47
47
|
],
|
|
@@ -56,23 +56,42 @@ It acts as a **bridge between LLM agents and the Targetprocess API**, providing:
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
```
|
|
59
|
-
###
|
|
59
|
+
### Claude Desktop
|
|
60
|
+
|
|
61
|
+
> [!NOTE]
|
|
62
|
+
> You need to have `node` and `npm` installed on your machine.
|
|
63
|
+
|
|
60
64
|
```json
|
|
61
65
|
{
|
|
62
66
|
"mcpServers": {
|
|
63
|
-
"
|
|
64
|
-
"command": "
|
|
67
|
+
"targetprocess": {
|
|
68
|
+
"command": "npx",
|
|
69
|
+
"args": [
|
|
70
|
+
"-y",
|
|
71
|
+
"targetprocess-mcp-server"
|
|
72
|
+
],
|
|
65
73
|
"env": {
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
"
|
|
74
|
+
"TP_TOKEN": "<your-tp-token>" // Settings -> Authentication and Security -> New Access Token,
|
|
75
|
+
"TP_BASE_URL": "<tp-api-endpoint>",
|
|
76
|
+
"TP_API_VERSION": "v1",
|
|
77
|
+
"TP_OWNER_ID": "<tp-owner-id>", // your user id
|
|
78
|
+
"TP_PROJECT_ID": "<tp-project-id>",
|
|
79
|
+
"TP_TEAM_ID": "<tp-team-id>"
|
|
69
80
|
}
|
|
70
81
|
}
|
|
71
|
-
}
|
|
82
|
+
},
|
|
72
83
|
}
|
|
73
84
|
|
|
74
85
|
```
|
|
75
86
|
|
|
87
|
+
### Claude Code
|
|
88
|
+
```bash
|
|
89
|
+
claude mcp add tarteprocess -s user \
|
|
90
|
+
-- env TP_TOKEN=<your-tp-token> \
|
|
91
|
+
-- env TP_BASE_URL=<tp-api-endpoint> \
|
|
92
|
+
npx -y targetprocess-mcp-server
|
|
93
|
+
```
|
|
94
|
+
|
|
76
95
|
## Local Development
|
|
77
96
|
```
|
|
78
97
|
git clone --recursive https://github.com/SerhiiMaksymiv/targetprocess-mcp-server.git
|
package/build/index.js
CHANGED
|
@@ -438,6 +438,128 @@ server.registerTool('add_comment', {
|
|
|
438
438
|
};
|
|
439
439
|
}
|
|
440
440
|
});
|
|
441
|
+
server.registerTool('get_user_story_comments', {
|
|
442
|
+
title: 'Get user story comments',
|
|
443
|
+
description: 'Get comments for a TP user story by its ID',
|
|
444
|
+
inputSchema: {
|
|
445
|
+
id: z.string()
|
|
446
|
+
.min(5)
|
|
447
|
+
.max(6)
|
|
448
|
+
.describe('TP user story ID (e.g. 145789)'),
|
|
449
|
+
results: z.number()
|
|
450
|
+
.default(25)
|
|
451
|
+
.optional()
|
|
452
|
+
.describe('Number of comments to return, default is 25'),
|
|
453
|
+
},
|
|
454
|
+
}, async ({ id, results }) => {
|
|
455
|
+
const response = await tp.getUserStoryComments(id, results);
|
|
456
|
+
if (!response) {
|
|
457
|
+
return {
|
|
458
|
+
content: [{
|
|
459
|
+
type: 'text',
|
|
460
|
+
text: `Failed to get comments for user story id: ${id}`
|
|
461
|
+
}],
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
const items = response.Items || [];
|
|
465
|
+
if (items.length === 0) {
|
|
466
|
+
return {
|
|
467
|
+
content: [{
|
|
468
|
+
type: 'text',
|
|
469
|
+
text: `No comments found for user story id: ${id}`,
|
|
470
|
+
}],
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
let parsedItems = [];
|
|
474
|
+
try {
|
|
475
|
+
parsedItems = items.map((item) => {
|
|
476
|
+
const dom = new JSDOM(`<html><body><div id="content">${item.Description}</div></body></html>`);
|
|
477
|
+
const descriptionText = dom.window.document.getElementById('content')?.textContent;
|
|
478
|
+
return {
|
|
479
|
+
id: item.Id,
|
|
480
|
+
description: descriptionText,
|
|
481
|
+
createDate: item.CreateDate,
|
|
482
|
+
owner: item.Owner.FullName,
|
|
483
|
+
};
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
console.error("Error parsing user story comments:", error);
|
|
488
|
+
return {
|
|
489
|
+
content: [{
|
|
490
|
+
type: 'text',
|
|
491
|
+
text: `Failed to parse user story comments for user story id: ${id}`,
|
|
492
|
+
}],
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
return {
|
|
496
|
+
content: [{
|
|
497
|
+
type: 'text',
|
|
498
|
+
text: JSON.stringify(parsedItems)
|
|
499
|
+
}],
|
|
500
|
+
};
|
|
501
|
+
});
|
|
502
|
+
server.registerTool('get_bug_comments', {
|
|
503
|
+
title: 'Get bug comments',
|
|
504
|
+
description: 'Get comments for a TP bug by its ID',
|
|
505
|
+
inputSchema: {
|
|
506
|
+
id: z.string()
|
|
507
|
+
.min(5)
|
|
508
|
+
.max(6)
|
|
509
|
+
.describe('TP bug ID (e.g. 145789)'),
|
|
510
|
+
results: z.number()
|
|
511
|
+
.default(25)
|
|
512
|
+
.optional()
|
|
513
|
+
.describe('Number of comments to return, default is 25'),
|
|
514
|
+
},
|
|
515
|
+
}, async ({ id, results }) => {
|
|
516
|
+
const response = await tp.getBugComments(id, results);
|
|
517
|
+
if (!response) {
|
|
518
|
+
return {
|
|
519
|
+
content: [{
|
|
520
|
+
type: 'text',
|
|
521
|
+
text: `Failed to get comments for bug id: ${id}`
|
|
522
|
+
}],
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
const items = response.Items || [];
|
|
526
|
+
if (items.length === 0) {
|
|
527
|
+
return {
|
|
528
|
+
content: [{
|
|
529
|
+
type: 'text',
|
|
530
|
+
text: `No comments found for bug id: ${id}`,
|
|
531
|
+
}],
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
let parsedItems = [];
|
|
535
|
+
try {
|
|
536
|
+
parsedItems = items.map((item) => {
|
|
537
|
+
const dom = new JSDOM(`<html><body><div id="content">${item.Description}</div></body></html>`);
|
|
538
|
+
const descriptionText = dom.window.document.getElementById('content')?.textContent;
|
|
539
|
+
return {
|
|
540
|
+
id: item.Id,
|
|
541
|
+
description: descriptionText,
|
|
542
|
+
createDate: item.CreateDate,
|
|
543
|
+
owner: item.Owner.FullName,
|
|
544
|
+
};
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
catch (error) {
|
|
548
|
+
console.error("Error parsing bug comments:", error);
|
|
549
|
+
return {
|
|
550
|
+
content: [{
|
|
551
|
+
type: 'text',
|
|
552
|
+
text: `Failed to parse bug comments for bug id: ${id}`,
|
|
553
|
+
}],
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
return {
|
|
557
|
+
content: [{
|
|
558
|
+
type: 'text',
|
|
559
|
+
text: JSON.stringify(parsedItems)
|
|
560
|
+
}],
|
|
561
|
+
};
|
|
562
|
+
});
|
|
441
563
|
server.registerTool('create_bug', {
|
|
442
564
|
title: 'Create a new bug card based on provided card id',
|
|
443
565
|
description: `Create a new bug card based on provided card id that summarizes the problem in concise,
|
|
@@ -451,10 +573,13 @@ server.registerTool('create_bug', {
|
|
|
451
573
|
inputSchema: {
|
|
452
574
|
title: z.string()
|
|
453
575
|
.describe('Bug card title that summarizes the problem in concise, descriptive, and actionable manner, enabling a developer to understand the issue without opening the report'),
|
|
454
|
-
|
|
455
|
-
.
|
|
456
|
-
|
|
457
|
-
|
|
576
|
+
card: z.object({
|
|
577
|
+
id: z.string()
|
|
578
|
+
.min(5)
|
|
579
|
+
.max(6)
|
|
580
|
+
.describe(`Usually user story id or bug ID (e.g. 145789)`),
|
|
581
|
+
type: z.enum(["UserStory", "Bug"])
|
|
582
|
+
}),
|
|
458
583
|
bugContent: z.string()
|
|
459
584
|
.describe(`Comment content to add, explain what happened in detail.
|
|
460
585
|
Include expected behaviour and what actually occurred.
|
|
@@ -462,13 +587,13 @@ server.registerTool('create_bug', {
|
|
|
462
587
|
Clearly outline the actions needed to trigger the bug.
|
|
463
588
|
Number each step so anyone can follow them easily`),
|
|
464
589
|
},
|
|
465
|
-
}, async ({ title,
|
|
466
|
-
const bugResponse = await tp.
|
|
590
|
+
}, async ({ title, card, bugContent }) => {
|
|
591
|
+
const bugResponse = await tp.createBug({ title, card, bugContent });
|
|
467
592
|
if (!bugResponse) {
|
|
468
593
|
return {
|
|
469
594
|
content: [{
|
|
470
595
|
type: 'text',
|
|
471
|
-
text: `Failed to create
|
|
596
|
+
text: `Failed to create bug "${title}"\n JSON: ${JSON.stringify(bugResponse, null, 2)}`
|
|
472
597
|
}]
|
|
473
598
|
};
|
|
474
599
|
}
|
package/build/tp.js
CHANGED
|
@@ -94,12 +94,15 @@ export class TpClient {
|
|
|
94
94
|
});
|
|
95
95
|
return response;
|
|
96
96
|
}
|
|
97
|
-
async createBug(title, bugContent) {
|
|
97
|
+
async createBug({ title, card, bugContent }) {
|
|
98
98
|
const bug = {
|
|
99
99
|
"Name": title,
|
|
100
100
|
"Project": {
|
|
101
101
|
"Id": 59901
|
|
102
102
|
},
|
|
103
|
+
[card.type]: {
|
|
104
|
+
"Id": card.id
|
|
105
|
+
},
|
|
103
106
|
"customFields": [{
|
|
104
107
|
"name": "Origin",
|
|
105
108
|
"type": "DropDown",
|
|
@@ -117,7 +120,7 @@ export class TpClient {
|
|
|
117
120
|
param: { "format": "json" },
|
|
118
121
|
}, bug);
|
|
119
122
|
}
|
|
120
|
-
async
|
|
123
|
+
async createBugBasedOnUserStory(title, userStoryId, bugContent) {
|
|
121
124
|
const bug = {
|
|
122
125
|
"Name": title,
|
|
123
126
|
"Project": {
|
|
@@ -185,6 +188,32 @@ export class TpClient {
|
|
|
185
188
|
param: { "format": "json" },
|
|
186
189
|
}, commentData);
|
|
187
190
|
}
|
|
191
|
+
async getBugComments(bugId, results = 25) {
|
|
192
|
+
const response = await this.get({
|
|
193
|
+
pathParam: {
|
|
194
|
+
"Bugs": bugId,
|
|
195
|
+
"Comments": "",
|
|
196
|
+
},
|
|
197
|
+
param: {
|
|
198
|
+
"format": "json",
|
|
199
|
+
"take": results,
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
return response;
|
|
203
|
+
}
|
|
204
|
+
async getUserStoryComments(userStoryId, results = 25) {
|
|
205
|
+
const response = await this.get({
|
|
206
|
+
pathParam: {
|
|
207
|
+
"UserStories": userStoryId,
|
|
208
|
+
"Comments": "",
|
|
209
|
+
},
|
|
210
|
+
param: {
|
|
211
|
+
"format": "json",
|
|
212
|
+
"take": results,
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
return response;
|
|
216
|
+
}
|
|
188
217
|
async searchContainsNameText({ text, entityType }) {
|
|
189
218
|
return this.get({
|
|
190
219
|
pathParam: { [entityType]: '' },
|
package/package.json
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"publishConfig": {
|
|
14
14
|
"ignore": [
|
|
15
15
|
"!build/",
|
|
16
|
+
".claude/",
|
|
16
17
|
"src/",
|
|
17
18
|
"test/"
|
|
18
19
|
]
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
"engines": {
|
|
25
26
|
"node": ">=20.x"
|
|
26
27
|
},
|
|
27
|
-
"version": "1.0.
|
|
28
|
+
"version": "1.0.8",
|
|
28
29
|
"description": "MCP server for Tartget Process",
|
|
29
30
|
"main": "build/index.js",
|
|
30
31
|
"keywords": [
|