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