targetprocess-mcp-server 2.0.4 → 2.0.6

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
@@ -50,6 +50,7 @@ Cards — Read
50
50
  - `get_user_story_content` — Fetch full content of a user story by ID (id)
51
51
  - `get_bug_comments` — Get comments on a bug (id, optional results)
52
52
  - `get_user_story_comments` — Get comments on a user story (id, optional results)
53
+ - `get_user_story_test_cases` — Fetch the linked test plan and all its test cases (with steps) for a user story (resourceId)
53
54
  - `search_all_cards_by_keyword` — Search bugs, stories, and features by keyword (keyword)
54
55
 
55
56
  Cards — Write
package/build/index.js CHANGED
@@ -650,10 +650,9 @@ server.registerTool('create_bug_based_on_card', {
650
650
  server.registerTool('create_bug', {
651
651
  title: 'Create a new bug card',
652
652
  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.
653
- NOTE: this tool does not require a user story or bug card referenced.
653
+ NOTE: this tool does not require a user story or bug card reference.
654
654
  CRITICAL WORKFLOW: Before calling this tool, you MUST follow these steps:
655
- 1) format the new bug inside html <div> tags with Issue Description, Steps to Reproduce, Expected Behavior, Actual Behavior sections (note: section titles should be wrapped in <h3> tags, e.g. <h3>Issue Description</h3>);
656
- 2) add a comment to the newly created bug with its Id and Title`,
655
+ 1) format the new bug inside html <div> tags with Issue Description, Steps to Reproduce, Expected Behavior, Actual Behavior sections (note: section titles should be wrapped in <h3> tags, e.g. <h3>Issue Description</h3>);`,
657
656
  inputSchema: {
658
657
  title: z.string()
659
658
  .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'),
@@ -946,6 +945,81 @@ server.registerTool('get_logged_in_user', {
946
945
  }],
947
946
  };
948
947
  });
948
+ server.registerTool('get_user_story_test_cases', {
949
+ title: 'Get test cases for TP UserStory card',
950
+ description: `Fetches a TP UserStory Linked Test Plan and fetches its Test Cases by provided card ID.`,
951
+ inputSchema: {
952
+ resourceId: z.string()
953
+ .min(5)
954
+ .max(6)
955
+ .describe('TP UserStory ID (e.g. 145789)')
956
+ },
957
+ }, async ({ resourceId }) => {
958
+ const userStoryResponse = await tp.getUserStoryTestPlan(resourceId);
959
+ if (!userStoryResponse) {
960
+ return {
961
+ content: [{
962
+ type: 'text',
963
+ text: `Failed to get test user story, JSON: ${JSON.stringify(userStoryResponse, null, 2)}`
964
+ }],
965
+ };
966
+ }
967
+ const items = userStoryResponse.items;
968
+ if (items.length === 0) {
969
+ return {
970
+ content: [{
971
+ type: 'text',
972
+ text: `No items in ${resourceId} user story response`,
973
+ }],
974
+ };
975
+ }
976
+ const testPlan = items[0].linkedTestPlan;
977
+ if (!testPlan) {
978
+ return {
979
+ content: [{
980
+ type: 'text',
981
+ text: `No linked test plan found for user story id: ${resourceId}`,
982
+ }],
983
+ };
984
+ }
985
+ const testCases = await tp.getTestPlanTestCases(String(testPlan.id));
986
+ if (testCases.Items.length === 0) {
987
+ return {
988
+ content: [{
989
+ type: 'text',
990
+ text: `No test cases found in test plan id: ${testPlan.id}`,
991
+ }],
992
+ };
993
+ }
994
+ const testCaseItems = testCases.Items;
995
+ if (!testCaseItems || testCaseItems.length === 0) {
996
+ return {
997
+ content: [{
998
+ type: 'text',
999
+ text: `No test case items found in test plan id: ${testPlan.id}`,
1000
+ }],
1001
+ };
1002
+ }
1003
+ const testCasesData = await Promise.all(testCaseItems.map(async (item) => {
1004
+ const testCaseSteps = await tp.getTestCaseSteps(String(item.Id));
1005
+ return {
1006
+ testCaseId: item.Id,
1007
+ testCaseName: item.Name,
1008
+ testCaseDescription: item.Description,
1009
+ testCaseSteps: testCaseSteps.Items.map((step) => ({
1010
+ description: step.Description,
1011
+ result: step.Result,
1012
+ runOrder: step.RunOrder,
1013
+ }))
1014
+ };
1015
+ }));
1016
+ return {
1017
+ content: [{
1018
+ type: 'text',
1019
+ text: JSON.stringify(testCasesData)
1020
+ }],
1021
+ };
1022
+ });
949
1023
  server.registerTool('write_test_cases', {
950
1024
  title: 'Write test cases for a TP card (UserStory, Bug, or Feature)',
951
1025
  description: `Fetches a TP card (UserStory, Bug, or Feature) content by ID.
package/build/tp.js CHANGED
@@ -381,6 +381,53 @@ export class TpClient {
381
381
  apiVersion: this.v2
382
382
  });
383
383
  }
384
+ async getUserStoryTestPlan(userStoryId) {
385
+ return this.get({
386
+ pathParam: { "userStories": userStoryId },
387
+ param: {
388
+ "format": "json",
389
+ "select": `{id,storyName:name,linkedtestplan}`,
390
+ },
391
+ apiVersion: this.v2
392
+ });
393
+ }
394
+ async getCardTestPlan(cardId, resourceType = 'UserStory') {
395
+ let requestPath = "";
396
+ if (resourceType === 'UserStory') {
397
+ requestPath = "userStories";
398
+ }
399
+ else if (resourceType === 'Bug') {
400
+ requestPath = "bugs";
401
+ }
402
+ else if (resourceType === 'Feature') {
403
+ requestPath = "features";
404
+ }
405
+ return this.get({
406
+ pathParam: { [requestPath]: cardId },
407
+ param: {
408
+ "format": "json",
409
+ "select": `{id,linkedtestplan}`,
410
+ },
411
+ });
412
+ }
413
+ async getTestPlanTestCases(testPlanId) {
414
+ return this.get({
415
+ pathParam: {
416
+ "testPlans": testPlanId,
417
+ "testcases": "",
418
+ },
419
+ param: { "format": "json" },
420
+ });
421
+ }
422
+ async getTestCaseSteps(testCaseId) {
423
+ return this.get({
424
+ pathParam: {
425
+ "testCases": testCaseId,
426
+ "teststeps": "",
427
+ },
428
+ param: { "format": "json", },
429
+ });
430
+ }
384
431
  async getProjects() {
385
432
  return this.get({
386
433
  pathParam: { "Projects": '' },
package/package.json CHANGED
@@ -25,7 +25,7 @@
25
25
  "engines": {
26
26
  "node": ">=20.x"
27
27
  },
28
- "version": "2.0.4",
28
+ "version": "2.0.6",
29
29
  "description": "MCP server for Tartget Process",
30
30
  "main": "build/index.js",
31
31
  "keywords": [