delete-checklist-item
Remove a specific subtask from a Microsoft Todo task while keeping the parent task intact. Delete checklist items to clean up completed or unnecessary subtasks.
Instructions
Delete a checklist item (subtask) from a task. This removes just the specific subtask, not the parent task.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| listId | Yes | ID of the task list | |
| taskId | Yes | ID of the task | |
| checklistItemId | Yes | ID of the checklist item to delete |
Implementation Reference
- src/todo-index.ts:1377-1421 (handler)The handler function for the 'delete-checklist-item' tool. It authenticates, constructs the Microsoft Graph API DELETE URL for the specific checklist item, calls makeGraphRequest to delete it, and returns success or error messages.async ({ listId, taskId, checklistItemId }) => { try { const token = await getAccessToken(); if (!token) { return { content: [ { type: "text", text: "Failed to authenticate with Microsoft API", }, ], }; } // Make a DELETE request to the Microsoft Graph API const url = `${MS_GRAPH_BASE}/me/todo/lists/${listId}/tasks/${taskId}/checklistItems/${checklistItemId}`; console.error(`Deleting checklist item: ${url}`); // The DELETE method doesn't return a response body, so we expect null await makeGraphRequest<null>( url, token, "DELETE" ); // If we get here, the delete was successful (204 No Content) return { content: [ { type: "text", text: `Checklist item with ID: ${checklistItemId} was successfully deleted from task: ${taskId}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error deleting checklist item: ${error}`, }, ], }; } }
- src/todo-index.ts:1372-1376 (schema)Zod input schema defining the required parameters: listId, taskId, and checklistItemId for identifying the checklist item to delete.{ listId: z.string().describe("ID of the task list"), taskId: z.string().describe("ID of the task"), checklistItemId: z.string().describe("ID of the checklist item to delete") },
- src/todo-index.ts:1369-1422 (registration)The server.tool registration for the 'delete-checklist-item' tool, including name, description, input schema, and handler function.server.tool( "delete-checklist-item", "Delete a checklist item (subtask) from a task. This removes just the specific subtask, not the parent task.", { listId: z.string().describe("ID of the task list"), taskId: z.string().describe("ID of the task"), checklistItemId: z.string().describe("ID of the checklist item to delete") }, async ({ listId, taskId, checklistItemId }) => { try { const token = await getAccessToken(); if (!token) { return { content: [ { type: "text", text: "Failed to authenticate with Microsoft API", }, ], }; } // Make a DELETE request to the Microsoft Graph API const url = `${MS_GRAPH_BASE}/me/todo/lists/${listId}/tasks/${taskId}/checklistItems/${checklistItemId}`; console.error(`Deleting checklist item: ${url}`); // The DELETE method doesn't return a response body, so we expect null await makeGraphRequest<null>( url, token, "DELETE" ); // If we get here, the delete was successful (204 No Content) return { content: [ { type: "text", text: `Checklist item with ID: ${checklistItemId} was successfully deleted from task: ${taskId}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error deleting checklist item: ${error}`, }, ], }; } } );
- src/todo-index.ts:75-137 (helper)Helper function makeGraphRequest used by the handler to make authenticated HTTP requests to Microsoft Graph API, including the DELETE call.async function makeGraphRequest<T>(url: string, token: string, method = "GET", body?: any): Promise<T | null> { const headers = { "User-Agent": USER_AGENT, "Accept": "application/json", "Authorization": `Bearer ${token}`, "Content-Type": "application/json" }; try { const options: RequestInit = { method, headers }; if (body && (method === "POST" || method === "PATCH")) { options.body = JSON.stringify(body); } console.error(`Making request to: ${url}`); console.error(`Request options: ${JSON.stringify({ method, headers: { ...headers, Authorization: 'Bearer [REDACTED]' } })}`); const response = await fetch(url, options); if (!response.ok) { const errorText = await response.text(); console.error(`HTTP error! status: ${response.status}, body: ${errorText}`); // Check for the specific MailboxNotEnabledForRESTAPI error if (errorText.includes('MailboxNotEnabledForRESTAPI')) { console.error(` ================================================================= ERROR: MailboxNotEnabledForRESTAPI The Microsoft To Do API is not available for personal Microsoft accounts (outlook.com, hotmail.com, live.com, etc.) through the Graph API. This is a limitation of the Microsoft Graph API, not an authentication issue. Microsoft only allows To Do API access for Microsoft 365 business accounts. You can still use Microsoft To Do through the web interface or mobile apps, but API access is restricted for personal accounts. ================================================================= `); throw new Error("Microsoft To Do API is not available for personal Microsoft accounts. See console for details."); } throw new Error(`HTTP error! status: ${response.status}, body: ${errorText}`); } const data = await response.json(); console.error(`Response received: ${JSON.stringify(data).substring(0, 200)}...`); return data as T; } catch (error) { console.error("Error making Graph API request:", error); return null; }
- src/todo-index.ts:192-243 (helper)Helper function getAccessToken used by the handler to obtain a valid access token, handling refresh if necessary.async function getAccessToken(): Promise<string | null> { try { console.error('getAccessToken called'); // First check if we have a valid current access token in memory if (currentAccessToken) { return currentAccessToken; } // Check for tokens in environment variables or file try { // Read token file const tokenData = readTokens(); if (tokenData) { // Check if token is expired const now = Date.now(); if (now > tokenData.expiresAt) { console.error(`Token is expired. Current time: ${now}, expires at: ${tokenData.expiresAt}`); // If we have a refresh token, try to refresh the access token if (tokenData.refreshToken || currentRefreshToken) { console.error('Attempting to refresh token...'); const refreshTokenToUse = currentRefreshToken || tokenData.refreshToken; const newTokenData = await refreshAccessToken(refreshTokenToUse); if (newTokenData) { console.error('Token refreshed successfully'); return newTokenData.accessToken; } console.error('Token refresh failed'); } return null; } // Success - return the token and update current state currentAccessToken = tokenData.accessToken; currentRefreshToken = tokenData.refreshToken; console.error(`Successfully retrieved valid token (${tokenData.accessToken.substring(0, 10)}...)`); return tokenData.accessToken; } } catch (readError) { console.error(`Direct token read error: ${readError}`); return null; } return null; } catch (error) { console.error("Error getting access token:", error); return null; } }