Skip to main content
Glama
tools.ts8.21 kB
import { FastMCP } from "fastmcp"; import { taskStorage } from "./storage.js"; import { Task, NewTaskSchema, TaskUpdateSchema, TaskSchema, TaskStatusEnum, TaskPriorityEnum } from "./schemas.js"; import { z } from "zod"; /** * Register task management tools with the MCP server * * @param server FastMCP server instance */ export function registerTaskTools(server: FastMCP): void { // Schema for plan_tasks parameters const PlanTasksSchema = z.object({ tasks: z.array( z.object({ description: z.string().min(3, "Description must be at least 3 characters"), status: TaskStatusEnum.optional(), dependsOn: z.array(z.string().uuid()).optional(), due: z.string().datetime().optional(), priority: TaskPriorityEnum.optional(), tags: z.array(z.string()).optional() }) ) }); // Schema for list_tasks parameters const ListTasksSchema = z.object({ status: TaskStatusEnum.optional(), priority: TaskPriorityEnum.optional() }); // Schema for complete_task parameters const CompleteTaskSchema = z.object({ id: z.string().uuid() }); // Schema for update_tasks parameters const UpdateTasksSchema = z.object({ updates: z.array( z.object({ id: z.string().uuid(), description: z.string().min(3, "Description must be at least 3 characters").optional(), status: TaskStatusEnum.optional(), priority: TaskPriorityEnum.optional(), due: z.string().datetime().optional(), tags: z.array(z.string()).optional(), dependsOn: z.array(z.string().uuid()).optional() }) ) }); // Tool to plan tasks server.addTool({ name: "plan_tasks", description: "Create multiple tasks from a plan. Generates IDs and syncs with knowledge graph.", execute: async (params: any) => { try { // Validate input parameters const validatedParams = PlanTasksSchema.parse(params); const createdTasks = []; for (const task of validatedParams.tasks) { try { const newTask = taskStorage.add({ description: task.description, status: task.status || "todo", priority: task.priority || "medium", due: task.due, tags: task.tags || [], dependsOn: task.dependsOn || [] }); createdTasks.push(newTask); } catch (error) { return JSON.stringify({ error: `Failed to create task: ${error instanceof Error ? error.message : String(error)}`, task: task }); } } return JSON.stringify({ tasks: createdTasks, message: `Created ${createdTasks.length} tasks` }); } catch (error) { return JSON.stringify({ error: `Invalid task parameters: ${error instanceof Error ? error.message : String(error)}` }); } } }); // Tool to list tasks server.addTool({ name: "list_tasks", description: "List tasks with optional filtering by status and priority.", execute: async (params: any) => { try { // Validate input parameters const validatedParams = ListTasksSchema.parse(params); const allTasks = taskStorage.getAll(); const filter: Partial<Task> = {}; if (validatedParams.status) filter.status = validatedParams.status; if (validatedParams.priority) filter.priority = validatedParams.priority; // Apply filters if any const filteredTasks = Object.keys(filter).length > 0 ? allTasks.filter(task => { return Object.entries(filter).every(([key, value]) => task[key as keyof Task] === value ); }) : allTasks; return JSON.stringify({ tasks: filteredTasks, count: filteredTasks.length, filters: Object.keys(filter).length > 0 ? filter : "none" }); } catch (error) { return JSON.stringify({ error: `Invalid list parameters: ${error instanceof Error ? error.message : String(error)}` }); } } }); // Tool to get next task server.addTool({ name: "next_task", description: "Get the next highest priority todo task and mark it as in-progress.", execute: async () => { try { const nextTask = taskStorage.getHighestPriority("todo"); if (!nextTask) { return JSON.stringify({ message: "No todo tasks found", task: null }); } // Update task status to in-progress const updatedTask = taskStorage.update(nextTask.id, { status: "in-progress" }); return JSON.stringify({ task: updatedTask, message: "Task marked as in-progress" }); } catch (error) { return JSON.stringify({ error: `Failed to get next task: ${error instanceof Error ? error.message : String(error)}` }); } } }); // Tool to complete task server.addTool({ name: "complete_task", description: "Mark a task as completed.", execute: async (params: any) => { try { // Validate input parameters const validatedParams = CompleteTaskSchema.parse(params); const task = taskStorage.get(validatedParams.id); if (!task) { return JSON.stringify({ error: `Task with ID ${validatedParams.id} not found` }); } // Update task status to done const updatedTask = taskStorage.update(validatedParams.id, { status: "done" }); return JSON.stringify({ task: updatedTask, message: "Task marked as completed" }); } catch (error) { return JSON.stringify({ error: `Invalid complete_task parameters: ${error instanceof Error ? error.message : String(error)}` }); } } }); // Tool to update tasks server.addTool({ name: "update_tasks", description: "Update multiple tasks with new values.", execute: async (params: any) => { try { // Validate input parameters const validatedParams = UpdateTasksSchema.parse(params); const results = []; for (const { id, ...changes } of validatedParams.updates) { try { // Verify task exists const task = taskStorage.get(id); if (!task) { results.push({ id, success: false, error: `Task with ID ${id} not found` }); continue; } // Validate dependencies if they exist if (changes.dependsOn) { const missingDependencies = changes.dependsOn.filter(depId => !taskStorage.get(depId)); if (missingDependencies.length > 0) { results.push({ id, success: false, error: `Dependencies not found: ${missingDependencies.join(', ')}` }); continue; } } // Update task const updatedTask = taskStorage.update(id, changes); results.push({ id, success: true, task: updatedTask }); } catch (error) { results.push({ id, success: false, error: `Error updating task: ${error instanceof Error ? error.message : String(error)}` }); } } return JSON.stringify({ updates: results, success: results.filter((r: any) => r.success).length, failed: results.filter((r: any) => !r.success).length }); } catch (error) { return JSON.stringify({ error: `Invalid update_tasks parameters: ${error instanceof Error ? error.message : String(error)}` }); } } }); }

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/flight505/mcp-think-tank'

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