snboard-mcp 1.0.5 → 1.1.1
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/dist/index.js +1490 -156
- package/package.json +1 -1
- package/{README.md → readme.md} +13 -4
package/dist/index.js
CHANGED
|
@@ -32,7 +32,14 @@ var kanbanApi = {
|
|
|
32
32
|
createFolder: (data) => api("/api/folders", { method: "POST", body: JSON.stringify(data) }),
|
|
33
33
|
updateFolder: (id, data) => api(`/api/folders/${id}`, { method: "PATCH", body: JSON.stringify(data) }),
|
|
34
34
|
deleteFolder: (id) => api(`/api/folders/${id}`, { method: "DELETE" }),
|
|
35
|
-
moveProjectToFolder: (projectId, folderId) => api(`/api/projects/${projectId}`, {
|
|
35
|
+
moveProjectToFolder: (projectId, folderId) => api(`/api/projects/${projectId}`, {
|
|
36
|
+
method: "PATCH",
|
|
37
|
+
body: JSON.stringify({ folderId })
|
|
38
|
+
}),
|
|
39
|
+
reorderFolders: (folderId, targetFolderId) => api("/api/folders/reorder", {
|
|
40
|
+
method: "POST",
|
|
41
|
+
body: JSON.stringify({ folderId, targetFolderId })
|
|
42
|
+
}),
|
|
36
43
|
// Projects
|
|
37
44
|
listProjects: (params) => {
|
|
38
45
|
const searchParams = new URLSearchParams();
|
|
@@ -50,9 +57,21 @@ var kanbanApi = {
|
|
|
50
57
|
const query = searchParams.toString();
|
|
51
58
|
return api(`/api/projects/${id}${query ? `?${query}` : ""}`);
|
|
52
59
|
},
|
|
53
|
-
updateProject: (id, data) => api(`/api/projects/${id}`, { method: "
|
|
60
|
+
updateProject: (id, data) => api(`/api/projects/${id}`, { method: "PUT", body: JSON.stringify(data) }),
|
|
54
61
|
deleteProject: (id) => api(`/api/projects/${id}`, { method: "DELETE" }),
|
|
62
|
+
reorderProjects: (projectId, targetProjectId, folderId) => api("/api/projects/reorder", {
|
|
63
|
+
method: "POST",
|
|
64
|
+
body: JSON.stringify({ projectId, targetProjectId, folderId })
|
|
65
|
+
}),
|
|
55
66
|
// Boards
|
|
67
|
+
listBoards: (params) => {
|
|
68
|
+
const searchParams = new URLSearchParams();
|
|
69
|
+
if (params?.projectId) searchParams.set("projectId", params.projectId);
|
|
70
|
+
if (params?.limit) searchParams.set("limit", params.limit.toString());
|
|
71
|
+
if (params?.compact) searchParams.set("compact", "true");
|
|
72
|
+
const query = searchParams.toString();
|
|
73
|
+
return api(`/api/boards${query ? `?${query}` : ""}`);
|
|
74
|
+
},
|
|
56
75
|
createBoard: (data) => api("/api/boards", { method: "POST", body: JSON.stringify(data) }),
|
|
57
76
|
getBoard: (id, params) => {
|
|
58
77
|
const searchParams = new URLSearchParams();
|
|
@@ -68,17 +87,38 @@ var kanbanApi = {
|
|
|
68
87
|
const query = searchParams.toString();
|
|
69
88
|
return api(`/api/boards/${id}${query ? `?${query}` : ""}`);
|
|
70
89
|
},
|
|
71
|
-
updateBoard: (id, data) => api(`/api/boards/${id}`, { method: "
|
|
90
|
+
updateBoard: (id, data) => api(`/api/boards/${id}`, { method: "PUT", body: JSON.stringify(data) }),
|
|
72
91
|
deleteBoard: (id) => api(`/api/boards/${id}`, { method: "DELETE" }),
|
|
73
92
|
// Columns
|
|
74
93
|
createColumn: (data) => api("/api/columns", { method: "POST", body: JSON.stringify(data) }),
|
|
75
|
-
updateColumn: (id, data) => api(`/api/columns/${id}`, { method: "
|
|
94
|
+
updateColumn: (id, data) => api(`/api/columns/${id}`, { method: "PUT", body: JSON.stringify(data) }),
|
|
76
95
|
deleteColumn: (id) => api(`/api/columns/${id}`, { method: "DELETE" }),
|
|
96
|
+
reorderColumns: (columns) => api("/api/columns/reorder", {
|
|
97
|
+
method: "POST",
|
|
98
|
+
body: JSON.stringify({ columns })
|
|
99
|
+
}),
|
|
77
100
|
// Cards
|
|
101
|
+
getCard: (id) => api(`/api/cards/${id}`),
|
|
78
102
|
createCard: (data) => api("/api/cards", { method: "POST", body: JSON.stringify(data) }),
|
|
79
|
-
updateCard: (id, data) => api(`/api/cards/${id}`, { method: "
|
|
103
|
+
updateCard: (id, data) => api(`/api/cards/${id}`, { method: "PUT", body: JSON.stringify(data) }),
|
|
80
104
|
deleteCard: (id) => api(`/api/cards/${id}`, { method: "DELETE" }),
|
|
81
|
-
|
|
105
|
+
archiveCard: (id) => api(`/api/cards/${id}`, {
|
|
106
|
+
method: "PUT",
|
|
107
|
+
body: JSON.stringify({ isArchived: true })
|
|
108
|
+
}),
|
|
109
|
+
unarchiveCard: (id) => api(`/api/cards/${id}`, {
|
|
110
|
+
method: "PUT",
|
|
111
|
+
body: JSON.stringify({ isArchived: false })
|
|
112
|
+
}),
|
|
113
|
+
listArchivedCards: (boardId) => api(`/api/archived?boardId=${boardId}`),
|
|
114
|
+
moveCard: (id, targetColumnId, newOrder) => api("/api/cards/move", {
|
|
115
|
+
method: "POST",
|
|
116
|
+
body: JSON.stringify({
|
|
117
|
+
cardId: id,
|
|
118
|
+
targetColumnId,
|
|
119
|
+
...newOrder !== void 0 && { newOrder }
|
|
120
|
+
})
|
|
121
|
+
}),
|
|
82
122
|
getBranchName: (id, type) => api(`/api/cards/${id}/branch?type=${type}`),
|
|
83
123
|
searchCards: (params) => {
|
|
84
124
|
const searchParams = new URLSearchParams();
|
|
@@ -88,40 +128,131 @@ var kanbanApi = {
|
|
|
88
128
|
if (params.columnId) searchParams.set("columnId", params.columnId);
|
|
89
129
|
if (params.epicId) searchParams.set("epicId", params.epicId);
|
|
90
130
|
if (params.featureId) searchParams.set("featureId", params.featureId);
|
|
91
|
-
if (params.hasEpic !== void 0)
|
|
131
|
+
if (params.hasEpic !== void 0)
|
|
132
|
+
searchParams.set("hasEpic", params.hasEpic.toString());
|
|
92
133
|
if (params.status) searchParams.set("status", params.status);
|
|
93
|
-
if (params.tagIds?.length)
|
|
134
|
+
if (params.tagIds?.length)
|
|
135
|
+
searchParams.set("tagIds", params.tagIds.join(","));
|
|
94
136
|
searchParams.set("limit", (params.limit || 20).toString());
|
|
95
137
|
if (params.compact) searchParams.set("compact", "true");
|
|
96
138
|
return api(`/api/search?${searchParams.toString()}`);
|
|
97
139
|
},
|
|
98
|
-
//
|
|
140
|
+
// Tags - managed via card update with tagIds
|
|
141
|
+
addTagToCard: async (cardId, tagId) => {
|
|
142
|
+
const card = await api(`/api/cards/${cardId}`);
|
|
143
|
+
const currentTagIds = (card.tags || []).map((t) => t.id);
|
|
144
|
+
if (!currentTagIds.includes(tagId)) {
|
|
145
|
+
currentTagIds.push(tagId);
|
|
146
|
+
}
|
|
147
|
+
return api(`/api/cards/${cardId}`, {
|
|
148
|
+
method: "PUT",
|
|
149
|
+
body: JSON.stringify({ tagIds: currentTagIds })
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
removeTagFromCard: async (cardId, tagId) => {
|
|
153
|
+
const card = await api(`/api/cards/${cardId}`);
|
|
154
|
+
const currentTagIds = (card.tags || []).map((t) => t.id).filter((id) => id !== tagId);
|
|
155
|
+
return api(`/api/cards/${cardId}`, {
|
|
156
|
+
method: "PUT",
|
|
157
|
+
body: JSON.stringify({ tagIds: currentTagIds })
|
|
158
|
+
});
|
|
159
|
+
},
|
|
160
|
+
// Bulk Operations
|
|
99
161
|
bulkCreateCards: async (data) => {
|
|
100
162
|
const results = await Promise.all(
|
|
101
163
|
data.cards.map(
|
|
102
|
-
(card) => api("/api/cards", {
|
|
164
|
+
(card) => api("/api/cards", {
|
|
165
|
+
method: "POST",
|
|
166
|
+
body: JSON.stringify({ columnId: data.columnId, ...card })
|
|
167
|
+
})
|
|
103
168
|
)
|
|
104
169
|
);
|
|
105
170
|
return { created: results.length, cards: results };
|
|
106
171
|
},
|
|
107
172
|
bulkCreateEpicWithCards: async (data) => {
|
|
108
|
-
const epic = await api("/api/epics", {
|
|
173
|
+
const epic = await api("/api/epics", {
|
|
174
|
+
method: "POST",
|
|
175
|
+
body: JSON.stringify(data.epic)
|
|
176
|
+
});
|
|
109
177
|
const cardResults = await Promise.all(
|
|
110
178
|
data.cards.map(
|
|
111
|
-
(card) => api("/api/cards", {
|
|
179
|
+
(card) => api("/api/cards", {
|
|
180
|
+
method: "POST",
|
|
181
|
+
body: JSON.stringify({
|
|
182
|
+
columnId: data.columnId,
|
|
183
|
+
epicId: epic.id,
|
|
184
|
+
...card
|
|
185
|
+
})
|
|
186
|
+
})
|
|
112
187
|
)
|
|
113
188
|
);
|
|
114
189
|
return { epic, cards: cardResults, created: cardResults.length };
|
|
115
190
|
},
|
|
191
|
+
bulkCreateEpicWithFeatures: async (data) => {
|
|
192
|
+
const epic = await api("/api/epics", {
|
|
193
|
+
method: "POST",
|
|
194
|
+
body: JSON.stringify(data.epic)
|
|
195
|
+
});
|
|
196
|
+
const features = await Promise.all(
|
|
197
|
+
data.features.map(
|
|
198
|
+
(f) => api("/api/features", {
|
|
199
|
+
method: "POST",
|
|
200
|
+
body: JSON.stringify({
|
|
201
|
+
epicId: epic.id,
|
|
202
|
+
title: f.title,
|
|
203
|
+
slug: f.slug,
|
|
204
|
+
description: f.description
|
|
205
|
+
})
|
|
206
|
+
})
|
|
207
|
+
)
|
|
208
|
+
);
|
|
209
|
+
const featureResults = await Promise.all(
|
|
210
|
+
features.map(async (feature, i) => {
|
|
211
|
+
const featureCards = data.features[i].cards;
|
|
212
|
+
const cards = await Promise.all(
|
|
213
|
+
featureCards.map(
|
|
214
|
+
(c) => api("/api/cards", {
|
|
215
|
+
method: "POST",
|
|
216
|
+
body: JSON.stringify({ ...c, epicId: epic.id })
|
|
217
|
+
})
|
|
218
|
+
)
|
|
219
|
+
);
|
|
220
|
+
for (const card of cards) {
|
|
221
|
+
await api(`/api/features/${feature.id}/cards`, {
|
|
222
|
+
method: "POST",
|
|
223
|
+
body: JSON.stringify({ cardId: card.id })
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
id: feature.id,
|
|
228
|
+
slug: feature.slug,
|
|
229
|
+
title: feature.title,
|
|
230
|
+
cardIds: cards.map((c) => c.id)
|
|
231
|
+
};
|
|
232
|
+
})
|
|
233
|
+
);
|
|
234
|
+
const totalCards = featureResults.reduce(
|
|
235
|
+
(sum, f) => sum + f.cardIds.length,
|
|
236
|
+
0
|
|
237
|
+
);
|
|
238
|
+
return {
|
|
239
|
+
epic: { id: epic.id, slug: epic.slug, name: epic.name },
|
|
240
|
+
features: featureResults,
|
|
241
|
+
total: { features: features.length, cards: totalCards }
|
|
242
|
+
};
|
|
243
|
+
},
|
|
116
244
|
bulkMoveCards: async (data) => {
|
|
117
245
|
const results = await Promise.all(
|
|
118
246
|
data.cardIds.map(
|
|
119
|
-
(cardId) => api("/api/cards/move", {
|
|
247
|
+
(cardId) => api("/api/cards/move", {
|
|
248
|
+
method: "POST",
|
|
249
|
+
body: JSON.stringify({ cardId, targetColumnId: data.targetColumnId })
|
|
250
|
+
})
|
|
120
251
|
)
|
|
121
252
|
);
|
|
122
253
|
return { moved: results.length };
|
|
123
254
|
},
|
|
124
|
-
// Aggregated views
|
|
255
|
+
// Aggregated views
|
|
125
256
|
getWorkspace: async (projectId) => {
|
|
126
257
|
const project = await api(
|
|
127
258
|
`/api/projects/${projectId}?includeBoards=true&boardsCompact=true`
|
|
@@ -130,10 +261,15 @@ var kanbanApi = {
|
|
|
130
261
|
const boardsWithColumns = await Promise.all(
|
|
131
262
|
project.boards.map((b) => api(`/api/boards/${b.id}`))
|
|
132
263
|
);
|
|
133
|
-
return {
|
|
264
|
+
return {
|
|
265
|
+
project: { id: project.id, name: project.name },
|
|
266
|
+
boards: boardsWithColumns
|
|
267
|
+
};
|
|
134
268
|
},
|
|
135
269
|
getBoardSummary: async (boardId) => {
|
|
136
|
-
const board = await api(
|
|
270
|
+
const board = await api(
|
|
271
|
+
`/api/boards/${boardId}?includeCards=true&compact=true`
|
|
272
|
+
);
|
|
137
273
|
const summary = {
|
|
138
274
|
id: board.id,
|
|
139
275
|
name: board.name,
|
|
@@ -145,16 +281,25 @@ var kanbanApi = {
|
|
|
145
281
|
p2Count: col.cards?.filter((c) => c.priority === "P2").length || 0,
|
|
146
282
|
p3Count: col.cards?.filter((c) => c.priority === "P3").length || 0
|
|
147
283
|
})),
|
|
148
|
-
totalCards: board.columns.reduce(
|
|
284
|
+
totalCards: board.columns.reduce(
|
|
285
|
+
(sum, col) => sum + (col.cards?.length || 0),
|
|
286
|
+
0
|
|
287
|
+
)
|
|
149
288
|
};
|
|
150
289
|
return summary;
|
|
151
290
|
},
|
|
152
291
|
getEpicSummary: async (epicId) => {
|
|
153
292
|
const epic = await api(`/api/epics/${epicId}`);
|
|
154
293
|
const cards = epic.cards || [];
|
|
155
|
-
const todoCards = cards.filter(
|
|
156
|
-
|
|
157
|
-
|
|
294
|
+
const todoCards = cards.filter(
|
|
295
|
+
(c) => c.column?.name?.toLowerCase().includes("todo") || c.column?.name?.toLowerCase().includes("to do")
|
|
296
|
+
);
|
|
297
|
+
const inProgressCards = cards.filter(
|
|
298
|
+
(c) => c.column?.name?.toLowerCase().includes("progress")
|
|
299
|
+
);
|
|
300
|
+
const doneCards = cards.filter(
|
|
301
|
+
(c) => c.column?.name?.toLowerCase().includes("done")
|
|
302
|
+
);
|
|
158
303
|
return {
|
|
159
304
|
id: epic.id,
|
|
160
305
|
slug: epic.slug,
|
|
@@ -190,7 +335,12 @@ var kanbanApi = {
|
|
|
190
335
|
}
|
|
191
336
|
if (!cards.length) return { created: 0, cards: [] };
|
|
192
337
|
const results = await Promise.all(
|
|
193
|
-
cards.map(
|
|
338
|
+
cards.map(
|
|
339
|
+
(card) => api("/api/cards", {
|
|
340
|
+
method: "POST",
|
|
341
|
+
body: JSON.stringify({ columnId: data.columnId, ...card })
|
|
342
|
+
})
|
|
343
|
+
)
|
|
194
344
|
);
|
|
195
345
|
return { created: results.length, cards: results };
|
|
196
346
|
},
|
|
@@ -201,141 +351,1164 @@ var kanbanApi = {
|
|
|
201
351
|
const cards = Array.isArray(searchResult) ? searchResult : searchResult.cards || [];
|
|
202
352
|
if (!cards.length) return { moved: 0 };
|
|
203
353
|
await Promise.all(
|
|
204
|
-
cards.map(
|
|
354
|
+
cards.map(
|
|
355
|
+
(c) => api("/api/cards/move", {
|
|
356
|
+
method: "POST",
|
|
357
|
+
body: JSON.stringify({
|
|
358
|
+
cardId: c.id,
|
|
359
|
+
targetColumnId: data.targetColumnId
|
|
360
|
+
})
|
|
361
|
+
})
|
|
362
|
+
)
|
|
205
363
|
);
|
|
206
364
|
return { moved: cards.length };
|
|
207
365
|
},
|
|
208
366
|
// Comments
|
|
209
|
-
addComment: (cardId, content) => api("/api/comments", {
|
|
367
|
+
addComment: (cardId, content) => api("/api/comments", {
|
|
368
|
+
method: "POST",
|
|
369
|
+
body: JSON.stringify({ cardId, content })
|
|
370
|
+
}),
|
|
371
|
+
deleteComment: (commentId) => api(`/api/comments?id=${commentId}`, { method: "DELETE" }),
|
|
210
372
|
// Checklists
|
|
211
373
|
createChecklist: (data) => api("/api/checklists", { method: "POST", body: JSON.stringify(data) }),
|
|
212
374
|
updateChecklist: (id, data) => api(`/api/checklists/${id}`, { method: "PUT", body: JSON.stringify(data) }),
|
|
213
375
|
deleteChecklist: (id) => api(`/api/checklists/${id}`, { method: "DELETE" }),
|
|
214
376
|
// Checklist Items
|
|
215
377
|
createChecklistItem: (data) => api("/api/checklist-items", { method: "POST", body: JSON.stringify(data) }),
|
|
216
|
-
updateChecklistItem: (id, data) => api(`/api/checklist-items/${id}`, {
|
|
378
|
+
updateChecklistItem: (id, data) => api(`/api/checklist-items/${id}`, {
|
|
379
|
+
method: "PUT",
|
|
380
|
+
body: JSON.stringify(data)
|
|
381
|
+
}),
|
|
217
382
|
deleteChecklistItem: (id) => api(`/api/checklist-items/${id}`, { method: "DELETE" }),
|
|
218
383
|
// Tags
|
|
219
384
|
listTags: () => api("/api/tags"),
|
|
220
385
|
createTag: (data) => api("/api/tags", { method: "POST", body: JSON.stringify(data) }),
|
|
221
|
-
deleteTag: (id) => api(`/api/tags
|
|
222
|
-
addTagToCard: (cardId, tagId) => api(`/api/cards/${cardId}/tags`, { method: "POST", body: JSON.stringify({ tagId }) }),
|
|
223
|
-
removeTagFromCard: (cardId, tagId) => api(`/api/cards/${cardId}/tags/${tagId}`, { method: "DELETE" }),
|
|
386
|
+
deleteTag: (id) => api(`/api/tags?id=${id}`, { method: "DELETE" }),
|
|
224
387
|
// Epics
|
|
225
388
|
listEpics: (params) => {
|
|
226
389
|
const searchParams = new URLSearchParams();
|
|
227
390
|
if (params?.status) searchParams.set("status", params.status);
|
|
228
|
-
if (params?.includeProgress === false)
|
|
391
|
+
if (params?.includeProgress === false)
|
|
392
|
+
searchParams.set("includeProgress", "false");
|
|
229
393
|
searchParams.set("limit", (params?.limit || 15).toString());
|
|
230
394
|
if (params?.compact) searchParams.set("compact", "true");
|
|
231
395
|
const query = searchParams.toString();
|
|
232
396
|
return api(`/api/epics${query ? `?${query}` : ""}`);
|
|
233
397
|
},
|
|
234
398
|
createEpic: (data) => api("/api/epics", { method: "POST", body: JSON.stringify(data) }),
|
|
235
|
-
updateEpic: (id, data) => api(`/api/epics/${id}`, { method: "
|
|
399
|
+
updateEpic: (id, data) => api(`/api/epics/${id}`, { method: "PUT", body: JSON.stringify(data) }),
|
|
400
|
+
getEpic: (id) => api(`/api/epics/${id}`),
|
|
236
401
|
deleteEpic: (id) => api(`/api/epics/${id}`, { method: "DELETE" }),
|
|
237
|
-
addCardToEpic: (epicId, cardId) => api(`/api/epics/${epicId}/cards`, {
|
|
402
|
+
addCardToEpic: (epicId, cardId) => api(`/api/epics/${epicId}/cards`, {
|
|
403
|
+
method: "POST",
|
|
404
|
+
body: JSON.stringify({ cardId })
|
|
405
|
+
}),
|
|
238
406
|
removeCardFromEpic: (epicId, cardId) => api(`/api/epics/${epicId}/cards/${cardId}`, { method: "DELETE" }),
|
|
239
|
-
|
|
407
|
+
// Features
|
|
408
|
+
listFeatures: (epicId) => {
|
|
409
|
+
const query = epicId ? `?epicId=${epicId}` : "";
|
|
410
|
+
return api(`/api/features${query}`);
|
|
411
|
+
},
|
|
412
|
+
getFeature: (id) => api(`/api/features/${id}`),
|
|
413
|
+
getActiveFeatures: () => api("/api/features/active"),
|
|
414
|
+
createFeature: (data) => api("/api/features", { method: "POST", body: JSON.stringify(data) }),
|
|
415
|
+
updateFeature: (id, data) => api(`/api/features/${id}`, { method: "PATCH", body: JSON.stringify(data) }),
|
|
416
|
+
deleteFeature: (id) => api(`/api/features/${id}`, { method: "DELETE" }),
|
|
417
|
+
addCardToFeature: (featureId, cardId) => api(`/api/features/${featureId}/cards`, {
|
|
418
|
+
method: "POST",
|
|
419
|
+
body: JSON.stringify({ cardId })
|
|
420
|
+
}),
|
|
421
|
+
removeCardFromFeature: (featureId, cardId) => api(`/api/features/${featureId}/cards/${cardId}`, { method: "DELETE" }),
|
|
422
|
+
getFeatureCards: (featureId) => api(`/api/features/${featureId}/cards`),
|
|
240
423
|
// Card Links
|
|
241
|
-
linkCards: (cardId1, cardId2, label) => api("/api/card-links", {
|
|
242
|
-
|
|
424
|
+
linkCards: (cardId1, cardId2, label) => api("/api/card-links", {
|
|
425
|
+
method: "POST",
|
|
426
|
+
body: JSON.stringify({ fromCardId: cardId1, toCardId: cardId2, label })
|
|
427
|
+
}),
|
|
428
|
+
unlinkCards: (linkId) => api(`/api/card-links?id=${linkId}`, { method: "DELETE" }),
|
|
243
429
|
getLinkedCards: (cardId) => api(`/api/card-links?cardId=${cardId}`),
|
|
244
|
-
// GitHub Integration
|
|
245
|
-
setupGithubIntegration: (data) => api(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
430
|
+
// GitHub Integration - routes at /api/projects/[id]/github
|
|
431
|
+
setupGithubIntegration: (data) => api(`/api/projects/${data.projectId}/github`, {
|
|
432
|
+
method: "POST",
|
|
433
|
+
body: JSON.stringify(data)
|
|
434
|
+
}),
|
|
435
|
+
getGithubIntegration: (projectId) => api(`/api/projects/${projectId}/github`),
|
|
436
|
+
updateGithubIntegration: (projectId, data) => api(`/api/projects/${projectId}/github`, {
|
|
437
|
+
method: "PUT",
|
|
438
|
+
body: JSON.stringify(data)
|
|
439
|
+
}),
|
|
440
|
+
removeGithubIntegration: (projectId) => api(`/api/projects/${projectId}/github`, { method: "DELETE" }),
|
|
441
|
+
linkCardToBranch: (cardId, branch) => api(`/api/cards/${cardId}`, {
|
|
442
|
+
method: "PUT",
|
|
443
|
+
body: JSON.stringify({ githubBranch: branch })
|
|
444
|
+
}),
|
|
445
|
+
linkCardToPr: (cardId, prUrl) => api(`/api/cards/${cardId}`, {
|
|
446
|
+
method: "PUT",
|
|
447
|
+
body: JSON.stringify({ githubPrUrl: prUrl })
|
|
448
|
+
})
|
|
256
449
|
};
|
|
257
450
|
var server = new Server(
|
|
258
|
-
{ name: "kanban-mcp", version: "1.
|
|
451
|
+
{ name: "kanban-mcp", version: "1.1.0" },
|
|
259
452
|
{ capabilities: { tools: {} } }
|
|
260
453
|
);
|
|
261
454
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
262
455
|
tools: [
|
|
263
456
|
// FOLDERS
|
|
264
|
-
{
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
457
|
+
{
|
|
458
|
+
name: "list_folders",
|
|
459
|
+
description: "List all folders with their projects",
|
|
460
|
+
inputSchema: { type: "object", properties: {} }
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
name: "create_folder",
|
|
464
|
+
description: "Create a new folder to organize projects",
|
|
465
|
+
inputSchema: {
|
|
466
|
+
type: "object",
|
|
467
|
+
properties: {
|
|
468
|
+
name: { type: "string" },
|
|
469
|
+
icon: { type: "string" },
|
|
470
|
+
color: { type: "string" }
|
|
471
|
+
},
|
|
472
|
+
required: ["name"]
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
name: "update_folder",
|
|
477
|
+
description: "Update a folder (name, icon, color)",
|
|
478
|
+
inputSchema: {
|
|
479
|
+
type: "object",
|
|
480
|
+
properties: {
|
|
481
|
+
folderId: { type: "string" },
|
|
482
|
+
name: { type: "string" },
|
|
483
|
+
icon: { type: "string" },
|
|
484
|
+
color: { type: "string" }
|
|
485
|
+
},
|
|
486
|
+
required: ["folderId"]
|
|
487
|
+
}
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
name: "delete_folder",
|
|
491
|
+
description: "Delete a folder (projects become orphans)",
|
|
492
|
+
inputSchema: {
|
|
493
|
+
type: "object",
|
|
494
|
+
properties: { folderId: { type: "string" } },
|
|
495
|
+
required: ["folderId"]
|
|
496
|
+
}
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
name: "move_project_to_folder",
|
|
500
|
+
description: "Move project to folder (null to remove)",
|
|
501
|
+
inputSchema: {
|
|
502
|
+
type: "object",
|
|
503
|
+
properties: {
|
|
504
|
+
projectId: { type: "string" },
|
|
505
|
+
folderId: { type: "string" }
|
|
506
|
+
},
|
|
507
|
+
required: ["projectId"]
|
|
508
|
+
}
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
name: "reorder_folders",
|
|
512
|
+
description: "Reorder folders by moving one before/after another",
|
|
513
|
+
inputSchema: {
|
|
514
|
+
type: "object",
|
|
515
|
+
properties: {
|
|
516
|
+
folderId: { type: "string" },
|
|
517
|
+
targetFolderId: { type: "string" }
|
|
518
|
+
},
|
|
519
|
+
required: ["folderId", "targetFolderId"]
|
|
520
|
+
}
|
|
521
|
+
},
|
|
269
522
|
// PROJECTS
|
|
270
|
-
{
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
523
|
+
{
|
|
524
|
+
name: "list_projects",
|
|
525
|
+
description: "List projects (default limit:20). Use compact:true for minimal fields",
|
|
526
|
+
inputSchema: {
|
|
527
|
+
type: "object",
|
|
528
|
+
properties: {
|
|
529
|
+
folderId: {
|
|
530
|
+
type: "string",
|
|
531
|
+
description: 'Filter by folder. Use "none" for orphan projects'
|
|
532
|
+
},
|
|
533
|
+
limit: { type: "number" },
|
|
534
|
+
compact: { type: "boolean" }
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
name: "create_project",
|
|
540
|
+
description: "Create a new project",
|
|
541
|
+
inputSchema: {
|
|
542
|
+
type: "object",
|
|
543
|
+
properties: {
|
|
544
|
+
name: { type: "string" },
|
|
545
|
+
description: { type: "string" },
|
|
546
|
+
emoji: { type: "string" },
|
|
547
|
+
color: { type: "string" },
|
|
548
|
+
folderId: { type: "string" }
|
|
549
|
+
},
|
|
550
|
+
required: ["name"]
|
|
551
|
+
}
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
name: "get_project",
|
|
555
|
+
description: "Get project. Use includeBoards:true to get boards in 1 call",
|
|
556
|
+
inputSchema: {
|
|
557
|
+
type: "object",
|
|
558
|
+
properties: {
|
|
559
|
+
projectId: { type: "string" },
|
|
560
|
+
includeBoards: { type: "boolean" },
|
|
561
|
+
boardsCompact: { type: "boolean" }
|
|
562
|
+
},
|
|
563
|
+
required: ["projectId"]
|
|
564
|
+
}
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
name: "update_project",
|
|
568
|
+
description: "Update project",
|
|
569
|
+
inputSchema: {
|
|
570
|
+
type: "object",
|
|
571
|
+
properties: {
|
|
572
|
+
projectId: { type: "string" },
|
|
573
|
+
name: { type: "string" },
|
|
574
|
+
description: { type: "string" },
|
|
575
|
+
emoji: { type: "string" },
|
|
576
|
+
color: { type: "string" },
|
|
577
|
+
folderId: {
|
|
578
|
+
type: "string",
|
|
579
|
+
description: "Move to folder (null to remove)"
|
|
580
|
+
}
|
|
581
|
+
},
|
|
582
|
+
required: ["projectId"]
|
|
583
|
+
}
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
name: "delete_project",
|
|
587
|
+
description: "Delete project and all its content",
|
|
588
|
+
inputSchema: {
|
|
589
|
+
type: "object",
|
|
590
|
+
properties: { projectId: { type: "string" } },
|
|
591
|
+
required: ["projectId"]
|
|
592
|
+
}
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
name: "reorder_projects",
|
|
596
|
+
description: "Reorder projects within a folder",
|
|
597
|
+
inputSchema: {
|
|
598
|
+
type: "object",
|
|
599
|
+
properties: {
|
|
600
|
+
projectId: { type: "string" },
|
|
601
|
+
targetProjectId: { type: "string" },
|
|
602
|
+
folderId: {
|
|
603
|
+
type: "string",
|
|
604
|
+
description: "Folder context (null for orphans)"
|
|
605
|
+
}
|
|
606
|
+
},
|
|
607
|
+
required: ["projectId", "targetProjectId"]
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
// BOARDS
|
|
611
|
+
{
|
|
612
|
+
name: "list_boards",
|
|
613
|
+
description: "List boards for a project",
|
|
614
|
+
inputSchema: {
|
|
615
|
+
type: "object",
|
|
616
|
+
properties: {
|
|
617
|
+
projectId: { type: "string" },
|
|
618
|
+
limit: { type: "number" },
|
|
619
|
+
compact: { type: "boolean" }
|
|
620
|
+
},
|
|
621
|
+
required: ["projectId"]
|
|
622
|
+
}
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
name: "create_board",
|
|
626
|
+
description: "Create board with default columns",
|
|
627
|
+
inputSchema: {
|
|
628
|
+
type: "object",
|
|
629
|
+
properties: { projectId: { type: "string" }, name: { type: "string" } },
|
|
630
|
+
required: ["projectId", "name"]
|
|
631
|
+
}
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
name: "get_board",
|
|
635
|
+
description: "Get board with columns. Cards NOT included by default. Use includeCards:true + cardLimit + columnId to get specific cards.",
|
|
636
|
+
inputSchema: {
|
|
637
|
+
type: "object",
|
|
638
|
+
properties: {
|
|
639
|
+
boardId: { type: "string" },
|
|
640
|
+
columnId: { type: "string", description: "Get only this column" },
|
|
641
|
+
includeCards: {
|
|
642
|
+
type: "boolean",
|
|
643
|
+
description: "Include cards (default: false)"
|
|
644
|
+
},
|
|
645
|
+
cardLimit: {
|
|
646
|
+
type: "number",
|
|
647
|
+
description: "Max cards per column (e.g. 5)"
|
|
648
|
+
},
|
|
649
|
+
priority: { type: "string", enum: ["P1", "P2", "P3"] },
|
|
650
|
+
compact: {
|
|
651
|
+
type: "boolean",
|
|
652
|
+
description: "Minimal fields (id, title, priority)"
|
|
653
|
+
},
|
|
654
|
+
includeTags: { type: "boolean" },
|
|
655
|
+
includeComments: {
|
|
656
|
+
type: "boolean",
|
|
657
|
+
description: "Include comments (max 5)"
|
|
658
|
+
}
|
|
659
|
+
},
|
|
660
|
+
required: ["boardId"]
|
|
661
|
+
}
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
name: "update_board",
|
|
665
|
+
description: "Rename a board",
|
|
666
|
+
inputSchema: {
|
|
667
|
+
type: "object",
|
|
668
|
+
properties: { boardId: { type: "string" }, name: { type: "string" } },
|
|
669
|
+
required: ["boardId", "name"]
|
|
670
|
+
}
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
name: "delete_board",
|
|
674
|
+
description: "Delete board and all content",
|
|
675
|
+
inputSchema: {
|
|
676
|
+
type: "object",
|
|
677
|
+
properties: { boardId: { type: "string" } },
|
|
678
|
+
required: ["boardId"]
|
|
679
|
+
}
|
|
680
|
+
},
|
|
280
681
|
// COLUMNS
|
|
281
|
-
{
|
|
282
|
-
|
|
283
|
-
|
|
682
|
+
{
|
|
683
|
+
name: "create_column",
|
|
684
|
+
description: "Create column in board",
|
|
685
|
+
inputSchema: {
|
|
686
|
+
type: "object",
|
|
687
|
+
properties: {
|
|
688
|
+
boardId: { type: "string" },
|
|
689
|
+
name: { type: "string" },
|
|
690
|
+
emoji: { type: "string" }
|
|
691
|
+
},
|
|
692
|
+
required: ["boardId", "name"]
|
|
693
|
+
}
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
name: "update_column",
|
|
697
|
+
description: "Update column",
|
|
698
|
+
inputSchema: {
|
|
699
|
+
type: "object",
|
|
700
|
+
properties: {
|
|
701
|
+
columnId: { type: "string" },
|
|
702
|
+
name: { type: "string" },
|
|
703
|
+
emoji: { type: "string" }
|
|
704
|
+
},
|
|
705
|
+
required: ["columnId"]
|
|
706
|
+
}
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
name: "delete_column",
|
|
710
|
+
description: "Delete column and cards",
|
|
711
|
+
inputSchema: {
|
|
712
|
+
type: "object",
|
|
713
|
+
properties: { columnId: { type: "string" } },
|
|
714
|
+
required: ["columnId"]
|
|
715
|
+
}
|
|
716
|
+
},
|
|
717
|
+
{
|
|
718
|
+
name: "reorder_columns",
|
|
719
|
+
description: "Reorder columns in a board",
|
|
720
|
+
inputSchema: {
|
|
721
|
+
type: "object",
|
|
722
|
+
properties: {
|
|
723
|
+
columns: {
|
|
724
|
+
type: "array",
|
|
725
|
+
items: {
|
|
726
|
+
type: "object",
|
|
727
|
+
properties: {
|
|
728
|
+
id: { type: "string" },
|
|
729
|
+
order: { type: "number" }
|
|
730
|
+
},
|
|
731
|
+
required: ["id", "order"]
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
},
|
|
735
|
+
required: ["columns"]
|
|
736
|
+
}
|
|
737
|
+
},
|
|
284
738
|
// CARDS
|
|
285
|
-
{
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
739
|
+
{
|
|
740
|
+
name: "get_card",
|
|
741
|
+
description: "Get a card with all details (tags, comments, checklists, epics, features)",
|
|
742
|
+
inputSchema: {
|
|
743
|
+
type: "object",
|
|
744
|
+
properties: { cardId: { type: "string" } },
|
|
745
|
+
required: ["cardId"]
|
|
746
|
+
}
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
name: "create_card",
|
|
750
|
+
description: "Create card. Auto-assign to epic if epicId provided.",
|
|
751
|
+
inputSchema: {
|
|
752
|
+
type: "object",
|
|
753
|
+
properties: {
|
|
754
|
+
columnId: { type: "string" },
|
|
755
|
+
title: { type: "string" },
|
|
756
|
+
description: { type: "string" },
|
|
757
|
+
priority: { type: "string", enum: ["P1", "P2", "P3"] },
|
|
758
|
+
dueDate: { type: "string" },
|
|
759
|
+
epicId: { type: "string" },
|
|
760
|
+
tagIds: { type: "array", items: { type: "string" } },
|
|
761
|
+
estimatedMinutes: {
|
|
762
|
+
type: "number",
|
|
763
|
+
description: "Estimated time in minutes"
|
|
764
|
+
},
|
|
765
|
+
cognitiveLoad: {
|
|
766
|
+
type: "string",
|
|
767
|
+
description: "Cognitive load level"
|
|
768
|
+
}
|
|
769
|
+
},
|
|
770
|
+
required: ["columnId", "title"]
|
|
771
|
+
}
|
|
772
|
+
},
|
|
773
|
+
{
|
|
774
|
+
name: "update_card",
|
|
775
|
+
description: "Update card fields",
|
|
776
|
+
inputSchema: {
|
|
777
|
+
type: "object",
|
|
778
|
+
properties: {
|
|
779
|
+
cardId: { type: "string" },
|
|
780
|
+
title: { type: "string" },
|
|
781
|
+
description: { type: "string" },
|
|
782
|
+
priority: { type: "string", enum: ["P1", "P2", "P3"] },
|
|
783
|
+
dueDate: { type: "string" },
|
|
784
|
+
tagIds: {
|
|
785
|
+
type: "array",
|
|
786
|
+
items: { type: "string" },
|
|
787
|
+
description: "Replace all tags with these IDs"
|
|
788
|
+
},
|
|
789
|
+
cognitiveLoad: { type: "string" },
|
|
790
|
+
estimatedMinutes: { type: "number" },
|
|
791
|
+
githubBranch: { type: "string" },
|
|
792
|
+
githubPrUrl: { type: "string" },
|
|
793
|
+
isArchived: { type: "boolean" }
|
|
794
|
+
},
|
|
795
|
+
required: ["cardId"]
|
|
796
|
+
}
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
name: "delete_card",
|
|
800
|
+
description: "Delete a card",
|
|
801
|
+
inputSchema: {
|
|
802
|
+
type: "object",
|
|
803
|
+
properties: { cardId: { type: "string" } },
|
|
804
|
+
required: ["cardId"]
|
|
805
|
+
}
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
name: "archive_card",
|
|
809
|
+
description: "Archive a card",
|
|
810
|
+
inputSchema: {
|
|
811
|
+
type: "object",
|
|
812
|
+
properties: { cardId: { type: "string" } },
|
|
813
|
+
required: ["cardId"]
|
|
814
|
+
}
|
|
815
|
+
},
|
|
816
|
+
{
|
|
817
|
+
name: "unarchive_card",
|
|
818
|
+
description: "Unarchive a card (restore from archive)",
|
|
819
|
+
inputSchema: {
|
|
820
|
+
type: "object",
|
|
821
|
+
properties: { cardId: { type: "string" } },
|
|
822
|
+
required: ["cardId"]
|
|
823
|
+
}
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
name: "list_archived_cards",
|
|
827
|
+
description: "List archived cards for a board",
|
|
828
|
+
inputSchema: {
|
|
829
|
+
type: "object",
|
|
830
|
+
properties: { boardId: { type: "string" } },
|
|
831
|
+
required: ["boardId"]
|
|
832
|
+
}
|
|
833
|
+
},
|
|
834
|
+
{
|
|
835
|
+
name: "move_card",
|
|
836
|
+
description: "Move card to column. Use newOrder for specific positioning.",
|
|
837
|
+
inputSchema: {
|
|
838
|
+
type: "object",
|
|
839
|
+
properties: {
|
|
840
|
+
cardId: { type: "string" },
|
|
841
|
+
targetColumnId: { type: "string" },
|
|
842
|
+
newOrder: {
|
|
843
|
+
type: "number",
|
|
844
|
+
description: "Position in target column (0-indexed, default: end)"
|
|
845
|
+
}
|
|
846
|
+
},
|
|
847
|
+
required: ["cardId", "targetColumnId"]
|
|
848
|
+
}
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
name: "add_comment",
|
|
852
|
+
description: "Add comment to card",
|
|
853
|
+
inputSchema: {
|
|
854
|
+
type: "object",
|
|
855
|
+
properties: { cardId: { type: "string" }, content: { type: "string" } },
|
|
856
|
+
required: ["cardId", "content"]
|
|
857
|
+
}
|
|
858
|
+
},
|
|
859
|
+
{
|
|
860
|
+
name: "delete_comment",
|
|
861
|
+
description: "Delete a comment",
|
|
862
|
+
inputSchema: {
|
|
863
|
+
type: "object",
|
|
864
|
+
properties: { commentId: { type: "string" } },
|
|
865
|
+
required: ["commentId"]
|
|
866
|
+
}
|
|
867
|
+
},
|
|
290
868
|
// CHECKLISTS
|
|
291
|
-
{
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
{
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
869
|
+
{
|
|
870
|
+
name: "create_checklist",
|
|
871
|
+
description: "Create checklist on card",
|
|
872
|
+
inputSchema: {
|
|
873
|
+
type: "object",
|
|
874
|
+
properties: { cardId: { type: "string" }, title: { type: "string" } },
|
|
875
|
+
required: ["cardId", "title"]
|
|
876
|
+
}
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
name: "update_checklist",
|
|
880
|
+
description: "Update checklist title",
|
|
881
|
+
inputSchema: {
|
|
882
|
+
type: "object",
|
|
883
|
+
properties: {
|
|
884
|
+
checklistId: { type: "string" },
|
|
885
|
+
title: { type: "string" }
|
|
886
|
+
},
|
|
887
|
+
required: ["checklistId", "title"]
|
|
888
|
+
}
|
|
889
|
+
},
|
|
890
|
+
{
|
|
891
|
+
name: "delete_checklist",
|
|
892
|
+
description: "Delete checklist",
|
|
893
|
+
inputSchema: {
|
|
894
|
+
type: "object",
|
|
895
|
+
properties: { checklistId: { type: "string" } },
|
|
896
|
+
required: ["checklistId"]
|
|
897
|
+
}
|
|
898
|
+
},
|
|
899
|
+
{
|
|
900
|
+
name: "create_checklist_item",
|
|
901
|
+
description: "Add checklist item",
|
|
902
|
+
inputSchema: {
|
|
903
|
+
type: "object",
|
|
904
|
+
properties: {
|
|
905
|
+
checklistId: { type: "string" },
|
|
906
|
+
content: { type: "string" }
|
|
907
|
+
},
|
|
908
|
+
required: ["checklistId", "content"]
|
|
909
|
+
}
|
|
910
|
+
},
|
|
911
|
+
{
|
|
912
|
+
name: "update_checklist_item",
|
|
913
|
+
description: "Update checklist item",
|
|
914
|
+
inputSchema: {
|
|
915
|
+
type: "object",
|
|
916
|
+
properties: {
|
|
917
|
+
itemId: { type: "string" },
|
|
918
|
+
content: { type: "string" },
|
|
919
|
+
completed: { type: "boolean" }
|
|
920
|
+
},
|
|
921
|
+
required: ["itemId"]
|
|
922
|
+
}
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
name: "delete_checklist_item",
|
|
926
|
+
description: "Delete checklist item",
|
|
927
|
+
inputSchema: {
|
|
928
|
+
type: "object",
|
|
929
|
+
properties: { itemId: { type: "string" } },
|
|
930
|
+
required: ["itemId"]
|
|
931
|
+
}
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
name: "get_branch_name",
|
|
935
|
+
description: "Generate GitHub branch name",
|
|
936
|
+
inputSchema: {
|
|
937
|
+
type: "object",
|
|
938
|
+
properties: {
|
|
939
|
+
cardId: { type: "string" },
|
|
940
|
+
type: {
|
|
941
|
+
type: "string",
|
|
942
|
+
enum: ["feature", "fix", "chore", "refactor", "docs"]
|
|
943
|
+
}
|
|
944
|
+
},
|
|
945
|
+
required: ["cardId"]
|
|
946
|
+
}
|
|
947
|
+
},
|
|
948
|
+
{
|
|
949
|
+
name: "search_cards",
|
|
950
|
+
description: "Search cards, projects and boards (default limit:20). Use compact:true for minimal fields",
|
|
951
|
+
inputSchema: {
|
|
952
|
+
type: "object",
|
|
953
|
+
properties: {
|
|
954
|
+
query: { type: "string" },
|
|
955
|
+
projectId: { type: "string" },
|
|
956
|
+
boardId: { type: "string" },
|
|
957
|
+
columnId: { type: "string" },
|
|
958
|
+
epicId: { type: "string" },
|
|
959
|
+
featureId: { type: "string" },
|
|
960
|
+
hasEpic: { type: "boolean" },
|
|
961
|
+
status: { type: "string", enum: ["todo", "in_progress", "done"] },
|
|
962
|
+
tagIds: { type: "array", items: { type: "string" } },
|
|
963
|
+
limit: { type: "number" },
|
|
964
|
+
compact: { type: "boolean" }
|
|
965
|
+
},
|
|
966
|
+
required: ["query"]
|
|
967
|
+
}
|
|
968
|
+
},
|
|
969
|
+
// BULK OPERATIONS
|
|
970
|
+
{
|
|
971
|
+
name: "bulk_create_cards",
|
|
972
|
+
description: "Create multiple cards in 1 call",
|
|
973
|
+
inputSchema: {
|
|
974
|
+
type: "object",
|
|
975
|
+
properties: {
|
|
976
|
+
columnId: { type: "string" },
|
|
977
|
+
cards: {
|
|
978
|
+
type: "array",
|
|
979
|
+
items: {
|
|
980
|
+
type: "object",
|
|
981
|
+
properties: {
|
|
982
|
+
title: { type: "string" },
|
|
983
|
+
description: { type: "string" },
|
|
984
|
+
priority: { type: "string", enum: ["P1", "P2", "P3"] },
|
|
985
|
+
epicId: { type: "string" }
|
|
986
|
+
},
|
|
987
|
+
required: ["title"]
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
},
|
|
991
|
+
required: ["columnId", "cards"]
|
|
992
|
+
}
|
|
993
|
+
},
|
|
994
|
+
{
|
|
995
|
+
name: "bulk_create_epic_with_cards",
|
|
996
|
+
description: "Create epic + all its cards in 1 call",
|
|
997
|
+
inputSchema: {
|
|
998
|
+
type: "object",
|
|
999
|
+
properties: {
|
|
1000
|
+
epic: {
|
|
1001
|
+
type: "object",
|
|
1002
|
+
properties: {
|
|
1003
|
+
slug: { type: "string" },
|
|
1004
|
+
name: { type: "string" },
|
|
1005
|
+
description: { type: "string" },
|
|
1006
|
+
emoji: { type: "string" },
|
|
1007
|
+
color: { type: "string" }
|
|
1008
|
+
},
|
|
1009
|
+
required: ["slug", "name"]
|
|
1010
|
+
},
|
|
1011
|
+
columnId: { type: "string" },
|
|
1012
|
+
cards: {
|
|
1013
|
+
type: "array",
|
|
1014
|
+
items: {
|
|
1015
|
+
type: "object",
|
|
1016
|
+
properties: {
|
|
1017
|
+
title: { type: "string" },
|
|
1018
|
+
description: { type: "string" },
|
|
1019
|
+
priority: { type: "string", enum: ["P1", "P2", "P3"] }
|
|
1020
|
+
},
|
|
1021
|
+
required: ["title"]
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
},
|
|
1025
|
+
required: ["epic", "columnId", "cards"]
|
|
1026
|
+
}
|
|
1027
|
+
},
|
|
1028
|
+
{
|
|
1029
|
+
name: "bulk_create_epic_with_features",
|
|
1030
|
+
description: "Create epic + features + cards across projects in 1 call. Cards auto-prefixed with SLUG{N}-.",
|
|
1031
|
+
inputSchema: {
|
|
1032
|
+
type: "object",
|
|
1033
|
+
properties: {
|
|
1034
|
+
epic: {
|
|
1035
|
+
type: "object",
|
|
1036
|
+
properties: {
|
|
1037
|
+
slug: { type: "string" },
|
|
1038
|
+
name: { type: "string" },
|
|
1039
|
+
description: { type: "string" },
|
|
1040
|
+
emoji: { type: "string" },
|
|
1041
|
+
color: { type: "string" }
|
|
1042
|
+
},
|
|
1043
|
+
required: ["slug", "name"]
|
|
1044
|
+
},
|
|
1045
|
+
features: {
|
|
1046
|
+
type: "array",
|
|
1047
|
+
items: {
|
|
1048
|
+
type: "object",
|
|
1049
|
+
properties: {
|
|
1050
|
+
title: { type: "string" },
|
|
1051
|
+
slug: {
|
|
1052
|
+
type: "string",
|
|
1053
|
+
description: "UPPERCASE slug (auto-generated from title if omitted)"
|
|
1054
|
+
},
|
|
1055
|
+
description: { type: "string" },
|
|
1056
|
+
cards: {
|
|
1057
|
+
type: "array",
|
|
1058
|
+
items: {
|
|
1059
|
+
type: "object",
|
|
1060
|
+
properties: {
|
|
1061
|
+
columnId: { type: "string" },
|
|
1062
|
+
title: { type: "string" },
|
|
1063
|
+
description: { type: "string" },
|
|
1064
|
+
priority: { type: "string", enum: ["P1", "P2", "P3"] }
|
|
1065
|
+
},
|
|
1066
|
+
required: ["columnId", "title"]
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
},
|
|
1070
|
+
required: ["title", "cards"]
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
},
|
|
1074
|
+
required: ["epic", "features"]
|
|
1075
|
+
}
|
|
1076
|
+
},
|
|
1077
|
+
{
|
|
1078
|
+
name: "bulk_move_cards",
|
|
1079
|
+
description: "Move multiple cards to column in 1 call",
|
|
1080
|
+
inputSchema: {
|
|
1081
|
+
type: "object",
|
|
1082
|
+
properties: {
|
|
1083
|
+
cardIds: { type: "array", items: { type: "string" } },
|
|
1084
|
+
targetColumnId: { type: "string" }
|
|
1085
|
+
},
|
|
1086
|
+
required: ["cardIds", "targetColumnId"]
|
|
1087
|
+
}
|
|
1088
|
+
},
|
|
1089
|
+
{
|
|
1090
|
+
name: "quick_add_cards",
|
|
1091
|
+
description: 'Create cards from multiline text. Format: "- P1: task title" per line',
|
|
1092
|
+
inputSchema: {
|
|
1093
|
+
type: "object",
|
|
1094
|
+
properties: {
|
|
1095
|
+
columnId: { type: "string" },
|
|
1096
|
+
text: {
|
|
1097
|
+
type: "string",
|
|
1098
|
+
description: "Multiline text, 1 card per line"
|
|
1099
|
+
},
|
|
1100
|
+
defaultPriority: { type: "string", enum: ["P1", "P2", "P3"] }
|
|
1101
|
+
},
|
|
1102
|
+
required: ["columnId", "text"]
|
|
1103
|
+
}
|
|
1104
|
+
},
|
|
1105
|
+
{
|
|
1106
|
+
name: "move_cards_by_column",
|
|
1107
|
+
description: "Move ALL cards from one column to another",
|
|
1108
|
+
inputSchema: {
|
|
1109
|
+
type: "object",
|
|
1110
|
+
properties: {
|
|
1111
|
+
sourceColumnId: { type: "string" },
|
|
1112
|
+
targetColumnId: { type: "string" },
|
|
1113
|
+
limit: { type: "number" }
|
|
1114
|
+
},
|
|
1115
|
+
required: ["sourceColumnId", "targetColumnId"]
|
|
1116
|
+
}
|
|
1117
|
+
},
|
|
1118
|
+
// AGGREGATED VIEWS
|
|
1119
|
+
{
|
|
1120
|
+
name: "get_workspace",
|
|
1121
|
+
description: "Get project + all boards + columns in 1 call (no cards)",
|
|
1122
|
+
inputSchema: {
|
|
1123
|
+
type: "object",
|
|
1124
|
+
properties: { projectId: { type: "string" } },
|
|
1125
|
+
required: ["projectId"]
|
|
1126
|
+
}
|
|
1127
|
+
},
|
|
1128
|
+
{
|
|
1129
|
+
name: "get_board_summary",
|
|
1130
|
+
description: "Get board stats only: card counts per column + priority breakdown",
|
|
1131
|
+
inputSchema: {
|
|
1132
|
+
type: "object",
|
|
1133
|
+
properties: { boardId: { type: "string" } },
|
|
1134
|
+
required: ["boardId"]
|
|
1135
|
+
}
|
|
1136
|
+
},
|
|
1137
|
+
{
|
|
1138
|
+
name: "get_epic_summary",
|
|
1139
|
+
description: "Get epic with minimal card info: {id,title,priority,status} + progress stats",
|
|
1140
|
+
inputSchema: {
|
|
1141
|
+
type: "object",
|
|
1142
|
+
properties: { epicId: { type: "string" } },
|
|
1143
|
+
required: ["epicId"]
|
|
1144
|
+
}
|
|
1145
|
+
},
|
|
309
1146
|
// TAGS
|
|
310
|
-
{
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
1147
|
+
{
|
|
1148
|
+
name: "list_tags",
|
|
1149
|
+
description: "List all tags",
|
|
1150
|
+
inputSchema: { type: "object", properties: {} }
|
|
1151
|
+
},
|
|
1152
|
+
{
|
|
1153
|
+
name: "create_tag",
|
|
1154
|
+
description: "Create tag",
|
|
1155
|
+
inputSchema: {
|
|
1156
|
+
type: "object",
|
|
1157
|
+
properties: { name: { type: "string" }, color: { type: "string" } },
|
|
1158
|
+
required: ["name", "color"]
|
|
1159
|
+
}
|
|
1160
|
+
},
|
|
1161
|
+
{
|
|
1162
|
+
name: "delete_tag",
|
|
1163
|
+
description: "Delete tag",
|
|
1164
|
+
inputSchema: {
|
|
1165
|
+
type: "object",
|
|
1166
|
+
properties: { tagId: { type: "string" } },
|
|
1167
|
+
required: ["tagId"]
|
|
1168
|
+
}
|
|
1169
|
+
},
|
|
1170
|
+
{
|
|
1171
|
+
name: "add_tag_to_card",
|
|
1172
|
+
description: "Add tag to card",
|
|
1173
|
+
inputSchema: {
|
|
1174
|
+
type: "object",
|
|
1175
|
+
properties: { cardId: { type: "string" }, tagId: { type: "string" } },
|
|
1176
|
+
required: ["cardId", "tagId"]
|
|
1177
|
+
}
|
|
1178
|
+
},
|
|
1179
|
+
{
|
|
1180
|
+
name: "remove_tag_from_card",
|
|
1181
|
+
description: "Remove tag from card",
|
|
1182
|
+
inputSchema: {
|
|
1183
|
+
type: "object",
|
|
1184
|
+
properties: { cardId: { type: "string" }, tagId: { type: "string" } },
|
|
1185
|
+
required: ["cardId", "tagId"]
|
|
1186
|
+
}
|
|
1187
|
+
},
|
|
1188
|
+
// EPICS
|
|
1189
|
+
{
|
|
1190
|
+
name: "list_epics",
|
|
1191
|
+
description: "List epics (default limit:15)",
|
|
1192
|
+
inputSchema: {
|
|
1193
|
+
type: "object",
|
|
1194
|
+
properties: {
|
|
1195
|
+
status: { type: "string" },
|
|
1196
|
+
includeProgress: { type: "boolean" },
|
|
1197
|
+
limit: { type: "number" },
|
|
1198
|
+
compact: { type: "boolean" }
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
},
|
|
1202
|
+
{
|
|
1203
|
+
name: "create_epic",
|
|
1204
|
+
description: "Create epic",
|
|
1205
|
+
inputSchema: {
|
|
1206
|
+
type: "object",
|
|
1207
|
+
properties: {
|
|
1208
|
+
slug: { type: "string" },
|
|
1209
|
+
name: { type: "string" },
|
|
1210
|
+
description: { type: "string" },
|
|
1211
|
+
emoji: { type: "string" },
|
|
1212
|
+
color: { type: "string" },
|
|
1213
|
+
startDate: { type: "string" },
|
|
1214
|
+
targetDate: { type: "string" }
|
|
1215
|
+
},
|
|
1216
|
+
required: ["slug", "name"]
|
|
1217
|
+
}
|
|
1218
|
+
},
|
|
1219
|
+
{
|
|
1220
|
+
name: "get_epic",
|
|
1221
|
+
description: "Get an epic with all its cards, features and progress",
|
|
1222
|
+
inputSchema: {
|
|
1223
|
+
type: "object",
|
|
1224
|
+
properties: { epicId: { type: "string" } },
|
|
1225
|
+
required: ["epicId"]
|
|
1226
|
+
}
|
|
1227
|
+
},
|
|
1228
|
+
{
|
|
1229
|
+
name: "update_epic",
|
|
1230
|
+
description: "Update epic. Use syncDates:true to sync targetDate to all card due dates.",
|
|
1231
|
+
inputSchema: {
|
|
1232
|
+
type: "object",
|
|
1233
|
+
properties: {
|
|
1234
|
+
epicId: { type: "string" },
|
|
1235
|
+
slug: { type: "string" },
|
|
1236
|
+
name: { type: "string" },
|
|
1237
|
+
description: { type: "string" },
|
|
1238
|
+
emoji: { type: "string" },
|
|
1239
|
+
color: { type: "string" },
|
|
1240
|
+
status: { type: "string" },
|
|
1241
|
+
startDate: { type: "string" },
|
|
1242
|
+
targetDate: { type: "string" },
|
|
1243
|
+
syncDates: {
|
|
1244
|
+
type: "boolean",
|
|
1245
|
+
description: "Sync targetDate to all card due dates"
|
|
1246
|
+
}
|
|
1247
|
+
},
|
|
1248
|
+
required: ["epicId"]
|
|
1249
|
+
}
|
|
1250
|
+
},
|
|
1251
|
+
{
|
|
1252
|
+
name: "delete_epic",
|
|
1253
|
+
description: "Delete epic (cards unlinked)",
|
|
1254
|
+
inputSchema: {
|
|
1255
|
+
type: "object",
|
|
1256
|
+
properties: { epicId: { type: "string" } },
|
|
1257
|
+
required: ["epicId"]
|
|
1258
|
+
}
|
|
1259
|
+
},
|
|
1260
|
+
{
|
|
1261
|
+
name: "add_card_to_epic",
|
|
1262
|
+
description: "Add card to epic",
|
|
1263
|
+
inputSchema: {
|
|
1264
|
+
type: "object",
|
|
1265
|
+
properties: { epicId: { type: "string" }, cardId: { type: "string" } },
|
|
1266
|
+
required: ["epicId", "cardId"]
|
|
1267
|
+
}
|
|
1268
|
+
},
|
|
1269
|
+
{
|
|
1270
|
+
name: "remove_card_from_epic",
|
|
1271
|
+
description: "Remove card from epic",
|
|
1272
|
+
inputSchema: {
|
|
1273
|
+
type: "object",
|
|
1274
|
+
properties: { epicId: { type: "string" }, cardId: { type: "string" } },
|
|
1275
|
+
required: ["epicId", "cardId"]
|
|
1276
|
+
}
|
|
1277
|
+
},
|
|
1278
|
+
// FEATURES
|
|
1279
|
+
{
|
|
1280
|
+
name: "list_features",
|
|
1281
|
+
description: "List features. Filter by epicId or slug.",
|
|
1282
|
+
inputSchema: {
|
|
1283
|
+
type: "object",
|
|
1284
|
+
properties: {
|
|
1285
|
+
epicId: { type: "string" },
|
|
1286
|
+
slug: {
|
|
1287
|
+
type: "string",
|
|
1288
|
+
description: "Filter by feature slug (UPPERCASE)"
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
},
|
|
1293
|
+
{
|
|
1294
|
+
name: "get_feature",
|
|
1295
|
+
description: "Get a feature with cards and progress. Accepts featureId or featureSlug (UPPERCASE).",
|
|
1296
|
+
inputSchema: {
|
|
1297
|
+
type: "object",
|
|
1298
|
+
properties: {
|
|
1299
|
+
featureId: { type: "string", description: "Feature ID or slug" },
|
|
1300
|
+
featureSlug: {
|
|
1301
|
+
type: "string",
|
|
1302
|
+
description: "Feature slug (UPPERCASE), alternative to featureId"
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
},
|
|
1307
|
+
{
|
|
1308
|
+
name: "get_active_features",
|
|
1309
|
+
description: "Get features with cards in progress, organized by epic",
|
|
1310
|
+
inputSchema: { type: "object", properties: {} }
|
|
1311
|
+
},
|
|
1312
|
+
{
|
|
1313
|
+
name: "create_feature",
|
|
1314
|
+
description: "Create a new feature (optionally in an epic)",
|
|
1315
|
+
inputSchema: {
|
|
1316
|
+
type: "object",
|
|
1317
|
+
properties: {
|
|
1318
|
+
epicId: { type: "string" },
|
|
1319
|
+
title: { type: "string" },
|
|
1320
|
+
slug: { type: "string" },
|
|
1321
|
+
description: { type: "string" },
|
|
1322
|
+
status: {
|
|
1323
|
+
type: "string",
|
|
1324
|
+
enum: ["planning", "in_progress", "completed", "on_hold"]
|
|
1325
|
+
}
|
|
1326
|
+
},
|
|
1327
|
+
required: ["title"]
|
|
1328
|
+
}
|
|
1329
|
+
},
|
|
1330
|
+
{
|
|
1331
|
+
name: "update_feature",
|
|
1332
|
+
description: "Update a feature",
|
|
1333
|
+
inputSchema: {
|
|
1334
|
+
type: "object",
|
|
1335
|
+
properties: {
|
|
1336
|
+
featureId: { type: "string" },
|
|
1337
|
+
title: { type: "string" },
|
|
1338
|
+
slug: { type: "string" },
|
|
1339
|
+
description: { type: "string" },
|
|
1340
|
+
status: {
|
|
1341
|
+
type: "string",
|
|
1342
|
+
enum: ["planning", "in_progress", "completed", "on_hold"]
|
|
1343
|
+
},
|
|
1344
|
+
order: { type: "number" },
|
|
1345
|
+
epicId: { type: "string", description: "Move to another epic" }
|
|
1346
|
+
},
|
|
1347
|
+
required: ["featureId"]
|
|
1348
|
+
}
|
|
1349
|
+
},
|
|
1350
|
+
{
|
|
1351
|
+
name: "delete_feature",
|
|
1352
|
+
description: "Delete a feature (cards unlinked)",
|
|
1353
|
+
inputSchema: {
|
|
1354
|
+
type: "object",
|
|
1355
|
+
properties: { featureId: { type: "string" } },
|
|
1356
|
+
required: ["featureId"]
|
|
1357
|
+
}
|
|
1358
|
+
},
|
|
1359
|
+
{
|
|
1360
|
+
name: "add_card_to_feature",
|
|
1361
|
+
description: "Add a card to a feature. Accepts featureId or featureSlug.",
|
|
1362
|
+
inputSchema: {
|
|
1363
|
+
type: "object",
|
|
1364
|
+
properties: {
|
|
1365
|
+
cardId: { type: "string" },
|
|
1366
|
+
featureId: { type: "string", description: "Feature ID or slug" },
|
|
1367
|
+
featureSlug: {
|
|
1368
|
+
type: "string",
|
|
1369
|
+
description: "Feature slug (UPPERCASE), alternative to featureId"
|
|
1370
|
+
}
|
|
1371
|
+
},
|
|
1372
|
+
required: ["cardId"]
|
|
1373
|
+
}
|
|
1374
|
+
},
|
|
1375
|
+
{
|
|
1376
|
+
name: "remove_card_from_feature",
|
|
1377
|
+
description: "Remove a card from a feature. Accepts featureId or featureSlug.",
|
|
1378
|
+
inputSchema: {
|
|
1379
|
+
type: "object",
|
|
1380
|
+
properties: {
|
|
1381
|
+
cardId: { type: "string" },
|
|
1382
|
+
featureId: { type: "string", description: "Feature ID or slug" },
|
|
1383
|
+
featureSlug: {
|
|
1384
|
+
type: "string",
|
|
1385
|
+
description: "Feature slug (UPPERCASE), alternative to featureId"
|
|
1386
|
+
}
|
|
1387
|
+
},
|
|
1388
|
+
required: ["cardId"]
|
|
1389
|
+
}
|
|
1390
|
+
},
|
|
1391
|
+
{
|
|
1392
|
+
name: "get_feature_cards",
|
|
1393
|
+
description: "Get all cards in a feature. Accepts featureId or featureSlug.",
|
|
1394
|
+
inputSchema: {
|
|
1395
|
+
type: "object",
|
|
1396
|
+
properties: {
|
|
1397
|
+
featureId: { type: "string", description: "Feature ID or slug" },
|
|
1398
|
+
featureSlug: {
|
|
1399
|
+
type: "string",
|
|
1400
|
+
description: "Feature slug (UPPERCASE), alternative to featureId"
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
},
|
|
323
1405
|
// CARD LINKS
|
|
324
|
-
{
|
|
325
|
-
|
|
326
|
-
|
|
1406
|
+
{
|
|
1407
|
+
name: "link_cards",
|
|
1408
|
+
description: "Link two cards",
|
|
1409
|
+
inputSchema: {
|
|
1410
|
+
type: "object",
|
|
1411
|
+
properties: {
|
|
1412
|
+
cardId1: { type: "string" },
|
|
1413
|
+
cardId2: { type: "string" },
|
|
1414
|
+
label: { type: "string" }
|
|
1415
|
+
},
|
|
1416
|
+
required: ["cardId1", "cardId2"]
|
|
1417
|
+
}
|
|
1418
|
+
},
|
|
1419
|
+
{
|
|
1420
|
+
name: "unlink_cards",
|
|
1421
|
+
description: "Unlink two cards by link ID",
|
|
1422
|
+
inputSchema: {
|
|
1423
|
+
type: "object",
|
|
1424
|
+
properties: {
|
|
1425
|
+
linkId: { type: "string" }
|
|
1426
|
+
},
|
|
1427
|
+
required: ["linkId"]
|
|
1428
|
+
}
|
|
1429
|
+
},
|
|
1430
|
+
{
|
|
1431
|
+
name: "get_linked_cards",
|
|
1432
|
+
description: "Get linked cards",
|
|
1433
|
+
inputSchema: {
|
|
1434
|
+
type: "object",
|
|
1435
|
+
properties: { cardId: { type: "string" } },
|
|
1436
|
+
required: ["cardId"]
|
|
1437
|
+
}
|
|
1438
|
+
},
|
|
327
1439
|
// GITHUB INTEGRATION
|
|
328
|
-
{
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
1440
|
+
{
|
|
1441
|
+
name: "setup_github_integration",
|
|
1442
|
+
description: "Setup GitHub integration for a project (auto-creates webhook)",
|
|
1443
|
+
inputSchema: {
|
|
1444
|
+
type: "object",
|
|
1445
|
+
properties: {
|
|
1446
|
+
projectId: { type: "string" },
|
|
1447
|
+
repoOwner: { type: "string" },
|
|
1448
|
+
repoName: { type: "string" },
|
|
1449
|
+
inProgressColumnName: { type: "string" },
|
|
1450
|
+
doneColumnName: { type: "string" },
|
|
1451
|
+
autoMoveOnPush: { type: "boolean" },
|
|
1452
|
+
autoMoveOnPrMerge: { type: "boolean" },
|
|
1453
|
+
autoLinkPr: { type: "boolean" }
|
|
1454
|
+
},
|
|
1455
|
+
required: ["projectId", "repoOwner", "repoName"]
|
|
1456
|
+
}
|
|
1457
|
+
},
|
|
1458
|
+
{
|
|
1459
|
+
name: "get_github_integration",
|
|
1460
|
+
description: "Get GitHub integration settings",
|
|
1461
|
+
inputSchema: {
|
|
1462
|
+
type: "object",
|
|
1463
|
+
properties: { projectId: { type: "string" } },
|
|
1464
|
+
required: ["projectId"]
|
|
1465
|
+
}
|
|
1466
|
+
},
|
|
1467
|
+
{
|
|
1468
|
+
name: "update_github_integration",
|
|
1469
|
+
description: "Update GitHub integration settings",
|
|
1470
|
+
inputSchema: {
|
|
1471
|
+
type: "object",
|
|
1472
|
+
properties: {
|
|
1473
|
+
projectId: { type: "string" },
|
|
1474
|
+
repoOwner: { type: "string" },
|
|
1475
|
+
repoName: { type: "string" },
|
|
1476
|
+
autoMoveOnPush: { type: "boolean" },
|
|
1477
|
+
autoMoveOnPrMerge: { type: "boolean" },
|
|
1478
|
+
autoLinkPr: { type: "boolean" },
|
|
1479
|
+
inProgressColumnName: { type: "string" },
|
|
1480
|
+
doneColumnName: { type: "string" }
|
|
1481
|
+
},
|
|
1482
|
+
required: ["projectId"]
|
|
1483
|
+
}
|
|
1484
|
+
},
|
|
1485
|
+
{
|
|
1486
|
+
name: "remove_github_integration",
|
|
1487
|
+
description: "Remove GitHub integration",
|
|
1488
|
+
inputSchema: {
|
|
1489
|
+
type: "object",
|
|
1490
|
+
properties: { projectId: { type: "string" } },
|
|
1491
|
+
required: ["projectId"]
|
|
1492
|
+
}
|
|
1493
|
+
},
|
|
1494
|
+
{
|
|
1495
|
+
name: "link_card_to_branch",
|
|
1496
|
+
description: "Link card to branch",
|
|
1497
|
+
inputSchema: {
|
|
1498
|
+
type: "object",
|
|
1499
|
+
properties: { cardId: { type: "string" }, branch: { type: "string" } },
|
|
1500
|
+
required: ["cardId", "branch"]
|
|
1501
|
+
}
|
|
1502
|
+
},
|
|
1503
|
+
{
|
|
1504
|
+
name: "link_card_to_pr",
|
|
1505
|
+
description: "Link card to PR",
|
|
1506
|
+
inputSchema: {
|
|
1507
|
+
type: "object",
|
|
1508
|
+
properties: { cardId: { type: "string" }, prUrl: { type: "string" } },
|
|
1509
|
+
required: ["cardId", "prUrl"]
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
339
1512
|
]
|
|
340
1513
|
}));
|
|
341
1514
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
@@ -351,13 +1524,25 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
351
1524
|
result = await kanbanApi.createFolder(args);
|
|
352
1525
|
break;
|
|
353
1526
|
case "update_folder":
|
|
354
|
-
result = await kanbanApi.updateFolder(
|
|
1527
|
+
result = await kanbanApi.updateFolder(
|
|
1528
|
+
args.folderId,
|
|
1529
|
+
args
|
|
1530
|
+
);
|
|
355
1531
|
break;
|
|
356
1532
|
case "delete_folder":
|
|
357
1533
|
result = await kanbanApi.deleteFolder(args.folderId);
|
|
358
1534
|
break;
|
|
359
1535
|
case "move_project_to_folder":
|
|
360
|
-
result = await kanbanApi.moveProjectToFolder(
|
|
1536
|
+
result = await kanbanApi.moveProjectToFolder(
|
|
1537
|
+
args.projectId,
|
|
1538
|
+
args.folderId
|
|
1539
|
+
);
|
|
1540
|
+
break;
|
|
1541
|
+
case "reorder_folders":
|
|
1542
|
+
result = await kanbanApi.reorderFolders(
|
|
1543
|
+
args.folderId,
|
|
1544
|
+
args.targetFolderId
|
|
1545
|
+
);
|
|
361
1546
|
break;
|
|
362
1547
|
// PROJECTS
|
|
363
1548
|
case "list_projects":
|
|
@@ -367,15 +1552,31 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
367
1552
|
result = await kanbanApi.createProject(args);
|
|
368
1553
|
break;
|
|
369
1554
|
case "get_project":
|
|
370
|
-
result = await kanbanApi.getProject(
|
|
1555
|
+
result = await kanbanApi.getProject(
|
|
1556
|
+
args.projectId,
|
|
1557
|
+
args
|
|
1558
|
+
);
|
|
371
1559
|
break;
|
|
372
1560
|
case "update_project":
|
|
373
|
-
result = await kanbanApi.updateProject(
|
|
1561
|
+
result = await kanbanApi.updateProject(
|
|
1562
|
+
args.projectId,
|
|
1563
|
+
args
|
|
1564
|
+
);
|
|
374
1565
|
break;
|
|
375
1566
|
case "delete_project":
|
|
376
1567
|
result = await kanbanApi.deleteProject(args.projectId);
|
|
377
1568
|
break;
|
|
1569
|
+
case "reorder_projects":
|
|
1570
|
+
result = await kanbanApi.reorderProjects(
|
|
1571
|
+
args.projectId,
|
|
1572
|
+
args.targetProjectId,
|
|
1573
|
+
args.folderId
|
|
1574
|
+
);
|
|
1575
|
+
break;
|
|
378
1576
|
// BOARDS
|
|
1577
|
+
case "list_boards":
|
|
1578
|
+
result = await kanbanApi.listBoards(args);
|
|
1579
|
+
break;
|
|
379
1580
|
case "create_board":
|
|
380
1581
|
result = await kanbanApi.createBoard(args);
|
|
381
1582
|
break;
|
|
@@ -383,7 +1584,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
383
1584
|
result = await kanbanApi.getBoard(args.boardId, args);
|
|
384
1585
|
break;
|
|
385
1586
|
case "update_board":
|
|
386
|
-
result = await kanbanApi.updateBoard(args.boardId, {
|
|
1587
|
+
result = await kanbanApi.updateBoard(args.boardId, {
|
|
1588
|
+
name: args.name
|
|
1589
|
+
});
|
|
387
1590
|
break;
|
|
388
1591
|
case "delete_board":
|
|
389
1592
|
result = await kanbanApi.deleteBoard(args.boardId);
|
|
@@ -393,12 +1596,21 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
393
1596
|
result = await kanbanApi.createColumn(args);
|
|
394
1597
|
break;
|
|
395
1598
|
case "update_column":
|
|
396
|
-
result = await kanbanApi.updateColumn(
|
|
1599
|
+
result = await kanbanApi.updateColumn(
|
|
1600
|
+
args.columnId,
|
|
1601
|
+
args
|
|
1602
|
+
);
|
|
397
1603
|
break;
|
|
398
1604
|
case "delete_column":
|
|
399
1605
|
result = await kanbanApi.deleteColumn(args.columnId);
|
|
400
1606
|
break;
|
|
1607
|
+
case "reorder_columns":
|
|
1608
|
+
result = await kanbanApi.reorderColumns(args.columns);
|
|
1609
|
+
break;
|
|
401
1610
|
// CARDS
|
|
1611
|
+
case "get_card":
|
|
1612
|
+
result = await kanbanApi.getCard(args.cardId);
|
|
1613
|
+
break;
|
|
402
1614
|
case "create_card":
|
|
403
1615
|
result = await kanbanApi.createCard(args);
|
|
404
1616
|
break;
|
|
@@ -409,32 +1621,65 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
409
1621
|
result = await kanbanApi.deleteCard(args.cardId);
|
|
410
1622
|
break;
|
|
411
1623
|
case "move_card":
|
|
412
|
-
result = await kanbanApi.moveCard(
|
|
1624
|
+
result = await kanbanApi.moveCard(
|
|
1625
|
+
args.cardId,
|
|
1626
|
+
args.targetColumnId,
|
|
1627
|
+
args.newOrder
|
|
1628
|
+
);
|
|
1629
|
+
break;
|
|
1630
|
+
case "archive_card":
|
|
1631
|
+
result = await kanbanApi.archiveCard(args.cardId);
|
|
1632
|
+
break;
|
|
1633
|
+
case "unarchive_card":
|
|
1634
|
+
result = await kanbanApi.unarchiveCard(args.cardId);
|
|
1635
|
+
break;
|
|
1636
|
+
case "list_archived_cards":
|
|
1637
|
+
result = await kanbanApi.listArchivedCards(args.boardId);
|
|
413
1638
|
break;
|
|
414
1639
|
case "add_comment":
|
|
415
|
-
result = await kanbanApi.addComment(
|
|
1640
|
+
result = await kanbanApi.addComment(
|
|
1641
|
+
args.cardId,
|
|
1642
|
+
args.content
|
|
1643
|
+
);
|
|
1644
|
+
break;
|
|
1645
|
+
case "delete_comment":
|
|
1646
|
+
result = await kanbanApi.deleteComment(args.commentId);
|
|
416
1647
|
break;
|
|
417
1648
|
// CHECKLISTS
|
|
418
1649
|
case "create_checklist":
|
|
419
|
-
result = await kanbanApi.createChecklist({
|
|
1650
|
+
result = await kanbanApi.createChecklist({
|
|
1651
|
+
cardId: args.cardId,
|
|
1652
|
+
title: args.title
|
|
1653
|
+
});
|
|
420
1654
|
break;
|
|
421
1655
|
case "update_checklist":
|
|
422
|
-
result = await kanbanApi.updateChecklist(args.checklistId, {
|
|
1656
|
+
result = await kanbanApi.updateChecklist(args.checklistId, {
|
|
1657
|
+
title: args.title
|
|
1658
|
+
});
|
|
423
1659
|
break;
|
|
424
1660
|
case "delete_checklist":
|
|
425
1661
|
result = await kanbanApi.deleteChecklist(args.checklistId);
|
|
426
1662
|
break;
|
|
427
1663
|
case "create_checklist_item":
|
|
428
|
-
result = await kanbanApi.createChecklistItem({
|
|
1664
|
+
result = await kanbanApi.createChecklistItem({
|
|
1665
|
+
checklistId: args.checklistId,
|
|
1666
|
+
content: args.content
|
|
1667
|
+
});
|
|
429
1668
|
break;
|
|
430
1669
|
case "update_checklist_item":
|
|
431
|
-
result = await kanbanApi.updateChecklistItem(args.itemId, {
|
|
1670
|
+
result = await kanbanApi.updateChecklistItem(args.itemId, {
|
|
1671
|
+
content: args.content,
|
|
1672
|
+
completed: args.completed
|
|
1673
|
+
});
|
|
432
1674
|
break;
|
|
433
1675
|
case "delete_checklist_item":
|
|
434
1676
|
result = await kanbanApi.deleteChecklistItem(args.itemId);
|
|
435
1677
|
break;
|
|
436
1678
|
case "get_branch_name":
|
|
437
|
-
result = await kanbanApi.getBranchName(
|
|
1679
|
+
result = await kanbanApi.getBranchName(
|
|
1680
|
+
args.cardId,
|
|
1681
|
+
args.type || "feature"
|
|
1682
|
+
);
|
|
438
1683
|
break;
|
|
439
1684
|
case "search_cards":
|
|
440
1685
|
result = await kanbanApi.searchCards(args);
|
|
@@ -446,6 +1691,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
446
1691
|
case "bulk_create_epic_with_cards":
|
|
447
1692
|
result = await kanbanApi.bulkCreateEpicWithCards(args);
|
|
448
1693
|
break;
|
|
1694
|
+
case "bulk_create_epic_with_features":
|
|
1695
|
+
result = await kanbanApi.bulkCreateEpicWithFeatures(args);
|
|
1696
|
+
break;
|
|
449
1697
|
case "bulk_move_cards":
|
|
450
1698
|
result = await kanbanApi.bulkMoveCards(args);
|
|
451
1699
|
break;
|
|
@@ -476,10 +1724,16 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
476
1724
|
result = await kanbanApi.deleteTag(args.tagId);
|
|
477
1725
|
break;
|
|
478
1726
|
case "add_tag_to_card":
|
|
479
|
-
result = await kanbanApi.addTagToCard(
|
|
1727
|
+
result = await kanbanApi.addTagToCard(
|
|
1728
|
+
args.cardId,
|
|
1729
|
+
args.tagId
|
|
1730
|
+
);
|
|
480
1731
|
break;
|
|
481
1732
|
case "remove_tag_from_card":
|
|
482
|
-
result = await kanbanApi.removeTagFromCard(
|
|
1733
|
+
result = await kanbanApi.removeTagFromCard(
|
|
1734
|
+
args.cardId,
|
|
1735
|
+
args.tagId
|
|
1736
|
+
);
|
|
483
1737
|
break;
|
|
484
1738
|
// EPICS
|
|
485
1739
|
case "list_epics":
|
|
@@ -488,6 +1742,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
488
1742
|
case "create_epic":
|
|
489
1743
|
result = await kanbanApi.createEpic(args);
|
|
490
1744
|
break;
|
|
1745
|
+
case "get_epic":
|
|
1746
|
+
result = await kanbanApi.getEpic(args.epicId);
|
|
1747
|
+
break;
|
|
491
1748
|
case "update_epic":
|
|
492
1749
|
result = await kanbanApi.updateEpic(args.epicId, args);
|
|
493
1750
|
break;
|
|
@@ -495,20 +1752,97 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
495
1752
|
result = await kanbanApi.deleteEpic(args.epicId);
|
|
496
1753
|
break;
|
|
497
1754
|
case "add_card_to_epic":
|
|
498
|
-
result = await kanbanApi.addCardToEpic(
|
|
1755
|
+
result = await kanbanApi.addCardToEpic(
|
|
1756
|
+
args.epicId,
|
|
1757
|
+
args.cardId
|
|
1758
|
+
);
|
|
499
1759
|
break;
|
|
500
1760
|
case "remove_card_from_epic":
|
|
501
|
-
result = await kanbanApi.removeCardFromEpic(
|
|
1761
|
+
result = await kanbanApi.removeCardFromEpic(
|
|
1762
|
+
args.epicId,
|
|
1763
|
+
args.cardId
|
|
1764
|
+
);
|
|
1765
|
+
break;
|
|
1766
|
+
// FEATURES
|
|
1767
|
+
case "list_features": {
|
|
1768
|
+
const features = await kanbanApi.listFeatures(args.epicId);
|
|
1769
|
+
const slugFilter = args.slug;
|
|
1770
|
+
result = slugFilter ? (Array.isArray(features) ? features : []).filter(
|
|
1771
|
+
(f) => f.slug === slugFilter.toUpperCase()
|
|
1772
|
+
) : features;
|
|
502
1773
|
break;
|
|
503
|
-
|
|
504
|
-
|
|
1774
|
+
}
|
|
1775
|
+
case "get_feature": {
|
|
1776
|
+
const fId = args.featureId || args.featureSlug;
|
|
1777
|
+
if (!fId)
|
|
1778
|
+
throw new Error("Either featureId or featureSlug is required");
|
|
1779
|
+
result = await kanbanApi.getFeature(fId);
|
|
1780
|
+
break;
|
|
1781
|
+
}
|
|
1782
|
+
case "get_active_features":
|
|
1783
|
+
result = await kanbanApi.getActiveFeatures();
|
|
1784
|
+
break;
|
|
1785
|
+
case "create_feature":
|
|
1786
|
+
result = await kanbanApi.createFeature(args);
|
|
1787
|
+
break;
|
|
1788
|
+
case "update_feature":
|
|
1789
|
+
result = await kanbanApi.updateFeature(
|
|
1790
|
+
args.featureId,
|
|
1791
|
+
args
|
|
1792
|
+
);
|
|
1793
|
+
break;
|
|
1794
|
+
case "delete_feature":
|
|
1795
|
+
result = await kanbanApi.deleteFeature(args.featureId);
|
|
1796
|
+
break;
|
|
1797
|
+
case "add_card_to_feature": {
|
|
1798
|
+
let addFeatureId = args.featureId || args.featureSlug;
|
|
1799
|
+
if (!addFeatureId)
|
|
1800
|
+
throw new Error("Either featureId or featureSlug is required");
|
|
1801
|
+
if (args.featureSlug && !args.featureId) {
|
|
1802
|
+
const resolved = await kanbanApi.getFeature(addFeatureId);
|
|
1803
|
+
addFeatureId = resolved.id;
|
|
1804
|
+
}
|
|
1805
|
+
result = await kanbanApi.addCardToFeature(
|
|
1806
|
+
addFeatureId,
|
|
1807
|
+
args.cardId
|
|
1808
|
+
);
|
|
1809
|
+
break;
|
|
1810
|
+
}
|
|
1811
|
+
case "remove_card_from_feature": {
|
|
1812
|
+
let removeFeatureId = args.featureId || args.featureSlug;
|
|
1813
|
+
if (!removeFeatureId)
|
|
1814
|
+
throw new Error("Either featureId or featureSlug is required");
|
|
1815
|
+
if (args.featureSlug && !args.featureId) {
|
|
1816
|
+
const resolved = await kanbanApi.getFeature(removeFeatureId);
|
|
1817
|
+
removeFeatureId = resolved.id;
|
|
1818
|
+
}
|
|
1819
|
+
result = await kanbanApi.removeCardFromFeature(
|
|
1820
|
+
removeFeatureId,
|
|
1821
|
+
args.cardId
|
|
1822
|
+
);
|
|
1823
|
+
break;
|
|
1824
|
+
}
|
|
1825
|
+
case "get_feature_cards": {
|
|
1826
|
+
let cardsFeatureId = args.featureId || args.featureSlug;
|
|
1827
|
+
if (!cardsFeatureId)
|
|
1828
|
+
throw new Error("Either featureId or featureSlug is required");
|
|
1829
|
+
if (args.featureSlug && !args.featureId) {
|
|
1830
|
+
const resolved = await kanbanApi.getFeature(cardsFeatureId);
|
|
1831
|
+
cardsFeatureId = resolved.id;
|
|
1832
|
+
}
|
|
1833
|
+
result = await kanbanApi.getFeatureCards(cardsFeatureId);
|
|
505
1834
|
break;
|
|
1835
|
+
}
|
|
506
1836
|
// CARD LINKS
|
|
507
1837
|
case "link_cards":
|
|
508
|
-
result = await kanbanApi.linkCards(
|
|
1838
|
+
result = await kanbanApi.linkCards(
|
|
1839
|
+
args.cardId1,
|
|
1840
|
+
args.cardId2,
|
|
1841
|
+
args.label
|
|
1842
|
+
);
|
|
509
1843
|
break;
|
|
510
1844
|
case "unlink_cards":
|
|
511
|
-
result = await kanbanApi.unlinkCards(args.
|
|
1845
|
+
result = await kanbanApi.unlinkCards(args.linkId);
|
|
512
1846
|
break;
|
|
513
1847
|
case "get_linked_cards":
|
|
514
1848
|
result = await kanbanApi.getLinkedCards(args.cardId);
|
|
@@ -521,38 +1855,38 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
521
1855
|
result = await kanbanApi.getGithubIntegration(args.projectId);
|
|
522
1856
|
break;
|
|
523
1857
|
case "update_github_integration":
|
|
524
|
-
result = await kanbanApi.updateGithubIntegration(
|
|
1858
|
+
result = await kanbanApi.updateGithubIntegration(
|
|
1859
|
+
args.projectId,
|
|
1860
|
+
args
|
|
1861
|
+
);
|
|
525
1862
|
break;
|
|
526
1863
|
case "remove_github_integration":
|
|
527
|
-
result = await kanbanApi.removeGithubIntegration(
|
|
1864
|
+
result = await kanbanApi.removeGithubIntegration(
|
|
1865
|
+
args.projectId
|
|
1866
|
+
);
|
|
528
1867
|
break;
|
|
529
1868
|
case "link_card_to_branch":
|
|
530
|
-
result = await kanbanApi.linkCardToBranch(
|
|
1869
|
+
result = await kanbanApi.linkCardToBranch(
|
|
1870
|
+
args.cardId,
|
|
1871
|
+
args.branch
|
|
1872
|
+
);
|
|
531
1873
|
break;
|
|
532
1874
|
case "link_card_to_pr":
|
|
533
|
-
result = await kanbanApi.linkCardToPr(
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
result = await kanbanApi.githubListRepos(args.userId, args.type);
|
|
538
|
-
break;
|
|
539
|
-
case "github_create_branch":
|
|
540
|
-
result = await kanbanApi.githubCreateBranch(args);
|
|
541
|
-
break;
|
|
542
|
-
case "github_create_pr":
|
|
543
|
-
result = await kanbanApi.githubCreatePr(args);
|
|
544
|
-
break;
|
|
545
|
-
case "github_auto_setup_webhook":
|
|
546
|
-
result = await kanbanApi.githubAutoSetupWebhook(args);
|
|
1875
|
+
result = await kanbanApi.linkCardToPr(
|
|
1876
|
+
args.cardId,
|
|
1877
|
+
args.prUrl
|
|
1878
|
+
);
|
|
547
1879
|
break;
|
|
548
1880
|
default:
|
|
549
1881
|
throw new Error(`Unknown tool: ${name}`);
|
|
550
1882
|
}
|
|
551
1883
|
return {
|
|
552
|
-
content: [
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
1884
|
+
content: [
|
|
1885
|
+
{
|
|
1886
|
+
type: "text",
|
|
1887
|
+
text: typeof result === "string" ? result : JSON.stringify(result)
|
|
1888
|
+
}
|
|
1889
|
+
]
|
|
556
1890
|
};
|
|
557
1891
|
} catch (error) {
|
|
558
1892
|
const message = error instanceof Error ? error.message : "Unknown error";
|