@edicarlos.lds/businessmap-mcp 2.3.0 → 3.0.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.
Files changed (110) hide show
  1. package/README.md +1 -1
  2. package/dist/client/businessmap-client.d.ts +17 -99
  3. package/dist/client/businessmap-client.d.ts.map +1 -1
  4. package/dist/client/businessmap-client.js +27 -263
  5. package/dist/client/businessmap-client.js.map +1 -1
  6. package/dist/client/modules/card-client.d.ts +13 -1
  7. package/dist/client/modules/card-client.d.ts.map +1 -1
  8. package/dist/client/modules/card-client.js +21 -0
  9. package/dist/client/modules/card-client.js.map +1 -1
  10. package/dist/client/modules/custom-field-client.js +1 -1
  11. package/dist/client/modules/custom-field-client.js.map +1 -1
  12. package/dist/client/modules/doc-client.d.ts +44 -0
  13. package/dist/client/modules/doc-client.d.ts.map +1 -0
  14. package/dist/client/modules/doc-client.js +73 -0
  15. package/dist/client/modules/doc-client.js.map +1 -0
  16. package/dist/client/modules/index.d.ts +1 -0
  17. package/dist/client/modules/index.d.ts.map +1 -1
  18. package/dist/client/modules/index.js +1 -0
  19. package/dist/client/modules/index.js.map +1 -1
  20. package/dist/schemas/card-schemas.d.ts +60 -43
  21. package/dist/schemas/card-schemas.d.ts.map +1 -1
  22. package/dist/schemas/card-schemas.js +24 -162
  23. package/dist/schemas/card-schemas.js.map +1 -1
  24. package/dist/schemas/common-schemas.d.ts +6 -0
  25. package/dist/schemas/common-schemas.d.ts.map +1 -1
  26. package/dist/schemas/common-schemas.js +25 -0
  27. package/dist/schemas/common-schemas.js.map +1 -1
  28. package/dist/schemas/doc-schemas.d.ts +176 -0
  29. package/dist/schemas/doc-schemas.d.ts.map +1 -0
  30. package/dist/schemas/doc-schemas.js +141 -0
  31. package/dist/schemas/doc-schemas.js.map +1 -0
  32. package/dist/schemas/index.d.ts +1 -0
  33. package/dist/schemas/index.d.ts.map +1 -1
  34. package/dist/schemas/index.js +1 -0
  35. package/dist/schemas/index.js.map +1 -1
  36. package/dist/schemas/setup-schemas.d.ts +418 -0
  37. package/dist/schemas/setup-schemas.d.ts.map +1 -1
  38. package/dist/schemas/setup-schemas.js +30 -7
  39. package/dist/schemas/setup-schemas.js.map +1 -1
  40. package/dist/schemas/workspace-schemas.d.ts +3 -0
  41. package/dist/schemas/workspace-schemas.d.ts.map +1 -1
  42. package/dist/schemas/workspace-schemas.js +6 -0
  43. package/dist/schemas/workspace-schemas.js.map +1 -1
  44. package/dist/server/mcp-server.d.ts.map +1 -1
  45. package/dist/server/mcp-server.js +2 -1
  46. package/dist/server/mcp-server.js.map +1 -1
  47. package/dist/server/resources/board-resources.js +2 -2
  48. package/dist/server/resources/board-resources.js.map +1 -1
  49. package/dist/server/resources/card-resources.js +2 -2
  50. package/dist/server/resources/card-resources.js.map +1 -1
  51. package/dist/server/resources/workspace-resources.js +1 -1
  52. package/dist/server/resources/workspace-resources.js.map +1 -1
  53. package/dist/server/tools/base-tool.d.ts +34 -0
  54. package/dist/server/tools/base-tool.d.ts.map +1 -1
  55. package/dist/server/tools/base-tool.js +49 -0
  56. package/dist/server/tools/base-tool.js.map +1 -1
  57. package/dist/server/tools/board-tools.d.ts +0 -13
  58. package/dist/server/tools/board-tools.d.ts.map +1 -1
  59. package/dist/server/tools/board-tools.js +165 -257
  60. package/dist/server/tools/board-tools.js.map +1 -1
  61. package/dist/server/tools/card-tools.d.ts +6 -42
  62. package/dist/server/tools/card-tools.d.ts.map +1 -1
  63. package/dist/server/tools/card-tools.js +454 -693
  64. package/dist/server/tools/card-tools.js.map +1 -1
  65. package/dist/server/tools/custom-field-tools.d.ts +1 -2
  66. package/dist/server/tools/custom-field-tools.d.ts.map +1 -1
  67. package/dist/server/tools/custom-field-tools.js +8 -16
  68. package/dist/server/tools/custom-field-tools.js.map +1 -1
  69. package/dist/server/tools/doc-tools.d.ts +14 -0
  70. package/dist/server/tools/doc-tools.d.ts.map +1 -0
  71. package/dist/server/tools/doc-tools.js +280 -0
  72. package/dist/server/tools/doc-tools.js.map +1 -0
  73. package/dist/server/tools/index.d.ts +1 -0
  74. package/dist/server/tools/index.d.ts.map +1 -1
  75. package/dist/server/tools/index.js +1 -0
  76. package/dist/server/tools/index.js.map +1 -1
  77. package/dist/server/tools/setup-tools.d.ts +13 -2
  78. package/dist/server/tools/setup-tools.d.ts.map +1 -1
  79. package/dist/server/tools/setup-tools.js +145 -96
  80. package/dist/server/tools/setup-tools.js.map +1 -1
  81. package/dist/server/tools/user-tools.d.ts +0 -4
  82. package/dist/server/tools/user-tools.d.ts.map +1 -1
  83. package/dist/server/tools/user-tools.js +35 -65
  84. package/dist/server/tools/user-tools.js.map +1 -1
  85. package/dist/server/tools/utility-tools.d.ts +0 -2
  86. package/dist/server/tools/utility-tools.d.ts.map +1 -1
  87. package/dist/server/tools/utility-tools.js +15 -28
  88. package/dist/server/tools/utility-tools.js.map +1 -1
  89. package/dist/server/tools/workflow-tools.d.ts +0 -8
  90. package/dist/server/tools/workflow-tools.d.ts.map +1 -1
  91. package/dist/server/tools/workflow-tools.js +84 -139
  92. package/dist/server/tools/workflow-tools.js.map +1 -1
  93. package/dist/server/tools/workspace-tools.d.ts +0 -4
  94. package/dist/server/tools/workspace-tools.d.ts.map +1 -1
  95. package/dist/server/tools/workspace-tools.js +35 -65
  96. package/dist/server/tools/workspace-tools.js.map +1 -1
  97. package/dist/types/card.d.ts +11 -0
  98. package/dist/types/card.d.ts.map +1 -1
  99. package/dist/types/doc.d.ts +96 -0
  100. package/dist/types/doc.d.ts.map +1 -0
  101. package/dist/types/doc.js +3 -0
  102. package/dist/types/doc.js.map +1 -0
  103. package/dist/types/index.d.ts +1 -0
  104. package/dist/types/index.d.ts.map +1 -1
  105. package/dist/types/index.js +1 -0
  106. package/dist/types/index.js.map +1 -1
  107. package/dist/types/workspace.d.ts +1 -0
  108. package/dist/types/workspace.d.ts.map +1 -1
  109. package/docs/TOOLS.md +29 -6
  110. package/package.json +1 -1
