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 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 bug card as a reference (i.e. card ID).
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 bug card content, proceed to step 3 skipping step 2;
605
- 2) ELSE call "get_user_story_content" tool or "get_bug_content" tool to get user story or bug card content;
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 bug ID (e.g. 145789)`),
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
- "Id": card.id
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;
package/package.json CHANGED
@@ -25,7 +25,7 @@
25
25
  "engines": {
26
26
  "node": ">=20.x"
27
27
  },
28
- "version": "2.2.8",
28
+ "version": "2.2.10",
29
29
  "description": "MCP server for Tartget Process",
30
30
  "main": "build/index.js",
31
31
  "keywords": [