feat(tools): add maintenance and meal planning tools with CRUD operations
- Implement maintenance tool for adding, logging, and retrieving tasks - Create meals tool for managing recipes, meal plans, and shopping lists - Introduce reparse metadata tool for updating thought metadata - Add household knowledge, home maintenance, family calendar, meal planning, and professional CRM database migrations - Grant necessary permissions for new database tables
This commit is contained in:
151
internal/tools/household.go
Normal file
151
internal/tools/household.go
Normal file
@@ -0,0 +1,151 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"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 HouseholdTool struct {
|
||||
store *store.DB
|
||||
}
|
||||
|
||||
func NewHouseholdTool(db *store.DB) *HouseholdTool {
|
||||
return &HouseholdTool{store: db}
|
||||
}
|
||||
|
||||
// add_household_item
|
||||
|
||||
type AddHouseholdItemInput struct {
|
||||
Name string `json:"name" jsonschema:"name of the item"`
|
||||
Category string `json:"category,omitempty" jsonschema:"category (e.g. paint, appliance, measurement, document)"`
|
||||
Location string `json:"location,omitempty" jsonschema:"where in the home this item is"`
|
||||
Details map[string]any `json:"details,omitempty" jsonschema:"flexible metadata (model numbers, colors, specs, etc.)"`
|
||||
Notes string `json:"notes,omitempty"`
|
||||
}
|
||||
|
||||
type AddHouseholdItemOutput struct {
|
||||
Item ext.HouseholdItem `json:"item"`
|
||||
}
|
||||
|
||||
func (t *HouseholdTool) AddItem(ctx context.Context, _ *mcp.CallToolRequest, in AddHouseholdItemInput) (*mcp.CallToolResult, AddHouseholdItemOutput, error) {
|
||||
if strings.TrimSpace(in.Name) == "" {
|
||||
return nil, AddHouseholdItemOutput{}, errInvalidInput("name is required")
|
||||
}
|
||||
if in.Details == nil {
|
||||
in.Details = map[string]any{}
|
||||
}
|
||||
item, err := t.store.AddHouseholdItem(ctx, ext.HouseholdItem{
|
||||
Name: strings.TrimSpace(in.Name),
|
||||
Category: strings.TrimSpace(in.Category),
|
||||
Location: strings.TrimSpace(in.Location),
|
||||
Details: in.Details,
|
||||
Notes: strings.TrimSpace(in.Notes),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, AddHouseholdItemOutput{}, err
|
||||
}
|
||||
return nil, AddHouseholdItemOutput{Item: item}, nil
|
||||
}
|
||||
|
||||
// search_household_items
|
||||
|
||||
type SearchHouseholdItemsInput struct {
|
||||
Query string `json:"query,omitempty" jsonschema:"search text matching name or notes"`
|
||||
Category string `json:"category,omitempty" jsonschema:"filter by category"`
|
||||
Location string `json:"location,omitempty" jsonschema:"filter by location"`
|
||||
}
|
||||
|
||||
type SearchHouseholdItemsOutput struct {
|
||||
Items []ext.HouseholdItem `json:"items"`
|
||||
}
|
||||
|
||||
func (t *HouseholdTool) SearchItems(ctx context.Context, _ *mcp.CallToolRequest, in SearchHouseholdItemsInput) (*mcp.CallToolResult, SearchHouseholdItemsOutput, error) {
|
||||
items, err := t.store.SearchHouseholdItems(ctx, in.Query, in.Category, in.Location)
|
||||
if err != nil {
|
||||
return nil, SearchHouseholdItemsOutput{}, err
|
||||
}
|
||||
if items == nil {
|
||||
items = []ext.HouseholdItem{}
|
||||
}
|
||||
return nil, SearchHouseholdItemsOutput{Items: items}, nil
|
||||
}
|
||||
|
||||
// get_household_item
|
||||
|
||||
type GetHouseholdItemInput struct {
|
||||
ID uuid.UUID `json:"id" jsonschema:"item id"`
|
||||
}
|
||||
|
||||
type GetHouseholdItemOutput struct {
|
||||
Item ext.HouseholdItem `json:"item"`
|
||||
}
|
||||
|
||||
func (t *HouseholdTool) GetItem(ctx context.Context, _ *mcp.CallToolRequest, in GetHouseholdItemInput) (*mcp.CallToolResult, GetHouseholdItemOutput, error) {
|
||||
item, err := t.store.GetHouseholdItem(ctx, in.ID)
|
||||
if err != nil {
|
||||
return nil, GetHouseholdItemOutput{}, err
|
||||
}
|
||||
return nil, GetHouseholdItemOutput{Item: item}, nil
|
||||
}
|
||||
|
||||
// add_vendor
|
||||
|
||||
type AddVendorInput struct {
|
||||
Name string `json:"name" jsonschema:"vendor name"`
|
||||
ServiceType string `json:"service_type,omitempty" jsonschema:"type of service (e.g. plumber, electrician, landscaper)"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Website string `json:"website,omitempty"`
|
||||
Notes string `json:"notes,omitempty"`
|
||||
Rating *int `json:"rating,omitempty" jsonschema:"1-5 rating"`
|
||||
}
|
||||
|
||||
type AddVendorOutput struct {
|
||||
Vendor ext.HouseholdVendor `json:"vendor"`
|
||||
}
|
||||
|
||||
func (t *HouseholdTool) AddVendor(ctx context.Context, _ *mcp.CallToolRequest, in AddVendorInput) (*mcp.CallToolResult, AddVendorOutput, error) {
|
||||
if strings.TrimSpace(in.Name) == "" {
|
||||
return nil, AddVendorOutput{}, errInvalidInput("name is required")
|
||||
}
|
||||
vendor, err := t.store.AddVendor(ctx, ext.HouseholdVendor{
|
||||
Name: strings.TrimSpace(in.Name),
|
||||
ServiceType: strings.TrimSpace(in.ServiceType),
|
||||
Phone: strings.TrimSpace(in.Phone),
|
||||
Email: strings.TrimSpace(in.Email),
|
||||
Website: strings.TrimSpace(in.Website),
|
||||
Notes: strings.TrimSpace(in.Notes),
|
||||
Rating: in.Rating,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, AddVendorOutput{}, err
|
||||
}
|
||||
return nil, AddVendorOutput{Vendor: vendor}, nil
|
||||
}
|
||||
|
||||
// list_vendors
|
||||
|
||||
type ListVendorsInput struct {
|
||||
ServiceType string `json:"service_type,omitempty" jsonschema:"filter by service type"`
|
||||
}
|
||||
|
||||
type ListVendorsOutput struct {
|
||||
Vendors []ext.HouseholdVendor `json:"vendors"`
|
||||
}
|
||||
|
||||
func (t *HouseholdTool) ListVendors(ctx context.Context, _ *mcp.CallToolRequest, in ListVendorsInput) (*mcp.CallToolResult, ListVendorsOutput, error) {
|
||||
vendors, err := t.store.ListVendors(ctx, in.ServiceType)
|
||||
if err != nil {
|
||||
return nil, ListVendorsOutput{}, err
|
||||
}
|
||||
if vendors == nil {
|
||||
vendors = []ext.HouseholdVendor{}
|
||||
}
|
||||
return nil, ListVendorsOutput{Vendors: vendors}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user