Skip to main content
Glama
index.ts4.38 kB
#!/usr/bin/env node 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 { config } from 'dotenv'; import { getTaskCommentsTool, listPersonalInboxTasksTool, listBrianInboxPerBeckyTasksTool, listBeckyInboxPerBrianTasksTool, listNextActionsTool, getBrianOnlyProjectsTool, getBrianSharedProjectsTool, getBeckySharedProjectsTool, getInboxProjectsTool, createProjectLabelTool, createTaskCommentTool, updateTaskTool, createTaskTool, moveTaskTool, getContextLabelsTool, getTasksWithLabelTool, completeTaskTool, uncompleteTaskTool, searchTasksTool, searchTasksUsingAndTool, searchTasksUsingOrTool, getChoresDueTodayTool, getTasksDueTomorrowTool, getTasksDueThisWeekTool, getTicklerTasksTool, listGtdProjectsTool, getWaitingTasksTool, getRecentMediaTool, getAreasOfFocusTool, getShoppingListTool, completeBeckyTaskTool, listBrianTimeSensitiveTasksTool, listBeckyTimeSensitiveTasksTool, } from './tools'; import { handleToolRequest } from './handlers/tool-request-handler'; import { join } from 'path'; import { dirname } from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const envPath = join(__dirname, '..', '.env'); console.error('Loading .env file from:', envPath); config({ path: envPath }); // Validate required environment variables const requiredEnvVars = ['TODOIST_API_TOKEN']; const missingVars = requiredEnvVars.filter((varName) => !process.env[varName]); if (missingVars.length > 0) { console.error( 'Missing required environment variables:', missingVars.join(', ') ); console.error('Please create a .env file with the required variables.'); process.exit(1); } const server = new Server({ name: 'todoist-mcp', version: '1.0.0', capabilities: { tools: {}, }, }); // List tools server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ getTaskCommentsTool.schema, listPersonalInboxTasksTool.schema, listBrianInboxPerBeckyTasksTool.schema, listBeckyInboxPerBrianTasksTool.schema, listNextActionsTool.schema, getBrianOnlyProjectsTool.schema, getBrianSharedProjectsTool.schema, getBeckySharedProjectsTool.schema, getInboxProjectsTool.schema, createProjectLabelTool.schema, createTaskCommentTool.schema, updateTaskTool.schema, createTaskTool.schema, moveTaskTool.schema, getContextLabelsTool.schema, getTasksWithLabelTool.schema, completeTaskTool.schema, uncompleteTaskTool.schema, searchTasksTool.schema, searchTasksUsingAndTool.schema, searchTasksUsingOrTool.schema, getChoresDueTodayTool.schema, getTasksDueTomorrowTool.schema, getTasksDueThisWeekTool.schema, getTicklerTasksTool.schema, listGtdProjectsTool.schema, getWaitingTasksTool.schema, getRecentMediaTool.schema, getAreasOfFocusTool.schema, getShoppingListTool.schema, completeBeckyTaskTool.schema, listBrianTimeSensitiveTasksTool.schema, listBeckyTimeSensitiveTasksTool.schema, ], }; }); // Handle tool calls server.setRequestHandler(CallToolRequestSchema, handleToolRequest as any); // Start the server console.error('Creating transport...'); const transport = new StdioServerTransport(); console.error('Connecting server to transport...'); server.connect(transport); console.error('Todoist MCP server started'); console.error('Server ready to handle requests...'); // Keep the server alive by preventing stdin from closing process.stdin.resume(); // Keep the process alive process.on('SIGINT', () => { console.error('Received SIGINT, shutting down...'); process.exit(0); }); process.on('SIGTERM', () => { console.error('Received SIGTERM, shutting down...'); process.exit(0); }); // Add global error handling process.on('uncaughtException', (error) => { console.error('Uncaught exception:', error); process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { console.error('Unhandled rejection at:', promise, 'reason:', reason); 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/bkotos/todoist-mcp'

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