myhotlunchbox-mcp 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +3 -1
- package/dist/bundle.js +26 -4
- package/dist/tools/billing.js +45 -3
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "MCP server for My Hot Lunchbox — order school lunches, manage students, and track payments via natural language",
|
|
10
|
-
"version": "1.2.
|
|
10
|
+
"version": "1.2.2"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "My Hot Lunchbox",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "MCP server for My Hot Lunchbox — school lunch calendar, ordering, and payments. Signs in server-side with the parent account credentials.",
|
|
18
|
-
"version": "1.2.
|
|
18
|
+
"version": "1.2.2",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myhotlunchbox-mcp",
|
|
3
3
|
"displayName": "My Hot Lunchbox",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.2",
|
|
5
5
|
"description": "MCP server for My Hot Lunchbox — order school lunches, manage students, and track payments via natural language",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Chris Hall",
|
package/README.md
CHANGED
|
@@ -63,7 +63,9 @@ forced `zod` 4.6.2 bump — 20/20 green.
|
|
|
63
63
|
`mhlb_list_subscriptions`, `mhlb_get_subscription_settings`,
|
|
64
64
|
`mhlb_set_subscription_enabled`, `mhlb_unsubscribe_order`,
|
|
65
65
|
`mhlb_list_gift_cards`, `mhlb_apply_gift_card`, `mhlb_get_coupon`,
|
|
66
|
-
`mhlb_apply_coupon`, `mhlb_remove_coupon`
|
|
66
|
+
`mhlb_apply_coupon`, `mhlb_remove_coupon`. `mhlb_list_gift_cards` masks each code to its
|
|
67
|
+
last 4 characters (a code is redeemable money); pass `revealCodes: true` for
|
|
68
|
+
the full code.
|
|
67
69
|
|
|
68
70
|
**Checkout** — `mhlb_init_checkout`, `mhlb_checkout`
|
|
69
71
|
|
package/dist/bundle.js
CHANGED
|
@@ -59235,7 +59235,7 @@ var MhlbClient = class {
|
|
|
59235
59235
|
};
|
|
59236
59236
|
|
|
59237
59237
|
// src/version.ts
|
|
59238
|
-
var VERSION = "1.2.
|
|
59238
|
+
var VERSION = "1.2.2";
|
|
59239
59239
|
|
|
59240
59240
|
// src/tools/_shared.ts
|
|
59241
59241
|
var CONFIRMS = " Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).";
|
|
@@ -59679,11 +59679,16 @@ function registerBillingTools(server, client2) {
|
|
|
59679
59679
|
server.registerTool(
|
|
59680
59680
|
"mhlb_list_gift_cards",
|
|
59681
59681
|
{
|
|
59682
|
-
description: "List gift cards on the account \u2014
|
|
59682
|
+
description: "List gift cards on the account \u2014 balances and status, with each code masked to its last 4 characters. Pass revealCodes: true only when the user needs a full code.",
|
|
59683
59683
|
annotations: toolAnnotations({ title: "List gift cards", openWorld: true }),
|
|
59684
|
-
inputSchema: external_exports.object({
|
|
59684
|
+
inputSchema: external_exports.object({
|
|
59685
|
+
revealCodes: external_exports.boolean().optional().describe("Return full gift-card codes instead of masked ones. A code is redeemable money; default false.")
|
|
59686
|
+
})
|
|
59685
59687
|
},
|
|
59686
|
-
async () =>
|
|
59688
|
+
async ({ revealCodes }) => {
|
|
59689
|
+
const data = await client2.get("/parent/giftCardDataTables");
|
|
59690
|
+
return minifiedResult(revealCodes ? data : maskGiftCardCodes(data));
|
|
59691
|
+
}
|
|
59687
59692
|
);
|
|
59688
59693
|
server.registerTool(
|
|
59689
59694
|
"mhlb_apply_gift_card",
|
|
@@ -59755,6 +59760,23 @@ function registerBillingTools(server, client2) {
|
|
|
59755
59760
|
}
|
|
59756
59761
|
);
|
|
59757
59762
|
}
|
|
59763
|
+
var GIFT_CARD_CODE_KEY = /^code$|^(?:gift_?)?card_?(?:code|number|no|num)$/i;
|
|
59764
|
+
function maskCode(code) {
|
|
59765
|
+
const shown = Math.min(4, Math.floor(code.length / 2));
|
|
59766
|
+
return `****${shown > 0 ? code.slice(-shown) : ""}`;
|
|
59767
|
+
}
|
|
59768
|
+
function maskGiftCardCodes(value) {
|
|
59769
|
+
if (Array.isArray(value)) return value.map(maskGiftCardCodes);
|
|
59770
|
+
if (value === null || typeof value !== "object") return value;
|
|
59771
|
+
return Object.fromEntries(
|
|
59772
|
+
Object.entries(value).map(([k, v]) => {
|
|
59773
|
+
if (GIFT_CARD_CODE_KEY.test(k) && (typeof v === "string" || typeof v === "number")) {
|
|
59774
|
+
return [k, maskCode(String(v))];
|
|
59775
|
+
}
|
|
59776
|
+
return [k, maskGiftCardCodes(v)];
|
|
59777
|
+
})
|
|
59778
|
+
);
|
|
59779
|
+
}
|
|
59758
59780
|
|
|
59759
59781
|
// src/tools/checkout.ts
|
|
59760
59782
|
import { randomUUID } from "node:crypto";
|
package/dist/tools/billing.js
CHANGED
|
@@ -74,10 +74,19 @@ export function registerBillingTools(server, client) {
|
|
|
74
74
|
return minifiedResult(await client.write('/event/unsubcribeOrder', body));
|
|
75
75
|
});
|
|
76
76
|
server.registerTool('mhlb_list_gift_cards', {
|
|
77
|
-
description: 'List gift cards on the account —
|
|
77
|
+
description: 'List gift cards on the account — balances and status, with each code masked to its last 4 characters. ' +
|
|
78
|
+
'Pass revealCodes: true only when the user needs a full code.',
|
|
78
79
|
annotations: toolAnnotations({ title: 'List gift cards', openWorld: true }),
|
|
79
|
-
inputSchema: z.object({
|
|
80
|
-
|
|
80
|
+
inputSchema: z.object({
|
|
81
|
+
revealCodes: z
|
|
82
|
+
.boolean()
|
|
83
|
+
.optional()
|
|
84
|
+
.describe('Return full gift-card codes instead of masked ones. A code is redeemable money; default false.'),
|
|
85
|
+
}),
|
|
86
|
+
}, async ({ revealCodes }) => {
|
|
87
|
+
const data = await client.get('/parent/giftCardDataTables');
|
|
88
|
+
return minifiedResult(revealCodes ? data : maskGiftCardCodes(data));
|
|
89
|
+
});
|
|
81
90
|
server.registerTool('mhlb_apply_gift_card', {
|
|
82
91
|
description: 'Redeem a gift card code onto the account balance.' + CONFIRMS + UNVERIFIED,
|
|
83
92
|
annotations: toolAnnotations({ title: 'Apply gift card', readOnly: false, openWorld: true, destructive: true }),
|
|
@@ -135,3 +144,36 @@ export function registerBillingTools(server, client) {
|
|
|
135
144
|
return minifiedResult(await client.write('/parent/removeCoupon'));
|
|
136
145
|
});
|
|
137
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Keys that hold a gift-card code (a redeemable bearer value): `code`,
|
|
149
|
+
* `giftCardCode`, `cardNumber`, `giftCardNo`, … — but not `statusCode` and
|
|
150
|
+
* friends, which are enum values.
|
|
151
|
+
*/
|
|
152
|
+
const GIFT_CARD_CODE_KEY = /^code$|^(?:gift_?)?card_?(?:code|number|no|num)$/i;
|
|
153
|
+
/**
|
|
154
|
+
* `'****' + last 4` — enough to tell cards apart, not enough to redeem one.
|
|
155
|
+
* A short code shows at most half its characters (rounded down), so a code of
|
|
156
|
+
* 4 or fewer is never revealed in full.
|
|
157
|
+
*/
|
|
158
|
+
export function maskCode(code) {
|
|
159
|
+
const shown = Math.min(4, Math.floor(code.length / 2));
|
|
160
|
+
return `****${shown > 0 ? code.slice(-shown) : ''}`;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Mask every gift-card code in a `/parent/giftCardDataTables` response,
|
|
164
|
+
* leaving every other field (ids, balances, status, dates) intact. Walks the
|
|
165
|
+
* whole value rather than assuming one row shape, so a DataTables envelope, a
|
|
166
|
+
* bare array, or a renamed field are all covered.
|
|
167
|
+
*/
|
|
168
|
+
export function maskGiftCardCodes(value) {
|
|
169
|
+
if (Array.isArray(value))
|
|
170
|
+
return value.map(maskGiftCardCodes);
|
|
171
|
+
if (value === null || typeof value !== 'object')
|
|
172
|
+
return value;
|
|
173
|
+
return Object.fromEntries(Object.entries(value).map(([k, v]) => {
|
|
174
|
+
if (GIFT_CARD_CODE_KEY.test(k) && (typeof v === 'string' || typeof v === 'number')) {
|
|
175
|
+
return [k, maskCode(String(v))];
|
|
176
|
+
}
|
|
177
|
+
return [k, maskGiftCardCodes(v)];
|
|
178
|
+
}));
|
|
179
|
+
}
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Single source of truth for the server version; release-please rewrites it. */
|
|
2
|
-
export const VERSION = '1.2.
|
|
2
|
+
export const VERSION = '1.2.2'; // x-release-please-version
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myhotlunchbox-mcp",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"mcpName": "io.github.chrischall/myhotlunchbox-mcp",
|
|
5
5
|
"description": "My Hot Lunchbox MCP server for Claude — developed and maintained by AI (Claude Code)",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/myhotlunchbox-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "1.2.
|
|
9
|
+
"version": "1.2.2",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "myhotlunchbox-mcp",
|
|
14
|
-
"version": "1.2.
|
|
14
|
+
"version": "1.2.2",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|