agent-chef-mcp 1.0.0 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +2 -2
  2. package/catalog.json +744 -57
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -73,7 +73,7 @@ Client config for stdio:
73
73
  Without a key the server still lists everything; tool calls return a message explaining where to get a key.
74
74
  `npm run sync` refreshes `catalog.json` from the live server; `npm test` runs a stdio smoke test.
75
75
 
76
- ## Tools (34)
76
+ ## Tools (37)
77
77
 
78
78
  | Area | Tools |
79
79
  |---|---|
@@ -82,7 +82,7 @@ Without a key the server still lists everything; tool calls return a message exp
82
82
  | Preferences | `get_recipe_preferences`, `update_recipe_preferences` |
83
83
  | Household | `get_members`, `upsert_member`, `remove_member` |
84
84
  | Pantry | `get_ingredients`, `update_ingredients` |
85
- | Recipes | `search_recipes`, `get_recipe`, `update_recipe`, `import_recipe`, `get_favorite_recipes`, `favorite_recipe`, `get_past_recipes` |
85
+ | Recipes | `search_recipes`, `get_recipe`, `update_recipe`, `import_recipe`, `import_recipes`, `create_recipe`, `set_recipe_image`, `get_favorite_recipes`, `favorite_recipe`, `get_past_recipes` |
86
86
  | Weekly cycle | `propose_recipes`, `add_candidates`, `message_group`, `add_vote`, `add_ballot_feedback`, `get_past_votes`, `get_current_week`, `set_this_weeks_recipes`, `reopen_voting`, `set_voting_deadline`, `rate_recipe` |
87
87
  | Shopping | `assemble_online_grocery_order`, `record_grocery_order` |
88
88
 
package/catalog.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
- "synced_at": "2026-09-07T16:49:39.666Z",
2
+ "synced_at": "2026-09-08T23:16:36.525Z",
3
3
  "server": {
4
4
  "name": "agent-chef",
5
5
  "version": "0.4.0"
6
6
  },
