fix(mcp/task): require area_id in create_task

Amolith created

The Lunatask API requires an area_id when creating tasks, but the MCP
tool incorrectly documented and typed it as optional.

Assisted-by: Claude Opus 4.5 via Crush <crush@charm.land>

Change summary

internal/mcp/tools/task/create.go | 29 ++++++++++-------------------
1 file changed, 10 insertions(+), 19 deletions(-)

Detailed changes

internal/mcp/tools/task/create.go 🔗

@@ -24,9 +24,9 @@ const CreateToolDescription = `Creates a new task in Lunatask.
 
 Required:
 - name: Task title
+- area_id: Area UUID, lunatask:// deep link, or config key
 
 Optional:
-- area_id: Area UUID, lunatask:// deep link, or config key
 - goal_id: Goal UUID, lunatask:// deep link, or config key (requires area_id)
 - status: later, next, started, waiting (default: later)
 - note: Markdown note/description for the task
@@ -42,7 +42,7 @@ Returns the created task's ID and deep link.`
 // CreateInput is the input schema for creating a task.
 type CreateInput struct {
 	Name        string  `json:"name"                   jsonschema:"required"`
-	AreaID      *string `json:"area_id,omitempty"`
+	AreaID      string  `json:"area_id"                jsonschema:"required"`
 	GoalID      *string `json:"goal_id,omitempty"`
 	Status      *string `json:"status,omitempty"`
 	Note        *string `json:"note,omitempty"`
@@ -62,7 +62,7 @@ type CreateOutput struct {
 // parsedCreateInput holds validated and parsed create input fields.
 type parsedCreateInput struct {
 	Name        string
-	AreaID      *string
+	AreaID      string
 	GoalID      *string
 	Status      *lunatask.TaskStatus
 	Note        *string
@@ -128,22 +128,15 @@ func parseCreateInput(cfg *config.Config, input CreateInput) (*parsedCreateInput
 		Urgent:    input.Urgent,
 	}
 
-	if input.AreaID != nil {
-		areaID, err := validate.AreaRef(cfg, *input.AreaID)
-		if err != nil {
-			return nil, shared.ErrorResult(err.Error())
-		}
-
-		parsed.AreaID = &areaID
+	areaID, err := validate.AreaRef(cfg, input.AreaID)
+	if err != nil {
+		return nil, shared.ErrorResult(err.Error())
 	}
 
-	if input.GoalID != nil {
-		areaID := ""
-		if parsed.AreaID != nil {
-			areaID = *parsed.AreaID
-		}
+	parsed.AreaID = areaID
 
-		goalID, err := validate.GoalRef(cfg, areaID, *input.GoalID)
+	if input.GoalID != nil {
+		goalID, err := validate.GoalRef(cfg, parsed.AreaID, *input.GoalID)
 		if err != nil {
 			return nil, shared.ErrorResult(err.Error())
 		}
@@ -198,9 +191,7 @@ func parseCreateInput(cfg *config.Config, input CreateInput) (*parsedCreateInput
 
 //nolint:cyclop
 func applyToTaskBuilder(builder *lunatask.TaskBuilder, parsed *parsedCreateInput) {
-	if parsed.AreaID != nil {
-		builder.InArea(*parsed.AreaID)
-	}
+	builder.InArea(parsed.AreaID)
 
 	if parsed.GoalID != nil {
 		builder.InGoal(*parsed.GoalID)