workspace.ts•3.2 kB
/**
* ClickUp MCP Workspace Tools
*
* This module defines workspace-related tools like retrieving workspace hierarchy.
* It handles the workspace tool definitions and the implementation of their handlers.
*/
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import { WorkspaceTree, WorkspaceNode } from '../services/clickup/types.js';
// Use the workspace service imported from the server
// This is defined when server.ts imports this module
let workspaceService: any;
/**
* Tool definition for retrieving the complete workspace hierarchy
*/
export const workspaceHierarchyTool: Tool = {
name: 'get_workspace_hierarchy',
description: 'Get the complete workspace hierarchy including spaces, folders, and lists.',
inputSchema: {
type: 'object',
properties: {}
}
};
/**
* Initialize the tool with services
*/
export function initializeWorkspaceTool(services: any) {
workspaceService = services.workspace;
}
/**
* Handler for the get_workspace_hierarchy tool
*/
export async function handleGetWorkspaceHierarchy() {
try {
// Get workspace hierarchy from the workspace service
const hierarchy = await workspaceService.getWorkspaceHierarchy();
const response = formatHierarchyResponse(hierarchy);
return response;
} catch (error: any) {
return {
content: [
{
type: "text",
text: `Error getting workspace hierarchy: ${error.message}`
}
]
};
}
}
/**
* Format the hierarchy for the response
*/
function formatHierarchyResponse(hierarchy: WorkspaceTree): any {
try {
// Helper function to format a node and its children as a tree
const formatNodeAsTree = (node: WorkspaceNode | WorkspaceTree['root'], level: number = 0, isLast: boolean = true, parentPrefix: string = ''): string[] => {
const lines: string[] = [];
// Calculate the current line's prefix
const currentPrefix = level === 0 ? '' : parentPrefix + (isLast ? '└── ' : '├── ');
// Format current node with descriptive ID type
const idType = 'type' in node ? `${node.type.charAt(0).toUpperCase() + node.type.slice(1)} ID` : 'Workspace ID';
lines.push(`${currentPrefix}${node.name} (${idType}: ${node.id})`);
// Calculate the prefix for children
const childPrefix = level === 0 ? '' : parentPrefix + (isLast ? ' ' : '│ ');
// Process children
const children = node.children || [];
children.forEach((child, index) => {
const childLines = formatNodeAsTree(
child,
level + 1,
index === children.length - 1,
childPrefix
);
lines.push(...childLines);
});
return lines;
};
// Generate tree representation
const treeLines = formatNodeAsTree(hierarchy.root);
const treeOutput = treeLines.join('\n');
return {
content: [
{
type: "text",
text: treeOutput
}
]
};
} catch (error: any) {
return {
content: [
{
type: "text",
text: `Error formatting workspace hierarchy: ${error.message}`
}
]
};
}
}