@k-system/tickr-mcp 0.7.0 → 0.8.0

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.
@@ -12,6 +12,7 @@ export function formatTicketMarkdown(t) {
12
12
  `| Scope | ${t.scope || "-"} |`,
13
13
  `| Assignee | ${t.assigneeName || "Unassigned"} |`,
14
14
  `| Estimate | ${t.estimate || "-"} |`,
15
+ `| External ID | ${t.externalId || "-"} |`,
15
16
  `| Created | ${t.createdAt} |`,
16
17
  `| Updated | ${t.updatedAt} |`,
17
18
  ];
@@ -33,15 +34,15 @@ export function formatTicketMarkdown(t) {
33
34
  lines.push("", "---", "", t.content);
34
35
  }
35
36
  if (t.implementationItems?.length > 0) {
36
- lines.push("", "## Implementation Items", "", "| # | Area | Detail | Status | Note |", "|---|------|--------|--------|------|");
37
+ lines.push("", "## Implementation Items", "", "| # | Id | Area | Detail | Status | Note |", "|---|----|------|--------|--------|------|");
37
38
  t.implementationItems.forEach((item, i) => {
38
- lines.push(`| ${i} | ${item.area} | ${item.fileOrDetail} | ${item.status} | ${item.note || "-"} |`);
39
+ lines.push(`| ${i} | ${item.id} | ${item.area} | ${item.fileOrDetail} | ${item.status} | ${item.note || "-"} |`);
39
40
  });
40
41
  }
41
42
  if (t.relations && t.relations.length > 0) {
42
- lines.push("", "## Relations", "", "| Type | Direction | Ticket | Title | Status |", "|------|-----------|--------|-------|--------|");
43
+ lines.push("", "## Relations", "", "| Id | Type | Direction | Ticket | Title | Status |", "|----|------|-----------|--------|-------|--------|");
43
44
  for (const r of t.relations) {
44
- lines.push(`| ${r.type} | ${r.direction} | ${r.displayNumber} | ${r.title} | ${r.status} |`);
45
+ lines.push(`| ${r.id} | ${r.type} | ${r.direction} | ${r.displayNumber} | ${r.title} | ${r.status} |`);
45
46
  }
46
47
  }
47
48
  if (t.comments?.length > 0) {
@@ -7,6 +7,7 @@ export function registerCreateEpic(server, api) {
7
7
  color: z.string().optional().describe("Epic color hex code (e.g. #6366f1)"),
8
8
  start_date: z.string().optional().describe("Start date (YYYY-MM-DD)"),
9
9
  target_date: z.string().optional().describe("Target date (YYYY-MM-DD)"),
10
+ external_id: z.string().optional().describe("External identifier for linking to other systems"),
10
11
  }, async (params) => {
11
12
  try {
12
13
  const result = await api.post(`/api/projects/${params.project}/epics`, {
@@ -15,6 +16,7 @@ export function registerCreateEpic(server, api) {
15
16
  color: params.color,
16
17
  startDate: params.start_date,
17
18
  targetDate: params.target_date,
19
+ externalId: params.external_id,
18
20
  });
19
21
  return {
20
22
  content: [
@@ -9,6 +9,7 @@ export function registerCreateTicket(server, api) {
9
9
  content: z.string().optional().describe("Markdown content (analysis, solution)"),
10
10
  affected_parts: z.array(z.string()).optional(),
11
11
  due_date: z.string().optional().describe("Due date in YYYY-MM-DD format"),
12
+ external_id: z.string().optional().describe("External identifier (e.g. JIRA-123, GH-456)"),
12
13
  }, async (params) => {
13
14
  try {
14
15
  // Unescapovat double-escaped newlines z MCP tool parametrů
@@ -21,6 +22,7 @@ export function registerCreateTicket(server, api) {
21
22
  content,
22
23
  affectedParts: params.affected_parts,
23
24
  dueDate: params.due_date,
25
+ externalId: params.external_id,
24
26
  });
25
27
  return {
26
28
  content: [
@@ -6,7 +6,7 @@ export function registerListCycles(server, api) {
6
6
  try {
7
7
  const cycles = await api.get(`/api/projects/${params.project}/cycles`);
8
8
  const text = cycles
9
- .map((c) => `#${c.number}${c.name ? ` ${c.name}` : ""} [${c.status}] ${c.startDate}–${c.endDate} (${c.completedTickets}/${c.totalTickets})`)
9
+ .map((c) => `#${c.number}${c.name ? ` ${c.name}` : ""} (${c.id}) [${c.status}] ${c.startDate}–${c.endDate} (${c.completedTickets}/${c.totalTickets})`)
10
10
  .join("\n");
11
11
  return {
12
12
  content: [{ type: "text", text: text || "No cycles found." }],
@@ -6,7 +6,7 @@ export function registerListEpics(server, api) {
6
6
  try {
7
7
  const epics = await api.get(`/api/projects/${params.project}/epics`);
8
8
  const text = epics
9
- .map((e) => `${e.name} [${e.status}] (${e.completedTickets}/${e.totalTickets})${e.targetDate ? ` target: ${e.targetDate}` : ""}`)
9
+ .map((e) => `${e.name} (${e.id}) [${e.status}] (${e.completedTickets}/${e.totalTickets})${e.targetDate ? ` target: ${e.targetDate}` : ""}`)
10
10
  .join("\n");
11
11
  return {
12
12
  content: [{ type: "text", text: text || "No epics found." }],
@@ -6,7 +6,7 @@ export function registerListLabels(server, api) {
6
6
  try {
7
7
  const labels = await api.get(`/api/projects/${params.project}/labels`);
8
8
  const text = labels
9
- .map((l) => `${l.name} (${l.color})`)
9
+ .map((l) => `${l.name} (${l.id}) [${l.color}]`)
10
10
  .join("\n");
11
11
  return {
12
12
  content: [{ type: "text", text: text || "No labels configured." }],
@@ -8,6 +8,7 @@ export function registerUpdateEpic(server, api) {
8
8
  color: z.string().optional().describe("New hex color code, e.g. '#6366f1'"),
9
9
  startDate: z.string().optional().describe("New start date (YYYY-MM-DD)"),
10
10
  targetDate: z.string().optional().describe("New target date (YYYY-MM-DD)"),
11
+ external_id: z.string().optional().describe("External identifier"),
11
12
  }, async (params) => {
12
13
  try {
13
14
  const body = {};
@@ -21,6 +22,8 @@ export function registerUpdateEpic(server, api) {
21
22
  body.startDate = params.startDate;
22
23
  if (params.targetDate !== undefined)
23
24
  body.targetDate = params.targetDate;
25
+ if (params.external_id !== undefined)
26
+ body.externalId = params.external_id;
24
27
  await api.put(`/api/projects/${params.project}/epics/${params.epic_id}`, body);
25
28
  return {
26
29
  content: [
@@ -2,14 +2,14 @@ import { z } from "zod";
2
2
  export function registerUpdateImplementationItem(server, api) {
3
3
  server.tool("update_implementation_item", "Update an implementation item on a ticket", {
4
4
  number: z.string().describe("Ticket display number, e.g. 'TKR-42' (legacy) or 'TKR-BUG-0042' (typed)"),
5
- item_index: z.number().describe("0-based index in implementation table"),
5
+ item_id: z.string().describe("Implementation item GUID (from get_ticket output)"),
6
6
  status: z
7
7
  .enum(["todo", "in-progress", "done", "skipped"])
8
8
  .optional(),
9
9
  note: z.string().optional(),
10
10
  }, async (params) => {
11
11
  try {
12
- await api.patch(`/api/tickets/${params.number}/items/${params.item_index}`, {
12
+ await api.put(`/api/tickets/${params.number}/items/${params.item_id}`, {
13
13
  status: params.status,
14
14
  note: params.note?.replace(/\\n/g, "\n"),
15
15
  });
@@ -17,7 +17,7 @@ export function registerUpdateImplementationItem(server, api) {
17
17
  content: [
18
18
  {
19
19
  type: "text",
20
- text: `Item #${params.item_index} updated on ${params.number}`,
20
+ text: `Item ${params.item_id} updated on ${params.number}`,
21
21
  },
22
22
  ],
23
23
  };
@@ -9,13 +9,16 @@ export function registerUpdateTicket(server, api) {
9
9
  assignee: z.string().optional().describe("Username or 'unassigned'"),
10
10
  scope: z.string().optional(),
11
11
  due_date: z.string().optional().describe("Due date in YYYY-MM-DD format, or 'clear' to remove"),
12
+ external_id: z.string().optional().describe("External identifier (e.g. JIRA-123, GH-456)"),
12
13
  }, async (params) => {
13
14
  try {
14
- const { number, due_date, ...rest } = params;
15
+ const { number, due_date, external_id, ...rest } = params;
15
16
  // Unescapovat double-escaped newlines z MCP tool parametrů
16
17
  if (rest.content)
17
18
  rest.content = rest.content.replace(/\\n/g, "\n");
18
19
  const body = { ...rest };
20
+ if (external_id !== undefined)
21
+ body.externalId = external_id;
19
22
  if (due_date === "clear") {
20
23
  body.clearDueDate = true;
21
24
  }
package/dist/types.d.ts CHANGED
@@ -27,6 +27,7 @@ export interface Ticket {
27
27
  implementationItems: ImplementationItem[];
28
28
  comments: Comment[];
29
29
  relations?: TicketRelation[];
30
+ externalId: string | null;
30
31
  createdAt: string;
31
32
  updatedAt: string;
32
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k-system/tickr-mcp",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "MCP server for Tickr project management — 56 tools + setup CLI wizard",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",