#!/usr/bin/env node
/**
* SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
* SPDX-License-Identifier: MIT
*
* ClickUp MCP Server
*
* This custom server implements the Model Context Protocol (MCP) specification to enable
* AI applications to interact with ClickUp workspaces. It provides a standardized
* interface for managing tasks, lists, folders and other ClickUp entities using Natural Language.
*
* Key Features:
* - Complete task management (CRUD operations, moving, duplicating)
* - Workspace organization (spaces, folders, lists)
* - Bulk operations with concurrent processing
* - Natural language date parsing
* - File attachments support
* - Name-based entity resolution
* - Markdown formatting
* - Built-in rate limiting
* - Multiple transport options (STDIO, SSE, HTTP Streamable)
*
* For full documentation and usage examples, please refer to the README.md file.
*/
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { configureServer, server } from './server.js';
import { info, error } from './logger.js';
import config from './config.js';
import { startSSEServer } from './sse_server.js';
// Handle uncaught exceptions
process.on('uncaughtException', (err) => {
error("Uncaught Exception", { message: err.message, stack: err.stack });
process.exit(1);
});
// Handle unhandled promise rejections
process.on('unhandledRejection', (reason, promise) => {
error("Unhandled Rejection", { reason });
process.exit(1);
});
async function startStdioServer() {
// Connect using stdio transport (server assumed configured by caller)
info('Connecting to MCP stdio transport');
const transport = new StdioServerTransport();
await server.connect(transport);
info('STDIO transport ready to handle requests');
}
/**
* Application entry point that configures and starts the MCP server.
*/
async function main() {
try {
info('Starting ClickUp MCP server...');
info('Server environment', {
pid: process.pid,
node: process.version,
os: process.platform,
arch: process.arch,
transports: {
stdio: config.enableStdio,
sse: config.enableSSE,
},
});
// Configure once for all transports
info('Configuring request handlers...');
await configureServer();
const activeTransports: string[] = [];
if (config.enableSSE) {
// Start the new SSE server with HTTP Streamable support
await startSSEServer();
activeTransports.push('sse');
}
if (config.enableStdio) {
// Start the traditional STDIO server
await startStdioServer();
activeTransports.push('stdio');
}
if (activeTransports.length === 0) {
throw new Error('No transports enabled. Set ENABLE_SSE and/or ENABLE_STDIO to true.');
}
info('Active transports:', { transports: activeTransports });
} catch (err) {
error('Server startup failed:', {
message: err.message,
stack: err.stack,
});
process.exit(1);
}
}
main().catch((err) => {
error("Unhandled server error", { message: err.message, stack: err.stack });
process.exit(1);
});