snboard-mcp 1.0.5 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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}`, { method: "PATCH", body: JSON.stringify({ folderId }) }),
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: "PATCH", body: JSON.stringify(data) }),
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,28 @@ 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: "PATCH", body: JSON.stringify(data) }),
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: "PATCH", body: JSON.stringify(data) }),
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: "PATCH", body: JSON.stringify(data) }),
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
- moveCard: (id, targetColumnId) => api("/api/cards/move", { method: "POST", body: JSON.stringify({ cardId: id, targetColumnId }) }),
105
+ archiveCard: (id) => api(`/api/cards/${id}`, { method: "PUT", body: JSON.stringify({ isArchived: true }) }),
106
+ unarchiveCard: (id) => api(`/api/cards/${id}`, { method: "PUT", body: JSON.stringify({ isArchived: false }) }),
107
+ listArchivedCards: (boardId) => api(`/api/archived?boardId=${boardId}`),
108
+ moveCard: (id, targetColumnId, newOrder) => api("/api/cards/move", {
109
+ method: "POST",
110
+ body: JSON.stringify({ cardId: id, targetColumnId, ...newOrder !== void 0 && { newOrder } })
111
+ }),
82
112
  getBranchName: (id, type) => api(`/api/cards/${id}/branch?type=${type}`),
83
113
  searchCards: (params) => {
84
114
  const searchParams = new URLSearchParams();
@@ -88,40 +118,115 @@ var kanbanApi = {
88
118
  if (params.columnId) searchParams.set("columnId", params.columnId);
89
119
  if (params.epicId) searchParams.set("epicId", params.epicId);
90
120
  if (params.featureId) searchParams.set("featureId", params.featureId);
91
- if (params.hasEpic !== void 0) searchParams.set("hasEpic", params.hasEpic.toString());
121
+ if (params.hasEpic !== void 0)
122
+ searchParams.set("hasEpic", params.hasEpic.toString());
92
123
  if (params.status) searchParams.set("status", params.status);
93
- if (params.tagIds?.length) searchParams.set("tagIds", params.tagIds.join(","));
124
+ if (params.tagIds?.length)
125
+ searchParams.set("tagIds", params.tagIds.join(","));
94
126
  searchParams.set("limit", (params.limit || 20).toString());
95
127
  if (params.compact) searchParams.set("compact", "true");
96
128
  return api(`/api/search?${searchParams.toString()}`);
97
129
  },
98
- // Bulk Operations (MCP-side aggregation for efficiency)
130
+ // Tags - managed via card update with tagIds
131
+ addTagToCard: async (cardId, tagId) => {
132
+ const card = await api(`/api/cards/${cardId}`);
133
+ const currentTagIds = (card.tags || []).map((t) => t.id);
134
+ if (!currentTagIds.includes(tagId)) {
135
+ currentTagIds.push(tagId);
136
+ }
137
+ return api(`/api/cards/${cardId}`, {
138
+ method: "PUT",
139
+ body: JSON.stringify({ tagIds: currentTagIds })
140
+ });
141
+ },
142
+ removeTagFromCard: async (cardId, tagId) => {
143
+ const card = await api(`/api/cards/${cardId}`);
144
+ const currentTagIds = (card.tags || []).map((t) => t.id).filter((id) => id !== tagId);
145
+ return api(`/api/cards/${cardId}`, {
146
+ method: "PUT",
147
+ body: JSON.stringify({ tagIds: currentTagIds })
148
+ });
149
+ },
150
+ // Bulk Operations
99
151
  bulkCreateCards: async (data) => {
100
152
  const results = await Promise.all(
101
153
  data.cards.map(
102
- (card) => api("/api/cards", { method: "POST", body: JSON.stringify({ columnId: data.columnId, ...card }) })
154
+ (card) => api("/api/cards", {
155
+ method: "POST",
156
+ body: JSON.stringify({ columnId: data.columnId, ...card })
157
+ })
103
158
  )
104
159
  );
105
160
  return { created: results.length, cards: results };
106
161
  },
107
162
  bulkCreateEpicWithCards: async (data) => {
108
- const epic = await api("/api/epics", { method: "POST", body: JSON.stringify(data.epic) });
163
+ const epic = await api("/api/epics", {
164
+ method: "POST",
165
+ body: JSON.stringify(data.epic)
166
+ });
109
167
  const cardResults = await Promise.all(
110
168
  data.cards.map(
111
- (card) => api("/api/cards", { method: "POST", body: JSON.stringify({ columnId: data.columnId, epicId: epic.id, ...card }) })
169
+ (card) => api("/api/cards", {
170
+ method: "POST",
171
+ body: JSON.stringify({
172
+ columnId: data.columnId,
173
+ epicId: epic.id,
174
+ ...card
175
+ })
176
+ })
112
177
  )
113
178
  );
114
179
  return { epic, cards: cardResults, created: cardResults.length };
115
180
  },
181
+ bulkCreateEpicWithFeatures: async (data) => {
182
+ const epic = await api("/api/epics", { method: "POST", body: JSON.stringify(data.epic) });
183
+ const features = await Promise.all(
184
+ data.features.map(
185
+ (f) => api("/api/features", {
186
+ method: "POST",
187
+ body: JSON.stringify({ epicId: epic.id, title: f.title, slug: f.slug, description: f.description })
188
+ })
189
+ )
190
+ );
191
+ const featureResults = await Promise.all(
192
+ features.map(async (feature, i) => {
193
+ const featureCards = data.features[i].cards;
194
+ const cards = await Promise.all(
195
+ featureCards.map(
196
+ (c) => api("/api/cards", {
197
+ method: "POST",
198
+ body: JSON.stringify({ ...c, epicId: epic.id })
199
+ })
200
+ )
201
+ );
202
+ for (const card of cards) {
203
+ await api(`/api/features/${feature.id}/cards`, {
204
+ method: "POST",
205
+ body: JSON.stringify({ cardId: card.id })
206
+ });
207
+ }
208
+ return { id: feature.id, slug: feature.slug, title: feature.title, cardIds: cards.map((c) => c.id) };
209
+ })
210
+ );
211
+ const totalCards = featureResults.reduce((sum, f) => sum + f.cardIds.length, 0);
212
+ return {
213
+ epic: { id: epic.id, slug: epic.slug, name: epic.name },
214
+ features: featureResults,
215
+ total: { features: features.length, cards: totalCards }
216
+ };
217
+ },
116
218
  bulkMoveCards: async (data) => {
117
219
  const results = await Promise.all(
118
220
  data.cardIds.map(
119
- (cardId) => api("/api/cards/move", { method: "POST", body: JSON.stringify({ cardId, targetColumnId: data.targetColumnId }) })
221
+ (cardId) => api("/api/cards/move", {
222
+ method: "POST",
223
+ body: JSON.stringify({ cardId, targetColumnId: data.targetColumnId })
224
+ })
120
225
  )
121
226
  );
122
227
  return { moved: results.length };
123
228
  },
124
- // Aggregated views (reduces multiple API calls to 1)
229
+ // Aggregated views
125
230
  getWorkspace: async (projectId) => {
126
231
  const project = await api(
127
232
  `/api/projects/${projectId}?includeBoards=true&boardsCompact=true`
@@ -130,10 +235,15 @@ var kanbanApi = {
130
235
  const boardsWithColumns = await Promise.all(
131
236
  project.boards.map((b) => api(`/api/boards/${b.id}`))
132
237
  );
133
- return { project: { id: project.id, name: project.name }, boards: boardsWithColumns };
238
+ return {
239
+ project: { id: project.id, name: project.name },
240
+ boards: boardsWithColumns
241
+ };
134
242
  },
135
243
  getBoardSummary: async (boardId) => {
136
- const board = await api(`/api/boards/${boardId}?includeCards=true&compact=true`);
244
+ const board = await api(
245
+ `/api/boards/${boardId}?includeCards=true&compact=true`
246
+ );
137
247
  const summary = {
138
248
  id: board.id,
139
249
  name: board.name,
@@ -145,16 +255,25 @@ var kanbanApi = {
145
255
  p2Count: col.cards?.filter((c) => c.priority === "P2").length || 0,
146
256
  p3Count: col.cards?.filter((c) => c.priority === "P3").length || 0
147
257
  })),
148
- totalCards: board.columns.reduce((sum, col) => sum + (col.cards?.length || 0), 0)
258
+ totalCards: board.columns.reduce(
259
+ (sum, col) => sum + (col.cards?.length || 0),
260
+ 0
261
+ )
149
262
  };
150
263
  return summary;
151
264
  },
152
265
  getEpicSummary: async (epicId) => {
153
266
  const epic = await api(`/api/epics/${epicId}`);
154
267
  const cards = epic.cards || [];
155
- const todoCards = cards.filter((c) => c.column?.name?.toLowerCase().includes("todo") || c.column?.name?.toLowerCase().includes("to do"));
156
- const inProgressCards = cards.filter((c) => c.column?.name?.toLowerCase().includes("progress"));
157
- const doneCards = cards.filter((c) => c.column?.name?.toLowerCase().includes("done"));
268
+ const todoCards = cards.filter(
269
+ (c) => c.column?.name?.toLowerCase().includes("todo") || c.column?.name?.toLowerCase().includes("to do")
270
+ );
271
+ const inProgressCards = cards.filter(
272
+ (c) => c.column?.name?.toLowerCase().includes("progress")
273
+ );
274
+ const doneCards = cards.filter(
275
+ (c) => c.column?.name?.toLowerCase().includes("done")
276
+ );
158
277
  return {
159
278
  id: epic.id,
160
279
  slug: epic.slug,
@@ -190,7 +309,12 @@ var kanbanApi = {
190
309
  }
191
310
  if (!cards.length) return { created: 0, cards: [] };
192
311
  const results = await Promise.all(
193
- cards.map((card) => api("/api/cards", { method: "POST", body: JSON.stringify({ columnId: data.columnId, ...card }) }))
312
+ cards.map(
313
+ (card) => api("/api/cards", {
314
+ method: "POST",
315
+ body: JSON.stringify({ columnId: data.columnId, ...card })
316
+ })
317
+ )
194
318
  );
195
319
  return { created: results.length, cards: results };
196
320
  },
@@ -201,141 +325,1338 @@ var kanbanApi = {
201
325
  const cards = Array.isArray(searchResult) ? searchResult : searchResult.cards || [];
202
326
  if (!cards.length) return { moved: 0 };
203
327
  await Promise.all(
204
- cards.map((c) => api("/api/cards/move", { method: "POST", body: JSON.stringify({ cardId: c.id, targetColumnId: data.targetColumnId }) }))
328
+ cards.map(
329
+ (c) => api("/api/cards/move", {
330
+ method: "POST",
331
+ body: JSON.stringify({
332
+ cardId: c.id,
333
+ targetColumnId: data.targetColumnId
334
+ })
335
+ })
336
+ )
205
337
  );
206
338
  return { moved: cards.length };
207
339
  },
208
340
  // Comments
209
- addComment: (cardId, content) => api("/api/comments", { method: "POST", body: JSON.stringify({ cardId, content }) }),
341
+ addComment: (cardId, content) => api("/api/comments", {
342
+ method: "POST",
343
+ body: JSON.stringify({ cardId, content })
344
+ }),
345
+ deleteComment: (commentId) => api(`/api/comments?id=${commentId}`, { method: "DELETE" }),
210
346
  // Checklists
211
347
  createChecklist: (data) => api("/api/checklists", { method: "POST", body: JSON.stringify(data) }),
212
348
  updateChecklist: (id, data) => api(`/api/checklists/${id}`, { method: "PUT", body: JSON.stringify(data) }),
213
349
  deleteChecklist: (id) => api(`/api/checklists/${id}`, { method: "DELETE" }),
214
350
  // Checklist Items
215
351
  createChecklistItem: (data) => api("/api/checklist-items", { method: "POST", body: JSON.stringify(data) }),
216
- updateChecklistItem: (id, data) => api(`/api/checklist-items/${id}`, { method: "PUT", body: JSON.stringify(data) }),
352
+ updateChecklistItem: (id, data) => api(`/api/checklist-items/${id}`, {
353
+ method: "PUT",
354
+ body: JSON.stringify(data)
355
+ }),
217
356
  deleteChecklistItem: (id) => api(`/api/checklist-items/${id}`, { method: "DELETE" }),
218
357
  // Tags
219
358
  listTags: () => api("/api/tags"),
220
359
  createTag: (data) => api("/api/tags", { method: "POST", body: JSON.stringify(data) }),
221
- deleteTag: (id) => api(`/api/tags/${id}`, { method: "DELETE" }),
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" }),
360
+ deleteTag: (id) => api(`/api/tags?id=${id}`, { method: "DELETE" }),
224
361
  // Epics
225
362
  listEpics: (params) => {
226
363
  const searchParams = new URLSearchParams();
227
364
  if (params?.status) searchParams.set("status", params.status);
228
- if (params?.includeProgress === false) searchParams.set("includeProgress", "false");
365
+ if (params?.includeProgress === false)
366
+ searchParams.set("includeProgress", "false");
229
367
  searchParams.set("limit", (params?.limit || 15).toString());
230
368
  if (params?.compact) searchParams.set("compact", "true");
231
369
  const query = searchParams.toString();
232
370
  return api(`/api/epics${query ? `?${query}` : ""}`);
233
371
  },
234
372
  createEpic: (data) => api("/api/epics", { method: "POST", body: JSON.stringify(data) }),
235
- updateEpic: (id, data) => api(`/api/epics/${id}`, { method: "PATCH", body: JSON.stringify(data) }),
373
+ updateEpic: (id, data) => api(`/api/epics/${id}`, { method: "PUT", body: JSON.stringify(data) }),
374
+ getEpic: (id) => api(`/api/epics/${id}`),
236
375
  deleteEpic: (id) => api(`/api/epics/${id}`, { method: "DELETE" }),
237
- addCardToEpic: (epicId, cardId) => api(`/api/epics/${epicId}/cards`, { method: "POST", body: JSON.stringify({ cardId }) }),
376
+ addCardToEpic: (epicId, cardId) => api(`/api/epics/${epicId}/cards`, {
377
+ method: "POST",
378
+ body: JSON.stringify({ cardId })
379
+ }),
238
380
  removeCardFromEpic: (epicId, cardId) => api(`/api/epics/${epicId}/cards/${cardId}`, { method: "DELETE" }),
239
- getEpicTimeline: () => api("/api/epics/timeline"),
381
+ // Features
382
+ listFeatures: (epicId) => {
383
+ const query = epicId ? `?epicId=${epicId}` : "";
384
+ return api(`/api/features${query}`);
385
+ },
386
+ getFeature: (id) => api(`/api/features/${id}`),
387
+ getActiveFeatures: () => api("/api/features/active"),
388
+ createFeature: (data) => api("/api/features", { method: "POST", body: JSON.stringify(data) }),
389
+ updateFeature: (id, data) => api(`/api/features/${id}`, { method: "PATCH", body: JSON.stringify(data) }),
390
+ deleteFeature: (id) => api(`/api/features/${id}`, { method: "DELETE" }),
391
+ addCardToFeature: (featureId, cardId) => api(`/api/features/${featureId}/cards`, { method: "POST", body: JSON.stringify({ cardId }) }),
392
+ removeCardFromFeature: (featureId, cardId) => api(`/api/features/${featureId}/cards/${cardId}`, { method: "DELETE" }),
393
+ getFeatureCards: (featureId) => api(`/api/features/${featureId}/cards`),
240
394
  // Card Links
241
- linkCards: (cardId1, cardId2, label) => api("/api/card-links", { method: "POST", body: JSON.stringify({ cardId1, cardId2, label }) }),
242
- unlinkCards: (cardId1, cardId2) => api("/api/card-links", { method: "DELETE", body: JSON.stringify({ cardId1, cardId2 }) }),
395
+ linkCards: (cardId1, cardId2, label) => api("/api/card-links", {
396
+ method: "POST",
397
+ body: JSON.stringify({ fromCardId: cardId1, toCardId: cardId2, label })
398
+ }),
399
+ unlinkCards: (linkId) => api(`/api/card-links?id=${linkId}`, { method: "DELETE" }),
243
400
  getLinkedCards: (cardId) => api(`/api/card-links?cardId=${cardId}`),
244
- // GitHub Integration
245
- setupGithubIntegration: (data) => api("/api/github/integration", { method: "POST", body: JSON.stringify(data) }),
246
- getGithubIntegration: (projectId) => api(`/api/github/integration?projectId=${projectId}`),
247
- updateGithubIntegration: (projectId, data) => api(`/api/github/integration/${projectId}`, { method: "PATCH", body: JSON.stringify(data) }),
248
- removeGithubIntegration: (projectId) => api(`/api/github/integration/${projectId}`, { method: "DELETE" }),
249
- linkCardToBranch: (cardId, branch) => api(`/api/cards/${cardId}`, { method: "PATCH", body: JSON.stringify({ githubBranch: branch }) }),
250
- linkCardToPr: (cardId, prUrl) => api(`/api/cards/${cardId}`, { method: "PATCH", body: JSON.stringify({ githubPrUrl: prUrl }) }),
401
+ // GitHub Integration - routes at /api/projects/[id]/github
402
+ setupGithubIntegration: (data) => api(`/api/projects/${data.projectId}/github`, {
403
+ method: "POST",
404
+ body: JSON.stringify(data)
405
+ }),
406
+ getGithubIntegration: (projectId) => api(`/api/projects/${projectId}/github`),
407
+ updateGithubIntegration: (projectId, data) => api(`/api/projects/${projectId}/github`, {
408
+ method: "PUT",
409
+ body: JSON.stringify(data)
410
+ }),
411
+ removeGithubIntegration: (projectId) => api(`/api/projects/${projectId}/github`, { method: "DELETE" }),
412
+ linkCardToBranch: (cardId, branch) => api(`/api/cards/${cardId}`, {
413
+ method: "PUT",
414
+ body: JSON.stringify({ githubBranch: branch })
415
+ }),
416
+ linkCardToPr: (cardId, prUrl) => api(`/api/cards/${cardId}`, {
417
+ method: "PUT",
418
+ body: JSON.stringify({ githubPrUrl: prUrl })
419
+ }),
251
420
  // GitHub API
252
421
  githubListRepos: (userId, type) => api(`/api/github/repos?userId=${userId}${type ? `&type=${type}` : ""}`),
253
422
  githubCreateBranch: (data) => api("/api/github/branches", { method: "POST", body: JSON.stringify(data) }),
254
- githubCreatePr: (data) => api("/api/github/pull-requests", { method: "POST", body: JSON.stringify(data) }),
255
- githubAutoSetupWebhook: (data) => api("/api/github/webhooks/auto-setup", { method: "POST", body: JSON.stringify(data) })
423
+ githubCreatePr: (data) => api("/api/github/pull-requests", {
424
+ method: "POST",
425
+ body: JSON.stringify(data)
426
+ }),
427
+ // Ideas
428
+ listIdeas: (params) => {
429
+ const searchParams = new URLSearchParams();
430
+ if (params?.status) searchParams.set("status", params.status);
431
+ if (params?.filter) searchParams.set("filter", params.filter);
432
+ const query = searchParams.toString();
433
+ return api(`/api/ideas${query ? `?${query}` : ""}`);
434
+ },
435
+ getIdea: (id) => api(`/api/ideas/${id}`),
436
+ createIdea: (data) => api("/api/ideas", { method: "POST", body: JSON.stringify(data) }),
437
+ updateIdea: (id, data) => api(`/api/ideas/${id}`, { method: "PATCH", body: JSON.stringify(data) }),
438
+ deleteIdea: (id) => api(`/api/ideas/${id}`, { method: "DELETE" }),
439
+ convertIdeaToCard: (ideaId, data) => api(`/api/ideas/${ideaId}/convert`, { method: "POST", body: JSON.stringify(data) }),
440
+ // Time Tracking
441
+ getTimeTracking: (params) => {
442
+ const searchParams = new URLSearchParams();
443
+ if (params?.startDate) searchParams.set("startDate", params.startDate);
444
+ if (params?.endDate) searchParams.set("endDate", params.endDate);
445
+ if (params?.projectId) searchParams.set("projectId", params.projectId);
446
+ const query = searchParams.toString();
447
+ return api(`/api/time-tracking${query ? `?${query}` : ""}`);
448
+ },
449
+ logActivity: (data) => api("/api/time-tracking", { method: "POST", body: JSON.stringify(data) }),
450
+ endTimeSession: () => api("/api/time-tracking", { method: "DELETE" }),
451
+ // Daily Summary
452
+ getDailySummary: () => api("/api/daily-summary"),
453
+ // Retrospective
454
+ getRetrospective: (days) => api(`/api/retrospectives/weekly${days ? `?days=${days}` : ""}`),
455
+ // Export
456
+ exportBoard: (boardId) => api(`/api/export/board/${boardId}`),
457
+ exportProject: (projectId) => api(`/api/export/project/${projectId}`)
256
458
  };
257
459
  var server = new Server(
258
- { name: "kanban-mcp", version: "1.0.0" },
460
+ { name: "kanban-mcp", version: "1.1.0" },
259
461
  { capabilities: { tools: {} } }
260
462
  );
261
463
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
262
464
  tools: [
263
465
  // FOLDERS
264
- { name: "list_folders", description: "List all folders with their projects", inputSchema: { type: "object", properties: {} } },
265
- { name: "create_folder", description: "Create a new folder to organize projects", inputSchema: { type: "object", properties: { name: { type: "string" }, icon: { type: "string" }, color: { type: "string" } }, required: ["name"] } },
266
- { name: "update_folder", description: "Update a folder (name, icon, color)", inputSchema: { type: "object", properties: { folderId: { type: "string" }, name: { type: "string" }, icon: { type: "string" }, color: { type: "string" } }, required: ["folderId"] } },
267
- { name: "delete_folder", description: "Delete a folder (projects become orphans)", inputSchema: { type: "object", properties: { folderId: { type: "string" } }, required: ["folderId"] } },
268
- { name: "move_project_to_folder", description: "Move project to folder (null to remove)", inputSchema: { type: "object", properties: { projectId: { type: "string" }, folderId: { type: "string" } }, required: ["projectId"] } },
466
+ {
467
+ name: "list_folders",
468
+ description: "List all folders with their projects",
469
+ inputSchema: { type: "object", properties: {} }
470
+ },
471
+ {
472
+ name: "create_folder",
473
+ description: "Create a new folder to organize projects",
474
+ inputSchema: {
475
+ type: "object",
476
+ properties: {
477
+ name: { type: "string" },
478
+ icon: { type: "string" },
479
+ color: { type: "string" }
480
+ },
481
+ required: ["name"]
482
+ }
483
+ },
484
+ {
485
+ name: "update_folder",
486
+ description: "Update a folder (name, icon, color)",
487
+ inputSchema: {
488
+ type: "object",
489
+ properties: {
490
+ folderId: { type: "string" },
491
+ name: { type: "string" },
492
+ icon: { type: "string" },
493
+ color: { type: "string" }
494
+ },
495
+ required: ["folderId"]
496
+ }
497
+ },
498
+ {
499
+ name: "delete_folder",
500
+ description: "Delete a folder (projects become orphans)",
501
+ inputSchema: {
502
+ type: "object",
503
+ properties: { folderId: { type: "string" } },
504
+ required: ["folderId"]
505
+ }
506
+ },
507
+ {
508
+ name: "move_project_to_folder",
509
+ description: "Move project to folder (null to remove)",
510
+ inputSchema: {
511
+ type: "object",
512
+ properties: {
513
+ projectId: { type: "string" },
514
+ folderId: { type: "string" }
515
+ },
516
+ required: ["projectId"]
517
+ }
518
+ },
519
+ {
520
+ name: "reorder_folders",
521
+ description: "Reorder folders by moving one before/after another",
522
+ inputSchema: {
523
+ type: "object",
524
+ properties: {
525
+ folderId: { type: "string" },
526
+ targetFolderId: { type: "string" }
527
+ },
528
+ required: ["folderId", "targetFolderId"]
529
+ }
530
+ },
269
531
  // PROJECTS
270
- { name: "list_projects", description: "List projects (default limit:20). Use compact:true for minimal fields", inputSchema: { type: "object", properties: { folderId: { type: "string" }, limit: { type: "number" }, compact: { type: "boolean" } } } },
271
- { name: "create_project", description: "Create a new project", inputSchema: { type: "object", properties: { name: { type: "string" }, description: { type: "string" }, emoji: { type: "string" }, color: { type: "string" }, folderId: { type: "string" } }, required: ["name"] } },
272
- { name: "get_project", description: "Get project. Use includeBoards:true to get boards in 1 call", inputSchema: { type: "object", properties: { projectId: { type: "string" }, includeBoards: { type: "boolean" }, boardsCompact: { type: "boolean" } }, required: ["projectId"] } },
273
- { name: "update_project", description: "Update project", inputSchema: { type: "object", properties: { projectId: { type: "string" }, name: { type: "string" }, description: { type: "string" }, emoji: { type: "string" }, color: { type: "string" } }, required: ["projectId"] } },
274
- { name: "delete_project", description: "Delete project and all its content", inputSchema: { type: "object", properties: { projectId: { type: "string" } }, required: ["projectId"] } },
275
- // BOARDS (use get_workspace or get_project(includeBoards:true) to list boards)
276
- { name: "create_board", description: "Create board with default columns", inputSchema: { type: "object", properties: { projectId: { type: "string" }, name: { type: "string" } }, required: ["projectId", "name"] } },
277
- { name: "get_board", description: "Get board with columns. Cards NOT included by default. Use includeCards:true + cardLimit + columnId to get specific cards.", inputSchema: { type: "object", properties: { boardId: { type: "string" }, columnId: { type: "string", description: "Get only this column" }, includeCards: { type: "boolean", description: "Include cards (default: false)" }, cardLimit: { type: "number", description: "Max cards per column (e.g. 5)" }, priority: { type: "string", enum: ["P1", "P2", "P3"] }, compact: { type: "boolean", description: "Minimal fields (id, title, priority)" }, includeTags: { type: "boolean" }, includeComments: { type: "boolean", description: "Include comments (max 5)" } }, required: ["boardId"] } },
278
- { name: "update_board", description: "Rename a board", inputSchema: { type: "object", properties: { boardId: { type: "string" }, name: { type: "string" } }, required: ["boardId", "name"] } },
279
- { name: "delete_board", description: "Delete board and all content", inputSchema: { type: "object", properties: { boardId: { type: "string" } }, required: ["boardId"] } },
532
+ {
533
+ name: "list_projects",
534
+ description: "List projects (default limit:20). Use compact:true for minimal fields",
535
+ inputSchema: {
536
+ type: "object",
537
+ properties: {
538
+ folderId: { type: "string", description: 'Filter by folder. Use "none" for orphan projects' },
539
+ limit: { type: "number" },
540
+ compact: { type: "boolean" }
541
+ }
542
+ }
543
+ },
544
+ {
545
+ name: "create_project",
546
+ description: "Create a new project",
547
+ inputSchema: {
548
+ type: "object",
549
+ properties: {
550
+ name: { type: "string" },
551
+ description: { type: "string" },
552
+ emoji: { type: "string" },
553
+ color: { type: "string" },
554
+ folderId: { type: "string" }
555
+ },
556
+ required: ["name"]
557
+ }
558
+ },
559
+ {
560
+ name: "get_project",
561
+ description: "Get project. Use includeBoards:true to get boards in 1 call",
562
+ inputSchema: {
563
+ type: "object",
564
+ properties: {
565
+ projectId: { type: "string" },
566
+ includeBoards: { type: "boolean" },
567
+ boardsCompact: { type: "boolean" }
568
+ },
569
+ required: ["projectId"]
570
+ }
571
+ },
572
+ {
573
+ name: "update_project",
574
+ description: "Update project",
575
+ inputSchema: {
576
+ type: "object",
577
+ properties: {
578
+ projectId: { type: "string" },
579
+ name: { type: "string" },
580
+ description: { type: "string" },
581
+ emoji: { type: "string" },
582
+ color: { type: "string" },
583
+ folderId: { type: "string", description: "Move to folder (null to remove)" }
584
+ },
585
+ required: ["projectId"]
586
+ }
587
+ },
588
+ {
589
+ name: "delete_project",
590
+ description: "Delete project and all its content",
591
+ inputSchema: {
592
+ type: "object",
593
+ properties: { projectId: { type: "string" } },
594
+ required: ["projectId"]
595
+ }
596
+ },
597
+ {
598
+ name: "reorder_projects",
599
+ description: "Reorder projects within a folder",
600
+ inputSchema: {
601
+ type: "object",
602
+ properties: {
603
+ projectId: { type: "string" },
604
+ targetProjectId: { type: "string" },
605
+ folderId: { type: "string", description: "Folder context (null for orphans)" }
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
- { name: "create_column", description: "Create column in board", inputSchema: { type: "object", properties: { boardId: { type: "string" }, name: { type: "string" }, emoji: { type: "string" } }, required: ["boardId", "name"] } },
282
- { name: "update_column", description: "Update column", inputSchema: { type: "object", properties: { columnId: { type: "string" }, name: { type: "string" }, emoji: { type: "string" } }, required: ["columnId"] } },
283
- { name: "delete_column", description: "Delete column and cards", inputSchema: { type: "object", properties: { columnId: { type: "string" } }, required: ["columnId"] } },
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
- { name: "create_card", description: "Create card. Auto-assign to epic if title starts with [SLUG]. featureId for multi-project features.", inputSchema: { type: "object", properties: { columnId: { type: "string" }, title: { type: "string" }, description: { type: "string" }, priority: { type: "string", enum: ["P1", "P2", "P3"] }, featureId: { type: "string" }, dueDate: { type: "string" }, epicId: { type: "string" }, tagIds: { type: "array", items: { type: "string" } }, linkedCardIds: { type: "array", items: { type: "string" } }, linkLabel: { type: "string" } }, required: ["columnId", "title"] } },
286
- { name: "update_card", description: "Update card", inputSchema: { type: "object", properties: { cardId: { type: "string" }, title: { type: "string" }, description: { type: "string" }, priority: { type: "string", enum: ["P1", "P2", "P3"] }, featureId: { type: "string" }, dueDate: { type: "string" } }, required: ["cardId"] } },
287
- { name: "delete_card", description: "Delete a card", inputSchema: { type: "object", properties: { cardId: { type: "string" } }, required: ["cardId"] } },
288
- { name: "move_card", description: "Move card to column", inputSchema: { type: "object", properties: { cardId: { type: "string" }, targetColumnId: { type: "string" } }, required: ["cardId", "targetColumnId"] } },
289
- { name: "add_comment", description: "Add comment to card", inputSchema: { type: "object", properties: { cardId: { type: "string" }, content: { type: "string" } }, required: ["cardId", "content"] } },
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: { type: "number", description: "Estimated time in minutes" },
762
+ cognitiveLoad: { type: "string", description: "Cognitive load level" }
763
+ },
764
+ required: ["columnId", "title"]
765
+ }
766
+ },
767
+ {
768
+ name: "update_card",
769
+ description: "Update card fields",
770
+ inputSchema: {
771
+ type: "object",
772
+ properties: {
773
+ cardId: { type: "string" },
774
+ title: { type: "string" },
775
+ description: { type: "string" },
776
+ priority: { type: "string", enum: ["P1", "P2", "P3"] },
777
+ dueDate: { type: "string" },
778
+ tagIds: { type: "array", items: { type: "string" }, description: "Replace all tags with these IDs" },
779
+ cognitiveLoad: { type: "string" },
780
+ estimatedMinutes: { type: "number" },
781
+ githubBranch: { type: "string" },
782
+ githubPrUrl: { type: "string" },
783
+ isArchived: { type: "boolean" }
784
+ },
785
+ required: ["cardId"]
786
+ }
787
+ },
788
+ {
789
+ name: "delete_card",
790
+ description: "Delete a card",
791
+ inputSchema: {
792
+ type: "object",
793
+ properties: { cardId: { type: "string" } },
794
+ required: ["cardId"]
795
+ }
796
+ },
797
+ {
798
+ name: "archive_card",
799
+ description: "Archive a card",
800
+ inputSchema: {
801
+ type: "object",
802
+ properties: { cardId: { type: "string" } },
803
+ required: ["cardId"]
804
+ }
805
+ },
806
+ {
807
+ name: "unarchive_card",
808
+ description: "Unarchive a card (restore from archive)",
809
+ inputSchema: {
810
+ type: "object",
811
+ properties: { cardId: { type: "string" } },
812
+ required: ["cardId"]
813
+ }
814
+ },
815
+ {
816
+ name: "list_archived_cards",
817
+ description: "List archived cards for a board",
818
+ inputSchema: {
819
+ type: "object",
820
+ properties: { boardId: { type: "string" } },
821
+ required: ["boardId"]
822
+ }
823
+ },
824
+ {
825
+ name: "move_card",
826
+ description: "Move card to column. Use newOrder for specific positioning.",
827
+ inputSchema: {
828
+ type: "object",
829
+ properties: {
830
+ cardId: { type: "string" },
831
+ targetColumnId: { type: "string" },
832
+ newOrder: { type: "number", description: "Position in target column (0-indexed, default: end)" }
833
+ },
834
+ required: ["cardId", "targetColumnId"]
835
+ }
836
+ },
837
+ {
838
+ name: "add_comment",
839
+ description: "Add comment to card",
840
+ inputSchema: {
841
+ type: "object",
842
+ properties: { cardId: { type: "string" }, content: { type: "string" } },
843
+ required: ["cardId", "content"]
844
+ }
845
+ },
846
+ {
847
+ name: "delete_comment",
848
+ description: "Delete a comment",
849
+ inputSchema: {
850
+ type: "object",
851
+ properties: { commentId: { type: "string" } },
852
+ required: ["commentId"]
853
+ }
854
+ },
290
855
  // CHECKLISTS
291
- { name: "create_checklist", description: "Create checklist on card", inputSchema: { type: "object", properties: { cardId: { type: "string" }, title: { type: "string" } }, required: ["cardId", "title"] } },
292
- { name: "update_checklist", description: "Update checklist title", inputSchema: { type: "object", properties: { checklistId: { type: "string" }, title: { type: "string" } }, required: ["checklistId", "title"] } },
293
- { name: "delete_checklist", description: "Delete checklist", inputSchema: { type: "object", properties: { checklistId: { type: "string" } }, required: ["checklistId"] } },
294
- { name: "create_checklist_item", description: "Add checklist item", inputSchema: { type: "object", properties: { checklistId: { type: "string" }, content: { type: "string" } }, required: ["checklistId", "content"] } },
295
- { name: "update_checklist_item", description: "Update checklist item", inputSchema: { type: "object", properties: { itemId: { type: "string" }, content: { type: "string" }, completed: { type: "boolean" } }, required: ["itemId"] } },
296
- { name: "delete_checklist_item", description: "Delete checklist item", inputSchema: { type: "object", properties: { itemId: { type: "string" } }, required: ["itemId"] } },
297
- { name: "get_branch_name", description: "Generate GitHub branch name", inputSchema: { type: "object", properties: { cardId: { type: "string" }, type: { type: "string", enum: ["feature", "fix", "chore", "refactor", "docs"] } }, required: ["cardId"] } },
298
- { name: "search_cards", description: "Search cards (default limit:20). Use compact:true for minimal fields", inputSchema: { type: "object", properties: { query: { type: "string" }, projectId: { type: "string" }, boardId: { type: "string" }, columnId: { type: "string" }, epicId: { type: "string" }, featureId: { type: "string" }, hasEpic: { type: "boolean" }, status: { type: "string", enum: ["todo", "in_progress", "done"] }, tagIds: { type: "array", items: { type: "string" } }, limit: { type: "number" }, compact: { type: "boolean" } }, required: ["query"] } },
299
- // BULK OPERATIONS (reduces API calls)
300
- { name: "bulk_create_cards", description: "Create multiple cards in 1 call", inputSchema: { type: "object", properties: { columnId: { type: "string" }, cards: { type: "array", items: { type: "object", properties: { title: { type: "string" }, description: { type: "string" }, priority: { type: "string", enum: ["P1", "P2", "P3"] }, epicId: { type: "string" } }, required: ["title"] } } }, required: ["columnId", "cards"] } },
301
- { name: "bulk_create_epic_with_cards", description: "Create epic + all its cards in 1 call", inputSchema: { type: "object", properties: { epic: { type: "object", properties: { slug: { type: "string" }, name: { type: "string" }, description: { type: "string" }, emoji: { type: "string" }, color: { type: "string" } }, required: ["slug", "name"] }, columnId: { type: "string" }, cards: { type: "array", items: { type: "object", properties: { title: { type: "string" }, description: { type: "string" }, priority: { type: "string", enum: ["P1", "P2", "P3"] } }, required: ["title"] } } }, required: ["epic", "columnId", "cards"] } },
302
- { name: "bulk_move_cards", description: "Move multiple cards to column in 1 call", inputSchema: { type: "object", properties: { cardIds: { type: "array", items: { type: "string" } }, targetColumnId: { type: "string" } }, required: ["cardIds", "targetColumnId"] } },
303
- { name: "quick_add_cards", description: 'Create cards from multiline text. Format: "- P1: task title" per line', inputSchema: { type: "object", properties: { columnId: { type: "string" }, text: { type: "string", description: "Multiline text, 1 card per line" }, defaultPriority: { type: "string", enum: ["P1", "P2", "P3"] } }, required: ["columnId", "text"] } },
304
- { name: "move_cards_by_column", description: "Move ALL cards from one column to another", inputSchema: { type: "object", properties: { sourceColumnId: { type: "string" }, targetColumnId: { type: "string" }, limit: { type: "number" } }, required: ["sourceColumnId", "targetColumnId"] } },
305
- // AGGREGATED VIEWS (1 call instead of many)
306
- { name: "get_workspace", description: "Get project + all boards + columns in 1 call (no cards)", inputSchema: { type: "object", properties: { projectId: { type: "string" } }, required: ["projectId"] } },
307
- { name: "get_board_summary", description: "Get board stats only: card counts per column + priority breakdown", inputSchema: { type: "object", properties: { boardId: { type: "string" } }, required: ["boardId"] } },
308
- { name: "get_epic_summary", description: "Get epic with minimal card info: {id,title,priority,status} + progress stats", inputSchema: { type: "object", properties: { epicId: { type: "string" } }, required: ["epicId"] } },
856
+ {
857
+ name: "create_checklist",
858
+ description: "Create checklist on card",
859
+ inputSchema: {
860
+ type: "object",
861
+ properties: { cardId: { type: "string" }, title: { type: "string" } },
862
+ required: ["cardId", "title"]
863
+ }
864
+ },
865
+ {
866
+ name: "update_checklist",
867
+ description: "Update checklist title",
868
+ inputSchema: {
869
+ type: "object",
870
+ properties: {
871
+ checklistId: { type: "string" },
872
+ title: { type: "string" }
873
+ },
874
+ required: ["checklistId", "title"]
875
+ }
876
+ },
877
+ {
878
+ name: "delete_checklist",
879
+ description: "Delete checklist",
880
+ inputSchema: {
881
+ type: "object",
882
+ properties: { checklistId: { type: "string" } },
883
+ required: ["checklistId"]
884
+ }
885
+ },
886
+ {
887
+ name: "create_checklist_item",
888
+ description: "Add checklist item",
889
+ inputSchema: {
890
+ type: "object",
891
+ properties: {
892
+ checklistId: { type: "string" },
893
+ content: { type: "string" }
894
+ },
895
+ required: ["checklistId", "content"]
896
+ }
897
+ },
898
+ {
899
+ name: "update_checklist_item",
900
+ description: "Update checklist item",
901
+ inputSchema: {
902
+ type: "object",
903
+ properties: {
904
+ itemId: { type: "string" },
905
+ content: { type: "string" },
906
+ completed: { type: "boolean" }
907
+ },
908
+ required: ["itemId"]
909
+ }
910
+ },
911
+ {
912
+ name: "delete_checklist_item",
913
+ description: "Delete checklist item",
914
+ inputSchema: {
915
+ type: "object",
916
+ properties: { itemId: { type: "string" } },
917
+ required: ["itemId"]
918
+ }
919
+ },
920
+ {
921
+ name: "get_branch_name",
922
+ description: "Generate GitHub branch name",
923
+ inputSchema: {
924
+ type: "object",
925
+ properties: {
926
+ cardId: { type: "string" },
927
+ type: {
928
+ type: "string",
929
+ enum: ["feature", "fix", "chore", "refactor", "docs"]
930
+ }
931
+ },
932
+ required: ["cardId"]
933
+ }
934
+ },
935
+ {
936
+ name: "search_cards",
937
+ description: "Search cards, projects and boards (default limit:20). Use compact:true for minimal fields",
938
+ inputSchema: {
939
+ type: "object",
940
+ properties: {
941
+ query: { type: "string" },
942
+ projectId: { type: "string" },
943
+ boardId: { type: "string" },
944
+ columnId: { type: "string" },
945
+ epicId: { type: "string" },
946
+ featureId: { type: "string" },
947
+ hasEpic: { type: "boolean" },
948
+ status: { type: "string", enum: ["todo", "in_progress", "done"] },
949
+ tagIds: { type: "array", items: { type: "string" } },
950
+ limit: { type: "number" },
951
+ compact: { type: "boolean" }
952
+ },
953
+ required: ["query"]
954
+ }
955
+ },
956
+ // BULK OPERATIONS
957
+ {
958
+ name: "bulk_create_cards",
959
+ description: "Create multiple cards in 1 call",
960
+ inputSchema: {
961
+ type: "object",
962
+ properties: {
963
+ columnId: { type: "string" },
964
+ cards: {
965
+ type: "array",
966
+ items: {
967
+ type: "object",
968
+ properties: {
969
+ title: { type: "string" },
970
+ description: { type: "string" },
971
+ priority: { type: "string", enum: ["P1", "P2", "P3"] },
972
+ epicId: { type: "string" }
973
+ },
974
+ required: ["title"]
975
+ }
976
+ }
977
+ },
978
+ required: ["columnId", "cards"]
979
+ }
980
+ },
981
+ {
982
+ name: "bulk_create_epic_with_cards",
983
+ description: "Create epic + all its cards in 1 call",
984
+ inputSchema: {
985
+ type: "object",
986
+ properties: {
987
+ epic: {
988
+ type: "object",
989
+ properties: {
990
+ slug: { type: "string" },
991
+ name: { type: "string" },
992
+ description: { type: "string" },
993
+ emoji: { type: "string" },
994
+ color: { type: "string" }
995
+ },
996
+ required: ["slug", "name"]
997
+ },
998
+ columnId: { type: "string" },
999
+ cards: {
1000
+ type: "array",
1001
+ items: {
1002
+ type: "object",
1003
+ properties: {
1004
+ title: { type: "string" },
1005
+ description: { type: "string" },
1006
+ priority: { type: "string", enum: ["P1", "P2", "P3"] }
1007
+ },
1008
+ required: ["title"]
1009
+ }
1010
+ }
1011
+ },
1012
+ required: ["epic", "columnId", "cards"]
1013
+ }
1014
+ },
1015
+ {
1016
+ name: "bulk_create_epic_with_features",
1017
+ description: "Create epic + features + cards across projects in 1 call. Cards auto-prefixed with SLUG{N}-.",
1018
+ inputSchema: {
1019
+ type: "object",
1020
+ properties: {
1021
+ epic: {
1022
+ type: "object",
1023
+ properties: {
1024
+ slug: { type: "string" },
1025
+ name: { type: "string" },
1026
+ description: { type: "string" },
1027
+ emoji: { type: "string" },
1028
+ color: { type: "string" }
1029
+ },
1030
+ required: ["slug", "name"]
1031
+ },
1032
+ features: {
1033
+ type: "array",
1034
+ items: {
1035
+ type: "object",
1036
+ properties: {
1037
+ title: { type: "string" },
1038
+ slug: { type: "string", description: "UPPERCASE slug (auto-generated from title if omitted)" },
1039
+ description: { type: "string" },
1040
+ cards: {
1041
+ type: "array",
1042
+ items: {
1043
+ type: "object",
1044
+ properties: {
1045
+ columnId: { type: "string" },
1046
+ title: { type: "string" },
1047
+ description: { type: "string" },
1048
+ priority: { type: "string", enum: ["P1", "P2", "P3"] }
1049
+ },
1050
+ required: ["columnId", "title"]
1051
+ }
1052
+ }
1053
+ },
1054
+ required: ["title", "cards"]
1055
+ }
1056
+ }
1057
+ },
1058
+ required: ["epic", "features"]
1059
+ }
1060
+ },
1061
+ {
1062
+ name: "bulk_move_cards",
1063
+ description: "Move multiple cards to column in 1 call",
1064
+ inputSchema: {
1065
+ type: "object",
1066
+ properties: {
1067
+ cardIds: { type: "array", items: { type: "string" } },
1068
+ targetColumnId: { type: "string" }
1069
+ },
1070
+ required: ["cardIds", "targetColumnId"]
1071
+ }
1072
+ },
1073
+ {
1074
+ name: "quick_add_cards",
1075
+ description: 'Create cards from multiline text. Format: "- P1: task title" per line',
1076
+ inputSchema: {
1077
+ type: "object",
1078
+ properties: {
1079
+ columnId: { type: "string" },
1080
+ text: {
1081
+ type: "string",
1082
+ description: "Multiline text, 1 card per line"
1083
+ },
1084
+ defaultPriority: { type: "string", enum: ["P1", "P2", "P3"] }
1085
+ },
1086
+ required: ["columnId", "text"]
1087
+ }
1088
+ },
1089
+ {
1090
+ name: "move_cards_by_column",
1091
+ description: "Move ALL cards from one column to another",
1092
+ inputSchema: {
1093
+ type: "object",
1094
+ properties: {
1095
+ sourceColumnId: { type: "string" },
1096
+ targetColumnId: { type: "string" },
1097
+ limit: { type: "number" }
1098
+ },
1099
+ required: ["sourceColumnId", "targetColumnId"]
1100
+ }
1101
+ },
1102
+ // AGGREGATED VIEWS
1103
+ {
1104
+ name: "get_workspace",
1105
+ description: "Get project + all boards + columns in 1 call (no cards)",
1106
+ inputSchema: {
1107
+ type: "object",
1108
+ properties: { projectId: { type: "string" } },
1109
+ required: ["projectId"]
1110
+ }
1111
+ },
1112
+ {
1113
+ name: "get_board_summary",
1114
+ description: "Get board stats only: card counts per column + priority breakdown",
1115
+ inputSchema: {
1116
+ type: "object",
1117
+ properties: { boardId: { type: "string" } },
1118
+ required: ["boardId"]
1119
+ }
1120
+ },
1121
+ {
1122
+ name: "get_epic_summary",
1123
+ description: "Get epic with minimal card info: {id,title,priority,status} + progress stats",
1124
+ inputSchema: {
1125
+ type: "object",
1126
+ properties: { epicId: { type: "string" } },
1127
+ required: ["epicId"]
1128
+ }
1129
+ },
309
1130
  // TAGS
310
- { name: "list_tags", description: "List all tags", inputSchema: { type: "object", properties: {} } },
311
- { name: "create_tag", description: "Create tag", inputSchema: { type: "object", properties: { name: { type: "string" }, color: { type: "string" } }, required: ["name", "color"] } },
312
- { name: "delete_tag", description: "Delete tag", inputSchema: { type: "object", properties: { tagId: { type: "string" } }, required: ["tagId"] } },
313
- { name: "add_tag_to_card", description: "Add tag to card", inputSchema: { type: "object", properties: { cardId: { type: "string" }, tagId: { type: "string" } }, required: ["cardId", "tagId"] } },
314
- { name: "remove_tag_from_card", description: "Remove tag from card", inputSchema: { type: "object", properties: { cardId: { type: "string" }, tagId: { type: "string" } }, required: ["cardId", "tagId"] } },
315
- // EPICS (use get_epic_summary for optimized epic+cards view)
316
- { name: "list_epics", description: "List epics (default limit:15)", inputSchema: { type: "object", properties: { status: { type: "string" }, includeProgress: { type: "boolean" }, limit: { type: "number" }, compact: { type: "boolean" } } } },
317
- { name: "create_epic", description: "Create epic", inputSchema: { type: "object", properties: { slug: { type: "string" }, name: { type: "string" }, description: { type: "string" }, emoji: { type: "string" }, color: { type: "string" }, startDate: { type: "string" }, targetDate: { type: "string" } }, required: ["slug", "name"] } },
318
- { name: "update_epic", description: "Update epic", inputSchema: { type: "object", properties: { epicId: { type: "string" }, slug: { type: "string" }, name: { type: "string" }, description: { type: "string" }, emoji: { type: "string" }, color: { type: "string" }, status: { type: "string" }, startDate: { type: "string" }, targetDate: { type: "string" } }, required: ["epicId"] } },
319
- { name: "delete_epic", description: "Delete epic (cards unlinked)", inputSchema: { type: "object", properties: { epicId: { type: "string" } }, required: ["epicId"] } },
320
- { name: "add_card_to_epic", description: "Add card to epic", inputSchema: { type: "object", properties: { epicId: { type: "string" }, cardId: { type: "string" } }, required: ["epicId", "cardId"] } },
321
- { name: "remove_card_from_epic", description: "Remove card from epic", inputSchema: { type: "object", properties: { epicId: { type: "string" }, cardId: { type: "string" } }, required: ["epicId", "cardId"] } },
322
- { name: "get_epic_timeline", description: "Timeline of all epics", inputSchema: { type: "object", properties: {} } },
1131
+ {
1132
+ name: "list_tags",
1133
+ description: "List all tags",
1134
+ inputSchema: { type: "object", properties: {} }
1135
+ },
1136
+ {
1137
+ name: "create_tag",
1138
+ description: "Create tag",
1139
+ inputSchema: {
1140
+ type: "object",
1141
+ properties: { name: { type: "string" }, color: { type: "string" } },
1142
+ required: ["name", "color"]
1143
+ }
1144
+ },
1145
+ {
1146
+ name: "delete_tag",
1147
+ description: "Delete tag",
1148
+ inputSchema: {
1149
+ type: "object",
1150
+ properties: { tagId: { type: "string" } },
1151
+ required: ["tagId"]
1152
+ }
1153
+ },
1154
+ {
1155
+ name: "add_tag_to_card",
1156
+ description: "Add tag to card",
1157
+ inputSchema: {
1158
+ type: "object",
1159
+ properties: { cardId: { type: "string" }, tagId: { type: "string" } },
1160
+ required: ["cardId", "tagId"]
1161
+ }
1162
+ },
1163
+ {
1164
+ name: "remove_tag_from_card",
1165
+ description: "Remove tag from card",
1166
+ inputSchema: {
1167
+ type: "object",
1168
+ properties: { cardId: { type: "string" }, tagId: { type: "string" } },
1169
+ required: ["cardId", "tagId"]
1170
+ }
1171
+ },
1172
+ // EPICS
1173
+ {
1174
+ name: "list_epics",
1175
+ description: "List epics (default limit:15)",
1176
+ inputSchema: {
1177
+ type: "object",
1178
+ properties: {
1179
+ status: { type: "string" },
1180
+ includeProgress: { type: "boolean" },
1181
+ limit: { type: "number" },
1182
+ compact: { type: "boolean" }
1183
+ }
1184
+ }
1185
+ },
1186
+ {
1187
+ name: "create_epic",
1188
+ description: "Create epic",
1189
+ inputSchema: {
1190
+ type: "object",
1191
+ properties: {
1192
+ slug: { type: "string" },
1193
+ name: { type: "string" },
1194
+ description: { type: "string" },
1195
+ emoji: { type: "string" },
1196
+ color: { type: "string" },
1197
+ startDate: { type: "string" },
1198
+ targetDate: { type: "string" }
1199
+ },
1200
+ required: ["slug", "name"]
1201
+ }
1202
+ },
1203
+ {
1204
+ name: "get_epic",
1205
+ description: "Get an epic with all its cards, features and progress",
1206
+ inputSchema: {
1207
+ type: "object",
1208
+ properties: { epicId: { type: "string" } },
1209
+ required: ["epicId"]
1210
+ }
1211
+ },
1212
+ {
1213
+ name: "update_epic",
1214
+ description: "Update epic. Use syncDates:true to sync targetDate to all card due dates.",
1215
+ inputSchema: {
1216
+ type: "object",
1217
+ properties: {
1218
+ epicId: { type: "string" },
1219
+ slug: { type: "string" },
1220
+ name: { type: "string" },
1221
+ description: { type: "string" },
1222
+ emoji: { type: "string" },
1223
+ color: { type: "string" },
1224
+ status: { type: "string" },
1225
+ startDate: { type: "string" },
1226
+ targetDate: { type: "string" },
1227
+ syncDates: { type: "boolean", description: "Sync targetDate to all card due dates" }
1228
+ },
1229
+ required: ["epicId"]
1230
+ }
1231
+ },
1232
+ {
1233
+ name: "delete_epic",
1234
+ description: "Delete epic (cards unlinked)",
1235
+ inputSchema: {
1236
+ type: "object",
1237
+ properties: { epicId: { type: "string" } },
1238
+ required: ["epicId"]
1239
+ }
1240
+ },
1241
+ {
1242
+ name: "add_card_to_epic",
1243
+ description: "Add card to epic",
1244
+ inputSchema: {
1245
+ type: "object",
1246
+ properties: { epicId: { type: "string" }, cardId: { type: "string" } },
1247
+ required: ["epicId", "cardId"]
1248
+ }
1249
+ },
1250
+ {
1251
+ name: "remove_card_from_epic",
1252
+ description: "Remove card from epic",
1253
+ inputSchema: {
1254
+ type: "object",
1255
+ properties: { epicId: { type: "string" }, cardId: { type: "string" } },
1256
+ required: ["epicId", "cardId"]
1257
+ }
1258
+ },
1259
+ // FEATURES
1260
+ {
1261
+ name: "list_features",
1262
+ description: "List features. Filter by epicId or slug.",
1263
+ inputSchema: {
1264
+ type: "object",
1265
+ properties: {
1266
+ epicId: { type: "string" },
1267
+ slug: { type: "string", description: "Filter by feature slug (UPPERCASE)" }
1268
+ }
1269
+ }
1270
+ },
1271
+ {
1272
+ name: "get_feature",
1273
+ description: "Get a feature with cards and progress. Accepts featureId or featureSlug (UPPERCASE).",
1274
+ inputSchema: {
1275
+ type: "object",
1276
+ properties: {
1277
+ featureId: { type: "string", description: "Feature ID or slug" },
1278
+ featureSlug: { type: "string", description: "Feature slug (UPPERCASE), alternative to featureId" }
1279
+ }
1280
+ }
1281
+ },
1282
+ {
1283
+ name: "get_active_features",
1284
+ description: "Get features with cards in progress, organized by epic",
1285
+ inputSchema: { type: "object", properties: {} }
1286
+ },
1287
+ {
1288
+ name: "create_feature",
1289
+ description: "Create a new feature (optionally in an epic)",
1290
+ inputSchema: {
1291
+ type: "object",
1292
+ properties: {
1293
+ epicId: { type: "string" },
1294
+ title: { type: "string" },
1295
+ slug: { type: "string" },
1296
+ description: { type: "string" },
1297
+ status: { type: "string", enum: ["planning", "in_progress", "completed", "on_hold"] }
1298
+ },
1299
+ required: ["title"]
1300
+ }
1301
+ },
1302
+ {
1303
+ name: "update_feature",
1304
+ description: "Update a feature",
1305
+ inputSchema: {
1306
+ type: "object",
1307
+ properties: {
1308
+ featureId: { type: "string" },
1309
+ title: { type: "string" },
1310
+ slug: { type: "string" },
1311
+ description: { type: "string" },
1312
+ status: { type: "string", enum: ["planning", "in_progress", "completed", "on_hold"] },
1313
+ order: { type: "number" },
1314
+ epicId: { type: "string", description: "Move to another epic" }
1315
+ },
1316
+ required: ["featureId"]
1317
+ }
1318
+ },
1319
+ {
1320
+ name: "delete_feature",
1321
+ description: "Delete a feature (cards unlinked)",
1322
+ inputSchema: {
1323
+ type: "object",
1324
+ properties: { featureId: { type: "string" } },
1325
+ required: ["featureId"]
1326
+ }
1327
+ },
1328
+ {
1329
+ name: "add_card_to_feature",
1330
+ description: "Add a card to a feature. Accepts featureId or featureSlug.",
1331
+ inputSchema: {
1332
+ type: "object",
1333
+ properties: {
1334
+ cardId: { type: "string" },
1335
+ featureId: { type: "string", description: "Feature ID or slug" },
1336
+ featureSlug: { type: "string", description: "Feature slug (UPPERCASE), alternative to featureId" }
1337
+ },
1338
+ required: ["cardId"]
1339
+ }
1340
+ },
1341
+ {
1342
+ name: "remove_card_from_feature",
1343
+ description: "Remove a card from a feature. Accepts featureId or featureSlug.",
1344
+ inputSchema: {
1345
+ type: "object",
1346
+ properties: {
1347
+ cardId: { type: "string" },
1348
+ featureId: { type: "string", description: "Feature ID or slug" },
1349
+ featureSlug: { type: "string", description: "Feature slug (UPPERCASE), alternative to featureId" }
1350
+ },
1351
+ required: ["cardId"]
1352
+ }
1353
+ },
1354
+ {
1355
+ name: "get_feature_cards",
1356
+ description: "Get all cards in a feature. Accepts featureId or featureSlug.",
1357
+ inputSchema: {
1358
+ type: "object",
1359
+ properties: {
1360
+ featureId: { type: "string", description: "Feature ID or slug" },
1361
+ featureSlug: { type: "string", description: "Feature slug (UPPERCASE), alternative to featureId" }
1362
+ }
1363
+ }
1364
+ },
323
1365
  // CARD LINKS
324
- { name: "link_cards", description: "Link two cards", inputSchema: { type: "object", properties: { cardId1: { type: "string" }, cardId2: { type: "string" }, label: { type: "string" } }, required: ["cardId1", "cardId2"] } },
325
- { name: "unlink_cards", description: "Unlink two cards", inputSchema: { type: "object", properties: { cardId1: { type: "string" }, cardId2: { type: "string" } }, required: ["cardId1", "cardId2"] } },
326
- { name: "get_linked_cards", description: "Get linked cards", inputSchema: { type: "object", properties: { cardId: { type: "string" } }, required: ["cardId"] } },
1366
+ {
1367
+ name: "link_cards",
1368
+ description: "Link two cards",
1369
+ inputSchema: {
1370
+ type: "object",
1371
+ properties: {
1372
+ cardId1: { type: "string" },
1373
+ cardId2: { type: "string" },
1374
+ label: { type: "string" }
1375
+ },
1376
+ required: ["cardId1", "cardId2"]
1377
+ }
1378
+ },
1379
+ {
1380
+ name: "unlink_cards",
1381
+ description: "Unlink two cards by link ID",
1382
+ inputSchema: {
1383
+ type: "object",
1384
+ properties: {
1385
+ linkId: { type: "string" }
1386
+ },
1387
+ required: ["linkId"]
1388
+ }
1389
+ },
1390
+ {
1391
+ name: "get_linked_cards",
1392
+ description: "Get linked cards",
1393
+ inputSchema: {
1394
+ type: "object",
1395
+ properties: { cardId: { type: "string" } },
1396
+ required: ["cardId"]
1397
+ }
1398
+ },
327
1399
  // GITHUB INTEGRATION
328
- { name: "setup_github_integration", description: "Setup GitHub webhook", inputSchema: { type: "object", properties: { projectId: { type: "string" }, repoOwner: { type: "string" }, repoName: { type: "string" }, inProgressColumnName: { type: "string" }, doneColumnName: { type: "string" } }, required: ["projectId", "repoOwner", "repoName"] } },
329
- { name: "get_github_integration", description: "Get GitHub integration", inputSchema: { type: "object", properties: { projectId: { type: "string" } }, required: ["projectId"] } },
330
- { name: "update_github_integration", description: "Update GitHub integration", inputSchema: { type: "object", properties: { projectId: { type: "string" }, autoMoveOnPush: { type: "boolean" }, autoMoveOnPrMerge: { type: "boolean" }, autoLinkPr: { type: "boolean" }, inProgressColumnName: { type: "string" }, doneColumnName: { type: "string" } }, required: ["projectId"] } },
331
- { name: "remove_github_integration", description: "Remove GitHub integration", inputSchema: { type: "object", properties: { projectId: { type: "string" } }, required: ["projectId"] } },
332
- { name: "link_card_to_branch", description: "Link card to branch", inputSchema: { type: "object", properties: { cardId: { type: "string" }, branch: { type: "string" } }, required: ["cardId", "branch"] } },
333
- { name: "link_card_to_pr", description: "Link card to PR", inputSchema: { type: "object", properties: { cardId: { type: "string" }, prUrl: { type: "string" } }, required: ["cardId", "prUrl"] } },
1400
+ {
1401
+ name: "setup_github_integration",
1402
+ description: "Setup GitHub integration for a project (auto-creates webhook)",
1403
+ inputSchema: {
1404
+ type: "object",
1405
+ properties: {
1406
+ projectId: { type: "string" },
1407
+ repoOwner: { type: "string" },
1408
+ repoName: { type: "string" },
1409
+ inProgressColumnName: { type: "string" },
1410
+ doneColumnName: { type: "string" },
1411
+ autoMoveOnPush: { type: "boolean" },
1412
+ autoMoveOnPrMerge: { type: "boolean" },
1413
+ autoLinkPr: { type: "boolean" }
1414
+ },
1415
+ required: ["projectId", "repoOwner", "repoName"]
1416
+ }
1417
+ },
1418
+ {
1419
+ name: "get_github_integration",
1420
+ description: "Get GitHub integration settings",
1421
+ inputSchema: {
1422
+ type: "object",
1423
+ properties: { projectId: { type: "string" } },
1424
+ required: ["projectId"]
1425
+ }
1426
+ },
1427
+ {
1428
+ name: "update_github_integration",
1429
+ description: "Update GitHub integration settings",
1430
+ inputSchema: {
1431
+ type: "object",
1432
+ properties: {
1433
+ projectId: { type: "string" },
1434
+ repoOwner: { type: "string" },
1435
+ repoName: { type: "string" },
1436
+ autoMoveOnPush: { type: "boolean" },
1437
+ autoMoveOnPrMerge: { type: "boolean" },
1438
+ autoLinkPr: { type: "boolean" },
1439
+ inProgressColumnName: { type: "string" },
1440
+ doneColumnName: { type: "string" }
1441
+ },
1442
+ required: ["projectId"]
1443
+ }
1444
+ },
1445
+ {
1446
+ name: "remove_github_integration",
1447
+ description: "Remove GitHub integration",
1448
+ inputSchema: {
1449
+ type: "object",
1450
+ properties: { projectId: { type: "string" } },
1451
+ required: ["projectId"]
1452
+ }
1453
+ },
1454
+ {
1455
+ name: "link_card_to_branch",
1456
+ description: "Link card to branch",
1457
+ inputSchema: {
1458
+ type: "object",
1459
+ properties: { cardId: { type: "string" }, branch: { type: "string" } },
1460
+ required: ["cardId", "branch"]
1461
+ }
1462
+ },
1463
+ {
1464
+ name: "link_card_to_pr",
1465
+ description: "Link card to PR",
1466
+ inputSchema: {
1467
+ type: "object",
1468
+ properties: { cardId: { type: "string" }, prUrl: { type: "string" } },
1469
+ required: ["cardId", "prUrl"]
1470
+ }
1471
+ },
334
1472
  // GITHUB API
335
- { name: "github_list_repos", description: "List user repos", inputSchema: { type: "object", properties: { userId: { type: "string" }, type: { type: "string", enum: ["all", "owner", "member"] } }, required: ["userId"] } },
336
- { name: "github_create_branch", description: "Create branch", inputSchema: { type: "object", properties: { userId: { type: "string" }, owner: { type: "string" }, repo: { type: "string" }, branchName: { type: "string" }, sourceBranch: { type: "string" } }, required: ["userId", "owner", "repo", "branchName"] } },
337
- { name: "github_create_pr", description: "Create PR", inputSchema: { type: "object", properties: { userId: { type: "string" }, owner: { type: "string" }, repo: { type: "string" }, title: { type: "string" }, head: { type: "string" }, base: { type: "string" }, body: { type: "string" } }, required: ["userId", "owner", "repo", "title", "head"] } },
338
- { name: "github_auto_setup_webhook", description: "Auto-setup webhook", inputSchema: { type: "object", properties: { userId: { type: "string" }, projectId: { type: "string" }, owner: { type: "string" }, repo: { type: "string" } }, required: ["userId", "projectId", "owner", "repo"] } }
1473
+ {
1474
+ name: "github_list_repos",
1475
+ description: "List user repos",
1476
+ inputSchema: {
1477
+ type: "object",
1478
+ properties: {
1479
+ userId: { type: "string" },
1480
+ type: { type: "string", enum: ["all", "owner", "member"] }
1481
+ },
1482
+ required: ["userId"]
1483
+ }
1484
+ },
1485
+ {
1486
+ name: "github_create_branch",
1487
+ description: "Create branch",
1488
+ inputSchema: {
1489
+ type: "object",
1490
+ properties: {
1491
+ userId: { type: "string" },
1492
+ owner: { type: "string" },
1493
+ repo: { type: "string" },
1494
+ branchName: { type: "string" },
1495
+ sourceBranch: { type: "string" }
1496
+ },
1497
+ required: ["userId", "owner", "repo", "branchName"]
1498
+ }
1499
+ },
1500
+ {
1501
+ name: "github_create_pr",
1502
+ description: "Create PR",
1503
+ inputSchema: {
1504
+ type: "object",
1505
+ properties: {
1506
+ userId: { type: "string" },
1507
+ owner: { type: "string" },
1508
+ repo: { type: "string" },
1509
+ title: { type: "string" },
1510
+ head: { type: "string" },
1511
+ base: { type: "string" },
1512
+ body: { type: "string" }
1513
+ },
1514
+ required: ["userId", "owner", "repo", "title", "head"]
1515
+ }
1516
+ },
1517
+ // IDEAS
1518
+ {
1519
+ name: "list_ideas",
1520
+ description: "List ideas (canvas notes). Filter by status: active, archived, all",
1521
+ inputSchema: {
1522
+ type: "object",
1523
+ properties: {
1524
+ status: { type: "string", enum: ["active", "archived", "all"] },
1525
+ filter: { type: "string", enum: ["week"], description: "Filter by recent (week)" }
1526
+ }
1527
+ }
1528
+ },
1529
+ {
1530
+ name: "get_idea",
1531
+ description: "Get an idea with its tags",
1532
+ inputSchema: {
1533
+ type: "object",
1534
+ properties: { ideaId: { type: "string" } },
1535
+ required: ["ideaId"]
1536
+ }
1537
+ },
1538
+ {
1539
+ name: "create_idea",
1540
+ description: "Create a new idea (canvas note)",
1541
+ inputSchema: {
1542
+ type: "object",
1543
+ properties: {
1544
+ title: { type: "string" },
1545
+ description: { type: "string" },
1546
+ color: { type: "string" },
1547
+ posX: { type: "number" },
1548
+ posY: { type: "number" },
1549
+ tagIds: { type: "array", items: { type: "string" } }
1550
+ },
1551
+ required: ["title"]
1552
+ }
1553
+ },
1554
+ {
1555
+ name: "update_idea",
1556
+ description: "Update an idea",
1557
+ inputSchema: {
1558
+ type: "object",
1559
+ properties: {
1560
+ ideaId: { type: "string" },
1561
+ title: { type: "string" },
1562
+ description: { type: "string" },
1563
+ status: { type: "string", enum: ["active", "archived"] },
1564
+ color: { type: "string" },
1565
+ posX: { type: "number" },
1566
+ posY: { type: "number" },
1567
+ tagIds: { type: "array", items: { type: "string" } }
1568
+ },
1569
+ required: ["ideaId"]
1570
+ }
1571
+ },
1572
+ {
1573
+ name: "delete_idea",
1574
+ description: "Delete an idea",
1575
+ inputSchema: {
1576
+ type: "object",
1577
+ properties: { ideaId: { type: "string" } },
1578
+ required: ["ideaId"]
1579
+ }
1580
+ },
1581
+ {
1582
+ name: "convert_idea_to_card",
1583
+ description: "Convert an idea to a card in a specific board/column",
1584
+ inputSchema: {
1585
+ type: "object",
1586
+ properties: {
1587
+ ideaId: { type: "string" },
1588
+ boardId: { type: "string" },
1589
+ columnId: { type: "string" }
1590
+ },
1591
+ required: ["ideaId", "boardId", "columnId"]
1592
+ }
1593
+ },
1594
+ // TIME TRACKING
1595
+ {
1596
+ name: "get_time_tracking",
1597
+ description: "Get time tracking sessions with project breakdown",
1598
+ inputSchema: {
1599
+ type: "object",
1600
+ properties: {
1601
+ startDate: { type: "string", description: "ISO date (default: 7 days ago)" },
1602
+ endDate: { type: "string", description: "ISO date (default: now)" },
1603
+ projectId: { type: "string" }
1604
+ }
1605
+ }
1606
+ },
1607
+ {
1608
+ name: "log_activity",
1609
+ description: "Log activity to create/update time session",
1610
+ inputSchema: {
1611
+ type: "object",
1612
+ properties: {
1613
+ projectId: { type: "string" },
1614
+ cardId: { type: "string" },
1615
+ activityType: { type: "string" }
1616
+ }
1617
+ }
1618
+ },
1619
+ {
1620
+ name: "end_time_session",
1621
+ description: "End the current active time tracking session",
1622
+ inputSchema: { type: "object", properties: {} }
1623
+ },
1624
+ // DAILY SUMMARY
1625
+ {
1626
+ name: "get_daily_summary",
1627
+ description: "Get daily report: working on, blocked, completed today, weekly stats",
1628
+ inputSchema: { type: "object", properties: {} }
1629
+ },
1630
+ // RETROSPECTIVE
1631
+ {
1632
+ name: "get_retrospective",
1633
+ description: "Get retrospective data: completed, created, stale, blocked cards + movements",
1634
+ inputSchema: {
1635
+ type: "object",
1636
+ properties: {
1637
+ days: { type: "number", description: "Period in days (default: 7)" }
1638
+ }
1639
+ }
1640
+ },
1641
+ // EXPORT
1642
+ {
1643
+ name: "export_board",
1644
+ description: "Export a board as JSON (columns, cards, tags, comments)",
1645
+ inputSchema: {
1646
+ type: "object",
1647
+ properties: { boardId: { type: "string" } },
1648
+ required: ["boardId"]
1649
+ }
1650
+ },
1651
+ {
1652
+ name: "export_project",
1653
+ description: "Export a project as JSON (boards, columns, cards)",
1654
+ inputSchema: {
1655
+ type: "object",
1656
+ properties: { projectId: { type: "string" } },
1657
+ required: ["projectId"]
1658
+ }
1659
+ }
339
1660
  ]
340
1661
  }));
341
1662
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
@@ -357,7 +1678,16 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
357
1678
  result = await kanbanApi.deleteFolder(args.folderId);
358
1679
  break;
359
1680
  case "move_project_to_folder":
360
- result = await kanbanApi.moveProjectToFolder(args.projectId, args.folderId);
1681
+ result = await kanbanApi.moveProjectToFolder(
1682
+ args.projectId,
1683
+ args.folderId
1684
+ );
1685
+ break;
1686
+ case "reorder_folders":
1687
+ result = await kanbanApi.reorderFolders(
1688
+ args.folderId,
1689
+ args.targetFolderId
1690
+ );
361
1691
  break;
362
1692
  // PROJECTS
363
1693
  case "list_projects":
@@ -375,7 +1705,17 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
375
1705
  case "delete_project":
376
1706
  result = await kanbanApi.deleteProject(args.projectId);
377
1707
  break;
1708
+ case "reorder_projects":
1709
+ result = await kanbanApi.reorderProjects(
1710
+ args.projectId,
1711
+ args.targetProjectId,
1712
+ args.folderId
1713
+ );
1714
+ break;
378
1715
  // BOARDS
1716
+ case "list_boards":
1717
+ result = await kanbanApi.listBoards(args);
1718
+ break;
379
1719
  case "create_board":
380
1720
  result = await kanbanApi.createBoard(args);
381
1721
  break;
@@ -398,7 +1738,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
398
1738
  case "delete_column":
399
1739
  result = await kanbanApi.deleteColumn(args.columnId);
400
1740
  break;
1741
+ case "reorder_columns":
1742
+ result = await kanbanApi.reorderColumns(args.columns);
1743
+ break;
401
1744
  // CARDS
1745
+ case "get_card":
1746
+ result = await kanbanApi.getCard(args.cardId);
1747
+ break;
402
1748
  case "create_card":
403
1749
  result = await kanbanApi.createCard(args);
404
1750
  break;
@@ -409,32 +1755,58 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
409
1755
  result = await kanbanApi.deleteCard(args.cardId);
410
1756
  break;
411
1757
  case "move_card":
412
- result = await kanbanApi.moveCard(args.cardId, args.targetColumnId);
1758
+ result = await kanbanApi.moveCard(args.cardId, args.targetColumnId, args.newOrder);
1759
+ break;
1760
+ case "archive_card":
1761
+ result = await kanbanApi.archiveCard(args.cardId);
1762
+ break;
1763
+ case "unarchive_card":
1764
+ result = await kanbanApi.unarchiveCard(args.cardId);
1765
+ break;
1766
+ case "list_archived_cards":
1767
+ result = await kanbanApi.listArchivedCards(args.boardId);
413
1768
  break;
414
1769
  case "add_comment":
415
1770
  result = await kanbanApi.addComment(args.cardId, args.content);
416
1771
  break;
1772
+ case "delete_comment":
1773
+ result = await kanbanApi.deleteComment(args.commentId);
1774
+ break;
417
1775
  // CHECKLISTS
418
1776
  case "create_checklist":
419
- result = await kanbanApi.createChecklist({ cardId: args.cardId, title: args.title });
1777
+ result = await kanbanApi.createChecklist({
1778
+ cardId: args.cardId,
1779
+ title: args.title
1780
+ });
420
1781
  break;
421
1782
  case "update_checklist":
422
- result = await kanbanApi.updateChecklist(args.checklistId, { title: args.title });
1783
+ result = await kanbanApi.updateChecklist(args.checklistId, {
1784
+ title: args.title
1785
+ });
423
1786
  break;
424
1787
  case "delete_checklist":
425
1788
  result = await kanbanApi.deleteChecklist(args.checklistId);
426
1789
  break;
427
1790
  case "create_checklist_item":
428
- result = await kanbanApi.createChecklistItem({ checklistId: args.checklistId, content: args.content });
1791
+ result = await kanbanApi.createChecklistItem({
1792
+ checklistId: args.checklistId,
1793
+ content: args.content
1794
+ });
429
1795
  break;
430
1796
  case "update_checklist_item":
431
- result = await kanbanApi.updateChecklistItem(args.itemId, { content: args.content, completed: args.completed });
1797
+ result = await kanbanApi.updateChecklistItem(args.itemId, {
1798
+ content: args.content,
1799
+ completed: args.completed
1800
+ });
432
1801
  break;
433
1802
  case "delete_checklist_item":
434
1803
  result = await kanbanApi.deleteChecklistItem(args.itemId);
435
1804
  break;
436
1805
  case "get_branch_name":
437
- result = await kanbanApi.getBranchName(args.cardId, args.type || "feature");
1806
+ result = await kanbanApi.getBranchName(
1807
+ args.cardId,
1808
+ args.type || "feature"
1809
+ );
438
1810
  break;
439
1811
  case "search_cards":
440
1812
  result = await kanbanApi.searchCards(args);
@@ -446,6 +1818,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
446
1818
  case "bulk_create_epic_with_cards":
447
1819
  result = await kanbanApi.bulkCreateEpicWithCards(args);
448
1820
  break;
1821
+ case "bulk_create_epic_with_features":
1822
+ result = await kanbanApi.bulkCreateEpicWithFeatures(args);
1823
+ break;
449
1824
  case "bulk_move_cards":
450
1825
  result = await kanbanApi.bulkMoveCards(args);
451
1826
  break;
@@ -488,6 +1863,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
488
1863
  case "create_epic":
489
1864
  result = await kanbanApi.createEpic(args);
490
1865
  break;
1866
+ case "get_epic":
1867
+ result = await kanbanApi.getEpic(args.epicId);
1868
+ break;
491
1869
  case "update_epic":
492
1870
  result = await kanbanApi.updateEpic(args.epicId, args);
493
1871
  break;
@@ -500,15 +1878,71 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
500
1878
  case "remove_card_from_epic":
501
1879
  result = await kanbanApi.removeCardFromEpic(args.epicId, args.cardId);
502
1880
  break;
503
- case "get_epic_timeline":
504
- result = await kanbanApi.getEpicTimeline();
1881
+ // FEATURES
1882
+ case "list_features": {
1883
+ const features = await kanbanApi.listFeatures(args.epicId);
1884
+ const slugFilter = args.slug;
1885
+ result = slugFilter ? (Array.isArray(features) ? features : []).filter((f) => f.slug === slugFilter.toUpperCase()) : features;
1886
+ break;
1887
+ }
1888
+ case "get_feature": {
1889
+ const fId = args.featureId || args.featureSlug;
1890
+ if (!fId) throw new Error("Either featureId or featureSlug is required");
1891
+ result = await kanbanApi.getFeature(fId);
1892
+ break;
1893
+ }
1894
+ case "get_active_features":
1895
+ result = await kanbanApi.getActiveFeatures();
1896
+ break;
1897
+ case "create_feature":
1898
+ result = await kanbanApi.createFeature(args);
1899
+ break;
1900
+ case "update_feature":
1901
+ result = await kanbanApi.updateFeature(args.featureId, args);
505
1902
  break;
1903
+ case "delete_feature":
1904
+ result = await kanbanApi.deleteFeature(args.featureId);
1905
+ break;
1906
+ case "add_card_to_feature": {
1907
+ let addFeatureId = args.featureId || args.featureSlug;
1908
+ if (!addFeatureId) throw new Error("Either featureId or featureSlug is required");
1909
+ if (args.featureSlug && !args.featureId) {
1910
+ const resolved = await kanbanApi.getFeature(addFeatureId);
1911
+ addFeatureId = resolved.id;
1912
+ }
1913
+ result = await kanbanApi.addCardToFeature(addFeatureId, args.cardId);
1914
+ break;
1915
+ }
1916
+ case "remove_card_from_feature": {
1917
+ let removeFeatureId = args.featureId || args.featureSlug;
1918
+ if (!removeFeatureId) throw new Error("Either featureId or featureSlug is required");
1919
+ if (args.featureSlug && !args.featureId) {
1920
+ const resolved = await kanbanApi.getFeature(removeFeatureId);
1921
+ removeFeatureId = resolved.id;
1922
+ }
1923
+ result = await kanbanApi.removeCardFromFeature(removeFeatureId, args.cardId);
1924
+ break;
1925
+ }
1926
+ case "get_feature_cards": {
1927
+ let cardsFeatureId = args.featureId || args.featureSlug;
1928
+ if (!cardsFeatureId) throw new Error("Either featureId or featureSlug is required");
1929
+ if (args.featureSlug && !args.featureId) {
1930
+ const resolved = await kanbanApi.getFeature(cardsFeatureId);
1931
+ cardsFeatureId = resolved.id;
1932
+ }
1933
+ result = await kanbanApi.getFeatureCards(cardsFeatureId);
1934
+ break;
1935
+ }
506
1936
  // CARD LINKS
507
1937
  case "link_cards":
508
- result = await kanbanApi.linkCards(args.cardId1, args.cardId2, args.label);
1938
+ result = await kanbanApi.linkCards(
1939
+ args.cardId1,
1940
+ args.cardId2,
1941
+ args.label
1942
+ );
509
1943
  break;
510
1944
  case "unlink_cards":
511
- result = await kanbanApi.unlinkCards(args.cardId1, args.cardId2);
1945
+ result = await kanbanApi.unlinkCards(args.linkId);
512
1946
  break;
513
1947
  case "get_linked_cards":
514
1948
  result = await kanbanApi.getLinkedCards(args.cardId);
@@ -542,17 +1976,63 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
542
1976
  case "github_create_pr":
543
1977
  result = await kanbanApi.githubCreatePr(args);
544
1978
  break;
545
- case "github_auto_setup_webhook":
546
- result = await kanbanApi.githubAutoSetupWebhook(args);
1979
+ // IDEAS
1980
+ case "list_ideas":
1981
+ result = await kanbanApi.listIdeas(args);
1982
+ break;
1983
+ case "get_idea":
1984
+ result = await kanbanApi.getIdea(args.ideaId);
1985
+ break;
1986
+ case "create_idea":
1987
+ result = await kanbanApi.createIdea(args);
1988
+ break;
1989
+ case "update_idea":
1990
+ result = await kanbanApi.updateIdea(args.ideaId, args);
1991
+ break;
1992
+ case "delete_idea":
1993
+ result = await kanbanApi.deleteIdea(args.ideaId);
1994
+ break;
1995
+ case "convert_idea_to_card":
1996
+ result = await kanbanApi.convertIdeaToCard(args.ideaId, {
1997
+ boardId: args.boardId,
1998
+ columnId: args.columnId
1999
+ });
2000
+ break;
2001
+ // TIME TRACKING
2002
+ case "get_time_tracking":
2003
+ result = await kanbanApi.getTimeTracking(args);
2004
+ break;
2005
+ case "log_activity":
2006
+ result = await kanbanApi.logActivity(args);
2007
+ break;
2008
+ case "end_time_session":
2009
+ result = await kanbanApi.endTimeSession();
2010
+ break;
2011
+ // DAILY SUMMARY
2012
+ case "get_daily_summary":
2013
+ result = await kanbanApi.getDailySummary();
2014
+ break;
2015
+ // RETROSPECTIVE
2016
+ case "get_retrospective":
2017
+ result = await kanbanApi.getRetrospective(args.days);
2018
+ break;
2019
+ // EXPORT
2020
+ case "export_board":
2021
+ result = await kanbanApi.exportBoard(args.boardId);
2022
+ break;
2023
+ case "export_project":
2024
+ result = await kanbanApi.exportProject(args.projectId);
547
2025
  break;
548
2026
  default:
549
2027
  throw new Error(`Unknown tool: ${name}`);
550
2028
  }
551
2029
  return {
552
- content: [{
553
- type: "text",
554
- text: typeof result === "string" ? result : JSON.stringify(result)
555
- }]
2030
+ content: [
2031
+ {
2032
+ type: "text",
2033
+ text: typeof result === "string" ? result : JSON.stringify(result)
2034
+ }
2035
+ ]
556
2036
  };
557
2037
  } catch (error) {
558
2038
  const message = error instanceof Error ? error.message : "Unknown error";