package tools // import ( // "context" // "strings" // "time" // "github.com/google/uuid" // "github.com/modelcontextprotocol/go-sdk/mcp" // "git.warky.dev/wdevs/amcs/internal/store" // ext "git.warky.dev/wdevs/amcs/internal/types" // ) // type MealsTool struct { // store *store.DB // } // func NewMealsTool(db *store.DB) *MealsTool { // return &MealsTool{store: db} // } // // add_recipe // type AddRecipeInput struct { // Name string `json:"name" jsonschema:"recipe name"` // Cuisine string `json:"cuisine,omitempty"` // PrepTimeMinutes *int `json:"prep_time_minutes,omitempty"` // CookTimeMinutes *int `json:"cook_time_minutes,omitempty"` // Servings *int `json:"servings,omitempty"` // Ingredients []ext.Ingredient `json:"ingredients,omitempty" jsonschema:"list of ingredients with name, quantity, unit"` // Instructions []string `json:"instructions,omitempty" jsonschema:"ordered list of steps"` // Tags []string `json:"tags,omitempty"` // Rating *int `json:"rating,omitempty" jsonschema:"1-5 rating"` // Notes string `json:"notes,omitempty"` // } // type AddRecipeOutput struct { // Recipe ext.Recipe `json:"recipe"` // } // func (t *MealsTool) AddRecipe(ctx context.Context, _ *mcp.CallToolRequest, in AddRecipeInput) (*mcp.CallToolResult, AddRecipeOutput, error) { // if strings.TrimSpace(in.Name) == "" { // return nil, AddRecipeOutput{}, errRequiredField("name") // } // if in.Ingredients == nil { // in.Ingredients = []ext.Ingredient{} // } // if in.Instructions == nil { // in.Instructions = []string{} // } // if in.Tags == nil { // in.Tags = []string{} // } // recipe, err := t.store.AddRecipe(ctx, ext.Recipe{ // Name: strings.TrimSpace(in.Name), // Cuisine: strings.TrimSpace(in.Cuisine), // PrepTimeMinutes: in.PrepTimeMinutes, // CookTimeMinutes: in.CookTimeMinutes, // Servings: in.Servings, // Ingredients: in.Ingredients, // Instructions: in.Instructions, // Tags: in.Tags, // Rating: in.Rating, // Notes: strings.TrimSpace(in.Notes), // }) // if err != nil { // return nil, AddRecipeOutput{}, err // } // return nil, AddRecipeOutput{Recipe: recipe}, nil // } // // search_recipes // type SearchRecipesInput struct { // Query string `json:"query,omitempty" jsonschema:"search by recipe name"` // Cuisine string `json:"cuisine,omitempty"` // Tags []string `json:"tags,omitempty" jsonschema:"filter by tags (all must match)"` // Ingredient string `json:"ingredient,omitempty" jsonschema:"filter by ingredient name"` // } // type SearchRecipesOutput struct { // Recipes []ext.Recipe `json:"recipes"` // } // func (t *MealsTool) SearchRecipes(ctx context.Context, _ *mcp.CallToolRequest, in SearchRecipesInput) (*mcp.CallToolResult, SearchRecipesOutput, error) { // recipes, err := t.store.SearchRecipes(ctx, in.Query, in.Cuisine, in.Tags, in.Ingredient) // if err != nil { // return nil, SearchRecipesOutput{}, err // } // if recipes == nil { // recipes = []ext.Recipe{} // } // return nil, SearchRecipesOutput{Recipes: recipes}, nil // } // // update_recipe // type UpdateRecipeInput struct { // ID uuid.UUID `json:"id" jsonschema:"recipe id to update"` // Name string `json:"name" jsonschema:"recipe name"` // Cuisine string `json:"cuisine,omitempty"` // PrepTimeMinutes *int `json:"prep_time_minutes,omitempty"` // CookTimeMinutes *int `json:"cook_time_minutes,omitempty"` // Servings *int `json:"servings,omitempty"` // Ingredients []ext.Ingredient `json:"ingredients,omitempty"` // Instructions []string `json:"instructions,omitempty"` // Tags []string `json:"tags,omitempty"` // Rating *int `json:"rating,omitempty"` // Notes string `json:"notes,omitempty"` // } // type UpdateRecipeOutput struct { // Recipe ext.Recipe `json:"recipe"` // } // func (t *MealsTool) UpdateRecipe(ctx context.Context, _ *mcp.CallToolRequest, in UpdateRecipeInput) (*mcp.CallToolResult, UpdateRecipeOutput, error) { // if strings.TrimSpace(in.Name) == "" { // return nil, UpdateRecipeOutput{}, errRequiredField("name") // } // if in.Ingredients == nil { // in.Ingredients = []ext.Ingredient{} // } // if in.Instructions == nil { // in.Instructions = []string{} // } // if in.Tags == nil { // in.Tags = []string{} // } // recipe, err := t.store.UpdateRecipe(ctx, in.ID, ext.Recipe{ // Name: strings.TrimSpace(in.Name), // Cuisine: strings.TrimSpace(in.Cuisine), // PrepTimeMinutes: in.PrepTimeMinutes, // CookTimeMinutes: in.CookTimeMinutes, // Servings: in.Servings, // Ingredients: in.Ingredients, // Instructions: in.Instructions, // Tags: in.Tags, // Rating: in.Rating, // Notes: strings.TrimSpace(in.Notes), // }) // if err != nil { // return nil, UpdateRecipeOutput{}, err // } // return nil, UpdateRecipeOutput{Recipe: recipe}, nil // } // // create_meal_plan // type CreateMealPlanInput struct { // WeekStart time.Time `json:"week_start" jsonschema:"Monday of the week to plan"` // Meals []ext.MealPlanInput `json:"meals" jsonschema:"list of meal entries for the week"` // } // type CreateMealPlanOutput struct { // Entries []ext.MealPlanEntry `json:"entries"` // } // func (t *MealsTool) CreateMealPlan(ctx context.Context, _ *mcp.CallToolRequest, in CreateMealPlanInput) (*mcp.CallToolResult, CreateMealPlanOutput, error) { // if len(in.Meals) == 0 { // return nil, CreateMealPlanOutput{}, errInvalidInput("meals are required") // } // entries, err := t.store.CreateMealPlan(ctx, in.WeekStart, in.Meals) // if err != nil { // return nil, CreateMealPlanOutput{}, err // } // if entries == nil { // entries = []ext.MealPlanEntry{} // } // return nil, CreateMealPlanOutput{Entries: entries}, nil // } // // get_meal_plan // type GetMealPlanInput struct { // WeekStart time.Time `json:"week_start" jsonschema:"Monday of the week to retrieve"` // } // type GetMealPlanOutput struct { // Entries []ext.MealPlanEntry `json:"entries"` // } // func (t *MealsTool) GetMealPlan(ctx context.Context, _ *mcp.CallToolRequest, in GetMealPlanInput) (*mcp.CallToolResult, GetMealPlanOutput, error) { // entries, err := t.store.GetMealPlan(ctx, in.WeekStart) // if err != nil { // return nil, GetMealPlanOutput{}, err // } // if entries == nil { // entries = []ext.MealPlanEntry{} // } // return nil, GetMealPlanOutput{Entries: entries}, nil // } // // generate_shopping_list // type GenerateShoppingListInput struct { // WeekStart time.Time `json:"week_start" jsonschema:"Monday of the week to generate shopping list for"` // } // type GenerateShoppingListOutput struct { // ShoppingList ext.ShoppingList `json:"shopping_list"` // } // func (t *MealsTool) GenerateShoppingList(ctx context.Context, _ *mcp.CallToolRequest, in GenerateShoppingListInput) (*mcp.CallToolResult, GenerateShoppingListOutput, error) { // list, err := t.store.GenerateShoppingList(ctx, in.WeekStart) // if err != nil { // return nil, GenerateShoppingListOutput{}, err // } // return nil, GenerateShoppingListOutput{ShoppingList: list}, nil // }