Skip to main content
Glama
index.ts8.19 kB
#!/usr/bin/env node /** * Dooray MCP Server * Main entry point for the Model Context Protocol server */ import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import * as dotenv from 'dotenv'; import { initializeClient } from './api/client.js'; import { logger } from './utils/logger.js'; // Import all tools import { getMyMemberInfoTool, getMyMemberInfoHandler, getMyMemberInfoSchema } from './tools/common/get-my-member-info.js'; import { getProjectListTool, getProjectListHandler, getProjectListSchema } from './tools/projects/get-project-list.js'; import { getProjectTool, getProjectHandler, getProjectSchema } from './tools/projects/get-project.js'; import { getTaskListTool, getTaskListHandler, getTaskListSchema } from './tools/projects/get-task-list.js'; import { getTaskTool, getTaskHandler, getTaskSchema } from './tools/projects/get-task.js'; import { createTaskTool, createTaskHandler, createTaskSchema } from './tools/projects/create-task.js'; import { updateTaskTool, updateTaskHandler, updateTaskSchema } from './tools/projects/update-task.js'; import { createTaskCommentTool, createTaskCommentHandler, createTaskCommentSchema } from './tools/projects/create-task-comment.js'; import { getTaskCommentListTool, getTaskCommentListHandler, getTaskCommentListSchema } from './tools/projects/get-task-comment-list.js'; import { updateTaskCommentTool, updateTaskCommentHandler, updateTaskCommentSchema } from './tools/projects/update-task-comment.js'; import { getMilestoneListTool, getMilestoneListHandler, getMilestoneListSchema } from './tools/projects/get-milestone-list.js'; import { getTagListTool, getTagListHandler, getTagListSchema } from './tools/projects/get-tag-list.js'; import { getProjectTemplateListTool, getProjectTemplateListHandler, getProjectTemplateListSchema } from './tools/projects/get-project-template-list.js'; import { getProjectTemplateTool, getProjectTemplateHandler, getProjectTemplateSchema } from './tools/projects/get-project-template.js'; import { getProjectMemberListTool, getProjectMemberListHandler, getProjectMemberListSchema } from './tools/projects/get-project-member-list.js'; import { getProjectMemberGroupListTool, getProjectMemberGroupListHandler, getProjectMemberGroupListSchema } from './tools/projects/get-project-member-group-list.js'; import { getProjectWorkflowListTool, getProjectWorkflowListHandler, getProjectWorkflowListSchema } from './tools/projects/get-project-workflow-list.js'; // Load environment variables dotenv.config(); /** * Tool registry mapping tool names to their handlers and schemas */ const toolRegistry = { // Common tools 'get-my-member-info': { handler: getMyMemberInfoHandler, schema: getMyMemberInfoSchema }, // Projects tools 'get-project-list': { handler: getProjectListHandler, schema: getProjectListSchema }, 'get-project': { handler: getProjectHandler, schema: getProjectSchema }, 'get-task-list': { handler: getTaskListHandler, schema: getTaskListSchema }, 'get-task': { handler: getTaskHandler, schema: getTaskSchema }, 'create-task': { handler: createTaskHandler, schema: createTaskSchema }, 'update-task': { handler: updateTaskHandler, schema: updateTaskSchema }, 'create-task-comment': { handler: createTaskCommentHandler, schema: createTaskCommentSchema }, 'get-task-comment-list': { handler: getTaskCommentListHandler, schema: getTaskCommentListSchema }, 'update-task-comment': { handler: updateTaskCommentHandler, schema: updateTaskCommentSchema }, 'get-milestone-list': { handler: getMilestoneListHandler, schema: getMilestoneListSchema }, 'get-tag-list': { handler: getTagListHandler, schema: getTagListSchema }, 'get-project-template-list': { handler: getProjectTemplateListHandler, schema: getProjectTemplateListSchema }, 'get-project-template': { handler: getProjectTemplateHandler, schema: getProjectTemplateSchema }, 'get-project-member-list': { handler: getProjectMemberListHandler, schema: getProjectMemberListSchema }, 'get-project-member-group-list': { handler: getProjectMemberGroupListHandler, schema: getProjectMemberGroupListSchema }, 'get-project-workflow-list': { handler: getProjectWorkflowListHandler, schema: getProjectWorkflowListSchema }, }; /** * List of all available tools */ const tools = [ getMyMemberInfoTool, getProjectListTool, getProjectTool, getTaskListTool, getTaskTool, createTaskTool, updateTaskTool, createTaskCommentTool, getTaskCommentListTool, updateTaskCommentTool, getMilestoneListTool, getTagListTool, getProjectTemplateListTool, getProjectTemplateTool, getProjectMemberListTool, getProjectMemberGroupListTool, getProjectWorkflowListTool, ]; /** * Main server initialization */ async function main() { logger.info('Starting Dooray MCP Server...'); // Validate API token const apiToken = process.env.DOORAY_API_TOKEN; if (!apiToken) { logger.error('DOORAY_API_TOKEN environment variable is required'); process.exit(1); } // Initialize Dooray API client try { initializeClient({ apiToken, baseUrl: process.env.DOORAY_API_BASE_URL, }); logger.info('Dooray API client initialized'); } catch (error) { logger.error('Failed to initialize Dooray API client:', error); process.exit(1); } // Create MCP server const server = new Server( { name: 'dooray-mcp', version: '0.1.0', }, { capabilities: { tools: {}, }, } ); // Handle list tools request server.setRequestHandler(ListToolsRequestSchema, async () => { logger.debug('Handling list_tools request'); return { tools, }; }); // Handle call tool request server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; logger.info(`Tool called: ${name}`); logger.debug(`Tool arguments:`, args); const tool = toolRegistry[name as keyof typeof toolRegistry]; if (!tool) { logger.error(`Unknown tool: ${name}`); return { content: [ { type: 'text', text: `Error: Unknown tool '${name}'`, }, ], isError: true, }; } try { // Validate arguments with Zod schema const validatedArgs = tool.schema.parse(args || {}); // Call the tool handler const result = await (tool.handler as any)(validatedArgs); logger.debug(`Tool ${name} completed successfully`); return result; } catch (error) { logger.error(`Tool ${name} failed:`, error); // Handle Zod validation errors if (error && typeof error === 'object' && 'errors' in error) { const zodError = error as { errors: Array<{ path: string[]; message: string }> }; const errorMessages = zodError.errors .map(e => `${e.path.join('.')}: ${e.message}`) .join(', '); return { content: [ { type: 'text', text: `Validation Error: ${errorMessages}`, }, ], isError: true, }; } return { content: [ { type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}`, }, ], isError: true, }; } }); // Start the server with stdio transport const transport = new StdioServerTransport(); await server.connect(transport); logger.info(`Dooray MCP Server running with ${tools.length} tools`); logger.info('Tools available: ' + tools.map(t => t.name).join(', ')); } // Error handling process.on('uncaughtException', (error) => { logger.error('Uncaught exception:', error); process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { logger.error('Unhandled rejection at:', promise, 'reason:', reason); process.exit(1); }); // Start the server main().catch((error) => { logger.error('Failed to start server:', error); process.exit(1); });

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jhl8041/dooray-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server