7
- "instructions": "# How to run Agent Chef\n\nYou are the household's agent. Agent Chef is the state machine; you are the hands. You never need to remember where the week stands: the server tells you.\n\nRUN LOOP. When the user says \"run agent chef\", call run_agent_chef (it returns this manual, today's checklist, and whether a recurring schedule exists) and follow it. The first time, also schedule yourself to run \"Run Agent Chef.\" twice a day (09:00 and 18:00 in the household's timezone) and confirm it with record_schedule, so the whole week runs end to end without anyone asking. Then:\n1. Call next_actions.\n2. Execute the returned actions in order. Each one names the tool, why it's due, and the arguments or message text to use. Where an argument is in <angle brackets>, you fill it in (e.g. write the 10 recipes).\n3. Call next_actions again. Repeat until it returns no actions, then stop and report a one-line summary.\n\nWHAT THE PHASES MEAN\n- new_cycle: it's past the household's plan day. Ask for ratings on last week's dinners if any are missing (don't wait for answers), then propose 10 recipes and send the ballot.\n- voting: people vote on their personal links until voting_closes_at (household setting: weekday + time; set_voting_deadline moves it). You may be asked to send one reminder to non-voters shortly before the deadline, or to add 2-3 options answering ballot feedback. When everyone has voted or the deadline passes, lock in the winners, announce them, and build the cart.\n- shopping: assemble_online_grocery_order gives you the list minus the pantry plus the household's shopping_preferences (brands, organic, substitutions): follow them when picking products. Fill the cart in the store's website, show the total, and STOP for explicit approval before checkout. Then record_grocery_order.\n- cooking / idle: nothing to do until the next plan day.\n\nWRITING RECIPES (propose_recipes / add_candidates): read get_recipe_preferences first. Source recipes from real pages: import_recipe(url) saves a recipe from a trusted site with its photo, ingredients and steps, then pass its recipe_id; aim for most of the ballot to come from real sources. search_recipes finds anything already in the library. PHOTOS ARE YOUR JOB: every candidate should have a real image_url (the source page's photo, or one you found by searching). The server checks each URL is a live image and rejects dead ones; a card without a photo means you skipped this. Use get_favorite_recipes (include 1-2), get_past_recipes (avoid repeats from the last ~4 weeks), get_past_votes (lean into what wins), get_ingredients (use what's on hand). Each recipe: title, one appetizing sentence, servings, complete ingredients with quantities, steps, tags, and a real image_url (see PHOTOS).\n\nMESSAGING: message_group sends SMS/email to members and personalises {vote_link} per person. Pass the kind the action specifies so the server can track what was sent. If the household prefers, you may post the same text into their own group chat instead; still call message_group so it's logged (it dry-runs if no provider is configured).\n\nRULES: never invent a vote or a rating; never check out without explicit approval in this conversation; keep messages short and friendly; if a tool errors, fix the input and retry once, then report.",
7
+ "instructions": "# How to run Agent Chef\n\nYou are the household's agent. Agent Chef is the state machine; you are the hands. You never need to remember where the week stands: the server tells you.\n\nRUN LOOP. When the user says \"run agent chef\", call run_agent_chef (it returns this manual, today's checklist, and whether a recurring schedule exists) and follow it. The first time, also schedule yourself to run \"Run Agent Chef.\" twice a day (09:00 and 18:00 in the household's timezone) and confirm it with record_schedule, so the whole week runs end to end without anyone asking. Then:\n1. Call next_actions.\n2. Execute the returned actions in order. Each one names the tool, why it's due, and the arguments or message text to use. Where an argument is in <angle brackets>, you fill it in (e.g. write the 10 recipes).\n3. Call next_actions again. Repeat until it returns no actions, then stop and report a one-line summary.\n\nWHAT THE PHASES MEAN\n- new_cycle: it's past the household's plan day. Propose 10 recipes and send the ballot. Last week's unrated dinners are collected on the ballot page itself (a rating card sits above the new options), so don't send a separate rating request; the ballot text mentions it.\n- voting: people vote on their personal links until voting_closes_at (household setting: weekday + time; set_voting_deadline moves it). You may be asked to send one reminder to non-voters shortly before the deadline, or to add 2-3 options answering ballot feedback. When everyone has voted or the deadline passes, lock in the winners, announce them, and build the cart.\n- shopping: assemble_online_grocery_order gives you the list minus the pantry plus the household's shopping_preferences (brands, organic, substitutions): follow them when picking products. Fill the cart in the store's website, show the total, and STOP for explicit approval before checkout. Then record_grocery_order.\n- cooking / idle: nothing to do until the next plan day.\n\nWRITING RECIPES (propose_recipes / add_candidates): read get_recipe_preferences first. Source recipes from real pages: import_recipe(url) saves a recipe from a trusted site with its photo, ingredients and steps, then pass its recipe_id; aim for most of the ballot to come from real sources. search_recipes finds anything already in the library. PHOTOS ARE YOUR JOB: every candidate should have a real image_url (the source page's photo, or one you found by searching). The server checks each URL is a live image and rejects dead ones; a card without a photo means you skipped this. If no real photo exists, generate one with your image tool (a realistic photo of the plated dish, natural light, no text, no people) and attach it with set_recipe_image, which stores it permanently; image-tool URLs expire, so never pass them as image_url directly. After propose_recipes, check the returned candidates for a missing image_url and fix each with set_recipe_image. Use get_favorite_recipes (include 1-2), get_past_recipes (avoid repeats from the last ~4 weeks), get_past_votes (lean into what wins), get_ingredients (use what's on hand). Each recipe: title, one appetizing sentence, servings, complete ingredients with quantities, steps, tags, and a real image_url (see PHOTOS).\n\nMESSAGING: message_group sends push notifications (to members who tapped \"notify me\" on their vote page), SMS or email, and personalises {vote_link} per person; channel auto picks push first, then text, then email. Pass the kind the action specifies so the server can track what was sent. If the household prefers, you may post the same text into their own group chat instead; still call message_group so it's logged (it dry-runs if no provider is configured).\n\nSWITCHING FROM ANOTHER APP: when the owner lists meals they loved elsewhere (Mealime, a meal kit, a recipe manager), find a real recipe page for each name on a well-known recipe site, then save them all at once with import_recipes (favorite_all: true); URLs they give you go straight in. If you have a browser tool, you can collect the favorites yourself: open the old app, let the owner sign in (never type their password), gather the recipe links, then import. Mealime and HelloFresh recipe pages import cleanly; Blue Apron and Marley Spoon block automated fetching, so for those read each recipe card in your browser and save it with create_recipe (title, ingredients with quantities, steps, servings, photo URL, source link, favorite: true). Use create_recipe whenever import_recipe fails on a page you can read. Report what you saved and what you could not find. Favorites are re-proposed on future ballots.\n\nON-DEMAND REQUESTS: when the owner asks for something the schedule wouldn't do yet (\"start next week's ballot now\", \"add two more options\", \"lock it in early\", \"send a reminder\"), do it directly with the matching tool even if next_actions says nothing is due. For an early ballot, call propose_recipes with week_start set to the coming cycle start (next_actions returns it as on_demand / cycle_start) and then message_group with the ballot.\n\nHOUSEHOLDS OF ONE work the same way: one voter, top N by their votes, same loop. Never block on adding members.\n\nRULES: never invent a vote or a rating; never check out without explicit approval in this conversation; keep messages short and friendly; if a tool errors, fix the input and retry once, then report.",
8
8
  "tools": [
9
9
  {
10
10
  "name": "run_agent_chef",
@@ -99,6 +99,13 @@
99
99
  "string",
100
100
  "null"
101
101
  ]
102
+ },
103
+ "share_url": {
104
+ "type": [
105
+ "string",
106
+ "null"
107
+ ],
108
+ "description": "Public page showing this week's winners"
102
109
  }
103
110
  },
104
111
  "required": [
@@ -204,6 +211,12 @@
204
211
  "null"
205
212
  ]
206
213
  },
214
+ "on_demand": {
215
+ "type": [
216
+ "string",
217
+ "null"
218
+ ]
219
+ },
207
220
  "billing": {
208
221
  "anyOf": [
209
222
  {
@@ -567,6 +580,13 @@
567
580
  "string",
568
581
  "null"
569
582
  ]
583
+ },
584
+ "share_url": {
585
+ "type": [
586
+ "string",
587
+ "null"
588
+ ],
589
+ "description": "Public page showing this week's winners"
570
590
  }
571
591
  },
572
592
  "required": [
@@ -672,6 +692,12 @@
672
692
  "null"
673
693
  ]
674
694
  },
