@davidwoods/skylight-mcp 0.0.0-stage → 1.7.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 -0
- package/README.md +583 -2
- package/THIRD_PARTY_NOTICES.md +38 -0
- package/dist/api/auth.d.ts +34 -0
- package/dist/api/auth.d.ts.map +1 -0
- package/dist/api/auth.js +328 -0
- package/dist/api/auth.js.map +1 -0
- package/dist/api/client.d.ts +103 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +324 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/constants.d.ts +4 -0
- package/dist/api/constants.d.ts.map +1 -0
- package/dist/api/constants.js +4 -0
- package/dist/api/constants.js.map +1 -0
- package/dist/api/credential-store.d.ts +38 -0
- package/dist/api/credential-store.d.ts.map +1 -0
- package/dist/api/credential-store.js +273 -0
- package/dist/api/credential-store.js.map +1 -0
- package/dist/api/credential-types.d.ts +15 -0
- package/dist/api/credential-types.d.ts.map +1 -0
- package/dist/api/credential-types.js +11 -0
- package/dist/api/credential-types.js.map +1 -0
- package/dist/api/endpoints/calendar.d.ts +36 -0
- package/dist/api/endpoints/calendar.d.ts.map +1 -0
- package/dist/api/endpoints/calendar.js +74 -0
- package/dist/api/endpoints/calendar.js.map +1 -0
- package/dist/api/endpoints/categories.d.ts +32 -0
- package/dist/api/endpoints/categories.d.ts.map +1 -0
- package/dist/api/endpoints/categories.js +77 -0
- package/dist/api/endpoints/categories.js.map +1 -0
- package/dist/api/endpoints/chores.d.ts +50 -0
- package/dist/api/endpoints/chores.d.ts.map +1 -0
- package/dist/api/endpoints/chores.js +106 -0
- package/dist/api/endpoints/chores.js.map +1 -0
- package/dist/api/endpoints/devices.d.ts +6 -0
- package/dist/api/endpoints/devices.d.ts.map +1 -0
- package/dist/api/endpoints/devices.js +10 -0
- package/dist/api/endpoints/devices.js.map +1 -0
- package/dist/api/endpoints/frames.d.ts +6 -0
- package/dist/api/endpoints/frames.d.ts.map +1 -0
- package/dist/api/endpoints/frames.js +10 -0
- package/dist/api/endpoints/frames.js.map +1 -0
- package/dist/api/endpoints/lists.d.ts +55 -0
- package/dist/api/endpoints/lists.d.ts.map +1 -0
- package/dist/api/endpoints/lists.js +125 -0
- package/dist/api/endpoints/lists.js.map +1 -0
- package/dist/api/endpoints/meals.d.ts +154 -0
- package/dist/api/endpoints/meals.d.ts.map +1 -0
- package/dist/api/endpoints/meals.js +194 -0
- package/dist/api/endpoints/meals.js.map +1 -0
- package/dist/api/endpoints/messages.d.ts +98 -0
- package/dist/api/endpoints/messages.d.ts.map +1 -0
- package/dist/api/endpoints/messages.js +116 -0
- package/dist/api/endpoints/messages.js.map +1 -0
- package/dist/api/endpoints/misc.d.ts +27 -0
- package/dist/api/endpoints/misc.d.ts.map +1 -0
- package/dist/api/endpoints/misc.js +19 -0
- package/dist/api/endpoints/misc.js.map +1 -0
- package/dist/api/endpoints/photos.d.ts +13 -0
- package/dist/api/endpoints/photos.d.ts.map +1 -0
- package/dist/api/endpoints/photos.js +10 -0
- package/dist/api/endpoints/photos.js.map +1 -0
- package/dist/api/endpoints/rewards.d.ts +49 -0
- package/dist/api/endpoints/rewards.d.ts.map +1 -0
- package/dist/api/endpoints/rewards.js +106 -0
- package/dist/api/endpoints/rewards.js.map +1 -0
- package/dist/api/endpoints/shape.d.ts +11 -0
- package/dist/api/endpoints/shape.d.ts.map +1 -0
- package/dist/api/endpoints/shape.js +34 -0
- package/dist/api/endpoints/shape.js.map +1 -0
- package/dist/api/endpoints/taskbox.d.ts +13 -0
- package/dist/api/endpoints/taskbox.d.ts.map +1 -0
- package/dist/api/endpoints/taskbox.js +22 -0
- package/dist/api/endpoints/taskbox.js.map +1 -0
- package/dist/api/oauth.d.ts +62 -0
- package/dist/api/oauth.d.ts.map +1 -0
- package/dist/api/oauth.js +206 -0
- package/dist/api/oauth.js.map +1 -0
- package/dist/api/types.d.ts +277 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +5 -0
- package/dist/api/types.js.map +1 -0
- package/dist/cli.d.ts +23 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +105 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +27 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +78 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +17 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +17 -0
- package/dist/context.js.map +1 -0
- package/dist/doctor.d.ts +19 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +109 -0
- package/dist/doctor.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +29 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/calendar.d.ts +3 -0
- package/dist/tools/calendar.d.ts.map +1 -0
- package/dist/tools/calendar.js +298 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/chores.d.ts +3 -0
- package/dist/tools/chores.d.ts.map +1 -0
- package/dist/tools/chores.js +349 -0
- package/dist/tools/chores.js.map +1 -0
- package/dist/tools/family.d.ts +3 -0
- package/dist/tools/family.d.ts.map +1 -0
- package/dist/tools/family.js +182 -0
- package/dist/tools/family.js.map +1 -0
- package/dist/tools/lists.d.ts +3 -0
- package/dist/tools/lists.d.ts.map +1 -0
- package/dist/tools/lists.js +481 -0
- package/dist/tools/lists.js.map +1 -0
- package/dist/tools/meals.d.ts +3 -0
- package/dist/tools/meals.d.ts.map +1 -0
- package/dist/tools/meals.js +491 -0
- package/dist/tools/meals.js.map +1 -0
- package/dist/tools/messages.d.ts +3 -0
- package/dist/tools/messages.d.ts.map +1 -0
- package/dist/tools/messages.js +195 -0
- package/dist/tools/messages.js.map +1 -0
- package/dist/tools/misc.d.ts +3 -0
- package/dist/tools/misc.d.ts.map +1 -0
- package/dist/tools/misc.js +102 -0
- package/dist/tools/misc.js.map +1 -0
- package/dist/tools/photos.d.ts +3 -0
- package/dist/tools/photos.d.ts.map +1 -0
- package/dist/tools/photos.js +42 -0
- package/dist/tools/photos.js.map +1 -0
- package/dist/tools/planning.d.ts +15 -0
- package/dist/tools/planning.d.ts.map +1 -0
- package/dist/tools/planning.js +303 -0
- package/dist/tools/planning.js.map +1 -0
- package/dist/tools/registry.d.ts +39 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +142 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/rewards.d.ts +3 -0
- package/dist/tools/rewards.d.ts.map +1 -0
- package/dist/tools/rewards.js +339 -0
- package/dist/tools/rewards.js.map +1 -0
- package/dist/tools/tasks.d.ts +3 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +68 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/utils/dates.d.ts +26 -0
- package/dist/utils/dates.d.ts.map +1 -0
- package/dist/utils/dates.js +109 -0
- package/dist/utils/dates.js.map +1 -0
- package/dist/utils/errors.d.ts +45 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +102 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/schedule.d.ts +86 -0
- package/dist/utils/schedule.d.ts.map +1 -0
- package/dist/utils/schedule.js +189 -0
- package/dist/utils/schedule.js.map +1 -0
- package/package.json +76 -4
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Planning tools: the ones a proactive assistant (Claude Duet) needs to
|
|
3
|
+
* reason about a family week in one or two calls instead of five.
|
|
4
|
+
*
|
|
5
|
+
* get_week_overview calendar + chores + meals + lists, day by day, compact
|
|
6
|
+
* find_conflicts overlapping timed events
|
|
7
|
+
* find_free_slots gaps of at least N minutes within a daily window
|
|
8
|
+
* plan_week_meals write several meal sittings in one call, with dry run
|
|
9
|
+
*
|
|
10
|
+
* Output deliberately omits emails, calendar ids and UIDs: they are noise for
|
|
11
|
+
* the model and personal data in every transcript.
|
|
12
|
+
*/
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
import { getCalendarEvents } from "../api/endpoints/calendar.js";
|
|
15
|
+
import { getChores } from "../api/endpoints/chores.js";
|
|
16
|
+
import { getListWithItems, getLists } from "../api/endpoints/lists.js";
|
|
17
|
+
import { addRecipeToGroceryList, createMealSitting, getMealCategories, getMealSittings, mealCategoryName, } from "../api/endpoints/meals.js";
|
|
18
|
+
import { getConfig } from "../config.js";
|
|
19
|
+
import { getTodayDate, parseDate } from "../utils/dates.js";
|
|
20
|
+
import { formatErrorForMcp } from "../utils/errors.js";
|
|
21
|
+
import { addDays, eachDay, eventToInterval, findConflicts, findFreeSlots, formatDay, formatRange, groupByDay, } from "../utils/schedule.js";
|
|
22
|
+
const MAX_DAYS = 31;
|
|
23
|
+
const MAX_LIST_ITEMS_SHOWN = 15;
|
|
24
|
+
function text(t, isError = false) {
|
|
25
|
+
return { content: [{ type: "text", text: t }], ...(isError ? { isError: true } : {}) };
|
|
26
|
+
}
|
|
27
|
+
function resolveRange(date, dateEnd, days, timezone) {
|
|
28
|
+
const start = date ? parseDate(date, timezone) : getTodayDate(timezone);
|
|
29
|
+
const end = dateEnd ? parseDate(dateEnd, timezone) : addDays(start, Math.max(1, Math.min(days ?? 7, MAX_DAYS)) - 1);
|
|
30
|
+
if (end < start)
|
|
31
|
+
throw new Error("dateEnd is before date");
|
|
32
|
+
if (eachDay(start, end).length > MAX_DAYS)
|
|
33
|
+
throw new Error(`Range is longer than ${MAX_DAYS} days`);
|
|
34
|
+
return { start, end };
|
|
35
|
+
}
|
|
36
|
+
/** Meals for a range, keyed by "YYYY-MM-DD|Category". Null if the account has no meal planning. */
|
|
37
|
+
async function loadMeals(start, end) {
|
|
38
|
+
try {
|
|
39
|
+
const [categories, sittings] = await Promise.all([getMealCategories(), getMealSittings({ dateMin: start, dateMax: addDays(end, 1) })]);
|
|
40
|
+
const name = new Map(categories.map((c) => [c.id, mealCategoryName(c)]));
|
|
41
|
+
const byKey = new Map();
|
|
42
|
+
for (const s of sittings) {
|
|
43
|
+
const cat = name.get(s.relationships?.meal_category?.data?.id ?? "") ?? "Meal";
|
|
44
|
+
const what = describeSitting(s);
|
|
45
|
+
for (const d of s.attributes.instances ?? (s.attributes.date ? [s.attributes.date] : [])) {
|
|
46
|
+
if (d >= start && d <= end)
|
|
47
|
+
byKey.set(`${d}|${cat}`, what);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return { byKey, categories };
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null; // no Plus, or endpoint unavailable: the overview just omits meals
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function describeSitting(s) {
|
|
57
|
+
const summary = s.attributes.summary?.trim();
|
|
58
|
+
const recipe = s.relationships?.meal_recipe?.data?.id;
|
|
59
|
+
return summary || (recipe ? `recipe ${recipe}` : "(empty)");
|
|
60
|
+
}
|
|
61
|
+
export function registerPlanningTools(server) {
|
|
62
|
+
server.tool("get_week_overview", `One compact view of the family's week: calendar events, chores and tasks (with status and assignee), planned meals, and list summaries, day by day, plus any scheduling conflicts.
|
|
63
|
+
|
|
64
|
+
Use this first when planning anything (dinners, errands, who drives). It replaces separate calls to get_calendar_events, get_chores, get_meal_sittings and get_lists for the same range.
|
|
65
|
+
|
|
66
|
+
Parameters:
|
|
67
|
+
- date: first day (YYYY-MM-DD, 'today', 'monday'...). Default today.
|
|
68
|
+
- days: how many days (1–31). Default 7. Or give dateEnd instead.
|
|
69
|
+
- includeLists: include grocery/to-do list summaries. Default true.`, {
|
|
70
|
+
date: z.string().optional().describe("First day. Default today."),
|
|
71
|
+
dateEnd: z.string().optional().describe("Last day (YYYY-MM-DD). Overrides days."),
|
|
72
|
+
days: z.number().int().min(1).max(MAX_DAYS).optional().describe("Number of days. Default 7."),
|
|
73
|
+
includeLists: z.boolean().optional().describe("Include list summaries. Default true."),
|
|
74
|
+
}, async ({ date, dateEnd, days, includeLists }) => {
|
|
75
|
+
try {
|
|
76
|
+
const config = getConfig();
|
|
77
|
+
const tz = config.timezone;
|
|
78
|
+
const { start, end } = resolveRange(date, dateEnd, days, tz);
|
|
79
|
+
const dayList = eachDay(start, end);
|
|
80
|
+
const [events, choresResult, meals, lists] = await Promise.all([
|
|
81
|
+
getCalendarEvents({ dateMin: start, dateMax: end, timezone: tz }),
|
|
82
|
+
getChores({ after: start, before: end, includeLate: true }),
|
|
83
|
+
loadMeals(start, end),
|
|
84
|
+
includeLists === false ? Promise.resolve(null) : getLists().catch(() => null),
|
|
85
|
+
]);
|
|
86
|
+
const intervals = events.map((e) => eventToInterval(e, tz)).filter((i) => i !== null);
|
|
87
|
+
const byDay = groupByDay(intervals, dayList, tz);
|
|
88
|
+
const assignee = new Map(choresResult.categories.map((c) => [c.id, c.attributes.label ?? "someone"]));
|
|
89
|
+
const choresByDay = new Map(dayList.map((d) => [d, []]));
|
|
90
|
+
const late = [];
|
|
91
|
+
for (const chore of choresResult.chores) {
|
|
92
|
+
const a = chore.attributes;
|
|
93
|
+
const who = assignee.get(chore.relationships?.category?.data?.id ?? "");
|
|
94
|
+
const line = `${a.status === "completed" ? "[x]" : "[ ]"} ${a.summary}${who ? ` (${who})` : ""}${a.start_time ? ` at ${a.start_time}` : ""}${a.reward_points ? `, ${a.reward_points} pts` : ""} [chore ID: ${chore.id}]`;
|
|
95
|
+
if (a.start < start && a.status !== "completed")
|
|
96
|
+
late.push(`${line}, due ${formatDay(a.start)}`);
|
|
97
|
+
else
|
|
98
|
+
choresByDay.get(a.start)?.push(line);
|
|
99
|
+
}
|
|
100
|
+
const out = [`Week overview, ${formatDay(start)} to ${formatDay(end)} (${tz}):`];
|
|
101
|
+
for (const d of dayList) {
|
|
102
|
+
out.push("", `${formatDay(d)}`);
|
|
103
|
+
const evs = byDay.get(d) ?? [];
|
|
104
|
+
for (const i of evs)
|
|
105
|
+
out.push(` ${i.allDay ? "all day" : formatRange(i.start, i.end, tz)}: ${i.summary}`);
|
|
106
|
+
for (const c of choresByDay.get(d) ?? [])
|
|
107
|
+
out.push(` chore ${c}`);
|
|
108
|
+
if (meals) {
|
|
109
|
+
for (const cat of meals.categories) {
|
|
110
|
+
const what = meals.byKey.get(`${d}|${mealCategoryName(cat)}`);
|
|
111
|
+
if (what)
|
|
112
|
+
out.push(` ${mealCategoryName(cat).toLowerCase()}: ${what}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (evs.length === 0 && (choresByDay.get(d) ?? []).length === 0 && !hasMealOn(meals, d))
|
|
116
|
+
out.push(" (nothing scheduled)");
|
|
117
|
+
}
|
|
118
|
+
if (late.length)
|
|
119
|
+
out.push("", "Overdue chores:", ...late.map((l) => ` chore ${l}`));
|
|
120
|
+
const conflicts = findConflicts(intervals);
|
|
121
|
+
out.push("", conflicts.length ? "Conflicts:" : "Conflicts: none");
|
|
122
|
+
for (const c of conflicts) {
|
|
123
|
+
out.push(` ${formatDay(dateOf(c.overlapStart, tz))}: "${c.a.summary}" and "${c.b.summary}" overlap ${formatRange(c.overlapStart, c.overlapEnd, tz)}`);
|
|
124
|
+
}
|
|
125
|
+
if (meals === null)
|
|
126
|
+
out.push("", "Meals: not available on this account (Skylight Plus).");
|
|
127
|
+
if (lists) {
|
|
128
|
+
out.push("", "Lists:");
|
|
129
|
+
for (const list of lists) {
|
|
130
|
+
try {
|
|
131
|
+
const { items } = await getListWithItems(list.id);
|
|
132
|
+
const pending = items.filter((i) => i.attributes.status !== "completed");
|
|
133
|
+
const shown = pending.slice(0, MAX_LIST_ITEMS_SHOWN).map((i) => i.attributes.label).join(", ");
|
|
134
|
+
const more = pending.length > MAX_LIST_ITEMS_SHOWN ? `, +${pending.length - MAX_LIST_ITEMS_SHOWN} more` : "";
|
|
135
|
+
out.push(` ${list.attributes.label} (${list.attributes.kind === "shopping" ? "shopping" : "to-do"}${list.attributes.default_grocery_list ? ", default grocery" : ""}): ${pending.length} pending${pending.length ? `: ${shown}${more}` : ""} [list ID: ${list.id}]`);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
out.push(` ${list.attributes.label}: (could not load items)`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return text(out.join("\n"));
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
return text(formatErrorForMcp(error), true);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
server.tool("find_conflicts", `Find calendar events that overlap in time within a date range. All-day events never count as conflicts.
|
|
149
|
+
|
|
150
|
+
Returns each overlapping pair with the overlap window, or "none".`, {
|
|
151
|
+
date: z.string().optional().describe("First day. Default today."),
|
|
152
|
+
dateEnd: z.string().optional().describe("Last day. Default 7 days."),
|
|
153
|
+
days: z.number().int().min(1).max(MAX_DAYS).optional(),
|
|
154
|
+
}, async ({ date, dateEnd, days }) => {
|
|
155
|
+
try {
|
|
156
|
+
const tz = getConfig().timezone;
|
|
157
|
+
const { start, end } = resolveRange(date, dateEnd, days, tz);
|
|
158
|
+
const events = await getCalendarEvents({ dateMin: start, dateMax: end, timezone: tz });
|
|
159
|
+
const intervals = events.map((e) => eventToInterval(e, tz)).filter((i) => i !== null);
|
|
160
|
+
const conflicts = findConflicts(intervals);
|
|
161
|
+
if (conflicts.length === 0)
|
|
162
|
+
return text(`No conflicts between ${formatDay(start)} and ${formatDay(end)}.`);
|
|
163
|
+
const lines = conflicts.map((c) => `- ${formatDay(dateOf(c.overlapStart, tz))}: "${c.a.summary}" (${formatRange(c.a.start, c.a.end, tz)}) and "${c.b.summary}" (${formatRange(c.b.start, c.b.end, tz)}) overlap ${formatRange(c.overlapStart, c.overlapEnd, tz)} [event IDs: ${c.a.id}, ${c.b.id}]`);
|
|
164
|
+
return text(`Conflicts between ${formatDay(start)} and ${formatDay(end)}:\n\n${lines.join("\n")}`);
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
return text(formatErrorForMcp(error), true);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
server.tool("find_free_slots", `Find free time of at least a given length on each day, between an earliest and latest time, around the calendar's timed events. All-day events are not treated as busy.
|
|
171
|
+
|
|
172
|
+
Use for "when could we do X this week?" questions.`, {
|
|
173
|
+
date: z.string().optional().describe("First day. Default today."),
|
|
174
|
+
dateEnd: z.string().optional().describe("Last day. Default 7 days."),
|
|
175
|
+
days: z.number().int().min(1).max(MAX_DAYS).optional(),
|
|
176
|
+
durationMinutes: z.number().int().min(5).max(24 * 60).optional().describe("Minimum slot length. Default 60."),
|
|
177
|
+
earliest: z.string().regex(/^\d{2}:\d{2}$/).optional().describe("Window start, HH:MM local. Default 08:00."),
|
|
178
|
+
latest: z.string().regex(/^\d{2}:\d{2}$/).optional().describe("Window end, HH:MM local. Default 21:00."),
|
|
179
|
+
}, async ({ date, dateEnd, days, durationMinutes, earliest, latest }) => {
|
|
180
|
+
try {
|
|
181
|
+
const tz = getConfig().timezone;
|
|
182
|
+
const { start, end } = resolveRange(date, dateEnd, days, tz);
|
|
183
|
+
const events = await getCalendarEvents({ dateMin: start, dateMax: end, timezone: tz });
|
|
184
|
+
const intervals = events.map((e) => eventToInterval(e, tz)).filter((i) => i !== null);
|
|
185
|
+
const slots = findFreeSlots(intervals, eachDay(start, end), {
|
|
186
|
+
earliest: earliest ?? "08:00",
|
|
187
|
+
latest: latest ?? "21:00",
|
|
188
|
+
minMinutes: durationMinutes ?? 60,
|
|
189
|
+
timeZone: tz,
|
|
190
|
+
});
|
|
191
|
+
if (slots.length === 0)
|
|
192
|
+
return text(`No free slots of ${durationMinutes ?? 60}+ minutes between ${earliest ?? "08:00"} and ${latest ?? "21:00"} from ${formatDay(start)} to ${formatDay(end)}.`);
|
|
193
|
+
const byDay = new Map();
|
|
194
|
+
for (const s of slots) {
|
|
195
|
+
const list = byDay.get(s.date) ?? [];
|
|
196
|
+
list.push(`${formatRange(s.start, s.end, tz)} (${Math.floor(s.minutes / 60)}h${s.minutes % 60 ? ` ${s.minutes % 60}m` : ""})`);
|
|
197
|
+
byDay.set(s.date, list);
|
|
198
|
+
}
|
|
199
|
+
const lines = [...byDay.entries()].map(([d, l]) => `- ${formatDay(d)}: ${l.join("; ")}`);
|
|
200
|
+
return text(`Free slots of ${durationMinutes ?? 60}+ minutes, ${earliest ?? "08:00"}–${latest ?? "21:00"} (${tz}):\n\n${lines.join("\n")}`);
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
return text(formatErrorForMcp(error), true);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
server.tool("plan_week_meals", `Schedule several meals in one call - Plus subscription required.
|
|
207
|
+
|
|
208
|
+
Each entry names a date, a meal (category name like "Dinner", default Dinner), and either a free-text summary ("Thai green curry") or a saved recipeId. A slot that already has a meal is skipped and reported, never overwritten. Use dryRun first to see what would change.
|
|
209
|
+
|
|
210
|
+
Parameters:
|
|
211
|
+
- meals: list of { date, meal?, summary?, recipeId? }
|
|
212
|
+
- dryRun: report the plan without writing. Default false.
|
|
213
|
+
- addRecipesToGroceryList: for entries with a recipeId, also push that recipe's ingredients to the grocery list. Default false.`, {
|
|
214
|
+
meals: z
|
|
215
|
+
.array(z.object({
|
|
216
|
+
date: z.string().describe("YYYY-MM-DD, 'today', 'tomorrow', or a weekday name"),
|
|
217
|
+
meal: z.string().optional().describe("Category name, e.g. Dinner (default), Lunch, Breakfast, Snack"),
|
|
218
|
+
summary: z.string().max(200).optional().describe("Free-text meal name"),
|
|
219
|
+
recipeId: z.string().optional().describe("Saved recipe ID"),
|
|
220
|
+
}))
|
|
221
|
+
.min(1)
|
|
222
|
+
.max(31),
|
|
223
|
+
dryRun: z.boolean().optional(),
|
|
224
|
+
addRecipesToGroceryList: z.boolean().optional(),
|
|
225
|
+
}, async ({ meals, dryRun, addRecipesToGroceryList }) => {
|
|
226
|
+
try {
|
|
227
|
+
const tz = getConfig().timezone;
|
|
228
|
+
const categories = await getMealCategories();
|
|
229
|
+
const byName = new Map(categories.map((c) => [mealCategoryName(c).toLowerCase(), c]));
|
|
230
|
+
// Resolve and validate everything before writing anything.
|
|
231
|
+
const resolved = [];
|
|
232
|
+
const problems = [];
|
|
233
|
+
for (const m of meals) {
|
|
234
|
+
const date = parseDate(m.date, tz);
|
|
235
|
+
const category = byName.get((m.meal ?? "dinner").toLowerCase());
|
|
236
|
+
if (!category) {
|
|
237
|
+
problems.push(`${m.date}: no meal category called "${m.meal}". Available: ${[...byName.keys()].join(", ")}`);
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
if (!m.summary?.trim() && !m.recipeId) {
|
|
241
|
+
problems.push(`${m.date} ${mealCategoryName(category)}: give a summary or a recipeId`);
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
resolved.push({ date, category, summary: m.summary?.trim() || undefined, recipeId: m.recipeId, label: m.summary?.trim() || `recipe ${m.recipeId}` });
|
|
245
|
+
}
|
|
246
|
+
if (problems.length)
|
|
247
|
+
return text(`Nothing written. Fix these first:\n- ${problems.join("\n- ")}`, true);
|
|
248
|
+
const dates = resolved.map((r) => r.date).sort();
|
|
249
|
+
const existing = await loadMeals(dates[0], dates[dates.length - 1]);
|
|
250
|
+
const taken = existing?.byKey ?? new Map();
|
|
251
|
+
const lines = [];
|
|
252
|
+
let written = 0;
|
|
253
|
+
for (const r of resolved) {
|
|
254
|
+
const key = `${r.date}|${mealCategoryName(r.category)}`;
|
|
255
|
+
const current = taken.get(key);
|
|
256
|
+
if (current) {
|
|
257
|
+
lines.push(`- ${formatDay(r.date)} ${mealCategoryName(r.category)}: skipped, already "${current}"`);
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
if (dryRun) {
|
|
261
|
+
lines.push(`- ${formatDay(r.date)} ${mealCategoryName(r.category)}: would add "${r.label}"`);
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
try {
|
|
265
|
+
const sitting = await createMealSitting({ date: r.date, mealCategoryId: r.category.id, summary: r.summary, recipeId: r.recipeId });
|
|
266
|
+
written++;
|
|
267
|
+
taken.set(key, r.label);
|
|
268
|
+
let extra = "";
|
|
269
|
+
if (addRecipesToGroceryList && r.recipeId) {
|
|
270
|
+
try {
|
|
271
|
+
await addRecipeToGroceryList(r.recipeId);
|
|
272
|
+
extra = ", ingredients added to grocery list";
|
|
273
|
+
}
|
|
274
|
+
catch (e) {
|
|
275
|
+
extra = `, grocery push failed: ${e instanceof Error ? e.message : String(e)}`;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
lines.push(`- ${formatDay(r.date)} ${mealCategoryName(r.category)}: added "${r.label}" [sitting ID: ${sitting.id}]${extra}`);
|
|
279
|
+
}
|
|
280
|
+
catch (e) {
|
|
281
|
+
lines.push(`- ${formatDay(r.date)} ${mealCategoryName(r.category)}: FAILED "${r.label}": ${e instanceof Error ? e.message : String(e)}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
const head = dryRun ? "Dry run, nothing written:" : `Wrote ${written} of ${resolved.length}:`;
|
|
285
|
+
return text(`${head}\n${lines.join("\n")}`);
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
return text(formatErrorForMcp(error), true);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
function hasMealOn(meals, date) {
|
|
293
|
+
if (!meals)
|
|
294
|
+
return false;
|
|
295
|
+
for (const key of meals.byKey.keys())
|
|
296
|
+
if (key.startsWith(`${date}|`))
|
|
297
|
+
return true;
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
function dateOf(epochMs, tz) {
|
|
301
|
+
return new Date(epochMs).toLocaleDateString("en-CA", { timeZone: tz });
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=planning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planning.js","sourceRoot":"","sources":["../../src/tools/planning.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single place that knows every tool and what it does to the family's data.
|
|
3
|
+
*
|
|
4
|
+
* Each tool is classified by effect. The registry turns that into MCP tool
|
|
5
|
+
* annotations (so clients can show read-only vs destructive before calling)
|
|
6
|
+
* and lets a deployment exclude whole classes: the hosted server for Claude
|
|
7
|
+
* Duet, for example, registers no destructive tools.
|
|
8
|
+
*
|
|
9
|
+
* A tool that is not classified here fails registration loudly, so a new tool
|
|
10
|
+
* cannot ship unlabelled.
|
|
11
|
+
*/
|
|
12
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
13
|
+
import type { ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
|
|
14
|
+
/**
|
|
15
|
+
* read: no change to Skylight data.
|
|
16
|
+
* write: creates or updates; reversible by another edit.
|
|
17
|
+
* destructive: deletes or otherwise cannot be undone from the API.
|
|
18
|
+
*/
|
|
19
|
+
export type ToolEffect = "read" | "write" | "destructive";
|
|
20
|
+
export declare const TOOL_EFFECTS: Readonly<Record<string, ToolEffect>>;
|
|
21
|
+
export interface RegisterToolsOptions {
|
|
22
|
+
/** Whether the account has Skylight Plus; gates rewards, meals and photos. */
|
|
23
|
+
hasPlus: boolean;
|
|
24
|
+
/** Effects to register. Default: all. */
|
|
25
|
+
effects?: readonly ToolEffect[];
|
|
26
|
+
/** Individual tools to register even if their effect class is excluded. Least-privilege exceptions. */
|
|
27
|
+
include?: readonly string[];
|
|
28
|
+
/** Register the photo tools (uploads). Default: true when hasPlus. */
|
|
29
|
+
photos?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export declare function annotationsFor(effect: ToolEffect): ToolAnnotations;
|
|
32
|
+
/** Names of the tools that would be registered with these options. */
|
|
33
|
+
export declare function selectedTools(options: RegisterToolsOptions): string[];
|
|
34
|
+
/**
|
|
35
|
+
* Register the Skylight tools on `server`, filtered by effect, with MCP
|
|
36
|
+
* annotations derived from the classification above.
|
|
37
|
+
*/
|
|
38
|
+
export declare function registerTools(server: McpServer, options: RegisterToolsOptions): string[];
|
|
39
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAa1E;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;AAE1D,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CA6D7D,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,8EAA8E;IAC9E,OAAO,EAAE,OAAO,CAAC;IACjB,yCAAyC;IACzC,OAAO,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAChC,uGAAuG;IACvG,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,eAAe,CAOlE;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAMrE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAuCxF"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single place that knows every tool and what it does to the family's data.
|
|
3
|
+
*
|
|
4
|
+
* Each tool is classified by effect. The registry turns that into MCP tool
|
|
5
|
+
* annotations (so clients can show read-only vs destructive before calling)
|
|
6
|
+
* and lets a deployment exclude whole classes: the hosted server for Claude
|
|
7
|
+
* Duet, for example, registers no destructive tools.
|
|
8
|
+
*
|
|
9
|
+
* A tool that is not classified here fails registration loudly, so a new tool
|
|
10
|
+
* cannot ship unlabelled.
|
|
11
|
+
*/
|
|
12
|
+
import { registerCalendarTools } from "./calendar.js";
|
|
13
|
+
import { registerChoreTools } from "./chores.js";
|
|
14
|
+
import { registerFamilyTools } from "./family.js";
|
|
15
|
+
import { registerListTools } from "./lists.js";
|
|
16
|
+
import { registerMealTools } from "./meals.js";
|
|
17
|
+
import { registerMessageTools } from "./messages.js";
|
|
18
|
+
import { registerMiscTools } from "./misc.js";
|
|
19
|
+
import { registerPhotoTools } from "./photos.js";
|
|
20
|
+
import { registerPlanningTools } from "./planning.js";
|
|
21
|
+
import { registerRewardTools } from "./rewards.js";
|
|
22
|
+
import { registerTaskTools } from "./tasks.js";
|
|
23
|
+
export const TOOL_EFFECTS = {
|
|
24
|
+
// calendar
|
|
25
|
+
get_calendar_events: "read",
|
|
26
|
+
get_source_calendars: "read",
|
|
27
|
+
create_calendar_event: "write",
|
|
28
|
+
update_calendar_event: "write",
|
|
29
|
+
delete_calendar_event: "destructive",
|
|
30
|
+
// chores
|
|
31
|
+
get_chores: "read",
|
|
32
|
+
create_chore: "write",
|
|
33
|
+
update_chore: "write",
|
|
34
|
+
delete_chore: "destructive",
|
|
35
|
+
// lists
|
|
36
|
+
get_lists: "read",
|
|
37
|
+
get_list_items: "read",
|
|
38
|
+
create_list: "write",
|
|
39
|
+
update_list: "write",
|
|
40
|
+
create_list_item: "write",
|
|
41
|
+
update_list_item: "write",
|
|
42
|
+
delete_list: "destructive",
|
|
43
|
+
delete_list_item: "destructive",
|
|
44
|
+
// tasks
|
|
45
|
+
create_task: "write",
|
|
46
|
+
// family / misc
|
|
47
|
+
get_family_members: "read",
|
|
48
|
+
get_avatars: "read",
|
|
49
|
+
get_colors: "read",
|
|
50
|
+
get_frame_info: "read",
|
|
51
|
+
get_devices: "read",
|
|
52
|
+
// rewards (Plus)
|
|
53
|
+
get_rewards: "read",
|
|
54
|
+
get_reward_points: "read",
|
|
55
|
+
create_reward: "write",
|
|
56
|
+
update_reward: "write",
|
|
57
|
+
redeem_reward: "write",
|
|
58
|
+
unredeem_reward: "write",
|
|
59
|
+
delete_reward: "destructive",
|
|
60
|
+
// meals (Plus)
|
|
61
|
+
get_meal_categories: "read",
|
|
62
|
+
get_meal_sittings: "read",
|
|
63
|
+
get_recipes: "read",
|
|
64
|
+
get_recipe: "read",
|
|
65
|
+
create_meal_sitting: "write",
|
|
66
|
+
update_meal_sitting: "write",
|
|
67
|
+
delete_meal_sitting: "destructive",
|
|
68
|
+
create_recipe: "write",
|
|
69
|
+
update_recipe: "write",
|
|
70
|
+
add_recipe_to_grocery_list: "write",
|
|
71
|
+
delete_recipe: "destructive",
|
|
72
|
+
// photos (Plus)
|
|
73
|
+
get_albums: "read",
|
|
74
|
+
// planning (composite)
|
|
75
|
+
get_week_overview: "read",
|
|
76
|
+
find_conflicts: "read",
|
|
77
|
+
find_free_slots: "read",
|
|
78
|
+
plan_week_meals: "write",
|
|
79
|
+
// messages (frame "nudges")
|
|
80
|
+
get_messages: "read",
|
|
81
|
+
send_message: "write",
|
|
82
|
+
update_message: "write",
|
|
83
|
+
delete_message: "destructive",
|
|
84
|
+
};
|
|
85
|
+
export function annotationsFor(effect) {
|
|
86
|
+
return {
|
|
87
|
+
readOnlyHint: effect === "read",
|
|
88
|
+
destructiveHint: effect === "destructive",
|
|
89
|
+
idempotentHint: effect !== "write",
|
|
90
|
+
openWorldHint: false,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/** Names of the tools that would be registered with these options. */
|
|
94
|
+
export function selectedTools(options) {
|
|
95
|
+
const effects = new Set(options.effects ?? ["read", "write", "destructive"]);
|
|
96
|
+
const include = new Set(options.include ?? []);
|
|
97
|
+
return Object.entries(TOOL_EFFECTS)
|
|
98
|
+
.filter(([name, effect]) => effects.has(effect) || include.has(name))
|
|
99
|
+
.map(([name]) => name);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Register the Skylight tools on `server`, filtered by effect, with MCP
|
|
103
|
+
* annotations derived from the classification above.
|
|
104
|
+
*/
|
|
105
|
+
export function registerTools(server, options) {
|
|
106
|
+
const allowed = new Set(selectedTools(options));
|
|
107
|
+
const registered = [];
|
|
108
|
+
// Intercept server.tool() so the per-domain register functions stay as they
|
|
109
|
+
// are: the registry decides what gets through and attaches annotations.
|
|
110
|
+
const filtered = Object.create(server);
|
|
111
|
+
filtered.tool = ((name, ...rest) => {
|
|
112
|
+
const effect = TOOL_EFFECTS[name];
|
|
113
|
+
if (!effect) {
|
|
114
|
+
throw new Error(`Tool "${name}" is not classified in TOOL_EFFECTS; add it with its effect.`);
|
|
115
|
+
}
|
|
116
|
+
if (!allowed.has(name)) {
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
registered.push(name);
|
|
120
|
+
const callback = rest.pop();
|
|
121
|
+
// Insert annotations before the callback: tool(name, description?, schema?, annotations, cb)
|
|
122
|
+
return server.tool(name, ...rest, annotationsFor(effect), callback);
|
|
123
|
+
});
|
|
124
|
+
registerCalendarTools(filtered);
|
|
125
|
+
registerChoreTools(filtered);
|
|
126
|
+
registerListTools(filtered);
|
|
127
|
+
registerTaskTools(filtered);
|
|
128
|
+
registerFamilyTools(filtered);
|
|
129
|
+
registerMiscTools(filtered);
|
|
130
|
+
registerMessageTools(filtered);
|
|
131
|
+
// Planning tools degrade gracefully without Plus (meals are simply omitted),
|
|
132
|
+
// except plan_week_meals, which needs the meals API.
|
|
133
|
+
registerPlanningTools(filtered);
|
|
134
|
+
if (options.hasPlus) {
|
|
135
|
+
registerRewardTools(filtered);
|
|
136
|
+
registerMealTools(filtered);
|
|
137
|
+
if (options.photos ?? true)
|
|
138
|
+
registerPhotoTools(filtered);
|
|
139
|
+
}
|
|
140
|
+
return registered;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rewards.d.ts","sourceRoot":"","sources":["../../src/tools/rewards.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAczE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyX3D"}
|