targetprocess-mcp-server 2.2.10 → 2.2.12

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
@@ -63,6 +63,7 @@ Cards — Read
63
63
 
64
64
  Cards — Write
65
65
  - `add_comment` — Post a comment to any card (id, comment)
66
+ - `add_comment_with_user` — Post a comment to any card and mention a specific user (id, comment, user object from `get_users`)
66
67
  - `update_bug` — Update an existing bug (id, optional title, optional bugContent, optional origin, optional projectId, optional teamId, optional entityStateId)
67
68
  > Resolve state name → ID via `get_bug_workflows` before passing `entityStateId`
68
69
  - `update_user_story` — Update an existing user story (id, optional title, optional description, optional projectId, optional teamId, optional entityStateId)
@@ -103,6 +104,7 @@ Teams
103
104
 
104
105
  User
105
106
  - `get_logged_in_user` — Get the currently logged-in user's info (no params needed)
107
+ - `get_users` — Get all Targetprocess users (no params needed)
106
108
 
107
109
  Developer Tools
108
110
  - `get_commit_message` — Returns a formatted commit message string for a task or bug ID (id, type: task | bug)
package/build/index.js CHANGED
@@ -435,6 +435,89 @@ server.registerTool('get_bug_content', {
435
435
  }],
436
436
  };
437
437
  });
438
+ server.registerTool('get_users', {
439
+ title: 'Get users',
440
+ description: 'Get all users',
441
+ }, async () => {
442
+ const response = await tp.getUsers();
443
+ if (!response) {
444
+ return {
445
+ content: [{
446
+ type: 'text',
447
+ text: `Failed to get users, JSON: ${JSON.stringify(response, null, 2)}`
448
+ }],
449
+ };
450
+ }
451
+ const items = response.Items || [];
452
+ if (items.length === 0) {
453
+ return {
454
+ content: [{
455
+ type: 'text',
456
+ text: `No users found`,
457
+ }],
458
+ };
459
+ }
460
+ return {
461
+ content: [{
462
+ type: 'text',
463
+ text: JSON.stringify(items)
464
+ }],
465
+ };
466
+ });
467
+ server.registerTool('add_comment_with_user', {
468
+ title: 'Adds provided content to TP card (user story) as a comment',
469
+ description: `Adds provided content as a comment to the specified tp card by id, e.g. 145789 and mentions the user in the comment
470
+ CRITICAL WORKFLOW:
471
+ 1) call 'get_users' to get list of available users
472
+ 2) find the user by email, first name, or last name in the users list
473
+ `,
474
+ inputSchema: {
475
+ id: z.string()
476
+ .min(5)
477
+ .max(6)
478
+ .describe('TP card id, usually user story or bug ID (e.g. 145789)'),
479
+ comment: z.string()
480
+ .describe('Comment content to add'),
481
+ user: z.object({
482
+ Email: z.string()
483
+ .describe('User email'),
484
+ FirstName: z.string()
485
+ .describe('User first name'),
486
+ LastName: z.string()
487
+ .describe('User last name'),
488
+ IsActive: z.boolean()
489
+ .describe('User is active'),
490
+ })
491
+ .describe('User to add to the comment, from "get_users" tool'),
492
+ },
493
+ }, async ({ id, comment, user }) => {
494
+ try {
495
+ const addCommentResponse = await tp.addCommentWithUser(id, comment, user);
496
+ if (!addCommentResponse) {
497
+ return {
498
+ content: [{
499
+ type: 'text',
500
+ text: `Failed to add comment to user story id: ${id}`
501
+ }]
502
+ };
503
+ }
504
+ return {
505
+ content: [{
506
+ type: 'text',
507
+ text: JSON.stringify(addCommentResponse)
508
+ }],
509
+ };
510
+ }
511
+ catch (error) {
512
+ console.error("Error adding comment to user story:", error);
513
+ return {
514
+ content: [{
515
+ type: 'text',
516
+ text: `Failed to add comment to user story id: ${id}`
517
+ }]
518
+ };
519
+ }
520
+ });
438
521
  server.registerTool('add_comment', {
439
522
  title: 'Adds provided content to TP card (user story) as a comment',
440
523
  description: `Adds provided content as a comment to the specified tp card by id, e.g. 145789`,
@@ -603,7 +686,7 @@ server.registerTool('create_bug_based_on_card', {
603
686
  CRITICAL WORKFLOW: Before calling this tool, you MUST follow these steps:
604
687
  1) IF you already have user story, bug, or feature card content, proceed to step 3 skipping step 2;
605
688
  2) ELSE call "get_user_story_content" tool, "get_bug_content" tool, or fetch the feature to get card content;
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>);
689
+ 3) format the new bug inside html <div> tags with Environment (describes where bug was found, dev, feature, review or uat 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
690
  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
691
  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;
609
692
  6) add a comment to the card with created bug Id and its Title`,
@@ -636,7 +719,7 @@ server.registerTool('create_bug_based_on_card', {
636
719
  ])
637
720
  .default("Manual QA")
638
721
  .optional()
639
- .describe('Where the bug was found, defaults to "Manual QA"'),
722
+ .describe('Where the bug was found, defaults to "Manual QA" if no origin was specified'),
640
723
  projectId: z.string()
641
724
  .optional()
642
725
  .describe('Optional Project ID — if user gave a project name, resolve it via "get_projects" first; defaults to TP_PROJECT_ID from config'),
@@ -771,7 +854,7 @@ server.registerTool('create_bug', {
771
854
  description: `Create a new bug card that summarizes the problem in concise, descriptive manner answering questions "What? Where? When?" and content explaining what happened in detail.