695
+ "on_demand": {
696
+ "type": [
697
+ "string",
698
+ "null"
699
+ ]
700
+ },
675
701
  "billing": {
676
702
  "anyOf": [
677
703
  {
@@ -964,7 +990,7 @@
964
990
  {
965
991
  "name": "get_members",
966
992
  "title": "Get household members",
967
- "description": "List household members with contact info and their personal vote links.",
993
+ "description": "List household members with contact info, whether they get push notifications, and their personal vote links.",
968
994
  "inputSchema": {
969
995
  "type": "object",
970
996
  "properties": {}
@@ -1023,6 +1049,13 @@
1023
1049
  "null"
1024
1050
  ],
1025
1051
  "description": "Personal voting page for this member"
1052
+ },
1053
+ "push_subscribed": {
1054
+ "type": [
1055
+ "boolean",
1056
+ "null"
1057
+ ],
1058
+ "description": "Has a device opted in to push notifications"
1026
1059
  }
1027
1060
  },
1028
1061
  "required": [
@@ -1113,6 +1146,13 @@
1113
1146
  "null"
1114
1147
  ],
1115
1148
  "description": "Personal voting page for this member"
1149
+ },
1150
+ "push_subscribed": {
1151
+ "type": [
1152
+ "boolean",
1153
+ "null"
1154
+ ],
1155
+ "description": "Has a device opted in to push notifications"
1116
1156
  }
1117
1157
  },
1118
1158
  "required": [
@@ -1194,6 +1234,13 @@
1194
1234
  "null"
1195
1235
  ],
1196
1236
  "description": "Personal voting page for this member"
1237
+ },
1238
+ "push_subscribed": {
1239
+ "type": [
1240
+ "boolean",
1241
+ "null"
1242
+ ],
1243
+ "description": "Has a device opted in to push notifications"
1197
1244
  }
1198
1245
  },
1199
1246
  "required": [
@@ -1467,6 +1514,19 @@
1467
1514
  "null"
1468
1515
  ]
1469
1516
  },
1517
+ "is_public": {
1518
+ "type": [
1519
+ "boolean",
1520
+ "null"
1521
+ ]
1522
+ },
1523
+ "public_url": {
1524
+ "type": [
1525
+ "string",
1526
+ "null"
1527
+ ],
1528
+ "description": "Indexable public page, when published"
1529
+ },
1470
1530
  "created_at": {
1471
1531
  "type": [
1472
1532
  "string",
@@ -1657,6 +1717,19 @@
1657
1717
  "null"
1658
1718
  ]
1659
1719
  },