@@ -1,781 +1,542 @@
1
- import { addCardParentSchema, addPredecessorSchema, addStickerToCardSchema, addTagToCardSchema, blockCardSchema, cardCommentsSchema, cardSizeSchema, createCardSchema, createCardSubtaskSchema, createCommentSchema, createTagSchema, deleteCardSchema, deleteCardSubtaskSchema, deleteCommentSchema, getCardBlockedTimesSchema, getCardChildrenSchema, getCardCommentSchema, getCardFlowHistorySchema, getCardHistorySchema, getCardLoggedTimeSchema, getCardLinkedCardsSchema, getCardOutcomesSchema, getCardParentGraphSchema, getCardParentSchema, getCardParentsSchema, getCardSchema, getCardSubtaskSchema, getCardSubtasksSchema, getCardTypesSchema, listCardsSchema, moveCardSchema, removeCardParentSchema, removePredecessorSchema, removeStickerFromCardSchema, removeTagFromCardSchema, searchCardsSchema, unblockCardSchema, updateCardSchema, updateCardSubtaskSchema, updateCommentSchema, } from '../../schemas/index.js';
2
- import { createErrorResponse, createSuccessResponse } from './base-tool.js';
1
+ import { addCardParentSchema, addPredecessorSchema, addStickerToCardSchema, addTagToCardSchema, blockCardSchema, cardCommentsSchema, cardSizeSchema, createCardSchema, createCardSubtaskSchema, createCommentSchema, createTagSchema, deleteCardSchema, deleteCardSubtaskSchema, deleteCommentSchema, getCardBlockedTimesSchema, getCardChildGraphSchema, getCardChildrenSchema, getCardCommentSchema, getCardFlowHistorySchema, getCardHistorySchema, getCardLinkedCardsSchema, getCardLoggedTimeSchema, getCardOutcomesSchema, getCardParentGraphSchema, getCardParentSchema, getCardParentsSchema, getCardRevisionsSchema, getCardSchema, getCardSubtaskSchema, getCardSubtasksSchema, getCardTypesSchema, listCardsSchema, moveCardSchema, removeCardParentSchema, removePredecessorSchema, removeStickerFromCardSchema, removeTagFromCardSchema, searchCardsSchema, unblockCardSchema, updateCardSchema, updateCardSubtaskSchema, updateCommentSchema, } from '../../schemas/index.js';
2
+ import { READ_ONLY, WRITE, WRITE_IDEMPOTENT, registerTool, } from './base-tool.js';
3
3
  export class CardToolHandler {
4
4
  registerTools(server, client, readOnlyMode) {
5
- this.registerListCards(server, client);
6
- this.registerSearchCards(server, client);
7
- this.registerGetCard(server, client);
8
- this.registerGetCardLoggedTime(server, client);
9
- this.registerGetCardBlockedTimes(server, client);
10
- this.registerGetCardFlowHistory(server, client);
11
- this.registerGetCardSize(server, client);
12
- this.registerGetCardComments(server, client);
13
- this.registerGetCardComment(server, client);
14
- this.registerGetCardCustomFields(server, client);
15
- this.registerGetCardTypes(server, client);
16
- this.registerGetCardHistory(server, client);
17
- this.registerGetCardOutcomes(server, client);
18
- this.registerGetCardLinkedCards(server, client);
19
- this.registerGetCardSubtasks(server, client);
20
- this.registerGetCardSubtask(server, client);
21
- this.registerGetCardParents(server, client);
22
- this.registerGetCardParent(server, client);
23
- this.registerGetCardParentGraph(server, client);
24
- this.registerGetCardChildren(server, client);
5
+ this.registerReadTools(server, client);
25
6
  if (!readOnlyMode) {
26
- this.registerCreateCard(server, client);
27
- this.registerMoveCard(server, client);
28
- this.registerUpdateCard(server, client);
29
- this.registerSetCardSize(server, client);
30
- this.registerDeleteCard(server, client);
31
- this.registerCreateCardSubtask(server, client);
32
- this.registerUpdateCardSubtask(server, client);
33
- this.registerDeleteCardSubtask(server, client);
34
- this.registerAddCardParent(server, client);
35
- this.registerRemoveCardParent(server, client);
36
- // Block / Unblock
37
- this.registerBlockCard(server, client);
38
- this.registerUnblockCard(server, client);
39
- // Comments
40
- this.registerCreateComment(server, client);
41
- this.registerUpdateComment(server, client);
42
- this.registerDeleteComment(server, client);
43
- // Tags
44
- this.registerCreateTag(server, client);
45
- this.registerAddTagToCard(server, client);
46
- this.registerRemoveTagFromCard(server, client);
47
- // Stickers
48
- this.registerAddStickerToCard(server, client);
49
- this.registerRemoveStickerFromCard(server, client);
50
- // Predecessors
51
- this.registerAddPredecessor(server, client);
52
- this.registerRemovePredecessor(server, client);
7
+ this.registerCardWriteTools(server, client);
8
+ this.registerSubtaskWriteTools(server, client);
9
+ this.registerRelationshipWriteTools(server, client);
10
+ this.registerCommentWriteTools(server, client);
11
+ this.registerTagStickerWriteTools(server, client);
53
12
  }
54
13
  }
55
- registerListCards(server, client) {
56
- server.registerTool('list_cards', {
14
+ registerReadTools(server, client) {
15
+ registerTool(server, {
16
+ name: 'list_cards',
57
17
  title: 'List Cards',
58
18
  description: 'Get a list of cards from a board with optional filters',
59
- inputSchema: listCardsSchema.shape,
60
- annotations: { readOnlyHint: true, idempotentHint: true },
61
- }, async (params) => {
62
- try {
63
- const { board_id, ...filters } = params;
64
- const cards = await client.getCards(board_id, filters);
65
- return createSuccessResponse(cards);
66
- }
67
- catch (error) {
68
- return createErrorResponse(error, 'fetching cards');
69
- }
19
+ schema: listCardsSchema,
20
+ annotations: READ_ONLY,
21
+ errorContext: 'fetching cards',
22
+ handler: ({ board_id, ...filters }) => client.cards.getCards(board_id, filters),
70
23
  });
71
- }
72
- registerSearchCards(server, client) {
73
- server.registerTool('search_cards', {
24
+ registerTool(server, {
25
+ name: 'search_cards',
74
26
  title: 'Search Cards',
75
27
  description: 'Search for cards across all boards (or a subset of boards) using advanced filters: owners, priorities, sizes, blocked state, types, dates, lifecycle state and more',
76
- inputSchema: searchCardsSchema.shape,
77
- annotations: { readOnlyHint: true, idempotentHint: true },
78
- }, async (params) => {
79
- try {
80
- const result = await client.searchCards(params);
81
- return createSuccessResponse(result);
82
- }
83
- catch (error) {
84
- return createErrorResponse(error, 'searching cards');
85
- }
86
- });
87
- }
88
- registerGetCardLoggedTime(server, client) {
89
- server.registerTool('get_card_logged_time', {
90
- title: 'Get Card Logged Time',
91
- description: 'Get the time logged on a card (and optionally its subtasks), with the individual logged time entries',
92
- inputSchema: getCardLoggedTimeSchema.shape,
93
- annotations: { readOnlyHint: true, idempotentHint: true },
94
- }, async ({ card_id, include_subtasks }) => {
95
- try {
96
- const entries = await client.getCardLoggedTimes(card_id, include_subtasks ?? true);
97
- const totalTime = entries.reduce((sum, entry) => sum + (entry.time || 0), 0);
98
- return createSuccessResponse({ total_time: totalTime, entries, count: entries.length });
99
- }
100
- catch (error) {
101
- return createErrorResponse(error, 'getting card logged time');
102
- }
28
+ schema: searchCardsSchema,
29
+ annotations: READ_ONLY,
30
+ errorContext: 'searching cards',
31
+ handler: (params) => client.cards.searchCards(params),
103
32
  });
104
- }
105
- registerGetCardBlockedTimes(server, client) {
106
- server.registerTool('get_card_blocked_times', {
107
- title: 'Get Card Blocked Times',
108
- description: 'Get the full blocking history of a card, including when and where blocks occurred',
109
- inputSchema: getCardBlockedTimesSchema.shape,
110
- annotations: { readOnlyHint: true, idempotentHint: true },
111
- }, async ({ card_id }) => {
112
- try {
113
- const card = await client.getCardBlockTimes(card_id);
114
- if (!card) {
115
- return createErrorResponse(new Error(`Card ${card_id} not found`), 'getting card blocked times');
116
- }
117
- return createSuccessResponse(card);
118
- }
119
- catch (error) {
120
- return createErrorResponse(error, 'getting card blocked times');
121
- }
122
- });
123
- }
124
- registerGetCardFlowHistory(server, client) {
125
- server.registerTool('get_card_flow_history', {
126
- title: 'Get Card Flow History',
127
- description: "Get the card's movement history (transitions) across boards, workflows and columns with timing details",
128
- inputSchema: getCardFlowHistorySchema.shape,
129
- annotations: { readOnlyHint: true, idempotentHint: true },
130
- }, async ({ card_id }) => {
131
- try {
132
- const card = await client.getCardTransitions(card_id);
133
- if (!card) {
134
- return createErrorResponse(new Error(`Card ${card_id} not found`), 'getting card flow history');
135
- }
136
- return createSuccessResponse(card);
137
- }
138
- catch (error) {
139
- return createErrorResponse(error, 'getting card flow history');
140
- }
141
- });
142
- }
143
- registerGetCard(server, client) {
144
- server.registerTool('get_card', {
33
+ registerTool(server, {
34
+ name: 'get_card',
145
35
  title: 'Get Card',
146
36
  description: 'Get details of a specific card',
147
- inputSchema: getCardSchema.shape,
148
- annotations: { readOnlyHint: true, idempotentHint: true },
149
- }, async ({ card_id }) => {
150
- try {
151
- const card = await client.getCard(card_id);
152
- return createSuccessResponse(card);
153
- }
154
- catch (error) {
155
- return createErrorResponse(error, 'fetching card');
156
- }
37
+ schema: getCardSchema,
38
+ annotations: READ_ONLY,
39
+ errorContext: 'fetching card',
40
+ handler: ({ card_id }) => client.cards.getCard(card_id),
157
41
  });
158
- }
159
- registerGetCardSize(server, client) {
160
- server.registerTool('get_card_size', {
42
+ registerTool(server, {
43
+ name: 'get_card_size',
161
44
  title: 'Get Card Size',
162
45
  description: 'Get the size/points of a specific card',
163
- inputSchema: getCardSchema.shape,
164
- annotations: { readOnlyHint: true, idempotentHint: true },
165
- }, async ({ card_id }) => {
166
- try {
167
- const card = await client.getCard(card_id);
168
- const size = card.size || 0;
46
+ schema: getCardSchema,
47
+ annotations: READ_ONLY,
48
+ errorContext: 'fetching card size',
49
+ handler: async ({ card_id }) => {
50
+ const card = await client.cards.getCard(card_id);
169
51
  return {
170
52
  content: [
171
53
  {
172
54
  type: 'text',
173
- text: `Card "${card.title}" (ID: ${card_id}) has size: ${size} points`,
55
+ text: `Card "${card.title}" (ID: ${card_id}) has size: ${card.size || 0} points`,
174
56
  },
175
57
  ],
176
58
  };
177
- }
178
- catch (error) {
179
- return createErrorResponse(error, 'fetching card size');
180
- }
181
- });
182
- }
183
- registerCreateCard(server, client) {
184
- server.registerTool('create_card', {
185
- title: 'Create Card',
186
- description: 'Create a new card in a board',
187
- inputSchema: createCardSchema.shape,
188
- annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },
189
- }, async (params) => {
190
- try {
191
- const card = await client.createCard(params);
192
- return createSuccessResponse(card, 'Card created successfully:');
193
- }
194
- catch (error) {
195
- return createErrorResponse(error, 'creating card');
196
- }
59
+ },
197
60
  });
198
- }
199
- registerMoveCard(server, client) {
200
- server.registerTool('move_card', {
201
- title: 'Move Card',
202
- description: 'Move a card to a different column or lane',
203
- inputSchema: moveCardSchema.shape,
204
- annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },
205
- }, async ({ card_id, column_id, lane_id, position }) => {
206
- try {
207
- const card = await client.moveCard(card_id, column_id, lane_id, position);
208
- return createSuccessResponse(card, 'Card moved successfully:');
209
- }
210
- catch (error) {
211
- return createErrorResponse(error, 'moving card');
212
- }
61
+ registerTool(server, {
62
+ name: 'get_card_logged_time',
63
+ title: 'Get Card Logged Time',
64
+ description: 'Get the time logged on a card (and optionally its subtasks), with the individual logged time entries',
65
+ schema: getCardLoggedTimeSchema,
66
+ annotations: READ_ONLY,
67
+ errorContext: 'getting card logged time',
68
+ handler: async ({ card_id, include_subtasks }) => {
69
+ const entries = await client.cards.getCardLoggedTimes(card_id, include_subtasks ?? true);
70
+ const totalTime = entries.reduce((sum, entry) => sum + (entry.time || 0), 0);
71
+ return { total_time: totalTime, entries, count: entries.length };
72
+ },
213
73
  });
214
- }
215
- registerUpdateCard(server, client) {
216
- server.registerTool('update_card', {
217
- title: 'Update Card',
218
- description: "Update a card's properties",
219
- inputSchema: updateCardSchema.shape,
220
- annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },
221
- }, async (params) => {
222
- try {
223
- const card = await client.updateCard(params);
224
- return createSuccessResponse(card, 'Card updated successfully:');
225
- }
226
- catch (error) {
227
- return createErrorResponse(error, 'updating card');
228
- }
74
+ registerTool(server, {
75
+ name: 'get_card_blocked_times',
76
+ title: 'Get Card Blocked Times',
77
+ description: 'Get the full blocking history of a card, including when and where blocks occurred',
78
+ schema: getCardBlockedTimesSchema,
79
+ annotations: READ_ONLY,
80
+ errorContext: 'getting card blocked times',
81
+ handler: async ({ card_id }) => {
82
+ const card = await client.cards.getCardBlockTimes(card_id);
83
+ if (!card) {
84
+ throw new Error(`Card ${card_id} not found`);
85
+ }
86
+ return card;
87
+ },
229
88
  });
230
- }
231
- registerSetCardSize(server, client) {
232
- server.registerTool('set_card_size', {
233
- title: 'Set Card Size',
234
- description: 'Set the size/points of a specific card',
235
- inputSchema: cardSizeSchema.shape,
236
- annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },
237
- }, async ({ card_id, size }) => {
238
- try {
239
- const card = await client.updateCard({ card_id, size });
240
- return {
241
- content: [
242
- {
243
- type: 'text',
244
- text: `Card "${card.title}" (ID: ${card_id}) size updated to: ${size} points`,
245
- },
246
- ],
247
- };
248
- }
249
- catch (error) {
250
- return createErrorResponse(error, 'setting card size');
251
- }
89
+ registerTool(server, {
90
+ name: 'get_card_flow_history',
91
+ title: 'Get Card Flow History',
92
+ description: "Get the card's movement history (transitions) across boards, workflows and columns with timing details",
93
+ schema: getCardFlowHistorySchema,
94
+ annotations: READ_ONLY,
95
+ errorContext: 'getting card flow history',
96
+ handler: async ({ card_id }) => {
97
+ const card = await client.cards.getCardTransitions(card_id);
98
+ if (!card) {
99
+ throw new Error(`Card ${card_id} not found`);
100
+ }
101
+ return card;
102
+ },
252
103
  });
253
- }
254
- registerGetCardComments(server, client) {
255
- server.registerTool('get_card_comments', {
104
+ registerTool(server, {
105
+ name: 'get_card_comments',
256
106
  title: 'Get Card Comments',
257
107
  description: 'Get all comments for a specific card',
258
- inputSchema: cardCommentsSchema.shape,
259
- annotations: { readOnlyHint: true, idempotentHint: true },
260
- }, async ({ card_id }) => {
261
- try {
262
- const comments = await client.getCardComments(card_id);
263
- return createSuccessResponse({
264
- comments,
265
- count: comments.length,
266
- });
267
- }
268
- catch (error) {
269
- return createErrorResponse(error, 'getting card comments');
270
- }
271
- });
272
- }
273
- registerGetCardComment(server, client) {
274
- server.registerTool('get_card_comment', {
108
+ schema: cardCommentsSchema,
109
+ annotations: READ_ONLY,
110
+ errorContext: 'getting card comments',
111
+ handler: async ({ card_id }) => {
112
+ const comments = await client.cards.getCardComments(card_id);
113
+ return { comments, count: comments.length };
114
+ },
115
+ });
116
+ registerTool(server, {
117
+ name: 'get_card_comment',
275
118
  title: 'Get Card Comment',
276
119
  description: 'Get details of a specific comment from a card',
277
- inputSchema: getCardCommentSchema.shape,
278
- annotations: { readOnlyHint: true, idempotentHint: true },
279
- }, async ({ card_id, comment_id }) => {
280
- try {
281
- const comment = await client.getCardComment(card_id, comment_id);
282
- return createSuccessResponse(comment);
283
- }
284
- catch (error) {
285
- return createErrorResponse(error, 'getting card comment');
286
- }
120
+ schema: getCardCommentSchema,
121
+ annotations: READ_ONLY,
122
+ errorContext: 'getting card comment',
123
+ handler: ({ card_id, comment_id }) => client.cards.getCardComment(card_id, comment_id),
287
124
  });
288
- }
289
- registerGetCardCustomFields(server, client) {
290
- server.registerTool('get_card_custom_fields', {
125
+ registerTool(server, {
126
+ name: 'get_card_custom_fields',
291
127
  title: 'Get Card Custom Fields',
292
128
  description: 'Get all custom fields for a specific card',
293
- inputSchema: getCardSchema.shape,
294
- annotations: { readOnlyHint: true, idempotentHint: true },
295
- }, async ({ card_id }) => {
296
- try {
297
- const customFields = await client.getCardCustomFields(card_id);
298
- return createSuccessResponse({
299
- customFields,
300
- count: customFields.length,
301
- });
302
- }
303
- catch (error) {
304
- return createErrorResponse(error, 'getting card custom fields');
305
- }
306
- });
307
- }
308
- registerGetCardTypes(server, client) {
309
- server.registerTool('get_card_types', {
129
+ schema: getCardSchema,
130
+ annotations: READ_ONLY,
131
+ errorContext: 'getting card custom fields',
132
+ handler: async ({ card_id }) => {
133
+ const customFields = await client.cards.getCardCustomFields(card_id);
134
+ return { customFields, count: customFields.length };
135
+ },
136
+ });
137
+ registerTool(server, {
138
+ name: 'get_card_types',
310
139
  title: 'Get Card Types',
311
140
  description: 'Get all available card types',
312
- inputSchema: getCardTypesSchema.shape,
313
- annotations: { readOnlyHint: true, idempotentHint: true },
314
- }, async () => {
315
- try {
316
- const cardTypes = await client.getCardTypes();
317
- return createSuccessResponse({
318
- cardTypes,
319
- count: cardTypes.length,
320
- });
321
- }
322
- catch (error) {
323
- return createErrorResponse(error, 'getting card types');
324
- }
325
- });
326
- }
327
- registerGetCardHistory(server, client) {
328
- server.registerTool('get_card_history', {
141
+ schema: getCardTypesSchema,
142
+ annotations: READ_ONLY,
143
+ errorContext: 'getting card types',
144
+ handler: async () => {
145
+ const cardTypes = await client.cards.getCardTypes();
146
+ return { cardTypes, count: cardTypes.length };
147
+ },
148
+ });
149
+ registerTool(server, {
150
+ name: 'get_card_history',
329
151
  title: 'Get Card History',
330
152
  description: 'Get the history of a specific card outcome',
331
- inputSchema: getCardHistorySchema.shape,
332
- annotations: { readOnlyHint: true, idempotentHint: true },
333
- }, async ({ card_id, outcome_id }) => {
334
- try {
335
- const history = await client.getCardHistory(card_id, outcome_id);
336
- return createSuccessResponse({
337
- history,
338
- count: history.length,
339
- });
340
- }
341
- catch (error) {
342
- return createErrorResponse(error, 'getting card history');
343
- }
344
- });
345
- }
346
- registerGetCardOutcomes(server, client) {
347
- server.registerTool('get_card_outcomes', {
153
+ schema: getCardHistorySchema,
154
+ annotations: READ_ONLY,
155
+ errorContext: 'getting card history',
156
+ handler: async ({ card_id, outcome_id }) => {
157
+ const history = await client.cards.getCardHistory(card_id, outcome_id);
158
+ return { history, count: history.length };
159
+ },
160
+ });
161
+ registerTool(server, {
162
+ name: 'get_card_outcomes',
348
163
  title: 'Get Card Outcomes',
349
164
  description: 'Get all outcomes for a specific card',
350
- inputSchema: getCardOutcomesSchema.shape,
351
- annotations: { readOnlyHint: true, idempotentHint: true },
352
- }, async ({ card_id }) => {
353
- try {
354
- const outcomes = await client.getCardOutcomes(card_id);
355
- return createSuccessResponse({
356
- outcomes,
357
- count: outcomes.length,
358
- });
359
- }
360
- catch (error) {
361
- return createErrorResponse(error, 'getting card outcomes');
362
- }
363
- });
364
- }
365
- registerGetCardLinkedCards(server, client) {
366
- server.registerTool('get_card_linked_cards', {
165
+ schema: getCardOutcomesSchema,
166
+ annotations: READ_ONLY,
167
+ errorContext: 'getting card outcomes',
168
+ handler: async ({ card_id }) => {
169
+ const outcomes = await client.cards.getCardOutcomes(card_id);
170
+ return { outcomes, count: outcomes.length };
171
+ },
172
+ });
173
+ registerTool(server, {
174
+ name: 'get_card_linked_cards',
367
175
  title: 'Get Card Linked Cards',
368
176
  description: 'Get all linked cards for a specific card',
369
- inputSchema: getCardLinkedCardsSchema.shape,
370
- annotations: { readOnlyHint: true, idempotentHint: true },
371
- }, async ({ card_id }) => {
372
- try {
373
- const linkedCards = await client.getCardLinkedCards(card_id);
374
- return createSuccessResponse({
375
- linkedCards,
376
- count: linkedCards.length,
377
- });
378
- }
379
- catch (error) {
380
- return createErrorResponse(error, 'getting card linked cards');
381
- }
382
- });
383
- }
384
- registerGetCardSubtasks(server, client) {
385
- server.registerTool('get_card_subtasks', {
177
+ schema: getCardLinkedCardsSchema,
178
+ annotations: READ_ONLY,
179
+ errorContext: 'getting card linked cards',
180
+ handler: async ({ card_id }) => {
181
+ const linkedCards = await client.cards.getCardLinkedCards(card_id);
182
+ return { linkedCards, count: linkedCards.length };
183
+ },
184
+ });
185
+ registerTool(server, {
186
+ name: 'get_card_subtasks',
386
187
  title: 'Get Card Subtasks',
387
188
  description: 'Get all subtasks for a specific card',
388
- inputSchema: getCardSubtasksSchema.shape,
389
- annotations: { readOnlyHint: true, idempotentHint: true },
390
- }, async ({ card_id }) => {
391
- try {
392
- const subtasks = await client.getCardSubtasks(card_id);
393
- return createSuccessResponse({
394
- subtasks,
395
- count: subtasks.length,
396
- });
397
- }
398
- catch (error) {
399
- return createErrorResponse(error, 'getting card subtasks');
400
- }
401
- });
402
- }
403
- registerGetCardSubtask(server, client) {
404
- server.registerTool('get_card_subtask', {
189
+ schema: getCardSubtasksSchema,
190
+ annotations: READ_ONLY,
191
+ errorContext: 'getting card subtasks',
192
+ handler: async ({ card_id }) => {
193
+ const subtasks = await client.cards.getCardSubtasks(card_id);
194
+ return { subtasks, count: subtasks.length };
195
+ },
196
+ });
197
+ registerTool(server, {
198
+ name: 'get_card_subtask',
405
199
  title: 'Get Card Subtask',
406
200
  description: 'Get details of a specific subtask from a card',
407
- inputSchema: getCardSubtaskSchema.shape,
408
- annotations: { readOnlyHint: true, idempotentHint: true },
409
- }, async ({ card_id, subtask_id }) => {
410
- try {
411
- const subtask = await client.getCardSubtask(card_id, subtask_id);
412
- return createSuccessResponse(subtask);
413
- }
414
- catch (error) {
415
- return createErrorResponse(error, 'getting card subtask');
416
- }
417
- });
418
- }
419
- registerCreateCardSubtask(server, client) {
420
- server.registerTool('create_card_subtask', {
421
- title: 'Create Card Subtask',
422
- description: 'Create a new subtask for a card',
423
- inputSchema: createCardSubtaskSchema.shape,
424
- annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },
425
- }, async (params) => {
426
- try {
427
- const { card_id, ...subtaskData } = params;
428
- const subtask = await client.createCardSubtask(card_id, subtaskData);
429
- return createSuccessResponse(subtask, 'Subtask created successfully:');
430
- }
431
- catch (error) {
432
- return createErrorResponse(error, 'creating card subtask');
433
- }
434
- });
435
- }
436
- registerUpdateCardSubtask(server, client) {
437
- server.registerTool('update_card_subtask', {
438
- title: 'Update Card Subtask',
439
- description: 'Update an existing subtask of a card (description, owner, finished state, deadline, position)',
440
- inputSchema: updateCardSubtaskSchema.shape,
441
- annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },
442
- }, async (params) => {
443
- try {
444
- const { card_id, subtask_id, ...subtaskData } = params;
445
- const subtask = await client.updateCardSubtask(card_id, subtask_id, subtaskData);
446
- return createSuccessResponse(subtask, 'Subtask updated successfully:');
447
- }
448
- catch (error) {
449
- return createErrorResponse(error, 'updating card subtask');
450
- }
451
- });
452
- }
453
- registerDeleteCardSubtask(server, client) {
454
- server.registerTool('delete_card_subtask', {
455
- title: 'Delete Card Subtask',
456
- description: 'Delete a subtask from a card',
457
- inputSchema: deleteCardSubtaskSchema.shape,
458
- annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true },
459
- }, async ({ card_id, subtask_id }) => {
460
- try {
461
- await client.deleteCardSubtask(card_id, subtask_id);
462
- return createSuccessResponse({ card_id, subtask_id }, 'Subtask deleted successfully:');
463
- }
464
- catch (error) {
465
- return createErrorResponse(error, 'deleting card subtask');
466
- }
201
+ schema: getCardSubtaskSchema,
202
+ annotations: READ_ONLY,
203
+ errorContext: 'getting card subtask',
204
+ handler: ({ card_id, subtask_id }) => client.cards.getCardSubtask(card_id, subtask_id),
467
205
  });
468
- }
469
- registerGetCardParents(server, client) {
470
- server.registerTool('get_card_parents', {
206
+ registerTool(server, {
207
+ name: 'get_card_parents',
471
208
  title: 'Get Card Parents',
472
209
  description: 'Get a list of parent cards for a specific card',
473
- inputSchema: getCardParentsSchema.shape,
474
- annotations: { readOnlyHint: true, idempotentHint: true },
475
- }, async ({ card_id }) => {
476
- try {
477
- const parents = await client.getCardParents(card_id);
478
- return createSuccessResponse({
479
- parents,
480
- count: parents.length,
481
- });
482
- }
483
- catch (error) {
484
- return createErrorResponse(error, 'getting card parents');
485
- }
486
- });
487
- }
488
- registerGetCardParent(server, client) {
489
- server.registerTool('get_card_parent', {
210
+ schema: getCardParentsSchema,
211
+ annotations: READ_ONLY,
212
+ errorContext: 'getting card parents',
213
+ handler: async ({ card_id }) => {
214
+ const parents = await client.cards.getCardParents(card_id);
215
+ return { parents, count: parents.length };
216
+ },
217
+ });
218
+ registerTool(server, {
219
+ name: 'get_card_parent',
490
220
  title: 'Get Card Parent',
491
221
  description: 'Check if a card is a parent of a given card',
492
- inputSchema: getCardParentSchema.shape,
493
- annotations: { readOnlyHint: true, idempotentHint: true },
494
- }, async ({ card_id, parent_card_id }) => {
495
- try {
496
- const parent = await client.getCardParent(card_id, parent_card_id);
497
- return createSuccessResponse(parent);
498
- }
499
- catch (error) {
500
- return createErrorResponse(error, 'getting card parent');
501
- }
222
+ schema: getCardParentSchema,
223
+ annotations: READ_ONLY,
224
+ errorContext: 'getting card parent',
225
+ handler: ({ card_id, parent_card_id }) => client.cards.getCardParent(card_id, parent_card_id),
502
226
  });
503
- }
504
- registerAddCardParent(server, client) {
505
- server.registerTool('add_card_parent', {
506
- title: 'Add Card Parent',
507
- description: 'Make a card a parent of a given card',
508
- inputSchema: addCardParentSchema.shape,
509
- annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },
510
- }, async ({ card_id, parent_card_id }) => {
511
- try {
512
- const result = await client.addCardParent(card_id, parent_card_id);
513
- return createSuccessResponse(result, 'Card parent added successfully:');
514
- }
515
- catch (error) {
516
- return createErrorResponse(error, 'adding card parent');
517
- }
518
- });
519
- }
520
- registerRemoveCardParent(server, client) {
521
- server.registerTool('remove_card_parent', {
522
- title: 'Remove Card Parent',
523
- description: 'Remove the link between a child card and a parent card',
524
- inputSchema: removeCardParentSchema.shape,
525
- annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false },
526
- }, async ({ card_id, parent_card_id }) => {
527
- try {
528
- await client.removeCardParent(card_id, parent_card_id);
529
- return createSuccessResponse({ card_id, parent_card_id }, 'Card parent removed successfully:');
530
- }
531
- catch (error) {
532
- return createErrorResponse(error, 'removing card parent');
533
- }
534
- });
535
- }
536
- registerGetCardParentGraph(server, client) {
537
- server.registerTool('get_card_parent_graph', {
227
+ registerTool(server, {
228
+ name: 'get_card_parent_graph',
538
229
  title: 'Get Card Parent Graph',
539
230
  description: 'Get a list of parent cards including their parent cards too',
540
- inputSchema: getCardParentGraphSchema.shape,
541
- annotations: { readOnlyHint: true, idempotentHint: true },
542
- }, async ({ card_id }) => {
543
- try {
544
- const parentGraph = await client.getCardParentGraph(card_id);
545
- return createSuccessResponse({
546
- parentGraph,
547
- count: parentGraph.length,
548
- });
549
- }
550
- catch (error) {
551
- return createErrorResponse(error, 'getting card parent graph');
552
- }
553
- });
554
- }
555
- registerGetCardChildren(server, client) {
556
- server.registerTool('get_card_children', {
231
+ schema: getCardParentGraphSchema,
232
+ annotations: READ_ONLY,
233
+ errorContext: 'getting card parent graph',
234
+ handler: async ({ card_id }) => {
235
+ const parentGraph = await client.cards.getCardParentGraph(card_id);
236
+ return { parentGraph, count: parentGraph.length };
237
+ },
238
+ });
239
+ registerTool(server, {
240
+ name: 'get_card_children',
557
241
  title: 'Get Card Children',
558
242
  description: 'Get a list of child cards of a specified parent card',
559
- inputSchema: getCardChildrenSchema.shape,
560
- annotations: { readOnlyHint: true, idempotentHint: true },
561
- }, async ({ card_id }) => {
562
- try {
563
- const children = await client.getCardChildren(card_id);
564
- return createSuccessResponse({
565
- children,
566
- count: children.length,
567
- });
568
- }
569
- catch (error) {
570
- return createErrorResponse(error, 'getting card children');
571
- }
243
+ schema: getCardChildrenSchema,
244
+ annotations: READ_ONLY,
245
+ errorContext: 'getting card children',
246
+ handler: async ({ card_id }) => {
247
+ const children = await client.cards.getCardChildren(card_id);
248
+ return { children, count: children.length };
249
+ },
250
+ });
251
+ registerTool(server, {
252
+ name: 'get_card_child_graph',
253
+ title: 'Get Card Child Graph',
254
+ description: "Get the hierarchical graph of a card's children, including children of children",
255
+ schema: getCardChildGraphSchema,
256
+ annotations: READ_ONLY,
257
+ errorContext: 'getting card child graph',
258
+ handler: async ({ card_id }) => {
259
+ const graph = await client.cards.getCardChildGraph(card_id);
260
+ return { children: graph, count: graph.length };
261
+ },
262
+ });
263
+ registerTool(server, {
264
+ name: 'get_card_revisions',
265
+ title: 'Get Card Revisions',
266
+ description: 'Get the chronological change history (revisions) of a card. Pass a revision number to get the full card state at that revision.',
267
+ schema: getCardRevisionsSchema,
268
+ annotations: READ_ONLY,
269
+ errorContext: 'getting card revisions',
270
+ handler: async ({ card_id, revision }) => {
271
+ if (revision !== undefined) {
272
+ return client.cards.getCardRevision(card_id, revision);
273
+ }
274
+ const revisions = await client.cards.getCardRevisions(card_id);
275
+ return { revisions, count: revisions.length };
276
+ },
572
277
  });
573
278
  }
574
- // ─── Block / Unblock ────────────────────────────────────────────────────────
575
- registerBlockCard(server, client) {
576
- server.registerTool('block_card', {
279
+ registerCardWriteTools(server, client) {
280
+ registerTool(server, {
281
+ name: 'create_card',
282
+ title: 'Create Card',
283
+ description: 'Create a new card in a board',
284
+ schema: createCardSchema,
285
+ annotations: WRITE,
286
+ errorContext: 'creating card',
287
+ successMessage: 'Card created successfully:',
288
+ handler: (params) => client.cards.createCard(params),
289
+ });
290
+ registerTool(server, {
291
+ name: 'move_card',
292
+ title: 'Move Card',
293
+ description: 'Move a card to a different column or lane',
294
+ schema: moveCardSchema,
295
+ annotations: WRITE,
296
+ errorContext: 'moving card',
297
+ successMessage: 'Card moved successfully:',
298
+ handler: ({ card_id, column_id, lane_id, position }) => client.cards.moveCard(card_id, column_id, lane_id, position),
299
+ });
300
+ registerTool(server, {
301
+ name: 'update_card',
302
+ title: 'Update Card',
303
+ description: "Update a card's properties",
304
+ schema: updateCardSchema,
305
+ annotations: WRITE,
306
+ errorContext: 'updating card',
307
+ successMessage: 'Card updated successfully:',
308
+ handler: (params) => client.cards.updateCard(params),
309
+ });
310
+ registerTool(server, {
311
+ name: 'set_card_size',
312
+ title: 'Set Card Size',
313
+ description: 'Set the size/points of a specific card',
314
+ schema: cardSizeSchema,
315
+ annotations: WRITE,
316
+ errorContext: 'setting card size',
317
+ handler: async ({ card_id, size }) => {
318
+ const card = await client.cards.updateCard({ card_id, size });
319
+ return {
320
+ content: [
321
+ {
322
+ type: 'text',
323
+ text: `Card "${card.title}" (ID: ${card_id}) size updated to: ${size} points`,
324
+ },
325
+ ],
326
+ };
327
+ },
328
+ });
329
+ registerTool(server, {
330
+ name: 'delete_card',
331
+ title: 'Delete Card',
332
+ description: 'Permanently delete a card. This action cannot be undone and the card cannot be recovered.',
333
+ schema: deleteCardSchema,
334
+ errorContext: 'deleting card',
335
+ successMessage: 'Card deleted successfully:',
336
+ handler: async ({ card_id }) => {
337
+ await client.cards.deleteCard(card_id);
338
+ return { card_id };
339
+ },
340
+ });
341
+ registerTool(server, {
342
+ name: 'block_card',
577
343
  title: 'Block Card',
578
344
  description: 'Block a card and set a reason/comment explaining why it is blocked',
579
- inputSchema: blockCardSchema.shape,
580
- }, async ({ card_id, reason }) => {
581
- try {
582
- await client.blockCard(card_id, reason);
583
- return createSuccessResponse({ card_id, reason }, 'Card blocked successfully:');
584
- }
585
- catch (error) {
586
- return createErrorResponse(error, 'blocking card');
587
- }
588
- });
589
- }
590
- registerUnblockCard(server, client) {
591
- server.registerTool('unblock_card', {
345
+ schema: blockCardSchema,
346
+ errorContext: 'blocking card',
347
+ successMessage: 'Card blocked successfully:',
348
+ handler: async ({ card_id, reason }) => {
349
+ await client.cards.blockCard(card_id, reason);
350
+ return { card_id, reason };
351
+ },
352
+ });
353
+ registerTool(server, {
354
+ name: 'unblock_card',
592
355
  title: 'Unblock Card',
593
356
  description: 'Unblock a card by removing its block reason',
594
- inputSchema: unblockCardSchema.shape,
595
- }, async ({ card_id }) => {
596
- try {
597
- await client.unblockCard(card_id);
598
- return createSuccessResponse({ card_id }, 'Card unblocked successfully:');
599
- }
600
- catch (error) {
601
- return createErrorResponse(error, 'unblocking card');
602
- }
357
+ schema: unblockCardSchema,
358
+ errorContext: 'unblocking card',
359
+ successMessage: 'Card unblocked successfully:',
360
+ handler: async ({ card_id }) => {
361
+ await client.cards.unblockCard(card_id);
362
+ return { card_id };
363
+ },
364
+ });
365
+ }
366
+ registerSubtaskWriteTools(server, client) {
367
+ registerTool(server, {
368
+ name: 'create_card_subtask',
369
+ title: 'Create Card Subtask',
370
+ description: 'Create a new subtask for a card',
371
+ schema: createCardSubtaskSchema,
372
+ annotations: WRITE,
373
+ errorContext: 'creating card subtask',
374
+ successMessage: 'Subtask created successfully:',
375
+ handler: ({ card_id, ...subtaskData }) => client.cards.createCardSubtask(card_id, subtaskData),
376
+ });
377
+ registerTool(server, {
378
+ name: 'update_card_subtask',
379
+ title: 'Update Card Subtask',
380
+ description: 'Update an existing subtask of a card (description, owner, finished state, deadline, position)',
381
+ schema: updateCardSubtaskSchema,
382
+ annotations: WRITE_IDEMPOTENT,
383
+ errorContext: 'updating card subtask',
384
+ successMessage: 'Subtask updated successfully:',
385
+ handler: ({ card_id, subtask_id, ...subtaskData }) => client.cards.updateCardSubtask(card_id, subtask_id, subtaskData),
386
+ });
387
+ registerTool(server, {
388
+ name: 'delete_card_subtask',
389
+ title: 'Delete Card Subtask',
390
+ description: 'Delete a subtask from a card',
391
+ schema: deleteCardSubtaskSchema,
392
+ annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true },
393
+ errorContext: 'deleting card subtask',
394
+ successMessage: 'Subtask deleted successfully:',
395
+ handler: async ({ card_id, subtask_id }) => {
396
+ await client.cards.deleteCardSubtask(card_id, subtask_id);
397
+ return { card_id, subtask_id };
398
+ },
603
399
  });
604
400
  }
605
- // ─── Comments ───────────────────────────────────────────────────────────────
606
- registerCreateComment(server, client) {
607
- server.registerTool('create_comment', {
401
+ registerRelationshipWriteTools(server, client) {
402
+ registerTool(server, {
403
+ name: 'add_card_parent',
404
+ title: 'Add Card Parent',
405
+ description: 'Make a card a parent of a given card',
406
+ schema: addCardParentSchema,
407
+ annotations: WRITE,
408
+ errorContext: 'adding card parent',
409
+ successMessage: 'Card parent added successfully:',
410
+ handler: ({ card_id, parent_card_id }) => client.cards.addCardParent(card_id, parent_card_id),
411
+ });
412
+ registerTool(server, {
413
+ name: 'remove_card_parent',
414
+ title: 'Remove Card Parent',
415
+ description: 'Remove the link between a child card and a parent card',
416
+ schema: removeCardParentSchema,
417
+ annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false },
418
+ errorContext: 'removing card parent',
419
+ successMessage: 'Card parent removed successfully:',
420
+ handler: async ({ card_id, parent_card_id }) => {
421
+ await client.cards.removeCardParent(card_id, parent_card_id);
422
+ return { card_id, parent_card_id };
423
+ },
424
+ });
425
+ registerTool(server, {
426
+ name: 'add_predecessor',
427
+ title: 'Add Predecessor',
428
+ description: 'Establish or update a predecessor-successor relationship between two cards. The predecessor_card_id becomes a prerequisite that must be completed before the card.',
429
+ schema: addPredecessorSchema,
430
+ errorContext: 'adding predecessor',
431
+ successMessage: 'Predecessor added successfully:',
432
+ handler: async ({ card_id, predecessor_card_id, linked_card_position, card_position }) => {
433
+ await client.cards.addPredecessor(card_id, predecessor_card_id, {
434
+ ...(linked_card_position !== undefined && { linked_card_position }),
435
+ ...(card_position !== undefined && { card_position }),
436
+ });
437
+ return { card_id, predecessor_card_id };
438
+ },
439
+ });
440
+ registerTool(server, {
441
+ name: 'remove_predecessor',
442
+ title: 'Remove Predecessor',
443
+ description: 'Remove the predecessor-successor relationship between two cards.',
444
+ schema: removePredecessorSchema,
445
+ errorContext: 'removing predecessor',
446
+ successMessage: 'Predecessor removed successfully:',
447
+ handler: async ({ card_id, predecessor_card_id }) => {
448
+ await client.cards.removePredecessor(card_id, predecessor_card_id);
449
+ return { card_id, predecessor_card_id };
450
+ },
451
+ });
452
+ }
453
+ registerCommentWriteTools(server, client) {
454
+ registerTool(server, {
455
+ name: 'create_comment',
608
456
  title: 'Create Comment',
609
457
  description: 'Add a new comment to a card',
610
- inputSchema: createCommentSchema.shape,
611
- }, async ({ card_id, text }) => {
612
- try {
613
- const comment = await client.createCardComment(card_id, { text });
614
- return createSuccessResponse(comment, 'Comment created successfully:');
615
- }
616
- catch (error) {
617
- return createErrorResponse(error, 'creating comment');
618
- }
458
+ schema: createCommentSchema,
459
+ errorContext: 'creating comment',
460
+ successMessage: 'Comment created successfully:',
461
+ handler: ({ card_id, text }) => client.cards.createCardComment(card_id, { text }),
619
462
  });
620
- }
621
- registerUpdateComment(server, client) {
622
- server.registerTool('update_comment', {
463
+ registerTool(server, {
464
+ name: 'update_comment',
623
465
  title: 'Update Comment',
624
466
  description: 'Update the text of an existing comment on a card',
625
- inputSchema: updateCommentSchema.shape,
626
- }, async ({ card_id, comment_id, text }) => {
627
- try {
628
- const comment = await client.updateCardComment(card_id, comment_id, { text });
629
- return createSuccessResponse(comment, 'Comment updated successfully:');
630
- }
631
- catch (error) {
632
- return createErrorResponse(error, 'updating comment');
633
- }
467
+ schema: updateCommentSchema,
468
+ errorContext: 'updating comment',
469
+ successMessage: 'Comment updated successfully:',
470
+ handler: ({ card_id, comment_id, text }) => client.cards.updateCardComment(card_id, comment_id, { text }),
634
471
  });
635
- }
636
- registerDeleteComment(server, client) {
637
- server.registerTool('delete_comment', {
472
+ registerTool(server, {
473
+ name: 'delete_comment',
638
474
  title: 'Delete Comment',
639
475
  description: 'Delete a comment from a card',
640
- inputSchema: deleteCommentSchema.shape,
641
- }, async ({ card_id, comment_id }) => {
642
- try {
643
- await client.deleteCardComment(card_id, comment_id);
644
- return createSuccessResponse({ card_id, comment_id }, 'Comment deleted successfully:');
645
- }
646
- catch (error) {
647
- return createErrorResponse(error, 'deleting comment');
648
- }
649
- });
650
- }
651
- // ─── Tags ────────────────────────────────────────────────────────────────────
652
- registerCreateTag(server, client) {
653
- server.registerTool('create_tag', {
476
+ schema: deleteCommentSchema,
477
+ errorContext: 'deleting comment',
478
+ successMessage: 'Comment deleted successfully:',
479
+ handler: async ({ card_id, comment_id }) => {
480
+ await client.cards.deleteCardComment(card_id, comment_id);
481
+ return { card_id, comment_id };
482
+ },
483
+ });
484
+ }
485
+ registerTagStickerWriteTools(server, client) {
486
+ registerTool(server, {
487
+ name: 'create_tag',
654
488
  title: 'Create Tag',
655
489
  description: 'Create a new tag in the workspace',
656
- inputSchema: createTagSchema.shape,
657
- }, async ({ label, color }) => {
658
- try {
659
- const tag = await client.createTag({ label, color });
660
- return createSuccessResponse(tag, 'Tag created successfully:');
661
- }
662
- catch (error) {
663
- return createErrorResponse(error, 'creating tag');
664
- }
490
+ schema: createTagSchema,
491
+ errorContext: 'creating tag',
492
+ successMessage: 'Tag created successfully:',
493
+ handler: ({ label, color }) => client.cards.createTag({ label, color }),
665
494
  });
666
- }
667
- registerAddTagToCard(server, client) {
668
- server.registerTool('add_tag_to_card', {
495
+ registerTool(server, {
496
+ name: 'add_tag_to_card',
669
497
  title: 'Add Tag to Card',
670
498
  description: 'Add an existing tag to a card',
671
- inputSchema: addTagToCardSchema.shape,
672
- }, async ({ card_id, tag_id }) => {
673
- try {
674
- await client.addTagToCard(card_id, tag_id);
675
- return createSuccessResponse({ card_id, tag_id }, 'Tag added to card successfully:');
676
- }
677
- catch (error) {
678
- return createErrorResponse(error, 'adding tag to card');
679
- }
680
- });
681
- }
682
- registerRemoveTagFromCard(server, client) {
683
- server.registerTool('remove_tag_from_card', {
499
+ schema: addTagToCardSchema,
500
+ errorContext: 'adding tag to card',
501
+ successMessage: 'Tag added to card successfully:',
502
+ handler: async ({ card_id, tag_id }) => {
503
+ await client.cards.addTagToCard(card_id, tag_id);
504
+ return { card_id, tag_id };
505
+ },
506
+ });
507
+ registerTool(server, {
508
+ name: 'remove_tag_from_card',
684
509
  title: 'Remove Tag from Card',
685
510
  description: 'Remove a tag from a card',
686
- inputSchema: removeTagFromCardSchema.shape,
687
- }, async ({ card_id, tag_id }) => {
688
- try {
689
- await client.removeTagFromCard(card_id, tag_id);
690
- return createSuccessResponse({ card_id, tag_id }, 'Tag removed from card successfully:');
691
- }
692
- catch (error) {
693
- return createErrorResponse(error, 'removing tag from card');
694
- }
695
- });
696
- }
697
- // ─── Stickers ───────────────────────────────────────────────────────────────
698
- registerAddStickerToCard(server, client) {
699
- server.registerTool('add_sticker_to_card', {
511
+ schema: removeTagFromCardSchema,
512
+ errorContext: 'removing tag from card',
513
+ successMessage: 'Tag removed from card successfully:',
514
+ handler: async ({ card_id, tag_id }) => {
515
+ await client.cards.removeTagFromCard(card_id, tag_id);
516
+ return { card_id, tag_id };
517
+ },
518
+ });
519
+ registerTool(server, {
520
+ name: 'add_sticker_to_card',
700
521
  title: 'Add Sticker to Card',
701
522
  description: 'Add a sticker to a card',
702
- inputSchema: addStickerToCardSchema.shape,
703
- }, async ({ card_id, sticker_id }) => {
704
- try {
705
- const result = await client.addStickerToCard(card_id, sticker_id);
706
- return createSuccessResponse(result, 'Sticker added to card successfully:');
707
- }
708
- catch (error) {
709
- return createErrorResponse(error, 'adding sticker to card');
710
- }
523
+ schema: addStickerToCardSchema,
524
+ errorContext: 'adding sticker to card',
525
+ successMessage: 'Sticker added to card successfully:',
526
+ handler: ({ card_id, sticker_id }) => client.cards.addStickerToCard(card_id, sticker_id),
711
527
  });
712
- }
713
- registerRemoveStickerFromCard(server, client) {
714
- server.registerTool('remove_sticker_from_card', {
528
+ registerTool(server, {
529
+ name: 'remove_sticker_from_card',
715
530
  title: 'Remove Sticker from Card',
716
531
  description: 'Remove a sticker from a card using the sticker-card association ID ' +
717
532
  '(the "id" field returned when listing or adding stickers to a card)',
718
- inputSchema: removeStickerFromCardSchema.shape,
719
- }, async ({ card_id, sticker_card_id }) => {
720
- try {
721
- await client.removeStickerFromCard(card_id, sticker_card_id);
722
- return createSuccessResponse({ card_id, sticker_card_id }, 'Sticker removed from card successfully:');
723
- }
724
- catch (error) {
725
- return createErrorResponse(error, 'removing sticker from card');
726
- }
727
- });
728
- }
729
- // ─── Delete Card ─────────────────────────────────────────────────────────────
730
- registerDeleteCard(server, client) {
731
- server.registerTool('delete_card', {
732
- title: 'Delete Card',
733
- description: 'Permanently delete a card. This action cannot be undone and the card cannot be recovered.',
734
- inputSchema: deleteCardSchema.shape,
735
- }, async ({ card_id }) => {
736
- try {
737
- await client.deleteCard(card_id);
738
- return createSuccessResponse({ card_id }, 'Card deleted successfully:');
739
- }
740
- catch (error) {
741
- return createErrorResponse(error, 'deleting card');
742
- }
743
- });
744
- }
745
- // ─── Predecessors ─────────────────────────────────────────────────────────────
746
- registerAddPredecessor(server, client) {
747
- server.registerTool('add_predecessor', {
748
- title: 'Add Predecessor',
749
- description: 'Establish or update a predecessor-successor relationship between two cards. The predecessor_card_id becomes a prerequisite that must be completed before the card.',
750
- inputSchema: addPredecessorSchema.shape,
751
- }, async ({ card_id, predecessor_card_id, linked_card_position, card_position }) => {
752
- try {
753
- const params = {};
754
- if (linked_card_position !== undefined)
755
- params['linked_card_position'] = linked_card_position;
756
- if (card_position !== undefined)
757
- params['card_position'] = card_position;
758
- await client.addPredecessor(card_id, predecessor_card_id, params);
759
- return createSuccessResponse({ card_id, predecessor_card_id }, 'Predecessor added successfully:');
760
- }
761
- catch (error) {
762
- return createErrorResponse(error, 'adding predecessor');
763
- }
764
- });
765
- }
766
- registerRemovePredecessor(server, client) {
767
- server.registerTool('remove_predecessor', {
768
- title: 'Remove Predecessor',
769
- description: 'Remove the predecessor-successor relationship between two cards.',
770
- inputSchema: removePredecessorSchema.shape,
771
- }, async ({ card_id, predecessor_card_id }) => {
772
- try {
773
- await client.removePredecessor(card_id, predecessor_card_id);
774
- return createSuccessResponse({ card_id, predecessor_card_id }, 'Predecessor removed successfully:');
775
- }
776
- catch (error) {
777
- return createErrorResponse(error, 'removing predecessor');
778
- }
533
+ schema: removeStickerFromCardSchema,
534
+ errorContext: 'removing sticker from card',
535
+ successMessage: 'Sticker removed from card successfully:',
536
+ handler: async ({ card_id, sticker_card_id }) => {
537
+ await client.cards.removeStickerFromCard(card_id, sticker_card_id);
538
+ return { card_id, sticker_card_id };
539
+ },
779
540
  });
780
541
  }
781
542
  }