{
  "id": "recipes",
  "name": "Recipes",
  "version": "1.2.0",
  "minAppVersion": "0.1.0",
  "description": "A Recipes tab: steps with their ingredients, scaling by servings, and a table view where each step spans the ingredients it combines. MCP clients can import recipes they read online.",
  "author": "Aquamarine",
  "scopes": [],
  "main": "main.js",
  "collections": {
    "recipes": {
      "description": "One recipe.",
      "schema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["name", "steps"],
        "properties": {
          "name": { "type": "string", "minLength": 1, "maxLength": 200 },
          "description": { "type": "string", "maxLength": 2000 },
          "servings": { "type": "number", "exclusiveMinimum": 0, "description": "How many servings the amounts make" },
          "servings_unit": { "type": "string", "maxLength": 40, "description": "What a serving is, such as servings, slices or cookies" },
          "prep_minutes": { "type": "integer", "minimum": 0 },
          "cook_minutes": { "type": "integer", "minimum": 0 },
          "source_url": { "type": "string", "maxLength": 2000, "description": "The page the recipe came from" },
          "keywords": { "type": "array", "maxItems": 30, "items": { "type": "string", "maxLength": 40 } },
          "view": { "enum": ["steps", "table"], "description": "How the app shows this recipe; leave unset for the default" },
          "steps": {
            "type": "array",
            "maxItems": 100,
            "description": "In order. A step with no ingredients and no inputs, such as preheating the oven, shows as a note above the table.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["instruction"],
              "properties": {
                "instruction": { "type": "string", "minLength": 1, "maxLength": 2000, "description": "Short and imperative, such as \"whisk\" or \"bake 55 min at 350°F (175°C)\"" },
                "minutes": { "type": "integer", "minimum": 0 },
                "uses": {
                  "type": "array",
                  "items": { "type": "integer", "minimum": 0 },
                  "description": "Zero-based indexes of earlier steps whose result goes into this step. Leave unset to take the previous step's result."
                },
                "ingredients": {
                  "type": "array",
                  "maxItems": 60,
                  "description": "The ingredients this step adds, in the order they are added",
                  "items": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": ["food"],
                    "properties": {
                      "amount": { "type": ["number", "null"], "minimum": 0 },
                      "unit": { "type": "string", "maxLength": 30, "description": "Such as g, ml, cup, tbsp, tsp, large; empty for a count" },
                      "food": { "type": "string", "minLength": 1, "maxLength": 120 },
                      "note": { "type": "string", "maxLength": 200, "description": "Such as \"ripe\" or \"chopped\"" },
                      "category": { "enum": ["produce", "protein", "dairy", "grain", "baking", "spice", "sauce", "other"], "description": "What kind of ingredient it is: protein covers meat, fish, tofu and beans; spice covers herbs; sauce covers oils, vinegars, stocks and condiments. Leave unset to have the app guess from the food." }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "tools": [
    {
      "name": "import",
      "collection": "recipes",
      "action": "create",
      "description": "Save a recipe, for example one read from a web page. Split the method into short steps, attach each ingredient to the step that first uses it, give each ingredient a category, give amounts as numbers (1 1/3 is 1.333), and set `uses` when a step combines the results of earlier steps (mix the dry ingredients in one step, the wet in another, then a step that uses both). Put the page address in source_url."
    },
    { "name": "list", "collection": "recipes", "action": "list", "description": "List saved recipes, newest first; `query` matches any text in a recipe." },
    { "name": "get", "collection": "recipes", "action": "get", "description": "One saved recipe." },
    { "name": "update", "collection": "recipes", "action": "update", "description": "Change fields of a saved recipe; a field sent replaces the old one." }
  ]
}
