@bmhall2/skylight-mcp 1.1.7
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 +21 -0
- package/README.md +265 -0
- package/dist/api/auth.d.ts +38 -0
- package/dist/api/auth.d.ts.map +1 -0
- package/dist/api/auth.js +62 -0
- package/dist/api/auth.js.map +1 -0
- package/dist/api/client.d.ts +84 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +228 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/endpoints/calendar.d.ts +33 -0
- package/dist/api/endpoints/calendar.d.ts.map +1 -0
- package/dist/api/endpoints/calendar.js +60 -0
- package/dist/api/endpoints/calendar.js.map +1 -0
- package/dist/api/endpoints/categories.d.ts +23 -0
- package/dist/api/endpoints/categories.d.ts.map +1 -0
- package/dist/api/endpoints/categories.js +48 -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 +102 -0
- package/dist/api/endpoints/meals.d.ts.map +1 -0
- package/dist/api/endpoints/meals.js +100 -0
- package/dist/api/endpoints/meals.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 +18 -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 +105 -0
- package/dist/api/endpoints/rewards.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/generated-types.d.ts +18967 -0
- package/dist/api/generated-types.d.ts.map +1 -0
- package/dist/api/generated-types.js +6 -0
- package/dist/api/generated-types.js.map +1 -0
- package/dist/api/types.d.ts +283 -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/config.d.ts +52 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +80 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -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 +48 -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 +297 -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 +319 -0
- package/dist/tools/meals.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 +101 -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/rewards.d.ts +3 -0
- package/dist/tools/rewards.d.ts.map +1 -0
- package/dist/tools/rewards.js +338 -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/package.json +59 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getRewards, getRewardPoints, createReward, updateReward, deleteReward, redeemReward, unredeemReward, } from "../api/endpoints/rewards.js";
|
|
3
|
+
import { findCategoryByName } from "../api/endpoints/categories.js";
|
|
4
|
+
import { formatErrorForMcp } from "../utils/errors.js";
|
|
5
|
+
export function registerRewardTools(server) {
|
|
6
|
+
// get_rewards tool
|
|
7
|
+
server.tool("get_rewards", `Get available rewards that can be redeemed with reward points.
|
|
8
|
+
|
|
9
|
+
For family gamification - shows rewards that family members can earn.
|
|
10
|
+
|
|
11
|
+
Use this to answer:
|
|
12
|
+
- "What rewards can we redeem?"
|
|
13
|
+
- "What can the kids earn?"
|
|
14
|
+
- "Show available rewards"`, {
|
|
15
|
+
redeemedSince: z
|
|
16
|
+
.string()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe("Filter to rewards redeemed after this date (ISO datetime)"),
|
|
19
|
+
}, async ({ redeemedSince }) => {
|
|
20
|
+
try {
|
|
21
|
+
const rewards = await getRewards({
|
|
22
|
+
redeemedAtMin: redeemedSince,
|
|
23
|
+
});
|
|
24
|
+
if (rewards.length === 0) {
|
|
25
|
+
return {
|
|
26
|
+
content: [
|
|
27
|
+
{
|
|
28
|
+
type: "text",
|
|
29
|
+
text: "No rewards found.",
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const rewardList = rewards
|
|
35
|
+
.map((reward) => {
|
|
36
|
+
const parts = [`- Reward (ID: ${reward.id})`];
|
|
37
|
+
const attrs = reward.attributes;
|
|
38
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
39
|
+
if (value !== null && value !== undefined) {
|
|
40
|
+
parts.push(` ${key}: ${value}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return parts.join("\n");
|
|
44
|
+
})
|
|
45
|
+
.join("\n\n");
|
|
46
|
+
return {
|
|
47
|
+
content: [
|
|
48
|
+
{
|
|
49
|
+
type: "text",
|
|
50
|
+
text: `Available rewards:\n\n${rewardList}`,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
return {
|
|
57
|
+
content: [
|
|
58
|
+
{
|
|
59
|
+
type: "text",
|
|
60
|
+
text: formatErrorForMcp(error),
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
isError: true,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
// get_reward_points tool
|
|
68
|
+
server.tool("get_reward_points", `Get reward points balance for family members.
|
|
69
|
+
|
|
70
|
+
Shows how many reward points each family member has earned.
|
|
71
|
+
|
|
72
|
+
Use this to answer:
|
|
73
|
+
- "How many points does [name] have?"
|
|
74
|
+
- "Show reward points balance"
|
|
75
|
+
- "Who has the most points?"`, {}, async () => {
|
|
76
|
+
try {
|
|
77
|
+
const points = await getRewardPoints();
|
|
78
|
+
if (points.length === 0) {
|
|
79
|
+
return {
|
|
80
|
+
content: [
|
|
81
|
+
{
|
|
82
|
+
type: "text",
|
|
83
|
+
text: "No reward points found.",
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const pointsList = points
|
|
89
|
+
.map((point) => {
|
|
90
|
+
const parts = [`- Points (ID: ${point.id})`];
|
|
91
|
+
const attrs = point.attributes;
|
|
92
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
93
|
+
if (value !== null && value !== undefined) {
|
|
94
|
+
parts.push(` ${key}: ${value}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return parts.join("\n");
|
|
98
|
+
})
|
|
99
|
+
.join("\n\n");
|
|
100
|
+
return {
|
|
101
|
+
content: [
|
|
102
|
+
{
|
|
103
|
+
type: "text",
|
|
104
|
+
text: `Reward points:\n\n${pointsList}`,
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
return {
|
|
111
|
+
content: [
|
|
112
|
+
{
|
|
113
|
+
type: "text",
|
|
114
|
+
text: formatErrorForMcp(error),
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
isError: true,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
// create_reward tool
|
|
122
|
+
server.tool("create_reward", `Create a new reward that can be redeemed with points (Plus subscription required).
|
|
123
|
+
|
|
124
|
+
Use this when:
|
|
125
|
+
- Adding a new reward: "Create a reward for 30 minutes of screen time"
|
|
126
|
+
- Setting up family incentives: "Add a pizza night reward worth 100 points"
|
|
127
|
+
|
|
128
|
+
Parameters:
|
|
129
|
+
- name (required): Reward name (e.g., "30 min Screen Time")
|
|
130
|
+
- pointValue (required): Points needed to redeem this reward
|
|
131
|
+
- description: Additional details about the reward
|
|
132
|
+
- emojiIcon: Emoji to display with the reward
|
|
133
|
+
- assignee: Family member name to assign this reward to
|
|
134
|
+
- respawnOnRedemption: If true, reward can be redeemed multiple times
|
|
135
|
+
|
|
136
|
+
Returns: The created reward details.`, {
|
|
137
|
+
name: z.string().describe("Reward name (e.g., '30 min Screen Time')"),
|
|
138
|
+
pointValue: z.number().describe("Points needed to redeem this reward"),
|
|
139
|
+
description: z.string().optional().describe("Additional details about the reward"),
|
|
140
|
+
emojiIcon: z.string().optional().describe("Emoji for the reward (e.g., '🎮')"),
|
|
141
|
+
assignee: z.string().optional().describe("Family member to assign this reward to"),
|
|
142
|
+
respawnOnRedemption: z.boolean().optional().default(false).describe("Can be redeemed multiple times"),
|
|
143
|
+
}, async ({ name, pointValue, description, emojiIcon, assignee, respawnOnRedemption }) => {
|
|
144
|
+
try {
|
|
145
|
+
let categoryIds;
|
|
146
|
+
if (assignee) {
|
|
147
|
+
const category = await findCategoryByName(assignee);
|
|
148
|
+
if (!category) {
|
|
149
|
+
return {
|
|
150
|
+
content: [{ type: "text", text: `Could not find family member "${assignee}"` }],
|
|
151
|
+
isError: true,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
categoryIds = [category.id];
|
|
155
|
+
}
|
|
156
|
+
const reward = await createReward({
|
|
157
|
+
name,
|
|
158
|
+
pointValue,
|
|
159
|
+
description,
|
|
160
|
+
emojiIcon,
|
|
161
|
+
categoryIds,
|
|
162
|
+
respawnOnRedemption,
|
|
163
|
+
});
|
|
164
|
+
return {
|
|
165
|
+
content: [
|
|
166
|
+
{
|
|
167
|
+
type: "text",
|
|
168
|
+
text: `Created reward "${name}" worth ${pointValue} points (ID: ${reward.id})`,
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
return {
|
|
175
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
176
|
+
isError: true,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
// update_reward tool
|
|
181
|
+
server.tool("update_reward", `Update an existing reward (Plus subscription required).
|
|
182
|
+
|
|
183
|
+
Use this when:
|
|
184
|
+
- Changing point value: "Make the screen time reward cost 50 points"
|
|
185
|
+
- Updating reward details: "Add a description to the pizza reward"
|
|
186
|
+
|
|
187
|
+
Parameters:
|
|
188
|
+
- rewardId (required): ID of the reward (from get_rewards)
|
|
189
|
+
- name: New reward name
|
|
190
|
+
- pointValue: New point cost
|
|
191
|
+
- description: Updated description
|
|
192
|
+
- emojiIcon: Updated emoji
|
|
193
|
+
|
|
194
|
+
Returns: The updated reward details.`, {
|
|
195
|
+
rewardId: z.string().describe("ID of the reward to update"),
|
|
196
|
+
name: z.string().optional().describe("New reward name"),
|
|
197
|
+
pointValue: z.number().optional().describe("New point cost"),
|
|
198
|
+
description: z.string().nullable().optional().describe("Updated description (null to clear)"),
|
|
199
|
+
emojiIcon: z.string().nullable().optional().describe("Updated emoji (null to clear)"),
|
|
200
|
+
respawnOnRedemption: z.boolean().optional().describe("Can be redeemed multiple times"),
|
|
201
|
+
}, async ({ rewardId, name, pointValue, description, emojiIcon, respawnOnRedemption }) => {
|
|
202
|
+
try {
|
|
203
|
+
const updates = {};
|
|
204
|
+
if (name !== undefined)
|
|
205
|
+
updates.name = name;
|
|
206
|
+
if (pointValue !== undefined)
|
|
207
|
+
updates.pointValue = pointValue;
|
|
208
|
+
if (description !== undefined)
|
|
209
|
+
updates.description = description;
|
|
210
|
+
if (emojiIcon !== undefined)
|
|
211
|
+
updates.emojiIcon = emojiIcon;
|
|
212
|
+
if (respawnOnRedemption !== undefined)
|
|
213
|
+
updates.respawnOnRedemption = respawnOnRedemption;
|
|
214
|
+
const reward = await updateReward(rewardId, updates);
|
|
215
|
+
return {
|
|
216
|
+
content: [
|
|
217
|
+
{
|
|
218
|
+
type: "text",
|
|
219
|
+
text: `Updated reward (ID: ${reward.id})`,
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
return {
|
|
226
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
227
|
+
isError: true,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
// delete_reward tool
|
|
232
|
+
server.tool("delete_reward", `Delete a reward (Plus subscription required).
|
|
233
|
+
|
|
234
|
+
Use this when:
|
|
235
|
+
- Removing an old reward
|
|
236
|
+
- Cleaning up unused rewards
|
|
237
|
+
|
|
238
|
+
Parameters:
|
|
239
|
+
- rewardId (required): ID of the reward to delete (from get_rewards)
|
|
240
|
+
|
|
241
|
+
Note: This permanently removes the reward.`, {
|
|
242
|
+
rewardId: z.string().describe("ID of the reward to delete"),
|
|
243
|
+
}, async ({ rewardId }) => {
|
|
244
|
+
try {
|
|
245
|
+
await deleteReward(rewardId);
|
|
246
|
+
return {
|
|
247
|
+
content: [
|
|
248
|
+
{
|
|
249
|
+
type: "text",
|
|
250
|
+
text: `Deleted reward (ID: ${rewardId})`,
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
return {
|
|
257
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
258
|
+
isError: true,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
// redeem_reward tool
|
|
263
|
+
server.tool("redeem_reward", `Redeem a reward using points (Plus subscription required).
|
|
264
|
+
|
|
265
|
+
Use this when:
|
|
266
|
+
- A family member wants to cash in points: "Redeem the screen time reward for Johnny"
|
|
267
|
+
- Claiming an earned reward
|
|
268
|
+
|
|
269
|
+
Parameters:
|
|
270
|
+
- rewardId (required): ID of the reward to redeem (from get_rewards)
|
|
271
|
+
- assignee: Family member redeeming the reward (uses their points)
|
|
272
|
+
|
|
273
|
+
Returns: The redeemed reward details.`, {
|
|
274
|
+
rewardId: z.string().describe("ID of the reward to redeem"),
|
|
275
|
+
assignee: z.string().optional().describe("Family member redeeming the reward"),
|
|
276
|
+
}, async ({ rewardId, assignee }) => {
|
|
277
|
+
try {
|
|
278
|
+
let categoryId;
|
|
279
|
+
if (assignee) {
|
|
280
|
+
const category = await findCategoryByName(assignee);
|
|
281
|
+
if (!category) {
|
|
282
|
+
return {
|
|
283
|
+
content: [{ type: "text", text: `Could not find family member "${assignee}"` }],
|
|
284
|
+
isError: true,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
categoryId = category.id;
|
|
288
|
+
}
|
|
289
|
+
const reward = await redeemReward(rewardId, categoryId);
|
|
290
|
+
return {
|
|
291
|
+
content: [
|
|
292
|
+
{
|
|
293
|
+
type: "text",
|
|
294
|
+
text: `Redeemed reward (ID: ${reward.id})${assignee ? ` for ${assignee}` : ""}`,
|
|
295
|
+
},
|
|
296
|
+
],
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
return {
|
|
301
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
302
|
+
isError: true,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
// unredeem_reward tool
|
|
307
|
+
server.tool("unredeem_reward", `Cancel a reward redemption (Plus subscription required).
|
|
308
|
+
|
|
309
|
+
Use this when:
|
|
310
|
+
- A redemption was made by mistake
|
|
311
|
+
- Undoing a reward claim
|
|
312
|
+
|
|
313
|
+
Parameters:
|
|
314
|
+
- rewardId (required): ID of the reward to unredeem
|
|
315
|
+
|
|
316
|
+
Returns: The unredeemed reward details.`, {
|
|
317
|
+
rewardId: z.string().describe("ID of the reward to unredeem"),
|
|
318
|
+
}, async ({ rewardId }) => {
|
|
319
|
+
try {
|
|
320
|
+
const reward = await unredeemReward(rewardId);
|
|
321
|
+
return {
|
|
322
|
+
content: [
|
|
323
|
+
{
|
|
324
|
+
type: "text",
|
|
325
|
+
text: `Unredeemed reward (ID: ${reward.id})`,
|
|
326
|
+
},
|
|
327
|
+
],
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
return {
|
|
332
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
333
|
+
isError: true,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
//# sourceMappingURL=rewards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rewards.js","sourceRoot":"","sources":["../../src/tools/rewards.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/tools/tasks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwEzD"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { createTaskBoxItem } from "../api/endpoints/taskbox.js";
|
|
3
|
+
import { formatErrorForMcp } from "../utils/errors.js";
|
|
4
|
+
export function registerTaskTools(server) {
|
|
5
|
+
// create_task tool
|
|
6
|
+
server.tool("create_task", `Add a task to the Skylight task box.
|
|
7
|
+
|
|
8
|
+
The task box holds unscheduled tasks that can later be assigned to specific dates.
|
|
9
|
+
|
|
10
|
+
Use this when the user says:
|
|
11
|
+
- "Add XYZ to my task list"
|
|
12
|
+
- "Remind me to do ABC" (without a specific date)
|
|
13
|
+
- "Put 'clean garage' on the task box"
|
|
14
|
+
|
|
15
|
+
The task will appear on the Skylight display in the task box.`, {
|
|
16
|
+
summary: z.string().describe("Task description"),
|
|
17
|
+
emoji: z
|
|
18
|
+
.string()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("Emoji icon for the task (e.g., '🧹', '📞')"),
|
|
21
|
+
rewardPoints: z
|
|
22
|
+
.number()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("Reward points for completing this task (for gamification)"),
|
|
25
|
+
routine: z
|
|
26
|
+
.boolean()
|
|
27
|
+
.optional()
|
|
28
|
+
.default(false)
|
|
29
|
+
.describe("Is this a routine task?"),
|
|
30
|
+
}, async ({ summary, emoji, rewardPoints, routine }) => {
|
|
31
|
+
try {
|
|
32
|
+
const task = await createTaskBoxItem({
|
|
33
|
+
summary,
|
|
34
|
+
emojiIcon: emoji,
|
|
35
|
+
rewardPoints,
|
|
36
|
+
routine: routine ?? false,
|
|
37
|
+
});
|
|
38
|
+
const parts = [`Created task: "${task.attributes.summary}"`];
|
|
39
|
+
if (task.attributes.emoji_icon) {
|
|
40
|
+
parts.push(`Emoji: ${task.attributes.emoji_icon}`);
|
|
41
|
+
}
|
|
42
|
+
if (task.attributes.reward_points) {
|
|
43
|
+
parts.push(`Reward points: ${task.attributes.reward_points}`);
|
|
44
|
+
}
|
|
45
|
+
parts.push(`\nThe task has been added to the Skylight task box.`);
|
|
46
|
+
return {
|
|
47
|
+
content: [
|
|
48
|
+
{
|
|
49
|
+
type: "text",
|
|
50
|
+
text: parts.join("\n"),
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
return {
|
|
57
|
+
content: [
|
|
58
|
+
{
|
|
59
|
+
type: "text",
|
|
60
|
+
text: formatErrorForMcp(error),
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
isError: true,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/tools/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,aAAa,EACb;;;;;;;;;8DAS0D,EAC1D;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAChD,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,4CAA4C,CAAC;QACzD,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,2DAA2D,CAAC;QACxE,OAAO,EAAE,CAAC;aACP,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,OAAO,CAAC,KAAK,CAAC;aACd,QAAQ,CAAC,yBAAyB,CAAC;KACvC,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,EAAE;QAClD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC;gBACnC,OAAO;gBACP,SAAS,EAAE,KAAK;gBAChB,YAAY;gBACZ,OAAO,EAAE,OAAO,IAAI,KAAK;aAC1B,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,CAAC,kBAAkB,IAAI,CAAC,UAAU,CAAC,OAAO,GAAG,CAAC,CAAC;YAE7D,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;gBAC/B,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC;YACrD,CAAC;YAED,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC;gBAClC,KAAK,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC;YAChE,CAAC;YAED,KAAK,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;YAElE,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;qBACvB;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC;qBAC/B;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Date utility functions for Skylight MCP
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Get today's date in YYYY-MM-DD format
|
|
6
|
+
*/
|
|
7
|
+
export declare function getTodayDate(timezone?: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Get a date N days from today in YYYY-MM-DD format
|
|
10
|
+
*/
|
|
11
|
+
export declare function getDateOffset(days: number, timezone?: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Parse a date string to YYYY-MM-DD format
|
|
14
|
+
* Accepts: YYYY-MM-DD, MM/DD/YYYY, or natural language like "today", "tomorrow"
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseDate(input: string, timezone?: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Parse a time string to HH:MM format (24-hour)
|
|
19
|
+
* Accepts: "10:00", "10:00 AM", "2:30 PM", "14:30"
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseTime(input: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Format a date for display
|
|
24
|
+
*/
|
|
25
|
+
export declare function formatDateForDisplay(dateStr: string): string;
|
|
26
|
+
//# sourceMappingURL=dates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dates.d.ts","sourceRoot":"","sources":["../../src/utils/dates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAOrE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CA+ClE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAwB/C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAO5D"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Date utility functions for Skylight MCP
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Get today's date in YYYY-MM-DD format
|
|
6
|
+
*/
|
|
7
|
+
export function getTodayDate(timezone) {
|
|
8
|
+
const date = new Date();
|
|
9
|
+
if (timezone) {
|
|
10
|
+
return date.toLocaleDateString("en-CA", { timeZone: timezone });
|
|
11
|
+
}
|
|
12
|
+
return date.toISOString().split("T")[0];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get a date N days from today in YYYY-MM-DD format
|
|
16
|
+
*/
|
|
17
|
+
export function getDateOffset(days, timezone) {
|
|
18
|
+
const date = new Date();
|
|
19
|
+
date.setDate(date.getDate() + days);
|
|
20
|
+
if (timezone) {
|
|
21
|
+
return date.toLocaleDateString("en-CA", { timeZone: timezone });
|
|
22
|
+
}
|
|
23
|
+
return date.toISOString().split("T")[0];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse a date string to YYYY-MM-DD format
|
|
27
|
+
* Accepts: YYYY-MM-DD, MM/DD/YYYY, or natural language like "today", "tomorrow"
|
|
28
|
+
*/
|
|
29
|
+
export function parseDate(input, timezone) {
|
|
30
|
+
const lower = input.toLowerCase().trim();
|
|
31
|
+
// Handle natural language
|
|
32
|
+
if (lower === "today") {
|
|
33
|
+
return getTodayDate(timezone);
|
|
34
|
+
}
|
|
35
|
+
if (lower === "tomorrow") {
|
|
36
|
+
return getDateOffset(1, timezone);
|
|
37
|
+
}
|
|
38
|
+
if (lower === "yesterday") {
|
|
39
|
+
return getDateOffset(-1, timezone);
|
|
40
|
+
}
|
|
41
|
+
// Handle day of week (next occurrence)
|
|
42
|
+
const days = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
|
|
43
|
+
const dayIndex = days.indexOf(lower);
|
|
44
|
+
if (dayIndex !== -1) {
|
|
45
|
+
const today = new Date();
|
|
46
|
+
const todayDay = today.getDay();
|
|
47
|
+
let daysUntil = dayIndex - todayDay;
|
|
48
|
+
if (daysUntil <= 0) {
|
|
49
|
+
daysUntil += 7; // Next week if today or past
|
|
50
|
+
}
|
|
51
|
+
return getDateOffset(daysUntil, timezone);
|
|
52
|
+
}
|
|
53
|
+
// Already in YYYY-MM-DD format
|
|
54
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(input)) {
|
|
55
|
+
return input;
|
|
56
|
+
}
|
|
57
|
+
// MM/DD/YYYY format
|
|
58
|
+
const usMatch = input.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
|
|
59
|
+
if (usMatch) {
|
|
60
|
+
const [, month, day, year] = usMatch;
|
|
61
|
+
return `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`;
|
|
62
|
+
}
|
|
63
|
+
// Try parsing as a date
|
|
64
|
+
const parsed = new Date(input);
|
|
65
|
+
if (!isNaN(parsed.getTime())) {
|
|
66
|
+
return parsed.toISOString().split("T")[0];
|
|
67
|
+
}
|
|
68
|
+
// Return as-is if we can't parse it
|
|
69
|
+
return input;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Parse a time string to HH:MM format (24-hour)
|
|
73
|
+
* Accepts: "10:00", "10:00 AM", "2:30 PM", "14:30"
|
|
74
|
+
*/
|
|
75
|
+
export function parseTime(input) {
|
|
76
|
+
const trimmed = input.trim();
|
|
77
|
+
// Already in HH:MM format (24-hour)
|
|
78
|
+
if (/^\d{1,2}:\d{2}$/.test(trimmed)) {
|
|
79
|
+
const [hours, minutes] = trimmed.split(":");
|
|
80
|
+
return `${hours.padStart(2, "0")}:${minutes}`;
|
|
81
|
+
}
|
|
82
|
+
// 12-hour format with AM/PM
|
|
83
|
+
const match = trimmed.match(/^(\d{1,2}):(\d{2})\s*(AM|PM)$/i);
|
|
84
|
+
if (match) {
|
|
85
|
+
const [, hours, minutes, period] = match;
|
|
86
|
+
let h = parseInt(hours, 10);
|
|
87
|
+
if (period.toUpperCase() === "PM" && h !== 12) {
|
|
88
|
+
h += 12;
|
|
89
|
+
}
|
|
90
|
+
else if (period.toUpperCase() === "AM" && h === 12) {
|
|
91
|
+
h = 0;
|
|
92
|
+
}
|
|
93
|
+
return `${h.toString().padStart(2, "0")}:${minutes}`;
|
|
94
|
+
}
|
|
95
|
+
// Return as-is
|
|
96
|
+
return trimmed;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Format a date for display
|
|
100
|
+
*/
|
|
101
|
+
export function formatDateForDisplay(dateStr) {
|
|
102
|
+
const date = new Date(dateStr + "T00:00:00");
|
|
103
|
+
return date.toLocaleDateString("en-US", {
|
|
104
|
+
weekday: "short",
|
|
105
|
+
month: "short",
|
|
106
|
+
day: "numeric",
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=dates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dates.js","sourceRoot":"","sources":["../../src/utils/dates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for Skylight API errors
|
|
3
|
+
*/
|
|
4
|
+
export declare class SkylightError extends Error {
|
|
5
|
+
code: string;
|
|
6
|
+
statusCode?: number | undefined;
|
|
7
|
+
recoverable: boolean;
|
|
8
|
+
constructor(message: string, code: string, statusCode?: number | undefined, recoverable?: boolean);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Authentication failed - token may be expired or invalid
|
|
12
|
+
*/
|
|
13
|
+
export declare class AuthenticationError extends SkylightError {
|
|
14
|
+
constructor(message?: string);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Configuration error - missing or invalid settings
|
|
18
|
+
*/
|
|
19
|
+
export declare class ConfigurationError extends SkylightError {
|
|
20
|
+
constructor(message: string);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resource not found
|
|
24
|
+
*/
|
|
25
|
+
export declare class NotFoundError extends SkylightError {
|
|
26
|
+
constructor(resource: string);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Rate limited by the API
|
|
30
|
+
*/
|
|
31
|
+
export declare class RateLimitError extends SkylightError {
|
|
32
|
+
constructor(retryAfter?: number);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* API returned an unexpected response format
|
|
36
|
+
*/
|
|
37
|
+
export declare class ParseError extends SkylightError {
|
|
38
|
+
constructor(message?: string);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Format an error for MCP tool response
|
|
42
|
+
* Accepts unknown to handle any value from catch blocks safely
|
|
43
|
+
*/
|
|
44
|
+
export declare function formatErrorForMcp(error: unknown): string;
|
|
45
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;IAG7B,IAAI,EAAE,MAAM;IACZ,UAAU,CAAC,EAAE,MAAM;IACnB,WAAW,EAAE,OAAO;gBAH3B,OAAO,EAAE,MAAM,EACR,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,YAAA,EACnB,WAAW,GAAE,OAAe;CAKtC;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,aAAa;gBACxC,OAAO,GAAE,MAAuE;CAI7F;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,aAAa;gBACvC,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,aAAa;gBAClC,QAAQ,EAAE,MAAM;CAI7B;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,aAAa;gBACnC,UAAU,CAAC,EAAE,MAAM;CAShC;AAED;;GAEG;AACH,qBAAa,UAAW,SAAQ,aAAa;gBAC/B,OAAO,GAAE,MAAyC;CAI/D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CA0CxD"}
|