@davidwoods/skylight-mcp 1.7.0 → 1.8.0
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/LICENSE +22 -22
- package/README.md +633 -584
- package/THIRD_PARTY_NOTICES.md +38 -38
- package/dist/api/credential-store.d.ts.map +1 -1
- package/dist/api/credential-store.js +2 -1
- package/dist/api/credential-store.js.map +1 -1
- package/dist/api/endpoints/categories.d.ts +6 -6
- package/dist/api/endpoints/categories.d.ts.map +1 -1
- package/dist/api/endpoints/categories.js +6 -13
- package/dist/api/endpoints/categories.js.map +1 -1
- package/dist/api/endpoints/chores.d.ts +8 -0
- package/dist/api/endpoints/chores.d.ts.map +1 -1
- package/dist/api/endpoints/chores.js +9 -0
- package/dist/api/endpoints/chores.js.map +1 -1
- package/dist/api/endpoints/taskbox.d.ts +8 -0
- package/dist/api/endpoints/taskbox.d.ts.map +1 -1
- package/dist/api/endpoints/taskbox.js +17 -0
- package/dist/api/endpoints/taskbox.js.map +1 -1
- package/dist/api/types.d.ts +14 -0
- package/dist/api/types.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +9 -8
- package/dist/cli.js.map +1 -1
- package/dist/config.js +23 -23
- package/dist/doctor.d.ts +10 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +23 -7
- package/dist/doctor.js.map +1 -1
- package/dist/tools/calendar.d.ts +5 -0
- package/dist/tools/calendar.d.ts.map +1 -1
- package/dist/tools/calendar.js +107 -71
- package/dist/tools/calendar.js.map +1 -1
- package/dist/tools/chores.d.ts.map +1 -1
- package/dist/tools/chores.js +53 -81
- package/dist/tools/chores.js.map +1 -1
- package/dist/tools/family.js +17 -17
- package/dist/tools/lists.js +85 -85
- package/dist/tools/meals.js +102 -102
- package/dist/tools/messages.d.ts.map +1 -1
- package/dist/tools/messages.js +37 -49
- package/dist/tools/messages.js.map +1 -1
- package/dist/tools/misc.js +14 -14
- package/dist/tools/photos.js +6 -6
- package/dist/tools/planning.d.ts.map +1 -1
- package/dist/tools/planning.js +24 -23
- package/dist/tools/planning.js.map +1 -1
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +1 -0
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/rewards.d.ts.map +1 -1
- package/dist/tools/rewards.js +74 -90
- package/dist/tools/rewards.js.map +1 -1
- package/dist/tools/tasks.d.ts.map +1 -1
- package/dist/tools/tasks.js +45 -10
- package/dist/tools/tasks.js.map +1 -1
- package/dist/utils/errors.js +16 -16
- package/package.json +78 -78
package/dist/tools/lists.js
CHANGED
|
@@ -27,9 +27,9 @@ async function resolveListId(listId, listName, defaultToGrocery = false) {
|
|
|
27
27
|
}
|
|
28
28
|
export function registerListTools(server) {
|
|
29
29
|
// get_lists tool
|
|
30
|
-
server.tool("get_lists", `Get all lists from Skylight (grocery lists, to-do lists, etc.).
|
|
31
|
-
|
|
32
|
-
Use this to see what lists are available before adding items.
|
|
30
|
+
server.tool("get_lists", `Get all lists from Skylight (grocery lists, to-do lists, etc.).
|
|
31
|
+
|
|
32
|
+
Use this to see what lists are available before adding items.
|
|
33
33
|
Returns list names, types (shopping/to_do), and item counts.`, {}, async () => {
|
|
34
34
|
try {
|
|
35
35
|
const lists = await getLists();
|
|
@@ -80,13 +80,13 @@ Returns list names, types (shopping/to_do), and item counts.`, {}, async () => {
|
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
82
|
// get_list_items tool
|
|
83
|
-
server.tool("get_list_items", `Get items from a specific Skylight list.
|
|
84
|
-
|
|
85
|
-
Use this to answer:
|
|
86
|
-
- "What's on the grocery list?"
|
|
87
|
-
- "Show me my to-do list"
|
|
88
|
-
- "What items are on [list name]?"
|
|
89
|
-
|
|
83
|
+
server.tool("get_list_items", `Get items from a specific Skylight list.
|
|
84
|
+
|
|
85
|
+
Use this to answer:
|
|
86
|
+
- "What's on the grocery list?"
|
|
87
|
+
- "Show me my to-do list"
|
|
88
|
+
- "What items are on [list name]?"
|
|
89
|
+
|
|
90
90
|
Returns items organized by section with their completion status.`, {
|
|
91
91
|
listName: z
|
|
92
92
|
.string()
|
|
@@ -219,17 +219,17 @@ Returns items organized by section with their completion status.`, {
|
|
|
219
219
|
}
|
|
220
220
|
});
|
|
221
221
|
// create_list tool
|
|
222
|
-
server.tool("create_list", `Create a new list in Skylight.
|
|
223
|
-
|
|
224
|
-
Use this when:
|
|
225
|
-
- Creating a new shopping/grocery list
|
|
226
|
-
- Creating a new to-do list
|
|
227
|
-
|
|
228
|
-
Parameters:
|
|
229
|
-
- label (required): Name of the list (e.g., "Vacation Packing", "Weekly Groceries")
|
|
230
|
-
- kind (required): "shopping" for grocery/shopping lists, "to_do" for task lists
|
|
231
|
-
- color: Optional color for the list
|
|
232
|
-
|
|
222
|
+
server.tool("create_list", `Create a new list in Skylight.
|
|
223
|
+
|
|
224
|
+
Use this when:
|
|
225
|
+
- Creating a new shopping/grocery list
|
|
226
|
+
- Creating a new to-do list
|
|
227
|
+
|
|
228
|
+
Parameters:
|
|
229
|
+
- label (required): Name of the list (e.g., "Vacation Packing", "Weekly Groceries")
|
|
230
|
+
- kind (required): "shopping" for grocery/shopping lists, "to_do" for task lists
|
|
231
|
+
- color: Optional color for the list
|
|
232
|
+
|
|
233
233
|
Returns: The created list details.`, {
|
|
234
234
|
label: z.string().describe("Name of the list (e.g., 'Vacation Packing')"),
|
|
235
235
|
kind: z.enum(["shopping", "to_do"]).describe("Type of list: 'shopping' or 'to_do'"),
|
|
@@ -254,19 +254,19 @@ Returns: The created list details.`, {
|
|
|
254
254
|
}
|
|
255
255
|
});
|
|
256
256
|
// update_list tool
|
|
257
|
-
server.tool("update_list", `Update an existing list's name or settings.
|
|
258
|
-
|
|
259
|
-
Use this when:
|
|
260
|
-
- Renaming a list
|
|
261
|
-
- Changing a list's type or color
|
|
262
|
-
|
|
263
|
-
Parameters:
|
|
264
|
-
- listId: ID of the list to update (use get_lists to find IDs)
|
|
265
|
-
- listName: Name of the list to update (alternative to listId)
|
|
266
|
-
- label: New name for the list
|
|
267
|
-
- kind: New type ("shopping" or "to_do")
|
|
268
|
-
- color: New color for the list
|
|
269
|
-
|
|
257
|
+
server.tool("update_list", `Update an existing list's name or settings.
|
|
258
|
+
|
|
259
|
+
Use this when:
|
|
260
|
+
- Renaming a list
|
|
261
|
+
- Changing a list's type or color
|
|
262
|
+
|
|
263
|
+
Parameters:
|
|
264
|
+
- listId: ID of the list to update (use get_lists to find IDs)
|
|
265
|
+
- listName: Name of the list to update (alternative to listId)
|
|
266
|
+
- label: New name for the list
|
|
267
|
+
- kind: New type ("shopping" or "to_do")
|
|
268
|
+
- color: New color for the list
|
|
269
|
+
|
|
270
270
|
Returns: The updated list details.`, {
|
|
271
271
|
listId: z.string().optional().describe("ID of the list to update"),
|
|
272
272
|
listName: z.string().optional().describe("Name of the list to update (alternative to listId)"),
|
|
@@ -307,16 +307,16 @@ Returns: The updated list details.`, {
|
|
|
307
307
|
}
|
|
308
308
|
});
|
|
309
309
|
// delete_list tool
|
|
310
|
-
server.tool("delete_list", `Delete a list from Skylight.
|
|
311
|
-
|
|
312
|
-
Use this when:
|
|
313
|
-
- Removing an old or unused list
|
|
314
|
-
- Deleting a temporary list
|
|
315
|
-
|
|
316
|
-
Parameters:
|
|
317
|
-
- listId: ID of the list to delete (use get_lists to find IDs)
|
|
318
|
-
- listName: Name of the list to delete (alternative to listId)
|
|
319
|
-
|
|
310
|
+
server.tool("delete_list", `Delete a list from Skylight.
|
|
311
|
+
|
|
312
|
+
Use this when:
|
|
313
|
+
- Removing an old or unused list
|
|
314
|
+
- Deleting a temporary list
|
|
315
|
+
|
|
316
|
+
Parameters:
|
|
317
|
+
- listId: ID of the list to delete (use get_lists to find IDs)
|
|
318
|
+
- listName: Name of the list to delete (alternative to listId)
|
|
319
|
+
|
|
320
320
|
Note: This permanently deletes the list and all its items.`, {
|
|
321
321
|
listId: z.string().optional().describe("ID of the list to delete"),
|
|
322
322
|
listName: z.string().optional().describe("Name of the list to delete (alternative to listId)"),
|
|
@@ -347,23 +347,23 @@ Note: This permanently deletes the list and all its items.`, {
|
|
|
347
347
|
}
|
|
348
348
|
});
|
|
349
349
|
// create_list_item tool
|
|
350
|
-
server.tool("create_list_item", `Add an item to a Skylight list.
|
|
351
|
-
|
|
352
|
-
Use this when:
|
|
353
|
-
- Adding something to the grocery list: "Add milk to the shopping list"
|
|
354
|
-
- Creating a to-do item: "Put 'call doctor' on my to-do list"
|
|
355
|
-
- Adding items to any list
|
|
356
|
-
|
|
357
|
-
Parameters:
|
|
358
|
-
- label (required): The item text (e.g., "Milk", "Call doctor")
|
|
359
|
-
- listId: ID of the list to add to
|
|
360
|
-
- listName: Name of the list to add to (e.g., "Grocery List")
|
|
361
|
-
- section: Category within the list (e.g., "Dairy", "Produce")
|
|
362
|
-
|
|
363
|
-
If no list is specified, adds to the default grocery list.
|
|
364
|
-
|
|
365
|
-
Returns: Confirmation of the added item.
|
|
366
|
-
|
|
350
|
+
server.tool("create_list_item", `Add an item to a Skylight list.
|
|
351
|
+
|
|
352
|
+
Use this when:
|
|
353
|
+
- Adding something to the grocery list: "Add milk to the shopping list"
|
|
354
|
+
- Creating a to-do item: "Put 'call doctor' on my to-do list"
|
|
355
|
+
- Adding items to any list
|
|
356
|
+
|
|
357
|
+
Parameters:
|
|
358
|
+
- label (required): The item text (e.g., "Milk", "Call doctor")
|
|
359
|
+
- listId: ID of the list to add to
|
|
360
|
+
- listName: Name of the list to add to (e.g., "Grocery List")
|
|
361
|
+
- section: Category within the list (e.g., "Dairy", "Produce")
|
|
362
|
+
|
|
363
|
+
If no list is specified, adds to the default grocery list.
|
|
364
|
+
|
|
365
|
+
Returns: Confirmation of the added item.
|
|
366
|
+
|
|
367
367
|
Related: Use get_lists to see available lists and their IDs.`, {
|
|
368
368
|
label: z.string().describe("The item text to add (e.g., 'Milk', 'Call doctor')"),
|
|
369
369
|
listId: z.string().optional().describe("ID of the list to add to"),
|
|
@@ -397,20 +397,20 @@ Related: Use get_lists to see available lists and their IDs.`, {
|
|
|
397
397
|
}
|
|
398
398
|
});
|
|
399
399
|
// update_list_item tool
|
|
400
|
-
server.tool("update_list_item", `Update a list item (mark complete, rename, move to section).
|
|
401
|
-
|
|
402
|
-
Use this when:
|
|
403
|
-
- Marking an item as complete: "Check off milk from the list"
|
|
404
|
-
- Renaming an item: "Change 'milk' to '2% milk'"
|
|
405
|
-
- Moving an item to a different section
|
|
406
|
-
|
|
407
|
-
Parameters:
|
|
408
|
-
- itemId (required): ID of the item to update
|
|
409
|
-
- listId (required): ID of the list containing the item
|
|
410
|
-
- label: New text for the item
|
|
411
|
-
- status: "completed" to check off, "pending" to uncheck
|
|
412
|
-
- section: Move to a different section
|
|
413
|
-
|
|
400
|
+
server.tool("update_list_item", `Update a list item (mark complete, rename, move to section).
|
|
401
|
+
|
|
402
|
+
Use this when:
|
|
403
|
+
- Marking an item as complete: "Check off milk from the list"
|
|
404
|
+
- Renaming an item: "Change 'milk' to '2% milk'"
|
|
405
|
+
- Moving an item to a different section
|
|
406
|
+
|
|
407
|
+
Parameters:
|
|
408
|
+
- itemId (required): ID of the item to update
|
|
409
|
+
- listId (required): ID of the list containing the item
|
|
410
|
+
- label: New text for the item
|
|
411
|
+
- status: "completed" to check off, "pending" to uncheck
|
|
412
|
+
- section: Move to a different section
|
|
413
|
+
|
|
414
414
|
Returns: The updated item details.`, {
|
|
415
415
|
itemId: z.string().describe("ID of the item to update"),
|
|
416
416
|
listId: z.string().describe("ID of the list containing the item"),
|
|
@@ -445,16 +445,16 @@ Returns: The updated item details.`, {
|
|
|
445
445
|
}
|
|
446
446
|
});
|
|
447
447
|
// delete_list_item tool
|
|
448
|
-
server.tool("delete_list_item", `Remove an item from a list.
|
|
449
|
-
|
|
450
|
-
Use this when:
|
|
451
|
-
- Removing an item that was added by mistake
|
|
452
|
-
- Deleting an item instead of marking it complete
|
|
453
|
-
|
|
454
|
-
Parameters:
|
|
455
|
-
- itemId (required): ID of the item to delete
|
|
456
|
-
- listId (required): ID of the list containing the item
|
|
457
|
-
|
|
448
|
+
server.tool("delete_list_item", `Remove an item from a list.
|
|
449
|
+
|
|
450
|
+
Use this when:
|
|
451
|
+
- Removing an item that was added by mistake
|
|
452
|
+
- Deleting an item instead of marking it complete
|
|
453
|
+
|
|
454
|
+
Parameters:
|
|
455
|
+
- itemId (required): ID of the item to delete
|
|
456
|
+
- listId (required): ID of the list containing the item
|
|
457
|
+
|
|
458
458
|
Note: This permanently removes the item. Use update_list_item with status="completed" to check it off instead.`, {
|
|
459
459
|
itemId: z.string().describe("ID of the item to delete"),
|
|
460
460
|
listId: z.string().describe("ID of the list containing the item"),
|
package/dist/tools/meals.js
CHANGED
|
@@ -6,12 +6,12 @@ import { formatErrorForMcp } from "../utils/errors.js";
|
|
|
6
6
|
import { getConfig } from "../config.js";
|
|
7
7
|
export function registerMealTools(server) {
|
|
8
8
|
// get_meal_categories tool
|
|
9
|
-
server.tool("get_meal_categories", `Get meal categories (Breakfast, Lunch, Dinner, etc.) - Plus subscription required.
|
|
10
|
-
|
|
11
|
-
Use this when:
|
|
12
|
-
- Finding category IDs for scheduling meals
|
|
13
|
-
- Seeing what meal times are available
|
|
14
|
-
|
|
9
|
+
server.tool("get_meal_categories", `Get meal categories (Breakfast, Lunch, Dinner, etc.) - Plus subscription required.
|
|
10
|
+
|
|
11
|
+
Use this when:
|
|
12
|
+
- Finding category IDs for scheduling meals
|
|
13
|
+
- Seeing what meal times are available
|
|
14
|
+
|
|
15
15
|
Returns: List of meal categories with IDs.`, {}, async () => {
|
|
16
16
|
try {
|
|
17
17
|
const categories = await getMealCategories();
|
|
@@ -35,12 +35,12 @@ Returns: List of meal categories with IDs.`, {}, async () => {
|
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
37
|
// get_recipes tool
|
|
38
|
-
server.tool("get_recipes", `Get all saved recipes - Plus subscription required.
|
|
39
|
-
|
|
40
|
-
Use this when:
|
|
41
|
-
- Browsing available recipes
|
|
42
|
-
- Finding a recipe ID for meal planning
|
|
43
|
-
|
|
38
|
+
server.tool("get_recipes", `Get all saved recipes - Plus subscription required.
|
|
39
|
+
|
|
40
|
+
Use this when:
|
|
41
|
+
- Browsing available recipes
|
|
42
|
+
- Finding a recipe ID for meal planning
|
|
43
|
+
|
|
44
44
|
Returns: List of recipes with their details.`, {}, async () => {
|
|
45
45
|
try {
|
|
46
46
|
const recipes = await getRecipes();
|
|
@@ -70,11 +70,11 @@ Returns: List of recipes with their details.`, {}, async () => {
|
|
|
70
70
|
}
|
|
71
71
|
});
|
|
72
72
|
// get_recipe tool
|
|
73
|
-
server.tool("get_recipe", `Get details for a specific recipe - Plus subscription required.
|
|
74
|
-
|
|
75
|
-
Parameters:
|
|
76
|
-
- recipeId (required): ID of the recipe
|
|
77
|
-
|
|
73
|
+
server.tool("get_recipe", `Get details for a specific recipe - Plus subscription required.
|
|
74
|
+
|
|
75
|
+
Parameters:
|
|
76
|
+
- recipeId (required): ID of the recipe
|
|
77
|
+
|
|
78
78
|
Returns: Recipe details including description.`, {
|
|
79
79
|
recipeId: z.string().describe("ID of the recipe"),
|
|
80
80
|
}, async ({ recipeId }) => {
|
|
@@ -98,17 +98,17 @@ Returns: Recipe details including description.`, {
|
|
|
98
98
|
}
|
|
99
99
|
});
|
|
100
100
|
// create_recipe tool
|
|
101
|
-
server.tool("create_recipe", `Create a new recipe - Plus subscription required.
|
|
102
|
-
|
|
103
|
-
Use this when:
|
|
104
|
-
- Adding a new family recipe
|
|
105
|
-
- Saving a meal for meal planning
|
|
106
|
-
|
|
107
|
-
Parameters:
|
|
108
|
-
- summary (required): Recipe name
|
|
109
|
-
- description: Recipe details or instructions
|
|
110
|
-
- mealCategoryId: Category ID (use get_meal_categories)
|
|
111
|
-
|
|
101
|
+
server.tool("create_recipe", `Create a new recipe - Plus subscription required.
|
|
102
|
+
|
|
103
|
+
Use this when:
|
|
104
|
+
- Adding a new family recipe
|
|
105
|
+
- Saving a meal for meal planning
|
|
106
|
+
|
|
107
|
+
Parameters:
|
|
108
|
+
- summary (required): Recipe name
|
|
109
|
+
- description: Recipe details or instructions
|
|
110
|
+
- mealCategoryId: Category ID (use get_meal_categories)
|
|
111
|
+
|
|
112
112
|
Returns: The created recipe.`, {
|
|
113
113
|
summary: z.string().describe("Recipe name (e.g., 'Spaghetti Bolognese')"),
|
|
114
114
|
description: z.string().optional().describe("Recipe details or instructions"),
|
|
@@ -133,13 +133,13 @@ Returns: The created recipe.`, {
|
|
|
133
133
|
}
|
|
134
134
|
});
|
|
135
135
|
// update_recipe tool
|
|
136
|
-
server.tool("update_recipe", `Update an existing recipe - Plus subscription required.
|
|
137
|
-
|
|
138
|
-
Parameters:
|
|
139
|
-
- recipeId (required): ID of the recipe
|
|
140
|
-
- summary: New name
|
|
141
|
-
- description: New description
|
|
142
|
-
|
|
136
|
+
server.tool("update_recipe", `Update an existing recipe - Plus subscription required.
|
|
137
|
+
|
|
138
|
+
Parameters:
|
|
139
|
+
- recipeId (required): ID of the recipe
|
|
140
|
+
- summary: New name
|
|
141
|
+
- description: New description
|
|
142
|
+
|
|
143
143
|
Returns: The updated recipe.`, {
|
|
144
144
|
recipeId: z.string().describe("ID of the recipe to update"),
|
|
145
145
|
summary: z.string().optional().describe("New recipe name"),
|
|
@@ -169,11 +169,11 @@ Returns: The updated recipe.`, {
|
|
|
169
169
|
}
|
|
170
170
|
});
|
|
171
171
|
// delete_recipe tool
|
|
172
|
-
server.tool("delete_recipe", `Delete a recipe - Plus subscription required.
|
|
173
|
-
|
|
174
|
-
Parameters:
|
|
175
|
-
- recipeId (required): ID of the recipe to delete
|
|
176
|
-
|
|
172
|
+
server.tool("delete_recipe", `Delete a recipe - Plus subscription required.
|
|
173
|
+
|
|
174
|
+
Parameters:
|
|
175
|
+
- recipeId (required): ID of the recipe to delete
|
|
176
|
+
|
|
177
177
|
Note: This permanently removes the recipe.`, {
|
|
178
178
|
recipeId: z.string().describe("ID of the recipe to delete"),
|
|
179
179
|
}, async ({ recipeId }) => {
|
|
@@ -191,15 +191,15 @@ Note: This permanently removes the recipe.`, {
|
|
|
191
191
|
}
|
|
192
192
|
});
|
|
193
193
|
// add_recipe_to_grocery_list tool
|
|
194
|
-
server.tool("add_recipe_to_grocery_list", `Add a recipe's ingredients to the grocery list - Plus subscription required.
|
|
195
|
-
|
|
196
|
-
Use this when:
|
|
197
|
-
- Planning to make a recipe and need to buy ingredients
|
|
198
|
-
- Adding meal ingredients to shopping list
|
|
199
|
-
|
|
200
|
-
Parameters:
|
|
201
|
-
- recipeId (required): ID of the recipe
|
|
202
|
-
|
|
194
|
+
server.tool("add_recipe_to_grocery_list", `Add a recipe's ingredients to the grocery list - Plus subscription required.
|
|
195
|
+
|
|
196
|
+
Use this when:
|
|
197
|
+
- Planning to make a recipe and need to buy ingredients
|
|
198
|
+
- Adding meal ingredients to shopping list
|
|
199
|
+
|
|
200
|
+
Parameters:
|
|
201
|
+
- recipeId (required): ID of the recipe
|
|
202
|
+
|
|
203
203
|
Returns: Confirmation that ingredients were added.`, {
|
|
204
204
|
recipeId: z.string().describe("ID of the recipe"),
|
|
205
205
|
}, async ({ recipeId }) => {
|
|
@@ -222,16 +222,16 @@ Returns: Confirmation that ingredients were added.`, {
|
|
|
222
222
|
}
|
|
223
223
|
});
|
|
224
224
|
// get_meal_sittings tool
|
|
225
|
-
server.tool("get_meal_sittings", `Get scheduled meals for a date range - Plus subscription required.
|
|
226
|
-
|
|
227
|
-
Use this when:
|
|
228
|
-
- Viewing the meal plan for the week
|
|
229
|
-
- Checking what's scheduled for dinner
|
|
230
|
-
|
|
231
|
-
Parameters:
|
|
232
|
-
- date: Start date (defaults to today)
|
|
233
|
-
- dateEnd: End date (defaults to 7 days from start)
|
|
234
|
-
|
|
225
|
+
server.tool("get_meal_sittings", `Get scheduled meals for a date range - Plus subscription required.
|
|
226
|
+
|
|
227
|
+
Use this when:
|
|
228
|
+
- Viewing the meal plan for the week
|
|
229
|
+
- Checking what's scheduled for dinner
|
|
230
|
+
|
|
231
|
+
Parameters:
|
|
232
|
+
- date: Start date (defaults to today)
|
|
233
|
+
- dateEnd: End date (defaults to 7 days from start)
|
|
234
|
+
|
|
235
235
|
Returns: List of scheduled meals.`, {
|
|
236
236
|
date: z.string().optional().describe("Start date (YYYY-MM-DD or 'today')"),
|
|
237
237
|
dateEnd: z.string().optional().describe("End date (YYYY-MM-DD)"),
|
|
@@ -291,20 +291,20 @@ Returns: List of scheduled meals.`, {
|
|
|
291
291
|
}
|
|
292
292
|
});
|
|
293
293
|
// create_meal_sitting tool
|
|
294
|
-
server.tool("create_meal_sitting", `Schedule a meal for a specific date - Plus subscription required.
|
|
295
|
-
|
|
296
|
-
Use this when:
|
|
297
|
-
- Planning meals for the week
|
|
298
|
-
- Scheduling a recipe for dinner
|
|
299
|
-
|
|
300
|
-
Parameters:
|
|
301
|
-
- date (required): Date for the meal (YYYY-MM-DD)
|
|
302
|
-
- mealCategoryId (required): Meal category ID (use get_meal_categories to find "Dinner" etc.)
|
|
303
|
-
- summary: What the meal is, as free text, e.g. "Thai green curry". No recipe needed.
|
|
304
|
-
- recipeId: A saved recipe to link instead of, or as well as, a summary.
|
|
305
|
-
|
|
306
|
-
Give at least one of summary or recipeId.
|
|
307
|
-
|
|
294
|
+
server.tool("create_meal_sitting", `Schedule a meal for a specific date - Plus subscription required.
|
|
295
|
+
|
|
296
|
+
Use this when:
|
|
297
|
+
- Planning meals for the week
|
|
298
|
+
- Scheduling a recipe for dinner
|
|
299
|
+
|
|
300
|
+
Parameters:
|
|
301
|
+
- date (required): Date for the meal (YYYY-MM-DD)
|
|
302
|
+
- mealCategoryId (required): Meal category ID (use get_meal_categories to find "Dinner" etc.)
|
|
303
|
+
- summary: What the meal is, as free text, e.g. "Thai green curry". No recipe needed.
|
|
304
|
+
- recipeId: A saved recipe to link instead of, or as well as, a summary.
|
|
305
|
+
|
|
306
|
+
Give at least one of summary or recipeId.
|
|
307
|
+
|
|
308
308
|
Returns: The created meal sitting.`, {
|
|
309
309
|
date: z.string().describe("Date for the meal (YYYY-MM-DD or 'today', 'tomorrow')"),
|
|
310
310
|
mealCategoryId: z.string().describe("Meal category ID (e.g., ID for 'Dinner')"),
|
|
@@ -344,23 +344,23 @@ Returns: The created meal sitting.`, {
|
|
|
344
344
|
}
|
|
345
345
|
});
|
|
346
346
|
// update_meal_sitting tool
|
|
347
|
-
server.tool("update_meal_sitting", `Edit or move a scheduled meal - Plus subscription required.
|
|
348
|
-
|
|
349
|
-
Use this when:
|
|
350
|
-
- Renaming a planned meal, or changing its note or category
|
|
351
|
-
- Moving a meal to another day
|
|
352
|
-
|
|
353
|
-
Parameters:
|
|
354
|
-
- sittingId (required): from get_meal_sittings
|
|
355
|
-
- date (required): the meal's CURRENT date (YYYY-MM-DD), also from get_meal_sittings
|
|
356
|
-
- newDate: move the meal to this date
|
|
357
|
-
- summary: new meal name
|
|
358
|
-
- note: new note
|
|
359
|
-
- mealCategoryId: move to another meal category (use get_meal_categories)
|
|
360
|
-
|
|
361
|
-
Give at least one change. Only one-off meals can be edited here; repeating meals
|
|
362
|
-
must be edited in the Skylight app.
|
|
363
|
-
|
|
347
|
+
server.tool("update_meal_sitting", `Edit or move a scheduled meal - Plus subscription required.
|
|
348
|
+
|
|
349
|
+
Use this when:
|
|
350
|
+
- Renaming a planned meal, or changing its note or category
|
|
351
|
+
- Moving a meal to another day
|
|
352
|
+
|
|
353
|
+
Parameters:
|
|
354
|
+
- sittingId (required): from get_meal_sittings
|
|
355
|
+
- date (required): the meal's CURRENT date (YYYY-MM-DD), also from get_meal_sittings
|
|
356
|
+
- newDate: move the meal to this date
|
|
357
|
+
- summary: new meal name
|
|
358
|
+
- note: new note
|
|
359
|
+
- mealCategoryId: move to another meal category (use get_meal_categories)
|
|
360
|
+
|
|
361
|
+
Give at least one change. Only one-off meals can be edited here; repeating meals
|
|
362
|
+
must be edited in the Skylight app.
|
|
363
|
+
|
|
364
364
|
Returns: What changed.`, {
|
|
365
365
|
sittingId: z.string().describe("Sitting ID from get_meal_sittings"),
|
|
366
366
|
date: z.string().describe("The meal's current date (YYYY-MM-DD)"),
|
|
@@ -424,18 +424,18 @@ Returns: What changed.`, {
|
|
|
424
424
|
}
|
|
425
425
|
});
|
|
426
426
|
// delete_meal_sitting tool
|
|
427
|
-
server.tool("delete_meal_sitting", `Delete a scheduled meal - Plus subscription required. THIS CANNOT BE UNDONE.
|
|
428
|
-
|
|
429
|
-
Use this when:
|
|
430
|
-
- Removing a meal that was planned by mistake or is no longer happening
|
|
431
|
-
|
|
432
|
-
Parameters:
|
|
433
|
-
- sittingId (required): from get_meal_sittings
|
|
434
|
-
- date (required): the meal's date (YYYY-MM-DD)
|
|
435
|
-
- confirm: must be true to delete. Without it nothing is deleted and the meal that would be removed is shown.
|
|
436
|
-
|
|
437
|
-
Only one-off meals can be deleted here; repeating meals must be handled in the Skylight app.
|
|
438
|
-
|
|
427
|
+
server.tool("delete_meal_sitting", `Delete a scheduled meal - Plus subscription required. THIS CANNOT BE UNDONE.
|
|
428
|
+
|
|
429
|
+
Use this when:
|
|
430
|
+
- Removing a meal that was planned by mistake or is no longer happening
|
|
431
|
+
|
|
432
|
+
Parameters:
|
|
433
|
+
- sittingId (required): from get_meal_sittings
|
|
434
|
+
- date (required): the meal's date (YYYY-MM-DD)
|
|
435
|
+
- confirm: must be true to delete. Without it nothing is deleted and the meal that would be removed is shown.
|
|
436
|
+
|
|
437
|
+
Only one-off meals can be deleted here; repeating meals must be handled in the Skylight app.
|
|
438
|
+
|
|
439
439
|
Returns: Confirmation that Skylight removed the meal.`, {
|
|
440
440
|
sittingId: z.string().describe("Sitting ID from get_meal_sittings"),
|
|
441
441
|
date: z.string().describe("The meal's date (YYYY-MM-DD)"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/tools/messages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASzE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/tools/messages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASzE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8K5D"}
|
package/dist/tools/messages.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { assertNudgeId, createNudge, deleteNudge, findNudge, getNudges, updateNudge } from "../api/endpoints/messages.js";
|
|
3
|
-
import { getCategories,
|
|
3
|
+
import { getCategories, resolveProfile, resolveProfileIds } from "../api/endpoints/categories.js";
|
|
4
4
|
import { getConfig } from "../config.js";
|
|
5
5
|
import { parseDate, getDateOffset } from "../utils/dates.js";
|
|
6
6
|
import { dateInZone, formatDay, formatTime } from "../utils/schedule.js";
|
|
7
7
|
import { formatErrorForMcp } from "../utils/errors.js";
|
|
8
8
|
export function registerMessageTools(server) {
|
|
9
|
-
server.tool("get_messages", `Get messages (Skylight calls them "nudges") shown on the family frame.
|
|
10
|
-
|
|
11
|
-
Use this when:
|
|
12
|
-
- Checking what has already been posted to the frame
|
|
13
|
-
- Avoiding a duplicate before sending a reminder
|
|
14
|
-
|
|
15
|
-
Returns: Messages grouped by day with time, text, recipients and sender.
|
|
9
|
+
server.tool("get_messages", `Get messages (Skylight calls them "nudges") shown on the family frame.
|
|
10
|
+
|
|
11
|
+
Use this when:
|
|
12
|
+
- Checking what has already been posted to the frame
|
|
13
|
+
- Avoiding a duplicate before sending a reminder
|
|
14
|
+
|
|
15
|
+
Returns: Messages grouped by day with time, text, recipients and sender.
|
|
16
16
|
Defaults to the last 7 days through the next 7 days. Max 31 days.`, {
|
|
17
17
|
date: z.string().optional().describe("Start date (YYYY-MM-DD or 'today'). Default: 7 days ago."),
|
|
18
18
|
dateEnd: z.string().optional().describe("End date, inclusive. Default: 7 days ahead."),
|
|
@@ -51,17 +51,17 @@ Defaults to the last 7 days through the next 7 days. Max 31 days.`, {
|
|
|
51
51
|
return { content: [{ type: "text", text: formatErrorForMcp(error) }], isError: true };
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
|
-
server.tool("send_message", `Post a message to the family frame now, on all devices. Shown to everyone unless "to" names profiles.
|
|
55
|
-
|
|
56
|
-
PERMANENT in practice: the Skylight app has no way to delete a message (delete_message
|
|
57
|
-
is experimental), and it appears on the family frame for the whole
|
|
58
|
-
household immediately.
|
|
59
|
-
|
|
60
|
-
Two-step by design. Called without confirm it only previews and posts nothing.
|
|
61
|
-
Show the user the exact text and get a clear yes, then call again with confirm: true.
|
|
62
|
-
Never pass confirm: true on the first call, and never invent message text the user
|
|
63
|
-
did not ask for. Read aloud is OFF by default; enable it only if the user asked.
|
|
64
|
-
|
|
54
|
+
server.tool("send_message", `Post a message to the family frame now, on all devices. Shown to everyone unless "to" names profiles.
|
|
55
|
+
|
|
56
|
+
PERMANENT in practice: the Skylight app has no way to delete a message (delete_message
|
|
57
|
+
is experimental), and it appears on the family frame for the whole
|
|
58
|
+
household immediately.
|
|
59
|
+
|
|
60
|
+
Two-step by design. Called without confirm it only previews and posts nothing.
|
|
61
|
+
Show the user the exact text and get a clear yes, then call again with confirm: true.
|
|
62
|
+
Never pass confirm: true on the first call, and never invent message text the user
|
|
63
|
+
did not ask for. Read aloud is OFF by default; enable it only if the user asked.
|
|
64
|
+
|
|
65
65
|
Check get_messages first to avoid posting a duplicate.`, {
|
|
66
66
|
body: z.string().min(1).max(300).describe("Message text, up to 300 characters."),
|
|
67
67
|
readAloud: z.boolean().optional().describe("Speak the message on the frame when delivered. Default false."),
|
|
@@ -76,14 +76,8 @@ Check get_messages first to avoid posting a duplicate.`, {
|
|
|
76
76
|
const recipients = to && to.length > 0 ? await resolveProfileIds(to) : undefined;
|
|
77
77
|
const audience = recipients ? recipients.labels.join(", ") : "everyone";
|
|
78
78
|
let senderCategoryId;
|
|
79
|
-
if (from)
|
|
80
|
-
|
|
81
|
-
if (!match) {
|
|
82
|
-
const known = (await getCategories()).map((c) => c.attributes.label).filter(Boolean).join(", ");
|
|
83
|
-
throw new Error(`No profile called "${from}". Profiles: ${known}.`);
|
|
84
|
-
}
|
|
85
|
-
senderCategoryId = match.id;
|
|
86
|
-
}
|
|
79
|
+
if (from)
|
|
80
|
+
senderCategoryId = (await resolveProfile(from)).id;
|
|
87
81
|
const who = senderCategoryId ? ` from ${from}` : "";
|
|
88
82
|
if (confirm !== true) {
|
|
89
83
|
return {
|
|
@@ -105,11 +99,11 @@ Check get_messages first to avoid posting a duplicate.`, {
|
|
|
105
99
|
return { content: [{ type: "text", text: formatErrorForMcp(error) }], isError: true };
|
|
106
100
|
}
|
|
107
101
|
});
|
|
108
|
-
server.tool("update_message", `Edit the text (and optionally the sender) of a message already on the frame.
|
|
109
|
-
|
|
110
|
-
Only messages sent to everyone on all devices and not repeating can be edited;
|
|
111
|
-
anything else must be edited in the Skylight app. Delivery time and read-aloud
|
|
112
|
-
setting are kept. The edit is visible on the frame immediately. Get the message
|
|
102
|
+
server.tool("update_message", `Edit the text (and optionally the sender) of a message already on the frame.
|
|
103
|
+
|
|
104
|
+
Only messages sent to everyone on all devices and not repeating can be edited;
|
|
105
|
+
anything else must be edited in the Skylight app. Delivery time and read-aloud
|
|
106
|
+
setting are kept. The edit is visible on the frame immediately. Get the message
|
|
113
107
|
ID from get_messages (looks within 31 days either side of today).`, {
|
|
114
108
|
messageId: z.string().describe("Numeric message ID from get_messages."),
|
|
115
109
|
body: z.string().min(1).max(300).describe("New message text, up to 300 characters."),
|
|
@@ -125,14 +119,8 @@ ID from get_messages (looks within 31 days either side of today).`, {
|
|
|
125
119
|
if (!existing)
|
|
126
120
|
throw new Error(`No message with ID ${id} within 31 days of today.`);
|
|
127
121
|
let senderCategoryId;
|
|
128
|
-
if (from)
|
|
129
|
-
|
|
130
|
-
if (!match) {
|
|
131
|
-
const known = (await getCategories()).map((c) => c.attributes.label).filter(Boolean).join(", ");
|
|
132
|
-
throw new Error(`No profile called "${from}". Profiles: ${known}.`);
|
|
133
|
-
}
|
|
134
|
-
senderCategoryId = match.id;
|
|
135
|
-
}
|
|
122
|
+
if (from)
|
|
123
|
+
senderCategoryId = (await resolveProfile(from)).id;
|
|
136
124
|
await updateNudge({ existing, body: text, senderCategoryId, timeZone: timezone });
|
|
137
125
|
return { content: [{ type: "text", text: `Updated message ${id}: "${text}"` }] };
|
|
138
126
|
}
|
|
@@ -140,15 +128,15 @@ ID from get_messages (looks within 31 days either side of today).`, {
|
|
|
140
128
|
return { content: [{ type: "text", text: formatErrorForMcp(error) }], isError: true };
|
|
141
129
|
}
|
|
142
130
|
});
|
|
143
|
-
server.tool("delete_message", `EXPERIMENTAL: delete a message from the family frame.
|
|
144
|
-
|
|
145
|
-
The Skylight app has no delete button for messages. This calls the delete endpoint
|
|
146
|
-
that other Skylight clients use; it is unverified on this account until tested, so a
|
|
147
|
-
failure is expected to be reported plainly, not retried.
|
|
148
|
-
|
|
149
|
-
Two-step. Without confirm it only previews which message would go. Show the user the
|
|
150
|
-
text and get a clear yes before calling with confirm: true. After deleting it reads the
|
|
151
|
-
message list back and reports whether the message is really gone. Get the ID from
|
|
131
|
+
server.tool("delete_message", `EXPERIMENTAL: delete a message from the family frame.
|
|
132
|
+
|
|
133
|
+
The Skylight app has no delete button for messages. This calls the delete endpoint
|
|
134
|
+
that other Skylight clients use; it is unverified on this account until tested, so a
|
|
135
|
+
failure is expected to be reported plainly, not retried.
|
|
136
|
+
|
|
137
|
+
Two-step. Without confirm it only previews which message would go. Show the user the
|
|
138
|
+
text and get a clear yes before calling with confirm: true. After deleting it reads the
|
|
139
|
+
message list back and reports whether the message is really gone. Get the ID from
|
|
152
140
|
get_messages (looks within 31 days either side of today).`, {
|
|
153
141
|
messageId: z.string().describe("Numeric message ID from get_messages."),
|
|
154
142
|
confirm: z.boolean().optional().describe("Must be true to actually delete. Default false: preview only."),
|