772
855
  NOTE: this tool does not require a user story or bug card reference.
773
856
  CRITICAL WORKFLOW: Before calling this tool, you MUST follow these steps:
774
- 1) 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>, step to reproduce should be wrapped in <ol>);
857
+ 1) format the new bug inside html <div> tags with Environment(describes where bug was found, dev, feature, review or uat 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>, step to reproduce should be wrapped in <ol>);
775
858
  2) IF the user specified a team by name (not ID), call "get_teams" to find the matching team and use its ID as teamId;
776
859
  3) IF the user specified a project by name (not ID), call "get_projects" to find the matching project and use its ID as projectId;`,
777
860
  inputSchema: {
@@ -792,7 +875,7 @@ server.registerTool('create_bug', {
792
875
  ])
793
876
  .default("Manual QA")
794
877
  .optional()
795
- .describe('Where the bug was found, defaults to "Manual QA"'),
878
+ .describe('Where the bug was found, defaults to "Manual QA" if no origin was specified'),
796
879
  projectId: z.string()
797
880
  .optional()
798
881
  .describe('Optional Project ID — if user gave a project name, resolve it via "get_projects" first; defaults to TP_PROJECT_ID from config'),
@@ -1481,9 +1564,9 @@ server.registerTool('get_bug_workflows', {
1481
1564
  });
1482
1565
  server.registerTool('get_user_story_workflows', {
1483
1566
  title: 'Get User Story workflows',
1484
- description: 'Get all Targetprocess user story workflows',
1567
+ description: 'Get all Targetprocess user story workflows, with sub-states',
1485
1568
  }, async ({}) => {
1486
- const response = await tp.getUserStoryWorkflows();
1569
+ const response = await tp.getUserStoryWorkflowsWithSubStates();
1487
1570
  if (!response) {
1488
1571
  return {
1489
1572
  content: [{
@@ -1501,12 +1584,13 @@ server.registerTool('get_user_story_workflows', {
1501
1584
  }],
1502
1585
  };
1503
1586
  }
1504
- const workflows = items.map((w) => ({
1587
+ const userStoryWorkflows = items.filter((w) => w.entityType.name === "UserStory");
1588
+ const workflows = userStoryWorkflows.map((w) => ({
1505
1589
  id: w.id,
1506
- name: w.name,
1507
- processId: w.process,
1508
- entityType: w.entityType,
1509
- entityStates: w.entityStates.map((es) => ({
1590
+ processId: w.workflow.process.id,
1591
+ entityType: w.entityType.name,
1592
+ entityState: w.name,
1593
+ entitySubStates: w.subEntityStates.map((es) => ({
1510
1594
  id: es.id,
1511
1595
  name: es.name,
1512
1596
  })),
package/build/tp.js CHANGED
@@ -310,6 +310,29 @@ export class TpClient {
310
310
  param: { "format": "json" },
311
311
  }, testPlan);
312
312
  }
313
+ async getUsers() {
314
+ return this.get({
315
+ pathParam: ["Users"],
316
+ param: { "format": "json" },
317
+ });
318
+ }
319
+ async addCommentWithUser(userStoryId, comment, user) {
320
+ const userAt = user ? `cc - <div>@user:${user.Email}[${user.FirstName} ${user.LastName}]&nbsp;</div>` : '';
321
+ const commentContent = `${comment}\nn${userAt}`;
322
+ const commentData = {
323
+ description: commentContent,
324
+ owner: {
325
+ id: config.tp.ownerId
326
+ },
327
+ general: {
328
+ id: userStoryId,
329
+ },
330
+ };
331
+ return this.post({
332
+ pathParam: ["comments"],
333
+ param: { "format": "json" },
334
+ }, commentData);
335
+ }
313
336
  async addComment(userStoryId, comment) {
314
337
  const commentData = {
315
338
  description: comment,
@@ -562,6 +585,18 @@ export class TpClient {
562
585
  apiVersion: this.v2
563
586
  });
564
587
  }
588
+ async getUserStoryWorkflowsWithSubStates() {
589
+ return this.get({
590
+ pathParam: ["EntityState"],
591
+ param: {
592
+ "format": "json",
593
+ "select": `{id,name,isInitial,isFinal,isDefaultFinal,isPlanned,workflow:{workflow.id,process:{workflow.process.id}},entityType:{entityType.name},subEntityStates:subEntityStates.Select({id,name,entityType:{entityType.name},isInitial,isFinal,isDefaultFinal,isPlanned})}`,
594
+ "where": `(parentEntityState==null and workflow.process.id in [${config.tp.processId}])`,
595
+ "take": "1000",
596
+ },
597
+ apiVersion: this.v2
598
+ });
599
+ }
565
600
  async getBugWorkflows() {
566
601
  return this.get({
567
602
  pathParam: ["workflow"],
package/package.json CHANGED
@@ -25,7 +25,7 @@
25
25
  "engines": {
26
26
  "node": ">=20.x"
27
27
  },
28
- "version": "2.2.10",
28
+ "version": "2.2.12",
29
29
  "description": "MCP server for Tartget Process",
30
30
  "main": "build/index.js",
31
31
  "keywords": [