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