diff --git a/features/cooked-mcp/recipes.feature.yaml b/features/cooked-mcp/recipes.feature.yaml index 4a5cb0ea18f428b1e343aa72353780d8dfc17501..7dacc37e38828ba7b179f82da962439c08b33d4f 100644 --- a/features/cooked-mcp/recipes.feature.yaml +++ b/features/cooked-mcp/recipes.feature.yaml @@ -12,20 +12,24 @@ components: 5: The read tool reads a single recipe when its target is recipe and a recipe ID is provided. 6: A single recipe read includes recipe metadata needed for agent decisions. 6-1: A single recipe read includes the recipe title when Cooked provides it. - 6-2: A single recipe read includes owner or edit-permission information when Cooked provides it. + 6-2: + requirement: A single recipe read includes owner information when Cooked provides it. + deprecated: true + 6-3: A single recipe read omits edit-permission information. 7: A single recipe read includes recipe content. 8: A single recipe read includes portions. 8-1: Recipe reads preserve fractional portions when Cooked provides them. 9: Recipe reads omit image URLs unless a future feature explicitly exposes them. PREVIEW_TEXT: requirements: - 1: The preview_recipe_text tool previews raw recipe text without saving a recipe. - 1-1: Previewing raw recipe text requires a recipe title. - 1-2: Previewing raw recipe text requires the raw recipe text. - 2: The preview_recipe_text tool returns the preview title. - 3: The preview_recipe_text tool returns preview markdown. - 4: The preview_recipe_text tool returns preview portions. - 4-1: The preview_recipe_text tool preserves fractional portions when Cooked provides them. + 1: The extract_into_recipe tool extracts raw recipe text into Cooked recipe markdown and portions without saving a recipe. + 1-1: Extracting raw recipe text requires a recipe title. + 1-2: Extracting raw recipe text requires the raw recipe text. + 1-3: Extracting raw recipe text accepts an optional portions hint for the extraction output. + 2: The extract_into_recipe tool returns the extracted title. + 3: The extract_into_recipe tool returns extracted markdown. + 4: The extract_into_recipe tool returns extracted portions. + 4-1: The extract_into_recipe tool preserves fractional portions when Cooked provides them. SAVE: requirements: 1: The save_recipe tool saves a recipe from raw text. @@ -34,7 +38,7 @@ components: 2: The save_recipe tool saves a recipe from prepared markdown and portions. 2-1: Saving prepared markdown requires a recipe title. 2-2: Saving prepared markdown requires recipe markdown. - 2-3: Saving prepared markdown requires portions. + 2-3: Saving prepared markdown defaults portions to 1 when omitted. 3: The save_recipe tool imports a recipe from a URL. 3-1: Importing a recipe from a URL requires a URL. 4: When URL import creates a saved recipe immediately, save_recipe returns the new recipe ID. @@ -45,12 +49,15 @@ components: 7-2: Saving a reviewed extraction draft may include reviewed markdown and portions. 7-3: Saving a reviewed extraction draft without reviewed markdown and portions uses the draft content from Cooked. 7-4: Saving a reviewed extraction draft rejects partial reviewed content. + 7-5: Saving a reviewed extraction draft may overwrite an existing recipe when a recipe ID is provided. 8: The save_recipe tool updates an existing saved recipe. 8-1: Updating an existing saved recipe requires a recipe ID. 8-2: Updating an existing saved recipe requires recipe markdown. - 8-3: Updating an existing saved recipe requires portions. + 8-3: Updating an existing saved recipe defaults portions to 1 when omitted. + 8-5: Updating an existing saved recipe overwrites the recipe title, markdown, and portions. 8-4: Saving or updating recipes preserves fractional portions supplied by the agent. 9: Recipe save and update results include the affected recipe ID. + 9-1: Saving a reviewed extraction draft into an existing recipe reports that the existing recipe was overwritten. 10: Recipe save requests use explicit source values. 10-1: The recipe save source values are raw_text, prepared, url, draft, and existing. 11: Saving raw recipe text hides Cooked's preview-then-save sequence behind one tool call. @@ -63,6 +70,12 @@ components: requirements: 1: The delete_recipe tool deletes a saved recipe by recipe ID. 2: Recipe deletion reports which recipe ID was deleted. + RESOLVE: + requirements: + 1: The resolve_recipe_id tool resolves a recipe ID prefix to matching saved recipes. + 2: Resolving a recipe ID requires a UUID prefix. + 3: Resolving a recipe ID returns matching recipe IDs and titles. + 4: Resolving a recipe ID warns when the prefix matches multiple recipes. constraints: PAGINATION: requirements: @@ -77,6 +90,11 @@ constraints: 1: Draft-saving requires an explicit draft ID. 2: Existing recipe updates require an explicit recipe ID. 3: Recipe deletion requires an explicit recipe ID. + VALIDATION: + requirements: + 1: Recipe IDs, draft IDs, and product group IDs are validated as UUIDs before calling Cooked. + 2: A single malformed recipe ID, draft ID, or product group ID is rejected before calling Cooked. + 3: Malformed product group IDs in an array are reported and skipped rather than failing the whole call. VERIFICATION: requirements: 1: Recipe behaviour is verified with fake Cooked HTTP servers. diff --git a/features/cooked-mcp/shopping-list.feature.yaml b/features/cooked-mcp/shopping-list.feature.yaml index 9a77bd52052c1a2cb9c534e4fd65372e66196aa6..30a7eb17f203fa19a0dd2a25ee8815f6cce21e12 100644 --- a/features/cooked-mcp/shopping-list.feature.yaml +++ b/features/cooked-mcp/shopping-list.feature.yaml @@ -29,6 +29,7 @@ components: 3: The server reads the current shopping list before sending a product-group update when needed to preserve omitted fields. 4: Updating a product group preserves omitted editable fields. 5: Updating a product group reports the product group ID that changed. + 5-1: Updating a product group reports the updated name, quantity, aisle ID, and selected state. 6: Updating a product group requires an explicit product group ID. 7: Updating a missing product group reports a user-facing tool error. 8: Partial product-group updates preserve the current name, quantity, aisle ID, and selected state unless replacements are provided. diff --git a/features/cooked-mcp/tools.feature.yaml b/features/cooked-mcp/tools.feature.yaml index a063f124b3ffa5d72b778cc771ce2c7bc54ce59f..f14367ab3b6ebac220e6cad327229d712ad374af 100644 --- a/features/cooked-mcp/tools.feature.yaml +++ b/features/cooked-mcp/tools.feature.yaml @@ -6,13 +6,14 @@ components: SURFACE: requirements: 1: The server exposes a read tool named read. - 2: The server exposes a recipe text preview tool named preview_recipe_text. + 2: The server exposes a recipe text extraction tool named extract_into_recipe. 3: The server exposes a recipe save tool named save_recipe. 4: The server exposes a recipe deletion tool named delete_recipe. 5: The server exposes a shopping-list mutation tool named change_shopping_list. 6: The server does not expose one MCP tool per Cooked API endpoint. 7: The server does not expose MCP resources. 8: The read tool supports recipe lists, single recipes, recipe format examples, and the shopping list through explicit target values. + 9: The server exposes a recipe ID resolution tool named resolve_recipe_id. READ_TOOL: requirements: 1: The read tool target values are recipes, recipe, example_recipes, and shopping_list. @@ -22,18 +23,20 @@ components: 5: The read tool accepts page with default 1 and minimum 1. 6: The read tool accepts limit with default 10, minimum 1, and maximum 30. 7: The read tool returns Cooked recipe markdown examples when target is example_recipes. - PREVIEW_RECIPE_TEXT_TOOL: + EXTRACT_INTO_RECIPE_TOOL: requirements: - 1: The preview_recipe_text tool requires title. - 2: The preview_recipe_text tool requires text. + 1: The extract_into_recipe tool requires title. + 2: The extract_into_recipe tool requires text. + 3: The extract_into_recipe tool accepts an optional portions hint. SAVE_RECIPE_TOOL: requirements: 1: The save_recipe source values are raw_text, prepared, url, draft, and existing. 2: source raw_text requires title and text. - 3: source prepared requires title, markdown, and portions. + 3: source prepared requires title and markdown, defaulting portions to 1 when omitted. 4: source url requires url. 5: source draft requires draft_id and accepts either both markdown and portions or neither. - 6: source existing requires recipe_id, markdown, and portions. + 6: source existing requires recipe_id and markdown, defaulting portions to 1 when omitted. + 7: source existing overwrites the existing recipe's title, markdown, and portions. DELETE_RECIPE_TOOL: requirements: 1: The delete_recipe tool requires recipe_id. @@ -44,11 +47,12 @@ components: 3: action add accepts recipe_id. 4: action update_item requires product_group_id. 5: action update_item accepts name, quantity, aisle_id, and selected. - 6: action replace_selection requires product_group_ids. - 7: action add_selection requires product_group_ids. - 8: action remove_selection requires product_group_ids. - 9: action remove requires product_group_ids. - 10: action clear has no required parameters beyond action. + 6: action update_item returns the updated product group's name, quantity, aisle_id, and selected state. + 7: action replace_selection requires product_group_ids. + 8: action add_selection requires product_group_ids. + 9: action remove_selection requires product_group_ids. + 10: action remove requires product_group_ids. + 11: action clear has no required parameters beyond action. READ_WRITE_SPLIT: requirements: 1: Read-only operations are exposed separately from operations that change Cooked data. @@ -82,5 +86,6 @@ constraints: 2: Tool parameters validate bounded numeric inputs. 3: Tool descriptions state important behavioural limits and follow-up tools. 4: Tool schemas reject unsupported read targets, recipe save sources, and shopping-list actions before calling Cooked. + 7: Tool schemas validate recipe IDs, draft IDs, and product group IDs as UUIDs before calling Cooked. 5: The shopping-list mutation tool description distinguishes destructive remove and clear actions from non-destructive actions. 6: The shopping-list mutation tool exposes product_group_ids as an optional array of strings that does not accept null.