@kanbodev/mcp 1.1.3 → 1.1.5
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 -15
- 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.5",
|
|
16843
16843
|
description: "MCP server for Kanbo project management"
|
|
16844
16844
|
};
|
|
16845
16845
|
var PAT_CONFIG = {
|
|
@@ -24657,8 +24657,8 @@ KanboClient.prototype.reviveTicket = async function(projectId, ticketId, destina
|
|
|
24657
24657
|
KanboClient.prototype.deleteTicket = async function(projectId, ticketId) {
|
|
24658
24658
|
return this.delete(EP.TICKETS.GET(projectId, ticketId));
|
|
24659
24659
|
};
|
|
24660
|
-
KanboClient.prototype.restoreTicket = async function(projectId, ticketId) {
|
|
24661
|
-
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 } : {});
|
|
24662
24662
|
};
|
|
24663
24663
|
KanboClient.prototype.moveToBacklog = async function(projectId, ticketId) {
|
|
24664
24664
|
return this.post(EP.TICKETS.BACKLOG(projectId, ticketId));
|
|
@@ -24914,8 +24914,8 @@ KanboClient.prototype.getMemberProfile = async function(userId) {
|
|
|
24914
24914
|
KanboClient.prototype.polishTitle = async function(title, projectId) {
|
|
24915
24915
|
return this.post(EP.AI.POLISH_TITLE, { title, projectId });
|
|
24916
24916
|
};
|
|
24917
|
-
KanboClient.prototype.generateDescription = async function(title, projectId, releaseId) {
|
|
24918
|
-
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 });
|
|
24919
24919
|
};
|
|
24920
24920
|
KanboClient.prototype.findSimilarTickets = async function(query, projectId, limit) {
|
|
24921
24921
|
return this.post(EP.AI.SIMILAR_TICKETS, { query, projectId, limit });
|
|
@@ -25512,7 +25512,7 @@ Start with a <p> overview using user story format: "As a [role], I want [goal],
|
|
|
25512
25512
|
},
|
|
25513
25513
|
description: {
|
|
25514
25514
|
type: "string",
|
|
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. 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.`
|
|
25516
25516
|
},
|
|
25517
25517
|
statusId: {
|
|
25518
25518
|
type: "string",
|
|
@@ -25560,7 +25560,7 @@ Start with a <p> overview using user story format: "As a [role], I want [goal],
|
|
|
25560
25560
|
},
|
|
25561
25561
|
acceptanceCriteria: {
|
|
25562
25562
|
type: "string",
|
|
25563
|
-
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.`
|
|
25564
25564
|
},
|
|
25565
25565
|
parentId: {
|
|
25566
25566
|
type: "string",
|
|
@@ -25616,7 +25616,7 @@ var updateTicketTool = {
|
|
|
25616
25616
|
},
|
|
25617
25617
|
description: {
|
|
25618
25618
|
type: "string",
|
|
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. 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.`
|
|
25620
25620
|
},
|
|
25621
25621
|
assigneeId: {
|
|
25622
25622
|
type: ["string", "null"],
|
|
@@ -25654,7 +25654,7 @@ var updateTicketTool = {
|
|
|
25654
25654
|
},
|
|
25655
25655
|
acceptanceCriteria: {
|
|
25656
25656
|
type: ["string", "null"],
|
|
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. 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.`
|
|
25658
25658
|
},
|
|
25659
25659
|
parentId: {
|
|
25660
25660
|
type: ["string", "null"],
|
|
@@ -25915,7 +25915,7 @@ var deleteTicketTool = {
|
|
|
25915
25915
|
var restoreTicketTool = {
|
|
25916
25916
|
tool: {
|
|
25917
25917
|
name: "restore_ticket",
|
|
25918
|
-
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.",
|
|
25919
25919
|
inputSchema: {
|
|
25920
25920
|
type: "object",
|
|
25921
25921
|
properties: {
|
|
@@ -25926,6 +25926,11 @@ var restoreTicketTool = {
|
|
|
25926
25926
|
ticketId: {
|
|
25927
25927
|
type: "string",
|
|
25928
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)"
|
|
25929
25934
|
}
|
|
25930
25935
|
},
|
|
25931
25936
|
required: ["projectId", "ticketId"]
|
|
@@ -25934,7 +25939,7 @@ var restoreTicketTool = {
|
|
|
25934
25939
|
handler: async (args) => {
|
|
25935
25940
|
try {
|
|
25936
25941
|
const client = getKanboClient();
|
|
25937
|
-
const response = await client.restoreTicket(args.projectId, args.ticketId);
|
|
25942
|
+
const response = await client.restoreTicket(args.projectId, args.ticketId, args.location);
|
|
25938
25943
|
return successResult(response.data);
|
|
25939
25944
|
} catch (error2) {
|
|
25940
25945
|
return errorResultFromError(error2);
|
|
@@ -28556,6 +28561,10 @@ The AI gathers project context automatically (related tickets, statuses, workflo
|
|
|
28556
28561
|
releaseId: {
|
|
28557
28562
|
type: "string",
|
|
28558
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)"
|
|
28559
28568
|
}
|
|
28560
28569
|
},
|
|
28561
28570
|
required: ["title", "projectId"]
|
|
@@ -28564,7 +28573,7 @@ The AI gathers project context automatically (related tickets, statuses, workflo
|
|
|
28564
28573
|
handler: async (args) => {
|
|
28565
28574
|
try {
|
|
28566
28575
|
const client = getKanboClient();
|
|
28567
|
-
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);
|
|
28568
28577
|
return successResult(response.data);
|
|
28569
28578
|
} catch (error2) {
|
|
28570
28579
|
return errorResultFromError(error2);
|
|
@@ -28574,7 +28583,7 @@ The AI gathers project context automatically (related tickets, statuses, workflo
|
|
|
28574
28583
|
var findSimilarTicketsTool = {
|
|
28575
28584
|
tool: {
|
|
28576
28585
|
name: "find_similar_tickets",
|
|
28577
|
-
description: "Semantic search for similar tickets. Use BEFORE creating a ticket to check for duplicates
|
|
28586
|
+
description: "Semantic search for similar tickets using vector similarity (cosine). Use cases: (1) BEFORE creating a ticket to check for duplicates, (2) find related work to a given ticket — pair with get_completed_tickets to discover closed tickets that addressed the same topic, (3) general discovery of thematically related tickets across the project. Returns results ranked by similarity score.",
|
|
28578
28587
|
inputSchema: {
|
|
28579
28588
|
type: "object",
|
|
28580
28589
|
properties: {
|
|
@@ -29411,6 +29420,7 @@ var TOOL_INDEX = {
|
|
|
29411
29420
|
},
|
|
29412
29421
|
acceptance_criteria: {
|
|
29413
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.",
|
|
29414
29424
|
format: 'JSON string of array: [{"id":"ac-1","text":"...","isChecked":false}]',
|
|
29415
29425
|
rules: [
|
|
29416
29426
|
"REQUIRED for every ticket — never skip acceptance criteria",
|
|
@@ -29419,14 +29429,26 @@ var TOOL_INDEX = {
|
|
|
29419
29429
|
'For simpler criteria, use direct statements: "Users can export data in CSV format"',
|
|
29420
29430
|
"Include at least one happy-path criterion and one error/edge-case criterion",
|
|
29421
29431
|
'Each criterion must be verifiable — someone can clearly say "yes, met" or "no, not met"',
|
|
29422
|
-
'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"
|
|
29423
29434
|
],
|
|
29424
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}]',
|
|
29425
29436
|
id_format: "Use unique IDs (ac-1, ac-2, etc.). Set isChecked to false for new tickets. Max 10000 chars total."
|
|
29426
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
|
+
},
|
|
29427
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.",
|
|
29428
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.",
|
|
29429
|
-
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.",
|
|
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. To find closed tickets related to a specific ticket, call find_similar_tickets with the ticket title/description, then cross-reference results with get_completed_tickets.",
|
|
29430
29452
|
ai_workflow: "For best results, use the AI tools in this order: find_similar_tickets (check duplicates/related) → check_clarity (verify title) → generate_description (AI-generate HTML + acceptance criteria) → suggest_attributes (AI-suggest priority, size, tags) → create_ticket (ALWAYS include acceptanceCriteria + parentId if related) → set_ticket_tags. The generate_description tool gathers project context (related tickets, workflow) automatically."
|
|
29431
29453
|
},
|
|
29432
29454
|
categories: {
|