1720
+ "is_public": {
1721
+ "type": [
1722
+ "boolean",
1723
+ "null"
1724
+ ]
1725
+ },
1726
+ "public_url": {
1727
+ "type": [
1728
+ "string",
1729
+ "null"
1730
+ ],
1731
+ "description": "Indexable public page, when published"
1732
+ },
1660
1733
  "created_at": {
1661
1734
  "type": [
1662
1735
  "string",
@@ -1720,7 +1793,7 @@
1720
1793
  {
1721
1794
  "name": "get_recipe",
1722
1795
  "title": "Get a recipe",
1723
- "description": "Full details for one recipe: ingredients, steps, servings, source, tags, ratings, comments, how often it's been cooked, and a link to its page.",
1796
+ "description": "Full details for one recipe: ingredients, steps, servings, source, tags, ratings, comments, how often it's been cooked, a link to its page, and a public share_url anyone can open.",
1724
1797
  "inputSchema": {
1725
1798
  "type": "object",
1726
1799
  "properties": {
@@ -1836,6 +1909,19 @@
1836
1909
  "null"
1837
1910
  ]
1838
1911
  },
1912
+ "is_public": {
1913
+ "type": [
1914
+ "boolean",
1915
+ "null"
1916
+ ]
1917
+ },
1918
+ "public_url": {
1919
+ "type": [
1920
+ "string",
1921
+ "null"
1922
+ ],
1923
+ "description": "Indexable public page, when published"
1924
+ },
1839
1925
  "created_at": {
1840
1926
  "type": [
1841
1927
  "string",
@@ -1943,6 +2029,13 @@
1943
2029
  },
1944
2030
  "url": {
1945
2031
  "$ref": "#/properties/id"
2032
+ },
2033
+ "share_url": {
2034
+ "type": [
2035
+ "string",
2036
+ "null"
2037
+ ],
2038
+ "description": "Public page for this recipe"
1946
2039
  }
1947
2040
  },
1948
2041
  "required": [
@@ -2081,6 +2174,19 @@
2081
2174
  "null"
2082
2175
  ]
2083
2176
  },
2177
+ "is_public": {
2178
+ "type": [
2179
+ "boolean",
2180
+ "null"
2181
+ ]
2182
+ },
2183
+ "public_url": {
2184
+ "type": [
2185
+ "string",
2186
+ "null"
2187
+ ],
2188
+ "description": "Indexable public page, when published"
2189
+ },
2084
2190
  "created_at": {
2085
2191
  "type": [
2086
2192
  "string",
@@ -2169,7 +2275,7 @@
2169
2275
  {
2170
2276
  "name": "update_recipe",
2171
2277
  "title": "Update a recipe",
2172
- "description": "Edit a stored recipe: fix an ingredient, add steps, change servings, tags, image or source. Only provided fields change.",
2278
+ "description": "Edit a stored recipe: fix an ingredient, add steps, change servings, tags, image or source, or set public to publish it on agentchef.net/recipes. Only provided fields change.",
2173
2279
  "inputSchema": {
2174
2280
  "type": "object",
2175
2281
  "properties": {
@@ -2222,6 +2328,10 @@
2222
2328
  "items": {
2223
2329
  "type": "string"
2224
2330
  }
2331
+ },
2332
+ "public": {
2333
+ "type": "boolean",
2334
+ "description": "Publish this recipe on agentchef.net/recipes (indexable, with the household's name). Imported recipes show ingredients and link to the source for steps."
2225
2335
  }
2226
2336
  },
2227
2337
  "required": [
@@ -2332,6 +2442,19 @@
2332
2442
  "null"
2333
2443
  ]
2334
2444
  },
2445
+ "is_public": {
2446
+ "type": [
2447
+ "boolean",
2448
+ "null"
2449
+ ]
2450
+ },
2451
+ "public_url": {
2452
+ "type": [
2453
+ "string",
2454
+ "null"
2455
+ ],
2456
+ "description": "Indexable public page, when published"
2457
+ },
2335
2458
  "created_at": {
2336
2459
  "type": [
2337
2460
  "string",
@@ -2440,63 +2563,451 @@
2440
2563
  "additionalProperties": true
2441
2564
  }
2442
2565
  },
2443
- {
2444
- "type": "null"
2445
- }
2446
- ]
2566
+ {
2567
+ "type": "null"
2568
+ }
2569
+ ]
2570
+ },
2571
+ "steps": {
2572
+ "anyOf": [
2573
+ {
2574
+ "type": "array",
2575
+ "items": {
2576
+ "$ref": "#/properties/id"
2577
+ }
2578
+ },
2579
+ {
2580
+ "type": "null"
2581
+ }
2582
+ ]
2583
+ },
2584
+ "tags": {
2585
+ "anyOf": [
2586
+ {
2587
+ "type": "array",
2588
+ "items": {
2589
+ "$ref": "#/properties/id"
2590
+ }
2591
+ },
2592
+ {
2593
+ "type": "null"
2594
+ }
2595
+ ]
2596
+ },
2597
+ "is_favorite": {
2598
+ "type": [
2599
+ "boolean",
2600
+ "null"
2601
+ ]
2602
+ },
2603
+ "is_public": {
2604
+ "type": [
2605
+ "boolean",
2606
+ "null"
2607
+ ]
2608
+ },
2609
+ "public_url": {
2610
+ "type": [
2611
+ "string",
2612
+ "null"
2613
+ ],
2614
+ "description": "Indexable public page, when published"
2615
+ },
2616
+ "created_at": {
2617
+ "type": [
2618
+ "string",
2619
+ "null"
2620
+ ]
2621
+ },
2622
+ "total_minutes": {
2623
+ "type": [
2624
+ "number",
2625
+ "null"
2626
+ ]
2627
+ },
2628
+ "url": {
2629
+ "$ref": "#/properties/id"
2630
+ }
2631
+ },
2632
+ "required": [
2633
+ "id",
2634
+ "title",
2635
+ "url"
2636
+ ],
2637
+ "additionalProperties": true,
2638
+ "$schema": "http://json-schema.org/draft-07/schema#"
2639
+ }
2640
+ },
2641
+ {
2642
+ "name": "create_recipe",
2643
+ "title": "Save a recipe you already have",
2644
+ "description": "Save a recipe to the library from details you already have: one you read in your browser (when a site blocks import_recipe or has no recipe markup), one the owner dictated, or one you wrote. Provide the complete ingredient list with quantities and the steps; include the source page and a real photo URL when you have them. Optionally mark it a favorite.",
2645
+ "inputSchema": {
2646
+ "type": "object",
2647
+ "properties": {
2648
+ "title": {
2649
+ "type": "string",
2650
+ "minLength": 2
2651
+ },
2652
+ "description": {
2653
+ "type": "string"
2654
+ },
2655
+ "image_url": {
2656
+ "type": "string",
2657
+ "description": "A real, publicly reachable photo of the dish; verified by the server and dropped if dead"
2658
+ },
2659
+ "source_url": {
2660
+ "type": "string"
2661
+ },
2662
+ "servings": {
2663
+ "type": "integer"
2664
+ },
2665
+ "ingredients": {
2666
+ "type": "array",
2667
+ "items": {
2668
+ "type": "object",
2669
+ "properties": {
2670
+ "name": {
2671
+ "type": "string",
2672
+ "description": "Plain ingredient name, e.g. 'chicken thighs'"
2673
+ },
2674
+ "quantity": {
2675
+ "type": "string",
2676
+ "description": "Free text, e.g. '2 lbs', '1 bunch'"
2677
+ }
2678
+ },
2679
+ "required": [
2680
+ "name"
2681
+ ],
2682
+ "additionalProperties": false
2683
+ },
2684
+ "minItems": 1
2685
+ },
2686
+ "steps": {
2687
+ "type": "array",
2688
+ "items": {
2689
+ "type": "string"
2690
+ },
2691
+ "minItems": 1
2692
+ },
2693
+ "tags": {
2694
+ "type": "array",
2695
+ "items": {
2696
+ "type": "string"
2697
+ }
2698
+ },
2699
+ "favorite": {
2700
+ "type": "boolean"
2701
+ }
2702
+ },
2703
+ "required": [
2704
+ "title",
2705
+ "ingredients",
2706
+ "steps"
2707
+ ],
2708
+ "additionalProperties": false,
2709
+ "$schema": "http://json-schema.org/draft-07/schema#"
2710
+ },
2711
+ "annotations": {
2712
+ "readOnlyHint": false,
2713
+ "destructiveHint": false,
2714
+ "openWorldHint": false
2715
+ },
2716
+ "execution": {
2717
+ "taskSupport": "forbidden"
2718
+ },
2719
+ "outputSchema": {
2720
+ "type": "object",
2721
+ "properties": {
2722
+ "id": {
2723
+ "type": "string"
2724
+ },
2725
+ "title": {
2726
+ "$ref": "#/properties/id"
2727
+ },
2728
+ "description": {
2729
+ "type": [
2730
+ "string",
2731
+ "null"
2732
+ ]
2733
+ },
2734
+ "image_url": {
2735
+ "type": [
2736
+ "string",
2737
+ "null"
2738
+ ]
2739
+ },
2740
+ "source_url": {
2741
+ "type": [
2742
+ "string",
2743
+ "null"
2744
+ ]
2745
+ },
2746
+ "servings": {
2747
+ "type": [
2748
+ "number",
2749
+ "null"
2750
+ ]
2751
+ },
2752
+ "ingredients": {
2753
+ "anyOf": [
2754
+ {
2755
+ "type": "array",
2756
+ "items": {
2757
+ "type": "object",
2758
+ "properties": {
2759
+ "name": {
2760
+ "$ref": "#/properties/id"
2761
+ },
2762
+ "quantity": {
2763
+ "type": [
2764
+ "string",
2765
+ "null"
2766
+ ],
2767
+ "description": "Free text, e.g. '2 lbs'"
2768
+ }
2769
+ },
2770
+ "required": [
2771
+ "name"
2772
+ ],
2773
+ "additionalProperties": true
2774
+ }
2775
+ },
2776
+ {
2777
+ "type": "null"
2778
+ }
2779
+ ]
2780
+ },
2781
+ "steps": {
2782
+ "anyOf": [
2783
+ {
2784
+ "type": "array",
2785
+ "items": {
2786
+ "$ref": "#/properties/id"
2787
+ }
2788
+ },
2789
+ {
2790
+ "type": "null"
2791
+ }
2792
+ ]
2793
+ },
2794
+ "tags": {
2795
+ "anyOf": [
2796
+ {
2797
+ "type": "array",
2798
+ "items": {
2799
+ "$ref": "#/properties/id"
2800
+ }
2801
+ },
2802
+ {
2803
+ "type": "null"
2804
+ }
2805
+ ]
2806
+ },
2807
+ "is_favorite": {
2808
+ "type": [
2809
+ "boolean",
2810
+ "null"
2811
+ ]
2812
+ },
2813
+ "is_public": {
2814
+ "type": [
2815
+ "boolean",
2816
+ "null"
2817
+ ]
2818
+ },
2819
+ "public_url": {
2820
+ "type": [
2821
+ "string",
2822
+ "null"
2823
+ ],
2824
+ "description": "Indexable public page, when published"
2825
+ },
2826
+ "created_at": {
2827
+ "type": [
2828
+ "string",
2829
+ "null"
2830
+ ]
2831
+ },
2832
+ "url": {
2833
+ "$ref": "#/properties/id"
2834
+ }
2835
+ },
2836
+ "required": [
2837
+ "id",
2838
+ "title",
2839
+ "url"
2840
+ ],
2841
+ "additionalProperties": true,
2842
+ "$schema": "http://json-schema.org/draft-07/schema#"
2843
+ }
2844
+ },
2845
+ {
2846
+ "name": "set_recipe_image",
2847
+ "title": "Attach a photo to a recipe",
2848
+ "description": "Store a photo for a recipe permanently and set it as the recipe's image. Use for images you generated with your image tool (their URLs expire) or any photo you have as a URL or base64. Pass either image_url (we fetch and copy it) or image_base64 + content_type. Max 6 MB; JPEG, PNG, WebP or GIF.",
2849
+ "inputSchema": {
2850
+ "type": "object",
2851
+ "properties": {
2852
+ "recipe_id": {
2853
+ "type": "string"
2854
+ },
2855
+ "image_url": {
2856
+ "type": "string",
2857
+ "format": "uri"
2858
+ },
2859
+ "image_base64": {
2860
+ "type": "string",
2861
+ "description": "Raw base64 (no data: prefix)"
2862
+ },
2863
+ "content_type": {
2864
+ "type": "string",
2865
+ "description": "e.g. image/png"
2866
+ }
2867
+ },
2868
+ "required": [
2869
+ "recipe_id"
2870
+ ],
2871
+ "additionalProperties": false,
2872
+ "$schema": "http://json-schema.org/draft-07/schema#"
2873
+ },
2874
+ "annotations": {
2875
+ "readOnlyHint": false,
2876
+ "destructiveHint": false,
2877
+ "openWorldHint": false
2878
+ },
2879
+ "execution": {
2880
+ "taskSupport": "forbidden"
2881
+ },
2882
+ "outputSchema": {
2883
+ "type": "object",
2884
+ "properties": {
2885
+ "recipe_id": {
2886
+ "type": "string"
2887
+ },
2888
+ "image_url": {
2889
+ "type": "string",
2890
+ "description": "Permanent public URL of the stored photo"
2891
+ }
2892
+ },
2893
+ "required": [
2894
+ "recipe_id",
2895
+ "image_url"
2896
+ ],
2897
+ "additionalProperties": true,
2898
+ "$schema": "http://json-schema.org/draft-07/schema#"
2899
+ }
2900
+ },
2901
+ {
2902
+ "name": "import_recipes",
2903
+ "title": "Import several recipes from URLs",
2904
+ "description": "Bulk version of import_recipe: fetch up to 15 recipe pages and save them to the library, optionally marking each as a favorite. Use when the owner is moving favorites from another app (Mealime, a meal kit, a recipe manager). Names without URLs are your job: search for a real recipe page first, then pass the URLs here. Per-URL failures are reported, not thrown.",
2905
+ "inputSchema": {
2906
+ "type": "object",
2907
+ "properties": {
2908
+ "items": {
2909
+ "type": "array",
2910
+ "items": {
2911
+ "type": "object",
2912
+ "properties": {
2913
+ "url": {
2914
+ "type": "string",
2915
+ "format": "uri"
2916
+ },
2917
+ "favorite": {
2918
+ "type": "boolean"
2919
+ },
2920
+ "tags": {
2921
+ "type": "array",
2922
+ "items": {
2923
+ "type": "string"
2924
+ }
2925
+ }
2926
+ },
2927
+ "required": [
2928
+ "url"
2929
+ ],
2930
+ "additionalProperties": false
2931
+ },
2932
+ "minItems": 1,
2933
+ "maxItems": 15
2447
2934
  },
2448
- "steps": {
2449
- "anyOf": [
2450
- {
2451
- "type": "array",
2452
- "items": {
2453
- "$ref": "#/properties/id"
2935
+ "favorite_all": {
2936
+ "type": "boolean",
2937
+ "description": "Mark every imported recipe as a favorite"
2938
+ }
2939
+ },
2940
+ "required": [
2941
+ "items"
2942
+ ],
2943
+ "additionalProperties": false,
2944
+ "$schema": "http://json-schema.org/draft-07/schema#"
2945
+ },
2946
+ "annotations": {
2947
+ "readOnlyHint": false,
2948
+ "destructiveHint": false,
2949
+ "openWorldHint": true
2950
+ },
2951
+ "execution": {
2952
+ "taskSupport": "forbidden"
2953
+ },
2954
+ "outputSchema": {
2955
+ "type": "object",
2956
+ "properties": {
2957
+ "imported": {
2958
+ "type": "array",
2959
+ "items": {
2960
+ "type": "object",
2961
+ "properties": {
2962
+ "recipe_id": {
2963
+ "type": "string"
2964
+ },
2965
+ "title": {
2966
+ "$ref": "#/properties/imported/items/properties/recipe_id"
2967
+ },
2968
+ "url": {
2969
+ "$ref": "#/properties/imported/items/properties/recipe_id"
2970
+ },
2971
+ "favorite": {
2972
+ "type": "boolean"
2973
+ },
2974
+ "ingredients": {
2975
+ "type": "number"
2454
2976
  }
2455
2977
  },
2456
- {
2457
- "type": "null"
2458
- }
2459
- ]
2978
+ "required": [
2979
+ "recipe_id",
2980
+ "title",
2981
+ "url",
2982
+ "favorite",
2983
+ "ingredients"
2984
+ ],
2985
+ "additionalProperties": true
2986
+ }
2460
2987
  },
2461
- "tags": {
2462
- "anyOf": [
2463
- {
2464
- "type": "array",
2465
- "items": {
2466
- "$ref": "#/properties/id"
2988
+ "failed": {
2989
+ "type": "array",
2990
+ "items": {
2991
+ "type": "object",
2992
+ "properties": {
2993
+ "url": {
2994
+ "$ref": "#/properties/imported/items/properties/recipe_id"
2995
+ },
2996
+ "error": {
2997
+ "$ref": "#/properties/imported/items/properties/recipe_id"
2467
2998
  }
2468
2999
  },
2469
- {
2470
- "type": "null"
2471
- }
2472
- ]
2473
- },
2474
- "is_favorite": {
2475
- "type": [
2476
- "boolean",
2477
- "null"
2478
- ]
2479
- },
2480
- "created_at": {
2481
- "type": [
2482
- "string",
2483
- "null"
2484
- ]
2485
- },
2486
- "total_minutes": {
2487
- "type": [
2488
- "number",
2489
- "null"
2490
- ]
2491
- },
2492
- "url": {
2493
- "$ref": "#/properties/id"
3000
+ "required": [
3001
+ "url",
3002
+ "error"
3003
+ ],
3004
+ "additionalProperties": true
3005
+ }
2494
3006
  }
2495
3007
  },
2496
3008
  "required": [
2497
- "id",
2498
- "title",
2499
- "url"
3009
+ "imported",
3010
+ "failed"
2500
3011
  ],
2501
3012
  "additionalProperties": true,
2502
3013
  "$schema": "http://json-schema.org/draft-07/schema#"
@@ -2624,6 +3135,19 @@
2624
3135
  "null"
2625
3136
  ]
2626
3137
  },
3138
+ "is_public": {
3139
+ "type": [
3140
+ "boolean",
3141
+ "null"
3142
+ ]
3143
+ },
3144
+ "public_url": {
3145
+ "type": [
3146
+ "string",
3147
+ "null"
3148
+ ],
3149
+ "description": "Indexable public page, when published"
3150
+ },
2627
3151
  "created_at": {
2628
3152
  "type": [
2629
3153
  "string",
@@ -2756,6 +3280,13 @@
2756
3280
  "string",
2757
3281
  "null"
2758
3282
  ]
3283
+ },
3284
+ "share_url": {
3285
+ "type": [
3286
+ "string",
3287
+ "null"
3288
+ ],
3289
+ "description": "Public page showing this week's winners"
2759
3290
  }
2760
3291
  },
2761
3292
  "required": [
@@ -2868,6 +3399,19 @@
2868
3399
  "null"
2869
3400
  ]
2870
3401
  },
3402
+ "is_public": {
3403
+ "type": [
3404
+ "boolean",
3405
+ "null"
3406
+ ]
3407
+ },
3408
+ "public_url": {
3409
+ "type": [
3410
+ "string",
3411
+ "null"
3412
+ ],
3413
+ "description": "Indexable public page, when published"
3414
+ },
2871
3415
  "created_at": {
2872
3416
  "type": [
2873
3417
  "string",
@@ -3159,7 +3703,7 @@
3159
3703
  },
3160
3704
  "image_url": {
3161
3705
  "type": "string",
3162
- "description": "A real, publicly reachable photo of the dish: the og:image of the recipe page you used, or one found via web/image search. The server verifies the URL is an image and drops it otherwise. Never invent URLs; prefer import_recipe, which captures the source photo."
3706
+ "description": "A real, publicly reachable photo of the dish: the og:image of the recipe page you used, or one found via web/image search. The server verifies the URL is an image and drops it otherwise. Never invent URLs; prefer import_recipe, which captures the source photo. For generated images use set_recipe_image afterwards."
3163
3707
  },
3164
3708
  "source_url": {
3165
3709
  "type": "string"
@@ -3253,6 +3797,13 @@
3253
3797
  "string",
3254
3798
  "null"
3255
3799
  ]
3800
+ },
3801
+ "share_url": {
3802
+ "type": [
3803
+ "string",
3804
+ "null"
3805
+ ],
3806
+ "description": "Public page showing this week's winners"
3256
3807
  }
3257
3808
  },
3258
3809
  "required": [
@@ -3358,6 +3909,19 @@
3358
3909
  "null"
3359
3910
  ]
3360
3911
  },
3912
+ "is_public": {
3913
+ "type": [
3914
+ "boolean",
3915
+ "null"
3916
+ ]
3917
+ },
3918
+ "public_url": {
3919
+ "type": [
3920
+ "string",
3921
+ "null"
3922
+ ],
3923
+ "description": "Indexable public page, when published"
3924
+ },
3361
3925
  "created_at": {
3362
3926
  "type": [
3363
3927
  "string",
@@ -3503,7 +4067,7 @@
3503
4067
  },
3504
4068
  "image_url": {
3505
4069
  "type": "string",
3506
- "description": "A real, publicly reachable photo of the dish: the og:image of the recipe page you used, or one found via web/image search. The server verifies the URL is an image and drops it otherwise. Never invent URLs; prefer import_recipe, which captures the source photo."
4070
+ "description": "A real, publicly reachable photo of the dish: the og:image of the recipe page you used, or one found via web/image search. The server verifies the URL is an image and drops it otherwise. Never invent URLs; prefer import_recipe, which captures the source photo. For generated images use set_recipe_image afterwards."
3507
4071
  },
3508
4072
  "source_url": {
3509
4073
  "type": "string"
@@ -3604,6 +4168,13 @@
3604
4168
  "string",
3605
4169
  "null"
3606
4170
  ]
4171
+ },
4172
+ "share_url": {
4173
+ "type": [
4174
+ "string",
4175
+ "null"
4176
+ ],
4177
+ "description": "Public page showing this week's winners"
3607
4178
  }
3608
4179
  },
3609
4180
  "required": [
@@ -3709,6 +4280,19 @@
3709
4280
  "null"
3710
4281
  ]
3711
4282
  },
