@edicarlos.lds/businessmap-mcp 3.0.0 → 4.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.
- package/CONTRIBUTING.md +73 -0
- package/README.md +35 -15
- package/SECURITY.md +36 -0
- package/dist/client/businessmap-client.d.ts +0 -1
- package/dist/client/businessmap-client.d.ts.map +1 -1
- package/dist/client/businessmap-client.js +39 -23
- 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 +7 -5
- package/dist/client/modules/card-client.d.ts.map +1 -1
- package/dist/client/modules/card-client.js +40 -13
- package/dist/client/modules/card-client.js.map +1 -1
- package/dist/client/modules/index.d.ts +0 -3
- package/dist/client/modules/index.d.ts.map +1 -1
- package/dist/client/modules/index.js +0 -1
- 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 +64 -3
- package/dist/config/environment.js.map +1 -1
- package/dist/index.d.ts +2 -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/board-schemas.d.ts +6 -6
- package/dist/schemas/board-schemas.d.ts.map +1 -1
- package/dist/schemas/board-schemas.js +6 -2
- package/dist/schemas/board-schemas.js.map +1 -1
- package/dist/schemas/card-schemas.d.ts +67 -48
- package/dist/schemas/card-schemas.d.ts.map +1 -1
- package/dist/schemas/card-schemas.js +23 -0
- package/dist/schemas/card-schemas.js.map +1 -1
- package/dist/schemas/common-schemas.d.ts +4 -4
- 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 +1 -1
- package/dist/server/mcp-server.js.map +1 -1
- package/dist/server/prompts/base-prompt.d.ts +12 -0
- package/dist/server/prompts/base-prompt.d.ts.map +1 -1
- package/dist/server/prompts/base-prompt.js +9 -1
- package/dist/server/prompts/base-prompt.js.map +1 -1
- package/dist/server/prompts/board-prompts.d.ts.map +1 -1
- package/dist/server/prompts/board-prompts.js +6 -5
- package/dist/server/prompts/board-prompts.js.map +1 -1
- package/dist/server/prompts/card-prompts.d.ts.map +1 -1
- package/dist/server/prompts/card-prompts.js +2 -1
- package/dist/server/prompts/card-prompts.js.map +1 -1
- package/dist/server/prompts/index.d.ts +0 -1
- package/dist/server/prompts/index.d.ts.map +1 -1
- package/dist/server/prompts/index.js.map +1 -1
- package/dist/server/prompts/workspace-prompts.d.ts.map +1 -1
- package/dist/server/prompts/workspace-prompts.js +4 -3
- package/dist/server/prompts/workspace-prompts.js.map +1 -1
- package/dist/server/resources/card-resources.d.ts.map +1 -1
- package/dist/server/resources/card-resources.js +45 -3
- package/dist/server/resources/card-resources.js.map +1 -1
- package/dist/server/tools/base-tool.d.ts +5 -0
- package/dist/server/tools/base-tool.d.ts.map +1 -1
- package/dist/server/tools/base-tool.js +89 -6
- package/dist/server/tools/base-tool.js.map +1 -1
- package/dist/server/tools/board-tools.d.ts +0 -6
- package/dist/server/tools/board-tools.d.ts.map +1 -1
- package/dist/server/tools/board-tools.js +35 -72
- package/dist/server/tools/board-tools.js.map +1 -1
- package/dist/server/tools/card-tools.d.ts.map +1 -1
- package/dist/server/tools/card-tools.js +99 -11
- package/dist/server/tools/card-tools.js.map +1 -1
- package/dist/server/tools/doc-tools.d.ts +2 -1
- package/dist/server/tools/doc-tools.d.ts.map +1 -1
- package/dist/server/tools/doc-tools.js +47 -20
- package/dist/server/tools/doc-tools.js.map +1 -1
- package/dist/server/tools/index.d.ts +0 -2
- package/dist/server/tools/index.d.ts.map +1 -1
- package/dist/server/tools/index.js +0 -1
- package/dist/server/tools/index.js.map +1 -1
- package/dist/server/tools/user-tools.d.ts.map +1 -1
- package/dist/server/tools/user-tools.js +2 -1
- package/dist/server/tools/user-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 +10 -5
- package/dist/types/card.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 +116 -96
- package/package.json +22 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-tool.d.ts","sourceRoot":"","sources":["../../../src/server/tools/base-tool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"base-tool.d.ts","sourceRoot":"","sources":["../../../src/server/tools/base-tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAKvE,eAAO,MAAM,eAAe,aA2B1B,CAAC;AAEH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;CAC1F;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM;;;;;;EAUpE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM;;;;;EAWpE;AAED,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5F,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,sCAAsC;AACtC,eAAO,MAAM,SAAS,EAAE,eAA8D,CAAC;AACvF,2DAA2D;AAC3D,eAAO,MAAM,KAAK,EAAE,eAInB,CAAC;AACF,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB,EAAE,eAI9B,CAAC;AACF,qEAAqE;AACrE,eAAO,MAAM,sBAAsB,EAAE,eAIpC,CAAC;AACF,4EAA4E;AAC5E,eAAO,MAAM,WAAW,EAAE,eAIzB,CAAC;AAEF,MAAM,WAAW,cAAc,CAAC,KAAK,SAAS,CAAC,CAAC,WAAW;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC3B,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,cAAc,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC,CAAC;IACtD,6EAA6E;IAC7E,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9E;AAyBD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,SAAS,CAAC,CAAC,WAAW,EACtD,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,cAAc,CAAC,KAAK,CAAC,GACzB,IAAI,CAmEN"}
|
|
@@ -1,3 +1,35 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { config } from '../../config/environment.js';
|
|
3
|
+
import { logger } from '../../utils/logger.js';
|
|
4
|
+
import { getRequestContext, runWithRequestContext } from '../../utils/request-context.js';
|
|
5
|
+
export const ESSENTIAL_TOOLS = new Set([
|
|
6
|
+
'list_workspaces',
|
|
7
|
+
'get_workspace',
|
|
8
|
+
'list_boards',
|
|
9
|
+
'search_board',
|
|
10
|
+
'get_board',
|
|
11
|
+
'get_columns',
|
|
12
|
+
'get_lanes',
|
|
13
|
+
'get_current_board_structure',
|
|
14
|
+
'list_cards',
|
|
15
|
+
'search_cards',
|
|
16
|
+
'get_card',
|
|
17
|
+
'get_card_comments',
|
|
18
|
+
'get_card_subtasks',
|
|
19
|
+
'get_card_parents',
|
|
20
|
+
'get_card_children',
|
|
21
|
+
'create_card',
|
|
22
|
+
'move_card',
|
|
23
|
+
'update_card',
|
|
24
|
+
'create_comment',
|
|
25
|
+
'search_docs',
|
|
26
|
+
'list_docs',
|
|
27
|
+
'get_doc_content_batch',
|
|
28
|
+
'list_users',
|
|
29
|
+
'get_current_user',
|
|
30
|
+
'health_check',
|
|
31
|
+
'get_api_info',
|
|
32
|
+
]);
|
|
1
33
|
/**
|
|
2
34
|
* Standard error handler for tool responses
|
|
3
35
|
*/
|
|
@@ -41,21 +73,56 @@ export const WRITE_IDEMPOTENT = {
|
|
|
41
73
|
destructiveHint: false,
|
|
42
74
|
idempotentHint: true,
|
|
43
75
|
};
|
|
76
|
+
/** Annotations for destructive operations that are safe to repeat */
|
|
77
|
+
export const DESTRUCTIVE_IDEMPOTENT = {
|
|
78
|
+
readOnlyHint: false,
|
|
79
|
+
destructiveHint: true,
|
|
80
|
+
idempotentHint: true,
|
|
81
|
+
};
|
|
82
|
+
/** Annotations for destructive operations that may not be safe to repeat */
|
|
83
|
+
export const DESTRUCTIVE = {
|
|
84
|
+
readOnlyHint: false,
|
|
85
|
+
destructiveHint: true,
|
|
86
|
+
idempotentHint: false,
|
|
87
|
+
};
|
|
44
88
|
function isToolResponse(value) {
|
|
45
89
|
return (value !== null &&
|
|
46
90
|
typeof value === 'object' &&
|
|
47
91
|
'content' in value &&
|
|
48
92
|
Array.isArray(value.content));
|
|
49
93
|
}
|
|
94
|
+
function getAuditIdentifiers(args) {
|
|
95
|
+
return Object.fromEntries(Object.entries(args).filter(([key, value]) => {
|
|
96
|
+
if (!/(?:^|_)ids?$/.test(key)) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
return (typeof value === 'number' ||
|
|
100
|
+
(Array.isArray(value) && value.every((item) => typeof item === 'number')));
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
50
103
|
/**
|
|
51
104
|
* Register a tool with standard try/catch error handling and JSON success formatting.
|
|
52
105
|
* The handler either returns plain data (serialized via createSuccessResponse) or a
|
|
53
106
|
* complete ToolResponse for tools that need custom response shaping.
|
|
54
107
|
*/
|
|
55
108
|
export function registerTool(server, def) {
|
|
56
|
-
|
|
109
|
+
if (config.businessMap.toolProfile === 'essential' && !ESSENTIAL_TOOLS.has(def.name)) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const execute = async (args) => {
|
|
113
|
+
const startedAt = Date.now();
|
|
114
|
+
const isMutation = def.annotations?.readOnlyHint === false;
|
|
57
115
|
try {
|
|
58
116
|
const result = await def.handler(args);
|
|
117
|
+
if (isMutation) {
|
|
118
|
+
logger.info('MCP mutation tool completed', {
|
|
119
|
+
event: 'mcp_tool_mutation',
|
|
120
|
+
tool: def.name,
|
|
121
|
+
outcome: 'success',
|
|
122
|
+
durationMs: Date.now() - startedAt,
|
|
123
|
+
identifiers: getAuditIdentifiers(args),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
59
126
|
if (isToolResponse(result)) {
|
|
60
127
|
return result;
|
|
61
128
|
}
|
|
@@ -63,17 +130,33 @@ export function registerTool(server, def) {
|
|
|
63
130
|
return createSuccessResponse(result, message);
|
|
64
131
|
}
|
|
65
132
|
catch (error) {
|
|
133
|
+
if (isMutation) {
|
|
134
|
+
logger.warn('MCP mutation tool failed', {
|
|
135
|
+
event: 'mcp_tool_mutation',
|
|
136
|
+
tool: def.name,
|
|
137
|
+
outcome: 'error',
|
|
138
|
+
durationMs: Date.now() - startedAt,
|
|
139
|
+
identifiers: getAuditIdentifiers(args),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
66
142
|
return createErrorResponse(error, def.errorContext);
|
|
67
143
|
}
|
|
68
144
|
};
|
|
69
|
-
|
|
145
|
+
const callback = async (args) => {
|
|
146
|
+
if (getRequestContext()) {
|
|
147
|
+
return execute(args);
|
|
148
|
+
}
|
|
149
|
+
return runWithRequestContext({ correlationId: randomUUID() }, () => execute(args));
|
|
150
|
+
};
|
|
151
|
+
// The SDK infers its own callback arg/return types from the raw shape; our callback is
|
|
152
|
+
// structurally compatible (validated args in, ToolResponse out). Calling through a
|
|
153
|
+
// non-generic signature also keeps TS from recursing into the schema generics (TS2589).
|
|
154
|
+
const register = server.registerTool.bind(server);
|
|
155
|
+
register(def.name, {
|
|
70
156
|
title: def.title,
|
|
71
157
|
description: def.description,
|
|
72
158
|
inputSchema: def.schema.shape,
|
|
73
159
|
...(def.annotations && { annotations: def.annotations }),
|
|
74
|
-
},
|
|
75
|
-
// The SDK infers its own callback arg/return types from the raw shape; our callback is
|
|
76
|
-
// structurally compatible (validated args in, ToolResponse out), so bridge the generics here.
|
|
77
|
-
callback);
|
|
160
|
+
}, callback);
|
|
78
161
|
}
|
|
79
162
|
//# sourceMappingURL=base-tool.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-tool.js","sourceRoot":"","sources":["../../../src/server/tools/base-tool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"base-tool.js","sourceRoot":"","sources":["../../../src/server/tools/base-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,11 +3,5 @@ import { BusinessMapClient } from '../../client/businessmap-client.js';
|
|
|
3
3
|
import { BaseToolHandler } from './base-tool.js';
|
|
4
4
|
export declare class BoardToolHandler implements BaseToolHandler {
|
|
5
5
|
registerTools(server: McpServer, client: BusinessMapClient, readOnlyMode: boolean): void;
|
|
6
|
-
private searchBoardById;
|
|
7
|
-
private searchBoardByIdFallback;
|
|
8
|
-
private searchBoardByName;
|
|
9
|
-
private getAllBoards;
|
|
10
|
-
private getBoardWithStructure;
|
|
11
|
-
private formatBoardsList;
|
|
12
6
|
}
|
|
13
7
|
//# sourceMappingURL=board-tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-tools.d.ts","sourceRoot":"","sources":["../../../src/server/tools/board-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAmBvE,OAAO,EACL,eAAe,
|
|
1
|
+
{"version":3,"file":"board-tools.d.ts","sourceRoot":"","sources":["../../../src/server/tools/board-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAmBvE,OAAO,EACL,eAAe,EAMhB,MAAM,gBAAgB,CAAC;AAWxB,qBAAa,gBAAiB,YAAW,eAAe;IACtD,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI;CAsNzF"}
|
|
@@ -1,35 +1,52 @@
|
|
|
1
|
-
import { createBoardSchema, createColumnSchema, createColumnInputSchema, createLaneSchema, deleteColumnSchema, getColumnsSchema, getCurrentBoardStructureSchema, getLanesSchema, getLaneSchema, listBoardsSchema, searchBoardSchema, updateBoardSchema, updateColumnSchema, updateLaneSchema, } from '../../schemas/index.js';
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { createBoardSchema, createColumnSchema, createColumnInputSchema, createLaneSchema, deleteColumnSchema, getBoardSchema, getColumnsSchema, getCurrentBoardStructureSchema, getLanesSchema, getLaneSchema, listBoardsSchema, searchBoardSchema, updateBoardSchema, updateColumnSchema, updateLaneSchema, } from '../../schemas/index.js';
|
|
2
|
+
import { DESTRUCTIVE_IDEMPOTENT, READ_ONLY, WRITE, WRITE_IDEMPOTENT, registerTool, } from './base-tool.js';
|
|
3
|
+
function compactBoard(board) {
|
|
4
|
+
return {
|
|
5
|
+
board_id: board.board_id,
|
|
6
|
+
workspace_id: board.workspace_id,
|
|
7
|
+
name: board.name,
|
|
8
|
+
is_archived: board.is_archived,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
4
11
|
export class BoardToolHandler {
|
|
5
12
|
registerTools(server, client, readOnlyMode) {
|
|
6
13
|
registerTool(server, {
|
|
7
14
|
name: 'list_boards',
|
|
8
15
|
title: 'List Boards',
|
|
9
|
-
description: '
|
|
16
|
+
description: 'Discover boards with optional filters. Returns compact candidates by default; use get_board with a returned board_id for details.',
|
|
10
17
|
schema: listBoardsSchema,
|
|
11
18
|
annotations: READ_ONLY,
|
|
12
19
|
errorContext: 'fetching boards',
|
|
13
|
-
handler: (params) =>
|
|
20
|
+
handler: async ({ detail_level, ...params }) => {
|
|
21
|
+
const boards = await client.boards.getBoards(params);
|
|
22
|
+
return detail_level === 'full' ? boards : boards.map(compactBoard);
|
|
23
|
+
},
|
|
14
24
|
});
|
|
15
25
|
registerTool(server, {
|
|
16
26
|
name: 'search_board',
|
|
17
27
|
title: 'Search Board',
|
|
18
|
-
description: '
|
|
28
|
+
description: 'Find compact board candidates by name fragment, then use get_board with a returned board_id. If the board_id is already known, call get_board directly.',
|
|
19
29
|
schema: searchBoardSchema,
|
|
20
30
|
annotations: READ_ONLY,
|
|
21
31
|
errorContext: 'searching for board',
|
|
22
|
-
handler: async ({
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
// If neither ID nor name provided, list all boards
|
|
30
|
-
return this.getAllBoards(client, workspace_id);
|
|
32
|
+
handler: async ({ board_name, workspace_id }) => {
|
|
33
|
+
const boards = await client.boards.getBoards(workspace_id !== undefined ? { workspace_id } : undefined);
|
|
34
|
+
const query = board_name.toLowerCase();
|
|
35
|
+
const matches = boards
|
|
36
|
+
.filter((board) => board.name.toLowerCase().includes(query))
|
|
37
|
+
.map(compactBoard);
|
|
38
|
+
return { matches, count: matches.length };
|
|
31
39
|
},
|
|
32
40
|
});
|
|
41
|
+
registerTool(server, {
|
|
42
|
+
name: 'get_board',
|
|
43
|
+
title: 'Get Board',
|
|
44
|
+
description: 'Inspect a board selected by board_id. Returns board details without its structure; use get_current_board_structure only when workflows, columns and lanes are needed.',
|
|
45
|
+
schema: getBoardSchema,
|
|
46
|
+
annotations: READ_ONLY,
|
|
47
|
+
errorContext: 'fetching board',
|
|
48
|
+
handler: ({ board_id }) => client.boards.getBoard(board_id),
|
|
49
|
+
});
|
|
33
50
|
registerTool(server, {
|
|
34
51
|
name: 'get_columns',
|
|
35
52
|
title: 'Get Board Columns',
|
|
@@ -129,6 +146,7 @@ export class BoardToolHandler {
|
|
|
129
146
|
title: 'Create Column',
|
|
130
147
|
description: 'Create a new column on a board. Supports both main columns (requires workflow_id and section) and sub-columns (requires parent_column_id). Section values: 1=Backlog, 2=Requested, 3=Progress, 4=Done.',
|
|
131
148
|
schema: createColumnInputSchema,
|
|
149
|
+
annotations: WRITE,
|
|
132
150
|
errorContext: 'creating column',
|
|
133
151
|
successMessage: 'Column created successfully:',
|
|
134
152
|
handler: (params) => {
|
|
@@ -149,6 +167,7 @@ export class BoardToolHandler {
|
|
|
149
167
|
title: 'Update Column',
|
|
150
168
|
description: 'Update the details of a specific column on a board',
|
|
151
169
|
schema: updateColumnSchema,
|
|
170
|
+
annotations: WRITE_IDEMPOTENT,
|
|
152
171
|
errorContext: 'updating column',
|
|
153
172
|
successMessage: 'Column updated successfully:',
|
|
154
173
|
handler: ({ board_id, column_id, name, limit, section, position, description }) => client.boards.updateColumn(board_id, column_id, {
|
|
@@ -164,6 +183,7 @@ export class BoardToolHandler {
|
|
|
164
183
|
title: 'Delete Column',
|
|
165
184
|
description: 'Delete a column from a board',
|
|
166
185
|
schema: deleteColumnSchema,
|
|
186
|
+
annotations: DESTRUCTIVE_IDEMPOTENT,
|
|
167
187
|
errorContext: 'deleting column',
|
|
168
188
|
successMessage: 'Column deleted successfully:',
|
|
169
189
|
handler: async ({ board_id, column_id }) => {
|
|
@@ -173,62 +193,5 @@ export class BoardToolHandler {
|
|
|
173
193
|
});
|
|
174
194
|
}
|
|
175
195
|
}
|
|
176
|
-
async searchBoardById(client, boardId, workspaceId) {
|
|
177
|
-
try {
|
|
178
|
-
const [board, structure] = await Promise.all([
|
|
179
|
-
client.boards.getBoard(boardId),
|
|
180
|
-
client.boards.getBoardStructure(boardId),
|
|
181
|
-
]);
|
|
182
|
-
return createSuccessResponse({ ...board, structure }, 'Board found directly:');
|
|
183
|
-
}
|
|
184
|
-
catch (directError) {
|
|
185
|
-
logger.warn(`Direct board lookup failed for ID ${boardId}: ${directError instanceof Error ? directError.message : 'Unknown error'}`);
|
|
186
|
-
return await this.searchBoardByIdFallback(client, boardId, workspaceId);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
async searchBoardByIdFallback(client, boardId, workspaceId) {
|
|
190
|
-
const boards = await client.boards.getBoards(workspaceId ? { workspace_id: workspaceId } : undefined);
|
|
191
|
-
const foundBoard = boards.find((b) => b.board_id === boardId);
|
|
192
|
-
if (!foundBoard) {
|
|
193
|
-
return createErrorResponse(new Error(`Board with ID ${boardId} not found. Available boards:\n${JSON.stringify(this.formatBoardsList(boards), null, 2)}`), 'searching for board');
|
|
194
|
-
}
|
|
195
|
-
return await this.getBoardWithStructure(client, foundBoard, 'Board found via list search:');
|
|
196
|
-
}
|
|
197
|
-
async searchBoardByName(client, boardName, workspaceId) {
|
|
198
|
-
const boards = await client.boards.getBoards(workspaceId ? { workspace_id: workspaceId } : undefined);
|
|
199
|
-
const foundBoards = boards.filter((b) => b.name.toLowerCase().includes(boardName.toLowerCase()));
|
|
200
|
-
if (foundBoards.length === 0) {
|
|
201
|
-
return createErrorResponse(new Error(`No boards found matching name "${boardName}". Available boards:\n${JSON.stringify(this.formatBoardsList(boards), null, 2)}`), 'searching for board by name');
|
|
202
|
-
}
|
|
203
|
-
if (foundBoards.length === 1) {
|
|
204
|
-
const foundBoard = foundBoards[0];
|
|
205
|
-
if (!foundBoard.board_id) {
|
|
206
|
-
return createErrorResponse(new Error('Board missing board_id'), 'board validation');
|
|
207
|
-
}
|
|
208
|
-
return await this.getBoardWithStructure(client, foundBoard, 'Board found by name:');
|
|
209
|
-
}
|
|
210
|
-
return createSuccessResponse(this.formatBoardsList(foundBoards), `Multiple boards found matching "${boardName}":`);
|
|
211
|
-
}
|
|
212
|
-
async getAllBoards(client, workspaceId) {
|
|
213
|
-
const boards = await client.boards.getBoards(workspaceId ? { workspace_id: workspaceId } : undefined);
|
|
214
|
-
return createSuccessResponse(this.formatBoardsList(boards), 'All available boards:');
|
|
215
|
-
}
|
|
216
|
-
async getBoardWithStructure(client, board, successMessage) {
|
|
217
|
-
try {
|
|
218
|
-
const structure = await client.boards.getBoardStructure(board.board_id);
|
|
219
|
-
return createSuccessResponse({ ...board, structure }, successMessage);
|
|
220
|
-
}
|
|
221
|
-
catch (structureError) {
|
|
222
|
-
logger.warn(`Structure lookup failed for board ID ${board.board_id}: ${structureError instanceof Error ? structureError.message : 'Unknown error'}`);
|
|
223
|
-
return createSuccessResponse(board, `Board found but structure unavailable. Structure error: ${structureError instanceof Error ? structureError.message : 'Unknown error'}`);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
formatBoardsList(boards) {
|
|
227
|
-
return boards.map((b) => ({
|
|
228
|
-
board_id: b.board_id,
|
|
229
|
-
name: b.name,
|
|
230
|
-
workspace_id: b.workspace_id,
|
|
231
|
-
}));
|
|
232
|
-
}
|
|
233
196
|
}
|
|
234
197
|
//# sourceMappingURL=board-tools.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-tools.js","sourceRoot":"","sources":["../../../src/server/tools/board-tools.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,8BAA8B,EAC9B,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,
|
|
1
|
+
{"version":3,"file":"board-tools.js","sourceRoot":"","sources":["../../../src/server/tools/board-tools.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,8BAA8B,EAC9B,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEL,sBAAsB,EACtB,SAAS,EACT,KAAK,EACL,gBAAgB,EAChB,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,SAAS,YAAY,CAAC,KAAY;IAChC,OAAO;QACL,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,WAAW,EAAE,KAAK,CAAC,WAAW;KAC/B,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,gBAAgB;IAC3B,aAAa,CAAC,MAAiB,EAAE,MAAyB,EAAE,YAAqB;QAC/E,YAAY,CAAC,MAAM,EAAE;YACnB,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,aAAa;YACpB,WAAW,EACT,mIAAmI;YACrI,MAAM,EAAE,gBAAgB;YACxB,WAAW,EAAE,SAAS;YACtB,YAAY,EAAE,iBAAiB;YAC/B,OAAO,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE;gBAC7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBACrD,OAAO,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YACrE,CAAC;SACF,CAAC,CAAC;QAEH,YAAY,CAAC,MAAM,EAAE;YACnB,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,cAAc;YACrB,WAAW,EACT,yJAAyJ;YAC3J,MAAM,EAAE,iBAAiB;YACzB,WAAW,EAAE,SAAS;YACtB,YAAY,EAAE,qBAAqB;YACnC,OAAO,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE,EAAE;gBAC9C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAC1C,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,SAAS,CAC1D,CAAC;gBACF,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;gBACvC,MAAM,OAAO,GAAG,MAAM;qBACnB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;qBAC3D,GAAG,CAAC,YAAY,CAAC,CAAC;gBACrB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;YAC5C,CAAC;SACF,CAAC,CAAC;QAEH,YAAY,CAAC,MAAM,EAAE;YACnB,IAAI,EAAE,WAAW;YACjB,KAAK,EAAE,WAAW;YAClB,WAAW,EACT,uKAAuK;YACzK,MAAM,EAAE,cAAc;YACtB,WAAW,EAAE,SAAS;YACtB,YAAY,EAAE,gBAAgB;YAC9B,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;SAC5D,CAAC,CAAC;QAEH,YAAY,CAAC,MAAM,EAAE;YACnB,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,mBAAmB;YAC1B,WAAW,EAAE,6BAA6B;YAC1C,MAAM,EAAE,gBAAgB;YACxB,WAAW,EAAE,SAAS;YACtB,YAAY,EAAE,wBAAwB;YACtC,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;SAC9D,CAAC,CAAC;QAEH,YAAY,CAAC,MAAM,EAAE;YACnB,IAAI,EAAE,WAAW;YACjB,KAAK,EAAE,iBAAiB;YACxB,WAAW,EAAE,qCAAqC;YAClD,MAAM,EAAE,cAAc;YACtB,WAAW,EAAE,SAAS;YACtB,YAAY,EAAE,sBAAsB;YACpC,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;SAC5D,CAAC,CAAC;QAEH,YAAY,CAAC,MAAM,EAAE;YACnB,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,kBAAkB;YACzB,WAAW,EAAE,yCAAyC;YACtD,MAAM,EAAE,aAAa;YACrB,WAAW,EAAE,SAAS;YACtB,YAAY,EAAE,uBAAuB;YACrC,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC;SAC7E,CAAC,CAAC;QAEH,YAAY,CAAC,MAAM,EAAE;YACnB,IAAI,EAAE,6BAA6B;YACnC,KAAK,EAAE,6BAA6B;YACpC,WAAW,EACT,uGAAuG;YACzG,MAAM,EAAE,8BAA8B;YACtC,WAAW,EAAE,SAAS;YACtB,YAAY,EAAE,iCAAiC;YAC/C,cAAc,EAAE,yCAAyC;YACzD,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,wBAAwB,CAAC,QAAQ,CAAC;SAC5E,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,YAAY,CAAC,MAAM,EAAE;gBACnB,IAAI,EAAE,cAAc;gBACpB,KAAK,EAAE,cAAc;gBACrB,WAAW,EAAE,mCAAmC;gBAChD,MAAM,EAAE,iBAAiB;gBACzB,WAAW,EAAE,KAAK;gBAClB,YAAY,EAAE,gBAAgB;gBAC9B,cAAc,EAAE,6BAA6B;gBAC7C,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,EAAE,CAC/C,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;aACjE,CAAC,CAAC;YAEH,YAAY,CAAC,MAAM,EAAE;gBACnB,IAAI,EAAE,cAAc;gBACpB,KAAK,EAAE,cAAc;gBACrB,WAAW,EAAE,yDAAyD;gBACtE,MAAM,EAAE,iBAAiB;gBACzB,WAAW,EAAE,gBAAgB;gBAC7B,YAAY,EAAE,gBAAgB;gBAC9B,cAAc,EAAE,6BAA6B;gBAC7C,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,CAC3C,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE;oBAClC,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,CAAC;oBACnC,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,CAAC;iBAClD,CAAC;aACL,CAAC,CAAC;YAEH,YAAY,CAAC,MAAM,EAAE;gBACnB,IAAI,EAAE,aAAa;gBACnB,KAAK,EAAE,aAAa;gBACpB,WAAW,EAAE,uCAAuC;gBACpD,MAAM,EAAE,gBAAgB;gBACxB,WAAW,EAAE,KAAK;gBAClB,YAAY,EAAE,eAAe;gBAC7B,cAAc,EAAE,4BAA4B;gBAC5C,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,EAAE,CACzF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE;oBACjC,WAAW;oBACX,IAAI;oBACJ,WAAW,EAAE,WAAW,IAAI,IAAI;oBAChC,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC;oBACrC,QAAQ;oBACR,GAAG,CAAC,cAAc,KAAK,SAAS,IAAI,EAAE,cAAc,EAAE,CAAC;iBACxD,CAAC;aACL,CAAC,CAAC;YAEH,YAAY,CAAC,MAAM,EAAE;gBACnB,IAAI,EAAE,aAAa;gBACnB,KAAK,EAAE,aAAa;gBACpB,WAAW,EACT,sFAAsF;gBACxF,MAAM,EAAE,gBAAgB;gBACxB,WAAW,EAAE,gBAAgB;gBAC7B,YAAY,EAAE,eAAe;gBAC7B,cAAc,EAAE,4BAA4B;gBAC5C,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,EAAE,CACrF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE;oBAC1C,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,CAAC;oBACnC,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,CAAC;oBACjD,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC;oBACrC,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,CAAC;oBAC3C,GAAG,CAAC,cAAc,KAAK,SAAS,IAAI,EAAE,cAAc,EAAE,CAAC;iBACxD,CAAC;aACL,CAAC,CAAC;YAEH,YAAY,CAAC,MAAM,EAAE;gBACnB,IAAI,EAAE,eAAe;gBACrB,KAAK,EAAE,eAAe;gBACtB,WAAW,EACT,wMAAwM;gBAC1M,MAAM,EAAE,uBAAuB;gBAC/B,WAAW,EAAE,KAAK;gBAClB,YAAY,EAAE,iBAAiB;gBAC/B,cAAc,EAAE,8BAA8B;gBAC9C,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;oBAClB,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,GAC5F,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBACnC,MAAM,YAAY,GAAG;wBACnB,QAAQ;wBACR,IAAI;wBACJ,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC;wBACrC,GAAG,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,CAAC;qBACpC,CAAC;oBACF,OAAO,MAAM,CAAC,MAAM,CAAC,YAAY,CAC/B,QAAQ,EACR,gBAAgB;wBACd,CAAC,CAAC,EAAE,gBAAgB,EAAE,GAAG,YAAY,EAAE;wBACvC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,CAC9C,CAAC;gBACJ,CAAC;aACF,CAAC,CAAC;YAEH,YAAY,CAAC,MAAM,EAAE;gBACnB,IAAI,EAAE,eAAe;gBACrB,KAAK,EAAE,eAAe;gBACtB,WAAW,EAAE,oDAAoD;gBACjE,MAAM,EAAE,kBAAkB;gBAC1B,WAAW,EAAE,gBAAgB;gBAC7B,YAAY,EAAE,iBAAiB;gBAC/B,cAAc,EAAE,8BAA8B;gBAC9C,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE,CAChF,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,SAAS,EAAE;oBAC9C,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,CAAC;oBACnC,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC;oBACrC,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,CAAC;oBACzC,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,CAAC;oBAC3C,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,CAAC;iBAClD,CAAC;aACL,CAAC,CAAC;YAEH,YAAY,CAAC,MAAM,EAAE;gBACnB,IAAI,EAAE,eAAe;gBACrB,KAAK,EAAE,eAAe;gBACtB,WAAW,EAAE,8BAA8B;gBAC3C,MAAM,EAAE,kBAAkB;gBAC1B,WAAW,EAAE,sBAAsB;gBACnC,YAAY,EAAE,iBAAiB;gBAC/B,cAAc,EAAE,8BAA8B;gBAC9C,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE;oBACzC,MAAM,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;oBACtD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;gBACjC,CAAC;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card-tools.d.ts","sourceRoot":"","sources":["../../../src/server/tools/card-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"card-tools.d.ts","sourceRoot":"","sources":["../../../src/server/tools/card-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AA+CvE,OAAO,EACL,eAAe,EAOhB,MAAM,gBAAgB,CAAC;AA+DxB,qBAAa,eAAgB,YAAW,eAAe;IACrD,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI;IAYxF,OAAO,CAAC,iBAAiB;IAuTzB,OAAO,CAAC,sBAAsB;IAmG9B,OAAO,CAAC,yBAAyB;IAwCjC,OAAO,CAAC,8BAA8B;IA2DtC,OAAO,CAAC,yBAAyB;IAuCjC,OAAO,CAAC,4BAA4B;CAmErC"}
|
|
@@ -1,5 +1,63 @@
|
|
|
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';
|
|
1
|
+
import { addCardParentSchema, addPredecessorSchema, addStickerToCardSchema, addTagToCardSchema, blockCardSchema, cardCommentsSchema, cardSizeSchema, createCardSchema, createCardSubtaskSchema, createCommentSchema, createTagSchema, deleteCardSchema, deleteCardSubtaskSchema, deleteCommentSchema, getCardBlockedTimesSchema, getCardChildGraphSchema, getCardChildrenSchema, getCardCommentSchema, getCardDetailSchema, 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 boundedText(value, maxLength = 2000) {
|
|
20
|
+
if (!value || value.length <= maxLength)
|
|
21
|
+
return value;
|
|
22
|
+
return `${value.slice(0, maxLength)}…`;
|
|
23
|
+
}
|
|
24
|
+
function summarizeCard(card) {
|
|
25
|
+
return {
|
|
26
|
+
...compactCard(card),
|
|
27
|
+
workflow_id: card.workflow_id,
|
|
28
|
+
section: card.section,
|
|
29
|
+
description: boundedText(card.description),
|
|
30
|
+
description_truncated: (card.description?.length ?? 0) > 2000,
|
|
31
|
+
created_at: card.created_at,
|
|
32
|
+
last_modified: card.last_modified,
|
|
33
|
+
in_current_position_since: card.in_current_position_since,
|
|
34
|
+
current_cycle_time: card.current_cycle_time,
|
|
35
|
+
related_counts: {
|
|
36
|
+
attachments: card.attachments?.length ?? 0,
|
|
37
|
+
custom_fields: card.custom_fields?.length ?? 0,
|
|
38
|
+
subtasks: card.subtasks?.length ?? 0,
|
|
39
|
+
linked_cards: card.linked_cards?.length ?? 0,
|
|
40
|
+
outcomes: card.outcomes?.length ?? 0,
|
|
41
|
+
},
|
|
42
|
+
next_tools: [
|
|
43
|
+
'get_card_comments',
|
|
44
|
+
'get_card_subtasks',
|
|
45
|
+
'get_card_parents',
|
|
46
|
+
'get_card_children',
|
|
47
|
+
],
|
|
48
|
+
full_profile_tools: [
|
|
49
|
+
'get_card_flow_history',
|
|
50
|
+
'get_card_blocked_times',
|
|
51
|
+
'get_card_revisions',
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function compactCardResult(result) {
|
|
56
|
+
if (Array.isArray(result)) {
|
|
57
|
+
return result.map(compactCard);
|
|
58
|
+
}
|
|
59
|
+
return { ...result, data: result.data.map(compactCard) };
|
|
60
|
+
}
|
|
3
61
|
export class CardToolHandler {
|
|
4
62
|
registerTools(server, client, readOnlyMode) {
|
|
5
63
|
this.registerReadTools(server, client);
|
|
@@ -15,29 +73,46 @@ export class CardToolHandler {
|
|
|
15
73
|
registerTool(server, {
|
|
16
74
|
name: 'list_cards',
|
|
17
75
|
title: 'List Cards',
|
|
18
|
-
description: '
|
|
76
|
+
description: 'Discover cards on one board. Returns a compact, paginated page by default; use get_card with a returned card_id for detail.',
|
|
19
77
|
schema: listCardsSchema,
|
|
20
78
|
annotations: READ_ONLY,
|
|
21
79
|
errorContext: 'fetching cards',
|
|
22
|
-
handler: ({ board_id, ...filters }) =>
|
|
80
|
+
handler: async ({ board_id, include_pagination, compact, ...filters }) => {
|
|
81
|
+
const shouldPaginate = include_pagination ?? true;
|
|
82
|
+
const shouldCompact = compact ?? true;
|
|
83
|
+
const boundedFilters = { ...filters, per_page: filters.per_page ?? 50 };
|
|
84
|
+
const result = shouldPaginate
|
|
85
|
+
? await client.cards.getCardsPage(board_id, boundedFilters)
|
|
86
|
+
: await client.cards.getCards(board_id, boundedFilters);
|
|
87
|
+
return shouldCompact ? compactCardResult(result) : result;
|
|
88
|
+
},
|
|
23
89
|
});
|
|
24
90
|
registerTool(server, {
|
|
25
91
|
name: 'search_cards',
|
|
26
92
|
title: 'Search Cards',
|
|
27
|
-
description: '
|
|
93
|
+
description: 'Discover cards across boards using advanced filters. Returns compact results by default; use get_card with a returned card_id for detail.',
|
|
28
94
|
schema: searchCardsSchema,
|
|
29
95
|
annotations: READ_ONLY,
|
|
30
96
|
errorContext: 'searching cards',
|
|
31
|
-
handler: (params) =>
|
|
97
|
+
handler: async ({ compact, ...params }) => {
|
|
98
|
+
const result = await client.cards.searchCards({
|
|
99
|
+
...params,
|
|
100
|
+
per_page: params.per_page ?? 50,
|
|
101
|
+
});
|
|
102
|
+
return (compact ?? true) ? compactCardResult(result) : result;
|
|
103
|
+
},
|
|
32
104
|
});
|
|
33
105
|
registerTool(server, {
|
|
34
106
|
name: 'get_card',
|
|
35
107
|
title: 'Get Card',
|
|
36
|
-
description: '
|
|
37
|
-
schema:
|
|
108
|
+
description: 'Inspect a card selected by card_id. Returns a useful summary and related-item counts by default; set detail_level=full only when the complete payload is required.',
|
|
109
|
+
schema: getCardDetailSchema,
|
|
38
110
|
annotations: READ_ONLY,
|
|
39
111
|
errorContext: 'fetching card',
|
|
40
|
-
handler: ({ card_id }) =>
|
|
112
|
+
handler: async ({ card_id, detail_level }) => {
|
|
113
|
+
const card = await client.cards.getCard(card_id);
|
|
114
|
+
return detail_level === 'full' ? card : summarizeCard(card);
|
|
115
|
+
},
|
|
41
116
|
});
|
|
42
117
|
registerTool(server, {
|
|
43
118
|
name: 'get_card_size',
|
|
@@ -331,6 +406,7 @@ export class CardToolHandler {
|
|
|
331
406
|
title: 'Delete Card',
|
|
332
407
|
description: 'Permanently delete a card. This action cannot be undone and the card cannot be recovered.',
|
|
333
408
|
schema: deleteCardSchema,
|
|
409
|
+
annotations: DESTRUCTIVE_IDEMPOTENT,
|
|
334
410
|
errorContext: 'deleting card',
|
|
335
411
|
successMessage: 'Card deleted successfully:',
|
|
336
412
|
handler: async ({ card_id }) => {
|
|
@@ -343,6 +419,7 @@ export class CardToolHandler {
|
|
|
343
419
|
title: 'Block Card',
|
|
344
420
|
description: 'Block a card and set a reason/comment explaining why it is blocked',
|
|
345
421
|
schema: blockCardSchema,
|
|
422
|
+
annotations: WRITE_IDEMPOTENT,
|
|
346
423
|
errorContext: 'blocking card',
|
|
347
424
|
successMessage: 'Card blocked successfully:',
|
|
348
425
|
handler: async ({ card_id, reason }) => {
|
|
@@ -355,6 +432,7 @@ export class CardToolHandler {
|
|
|
355
432
|
title: 'Unblock Card',
|
|
356
433
|
description: 'Unblock a card by removing its block reason',
|
|
357
434
|
schema: unblockCardSchema,
|
|
435
|
+
annotations: WRITE_IDEMPOTENT,
|
|
358
436
|
errorContext: 'unblocking card',
|
|
359
437
|
successMessage: 'Card unblocked successfully:',
|
|
360
438
|
handler: async ({ card_id }) => {
|
|
@@ -389,7 +467,7 @@ export class CardToolHandler {
|
|
|
389
467
|
title: 'Delete Card Subtask',
|
|
390
468
|
description: 'Delete a subtask from a card',
|
|
391
469
|
schema: deleteCardSubtaskSchema,
|
|
392
|
-
annotations:
|
|
470
|
+
annotations: DESTRUCTIVE_IDEMPOTENT,
|
|
393
471
|
errorContext: 'deleting card subtask',
|
|
394
472
|
successMessage: 'Subtask deleted successfully:',
|
|
395
473
|
handler: async ({ card_id, subtask_id }) => {
|
|
@@ -414,7 +492,7 @@ export class CardToolHandler {
|
|
|
414
492
|
title: 'Remove Card Parent',
|
|
415
493
|
description: 'Remove the link between a child card and a parent card',
|
|
416
494
|
schema: removeCardParentSchema,
|
|
417
|
-
annotations:
|
|
495
|
+
annotations: DESTRUCTIVE,
|
|
418
496
|
errorContext: 'removing card parent',
|
|
419
497
|
successMessage: 'Card parent removed successfully:',
|
|
420
498
|
handler: async ({ card_id, parent_card_id }) => {
|
|
@@ -427,6 +505,7 @@ export class CardToolHandler {
|
|
|
427
505
|
title: 'Add Predecessor',
|
|
428
506
|
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
507
|
schema: addPredecessorSchema,
|
|
508
|
+
annotations: WRITE_IDEMPOTENT,
|
|
430
509
|
errorContext: 'adding predecessor',
|
|
431
510
|
successMessage: 'Predecessor added successfully:',
|
|
432
511
|
handler: async ({ card_id, predecessor_card_id, linked_card_position, card_position }) => {
|
|
@@ -442,6 +521,7 @@ export class CardToolHandler {
|
|
|
442
521
|
title: 'Remove Predecessor',
|
|
443
522
|
description: 'Remove the predecessor-successor relationship between two cards.',
|
|
444
523
|
schema: removePredecessorSchema,
|
|
524
|
+
annotations: DESTRUCTIVE_IDEMPOTENT,
|
|
445
525
|
errorContext: 'removing predecessor',
|
|
446
526
|
successMessage: 'Predecessor removed successfully:',
|
|
447
527
|
handler: async ({ card_id, predecessor_card_id }) => {
|
|
@@ -456,6 +536,7 @@ export class CardToolHandler {
|
|
|
456
536
|
title: 'Create Comment',
|
|
457
537
|
description: 'Add a new comment to a card',
|
|
458
538
|
schema: createCommentSchema,
|
|
539
|
+
annotations: WRITE,
|
|
459
540
|
errorContext: 'creating comment',
|
|
460
541
|
successMessage: 'Comment created successfully:',
|
|
461
542
|
handler: ({ card_id, text }) => client.cards.createCardComment(card_id, { text }),
|
|
@@ -465,6 +546,7 @@ export class CardToolHandler {
|
|
|
465
546
|
title: 'Update Comment',
|
|
466
547
|
description: 'Update the text of an existing comment on a card',
|
|
467
548
|
schema: updateCommentSchema,
|
|
549
|
+
annotations: WRITE_IDEMPOTENT,
|
|
468
550
|
errorContext: 'updating comment',
|
|
469
551
|
successMessage: 'Comment updated successfully:',
|
|
470
552
|
handler: ({ card_id, comment_id, text }) => client.cards.updateCardComment(card_id, comment_id, { text }),
|
|
@@ -474,6 +556,7 @@ export class CardToolHandler {
|
|
|
474
556
|
title: 'Delete Comment',
|
|
475
557
|
description: 'Delete a comment from a card',
|
|
476
558
|
schema: deleteCommentSchema,
|
|
559
|
+
annotations: DESTRUCTIVE_IDEMPOTENT,
|
|
477
560
|
errorContext: 'deleting comment',
|
|
478
561
|
successMessage: 'Comment deleted successfully:',
|
|
479
562
|
handler: async ({ card_id, comment_id }) => {
|
|
@@ -488,6 +571,7 @@ export class CardToolHandler {
|
|
|
488
571
|
title: 'Create Tag',
|
|
489
572
|
description: 'Create a new tag in the workspace',
|
|
490
573
|
schema: createTagSchema,
|
|
574
|
+
annotations: WRITE,
|
|
491
575
|
errorContext: 'creating tag',
|
|
492
576
|
successMessage: 'Tag created successfully:',
|
|
493
577
|
handler: ({ label, color }) => client.cards.createTag({ label, color }),
|
|
@@ -497,6 +581,7 @@ export class CardToolHandler {
|
|
|
497
581
|
title: 'Add Tag to Card',
|
|
498
582
|
description: 'Add an existing tag to a card',
|
|
499
583
|
schema: addTagToCardSchema,
|
|
584
|
+
annotations: WRITE_IDEMPOTENT,
|
|
500
585
|
errorContext: 'adding tag to card',
|
|
501
586
|
successMessage: 'Tag added to card successfully:',
|
|
502
587
|
handler: async ({ card_id, tag_id }) => {
|
|
@@ -509,6 +594,7 @@ export class CardToolHandler {
|
|
|
509
594
|
title: 'Remove Tag from Card',
|
|
510
595
|
description: 'Remove a tag from a card',
|
|
511
596
|
schema: removeTagFromCardSchema,
|
|
597
|
+
annotations: DESTRUCTIVE_IDEMPOTENT,
|
|
512
598
|
errorContext: 'removing tag from card',
|
|
513
599
|
successMessage: 'Tag removed from card successfully:',
|
|
514
600
|
handler: async ({ card_id, tag_id }) => {
|
|
@@ -521,6 +607,7 @@ export class CardToolHandler {
|
|
|
521
607
|
title: 'Add Sticker to Card',
|
|
522
608
|
description: 'Add a sticker to a card',
|
|
523
609
|
schema: addStickerToCardSchema,
|
|
610
|
+
annotations: WRITE,
|
|
524
611
|
errorContext: 'adding sticker to card',
|
|
525
612
|
successMessage: 'Sticker added to card successfully:',
|
|
526
613
|
handler: ({ card_id, sticker_id }) => client.cards.addStickerToCard(card_id, sticker_id),
|
|
@@ -531,6 +618,7 @@ export class CardToolHandler {
|
|
|
531
618
|
description: 'Remove a sticker from a card using the sticker-card association ID ' +
|
|
532
619
|
'(the "id" field returned when listing or adding stickers to a card)',
|
|
533
620
|
schema: removeStickerFromCardSchema,
|
|
621
|
+
annotations: DESTRUCTIVE_IDEMPOTENT,
|
|
534
622
|
errorContext: 'removing sticker from card',
|
|
535
623
|
successMessage: 'Sticker removed from card successfully:',
|
|
536
624
|
handler: async ({ card_id, sticker_card_id }) => {
|