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.
@@ -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.0"
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.0",
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.0",
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.0";
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 codes, balances and status.",
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 () => minifiedResult(await client2.get("/parent/giftCardDataTables"))
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";
@@ -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 — codes, balances and status.',
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
- }, async () => minifiedResult(await client.get('/parent/giftCardDataTables')));
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.0'; // x-release-please-version
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.0",
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.0",
9
+ "version": "1.2.2",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "myhotlunchbox-mcp",
14
- "version": "1.2.0",
14
+ "version": "1.2.2",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },