Skip to main content
Glama
brysontang

DeltaTask MCP Server

by brysontang

delete_task

Remove tasks from the DeltaTask MCP Server task management system by specifying the task ID to clear completed or unnecessary items.

Instructions

Delete a task.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
task_idYes

Implementation Reference

  • server.py:53-56 (handler)
    MCP tool handler for 'delete_task', decorated with @mcp.tool() which registers it. Delegates deletion to TaskService.delete_task_by_id.
    @mcp.tool()
    async def delete_task(task_id: str) -> dict[str, Any]:
        """Delete a task."""
        return service.delete_task_by_id(task_id)
  • Core service method implementing task deletion: validates existence, deletes from database (optionally subtasks), deletes markdown file, updates views.
    def delete_task_by_id(self, task_id: str, 
                        delete_subtasks: bool = True) -> Dict[str, Any]:
        """Delete a task and return success status."""
        logger.info(f"Deleting task {task_id} (with subtasks: {delete_subtasks})")
        
        try:
            # Check if task exists
            existing_task = self.repository.get_todo_by_id(task_id)
            if not existing_task:
                logger.warning(f"Attempted to delete non-existent task: {task_id}")
                return {"error": "Task not found"}
            
            try:
                # Delete from database
                success = self.repository.delete_todo(task_id, delete_subtasks)
                
                if not success:
                    logger.error(f"Database deletion failed for task {task_id}")
                    return {"error": "Failed to delete task from database"}
                
                logger.info(f"Task {task_id} deleted from database")
            except Exception as e:
                logger.error(f"Error deleting task {task_id} from database: {e}", exc_info=True)
                raise
            
            try:
                # Delete markdown file
                self.markdown_manager.delete_task_file(task_id)
                logger.info(f"Markdown file deleted for task {task_id}")
            except Exception as e:
                logger.error(f"Error deleting markdown for task {task_id}: {e}", exc_info=True)
                # Continue even if markdown deletion fails
            
            try:
                # Update views
                self._update_all_views()
                logger.info("Task views updated after task deletion")
            except Exception as e:
                logger.error(f"Error updating views after task deletion: {e}", exc_info=True)
                # Continue even if views update fails
            
            return {"message": "Task deleted successfully"}
            
        except Exception as e:
            # Handle other errors
            logger.error(f"Unexpected error deleting task {task_id}: {e}", exc_info=True)
            return {"error": f"Failed to delete task: {str(e)}"}
  • Deletes the task markdown file and performs cleanup: removes parent/child links and entries from tag files.
    def delete_task_file(self, task_id: str) -> None:
        """Delete a task markdown file."""
        # Try to find the task file with any name pattern that starts with the task ID
        tasks_dir = os.path.join(self.vault_path, "tasks")
        matching_files = []
        
        if os.path.exists(tasks_dir):
            for filename in os.listdir(tasks_dir):
                if filename.startswith(f"{task_id}") and filename.endswith(".md"):
                    matching_files.append(os.path.join(tasks_dir, filename))
        
        if not matching_files:
            logger.warning(f"Task file {task_id} not found when attempting to delete")
            return
            
        # Use the first matching file
        task_file = matching_files[0]
            
        try:
            # Get task data before deletion
            post = frontmatter.load(task_file)
            parent_id = post.get("parent")
            tags = post.get("tags", [])
            task_title = post.get("title", f"Task {task_id}")
            
            # Remove this task from all child tasks' parent link
            # This ensures if a parent is deleted, child tasks no longer reference it
            self._remove_parent_links_from_children(task_id)
            
            # Remove from parent's subtasks list
            if parent_id:
                logger.info(f"Removing task {task_id} from parent {parent_id}")
                self._remove_from_parent_subtasks(parent_id, task_id)
            
            # Remove from tag files
            if tags:
                logger.info(f"Removing task {task_id} from {len(tags)} tags")
                for tag in tags:
                    self._remove_task_from_tag(tag, task_id)
            
            # Delete the task file
            try:
                os.remove(task_file)
                logger.info(f"Deleted task file {task_id}")
            except OSError as e:
                logger.error(f"Error deleting task file {task_file}: {e}", exc_info=True)
                raise
                
        except frontmatter.FrontmatterError as e:
            logger.error(f"Frontmatter error when deleting task {task_id}: {e}", exc_info=True)
            # Try to force delete the file if it exists
            if os.path.exists(task_file):
                try:
                    os.remove(task_file)
                    logger.info(f"Force deleted task file {task_id} after frontmatter error")
                except OSError as delete_error:
                    logger.error(f"Failed to force delete task file {task_file}: {delete_error}", exc_info=True)
        except Exception as e:
            logger.error(f"Error deleting task file {task_id}: {e}", exc_info=True)
            raise

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/brysontang/DeltaTask'

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