@@ -85,6 +85,11 @@ type UpdateTaskResponse struct {
Task Task `json:"task"`
}
+// DeleteTaskResponse represents the response from Lunatask API when deleting a task
+type DeleteTaskResponse struct {
+ Task Task `json:"task"`
+}
+
// ValidationError represents errors returned by the validator
type ValidationError struct {
Field string
@@ -257,3 +262,57 @@ func (c *Client) UpdateTask(ctx context.Context, taskID string, task *CreateTask
return &response, nil
}
+
+// DeleteTask deletes a task in Lunatask
+func (c *Client) DeleteTask(ctx context.Context, taskID string) (*DeleteTaskResponse, error) {
+ if taskID == "" {
+ return nil, errors.New("task ID cannot be empty")
+ }
+
+ // Create the request
+ req, err := http.NewRequestWithContext(
+ ctx,
+ "DELETE",
+ fmt.Sprintf("%s/tasks/%s", c.BaseURL, taskID),
+ nil,
+ )
+ if err != nil {
+ return nil, fmt.Errorf("failed to create HTTP request: %w", err)
+ }
+
+ // Set headers
+ req.Header.Set("Authorization", "bearer "+c.AccessToken)
+
+ // Send the request
+ resp, err := c.HTTPClient.Do(req)
+ if err != nil {
+ return nil, fmt.Errorf("failed to send HTTP request: %w", err)
+ }
+ defer func() {
+ if resp.Body != nil {
+ if err := resp.Body.Close(); err != nil {
+ fmt.Printf("Error closing response body: %v\n", err)
+ }
+ }
+ }()
+
+ // Handle error status codes
+ if resp.StatusCode < 200 || resp.StatusCode >= 300 {
+ respBody, _ := io.ReadAll(resp.Body)
+ return nil, fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(respBody))
+ }
+
+ // Read and parse the response
+ respBody, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read response body: %w", err)
+ }
+
+ var response DeleteTaskResponse
+ err = json.Unmarshal(respBody, &response)
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse response: %w", err)
+ }
+
+ return &response, nil
+}
@@ -297,6 +297,16 @@ func NewMCPServer(config *Config) *server.MCPServer {
return handleUpdateTask(ctx, request, config)
})
+ mcpServer.AddTool(mcp.NewTool("delete_task",
+ mcp.WithDescription("Deletes an existing task"),
+ mcp.WithString("task_id",
+ mcp.Description("ID of the task to delete."),
+ mcp.Required(),
+ ),
+ ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
+ return handleDeleteTask(ctx, request, config)
+ })
+
return mcpServer
}
@@ -619,6 +629,37 @@ func handleUpdateTask(
}, nil
}
+func handleDeleteTask(
+ ctx context.Context,
+ request mcp.CallToolRequest,
+ config *Config,
+) (*mcp.CallToolResult, error) {
+ arguments := request.Params.Arguments
+
+ taskID, ok := arguments["task_id"].(string)
+ if !ok || taskID == "" {
+ return reportMCPError("Missing or invalid required argument: task_id")
+ }
+
+ // Create Lunatask client
+ client := lunatask.NewClient(config.AccessToken)
+
+ // Call the client to delete the task
+ _, err := client.DeleteTask(ctx, taskID)
+ if err != nil {
+ return reportMCPError(fmt.Sprintf("Failed to delete task: %v", err))
+ }
+
+ return &mcp.CallToolResult{
+ Content: []mcp.Content{
+ mcp.TextContent{
+ Type: "text",
+ Text: "Task deleted successfully.",
+ },
+ },
+ }, nil
+}
+
func createDefaultConfigFile(configPath string) {
defaultConfig := Config{
Server: ServerConfig{