update_recipe
Modify recipe text fields by finding and replacing content in Paprika Recipe Manager. This operation requires user confirmation due to its potential impact.
Instructions
Update recipe fields using find/replace. This is a DANGEROUS operation that requires user confirmation. Can update any text field in a recipe.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Recipe UID to update | |
| field | Yes | Field to update | |
| find | Yes | Text to find in the field | |
| replace | Yes | Text to replace it with | |
| regex | No | Whether to treat 'find' as a regex pattern (default: false) |
Implementation Reference
- Core handler function that implements the update_recipe tool logic: retrieves recipe by ID, performs find/replace (regex optional) on specified field, updates the recipe object, and uploads changes back to Paprika.async def update_recipe_tool(args: dict[str, Any]) -> list[TextContent]: """Update recipe fields using find/replace - DANGEROUS operation.""" recipe_id = args["id"] field = args["field"] find = args["find"] replace = args["replace"] use_regex = args.get("regex", False) # Get the remote remote = get_remote() # Fetch the recipe recipe = None for r in remote.recipes: if r.uid == recipe_id: recipe = r break if not recipe: return [ TextContent( type="text", text=f"Error: No recipe found with ID '{recipe_id}'", ) ] # Get the current field value field_value = getattr(recipe, field, None) if field_value is None: return [ TextContent( type="text", text=f"Error: Recipe '{recipe.name}' does not have field '{field}'", ) ] # Perform the find/replace if use_regex: try: new_value = re.sub(find, replace, field_value) except re.error as e: return [ TextContent( type="text", text=f"Error: Invalid regex pattern '{find}': {str(e)}" ) ] else: new_value = field_value.replace(find, replace) # Check if anything changed if new_value == field_value: return [ TextContent( type="text", text=f"No changes made - pattern '{find}' not found in field '{field}' of recipe '{recipe.name}'", ) ] # Update the field setattr(recipe, field, new_value) # Save the recipe try: remote.upload_recipe(recipe) return [ TextContent( type="text", text=f"Successfully updated field '{field}' in recipe '{recipe.name}' (ID: {recipe_id})\n\nOld value:\n{field_value}\n\nNew value:\n{new_value}", ) ] except Exception as e: return [ TextContent( type="text", text=f"Error updating recipe '{recipe.name}': {str(e)}" ) ]
- Input schema and metadata definition for the update_recipe tool, including parameters with types, descriptions, enum for fields, and required fields.TOOL_DEFINITION = { "name": "update_recipe", "description": ( "Update recipe fields using find/replace. " "This is a DANGEROUS operation that requires user confirmation. " "Can update any text field in a recipe." ), "inputSchema": { "type": "object", "properties": { "id": {"type": "string", "description": "Recipe UID to update"}, "field": { "type": "string", "enum": [ "name", "ingredients", "directions", "notes", "description", "categories", "source", "source_url", "prep_time", "cook_time", "total_time", "servings", "difficulty", "rating", "nutritional_info", ], "description": "Field to update", }, "find": {"type": "string", "description": "Text to find in the field"}, "replace": {"type": "string", "description": "Text to replace it with"}, "regex": { "type": "boolean", "description": "Whether to treat 'find' as a regex pattern (default: false)", "default": False, }, }, "required": ["id", "field", "find", "replace"], }, }
- src/paprika_mcp/tools/__init__.py:22-25 (registration)Tool registration in the central TOOLS dictionary in tools/__init__.py, linking the tool name to its schema definition and handler function."update_recipe": { "definition": UPDATE_RECIPE_DEF, "handler": update_recipe_tool, },
- src/paprika_mcp/server.py:33-37 (registration)MCP server registration: list_tools handler exposes all tools from TOOLS (including update_recipe) to the MCP protocol.@app.list_tools() async def list_tools(): """List available tools.""" return [Tool(**tool["definition"]) for tool in TOOLS.values()]
- src/paprika_mcp/server.py:39-51 (registration)MCP server registration: call_tool handler dispatches tool calls (including to update_recipe handler) based on name from TOOLS.@app.call_tool() async def call_tool(name: str, arguments: dict): """Handle tool calls.""" if name in TOOLS: try: return await TOOLS[name]["handler"](arguments) except Exception as e: logger.error(f"Error in {name}: {e}", exc_info=True) from mcp.types import TextContent return [TextContent(type="text", text=f"Error: {str(e)}")] raise ValueError(f"Unknown tool: {name}")