@kanbodev/mcp 1.1.2 → 1.1.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/README.md +6 -0
- package/dist/index.js +37 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -116,6 +116,8 @@ The assistant respects your workflow transition rules — it checks which status
|
|
|
116
116
|
> "Pull PROJ-78 back to the board and put it in To Do"
|
|
117
117
|
>
|
|
118
118
|
> "Show me the backlog for the mobile project"
|
|
119
|
+
>
|
|
120
|
+
> "Restore the deleted ticket PROJ-99 and put it in the backlog"
|
|
119
121
|
|
|
120
122
|
### Comments and collaboration
|
|
121
123
|
|
|
@@ -164,6 +166,10 @@ Batch operations work on up to 50 tickets at once.
|
|
|
164
166
|
> "Make this description clearer: ..."
|
|
165
167
|
>
|
|
166
168
|
> "Check if this title is clear enough: 'fix thing'"
|
|
169
|
+
>
|
|
170
|
+
> "Create a ticket from my notes: users need to be able to export reports as PDF, it should respect filters, and show a progress bar for large exports"
|
|
171
|
+
|
|
172
|
+
The last example passes your raw notes directly to `generate_description` — the AI organizes, structures, and expands them into a full ticket description rather than generating from scratch.
|
|
167
173
|
|
|
168
174
|
### Analytics and reporting
|
|
169
175
|
|
package/dist/index.js
CHANGED
|
@@ -16839,7 +16839,7 @@ var CONFIG = {
|
|
|
16839
16839
|
};
|
|
16840
16840
|
var SERVER_INFO = {
|
|
16841
16841
|
name: "kanbo-mcp",
|
|
16842
|
-
version: "1.1.
|
|
16842
|
+
version: "1.1.4",
|
|
16843
16843
|
description: "MCP server for Kanbo project management"
|
|
16844
16844
|
};
|
|
16845
16845
|
var PAT_CONFIG = {
|
|
@@ -24375,7 +24375,8 @@ class KanboClient {
|
|
|
24375
24375
|
}
|
|
24376
24376
|
}
|
|
24377
24377
|
const headers = {
|
|
24378
|
-
"Content-Type": "application/json"
|
|
24378
|
+
"Content-Type": "application/json",
|
|
24379
|
+
"X-Kanbo-Source": "mcp"
|
|
24379
24380
|
};
|
|
24380
24381
|
if (this.useOidcAuth) {
|
|
24381
24382
|
const oidcToken = await fetchOidcToken(this.apiUrl);
|
|
@@ -24656,8 +24657,8 @@ KanboClient.prototype.reviveTicket = async function(projectId, ticketId, destina
|
|
|
24656
24657
|
KanboClient.prototype.deleteTicket = async function(projectId, ticketId) {
|
|
24657
24658
|
return this.delete(EP.TICKETS.GET(projectId, ticketId));
|
|
24658
24659
|
};
|
|
24659
|
-
KanboClient.prototype.restoreTicket = async function(projectId, ticketId) {
|
|
24660
|
-
return this.post(EP.TICKETS.RESTORE(projectId, ticketId));
|
|
24660
|
+
KanboClient.prototype.restoreTicket = async function(projectId, ticketId, location) {
|
|
24661
|
+
return this.post(EP.TICKETS.RESTORE(projectId, ticketId), location ? { location } : {});
|
|
24661
24662
|
};
|
|
24662
24663
|
KanboClient.prototype.moveToBacklog = async function(projectId, ticketId) {
|
|
24663
24664
|
return this.post(EP.TICKETS.BACKLOG(projectId, ticketId));
|
|
@@ -24913,8 +24914,8 @@ KanboClient.prototype.getMemberProfile = async function(userId) {
|
|
|
24913
24914
|
KanboClient.prototype.polishTitle = async function(title, projectId) {
|
|
24914
24915
|
return this.post(EP.AI.POLISH_TITLE, { title, projectId });
|
|
24915
24916
|
};
|
|
24916
|
-
KanboClient.prototype.generateDescription = async function(title, projectId, releaseId) {
|
|
24917
|
-
return this.post(EP.AI.GENERATE_DESCRIPTION, { title, projectId, releaseId });
|
|
24917
|
+
KanboClient.prototype.generateDescription = async function(title, projectId, releaseId, userNotes) {
|
|
24918
|
+
return this.post(EP.AI.GENERATE_DESCRIPTION, { title, projectId, releaseId, userNotes });
|
|
24918
24919
|
};
|
|
24919
24920
|
KanboClient.prototype.findSimilarTickets = async function(query, projectId, limit) {
|
|
24920
24921
|
return this.post(EP.AI.SIMILAR_TICKETS, { query, projectId, limit });
|
|
@@ -25511,7 +25512,7 @@ Start with a <p> overview using user story format: "As a [role], I want [goal],
|
|
|
25511
25512
|
},
|
|
25512
25513
|
description: {
|
|
25513
25514
|
type: "string",
|
|
25514
|
-
description: `Ticket description as KanboEditor HTML (max ${LIMITS.DESCRIPTION_MAX} chars). Use <p> for paragraphs, <h2>/<h3> for section headings, <ul>/<ol>/<li> for lists, <strong> for emphasis, <code> for technical terms. Start with a <p> overview, then add structured sections per ticket type. Example: "<p>As a user, I want to <strong>export data</strong> in CSV format.</p><h2>Requirements</h2><ul><li>Support CSV and JSON formats</li><li>Show progress for large exports</li></ul><h2>Technical Notes</h2><ul><li>Use existing <code>/api/export</code> endpoint</li></ul>". Use generate_description to AI-generate this, or write manually following the structure in the tool description above.`
|
|
25515
|
+
description: `Ticket description as KanboEditor HTML (max ${LIMITS.DESCRIPTION_MAX} chars). Use <p> for paragraphs, <h2>/<h3> for section headings, <ul>/<ol>/<li> for lists, <strong> for emphasis, <code> for technical terms. Start with a <p> overview, then add structured sections per ticket type. Do NOT embed acceptance criteria in the description — use the separate acceptanceCriteria field instead (it renders as a standalone interactive checklist widget below the description). TICKET REFERENCES: To mention/link other tickets, use <span data-ticket-key="PROJ-123" class="ticket-tag">PROJ-123</span> — the system auto-creates cross-references. Example: "<p>As a user, I want to <strong>export data</strong> in CSV format.</p><h2>Requirements</h2><ul><li>Support CSV and JSON formats</li><li>Show progress for large exports</li></ul><h2>Technical Notes</h2><ul><li>Use existing <code>/api/export</code> endpoint</li><li>Related to <span data-ticket-key="PROJ-42" class="ticket-tag">PROJ-42</span></li></ul>". Use generate_description to AI-generate this, or write manually following the structure in the tool description above.`
|
|
25515
25516
|
},
|
|
25516
25517
|
statusId: {
|
|
25517
25518
|
type: "string",
|
|
@@ -25559,7 +25560,7 @@ Start with a <p> overview using user story format: "As a [role], I want [goal],
|
|
|
25559
25560
|
},
|
|
25560
25561
|
acceptanceCriteria: {
|
|
25561
25562
|
type: "string",
|
|
25562
|
-
description: `Acceptance criteria as JSON string of array (max ${LIMITS.ACCEPTANCE_CRITERIA_MAX} chars). Format: [{"id":"ac-1","text":"Given a user on X page, When they do Y, Then Z happens","isChecked":false}]. Use Given/When/Then format. Include 3-8 criteria. Use unique IDs (ac-1, ac-2). Set isChecked to false for new tickets.`
|
|
25563
|
+
description: `Acceptance criteria as JSON string of array (max ${LIMITS.ACCEPTANCE_CRITERIA_MAX} chars). Renders as a standalone interactive checklist widget below the description — do NOT embed AC in the description HTML. Format: [{"id":"ac-1","text":"Given a user on X page, When they do Y, Then Z happens","isChecked":false}]. Use Given/When/Then format. Include 3-8 criteria. Use unique IDs (ac-1, ac-2). Set isChecked to false for new tickets.`
|
|
25563
25564
|
},
|
|
25564
25565
|
parentId: {
|
|
25565
25566
|
type: "string",
|
|
@@ -25615,7 +25616,7 @@ var updateTicketTool = {
|
|
|
25615
25616
|
},
|
|
25616
25617
|
description: {
|
|
25617
25618
|
type: "string",
|
|
25618
|
-
description: `New description as KanboEditor HTML (max ${LIMITS.DESCRIPTION_MAX} chars). Use <p>, <h2>, <h3>, <ul>, <li>, <strong>, <code> tags. Structure with <h2> section headings per ticket type. Use refine_description to AI-refine an existing description based on feedback instead of rewriting manually.`
|
|
25619
|
+
description: `New description as KanboEditor HTML (max ${LIMITS.DESCRIPTION_MAX} chars). Use <p>, <h2>, <h3>, <ul>, <li>, <strong>, <code> tags. Structure with <h2> section headings per ticket type. Do NOT embed acceptance criteria in the description — use the separate acceptanceCriteria field. TICKET REFERENCES: To mention other tickets, use <span data-ticket-key="PROJ-123" class="ticket-tag">PROJ-123</span>. Use refine_description to AI-refine an existing description based on feedback instead of rewriting manually.`
|
|
25619
25620
|
},
|
|
25620
25621
|
assigneeId: {
|
|
25621
25622
|
type: ["string", "null"],
|
|
@@ -25653,7 +25654,7 @@ var updateTicketTool = {
|
|
|
25653
25654
|
},
|
|
25654
25655
|
acceptanceCriteria: {
|
|
25655
25656
|
type: ["string", "null"],
|
|
25656
|
-
description: `Acceptance criteria as JSON string of array (max ${LIMITS.ACCEPTANCE_CRITERIA_MAX} chars): [{"id":"ac-1","text":"Given... When... Then...","isChecked":false}], or null to clear. Preserve existing criteria IDs when updating.`
|
|
25657
|
+
description: `Acceptance criteria as JSON string of array (max ${LIMITS.ACCEPTANCE_CRITERIA_MAX} chars): [{"id":"ac-1","text":"Given... When... Then...","isChecked":false}], or null to clear. Renders as a standalone interactive checklist widget below the description. Preserve existing criteria IDs when updating.`
|
|
25657
25658
|
},
|
|
25658
25659
|
parentId: {
|
|
25659
25660
|
type: ["string", "null"],
|
|
@@ -25914,7 +25915,7 @@ var deleteTicketTool = {
|
|
|
25914
25915
|
var restoreTicketTool = {
|
|
25915
25916
|
tool: {
|
|
25916
25917
|
name: "restore_ticket",
|
|
25917
|
-
description: "Restore a soft-deleted ticket from trash back to
|
|
25918
|
+
description: "Restore a soft-deleted ticket from trash back to the board, backlog, completed, or abandoned area. Defaults to the ticket's previous location if no location is specified.",
|
|
25918
25919
|
inputSchema: {
|
|
25919
25920
|
type: "object",
|
|
25920
25921
|
properties: {
|
|
@@ -25925,6 +25926,11 @@ var restoreTicketTool = {
|
|
|
25925
25926
|
ticketId: {
|
|
25926
25927
|
type: "string",
|
|
25927
25928
|
description: "Ticket ID to restore"
|
|
25929
|
+
},
|
|
25930
|
+
location: {
|
|
25931
|
+
type: "string",
|
|
25932
|
+
enum: ["board", "backlog", "completed", "abandoned"],
|
|
25933
|
+
description: "Where to restore the ticket (optional — defaults to previous location)"
|
|
25928
25934
|
}
|
|
25929
25935
|
},
|
|
25930
25936
|
required: ["projectId", "ticketId"]
|
|
@@ -25933,7 +25939,7 @@ var restoreTicketTool = {
|
|
|
25933
25939
|
handler: async (args) => {
|
|
25934
25940
|
try {
|
|
25935
25941
|
const client = getKanboClient();
|
|
25936
|
-
const response = await client.restoreTicket(args.projectId, args.ticketId);
|
|
25942
|
+
const response = await client.restoreTicket(args.projectId, args.ticketId, args.location);
|
|
25937
25943
|
return successResult(response.data);
|
|
25938
25944
|
} catch (error2) {
|
|
25939
25945
|
return errorResultFromError(error2);
|
|
@@ -28555,6 +28561,10 @@ The AI gathers project context automatically (related tickets, statuses, workflo
|
|
|
28555
28561
|
releaseId: {
|
|
28556
28562
|
type: "string",
|
|
28557
28563
|
description: "Release ID for additional context — helps generate release-relevant descriptions (optional)"
|
|
28564
|
+
},
|
|
28565
|
+
userNotes: {
|
|
28566
|
+
type: "string",
|
|
28567
|
+
description: "Raw notes or brain dump from the user (max 5000 chars). When provided, the AI uses these as the primary source of intent — organizing, structuring, and expanding them rather than generating from scratch (optional)"
|
|
28558
28568
|
}
|
|
28559
28569
|
},
|
|
28560
28570
|
required: ["title", "projectId"]
|
|
@@ -28563,7 +28573,7 @@ The AI gathers project context automatically (related tickets, statuses, workflo
|
|
|
28563
28573
|
handler: async (args) => {
|
|
28564
28574
|
try {
|
|
28565
28575
|
const client = getKanboClient();
|
|
28566
|
-
const response = await client.generateDescription(args.title, args.projectId, args.releaseId);
|
|
28576
|
+
const response = await client.generateDescription(args.title, args.projectId, args.releaseId, args.userNotes);
|
|
28567
28577
|
return successResult(response.data);
|
|
28568
28578
|
} catch (error2) {
|
|
28569
28579
|
return errorResultFromError(error2);
|
|
@@ -29410,6 +29420,7 @@ var TOOL_INDEX = {
|
|
|
29410
29420
|
},
|
|
29411
29421
|
acceptance_criteria: {
|
|
29412
29422
|
priority: 'HIGH — ALWAYS include acceptance criteria when creating tickets. This is the primary definition of "done".',
|
|
29423
|
+
rendering: "AC renders as a standalone interactive checklist widget below the description. Just set the acceptanceCriteria field — do NOT embed AC in the description HTML.",
|
|
29413
29424
|
format: 'JSON string of array: [{"id":"ac-1","text":"...","isChecked":false}]',
|
|
29414
29425
|
rules: [
|
|
29415
29426
|
"REQUIRED for every ticket — never skip acceptance criteria",
|
|
@@ -29418,11 +29429,23 @@ var TOOL_INDEX = {
|
|
|
29418
29429
|
'For simpler criteria, use direct statements: "Users can export data in CSV format"',
|
|
29419
29430
|
"Include at least one happy-path criterion and one error/edge-case criterion",
|
|
29420
29431
|
'Each criterion must be verifiable — someone can clearly say "yes, met" or "no, not met"',
|
|
29421
|
-
'Do NOT include vague criteria like "Code is clean" or "Feature works correctly"'
|
|
29432
|
+
'Do NOT include vague criteria like "Code is clean" or "Feature works correctly"',
|
|
29433
|
+
"Do NOT embed acceptance criteria in the description HTML — use the dedicated acceptanceCriteria field"
|
|
29422
29434
|
],
|
|
29423
29435
|
example: '[{"id":"ac-1","text":"Given a user on the project settings page, when they select CSV format and click Export, then a CSV file downloads containing all tickets","isChecked":false},{"id":"ac-2","text":"Given an export with more than 100 items, when export is initiated, then a progress indicator is visible until completion","isChecked":false},{"id":"ac-3","text":"Given an export in progress, when it exceeds 30 seconds, then the user sees a timeout error with a retry option","isChecked":false}]',
|
|
29424
29436
|
id_format: "Use unique IDs (ac-1, ac-2, etc.). Set isChecked to false for new tickets. Max 10000 chars total."
|
|
29425
29437
|
},
|
|
29438
|
+
ticket_references: {
|
|
29439
|
+
description: "Mention/link other tickets in description HTML to auto-create cross-references.",
|
|
29440
|
+
format: '<span data-ticket-key="PROJ-123" class="ticket-tag">PROJ-123</span>',
|
|
29441
|
+
rules: [
|
|
29442
|
+
"Use the ticket key (e.g., WHLZ-55, UNO-1) in the data-ticket-key attribute",
|
|
29443
|
+
"The system automatically resolves keys to ticket IDs and creates bidirectional references",
|
|
29444
|
+
'Referenced tickets appear in the "References" section of both the source and target tickets',
|
|
29445
|
+
"Self-references are filtered out automatically"
|
|
29446
|
+
],
|
|
29447
|
+
example: '<p>This depends on <span data-ticket-key="WHLZ-42" class="ticket-tag">WHLZ-42</span> for the auth middleware.</p>'
|
|
29448
|
+
},
|
|
29426
29449
|
tags: "Apply 2-5 tags per ticket AFTER creation using set_ticket_tags. Use lowercase-kebab-case. Common categories: feature area (auth, billing), technology (react, api), work type (feature, bug, refactor). Create missing tags with create_tag first.",
|
|
29427
29450
|
ticket_type: "Always set typeSlug when creating tickets. Common types: feature, bug, task, improvement, story, spike, docs. Use list_ticket_types to see project-specific types. The typeSlug determines which template_structure sections to use.",
|
|
29428
29451
|
related_tickets: "ALWAYS call find_similar_tickets before creating a ticket to check for duplicates and related work. If a related parent ticket exists, link via parentId when creating. Use get_ticket_children to view subtasks of a ticket.",
|