4283
+ "is_public": {
4284
+ "type": [
4285
+ "boolean",
4286
+ "null"
4287
+ ]
4288
+ },
4289
+ "public_url": {
4290
+ "type": [
4291
+ "string",
4292
+ "null"
4293
+ ],
4294
+ "description": "Indexable public page, when published"
4295
+ },
3712
4296
  "created_at": {
3713
4297
  "type": [
3714
4298
  "string",
@@ -3960,7 +4544,7 @@
3960
4544
  {
3961
4545
  "name": "message_group",
3962
4546
  "title": "Message the household",
3963
- "description": "Send SMS/MMS or email to household members. '{vote_link}' in the message becomes each member's personal voting link. Channel 'auto' texts members with a phone and emails the rest. Providers now: {\"sms\":\"dry-run\",\"email\":\"dry-run\"} (dry-run = logged only).",
4547
+ "description": "Send a push notification, SMS/MMS or email to household members. '{vote_link}' in the message becomes each member's personal voting link. Channel 'auto' texts members with a phone and emails the rest. Providers now: {\"sms\":\"dry-run\",\"email\":\"resend\",\"push\":\"web-push\"} (dry-run = logged only).",
3964
4548
  "inputSchema": {
3965
4549
  "type": "object",
3966
4550
  "properties": {
@@ -3972,9 +4556,11 @@
3972
4556
  "enum": [
3973
4557
  "sms",
3974
4558
  "email",
4559
+ "push",
3975
4560
  "auto"
3976
4561
  ],
3977
- "default": "auto"
4562
+ "default": "auto",
4563
+ "description": "auto = push to members who opted in on their vote page, else text if they have a phone, else email"
3978
4564
  },
3979
4565
  "subject": {
3980
4566
  "type": "string"
@@ -4031,6 +4617,12 @@
4031
4617
  },
4032
4618
  "email": {
4033
4619
  "$ref": "#/properties/providers/properties/sms"
4620
+ },
4621
+ "push": {
4622
+ "type": [
4623
+ "string",
4624
+ "null"
4625
+ ]
4034
4626
  }
4035
4627
  },
4036
4628
  "required": [
@@ -4052,6 +4644,7 @@
4052
4644
  "enum": [
4053
4645
  "sms",
4054
4646
  "email",
4647
+ "push",
4055
4648
  "none"
4056
4649
  ]
4057
4650
  },
@@ -4254,6 +4847,13 @@
4254
4847
  "string",
4255
4848
  "null"
4256
4849
  ]
4850
+ },
4851
+ "share_url": {
4852
+ "type": [
4853
+ "string",
4854
+ "null"
4855
+ ],
4856
+ "description": "Public page showing this week's winners"
4257
4857
  }
4258
4858
  },
