Skip to main content
Glama
server.ts9 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 { getConfig } from './config.js'; import { logger } from './logger.js'; import { TududuClient } from './tududi-client.js'; // Initialize configuration and client const config = getConfig(); const tududuClient = new TududuClient( config.tududuApiUrl, config.tududuApiKey, config.tududuEmail, config.tududuPassword ); // Create MCP server const server = new Server( { name: 'tududi-mcp', version: '0.2.0', }, { capabilities: { tools: {}, }, } ); // List available tools server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'tududi_list_tasks', description: 'List all tasks from Tududi', inputSchema: { type: 'object', properties: {}, }, }, { name: 'tududi_create_task', description: 'Create a new task in Tududi', inputSchema: { type: 'object', properties: { title: { type: 'string', description: 'Task title', }, description: { type: 'string', description: 'Task description', }, projectId: { type: 'string', description: 'Project ID to assign task to', }, areaId: { type: 'string', description: 'Area ID to assign task to', }, dueDate: { type: 'string', description: 'Due date in ISO format', }, priority: { type: 'string', enum: ['low', 'medium', 'high'], description: 'Task priority', }, }, required: ['title'], }, }, { name: 'tududi_update_task', description: 'Update an existing task', inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Task ID', }, title: { type: 'string', description: 'New task title', }, description: { type: 'string', description: 'New task description', }, completed: { type: 'boolean', description: 'Task completion status', }, priority: { type: 'string', enum: ['low', 'medium', 'high'], description: 'Task priority', }, }, required: ['id'], }, }, { name: 'tududi_delete_task', description: 'Delete a task', inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Task ID to delete', }, }, required: ['id'], }, }, { name: 'tududi_complete_task', description: 'Mark a task as complete', inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Task ID to complete', }, }, required: ['id'], }, }, { name: 'tududi_list_projects', description: 'List all projects from Tududi', inputSchema: { type: 'object', properties: {}, }, }, { name: 'tududi_create_project', description: 'Create a new project in Tududi', inputSchema: { type: 'object', properties: { name: { type: 'string', description: 'Project name', }, description: { type: 'string', description: 'Project description', }, areaId: { type: 'string', description: 'Area ID to assign project to', }, }, required: ['name'], }, }, { name: 'tududi_list_areas', description: 'List all areas from Tududi', inputSchema: { type: 'object', properties: {}, }, }, { name: 'tududi_search_tasks', description: 'Search tasks with filters', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query', }, projectId: { type: 'string', description: 'Filter by project ID', }, areaId: { type: 'string', description: 'Filter by area ID', }, completed: { type: 'boolean', description: 'Filter by completion status', }, priority: { type: 'string', enum: ['low', 'medium', 'high'], description: 'Filter by priority', }, }, }, }, ], }; }); // Handle tool calls server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { switch (name) { case 'tududi_list_tasks': { const tasks = await tududuClient.listTasks(); return { content: [ { type: 'text', text: JSON.stringify(tasks, null, 2), }, ], }; } case 'tududi_create_task': { const task = await tududuClient.createTask(args as any); return { content: [ { type: 'text', text: `Task created successfully:\n${JSON.stringify(task, null, 2)}`, }, ], }; } case 'tududi_update_task': { const { id, ...updateData } = args as any; const task = await tududuClient.updateTask(id, updateData); return { content: [ { type: 'text', text: `Task updated successfully:\n${JSON.stringify(task, null, 2)}`, }, ], }; } case 'tududi_delete_task': { const { id } = args as any; await tududuClient.deleteTask(id); return { content: [ { type: 'text', text: `Task ${id} deleted successfully`, }, ], }; } case 'tududi_complete_task': { const { id } = args as any; const task = await tududuClient.completeTask(id); return { content: [ { type: 'text', text: `Task completed successfully:\n${JSON.stringify(task, null, 2)}`, }, ], }; } case 'tududi_list_projects': { const projects = await tududuClient.listProjects(); return { content: [ { type: 'text', text: JSON.stringify(projects, null, 2), }, ], }; } case 'tududi_create_project': { const project = await tududuClient.createProject(args as any); return { content: [ { type: 'text', text: `Project created successfully:\n${JSON.stringify(project, null, 2)}`, }, ], }; } case 'tududi_list_areas': { const areas = await tududuClient.listAreas(); return { content: [ { type: 'text', text: JSON.stringify(areas, null, 2), }, ], }; } case 'tududi_search_tasks': { const tasks = await tududuClient.searchTasks(args as any); return { content: [ { type: 'text', text: JSON.stringify(tasks, null, 2), }, ], }; } default: throw new Error(`Unknown tool: ${name}`); } } catch (error) { logger.error({ error, tool: name }, 'Tool execution failed'); return { content: [ { type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, }, ], isError: true, }; } }); // Start server async function main() { logger.info('Starting Tududi MCP server...'); const transport = new StdioServerTransport(); await server.connect(transport); logger.info('Tududi MCP server running'); } main().catch((error) => { logger.error({ error }, 'Server failed to start'); process.exit(1); });

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/jerrytunin/tududi-mcp'

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