mcp: clarify tool guidance

Amolith created

Update MCP tool descriptions to point agents at example_recipes before saving Cooked recipe markdown, make URL import draft behaviour explicit, and remove stale shopping-list read-output normalization wording.

Change summary

internal/mcp/server.go              | 6 +++---
internal/mcp/server_wording_test.go | 8 ++++++--
2 files changed, 9 insertions(+), 5 deletions(-)

Detailed changes

internal/mcp/server.go 🔗

@@ -699,7 +699,7 @@ func readTool() *sdk.Tool {
 	return &sdk.Tool{
 		Name:        readToolName,
 		Title:       "Read Cooked data",
-		Description: "Read Cooked data. Use target shopping_list for the current shopping list, recipes to list or search saved recipe IDs and titles, recipe with recipe_id to read a single recipe, or example_recipes for Cooked recipe markdown examples. Recipe results omit images and thumbnails.",
+		Description: "Read Cooked data. Use target shopping_list for the current shopping list, recipes to list or search saved recipe IDs and titles, recipe with recipe_id to read a single recipe, or example_recipes for Cooked recipe markdown examples. You MUST check the examples before saving anything because Cooked uses a particular Markdown dialect. Recipe results omit images and thumbnails.",
 		InputSchema: readInputSchema(),
 		Annotations: &sdk.ToolAnnotations{
 			Title:         "Read Cooked data",
@@ -728,7 +728,7 @@ func saveRecipeTool() *sdk.Tool {
 	return &sdk.Tool{
 		Name:        saveRecipeToolName,
 		Title:       "Save recipe",
-		Description: "Save a recipe from raw text, prepared markdown, a URL import, a reviewed URL-import draft, or an existing recipe update. URL imports may return a draft_id for review instead of saving immediately.",
+		Description: "Save a recipe from raw text, prepared markdown, a URL import, a reviewed URL-import draft, or an existing recipe update. URL imports will return a draft_id for review instead of saving immediately.",
 		InputSchema: saveRecipeInputSchema(),
 		Annotations: &sdk.ToolAnnotations{
 			Title:         "Save recipe",
@@ -780,7 +780,7 @@ func changeShoppingListTool() *sdk.Tool {
 	return &sdk.Tool{
 		Name:        changeShoppingListToolName,
 		Title:       "Change shopping list",
-		Description: "Change the Cooked shopping list. Supports add, update_item, replace_selection, add_selection, remove_selection, remove, and clear. Add accepts newline-separated ingredients and optional recipe_id; put quantities before names, such as `1 milk`. Simple read-output lines like `milk — 1` are normalized. Remove and clear are destructive.",
+		Description: "Change the Cooked shopping list. Supports add, update_item, replace_selection, add_selection, remove_selection, remove, and clear. Add accepts newline-separated ingredients and optional recipe_id; put quantities before names, such as `1 milk`. Remove and clear are destructive.",
 		InputSchema: changeShoppingListInputSchema(),
 		Annotations: &sdk.ToolAnnotations{
 			Title:           "Change shopping list",

internal/mcp/server_wording_test.go 🔗

@@ -59,6 +59,8 @@ func TestToolDescriptionsACIDToolsSchema3And5DescribeCurrentLimits(t *testing.T)
 		"recipes",
 		"recipe with recipe_id",
 		"example_recipes",
+		"You MUST check the examples before saving anything",
+		"particular Markdown dialect",
 		"Recipe results omit images and thumbnails",
 	} {
 		if !strings.Contains(read.Description, want) {
@@ -73,7 +75,7 @@ func TestToolDescriptionsACIDToolsSchema3And5DescribeCurrentLimits(t *testing.T)
 		"URL import",
 		"reviewed URL-import draft",
 		"existing recipe update",
-		"draft_id",
+		"URL imports will return a draft_id for review",
 	} {
 		if !strings.Contains(save.Description, want) {
 			t.Fatalf("save_recipe description missing %q: %q", want, save.Description)
@@ -91,12 +93,14 @@ func TestToolDescriptionsACIDToolsSchema3And5DescribeCurrentLimits(t *testing.T)
 		"clear",
 		"Remove and clear are destructive",
 		"put quantities before names",
-		"milk — 1",
 	} {
 		if !strings.Contains(shopping.Description, want) {
 			t.Fatalf("change_shopping_list description missing %q: %q", want, shopping.Description)
 		}
 	}
+	if strings.Contains(shopping.Description, "Simple read-output lines") {
+		t.Fatalf("change_shopping_list description includes removed read-output guidance: %q", shopping.Description)
+	}
 }
 
 // tools.SCHEMA.6