4259
4859
  "required": [
@@ -4387,6 +4987,13 @@
4387
4987
  "string",
4388
4988
  "null"
4389
4989
  ]
4990
+ },
4991
+ "share_url": {
4992
+ "type": [
4993
+ "string",
4994
+ "null"
4995
+ ],
4996
+ "description": "Public page showing this week's winners"
4390
4997
  }
4391
4998
  },
4392
4999
  "required": [
@@ -4492,6 +5099,19 @@
4492
5099
  "null"
4493
5100
  ]
4494
5101
  },
5102
+ "is_public": {
5103
+ "type": [
5104
+ "boolean",
5105
+ "null"
5106
+ ]
5107
+ },
5108
+ "public_url": {
5109
+ "type": [
5110
+ "string",
5111
+ "null"
5112
+ ],
5113
+ "description": "Indexable public page, when published"
5114
+ },
4495
5115
  "created_at": {
4496
5116
  "type": [
4497
5117
  "string",
@@ -4661,6 +5281,12 @@
4661
5281
  "recipes"
4662
5282
  ],
4663
5283
  "additionalProperties": true
5284
+ },
5285
+ "share_hint": {
5286
+ "type": [
5287
+ "string",
5288
+ "null"
5289
+ ]
4664
5290
  }
4665
5291
  },
