mcp-grocy 2.7.0 → 2.7.2
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.
- package/CHANGELOG.md +14 -0
- package/README.md +15 -1
- package/build/api/client.js +119 -0
- package/build/config/index.js +283 -0
- package/build/main.js +44 -0
- package/build/resources/CHANGELOG.md +15 -3
- package/build/resources/README.md +15 -1
- package/build/resources/api-reference.md +2 -1
- package/build/resources/response-format.md +1 -3
- package/build/server/http-server.js +398 -0
- package/build/server/mcp-server.js +230 -0
- package/build/server/resources.js +73 -0
- package/build/server/tool-input-zod.js +86 -0
- package/build/tools/base.js +157 -0
- package/build/tools/household/definitions.js +161 -0
- package/build/tools/household/handlers.js +109 -0
- package/build/tools/household/index.js +25 -0
- package/build/tools/index.js +2 -0
- package/build/tools/inventory/definitions.js +416 -0
- package/build/tools/inventory/handlers.js +443 -0
- package/build/tools/inventory/index.js +32 -0
- package/build/tools/module-loader.js +154 -0
- package/build/tools/recipes/definitions.js +278 -0
- package/build/tools/recipes/handlers.js +518 -0
- package/build/tools/recipes/index.js +33 -0
- package/build/tools/recipes/validations.js +29 -0
- package/build/tools/shopping/definitions.js +147 -0
- package/build/tools/shopping/handlers.js +198 -0
- package/build/tools/shopping/index.js +17 -0
- package/build/tools/system/definitions.js +89 -0
- package/build/tools/system/handlers.js +156 -0
- package/build/tools/system/index.js +16 -0
- package/build/tools/types.js +1 -0
- package/build/tools/validation-helpers.js +39 -0
- package/build/types/index.js +64 -0
- package/build/utils/errors.js +143 -0
- package/build/utils/logger.js +142 -0
- package/build/version.js +1 -1
- package/package.json +27 -25
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { config } from '../../config/index.js';
|
|
2
|
+
const RECIPES_COOKING_COMPLETE_TOOL = 'recipes_cooking_complete';
|
|
3
|
+
export const recipeToolDefinitions = [
|
|
4
|
+
// ==================== RECIPE MANAGEMENT ====================
|
|
5
|
+
{
|
|
6
|
+
name: 'recipes_management_get',
|
|
7
|
+
description: '[RECIPES/MANAGEMENT] **List/search many recipes**—you choose which fields (e.g. id+name). For one full recipe by ID use recipes_management_get_by_id.',
|
|
8
|
+
annotations: { readOnlyHint: true },
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
fields: {
|
|
13
|
+
type: 'array',
|
|
14
|
+
items: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
enum: [
|
|
17
|
+
'id',
|
|
18
|
+
'name',
|
|
19
|
+
'description',
|
|
20
|
+
'base_servings',
|
|
21
|
+
'desired_servings',
|
|
22
|
+
'not_check_shoppinglist',
|
|
23
|
+
'type',
|
|
24
|
+
'picture_file_name',
|
|
25
|
+
'ingredients',
|
|
26
|
+
'instructions',
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
description: 'Array of field names to retrieve. For basic lookup use ["id", "name"]. For recipe planning use ["id", "name", "description", "base_servings"]. Available fields: id, name, description, base_servings, desired_servings, not_check_shoppinglist, type, picture_file_name, ingredients, instructions',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
required: ['fields'],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'recipes_management_get_by_id',
|
|
37
|
+
description: '[RECIPES/MANAGEMENT] **Single recipe** by recipeId (full record). To scan or filter many recipes use recipes_management_get with a fields list.',
|
|
38
|
+
annotations: { readOnlyHint: true },
|
|
39
|
+
inputSchema: {
|
|
40
|
+
type: 'object',
|
|
41
|
+
properties: {
|
|
42
|
+
recipeId: {
|
|
43
|
+
type: 'number',
|
|
44
|
+
description: 'ID of the recipe to retrieve. Use recipes_management_get tool to find the correct recipe ID by name.',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
required: ['recipeId'],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'recipes_management_create',
|
|
52
|
+
description: '[RECIPES/MANAGEMENT] Create a new recipe in your Grocy instance with the provided name, description, base servings, and instructions.',
|
|
53
|
+
inputSchema: {
|
|
54
|
+
type: 'object',
|
|
55
|
+
properties: {
|
|
56
|
+
name: {
|
|
57
|
+
type: 'string',
|
|
58
|
+
description: 'Name of the recipe',
|
|
59
|
+
},
|
|
60
|
+
description: {
|
|
61
|
+
type: 'string',
|
|
62
|
+
description: 'Description of the recipe (optional)',
|
|
63
|
+
},
|
|
64
|
+
baseServings: {
|
|
65
|
+
type: 'number',
|
|
66
|
+
description: 'Base servings for the recipe (e.g., 4 for a family recipe)',
|
|
67
|
+
default: 1,
|
|
68
|
+
},
|
|
69
|
+
instructions: {
|
|
70
|
+
type: 'string',
|
|
71
|
+
description: 'Recipe instructions (optional)',
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
required: ['name'],
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'recipes_management_print_label',
|
|
79
|
+
description: '[RECIPES/MANAGEMENT] Print a Grocycode label for a recipe. Use recipes_management_get to find valid recipeId values.',
|
|
80
|
+
inputSchema: {
|
|
81
|
+
type: 'object',
|
|
82
|
+
properties: {
|
|
83
|
+
recipeId: {
|
|
84
|
+
type: 'number',
|
|
85
|
+
description: 'ID of the recipe to print label for. Use recipes_management_get tool to find the correct recipe ID.',
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
required: ['recipeId'],
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'recipes_fulfillment_get',
|
|
93
|
+
description: '[RECIPES/FULFILLMENT] **Single recipe**—can I make this dish? Ingredient coverage vs stock for one recipeId. For an overview of many recipes at once use recipes_fulfillment_get_all.',
|
|
94
|
+
annotations: { readOnlyHint: true },
|
|
95
|
+
inputSchema: {
|
|
96
|
+
type: 'object',
|
|
97
|
+
properties: {
|
|
98
|
+
recipeId: {
|
|
99
|
+
type: 'number',
|
|
100
|
+
description: 'ID of the recipe to check fulfillment for. Use recipes_management_get tool to find the correct recipe ID by name.',
|
|
101
|
+
},
|
|
102
|
+
onlyMissing: {
|
|
103
|
+
type: 'boolean',
|
|
104
|
+
description: 'If true, only return missing/insufficient ingredients',
|
|
105
|
+
default: false,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
required: ['recipeId'],
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: 'recipes_fulfillment_get_all',
|
|
113
|
+
description: '[RECIPES/FULFILLMENT] **All recipes**—batch view of which recipes are makeable with current stock (no recipeId). For one named recipe use recipes_fulfillment_get.',
|
|
114
|
+
annotations: { readOnlyHint: true },
|
|
115
|
+
inputSchema: {
|
|
116
|
+
type: 'object',
|
|
117
|
+
properties: {},
|
|
118
|
+
required: [],
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
// ==================== MEAL PLANNING ====================
|
|
122
|
+
{
|
|
123
|
+
name: 'recipes_mealplan_get',
|
|
124
|
+
description: '[RECIPES/MEALPLAN] Get your meal plan data from Grocy instance with corresponding recipe details. Returns planned meals for the requested date plus surrounding days for context. Use this to find out what recipes/meals are planned for a specific date (e.g., "what\'s for dinner tomorrow", "recipes for today", "meal plan for next week"). The returned data includes the id field (meal plan entry ID) which can be used with recipes_mealplan_delete_entry.',
|
|
125
|
+
annotations: { readOnlyHint: true },
|
|
126
|
+
inputSchema: {
|
|
127
|
+
type: 'object',
|
|
128
|
+
properties: {
|
|
129
|
+
date: {
|
|
130
|
+
type: 'string',
|
|
131
|
+
description: 'Date in YYYY-MM-DD format (e.g., "2024-12-25"). The tool will return meal plans for this date plus the previous and next day for better context.',
|
|
132
|
+
},
|
|
133
|
+
weekly: {
|
|
134
|
+
type: 'boolean',
|
|
135
|
+
description: 'If true, returns the entire calendar week containing the specified date.',
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
required: ['date'],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'recipes_mealplan_get_sections',
|
|
143
|
+
description: '[RECIPES/MEALPLAN] **Read-only:** list meal plan section names/IDs (Breakfast, Dinner, …). Does not return planned meals or dates—use recipes_mealplan_get for the calendar. Needed before recipes_mealplan_add_recipe to pick sectionId; the row with id -1 and name null is Grocy\'s built-in "no section".',
|
|
144
|
+
annotations: { readOnlyHint: true },
|
|
145
|
+
inputSchema: {
|
|
146
|
+
type: 'object',
|
|
147
|
+
properties: {},
|
|
148
|
+
required: [],
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'recipes_mealplan_add_recipe',
|
|
153
|
+
description: '[RECIPES/MEALPLAN] **Write:** put a recipe on the calendar (date + section + servings). Not for listing sections (recipes_mealplan_get_sections) or viewing the plan (recipes_mealplan_get).',
|
|
154
|
+
inputSchema: {
|
|
155
|
+
type: 'object',
|
|
156
|
+
properties: {
|
|
157
|
+
recipeId: {
|
|
158
|
+
type: 'number',
|
|
159
|
+
description: 'ID of the recipe to add to the meal plan. Use recipes_management_get tool to find valid recipe IDs and their names.',
|
|
160
|
+
},
|
|
161
|
+
day: {
|
|
162
|
+
type: 'string',
|
|
163
|
+
description: 'Day to add the recipe to in YYYY-MM-DD format (e.g., "2024-12-25").',
|
|
164
|
+
},
|
|
165
|
+
servings: {
|
|
166
|
+
type: 'number',
|
|
167
|
+
description: 'Number of servings for this meal plan entry (e.g., 2 for a family of two, 4 for a family of four).',
|
|
168
|
+
},
|
|
169
|
+
sectionId: {
|
|
170
|
+
type: 'number',
|
|
171
|
+
description: 'ID of the meal plan section that defines when this meal will be consumed (e.g., breakfast, lunch, dinner, snacks). Use recipes_mealplan_get_sections tool to discover what sections are available in your Grocy instance and get their specific IDs and names. Use -1 for Grocy\'s built-in "no section"; if the user names no meal or section, use -1 rather than guessing.',
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
required: ['recipeId', 'day', 'servings', 'sectionId'],
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: 'recipes_mealplan_delete_entry',
|
|
179
|
+
description: '[RECIPES/MEALPLAN] Delete a specific recipe entry from the meal plan. Use recipes_mealplan_get to find the mealPlanEntryId of the entry you want to remove.',
|
|
180
|
+
inputSchema: {
|
|
181
|
+
type: 'object',
|
|
182
|
+
properties: {
|
|
183
|
+
mealPlanEntryId: {
|
|
184
|
+
type: 'number',
|
|
185
|
+
description: 'ID of the specific meal plan entry to delete. Use recipes_mealplan_get to find the correct entry ID.',
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
required: ['mealPlanEntryId'],
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
// ==================== COOKING ====================
|
|
192
|
+
{
|
|
193
|
+
name: 'recipes_cooking_consume',
|
|
194
|
+
description: '[RECIPES/COOKING] Consume/cook a recipe, which removes the required ingredients from stock.',
|
|
195
|
+
inputSchema: {
|
|
196
|
+
type: 'object',
|
|
197
|
+
properties: {
|
|
198
|
+
recipeId: {
|
|
199
|
+
type: 'number',
|
|
200
|
+
description: 'ID of the recipe to consume. Use recipes_management_get tool to find the correct recipe ID by name.',
|
|
201
|
+
},
|
|
202
|
+
servings: {
|
|
203
|
+
type: 'number',
|
|
204
|
+
description: 'Number of servings to cook (scales ingredient consumption accordingly)',
|
|
205
|
+
default: 1,
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
required: ['recipeId'],
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
// ==================== SHOPPING INTEGRATION ====================
|
|
212
|
+
{
|
|
213
|
+
name: 'recipes_shopping_add_all_products',
|
|
214
|
+
description: '[RECIPES/SHOPPING] Add **every** recipe ingredient to the shopping list (ignores what you already have). For only what you are short on use recipes_shopping_add_missing_products.',
|
|
215
|
+
inputSchema: {
|
|
216
|
+
type: 'object',
|
|
217
|
+
properties: {
|
|
218
|
+
recipeId: {
|
|
219
|
+
type: 'number',
|
|
220
|
+
description: 'ID of the recipe whose products should be added to shopping list. Use recipes_management_get tool to find the correct recipe ID by name.',
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
required: ['recipeId'],
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: 'recipes_shopping_add_missing_products',
|
|
228
|
+
description: '[RECIPES/SHOPPING] Add **only missing or insufficient** ingredients (compares to stock). To add the full ingredient set regardless of stock use recipes_shopping_add_all_products.',
|
|
229
|
+
inputSchema: {
|
|
230
|
+
type: 'object',
|
|
231
|
+
properties: {
|
|
232
|
+
recipeId: {
|
|
233
|
+
type: 'number',
|
|
234
|
+
description: 'ID of the recipe to check for missing products. Use recipes_management_get tool to find the correct recipe ID by name.',
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
required: ['recipeId'],
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
// ==================== ADVANCED COOKING ====================
|
|
241
|
+
(() => {
|
|
242
|
+
const { toolSubConfigs } = config.parseToolConfiguration();
|
|
243
|
+
const subConfigs = toolSubConfigs?.get(RECIPES_COOKING_COMPLETE_TOOL);
|
|
244
|
+
const allowNoMealPlan = subConfigs?.get('allow_no_meal_plan') ?? false;
|
|
245
|
+
const allowAlreadyDone = subConfigs?.get('allow_meal_plan_entry_already_done') ?? false;
|
|
246
|
+
return {
|
|
247
|
+
name: 'recipes_cooking_complete',
|
|
248
|
+
description: '[RECIPES/COOKING] When the user cooks something this records it as done, consumes recipe ingredients, and creates labeled stock entries with custom portion sizes.',
|
|
249
|
+
inputSchema: {
|
|
250
|
+
type: 'object',
|
|
251
|
+
properties: {
|
|
252
|
+
...(allowNoMealPlan
|
|
253
|
+
? {
|
|
254
|
+
recipeId: {
|
|
255
|
+
type: 'number',
|
|
256
|
+
description: 'ID of the recipe to cook directly.',
|
|
257
|
+
},
|
|
258
|
+
}
|
|
259
|
+
: {
|
|
260
|
+
mealPlanEntryId: {
|
|
261
|
+
type: 'number',
|
|
262
|
+
description: `ID of the meal plan entry. Must be a recipe entry; note and product entries cannot be completed with this tool.${allowAlreadyDone ? '' : ' Note: This will fail if the meal plan entry is already marked as done (done=1).'}`,
|
|
263
|
+
},
|
|
264
|
+
}),
|
|
265
|
+
stockAmounts: {
|
|
266
|
+
type: 'array',
|
|
267
|
+
items: {
|
|
268
|
+
type: 'number',
|
|
269
|
+
minimum: 0.1,
|
|
270
|
+
},
|
|
271
|
+
description: 'Array of serving amounts for each stock entry to create (e.g., [1, 2, 2] for 1 single serving + 2 double servings). Total will be used for ingredient consumption.',
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
required: [...(allowNoMealPlan ? ['recipeId'] : ['mealPlanEntryId']), 'stockAmounts'],
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
})(),
|
|
278
|
+
];
|