updateTask
Modify task details like description, category, priority, or status using the task ID to manage and organize tasks effectively.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| taskId | Yes | The unique ID of the task to update | |
| task | No | New task description/title (if you want to change it) | |
| category | No | New task category (if you want to change it) | |
| priority | No | New task priority (if you want to change it) | |
| status | No | New task status (if you want to change it) |
Implementation Reference
- src/index.ts:452-513 (handler)The core handler function for the 'updateTask' tool. It builds a request body from provided optional parameters and performs a PATCH request to the task API endpoint /tasks/{taskId} using the makeApiRequest helper.async ({ taskId, task, category, priority, status }: { taskId: number; task?: string; category?: string; priority?: string; status?: string; }) => { try { const requestBody: any = {}; if (task) requestBody.task = task; if (category) requestBody.category = category; if (priority) requestBody.priority = priority; if (status) requestBody.status = status; if (Object.keys(requestBody).length === 0) { return { content: [ { type: "text", text: "No updates provided. Task remains unchanged." } ] }; } const updatedTask = await makeApiRequest( "PATCH", `/tasks/${taskId}`, requestBody ); return { content: [ { type: "text", text: `Task ${taskId} updated successfully.` }, { type: "text", text: JSON.stringify({ id: updatedTask.id, task: updatedTask.task, category: updatedTask.category, priority: updatedTask.priority, status: updatedTask.status, created: updatedTask.create_time }, null, 2) } ] }; } catch (error: any) { return { content: [ { type: "text", text: `Error updating task: ${error.message}` } ] }; } }
- src/index.ts:440-451 (schema)Zod input schema for the updateTask tool, defining taskId as required positive integer and other fields as optional strings or enums.{ taskId: z.number().int().positive("Task ID must be a positive integer") .describe("The unique ID of the task to update"), task: z.string().optional() .describe("New task description/title (if you want to change it)"), category: z.string().optional() .describe("New task category (if you want to change it)"), priority: z.enum(["low", "medium", "high"]).optional() .describe("New task priority (if you want to change it)"), status: z.enum(["not_started", "started", "done"]).optional() .describe("New task status (if you want to change it)") },
- src/index.ts:438-439 (registration)Registration of the updateTask tool on the MCP server using server.tool(), which includes the schema and handler.server.tool( "updateTask",
- src/index.ts:68-168 (helper)The makeApiRequest helper function used by updateTask handler to make authenticated PATCH requests to the task management API.async function makeApiRequest(method: string, endpoint: string, data: any = null, params: any = null): Promise<any> { const url = `${API_BASE_URL}${endpoint}`; // Validate that API_KEY is defined if (!API_KEY) { throw new Error("TASK_MANAGER_API_KEY environment variable is not defined. Please check your .env file."); } logDebug(`API Request: ${method} ${url}`); // Standard headers const headers = { "X-API-Key": API_KEY, "Content-Type": "application/json; charset=utf-8", "Accept": "application/json, text/plain, */*", "User-Agent": "TaskMcpServer/1.0", "Connection": "close", "Cache-Control": "no-cache" }; try { // Log request details const logEntry = `Timestamp: ${new Date().toISOString()}\nMethod: ${method}\nURL: ${url}\nParams: ${JSON.stringify(params)}\nData: ${JSON.stringify(data)}\nHeaders: ${JSON.stringify(headers)}\n\n`; fs.appendFileSync("api_debug.log", logEntry); // Configure axios request options const requestConfig: any = { method, url, headers, data, params, maxRedirects: 0, timeout: 20000, decompress: false, validateStatus: function (status: number) { return status < 500; // Don't reject if status code is less than 500 } }; // Ensure proper data encoding for all requests if (data) { requestConfig.data = JSON.stringify(data); } // Add transform request for properly handling all requests requestConfig.transformRequest = [(data: any, headers: any) => { // Force proper content type headers['Content-Type'] = 'application/json; charset=utf-8'; return typeof data === 'string' ? data : JSON.stringify(data); }]; // Add specific URL handling for individual task endpoints if (endpoint.startsWith('/tasks/') && method === 'GET') { // Fix to retrieve individual task by adding specific query parameters requestConfig.params = { ...params, id: endpoint.split('/')[2] }; } const response = await axios(requestConfig); // Check for HTTP error status codes we didn't automatically reject if (response.status >= 400 && response.status < 500) { logError(`HTTP error ${response.status} from API`, response.data); // Enhanced error logging const errorLogEntry = `Timestamp: ${new Date().toISOString()}\nError: HTTP ${response.status}\nURL: ${url}\nMethod: ${method}\nResponse: ${JSON.stringify(response.data)}\n\n`; fs.appendFileSync("api_error.log", errorLogEntry); throw new Error(`API Error (${response.status}): ${JSON.stringify(response.data)}`); } // Check if response has expected format if ((method === "POST" && endpoint === "/tasks/list") || (method === "GET" && endpoint === "/tasks")) { logDebug(`listTasks response`, response.data.tasks || []); if (!response.data || !response.data.tasks || response.data.tasks.length === 0) { logDebug("API returned empty tasks array"); } } return response.data; } catch (error: any) { logError(`API Error: ${error.message}`); // Enhanced error logging with more details const errorDetails = error.response ? `Status: ${error.response.status}, Data: ${JSON.stringify(error.response.data || 'No response data')}` : (error.request ? 'No response received' : error.message); const errorLogEntry = `Timestamp: ${new Date().toISOString()}\nError: ${error.message}\nDetails: ${errorDetails}\nURL: ${url}\nMethod: ${method}\n\n`; fs.appendFileSync("api_error.log", errorLogEntry); if (error.response) { throw new Error( `API Error (${error.response.status}): ${JSON.stringify(error.response.data || 'No response data')}`, ); } else if (error.request) { throw new Error(`API Request Error: No response received (possible network issue)`); } throw error; } }
- src/http-server.ts:468-530 (handler)Identical handler implementation in the HTTP server variant of the MCP server.async ({ taskId, task, category, priority, status }: { taskId: number; task?: string; category?: string; priority?: string; status?: string; }) => { try { const requestBody: any = {}; if (task) requestBody.task = task; if (category) requestBody.category = category; if (priority) requestBody.priority = priority; if (status) requestBody.status = status; if (Object.keys(requestBody).length === 0) { return { content: [ { type: "text", text: "No updates provided. Task remains unchanged." } ] }; } const updatedTask = await makeApiRequest( "PATCH", `/tasks/${taskId}`, requestBody ); return { content: [ { type: "text", text: `Task ${taskId} updated successfully.` }, { type: "text", text: JSON.stringify({ id: updatedTask.id, task: updatedTask.task, category: updatedTask.category, priority: updatedTask.priority, status: updatedTask.status, created: updatedTask.create_time }, null, 2) } ] }; } catch (error: any) { return { content: [ { type: "text", text: `Error updating task: ${error.message}` } ] }; } } );