4666
5292
  "required": [
@@ -4727,6 +5353,13 @@
4727
5353
  "string",
4728
5354
  "null"
4729
5355
  ]
5356
+ },
5357
+ "share_url": {
5358
+ "type": [
5359
+ "string",
5360
+ "null"
5361
+ ],
5362
+ "description": "Public page showing this week's winners"
4730
5363
  }
4731
5364
  },
4732
5365
  "required": [
@@ -4832,6 +5465,19 @@
4832
5465
  "null"
4833
5466
  ]
4834
5467
  },
5468
+ "is_public": {
5469
+ "type": [
5470
+ "boolean",
5471
+ "null"
5472
+ ]
5473
+ },
5474
+ "public_url": {
5475
+ "type": [
5476
+ "string",
5477
+ "null"
5478
+ ],
5479
+ "description": "Indexable public page, when published"
5480
+ },
4835
5481
  "created_at": {
4836
5482
  "type": [
4837
5483
  "string",
@@ -4982,6 +5628,13 @@
4982
5628
  "string",
4983
5629
  "null"
4984
5630
  ]
5631
+ },
5632
+ "share_url": {
5633
+ "type": [
5634
+ "string",
5635
+ "null"
5636
+ ],
5637
+ "description": "Public page showing this week's winners"
4985
5638
  }
