@@ -169,57 +169,23 @@ func (s *Server) handleSetGoal(ctx context.Context, request mcp.CallToolRequest)
arguments := request.GetArguments()
title, ok := arguments["title"].(string)
if !ok || title == "" {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: title parameter is required and must be a string",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: title parameter is required and must be a string"), nil
}
description, ok := arguments["description"].(string)
if !ok {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: description parameter is required and must be a string",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: description parameter is required and must be a string"), nil
}
// Set goal
if err := s.planner.SetGoal(title, description); err != nil {
s.logger.Error("Failed to set goal", "error", err)
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: fmt.Sprintf("Error setting goal: %v", err),
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult(fmt.Sprintf("Error setting goal: %v", err)), nil
}
- goalText := title
- if description != "" {
- goalText = fmt.Sprintf("%s: %s", title, description)
- }
+ goalText := formatGoalText(title, description)
response := fmt.Sprintf("Goal \"%s\" saved! You probably want to add one or more tasks now.", goalText)
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: response,
- },
- },
- }, nil
+ return createSuccessResult(response), nil
}
// handleChangeGoal handles the project_management__change_goal tool call
@@ -230,70 +196,28 @@ func (s *Server) handleChangeGoal(ctx context.Context, request mcp.CallToolReque
arguments := request.GetArguments()
title, ok := arguments["title"].(string)
if !ok || title == "" {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: title parameter is required and must be a string",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: title parameter is required and must be a string"), nil
}
description, ok := arguments["description"].(string)
if !ok {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: description parameter is required and must be a string",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: description parameter is required and must be a string"), nil
}
reason, ok := arguments["reason"].(string)
if !ok || reason == "" {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: reason parameter is required and must be a string",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: reason parameter is required and must be a string"), nil
}
// Change goal
if err := s.planner.ChangeGoal(title, description, reason); err != nil {
s.logger.Error("Failed to change goal", "error", err)
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: fmt.Sprintf("Error changing goal: %v", err),
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult(fmt.Sprintf("Error changing goal: %v", err)), nil
}
- goalText := title
- if description != "" {
- goalText = fmt.Sprintf("%s: %s", title, description)
- }
+ goalText := formatGoalText(title, description)
response := fmt.Sprintf("Goal changed to \"%s\" (reason: %s). You probably want to add one or more tasks now.", goalText, reason)
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: response,
- },
- },
- }, nil
+ return createSuccessResult(response), nil
}
// handleAddTasks handles the project_management__add_tasks tool call
@@ -304,29 +228,13 @@ func (s *Server) handleAddTasks(ctx context.Context, request mcp.CallToolRequest
arguments := request.GetArguments()
tasksRaw, ok := arguments["tasks"]
if !ok {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: tasks parameter is required",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: tasks parameter is required"), nil
}
// Convert to slice of interfaces
tasksSlice, ok := tasksRaw.([]any)
if !ok {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: tasks parameter must be an array",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: tasks parameter must be an array"), nil
}
// Parse tasks
@@ -334,28 +242,12 @@ func (s *Server) handleAddTasks(ctx context.Context, request mcp.CallToolRequest
for _, taskRaw := range tasksSlice {
taskMap, ok := taskRaw.(map[string]any)
if !ok {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: each task must be an object",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: each task must be an object"), nil
}
title, ok := taskMap["title"].(string)
if !ok || title == "" {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: each task must have a non-empty title",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: each task must have a non-empty title"), nil
}
description, _ := taskMap["description"].(string)
@@ -370,15 +262,7 @@ func (s *Server) handleAddTasks(ctx context.Context, request mcp.CallToolRequest
result, err := s.planner.AddTasks(tasks)
if err != nil {
s.logger.Error("Failed to add tasks", "error", err)
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: fmt.Sprintf("Error adding tasks: %v", err),
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult(fmt.Sprintf("Error adding tasks: %v", err)), nil
}
// Get the full task list with goal and legend
@@ -397,14 +281,7 @@ func (s *Server) handleAddTasks(ctx context.Context, request mcp.CallToolRequest
// Had existing tasks - just show the task list (like get_tasks)
response = taskList
}
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: response,
- },
- },
- }, nil
+ return createSuccessResult(response), nil
}
// handleGetTasks handles the project_management__get_tasks tool call
@@ -425,14 +302,7 @@ func (s *Server) handleGetTasks(ctx context.Context, request mcp.CallToolRequest
taskList = s.planner.GetTasksByStatus(statusFilter)
}
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: taskList,
- },
- },
- }, nil
+ return createSuccessResult(taskList), nil
}
// handleUpdateTaskStatuses handles the project_management__update_task_statuses tool call
@@ -443,41 +313,17 @@ func (s *Server) handleUpdateTaskStatuses(ctx context.Context, request mcp.CallT
arguments := request.GetArguments()
tasksRaw, ok := arguments["tasks"]
if !ok {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: tasks parameter is required",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: tasks parameter is required"), nil
}
// Convert to slice of interfaces
tasksSlice, ok := tasksRaw.([]any)
if !ok {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: tasks parameter must be an array",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: tasks parameter must be an array"), nil
}
if len(tasksSlice) == 0 {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: at least one task update is required",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: at least one task update is required"), nil
}
// Parse task updates
@@ -485,41 +331,17 @@ func (s *Server) handleUpdateTaskStatuses(ctx context.Context, request mcp.CallT
for _, taskRaw := range tasksSlice {
taskMap, ok := taskRaw.(map[string]any)
if !ok {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: each task update must be an object",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: each task update must be an object"), nil
}
taskID, ok := taskMap["task_id"].(string)
if !ok || taskID == "" {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: each task update must have a non-empty task_id",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: each task update must have a non-empty task_id"), nil
}
statusStr, ok := taskMap["status"].(string)
if !ok || statusStr == "" {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: each task update must have a non-empty status",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: each task update must have a non-empty status"), nil
}
// Parse status
@@ -534,27 +356,12 @@ func (s *Server) handleUpdateTaskStatuses(ctx context.Context, request mcp.CallT
// Update task statuses
if err := s.planner.UpdateTasks(updates); err != nil {
s.logger.Error("Failed to update task statuses", "error", err)
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: fmt.Sprintf("Error updating task statuses: %v", err),
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult(fmt.Sprintf("Error updating task statuses: %v", err)), nil
}
// Return full task list
taskList := s.planner.GetTasks()
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: taskList,
- },
- },
- }, nil
+ return createSuccessResult(taskList), nil
}
// handleDeleteTasks handles the project_management__delete_tasks tool call
@@ -565,41 +372,17 @@ func (s *Server) handleDeleteTasks(ctx context.Context, request mcp.CallToolRequ
arguments := request.GetArguments()
taskIDsRaw, ok := arguments["task_ids"]
if !ok {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: task_ids parameter is required",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: task_ids parameter is required"), nil
}
// Convert to slice of interfaces
taskIDsSlice, ok := taskIDsRaw.([]any)
if !ok {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: task_ids parameter must be an array",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: task_ids parameter must be an array"), nil
}
if len(taskIDsSlice) == 0 {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: at least one task ID is required",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: at least one task ID is required"), nil
}
// Parse task IDs
@@ -607,15 +390,7 @@ func (s *Server) handleDeleteTasks(ctx context.Context, request mcp.CallToolRequ
for _, taskIDRaw := range taskIDsSlice {
taskID, ok := taskIDRaw.(string)
if !ok || taskID == "" {
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: "Error: each task ID must be a non-empty string",
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult("Error: each task ID must be a non-empty string"), nil
}
taskIDs = append(taskIDs, taskID)
}
@@ -623,27 +398,12 @@ func (s *Server) handleDeleteTasks(ctx context.Context, request mcp.CallToolRequ
// Delete tasks
if err := s.planner.DeleteTasks(taskIDs); err != nil {
s.logger.Error("Failed to delete tasks", "error", err)
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: fmt.Sprintf("Error deleting tasks: %v", err),
- },
- },
- IsError: true,
- }, nil
+ return createErrorResult(fmt.Sprintf("Error deleting tasks: %v", err)), nil
}
// Return full task list
taskList := s.planner.GetTasks()
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: taskList,
- },
- },
- }, nil
+ return createSuccessResult(taskList), nil
}
// GetServer returns the underlying MCP server