@hauptsache.net/clickup-mcp 1.3.2 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +72 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/resources/space-resources.d.ts +6 -0
- package/dist/resources/space-resources.d.ts.map +1 -0
- package/dist/resources/space-resources.js +94 -0
- package/dist/shared/utils.d.ts +5 -0
- package/dist/shared/utils.d.ts.map +1 -1
- package/dist/shared/utils.js +70 -0
- package/dist/tools/space-tools.d.ts.map +1 -1
- package/dist/tools/space-tools.js +3 -63
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -13,9 +13,81 @@ async function main() {
|
|
|
13
13
|
console.log(server.server._instructions || "No instructions configured");
|
|
14
14
|
process.exit(0);
|
|
15
15
|
}
|
|
16
|
+
// Special commands for testing resources
|
|
17
|
+
if (args.length === 1 && args[0] === 'resources') {
|
|
18
|
+
console.log("Listing available resources...");
|
|
19
|
+
try {
|
|
20
|
+
// @ts-ignore - Accessing private property for testing purposes
|
|
21
|
+
const resourceTemplates = server._registeredResourceTemplates;
|
|
22
|
+
if (resourceTemplates && Object.keys(resourceTemplates).length > 0) {
|
|
23
|
+
for (const [name, template] of Object.entries(resourceTemplates)) {
|
|
24
|
+
console.log(`Resource template: ${name}`);
|
|
25
|
+
// @ts-ignore - Access template properties
|
|
26
|
+
const uriTemplate = template.resourceTemplate.uriTemplate;
|
|
27
|
+
console.log(` URI Template: ${uriTemplate}`);
|
|
28
|
+
// Test the list callback if available
|
|
29
|
+
// @ts-ignore - Access template properties
|
|
30
|
+
if (template.resourceTemplate._callbacks.list) {
|
|
31
|
+
try {
|
|
32
|
+
// @ts-ignore - Call list callback
|
|
33
|
+
const result = await template.resourceTemplate._callbacks.list();
|
|
34
|
+
console.log(` Resources found: ${result.resources.length}`);
|
|
35
|
+
result.resources.slice(0, 3).forEach((res, idx) => {
|
|
36
|
+
console.log(` ${idx + 1}. ${res.name} (${res.uri})`);
|
|
37
|
+
});
|
|
38
|
+
if (result.resources.length > 3) {
|
|
39
|
+
console.log(` ... and ${result.resources.length - 3} more`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
console.log(` Error listing resources: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
console.log("");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
console.log("No resource templates registered.");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.error("Error accessing resources:", error instanceof Error ? error.message : 'Unknown error');
|
|
55
|
+
}
|
|
56
|
+
process.exit(0);
|
|
57
|
+
}
|
|
58
|
+
// Special command to read a specific resource
|
|
59
|
+
if (args.length === 2 && args[0] === 'resource') {
|
|
60
|
+
const resourceUri = args[1];
|
|
61
|
+
console.log(`Reading resource: ${resourceUri}`);
|
|
62
|
+
try {
|
|
63
|
+
// @ts-ignore - Accessing private property for testing purposes
|
|
64
|
+
const resourceTemplates = server._registeredResourceTemplates;
|
|
65
|
+
// Find matching template and call read callback
|
|
66
|
+
for (const [name, template] of Object.entries(resourceTemplates)) {
|
|
67
|
+
try {
|
|
68
|
+
// @ts-ignore - Access template properties
|
|
69
|
+
const result = await template.readCallback(new URL(resourceUri), {}, {});
|
|
70
|
+
console.dir(result, { depth: null });
|
|
71
|
+
process.exit(0);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
// Continue to next template if this one doesn't match
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
console.error("No matching resource template found for URI:", resourceUri);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
console.error("Error reading resource:", error instanceof Error ? error.message : 'Unknown error');
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
16
86
|
if (args.length < 1) {
|
|
17
87
|
console.error("Usage: npm run cli <tool-name> [param1=value1 param2=value2 ...]");
|
|
18
88
|
console.error(" npm run cli instructions");
|
|
89
|
+
console.error(" npm run cli resources");
|
|
90
|
+
console.error(" npm run cli resource <uri>");
|
|
19
91
|
console.error("\nAvailable tools:");
|
|
20
92
|
// @ts-ignore - Accessing private property for testing purposes
|
|
21
93
|
const tools = server._registeredTools;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAqIpE,QAAA,MAAM,aAAa,oBAAqB,CAAC;AAIzC,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ const space_tools_1 = require("./tools/space-tools");
|
|
|
14
14
|
const list_tools_1 = require("./tools/list-tools");
|
|
15
15
|
const time_tools_1 = require("./tools/time-tools");
|
|
16
16
|
const doc_tools_1 = require("./tools/doc-tools");
|
|
17
|
+
const space_resources_1 = require("./resources/space-resources");
|
|
17
18
|
// Create server variable that will be initialized later
|
|
18
19
|
let server;
|
|
19
20
|
// Register tools based on mode with user data for enhanced documentation
|
|
@@ -97,6 +98,7 @@ Use the ClickUp search tools to find tasks assigned to me, and get detailed info
|
|
|
97
98
|
(0, task_tools_1.registerTaskToolsRead)(server, userData);
|
|
98
99
|
(0, search_tools_1.registerSearchTools)(server, userData);
|
|
99
100
|
(0, space_tools_1.registerSpaceTools)(server);
|
|
101
|
+
(0, space_resources_1.registerSpaceResources)(server);
|
|
100
102
|
(0, list_tools_1.registerListToolsRead)(server);
|
|
101
103
|
(0, time_tools_1.registerTimeToolsRead)(server);
|
|
102
104
|
(0, doc_tools_1.registerDocumentToolsRead)(server);
|
|
@@ -107,6 +109,7 @@ Use the ClickUp search tools to find tasks assigned to me, and get detailed info
|
|
|
107
109
|
(0, task_write_tools_1.registerTaskToolsWrite)(server, userData);
|
|
108
110
|
(0, search_tools_1.registerSearchTools)(server, userData);
|
|
109
111
|
(0, space_tools_1.registerSpaceTools)(server);
|
|
112
|
+
(0, space_resources_1.registerSpaceResources)(server);
|
|
110
113
|
(0, list_tools_1.registerListToolsRead)(server);
|
|
111
114
|
(0, list_tools_1.registerListToolsWrite)(server);
|
|
112
115
|
(0, time_tools_1.registerTimeToolsRead)(server);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
/**
|
|
3
|
+
* Register ClickUp space resources using resource templates for dynamic discovery
|
|
4
|
+
*/
|
|
5
|
+
export declare function registerSpaceResources(server: McpServer): void;
|
|
6
|
+
//# sourceMappingURL=space-resources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"space-resources.d.ts","sourceRoot":"","sources":["../../src/resources/space-resources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAoB,MAAM,yCAAyC,CAAC;AAiBtF;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,QAuFvD"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerSpaceResources = registerSpaceResources;
|
|
4
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
5
|
+
const utils_1 = require("../shared/utils");
|
|
6
|
+
/**
|
|
7
|
+
* Extract space ID from clickup:// URI
|
|
8
|
+
*/
|
|
9
|
+
function extractSpaceIdFromUri(uriString) {
|
|
10
|
+
try {
|
|
11
|
+
const url = new URL(uriString);
|
|
12
|
+
const pathParts = url.pathname.split('/');
|
|
13
|
+
return pathParts[pathParts.length - 1];
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
throw new Error(`Invalid ClickUp space URI: ${uriString}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Register ClickUp space resources using resource templates for dynamic discovery
|
|
21
|
+
*/
|
|
22
|
+
function registerSpaceResources(server) {
|
|
23
|
+
// Create resource template for ClickUp spaces
|
|
24
|
+
const spaceTemplate = new mcp_js_1.ResourceTemplate("clickup://space/{spaceId}", {
|
|
25
|
+
list: async () => {
|
|
26
|
+
try {
|
|
27
|
+
const searchIndex = await (0, utils_1.getSpaceSearchIndex)();
|
|
28
|
+
if (!searchIndex) {
|
|
29
|
+
return { resources: [] };
|
|
30
|
+
}
|
|
31
|
+
const spaces = searchIndex._docs || [];
|
|
32
|
+
// Filter out archived spaces for resource listing
|
|
33
|
+
const activeSpaces = spaces.filter((space) => !space.archived);
|
|
34
|
+
return {
|
|
35
|
+
resources: activeSpaces.map((space) => ({
|
|
36
|
+
uri: `clickup://space/${space.id}`,
|
|
37
|
+
name: space.name,
|
|
38
|
+
mimeType: "text/plain"
|
|
39
|
+
}))
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
console.error("Error listing space resources:", error);
|
|
44
|
+
return { resources: [] };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
// Register resource template for ClickUp spaces
|
|
49
|
+
server.registerResource("clickup-spaces", spaceTemplate, {
|
|
50
|
+
title: "ClickUp Spaces",
|
|
51
|
+
description: "Access ClickUp spaces with their complete structure including lists, folders, and documents",
|
|
52
|
+
}, async (uri) => {
|
|
53
|
+
try {
|
|
54
|
+
const spaceId = extractSpaceIdFromUri(uri.toString());
|
|
55
|
+
// Fetch space content including lists, folders, and documents
|
|
56
|
+
const { lists, folders, documents } = await (0, utils_1.getSpaceContent)(spaceId);
|
|
57
|
+
// Get space details from the search index
|
|
58
|
+
const searchIndex = await (0, utils_1.getSpaceSearchIndex)();
|
|
59
|
+
const spaces = searchIndex._docs || [];
|
|
60
|
+
const space = spaces.find((s) => s.id === spaceId);
|
|
61
|
+
if (!space) {
|
|
62
|
+
return {
|
|
63
|
+
contents: [{
|
|
64
|
+
uri: uri.toString(),
|
|
65
|
+
text: `Space with ID ${spaceId} not found.`,
|
|
66
|
+
}]
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// Format the content using the shared tree formatting function
|
|
70
|
+
const treeContent = (0, utils_1.formatSpaceTree)(space, lists, folders, documents);
|
|
71
|
+
// Add resource metadata
|
|
72
|
+
const metadata = [
|
|
73
|
+
'\n---',
|
|
74
|
+
`ℹ️ Resource last updated: ${new Date().toISOString()}`,
|
|
75
|
+
`💡 For real-time data, use the searchSpaces tool`
|
|
76
|
+
].join('\n');
|
|
77
|
+
return {
|
|
78
|
+
contents: [{
|
|
79
|
+
uri: uri.toString(),
|
|
80
|
+
text: treeContent + metadata,
|
|
81
|
+
}]
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error("Error reading space resource:", error);
|
|
86
|
+
return {
|
|
87
|
+
contents: [{
|
|
88
|
+
uri: uri.toString(),
|
|
89
|
+
text: `Error reading space: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
90
|
+
}]
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
package/dist/shared/utils.d.ts
CHANGED
|
@@ -39,6 +39,11 @@ export declare function generateFolderUrl(folderId: string): string;
|
|
|
39
39
|
* Generate a ClickUp document URL from a document ID and optional page ID
|
|
40
40
|
*/
|
|
41
41
|
export declare function generateDocumentUrl(docId: string, pageId?: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Format space content as tree structure
|
|
44
|
+
* Shared function used by both searchSpaces tool and space resources
|
|
45
|
+
*/
|
|
46
|
+
export declare function formatSpaceTree(space: any, lists: any[], folders: any[], documents: any[]): string;
|
|
42
47
|
/**
|
|
43
48
|
* Get or refresh the space search index
|
|
44
49
|
* Caches promise to prevent race conditions on concurrent calls
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/shared/utils.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,SAAS,CAAC;AAI3B;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAG7C;AAKD;;;GAGG;AACH,wBAAsB,cAAc,iBA6BnC;AAGD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIpD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA0B7D;AAKD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,CAAC,EAAE,MAAM,EAAE,EACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,EACnB,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CA+B3B;AAkED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAK1E;AAKD;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CA+CrE;AAKD;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAAC,OAAO,EAAE,GAAG,EAAE,CAAC;IAAC,SAAS,EAAE,GAAG,EAAE,CAAA;CAAE,CAAC,CAgFlH;AAKD;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CA+C3D;AAKD;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CA6B3B;AAuID;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,EACpB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,CAAC,EAAE,CAAC,CA8Dd"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/shared/utils.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,SAAS,CAAC;AAI3B;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAG7C;AAKD;;;GAGG;AACH,wBAAsB,cAAc,iBA6BnC;AAGD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIpD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA0B7D;AAKD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,CAAC,EAAE,MAAM,EAAE,EACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,EACnB,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CA+B3B;AAkED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAK1E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,MAAM,CA4ElG;AAKD;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CA+CrE;AAKD;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAAC,OAAO,EAAE,GAAG,EAAE,CAAC;IAAC,SAAS,EAAE,GAAG,EAAE,CAAA;CAAE,CAAC,CAgFlH;AAKD;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CA+C3D;AAKD;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CA6B3B;AAuID;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,EACpB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,CAAC,EAAE,CAAC,CA8Dd"}
|
package/dist/shared/utils.js
CHANGED
|
@@ -13,6 +13,7 @@ exports.generateListUrl = generateListUrl;
|
|
|
13
13
|
exports.generateSpaceUrl = generateSpaceUrl;
|
|
14
14
|
exports.generateFolderUrl = generateFolderUrl;
|
|
15
15
|
exports.generateDocumentUrl = generateDocumentUrl;
|
|
16
|
+
exports.formatSpaceTree = formatSpaceTree;
|
|
16
17
|
exports.getSpaceSearchIndex = getSpaceSearchIndex;
|
|
17
18
|
exports.getSpaceContent = getSpaceContent;
|
|
18
19
|
exports.getAllTeamMembers = getAllTeamMembers;
|
|
@@ -209,6 +210,75 @@ function generateDocumentUrl(docId, pageId) {
|
|
|
209
210
|
}
|
|
210
211
|
return `https://app.clickup.com/${config_1.CONFIG.teamId}/v/dc/${docId}`;
|
|
211
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Format space content as tree structure
|
|
215
|
+
* Shared function used by both searchSpaces tool and space resources
|
|
216
|
+
*/
|
|
217
|
+
function formatSpaceTree(space, lists, folders, documents) {
|
|
218
|
+
const spaceLines = [];
|
|
219
|
+
const totalLists = lists.length + folders.reduce((sum, f) => sum + (f.lists?.length || 0), 0);
|
|
220
|
+
// Space header
|
|
221
|
+
spaceLines.push(`🏢 SPACE: ${space.name} (space_id: ${space.id}${space.private ? ', private' : ''}${space.archived ? ', archived' : ''}) ${generateSpaceUrl(space.id)}`, ` ${totalLists} lists, ${folders.length} folders, ${documents.length} documents`);
|
|
222
|
+
// Create a tree structure
|
|
223
|
+
const hasDirectLists = lists.length > 0;
|
|
224
|
+
const hasFolders = folders.length > 0;
|
|
225
|
+
const hasDocuments = documents.length > 0;
|
|
226
|
+
// Direct lists (not in folders)
|
|
227
|
+
if (hasDirectLists) {
|
|
228
|
+
lists.forEach((list, listIndex) => {
|
|
229
|
+
const isLastDirectList = listIndex === lists.length - 1;
|
|
230
|
+
const isLastOverall = !hasFolders && !hasDocuments && isLastDirectList;
|
|
231
|
+
const treeChar = isLastOverall ? '└──' : '├──';
|
|
232
|
+
const extraInfo = [
|
|
233
|
+
...(list.task_count ? [`${list.task_count} tasks`] : []),
|
|
234
|
+
...(list.private ? ['private'] : []),
|
|
235
|
+
...(list.archived ? ['archived'] : [])
|
|
236
|
+
].join(', ');
|
|
237
|
+
const listLine = `${treeChar} 📝 ${list.name} (list_id: ${list.id}${extraInfo ? `, ${extraInfo}` : ''}) ${generateListUrl(list.id)}`;
|
|
238
|
+
spaceLines.push(listLine);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
// Folders and their lists
|
|
242
|
+
if (hasFolders) {
|
|
243
|
+
folders.forEach((folder, folderIndex) => {
|
|
244
|
+
const isLastFolder = folderIndex === folders.length - 1;
|
|
245
|
+
const isLastOverall = !hasDocuments && isLastFolder;
|
|
246
|
+
const folderTreeChar = isLastOverall ? '└──' : '├──';
|
|
247
|
+
const folderContinuation = isLastOverall ? ' ' : '│ ';
|
|
248
|
+
const folderExtraInfo = [
|
|
249
|
+
...(folder.lists?.length ? [`${folder.lists.length} lists`] : []),
|
|
250
|
+
...(folder.private ? ['private'] : []),
|
|
251
|
+
...(folder.archived ? ['archived'] : [])
|
|
252
|
+
].join(', ');
|
|
253
|
+
const folderLine = `${folderTreeChar} 📂 ${folder.name} (folder_id: ${folder.id}${folderExtraInfo ? `, ${folderExtraInfo}` : ''}) ${generateFolderUrl(folder.id)}`;
|
|
254
|
+
spaceLines.push(folderLine);
|
|
255
|
+
// Lists within this folder
|
|
256
|
+
if (folder.lists && folder.lists.length > 0) {
|
|
257
|
+
folder.lists.forEach((list, listIndex) => {
|
|
258
|
+
const isLastListInFolder = listIndex === folder.lists.length - 1;
|
|
259
|
+
const listTreeChar = isLastListInFolder ? '└──' : '├──';
|
|
260
|
+
const listExtraInfo = [
|
|
261
|
+
...(list.task_count ? [`${list.task_count} tasks`] : []),
|
|
262
|
+
...(list.private ? ['private'] : []),
|
|
263
|
+
...(list.archived ? ['archived'] : [])
|
|
264
|
+
].join(', ');
|
|
265
|
+
const listLine = `${folderContinuation}${listTreeChar} 📝 ${list.name} (list_id: ${list.id}${listExtraInfo ? `, ${listExtraInfo}` : ''}) ${generateListUrl(list.id)}`;
|
|
266
|
+
spaceLines.push(listLine);
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
// Documents attached to this space
|
|
272
|
+
if (hasDocuments) {
|
|
273
|
+
documents.forEach((document, docIndex) => {
|
|
274
|
+
const isLastDocument = docIndex === documents.length - 1;
|
|
275
|
+
const docTreeChar = isLastDocument ? '└──' : '├──';
|
|
276
|
+
const docLine = `${docTreeChar} 📄 ${document.name} (doc_id: ${document.id}) ${generateDocumentUrl(document.id)}`;
|
|
277
|
+
spaceLines.push(docLine);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
return spaceLines.join('\n');
|
|
281
|
+
}
|
|
212
282
|
// Space search index cache - cache promise to prevent race conditions
|
|
213
283
|
let spaceSearchIndexPromise = null;
|
|
214
284
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"space-tools.d.ts","sourceRoot":"","sources":["../../src/tools/space-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"space-tools.d.ts","sourceRoot":"","sources":["../../src/tools/space-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,QA6InD"}
|
|
@@ -70,72 +70,12 @@ function registerSpaceTools(server) {
|
|
|
70
70
|
if (isDetailedMode) {
|
|
71
71
|
// Detailed mode: create separate blocks for each space
|
|
72
72
|
spacesWithContent.forEach(({ space, lists, folders, documents }) => {
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
// Space header
|
|
76
|
-
spaceLines.push(`🏢 SPACE: ${space.name} (space_id: ${space.id}${space.private ? ', private' : ''}${space.archived ? ', archived' : ''}) ${(0, utils_1.generateSpaceUrl)(space.id)}`, ` ${totalLists} lists, ${folders.length} folders, ${documents.length} documents`);
|
|
77
|
-
// Create a tree structure
|
|
78
|
-
const hasDirectLists = lists.length > 0;
|
|
79
|
-
const hasFolders = folders.length > 0;
|
|
80
|
-
const hasDocuments = documents.length > 0;
|
|
81
|
-
// Direct lists (not in folders)
|
|
82
|
-
if (hasDirectLists) {
|
|
83
|
-
lists.forEach((list, listIndex) => {
|
|
84
|
-
const isLastDirectList = listIndex === lists.length - 1;
|
|
85
|
-
const isLastOverall = !hasFolders && !hasDocuments && isLastDirectList;
|
|
86
|
-
const treeChar = isLastOverall ? '└──' : '├──';
|
|
87
|
-
const extraInfo = [
|
|
88
|
-
...(list.task_count ? [`${list.task_count} tasks`] : []),
|
|
89
|
-
...(list.private ? ['private'] : []),
|
|
90
|
-
...(list.archived ? ['archived'] : [])
|
|
91
|
-
].join(', ');
|
|
92
|
-
const listLine = `${treeChar} 📝 ${list.name} (list_id: ${list.id}${extraInfo ? `, ${extraInfo}` : ''}) ${(0, utils_1.generateListUrl)(list.id)}`;
|
|
93
|
-
spaceLines.push(listLine);
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
// Folders and their lists
|
|
97
|
-
if (hasFolders) {
|
|
98
|
-
folders.forEach((folder, folderIndex) => {
|
|
99
|
-
const isLastFolder = folderIndex === folders.length - 1;
|
|
100
|
-
const isLastOverall = !hasDocuments && isLastFolder;
|
|
101
|
-
const folderTreeChar = isLastOverall ? '└──' : '├──';
|
|
102
|
-
const folderContinuation = isLastOverall ? ' ' : '│ ';
|
|
103
|
-
const folderExtraInfo = [
|
|
104
|
-
...(folder.lists?.length ? [`${folder.lists.length} lists`] : []),
|
|
105
|
-
...(folder.private ? ['private'] : []),
|
|
106
|
-
...(folder.archived ? ['archived'] : [])
|
|
107
|
-
].join(', ');
|
|
108
|
-
const folderLine = `${folderTreeChar} 📂 ${folder.name} (folder_id: ${folder.id}${folderExtraInfo ? `, ${folderExtraInfo}` : ''}) ${(0, utils_1.generateFolderUrl)(folder.id)}`;
|
|
109
|
-
spaceLines.push(folderLine);
|
|
110
|
-
// Lists within this folder
|
|
111
|
-
if (folder.lists && folder.lists.length > 0) {
|
|
112
|
-
folder.lists.forEach((list, listIndex) => {
|
|
113
|
-
const isLastListInFolder = listIndex === folder.lists.length - 1;
|
|
114
|
-
const listTreeChar = isLastListInFolder ? '└──' : '├──';
|
|
115
|
-
const listExtraInfo = [
|
|
116
|
-
...(list.task_count ? [`${list.task_count} tasks`] : []),
|
|
117
|
-
...(list.private ? ['private'] : []),
|
|
118
|
-
...(list.archived ? ['archived'] : [])
|
|
119
|
-
].join(', ');
|
|
120
|
-
const listLine = `${folderContinuation}${listTreeChar} 📝 ${list.name} (list_id: ${list.id}${listExtraInfo ? `, ${listExtraInfo}` : ''}) ${(0, utils_1.generateListUrl)(list.id)}`;
|
|
121
|
-
spaceLines.push(listLine);
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
// Documents attached to this space
|
|
127
|
-
if (hasDocuments) {
|
|
128
|
-
documents.forEach((document, docIndex) => {
|
|
129
|
-
const isLastDocument = docIndex === documents.length - 1;
|
|
130
|
-
const docTreeChar = isLastDocument ? '└──' : '├──';
|
|
131
|
-
const docLine = `${docTreeChar} 📄 ${document.name} (doc_id: ${document.id}) ${(0, utils_1.generateDocumentUrl)(document.id)}`;
|
|
132
|
-
spaceLines.push(docLine);
|
|
133
|
-
});
|
|
134
|
-
}
|
|
73
|
+
// Use shared tree formatting function
|
|
74
|
+
const spaceTreeText = (0, utils_1.formatSpaceTree)(space, lists, folders, documents);
|
|
135
75
|
// Add the complete space as a single content block
|
|
136
76
|
contentBlocks.push({
|
|
137
77
|
type: "text",
|
|
138
|
-
text:
|
|
78
|
+
text: spaceTreeText
|
|
139
79
|
});
|
|
140
80
|
});
|
|
141
81
|
}
|
package/package.json
CHANGED