4986
5639
  },
4987
5640
  "required": [
@@ -5138,6 +5791,19 @@
5138
5791
  "null"
5139
5792
  ]
5140
5793
  },
5794
+ "is_public": {
5795
+ "type": [
5796
+ "boolean",
5797
+ "null"
5798
+ ]
5799
+ },
5800
+ "public_url": {
5801
+ "type": [
5802
+ "string",
5803
+ "null"
5804
+ ],
5805
+ "description": "Indexable public page, when published"
5806
+ },
5141
5807
  "created_at": {
5142
5808
  "type": [
5143
5809
  "string",
@@ -5183,6 +5849,13 @@
5183
5849
  "string",
5184
5850
  "null"
5185
5851
  ]
5852
+ },
5853
+ "share_url": {
5854
+ "type": [
5855
+ "string",
5856
+ "null"
5857
+ ],
5858
+ "description": "Public page showing this week's winners"
5186
5859
  }
5187
5860
  },
5188
5861
  "required": [
@@ -5294,6 +5967,13 @@
5294
5967
  "string",
5295
5968
  "null"
5296
5969
  ]
5970
+ },
5971
+ "share_url": {
5972
+ "type": [
5973
+ "string",
5974
+ "null"
5975
+ ],
5976
+ "description": "Public page showing this week's winners"
5297
5977
  }
5298
5978
  },
5299
5979
  "required": [
@@ -5501,6 +6181,13 @@
5501
6181
  "string",
5502
6182
  "null"
5503
6183
  ]
6184
+ },
6185
+ "share_url": {
6186
+ "type": [
6187
+ "string",
6188
+ "null"
6189
+ ],
6190
+ "description": "Public page showing this week's winners"
5504
6191
  }
5505
6192
  },
5506
6193
  "required": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-chef-mcp",
3
- "version": "1.0.0",
3
+ "version": "1.0.9",
4
4
  "description": "Family meal planning run by your own AI agent: weekly dinners, household votes, grocery list minus the pantry. Stdio MCP server for the hosted Agent Chef service (https://agentchef.net/mcp).",
5
5
  "homepage": "https://agentchef.net",
6
6
  "repository": {