From ed5c9b0d8fb43eb17bda847ec794bde02ae2f7bd Mon Sep 17 00:00:00 2001 From: Amolith Date: Fri, 18 Apr 2025 20:38:33 -0600 Subject: [PATCH] feat: add new tools for listing areas and goals Add new tools to the MCP server for listing areas and their IDs, and listing goals and their IDs. Update the LunataskCreateTaskRequest struct to include validation rules and default values for the AreaID field. - Adds a new tool "list_areas" to the MCP server. - Adds a new tool "list_goals" to the MCP server. - Updates the LunataskCreateTaskRequest struct to include validation rules and default values for the AreaID field. --- main.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/main.go b/main.go index b26667732decf3a04b57f25ce454b3c81b4208e4..d51d4932e99bf26545689d61355f0008894eb274 100644 --- a/main.go +++ b/main.go @@ -177,22 +177,66 @@ func NewMCPServer(config *Config) *server.MCPServer { return handleCreateTask(ctx, request, config) }) + mcpServer.AddTool( + mcp.NewTool( + "list_areas", + mcp.WithDescription("List areas and their IDs."), + ), + func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + var b strings.Builder + b.WriteString("| Area Name | Area ID |\n|-----------|--------|\n") + for _, area := range config.Areas { + fmt.Fprintf(&b, "| %s | %s |\n", area.Name, area.ID) + } + return &mcp.CallToolResult{ + Content: []mcp.Content{ + mcp.TextContent{ + Type: "text", + Text: b.String(), + }, + }, + }, nil + }, + ) + + mcpServer.AddTool( + mcp.NewTool( + "list_goals", + mcp.WithDescription("List goals and their IDs."), + ), + func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + var b strings.Builder + b.WriteString("| Goal Name | Goal ID |\n|----------|--------|\n") + for _, goal := range config.Goals { + fmt.Fprintf(&b, "| %s | %s |\n", goal.Name, goal.ID) + } + return &mcp.CallToolResult{ + Content: []mcp.Content{ + mcp.TextContent{ + Type: "text", + Text: b.String(), + }, + }, + }, nil + }, + ) + return mcpServer } // LunataskCreateTaskRequest represents the request payload for creating a task in Lunatask type LunataskCreateTaskRequest struct { AreaID string `json:"area_id"` - GoalID string `json:"goal_id,omitempty"` + GoalID string `json:"goal_id,omitempty" validate:"omitempty"` Name string `json:"name" validate:"max=100"` - Note string `json:"note,omitempty"` - Status string `json:"status,omitempty" validate:"oneof=later next started waiting completed"` - Motivation string `json:"motivation,omitempty" validate:"oneof=must should want unknown"` - Estimate int `json:"estimate,omitempty" validate:"min=0,max=720"` - Priority int `json:"priority,omitempty" validate:"min=-2,max=2"` - ScheduledOn string `json:"scheduled_on,omitempty"` - CompletedAt string `json:"completed_at,omitempty"` - Source string `json:"source,omitempty"` + Note string `json:"note,omitempty" validate:"omitempty"` + Status string `json:"status,omitempty" validate:"omitempty,oneof=later next started waiting completed"` + Motivation string `json:"motivation,omitempty" validate:"omitempty,oneof=must should want unknown"` + Estimate int `json:"estimate,omitempty" validate:"omitempty,min=0,max=720"` + Priority int `json:"priority,omitempty" validate:"omitempty,min=-2,max=2"` + ScheduledOn string `json:"scheduled_on,omitempty" validate:"omitempty"` + CompletedAt string `json:"completed_at,omitempty" validate:"omitempty"` + Source string `json:"source,omitempty" validate:"omitempty"` } // LunataskCreateTaskResponse represents the response from Lunatask API when creating a task @@ -218,7 +262,7 @@ func handleCreateTask( arguments := request.Params.Arguments payload := LunataskCreateTaskRequest{ - Source: "lmcps", + AreaID: config.Areas[0].ID, } argBytes, err := json.Marshal(arguments) if err != nil {