targetprocess-mcp-server 2.4.2 → 2.4.4

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/build/index.js CHANGED
@@ -23,7 +23,7 @@ import { handleAddComment } from "./handlers/add_comment.js";
23
23
  import { handleGetUserStoryComments } from "./handlers/get_user_story_comments.js";
24
24
  import { handleGetBugComments } from "./handlers/get_bug_comments.js";
25
25
  import { handleCreateBug } from "./handlers/create_bug.js";
26
- // import { handleCreateUserStory } from "./handlers/create_user_story.js";
26
+ import { handleCreateUserStory } from "./handlers/create_user_story.js";
27
27
  import { handleCreateFeature } from "./handlers/create_feature.js";
28
28
  import { handleCreateTask } from "./handlers/create_task.js";
29
29
  import { handleUpdateBug } from "./handlers/update_bug.js";
@@ -39,7 +39,6 @@ import { handleUpdateUserStorySubState } from "./handlers/update_user_story_sub_
39
39
  import { handleGetCardRelations } from "./handlers/get_card_relations.js";
40
40
  import { handleCreateCardRelation } from "./handlers/create_card_relation.js";
41
41
  import { handleDeleteCardRelation } from "./handlers/delete_card_relation.js";
42
- import { handleFormatExistingUserStory } from "./handlers/format_existing_user_story.js";
43
42
  const server = new McpServer({
44
43
  name: "tp",
45
44
  version: "1.0.0"
@@ -531,39 +530,34 @@ server.registerTool('create_bug', {
531
530
  .describe('Optional Entity State ID — if user gave a state name, resolve it via "get_bug_workflows" first; defaults to "Done"'),
532
531
  },
533
532
  }, async ({ title, bugContent, origin, projectId, teamId, entityStateId }) => handleCreateBug(tp, { title, bugContent, origin, projectId, teamId, entityStateId }));
534
- // server.registerTool(
535
- // 'create_user_story',
536
- // {
537
- // title: 'Create a new user story',
538
- // description: `Create a new user story in Targetprocess.`,
539
- // inputSchema: {
540
- // title: z.string()
541
- // .describe('User story title'),
542
- // description: z.string()
543
- // .optional()
544
- // .describe('Optional user story description (when provided, format as HTML)'),
545
- // featureId: z.string()
546
- // .min(5)
547
- // .max(6)
548
- // .optional()
549
- // .describe('Optional Feature ID to link this user story to (e.g. 145636)'),
550
- // releaseId: z.string()
551
- // .min(5)
552
- // .max(6)
553
- // .optional()
554
- // .describe('Optional Release ID to link this user story to (e.g. 145200)'),
555
- // projectId: z.string()
556
- // .optional()
557
- // .describe('Optional Project ID — defaults to TP_PROJECT_ID from config'),
558
- // teamId: z.string()
559
- // .optional()
560
- // .describe('Optional Team ID — defaults to TP_TEAM_ID from config'),
561
- // },
562
- // },
563
- // async ({ title, description, featureId, releaseId, projectId, teamId }) =>
564
- // handleCreateUserStory(tp, { title, description, featureId, releaseId, projectId, teamId })
565
- // )
566
533
  server.registerTool('create_user_story', {
534
+ title: 'Create a new user story',
535
+ description: `Create a new user story in Targetprocess.`,
536
+ inputSchema: {
537
+ title: z.string()
538
+ .describe('User story title'),
539
+ description: z.string()
540
+ .optional()
541
+ .describe('Optional user story description (when provided, format as HTML)'),
542
+ featureId: z.string()
543
+ .min(5)
544
+ .max(6)
545
+ .optional()
546
+ .describe('Optional Feature ID to link this user story to (e.g. 145636)'),
547
+ releaseId: z.string()
548
+ .min(5)
549
+ .max(6)
550
+ .optional()
551
+ .describe('Optional Release ID to link this user story to (e.g. 145200)'),
552
+ projectId: z.string()
553
+ .optional()
554
+ .describe('Optional Project ID — defaults to TP_PROJECT_ID from config'),
555
+ teamId: z.string()
556
+ .optional()
557
+ .describe('Optional Team ID — defaults to TP_TEAM_ID from config'),
558
+ },
559
+ }, async ({ title, description, featureId, releaseId, projectId, teamId }) => handleCreateUserStory(tp, { title, description, featureId, releaseId, projectId, teamId }));
560
+ server.registerTool('create_formatted_user_story', {
567
561
  title: 'Create a formatted user story',
568
562
  description: `Create a new user story in Targetprocess with a structured, template-driven description.
569
563
  The description is assembled from discrete sections (header, definitions, acceptance criteria, Gherkin scenarios, edge cases, references, notes) and stored as HTML.
@@ -641,12 +635,12 @@ server.registerTool('create_user_story', {
641
635
  .describe('Optional Team ID — defaults to TP_TEAM_ID from config'),
642
636
  },
643
637
  }, async ({ title, header, definitions, acceptanceCriteria, scenarios, examplesTable, edgeCases, references, notes, featureId, releaseId, projectId, teamId }) => {
644
- const gherkinBlock = (items) => items.map((s, indx) => `<div><strong>Scenario ${indx + 1} - ${s.name}:</strong></div><div>${s.steps.map(step => `<div>\t${step}</div>`).join('\n')}</div>`).join('\n');
638
+ const gherkinBlock = (items) => items.map((s, indx) => `<div><strong>Scenario ${indx + 1} - ${s.name}:</strong></div><div>${s.steps.map(step => `<div>\t${step}</div>`).join('\n')}</div>`).join('<br>');
645
639
  const parts = ['<div>'];
646
640
  parts.push('<h3>Header</h3>');
647
641
  if (header.storyId)
648
642
  parts.push(`<p><strong>Story ID:</strong> ${header.storyId}</p>`);
649
- parts.push(`<p>As a ${header.asA} / I want ${header.iWant} / so that ${header.soThat}</p>`);
643
+ parts.push(`<p>As a ${header.asA} <br> I want ${header.iWant} <br> so that ${header.soThat}</p>`);
650
644
  if (definitions) {
651
645
  parts.push('<h3>Definitions</h3>');
652
646
  parts.push(`<div>`);
@@ -1386,72 +1380,6 @@ server.registerTool('get_my_time_logs', {
1386
1380
  .describe('Number of entries to return, default is 25'),
1387
1381
  },
1388
1382
  }, async ({ take }) => handleGetMyTimeLogs(tp, take));
1389
- server.registerTool('format_existing_user_story', {
1390
- title: 'Format an existing user story',
1391
- description: `Re-format the description of an existing user story using the structured template (Header, Definitions, Acceptance Criteria, Gherkin Scenarios, Edge Cases, References, Notes).
1392
- This is identical in structure to "create_user_story" but updates an existing card instead of creating a new one.
1393
- CRITICAL WORKFLOW: Before calling this tool, you MUST follow these steps:
1394
- 1) Call "get_user_story_content" to retrieve the current content of the user story;
1395
- 2) Extract or derive the structured fields (header, definitions, acceptanceCriteria, scenarios, etc.) from the existing description;
1396
- 3) Optionally update the title if the user requested it.`,
1397
- inputSchema: {
1398
- id: z.string()
1399
- .min(5)
1400
- .max(6)
1401
- .describe('ID of the user story to format (e.g. 145789)'),
1402
- title: z.string()
1403
- .optional()
1404
- .describe('Updated user story title — omit to keep the existing title'),
1405
- header: z.object({
1406
- storyId: z.string()
1407
- .optional()
1408
- .describe('Story ID if already known (e.g. US-12345), omit if not applicable'),
1409
- asA: z.string()
1410
- .describe('Role or persona — the "As a ..." part'),
1411
- iWant: z.string()
1412
- .describe('Goal — the "I want ..." part'),
1413
- soThat: z.string()
1414
- .describe('Benefit — the "so that ..." part'),
1415
- })
1416
- .describe('Story header following the As a / I want / so that format'),
1417
- definitions: z.array(z.object({
1418
- term: z.string()
1419
- .describe('The term, module name, or feature flag being defined'),
1420
- description: z.string()
1421
- .describe('Explanation of the term'),
1422
- })),
1423
- acceptanceCriteria: z.array(z.string())
1424
- .min(1)
1425
- .describe('Bullet checklist items for quick review sign-off — each string is one criterion'),
1426
- scenarios: z.array(z.object({
1427
- name: z.string()
1428
- .describe('Scenario name'),
1429
- steps: z.array(z.string())
1430
- .min(1)
1431
- .describe('Gherkin steps — each string is a full step line, e.g. "Given I am on the login page"'),
1432
- }))
1433
- .min(1)
1434
- .describe('Gherkin scenario blocks, one per behavior branch'),
1435
- examplesTable: z.string()
1436
- .optional()
1437
- .describe('Examples table for parameterized or matrix behavior (plain text or Gherkin Examples: table format)'),
1438
- edgeCases: z.array(z.object({
1439
- name: z.string()
1440
- .describe('Edge case scenario name'),
1441
- steps: z.array(z.string())
1442
- .min(1)
1443
- .describe('Gherkin steps for this edge case'),
1444
- }))
1445
- .optional()
1446
- .describe('Explicit edge case or boundary condition scenarios'),
1447
- references: z.string()
1448
- .optional()
1449
- .describe('Links to Axure mockups or other external references (not inline in prose)'),
1450
- notes: z.string()
1451
- .optional()
1452
- .describe('Anything that helps understand the story context but does not fit other sections'),
1453
- },
1454
- }, async ({ id, title, header, definitions, acceptanceCriteria, scenarios, examplesTable, edgeCases, references, notes }) => handleFormatExistingUserStory(tp, { id, title, header, definitions, acceptanceCriteria, scenarios, examplesTable, edgeCases, references, notes }));
1455
1383
  async function main() {
1456
1384
  const transport = new StdioServerTransport();
1457
1385
  await server.connect(transport);
package/package.json CHANGED
@@ -27,7 +27,7 @@
27
27
  "engines": {
28
28
  "node": ">=20.x"
29
29
  },
30
- "version": "2.4.2",
30
+ "version": "2.4.4",
31
31
  "description": "MCP server for Tartget Process",
32
32
  "main": "build/index.js",
33
33
  "keywords": [
@@ -1,55 +0,0 @@
1
- export async function handleFormatExistingUserStory(tp, params) {
2
- const { id, title, header, definitions, acceptanceCriteria, scenarios, examplesTable, edgeCases, references, notes, } = params;
3
- const gherkinBlock = (items) => items.map((s, indx) => `<div><strong>Scenario ${indx + 1} - ${s.name}:</strong></div><div>${s.steps.map(step => `<div>\t${step}</div>`).join('\n')}</div>`).join('\n');
4
- const parts = ['<div>'];
5
- parts.push('<h3>Header</h3>');
6
- if (header.storyId)
7
- parts.push(`<p><strong>Story ID:</strong> ${header.storyId}</p>`);
8
- parts.push(`<p>As a ${header.asA} / I want ${header.iWant} / so that ${header.soThat}</p>`);
9
- if (definitions && definitions.length > 0) {
10
- parts.push('<h3>Definitions</h3>');
11
- parts.push(`<div>`);
12
- for (const def of definitions) {
13
- parts.push(`<p><strong>${def.term}</strong> — ${def.description}</p>`);
14
- }
15
- parts.push(`</div>`);
16
- }
17
- parts.push('<h3>Acceptance Criteria</h3>');
18
- parts.push('<ol>');
19
- for (const criterion of acceptanceCriteria) {
20
- parts.push(`<li>${criterion}</li>`);
21
- }
22
- parts.push('</ol>');
23
- parts.push('<h3>Scenarios</h3>');
24
- parts.push(gherkinBlock(scenarios));
25
- if (examplesTable) {
26
- parts.push('<h3>Examples</h3>');
27
- parts.push(`<pre>${examplesTable}</pre>`);
28
- }
29
- if (edgeCases && edgeCases.length > 0) {
30
- parts.push('<h3>Edge Cases</h3>');
31
- parts.push(gherkinBlock(edgeCases));
32
- }
33
- if (references) {
34
- parts.push('<h3>References</h3>');
35
- parts.push(`<p>${references}</p>`);
36
- }
37
- if (notes) {
38
- parts.push('<h3>Notes</h3>');
39
- parts.push(`<p>${notes}</p>`);
40
- }
41
- parts.push('</div>');
42
- const description = parts.join('\n');
43
- const response = await tp.updateUserStory({ id, title, description });
44
- if (!response) {
45
- return {
46
- content: [{
47
- type: 'text',
48
- text: `Failed to format user story id: ${id}\n JSON: ${JSON.stringify(response, null, 2)}`
49
- }],
50
- };
51
- }
52
- return {
53
- content: [{ type: 'text', text: JSON.stringify(response) }],
54
- };
55
- }