Skip to main content
Glama

Agentic Tools MCP Server

create.ts4.17 kB
import { z } from 'zod'; import { randomUUID } from 'crypto'; import { Storage } from '../../storage/storage.js'; import { Subtask } from '../../models/subtask.js'; /** * Create a new subtask within a task * * @param storage - Storage instance * @returns MCP tool handler for creating subtasks */ export function createCreateSubtaskTool(storage: Storage) { return { name: 'create_subtask', description: 'Create a new subtask within a specific task', inputSchema: { name: z.string(), details: z.string(), taskId: z.string() }, handler: async ({ name, details, taskId }: { name: string; details: string; taskId: string }) => { try { // Validate inputs if (!name || name.trim().length === 0) { return { content: [{ type: 'text' as const, text: 'Error: Subtask name is required.' }], isError: true }; } if (name.trim().length > 100) { return { content: [{ type: 'text' as const, text: 'Error: Subtask name must be 100 characters or less.' }], isError: true }; } if (!details || details.trim().length === 0) { return { content: [{ type: 'text' as const, text: 'Error: Subtask details are required.' }], isError: true }; } if (details.trim().length > 1000) { return { content: [{ type: 'text' as const, text: 'Error: Subtask details must be 1000 characters or less.' }], isError: true }; } if (!taskId || taskId.trim().length === 0) { return { content: [{ type: 'text' as const, text: 'Error: Task ID is required.' }], isError: true }; } // Validate that task exists const task = await storage.getTask(taskId.trim()); if (!task) { return { content: [{ type: 'text' as const, text: `Error: Task with ID "${taskId}" not found. Use list_tasks to see all available tasks.` }], isError: true }; } // Get project information const project = await storage.getProject(task.projectId); const projectName = project ? project.name : 'Unknown Project'; // Check for duplicate subtask names within the same task const existingSubtasks = await storage.getSubtasks(taskId); const nameExists = existingSubtasks.some(s => s.name.toLowerCase() === name.toLowerCase()); if (nameExists) { return { content: [{ type: 'text' as const, text: `Error: A subtask with the name "${name}" already exists in task "${task.name}". Please choose a different name.` }], isError: true }; } const now = new Date().toISOString(); const subtask: Subtask = { id: randomUUID(), name: name.trim(), details: details.trim(), taskId, projectId: task.projectId, completed: false, createdAt: now, updatedAt: now }; const createdSubtask = await storage.createSubtask(subtask); return { content: [{ type: 'text' as const, text: `✅ Subtask created successfully! **${createdSubtask.name}** (ID: ${createdSubtask.id}) Task: ${task.name} Project: ${projectName} Details: ${createdSubtask.details} Status: Pending Created: ${new Date(createdSubtask.createdAt).toLocaleString()} You can mark this subtask as completed using update_subtask.` }] }; } catch (error) { return { content: [{ type: 'text' as const, text: `Error creating subtask: ${error instanceof Error ? error.message : 'Unknown error'}` }], isError: true }; } } }; }

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/Pimzino/agentic-tools-mcp'

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