# Implementation Plan
**Project**: mealie-mcp-enhancements
**Generated**: 2025-12-12T22:30:00Z
## Technical Context & Standards
*Detected Stack & Patterns*
- **Framework**: TypeScript + MCP SDK (@modelcontextprotocol/sdk v1.12.0)
- **Validation**: Zod for tool parameter schemas
- **API Client**: `MealieClient` class in `src/client.ts` with `_handleRequest<T>()` method
- **Tool Pattern**: `server.tool(name, description, zodSchema, handler)` in `src/tools/*.ts`
- **Types**: Defined in `src/types/*.ts`, exported via `src/types/index.ts`
- **Conventions**: ES modules (`.js` imports), camelCase, async/await
---
## Phase 1: Types & Client Foundation
- [x] **Add RecipeNote type** (ref: Recipe Notes)
Task ID: phase-1-types-01
> **Implementation**: Edit `src/types/recipe.ts`.
> **Details**: Add `RecipeNote` interface with `title: string` and `text: string` (both required per OpenAPI spec). Update `Recipe` interface to type `notes` as `RecipeNote[]` instead of `unknown[]`.
- [x] **Add image upload method to MealieClient** (ref: Recipe Images)
Task ID: phase-1-client-02
> **Implementation**: Edit `src/client.ts`.
> **Details**: Add `uploadRecipeImage(slug: string, imageData: Buffer, filename: string): Promise<void>` method. Use multipart/form-data with `Content-Type: multipart/form-data` header. API endpoint: `PUT /api/recipes/{slug}/image`. Must temporarily override the default JSON content-type header for this request.
- [x] **Add image fetch utility** (ref: Recipe Images)
Task ID: phase-1-client-03
> **Implementation**: Edit `src/client.ts`.
> **Details**: Add `fetchImageFromUrl(url: string): Promise<{data: Buffer, contentType: string}>` method. Use Node.js `fetch` to download image. Extract content-type from response headers. Throw descriptive error if fetch fails (404, timeout, etc.).
---
## Phase 2: Recipe Tool Enhancements
- [x] **Add notes parameter to create_recipe** (ref: Recipe Notes)
Task ID: phase-2-recipe-01
> **Implementation**: Edit `src/tools/recipe.ts`.
> **Details**: Add `notes` parameter to `create_recipe` tool schema: `z.array(z.object({title: z.string(), text: z.string()})).optional()`. Pass notes array to `updateRecipe()` call after initial creation. Default to empty array if not provided.
- [x] **Add servings parameters to create_recipe** (ref: Recipe Servings)
Task ID: phase-2-recipe-02
> **Implementation**: Edit `src/tools/recipe.ts`.
> **Details**: Add to `create_recipe` schema: `servings: z.number().optional()` (maps to `recipeServings`) and `yield_text: z.string().optional()` (maps to `recipeYield`). Pass both fields in the `updateRecipe()` call.
- [x] **Add notes parameter to update_recipe** (ref: Recipe Notes)
Task ID: phase-2-recipe-03
> **Implementation**: Edit `src/tools/recipe.ts`.
> **Details**: Add `notes` parameter to `update_recipe` tool schema with same structure as create_recipe. Include notes in the recipe update payload.
- [x] **Add servings parameters to update_recipe** (ref: Recipe Servings)
Task ID: phase-2-recipe-04
> **Implementation**: Edit `src/tools/recipe.ts`.
> **Details**: Add `servings` and `yield_text` parameters to `update_recipe` schema. Include `recipeServings` and `recipeYield` in update payload.
- [x] **Update tool descriptions for structured ingredients** (ref: Structured Ingredients Guidance)
Task ID: phase-2-recipe-05
> **Implementation**: Edit `src/tools/recipe.ts`.
> **Details**: Update descriptions for `create_recipe` and `update_recipe` to emphasize: "PREFERRED: Use structured ingredients with {quantity, unit, food, note} for proper tracking in Mealie. This enables meal planning and shopping list features. Plain text strings are supported as fallback but lose these benefits."
---
## Phase 3: Image Upload Tool
- [x] **Create add_recipe_image tool** (ref: Recipe Images)
Task ID: phase-3-image-01
> **Implementation**: Edit `src/tools/recipe.ts`.
> **Details**: Add new tool `add_recipe_image` with parameters:
> - `slug: z.string()` - Recipe identifier (required)
> - `image_url: z.string().optional()` - URL to fetch image from
> - `image_base64: z.string().optional()` - Base64 encoded image data
> Validation: Require exactly one of image_url or image_base64.
> If URL: call `client.fetchImageFromUrl()` then `client.uploadRecipeImage()`.
> If base64: decode to Buffer, call `client.uploadRecipeImage()`.
> Return success message with recipe slug.
- [x] **Add error handling for image operations** (ref: Recipe Images)
Task ID: phase-3-image-02
> **Implementation**: Edit `src/tools/recipe.ts`.
> **Details**: Wrap image operations in try/catch. Handle specific errors:
> - URL fetch failure: "Failed to fetch image from URL: {reason}"
> - Upload failure: "Failed to upload image to recipe: {reason}"
> - Invalid base64: "Invalid base64 image data"
> Use existing `formatErrorResponse()` utility from `src/utils.js`.
---
## Phase 4: Export & Verification
- [x] **Export RecipeNote type** (ref: Types)
Task ID: phase-4-export-01
> **Implementation**: Edit `src/types/index.ts`.
> **Details**: Add `RecipeNote` to the exports from `./recipe.js` if not already exported.
- [x] **Build and verify compilation** (ref: Verification)
Task ID: phase-4-verify-01
> **Implementation**: Run `npm run build`.
> **Details**: Ensure TypeScript compiles without errors. Fix any type mismatches.
- [x] **Run existing tests** (ref: Verification)
Task ID: phase-4-verify-02
> **Implementation**: Run `npm test`.
> **Details**: Ensure existing tests still pass. Add basic tests for new functionality if time permits.
---
*Generated by Clavix /clavix:plan*