UNPKG

mcp-clickup

Version:

A Model Context Protocol server for the ClickUp API.

218 lines (211 loc) 6.44 kB
#!/usr/bin/env node "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); // src/index.ts var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js"); var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js"); // src/common/tool.ts var import_dotenv = __toESM(require("dotenv"), 1); // src/utils/defineTool.ts var import_zod = require("zod"); var defineTool = (cb) => { const tool = cb(import_zod.z); const wrappedHandler = async (input, _) => { try { const result = await tool.handler(input); return { content: [ { type: "text", text: JSON.stringify(result, null, 2) } ] }; } catch (error) { return { content: [ { type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } }; return { ...tool, handler: wrappedHandler }; }; // src/common/clickup.ts var BASE_URL = "https://api.clickup.com/api/v2"; var ClickUpClient = class { headers; workspaceId; constructor(apiToken2, workspaceId2) { this.headers = { Authorization: apiToken2, "Content-Type": "application/json" }; this.workspaceId = workspaceId2; } async request(endpoint, options = {}) { const response = await fetch(`${BASE_URL}${endpoint}`, { ...options, headers: this.headers }); return response.json(); } async authenticate() { return this.request("/user"); } async getTask(taskId) { return this.request( `/task/${taskId}?custom_task_ids=false&team_id=${this.workspaceId}&include_subtasks=true&include_markdown_description=true` ); } async getTaskByCustomId(customId) { return this.request( `/task/${customId}?custom_task_ids=true&team_id=${this.workspaceId}&include_subtasks=true&include_markdown_description=true` ); } async getTasks(taskIds) { const tasksUrl = `/team/${this.workspaceId}/task?include_markdown_description=true&include_subtasks=true&${taskIds.map((id) => `task_ids=${id}`).join("&")}`; return this.request(tasksUrl); } }; var clickup_default = ClickUpClient; // src/common/tool.ts import_dotenv.default.config(); var apiToken = process.env.CLICKUP_API_TOKEN; var workspaceId = process.env.CLICKUP_WORKSPACE_ID; if (!apiToken || !workspaceId) { console.error( "Please set CLICKUP_API_TOKEN and CLICKUP_WORKSPACE_ID environment variables" ); process.exit(1); } var clickUpClient = new clickup_default(apiToken, workspaceId); var authenticateTool = defineTool((z2) => ({ name: "clickup_authenticate", description: "Authenticate with ClickUp API using an API token and workspace ID", inputSchema: { type: z2.object({}) }, handler: async (input) => { const response = await clickUpClient.authenticate(); return { content: [{ type: "text", text: JSON.stringify(response) }] }; } })); var getTaskTool = defineTool((z2) => ({ name: "clickup_get_task", description: "Get a task by its ID", inputSchema: { type: z2.object({ task_id: z2.string() }) }, handler: async (input) => { const { task_id } = input; const response = await clickUpClient.getTask(task_id); return { content: [{ type: "text", text: JSON.stringify(response) }] }; } })); var getTaskByCustomIdTool = defineTool((z2) => ({ name: "clickup_get_task_by_custom_id", description: "Get a task by its custom ID", inputSchema: { type: z2.object({ custom_id: z2.string() }) }, handler: async (input) => { const { custom_id } = input; const response = await clickUpClient.getTaskByCustomId(custom_id); return { content: [{ type: "text", text: JSON.stringify(response) }] }; } })); var getTasksTool = defineTool((z2) => ({ name: "clickup_get_tasks", description: "Get multiple tasks by their IDs", inputSchema: { type: z2.object({ task_ids: z2.array(z2.string()) }) }, handler: async (input) => { const { task_ids } = input; const response = await clickUpClient.getTasks(task_ids); return { content: [{ type: "text", text: JSON.stringify(response) }] }; } })); // src/index.ts var tools = [ authenticateTool, getTaskByCustomIdTool, getTasksTool, getTaskTool ]; async function main() { console.error("Starting ClickUp MCP Server..."); const apiToken2 = process.env.CLICKUP_API_TOKEN; const workspaceId2 = process.env.CLICKUP_WORKSPACE_ID; if (!apiToken2 || !workspaceId2) { console.error( "Please set CLICKUP_API_TOKEN and CLICKUP_WORKSPACE_ID environment variables" ); process.exit(1); } const server = new import_mcp.McpServer( { name: "ClickUp MCP Server", version: "1.0.0" }, { capabilities: { tools: {} } } ); tools.forEach((tool) => { server.tool(tool.name, tool.description, tool.inputSchema, tool.handler); }); const transport = new import_stdio.StdioServerTransport(); console.error("Connecting server to transport..."); await server.connect(transport); console.error("ClickUp MCP Server running on stdio"); } main().catch((error) => { console.error("Fatal error in main():", error); process.exit(1); });