targetprocess-mcp-server 2.2.8 → 2.2.10
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 +10 -0
- package/build/index.js +137 -5
- package/build/tp.js +55 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,6 +48,10 @@ Features
|
|
|
48
48
|
User Stories
|
|
49
49
|
- `get_user_story_bugs` — Get all bugs linked to a user story by its ID (id)
|
|
50
50
|
|
|
51
|
+
Tasks
|
|
52
|
+
- `get_in_progress_tasks_and_bugs` — Get all Tasks and Bugs currently in "In Progress" state assigned to a given user (userId)
|
|
53
|
+
- `create_task` — Create a new task linked to a user story (title, userStoryId, optional description)
|
|
54
|
+
|
|
51
55
|
Cards — Read
|
|
52
56
|
- `get_card_current_status` — Get EntityState, TeamState, and assigned teams for a card (id, optional resourceType: UserStory | Bug | Feature, default: UserStory)
|
|
53
57
|
- `get_bug_content` — Fetch full content of a bug by ID (id)
|
|
@@ -100,6 +104,12 @@ Teams
|
|
|
100
104
|
User
|
|
101
105
|
- `get_logged_in_user` — Get the currently logged-in user's info (no params needed)
|
|
102
106
|
|
|
107
|
+
Developer Tools
|
|
108
|
+
- `get_commit_message` — Returns a formatted commit message string for a task or bug ID (id, type: task | bug)
|
|
109
|
+
> Format for task on a user story: `F#<featureId> US#<userStoryId> T#<taskId> <title>`
|
|
110
|
+
> Format for bug on a user story: `F#<featureId> US#<userStoryId> B#<bugId> <title>`
|
|
111
|
+
> Format for standalone bug: `B#<bugId> <title>`
|
|
112
|
+
|
|
103
113
|
|
|
104
114
|
---
|
|
105
115
|
|
package/build/index.js
CHANGED
|
@@ -599,10 +599,10 @@ server.registerTool('get_bug_comments', {
|
|
|
599
599
|
server.registerTool('create_bug_based_on_card', {
|
|
600
600
|
title: 'Create a new bug card based on provided card id',
|
|
601
601
|
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.
|
|
602
|
-
NOTE: this tool requires a user story or
|
|
602
|
+
NOTE: this tool requires a user story, bug, or feature card as a reference (i.e. card ID).
|
|
603
603
|
CRITICAL WORKFLOW: Before calling this tool, you MUST follow these steps:
|
|
604
|
-
1) IF you already have user story or
|
|
605
|
-
2) ELSE call "get_user_story_content" tool
|
|
604
|
+
1) IF you already have user story, bug, or feature card content, proceed to step 3 skipping step 2;
|
|
605
|
+
2) ELSE call "get_user_story_content" tool, "get_bug_content" tool, or fetch the feature to get card content;
|
|
606
606
|
3) format the new bug inside html <div> tags with Environment, Issue Description, Steps to Reproduce, Expected Behavior, Actual Behavior and Attachments sections (note: section titles should be wrapped in <h3> tags, e.g. <h3>Issue Description</h3>);
|
|
607
607
|
4) IF the user specified a team by name (not ID), call "get_teams" to find the matching team and use its ID as teamId;
|
|
608
608
|
5) IF the user specified a project by name (not ID), call "get_projects" to find the matching project and use its ID as projectId;
|
|
@@ -614,8 +614,8 @@ server.registerTool('create_bug_based_on_card', {
|
|
|
614
614
|
id: z.string()
|
|
615
615
|
.min(5)
|
|
616
616
|
.max(6)
|
|
617
|
-
.describe(`Usually user story id or
|
|
618
|
-
type: z.enum(["UserStory", "Bug"])
|
|
617
|
+
.describe(`Usually user story id, bug ID, or feature ID (e.g. 145789)`),
|
|
618
|
+
type: z.enum(["UserStory", "Bug", "Feature"])
|
|
619
619
|
}),
|
|
620
620
|
bugContent: z.string()
|
|
621
621
|
.describe(`Comment content to add, explain what happened in detail.
|
|
@@ -1557,6 +1557,138 @@ server.registerTool('get_card_current_status', {
|
|
|
1557
1557
|
}],
|
|
1558
1558
|
};
|
|
1559
1559
|
});
|
|
1560
|
+
server.registerTool('get_in_progress_tasks_and_bugs', {
|
|
1561
|
+
title: 'Get in-progress tasks and bugs for a user',
|
|
1562
|
+
description: 'Get all Tasks and Bugs currently in "In Progress" state assigned to a given user ID',
|
|
1563
|
+
inputSchema: {
|
|
1564
|
+
userId: z.string()
|
|
1565
|
+
.describe('Targetprocess user ID (e.g. 123)'),
|
|
1566
|
+
},
|
|
1567
|
+
}, async ({ userId }) => {
|
|
1568
|
+
const result = await tp.getInProgressTasksAndBugs(userId);
|
|
1569
|
+
const tasks = result.tasks.map((t) => ({
|
|
1570
|
+
type: 'Task',
|
|
1571
|
+
id: t.Id,
|
|
1572
|
+
name: t.Name,
|
|
1573
|
+
state: t.EntityState?.Name,
|
|
1574
|
+
userStoryId: t.UserStory?.Id,
|
|
1575
|
+
userStoryName: t.UserStory?.Name,
|
|
1576
|
+
featureId: t.UserStory?.Feature?.Id,
|
|
1577
|
+
featureName: t.UserStory?.Feature?.Name,
|
|
1578
|
+
}));
|
|
1579
|
+
const bugs = result.bugs.map((b) => ({
|
|
1580
|
+
type: 'Bug',
|
|
1581
|
+
id: b.Id,
|
|
1582
|
+
name: b.Name,
|
|
1583
|
+
state: b.EntityState?.Name,
|
|
1584
|
+
userStoryId: b.UserStory?.Id,
|
|
1585
|
+
userStoryName: b.UserStory?.Name,
|
|
1586
|
+
featureId: b.UserStory?.Feature?.Id ?? b.Feature?.Id,
|
|
1587
|
+
featureName: b.UserStory?.Feature?.Name ?? b.Feature?.Name,
|
|
1588
|
+
}));
|
|
1589
|
+
const items = [...tasks, ...bugs];
|
|
1590
|
+
if (items.length === 0) {
|
|
1591
|
+
return {
|
|
1592
|
+
content: [{
|
|
1593
|
+
type: 'text',
|
|
1594
|
+
text: `No in-progress tasks or bugs found for user ID: ${userId}`,
|
|
1595
|
+
}],
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1598
|
+
return {
|
|
1599
|
+
content: [{
|
|
1600
|
+
type: 'text',
|
|
1601
|
+
text: JSON.stringify(items),
|
|
1602
|
+
}],
|
|
1603
|
+
};
|
|
1604
|
+
});
|
|
1605
|
+
server.registerTool('create_task', {
|
|
1606
|
+
title: 'Create a new task',
|
|
1607
|
+
description: 'Create a new task linked to a user story.',
|
|
1608
|
+
inputSchema: {
|
|
1609
|
+
title: z.string()
|
|
1610
|
+
.describe('Task title'),
|
|
1611
|
+
userStoryId: z.string()
|
|
1612
|
+
.min(5)
|
|
1613
|
+
.max(6)
|
|
1614
|
+
.describe('User story ID to link the task to (e.g. 145789)'),
|
|
1615
|
+
description: z.string()
|
|
1616
|
+
.optional()
|
|
1617
|
+
.describe('Task description (optional)'),
|
|
1618
|
+
},
|
|
1619
|
+
}, async ({ title, userStoryId, description }) => {
|
|
1620
|
+
const taskResponse = await tp.createTask({ title, userStoryId, description });
|
|
1621
|
+
if (!taskResponse) {
|
|
1622
|
+
return {
|
|
1623
|
+
content: [{
|
|
1624
|
+
type: 'text',
|
|
1625
|
+
text: `Failed to create task "${title}"\n JSON: ${JSON.stringify(taskResponse, null, 2)}`
|
|
1626
|
+
}]
|
|
1627
|
+
};
|
|
1628
|
+
}
|
|
1629
|
+
return {
|
|
1630
|
+
content: [{
|
|
1631
|
+
type: 'text',
|
|
1632
|
+
text: JSON.stringify(taskResponse)
|
|
1633
|
+
}],
|
|
1634
|
+
};
|
|
1635
|
+
});
|
|
1636
|
+
server.registerTool('get_commit_message', {
|
|
1637
|
+
title: 'Get commit message for a task or bug',
|
|
1638
|
+
description: `Returns the formatted commit message string for a given task or bug ID.
|
|
1639
|
+
Formats:
|
|
1640
|
+
- Task on a user story: "F#<featureId> US#<userStoryId> T#<taskId> <title>"
|
|
1641
|
+
- Bug on a user story: "F#<featureId> US#<userStoryId> B#<bugId> <title>"
|
|
1642
|
+
- Standalone bug (no user story): "B#<bugId> <title>"`,
|
|
1643
|
+
inputSchema: {
|
|
1644
|
+
id: z.string()
|
|
1645
|
+
.describe('The task or bug ID (e.g. 145789)'),
|
|
1646
|
+
type: z.enum(['task', 'bug'])
|
|
1647
|
+
.describe('Whether the ID refers to a task or a bug'),
|
|
1648
|
+
},
|
|
1649
|
+
}, async ({ id, type }) => {
|
|
1650
|
+
if (type === 'task') {
|
|
1651
|
+
const task = await tp.getTask(id);
|
|
1652
|
+
if (!task) {
|
|
1653
|
+
return {
|
|
1654
|
+
content: [{ type: 'text', text: `Failed to get task with id: ${id}` }],
|
|
1655
|
+
};
|
|
1656
|
+
}
|
|
1657
|
+
const userStory = task.UserStory;
|
|
1658
|
+
const feature = userStory?.Feature;
|
|
1659
|
+
if (!userStory) {
|
|
1660
|
+
return {
|
|
1661
|
+
content: [{ type: 'text', text: `Task ${id} has no linked user story` }],
|
|
1662
|
+
};
|
|
1663
|
+
}
|
|
1664
|
+
const prefix = feature
|
|
1665
|
+
? `F#${feature.Id} US#${userStory.Id} T#${task.Id}`
|
|
1666
|
+
: `US#${userStory.Id} T#${task.Id}`;
|
|
1667
|
+
return {
|
|
1668
|
+
content: [{ type: 'text', text: `${prefix} ${task.Name}` }],
|
|
1669
|
+
};
|
|
1670
|
+
}
|
|
1671
|
+
// type === 'bug'
|
|
1672
|
+
const bug = await tp.getBugWithRelations(id);
|
|
1673
|
+
if (!bug) {
|
|
1674
|
+
return {
|
|
1675
|
+
content: [{ type: 'text', text: `Failed to get bug with id: ${id}` }],
|
|
1676
|
+
};
|
|
1677
|
+
}
|
|
1678
|
+
const userStory = bug.UserStory;
|
|
1679
|
+
const feature = userStory?.Feature ?? bug.Feature;
|
|
1680
|
+
if (!userStory) {
|
|
1681
|
+
return {
|
|
1682
|
+
content: [{ type: 'text', text: `B#${bug.Id} ${bug.Name}` }],
|
|
1683
|
+
};
|
|
1684
|
+
}
|
|
1685
|
+
const prefix = feature
|
|
1686
|
+
? `F#${feature.Id} US#${userStory.Id} B#${bug.Id}`
|
|
1687
|
+
: `US#${userStory.Id} B#${bug.Id}`;
|
|
1688
|
+
return {
|
|
1689
|
+
content: [{ type: 'text', text: `${prefix} ${bug.Name}` }],
|
|
1690
|
+
};
|
|
1691
|
+
});
|
|
1560
1692
|
async function main() {
|
|
1561
1693
|
const transport = new StdioServerTransport();
|
|
1562
1694
|
await server.connect(transport);
|
package/build/tp.js
CHANGED
|
@@ -120,9 +120,10 @@ export class TpClient {
|
|
|
120
120
|
"Description": bugContent,
|
|
121
121
|
};
|
|
122
122
|
if (card.type === "UserStory") {
|
|
123
|
-
bug["UserStory"] = {
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
bug["UserStory"] = { "Id": card.id };
|
|
124
|
+
}
|
|
125
|
+
else if (card.type === "Feature") {
|
|
126
|
+
bug["Feature"] = { "Id": card.id };
|
|
126
127
|
}
|
|
127
128
|
return this.post({
|
|
128
129
|
pathParam: ["bugs"],
|
|
@@ -591,6 +592,57 @@ export class TpClient {
|
|
|
591
592
|
param: { "format": "json" }
|
|
592
593
|
});
|
|
593
594
|
}
|
|
595
|
+
async getInProgressTasksAndBugs(userId) {
|
|
596
|
+
const where = `(EntityState.Name eq 'In Progress') and (AssignedUser.Id eq ${userId})`;
|
|
597
|
+
const include = "[Id,Name,EntityState[Name],UserStory[Id,Name,Feature[Id,Name]]]";
|
|
598
|
+
const param = { "format": "json", "where": where, "include": include, "orderByDesc": "ModifyDate" };
|
|
599
|
+
const [tasks, bugs] = await Promise.all([
|
|
600
|
+
this.get({ pathParam: ["Tasks"], param }),
|
|
601
|
+
this.get({ pathParam: ["Bugs"], param }),
|
|
602
|
+
]);
|
|
603
|
+
return {
|
|
604
|
+
tasks: tasks?.Items ?? [],
|
|
605
|
+
bugs: bugs?.Items ?? [],
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
async getTask(taskId) {
|
|
609
|
+
const response = await this.get({
|
|
610
|
+
pathParam: ["Tasks", taskId],
|
|
611
|
+
param: {
|
|
612
|
+
"format": "json",
|
|
613
|
+
"include": "[Id,Name,UserStory[Id,Name,Feature[Id,Name]]]",
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
return response;
|
|
617
|
+
}
|
|
618
|
+
async getBugWithRelations(bugId) {
|
|
619
|
+
const response = await this.get({
|
|
620
|
+
pathParam: ["Bugs", bugId],
|
|
621
|
+
param: {
|
|
622
|
+
"format": "json",
|
|
623
|
+
"include": "[Id,Name,UserStory[Id,Name,Feature[Id,Name]]]",
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
return response;
|
|
627
|
+
}
|
|
628
|
+
async createTask({ title, description, userStoryId }) {
|
|
629
|
+
const task = {
|
|
630
|
+
"Name": title,
|
|
631
|
+
"Project": {
|
|
632
|
+
"Id": config.tp.projectId
|
|
633
|
+
},
|
|
634
|
+
"UserStory": {
|
|
635
|
+
"Id": userStoryId
|
|
636
|
+
},
|
|
637
|
+
};
|
|
638
|
+
if (description) {
|
|
639
|
+
task["Description"] = description;
|
|
640
|
+
}
|
|
641
|
+
return this.post({
|
|
642
|
+
pathParam: ["Tasks"],
|
|
643
|
+
param: { "format": "json" },
|
|
644
|
+
}, task);
|
|
645
|
+
}
|
|
594
646
|
async addAttachedFile(generalId, source) {
|
|
595
647
|
let blob;
|
|
596
648
|
let fileName;
|