Skip to main content
Glama
briantkatch

Paprika MCP Server

by briantkatch

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
NameRequiredDescriptionDefault
idYesRecipe UID to update
fieldYesField to update
findYesText to find in the field
replaceYesText to replace it with
regexNoWhether 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"],
        },
    }
  • 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,
    },
  • 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()]
  • 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}")

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/briantkatch/paprika-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server