migros-mcp 0.3.0 → 0.4.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.
Files changed (46) hide show
  1. package/README.md +35 -19
  2. package/dist/auth/api.js +18 -1
  3. package/dist/auth/api.js.map +1 -1
  4. package/dist/auth/cookies.d.ts +11 -0
  5. package/dist/auth/cookies.js +4 -0
  6. package/dist/auth/cookies.js.map +1 -1
  7. package/dist/auth/index.d.ts +20 -3
  8. package/dist/auth/index.js +75 -21
  9. package/dist/auth/index.js.map +1 -1
  10. package/dist/auth/login.d.ts +20 -2
  11. package/dist/auth/login.js +48 -5
  12. package/dist/auth/login.js.map +1 -1
  13. package/dist/auth/oauth.d.ts +11 -1
  14. package/dist/auth/oauth.js +41 -13
  15. package/dist/auth/oauth.js.map +1 -1
  16. package/dist/auth/rate-limit.d.ts +70 -0
  17. package/dist/auth/rate-limit.js +117 -0
  18. package/dist/auth/rate-limit.js.map +1 -0
  19. package/dist/auth-tools/_shared.d.ts +1 -1
  20. package/dist/auth-tools/_shared.js +2 -2
  21. package/dist/auth-tools/_shared.js.map +1 -1
  22. package/dist/auth-tools/authenticate.d.ts +10 -0
  23. package/dist/auth-tools/authenticate.js +17 -0
  24. package/dist/auth-tools/authenticate.js.map +1 -0
  25. package/dist/auth-tools/cart.d.ts +19 -1
  26. package/dist/auth-tools/cart.js +38 -4
  27. package/dist/auth-tools/cart.js.map +1 -1
  28. package/dist/auth-tools.d.ts +2 -1
  29. package/dist/auth-tools.js +2 -1
  30. package/dist/auth-tools.js.map +1 -1
  31. package/dist/index.d.ts +0 -0
  32. package/dist/index.js +7 -5
  33. package/dist/index.js.map +1 -1
  34. package/dist/migros.d.ts +0 -0
  35. package/dist/migros.js +0 -0
  36. package/dist/migros.js.map +0 -0
  37. package/dist/schemas.d.ts +14 -0
  38. package/dist/schemas.js +15 -2
  39. package/dist/schemas.js.map +1 -1
  40. package/dist/tools.d.ts +0 -0
  41. package/dist/tools.js +0 -0
  42. package/dist/tools.js.map +0 -0
  43. package/dist/types.d.ts +0 -0
  44. package/dist/types.js +0 -0
  45. package/dist/types.js.map +0 -0
  46. package/package.json +3 -1
@@ -1,11 +1,11 @@
1
1
  import https from "node:https";
2
2
  import axios from "axios";
3
3
  import { cookieHeader, ingestSetCookie } from "./cookies.js";
4
- // IMPORTANT: per-host User-Agent. Akamai on www.migros.ch rejects Chrome but
5
- // accepts this Firefox/Linux UA (same approach as migros-api-wrapper). The login
6
- // origin uses Cloudflare which is more permissive and accepts Chrome.
7
- const UA_LOGIN = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36";
8
- const UA_WWW = "Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0";
4
+ import { parseRetryAfter, RateLimitError, setRateLimited, clearRateLimit, } from "./rate-limit.js";
5
+ // User-Agent matters at the Cloudflare edge: a Chrome UA from Node gets
6
+ // blocked on www.migros.ch. This Firefox/Linux UA (borrowed from
7
+ // migros-api-wrapper) passes both www.migros.ch and login.migros.ch.
8
+ const UA = "Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0";
9
9
  const REDIRECT_URI = "https://www.migros.ch/m-login-silent-login-redirect.html";
10
10
  let _client = null;
11
11
  export function client() {
@@ -19,12 +19,9 @@ export function client() {
19
19
  });
20
20
  return _client;
21
21
  }
22
- export function uaFor(host) {
23
- return host === "www.migros.ch" ? UA_WWW : UA_LOGIN;
24
- }
25
22
  export function uniformHeaders(host, session, extra = {}) {
26
23
  return {
27
- "User-Agent": uaFor(host),
24
+ "User-Agent": UA,
28
25
  "Accept-Language": "en-US,en;q=0.9",
29
26
  "Accept-Encoding": "gzip, deflate, br",
30
27
  Cookie: cookieHeader(session, host),
@@ -47,6 +44,10 @@ function decodeJwtExp(jwt) {
47
44
  * Throws if the SSO cookies are missing/expired (e.g., user logged out of
48
45
  * migros.ch in their browser, or session.json is stale by weeks).
49
46
  *
47
+ * On a 429 (rate-limit), sets `session.rateLimitedUntil` and throws a
48
+ * {@link RateLimitError} so the caller can surface the cooldown and avoid
49
+ * cascading into a full credentialed login.
50
+ *
50
51
  * Caller is responsible for persisting the session afterward.
51
52
  */
52
53
  export async function silentOAuth(session) {
@@ -58,8 +59,14 @@ export async function silentOAuth(session) {
58
59
  headers: uniformHeaders("www.migros.ch", session, { Accept: "application/json, text/plain, */*" }),
59
60
  });
60
61
  ingestSetCookie(session, "www.migros.ch", r.headers["set-cookie"]);
62
+ if (r.status === 429) {
63
+ const retryAfter = parseRetryAfter(r.headers["retry-after"]);
64
+ setRateLimited(session, retryAfter, "oauth/authorize -> 429");
65
+ throw new RateLimitError("login.migros.ch rate-limited (429) during silent OAuth authorize step. " +
66
+ "Retry after: " + (retryAfter ?? "unknown") + "s", retryAfter);
67
+ }
61
68
  if (r.status !== 200)
62
- throw new Error(`oauth/authorize -> ${r.status}`);
69
+ throw new Error("oauth/authorize -> " + r.status);
63
70
  const data = typeof r.data === "string" ? JSON.parse(r.data) : r.data;
64
71
  const ssoUrl = data?.url;
65
72
  if (!ssoUrl)
@@ -70,6 +77,12 @@ export async function silentOAuth(session) {
70
77
  headers: uniformHeaders("login.migros.ch", session, { Accept: "text/html" }),
71
78
  });
72
79
  ingestSetCookie(session, "login.migros.ch", r.headers["set-cookie"]);
80
+ if (r.status === 429) {
81
+ const retryAfter = parseRetryAfter(r.headers["retry-after"]);
82
+ setRateLimited(session, retryAfter, "silent SSO -> 429");
83
+ throw new RateLimitError("login.migros.ch rate-limited (429) during silent SSO redirect. " +
84
+ "Retry after: " + (retryAfter ?? "unknown") + "s", retryAfter);
85
+ }
73
86
  const location = r.headers.location;
74
87
  if (!location) {
75
88
  throw new Error("silent SSO did not redirect — login.migros.ch session likely expired");
@@ -81,15 +94,21 @@ export async function silentOAuth(session) {
81
94
  throw new Error("silent SSO redirected without code/state");
82
95
  // Step 3: exchange the code for a JWT.
83
96
  const successUrl = "https://www.migros.ch/authentication/public/v1/api/oauth/login-success" +
84
- `?code=${encodeURIComponent(code)}&state=${encodeURIComponent(state)}` +
97
+ "?code=" + encodeURIComponent(code) + "&state=" + encodeURIComponent(state) +
85
98
  "&redirectUri=" + encodeURIComponent(REDIRECT_URI) +
86
99
  "&authorizationNotRequired=true";
87
100
  r = await client().get(successUrl, {
88
101
  headers: uniformHeaders("www.migros.ch", session, { Accept: "application/json" }),
89
102
  });
90
103
  ingestSetCookie(session, "www.migros.ch", r.headers["set-cookie"]);
104
+ if (r.status === 429) {
105
+ const retryAfter = parseRetryAfter(r.headers["retry-after"]);
106
+ setRateLimited(session, retryAfter, "oauth/login-success -> 429");
107
+ throw new RateLimitError("login.migros.ch rate-limited (429) during OAuth login-success step. " +
108
+ "Retry after: " + (retryAfter ?? "unknown") + "s", retryAfter);
109
+ }
91
110
  if (r.status !== 200)
92
- throw new Error(`oauth/login-success -> ${r.status}`);
111
+ throw new Error("oauth/login-success -> " + r.status);
93
112
  const tokenBody = (typeof r.data === "string" ? JSON.parse(r.data) : r.data);
94
113
  let token = (tokenBody.accessToken ?? tokenBody.access_token ?? tokenBody.token ?? null);
95
114
  if (!token)
@@ -100,13 +119,22 @@ export async function silentOAuth(session) {
100
119
  token = token.replace(/^bearer\s+/i, "");
101
120
  session.jwt = token;
102
121
  session.jwtExp = decodeJwtExp(token);
122
+ // Successful OAuth clears any stale rate-limit cooldown.
123
+ clearRateLimit(session);
103
124
  return token;
104
125
  }
126
+ /**
127
+ * How much JWT lifetime (in seconds) we keep in reserve before proactively
128
+ * refreshing via silent OAuth. Also used by fail-open paths in getJwt() so a
129
+ * near-expired token is never handed to the API (which would 401 and trigger
130
+ * a rate-limited refresh attempt).
131
+ */
132
+ export const JWT_BUFFER_SECONDS = 300;
105
133
  /**
106
134
  * Returns a usable JWT, refreshing via silent OAuth if the cached one is
107
135
  * within `bufferSeconds` of expiring (or missing). Mutates `session`.
108
136
  */
109
- export async function getJwt(session, bufferSeconds = 60) {
137
+ export async function getJwt(session, bufferSeconds = JWT_BUFFER_SECONDS) {
110
138
  const now = Math.floor(Date.now() / 1000);
111
139
  if (session.jwt && session.jwtExp && session.jwtExp - now > bufferSeconds) {
112
140
  return session.jwt;
@@ -1 +1 @@
1
- {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * 429 Too Many Requests handling for login.migros.ch.
3
+ *
4
+ * Cloudflare sits in front of login.migros.ch and throttles repeated login
5
+ * attempts. Without this module every authenticated tool call cascades from
6
+ * silent-OAuth failure straight into a full credentialed login that hammers the
7
+ * same rate-limited host, making the throttle worse and keeping the MCP
8
+ * unusable for the user.
9
+ *
10
+ * All times are in **unix epoch milliseconds** (Date.now() convention) to keep
11
+ * exported constants unambiguous.
12
+ */
13
+ /**
14
+ * Parse a `Retry-After` response header into a **seconds** value.
15
+ *
16
+ * Returns `null` when the header is missing, unparseable, or describes a date
17
+ * in the past (negative delay).
18
+ */
19
+ export declare function parseRetryAfter(header: string | null | undefined): number | null;
20
+ /**
21
+ * Exponential backoff schedule for when Retry-After is missing.
22
+ *
23
+ * Returns **milliseconds**.
24
+ */
25
+ export declare function rateLimitBackoff(attempt: number): number;
26
+ /**
27
+ * Thrown by the auth layer when a 429 is detected so upper layers can
28
+ * distinguish "we're being throttled" from "your credentials are wrong".
29
+ */
30
+ export declare class RateLimitError extends Error {
31
+ /** Parsed Retry-After in **seconds**, or `null` when the header was absent. */
32
+ readonly retryAfterSeconds: number | null;
33
+ constructor(message: string, retryAfterSeconds?: number | null);
34
+ }
35
+ /**
36
+ * Returns `true` when the session carries a rate-limit cooldown that hasn't
37
+ * expired yet.
38
+ */
39
+ export declare function isRateLimited(session: {
40
+ rateLimitedUntil?: number;
41
+ }): boolean;
42
+ /** Longest cooldown accepted from a Retry-After header (1 hour). */
43
+ export declare const MAX_COOLDOWN_SECONDS = 3600;
44
+ /** After this long without a new 429, the fallback backoff starts again at 30 s. */
45
+ export declare const BACKOFF_RESET_MS = 3600000;
46
+ type CooldownState = {
47
+ rateLimitedUntil?: number;
48
+ rateLimitReason?: string;
49
+ rateLimitAttempts?: number;
50
+ };
51
+ /**
52
+ * Apply a cooldown timestamp to the session in-place (caller persists).
53
+ *
54
+ * Consecutive 429s step the fallback backoff up (30 s, 2 min, 10 min). The
55
+ * count starts again after a successful login (clearRateLimit) or when the
56
+ * last cooldown ended more than BACKOFF_RESET_MS ago.
57
+ *
58
+ * @param retryAfterSeconds Parsed Retry-After seconds (capped at
59
+ * MAX_COOLDOWN_SECONDS), or `null` to use the
60
+ * backoff step for this attempt.
61
+ */
62
+ export declare function setRateLimited(session: CooldownState, retryAfterSeconds: number | null, reason: string): void;
63
+ /** Remove any rate-limit cooldown from the session. */
64
+ export declare function clearRateLimit(session: CooldownState): void;
65
+ /** Build a human-readable error for `isRateLimited` + expired JWT. */
66
+ export declare function rateLimitBlockedMessage(session: {
67
+ rateLimitedUntil?: number;
68
+ rateLimitReason?: string;
69
+ }): string;
70
+ export {};
@@ -0,0 +1,117 @@
1
+ /**
2
+ * 429 Too Many Requests handling for login.migros.ch.
3
+ *
4
+ * Cloudflare sits in front of login.migros.ch and throttles repeated login
5
+ * attempts. Without this module every authenticated tool call cascades from
6
+ * silent-OAuth failure straight into a full credentialed login that hammers the
7
+ * same rate-limited host, making the throttle worse and keeping the MCP
8
+ * unusable for the user.
9
+ *
10
+ * All times are in **unix epoch milliseconds** (Date.now() convention) to keep
11
+ * exported constants unambiguous.
12
+ */
13
+ /**
14
+ * Parse a `Retry-After` response header into a **seconds** value.
15
+ *
16
+ * Returns `null` when the header is missing, unparseable, or describes a date
17
+ * in the past (negative delay).
18
+ */
19
+ export function parseRetryAfter(header) {
20
+ if (!header)
21
+ return null;
22
+ const v = header.trim();
23
+ // Integer → delay-seconds.
24
+ if (/^\d+$/.test(v)) {
25
+ const s = Number.parseInt(v, 10);
26
+ return Number.isFinite(s) && s >= 0 ? s : null;
27
+ }
28
+ // HTTP-date (RFC 7231) — heuristically detect via the presence of letters
29
+ // or commas; Date.parse is very lenient and would accept "-1" as a valid
30
+ // (negative) timestamp, giving a false positive.
31
+ if (/[a-z,]/i.test(v)) {
32
+ const epoch = Date.parse(v);
33
+ if (!Number.isNaN(epoch)) {
34
+ const sec = Math.ceil((epoch - Date.now()) / 1000);
35
+ // Negative means the date is in the past: clamp to 0 (retry immediately).
36
+ return Math.max(0, sec);
37
+ }
38
+ }
39
+ return null;
40
+ }
41
+ /**
42
+ * Exponential backoff schedule for when Retry-After is missing.
43
+ *
44
+ * Returns **milliseconds**.
45
+ */
46
+ export function rateLimitBackoff(attempt) {
47
+ const delays = [30_000, 120_000, 600_000]; // 30 s → 2 min → 10 min
48
+ return delays[Math.min(attempt, delays.length - 1)] ?? 600_000;
49
+ }
50
+ // ---------------------------------------------------------------------------
51
+ // Error class
52
+ // ---------------------------------------------------------------------------
53
+ /**
54
+ * Thrown by the auth layer when a 429 is detected so upper layers can
55
+ * distinguish "we're being throttled" from "your credentials are wrong".
56
+ */
57
+ export class RateLimitError extends Error {
58
+ /** Parsed Retry-After in **seconds**, or `null` when the header was absent. */
59
+ retryAfterSeconds;
60
+ constructor(message, retryAfterSeconds = null) {
61
+ super(message);
62
+ this.name = "RateLimitError";
63
+ this.retryAfterSeconds = retryAfterSeconds;
64
+ }
65
+ }
66
+ // ---------------------------------------------------------------------------
67
+ // Cooldown state helpers
68
+ // ---------------------------------------------------------------------------
69
+ /**
70
+ * Returns `true` when the session carries a rate-limit cooldown that hasn't
71
+ * expired yet.
72
+ */
73
+ export function isRateLimited(session) {
74
+ return typeof session.rateLimitedUntil === "number" && Date.now() < session.rateLimitedUntil;
75
+ }
76
+ /** Longest cooldown accepted from a Retry-After header (1 hour). */
77
+ export const MAX_COOLDOWN_SECONDS = 3600;
78
+ /** After this long without a new 429, the fallback backoff starts again at 30 s. */
79
+ export const BACKOFF_RESET_MS = 3_600_000;
80
+ /**
81
+ * Apply a cooldown timestamp to the session in-place (caller persists).
82
+ *
83
+ * Consecutive 429s step the fallback backoff up (30 s, 2 min, 10 min). The
84
+ * count starts again after a successful login (clearRateLimit) or when the
85
+ * last cooldown ended more than BACKOFF_RESET_MS ago.
86
+ *
87
+ * @param retryAfterSeconds Parsed Retry-After seconds (capped at
88
+ * MAX_COOLDOWN_SECONDS), or `null` to use the
89
+ * backoff step for this attempt.
90
+ */
91
+ export function setRateLimited(session, retryAfterSeconds, reason) {
92
+ const recent = typeof session.rateLimitedUntil === "number" &&
93
+ Date.now() - session.rateLimitedUntil < BACKOFF_RESET_MS;
94
+ const attempt = recent ? session.rateLimitAttempts ?? 0 : 0;
95
+ const delay = retryAfterSeconds !== null
96
+ ? Math.min(retryAfterSeconds, MAX_COOLDOWN_SECONDS) * 1000
97
+ : rateLimitBackoff(attempt);
98
+ session.rateLimitedUntil = Date.now() + delay;
99
+ session.rateLimitReason = reason;
100
+ session.rateLimitAttempts = attempt + 1;
101
+ }
102
+ /** Remove any rate-limit cooldown from the session. */
103
+ export function clearRateLimit(session) {
104
+ delete session.rateLimitedUntil;
105
+ delete session.rateLimitReason;
106
+ delete session.rateLimitAttempts;
107
+ }
108
+ /** Build a human-readable error for `isRateLimited` + expired JWT. */
109
+ export function rateLimitBlockedMessage(session) {
110
+ const until = session.rateLimitedUntil
111
+ ? new Date(session.rateLimitedUntil).toISOString()
112
+ : "unknown";
113
+ return (`login.migros.ch rate-limited until ${until}; ` +
114
+ `reason: ${session.rateLimitReason ?? "unknown"}. ` +
115
+ `Cached JWT is also expired — cannot re-authenticate until the rate limit clears.`);
116
+ }
117
+ //# sourceMappingURL=rate-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../../src/auth/rate-limit.ts"],"names":[],"mappings":"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"}
@@ -3,4 +3,4 @@ import type { Credentials } from "../auth/index.js";
3
3
  * Read credentials from env. Returns undefined if not all vars are set, in
4
4
  * which case the auth layer falls back to a cached session if one exists.
5
5
  */
6
- export declare function credsFromEnv(): Credentials | undefined;
6
+ export declare function credsFromEnv(totpCode?: string): Credentials | undefined;
@@ -2,11 +2,11 @@
2
2
  * Read credentials from env. Returns undefined if not all vars are set, in
3
3
  * which case the auth layer falls back to a cached session if one exists.
4
4
  */
5
- export function credsFromEnv() {
5
+ export function credsFromEnv(totpCode) {
6
6
  const email = process.env.MIGROS_EMAIL;
7
7
  const password = process.env.MIGROS_PASSWORD;
8
8
  if (!email || !password)
9
9
  return undefined;
10
- return { email, password, totpSecret: process.env.MIGROS_TOTP_SECRET };
10
+ return { email, password, totpSecret: process.env.MIGROS_TOTP_SECRET || undefined, totpCode };
11
11
  }
12
12
  //# sourceMappingURL=_shared.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_shared.js","sourceRoot":"","sources":["../../src/auth-tools/_shared.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IACvC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC7C,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC1C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;AACzE,CAAC"}
1
+ {"version":3,"file":"_shared.js","sourceRoot":"","sources":["../../src/auth-tools/_shared.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,QAAiB;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IACvC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC7C,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC1C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,SAAS,EAAE,QAAQ,EAAE,CAAC;AAChG,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Establish or reuse the authenticated Migros session.
3
+ *
4
+ * The caller supplies a current six-digit TOTP code only when a cached
5
+ * session cannot be reused. The code is held only for this call and is never
6
+ * written to the persisted session.
7
+ */
8
+ export declare function authenticate(args?: {
9
+ totpCode?: string;
10
+ }): Promise<string>;
@@ -0,0 +1,17 @@
1
+ import { getJwt } from "../auth/index.js";
2
+ import { credsFromEnv } from "./_shared.js";
3
+ /**
4
+ * Establish or reuse the authenticated Migros session.
5
+ *
6
+ * The caller supplies a current six-digit TOTP code only when a cached
7
+ * session cannot be reused. The code is held only for this call and is never
8
+ * written to the persisted session.
9
+ */
10
+ export async function authenticate(args = {}) {
11
+ await getJwt(credsFromEnv(args.totpCode), { tryLoginWithoutCode: true });
12
+ return JSON.stringify({
13
+ authenticated: true,
14
+ message: "Migros authentication is ready. A cached session was reused when possible.",
15
+ }, null, 2);
16
+ }
17
+ //# sourceMappingURL=authenticate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticate.js","sourceRoot":"","sources":["../../src/auth-tools/authenticate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA8B,EAAE;IACjE,MAAM,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,CAAC;IACzE,OAAO,IAAI,CAAC,SAAS,CACnB;QACE,aAAa,EAAE,IAAI;QACnB,OAAO,EAAE,4EAA4E;KACtF,EACD,IAAI,EACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,3 +1,18 @@
1
+ interface ShoppingListSummary {
2
+ shoppingListId: number;
3
+ shoppingListName?: string;
4
+ }
5
+ /**
6
+ * Shape the list overview for the AI: id and name of each list, plus a hint
7
+ * on how to use them. The basket tools fall back to the first list here.
8
+ */
9
+ export declare function formatShoppingLists(lists: ShoppingListSummary[] | null | undefined): string;
10
+ /**
11
+ * List the user's shopping lists (id and name). Needed when someone keeps
12
+ * several lists: the basket tools otherwise use whichever list Migros returns
13
+ * first, which isn't always the one they mean.
14
+ */
15
+ export declare function getShoppingLists(): Promise<string>;
1
16
  /**
2
17
  * Fetch the contents of a shopping list (basket). Returns a flat summary of
3
18
  * items + totals. Product names are not returned by this endpoint — call
@@ -34,4 +49,7 @@ export declare function removeFromBasket(args: {
34
49
  * real browser (Datatrans 3DS / saved-card prompt), so we hand off rather than
35
50
  * try to automate the money step. Includes a basket summary for the LLM.
36
51
  */
37
- export declare function getCheckoutLink(): Promise<string>;
52
+ export declare function getCheckoutLink(args?: {
53
+ shoppingListId?: number;
54
+ }): Promise<string>;
55
+ export {};
@@ -1,5 +1,10 @@
1
1
  import { api } from "../auth/api.js";
2
2
  import { credsFromEnv } from "./_shared.js";
3
+ /** All of the user's shopping lists, as Migros returns them. */
4
+ async function fetchShoppingLists() {
5
+ const lists = (await api("GET", "/shopping-list/public/v1/lists/overview", undefined, { creds: credsFromEnv() }));
6
+ return lists ?? [];
7
+ }
3
8
  /**
4
9
  * Resolve the user's primary shopping list id, calling /lists/overview if not
5
10
  * provided. Most users have a single list named "Shopping list".
@@ -7,11 +12,40 @@ import { credsFromEnv } from "./_shared.js";
7
12
  async function resolveShoppingListId(provided) {
8
13
  if (typeof provided === "number")
9
14
  return provided;
10
- const lists = (await api("GET", "/shopping-list/public/v1/lists/overview", undefined, { creds: credsFromEnv() }));
11
- if (!lists?.length)
15
+ const lists = await fetchShoppingLists();
16
+ if (!lists.length)
12
17
  throw new Error("no shopping lists found for this account");
13
18
  return lists[0].shoppingListId;
14
19
  }
20
+ /**
21
+ * Shape the list overview for the AI: id and name of each list, plus a hint
22
+ * on how to use them. The basket tools fall back to the first list here.
23
+ */
24
+ export function formatShoppingLists(lists) {
25
+ const out = (lists ?? []).map((l) => ({
26
+ shoppingListId: l.shoppingListId,
27
+ name: l.shoppingListName ?? l.name,
28
+ }));
29
+ return JSON.stringify({
30
+ count: out.length,
31
+ lists: out,
32
+ hint: out.length > 1
33
+ ? "Several lists. If it isn't clear which one the user means, ask. Then pass its shoppingListId " +
34
+ "to get_basket, add_to_basket, update_basket_quantity, remove_from_basket or get_checkout_link. " +
35
+ "Without it, those tools use the first list here."
36
+ : out.length === 1
37
+ ? "One list. The basket tools use it by default."
38
+ : "No shopping lists found for this account.",
39
+ }, null, 2);
40
+ }
41
+ /**
42
+ * List the user's shopping lists (id and name). Needed when someone keeps
43
+ * several lists: the basket tools otherwise use whichever list Migros returns
44
+ * first, which isn't always the one they mean.
45
+ */
46
+ export async function getShoppingLists() {
47
+ return formatShoppingLists(await fetchShoppingLists());
48
+ }
15
49
  /**
16
50
  * Format a basket response into the same flat shape get_basket returns.
17
51
  * Used by both reads and writes since the v3/items endpoint returns the
@@ -93,8 +127,8 @@ export async function removeFromBasket(args) {
93
127
  * real browser (Datatrans 3DS / saved-card prompt), so we hand off rather than
94
128
  * try to automate the money step. Includes a basket summary for the LLM.
95
129
  */
96
- export async function getCheckoutLink() {
97
- const shoppingListId = await resolveShoppingListId();
130
+ export async function getCheckoutLink(args = {}) {
131
+ const shoppingListId = await resolveShoppingListId(args.shoppingListId);
98
132
  const data = (await api("GET", `/shopping-list/public/v2/list/details?shoppingListId=${shoppingListId}`, undefined, { creds: credsFromEnv() }));
99
133
  const items = (data.categories ?? []).flatMap((c) => c.items ?? []);
100
134
  if (items.length === 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"cart.js","sourceRoot":"","sources":["../../src/auth-tools/cart.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cart.js","sourceRoot":"","sources":["../../src/auth-tools/cart.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@
4
4
  * keep each file focused and easy to scan.
5
5
  */
6
6
  export { getProfile, getAddresses } from "./auth-tools/account.js";
7
- export { getBasket, addToBasket, updateBasketQuantity, removeFromBasket, getCheckoutLink, } from "./auth-tools/cart.js";
7
+ export { authenticate } from "./auth-tools/authenticate.js";
8
+ export { getShoppingLists, getBasket, addToBasket, updateBasketQuantity, removeFromBasket, getCheckoutLink, } from "./auth-tools/cart.js";
8
9
  export { getOrders, getOrderDetails } from "./auth-tools/orders.js";
9
10
  export { getCumulusStatus, getInStoreReceipts, getReceiptDetails, getCumulusCoupons, } from "./auth-tools/cumulus.js";
@@ -4,7 +4,8 @@
4
4
  * keep each file focused and easy to scan.
5
5
  */
6
6
  export { getProfile, getAddresses } from "./auth-tools/account.js";
7
- export { getBasket, addToBasket, updateBasketQuantity, removeFromBasket, getCheckoutLink, } from "./auth-tools/cart.js";
7
+ export { authenticate } from "./auth-tools/authenticate.js";
8
+ export { getShoppingLists, getBasket, addToBasket, updateBasketQuantity, removeFromBasket, getCheckoutLink, } from "./auth-tools/cart.js";
8
9
  export { getOrders, getOrderDetails } from "./auth-tools/orders.js";
9
10
  export { getCumulusStatus, getInStoreReceipts, getReceiptDetails, getCumulusCoupons, } from "./auth-tools/cumulus.js";
10
11
  //# sourceMappingURL=auth-tools.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-tools.js","sourceRoot":"","sources":["../src/auth-tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EACL,SAAS,EACT,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"auth-tools.js","sourceRoot":"","sources":["../src/auth-tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC"}
package/dist/index.d.ts CHANGED
File without changes
package/dist/index.js CHANGED
@@ -2,13 +2,13 @@
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
4
  import { register } from "./register.js";
5
- import { SearchProductsSchema, GetProductDetailsSchema, GetStockSchema, SearchStoresSchema, GetPromotionsSchema, SearchRecipesSchema, GetRecipeDetailsSchema, GetRecipeProductsSchema, GetBasketSchema, AddToBasketSchema, UpdateBasketQuantitySchema, RemoveFromBasketSchema, GetOrdersSchema, GetOrderDetailsSchema, GetInStoreReceiptsSchema, GetReceiptDetailsSchema, } from "./schemas.js";
5
+ import { SearchProductsSchema, GetProductDetailsSchema, GetStockSchema, SearchStoresSchema, GetPromotionsSchema, SearchRecipesSchema, GetRecipeDetailsSchema, GetRecipeProductsSchema, AuthenticateSchema, GetBasketSchema, GetCheckoutLinkSchema, AddToBasketSchema, UpdateBasketQuantitySchema, RemoveFromBasketSchema, GetOrdersSchema, GetOrderDetailsSchema, GetInStoreReceiptsSchema, GetReceiptDetailsSchema, } from "./schemas.js";
6
6
  import { searchProducts, getProductDetails, getStock, getCategories, searchStores, getPromotions, searchRecipes, getRecipeDetails, getRecipeProducts, } from "./tools.js";
7
- import { getProfile, getBasket, addToBasket, updateBasketQuantity, removeFromBasket, getAddresses, getOrders, getOrderDetails, getCheckoutLink, getCumulusStatus, getInStoreReceipts, getReceiptDetails, getCumulusCoupons, } from "./auth-tools.js";
7
+ import { authenticate, getProfile, getShoppingLists, getBasket, addToBasket, updateBasketQuantity, removeFromBasket, getAddresses, getOrders, getOrderDetails, getCheckoutLink, getCumulusStatus, getInStoreReceipts, getReceiptDetails, getCumulusCoupons, } from "./auth-tools.js";
8
8
  // ---------------------------------------------------------------------------
9
9
  // Server + tool registrations
10
10
  // ---------------------------------------------------------------------------
11
- const server = new McpServer({ name: "migros-mcp", version: "0.3.0" });
11
+ const server = new McpServer({ name: "migros-mcp", version: "0.4.0" });
12
12
  // --- Anonymous: search & browse ---
13
13
  register(server, "search_products", "Search Migros products by name or keyword. Returns product IDs that can be used with get_product_details.", SearchProductsSchema.shape, ({ query, language }) => searchProducts(query, language ?? "de"));
14
14
  register(server, "get_product_details", "Get full product details including nutrition facts, ingredients, allergens, price, and ratings. Use search_products first to get product IDs.", GetProductDetailsSchema.shape, ({ productIds }) => getProductDetails(productIds));
@@ -21,17 +21,19 @@ register(server, "search_recipes", "Search Migusto (Migros' recipe site) by free
21
21
  register(server, "get_recipe_details", "Fetch a full Migusto recipe by slug: ingredients with quantities, step-by-step instructions, photos, nutrition. Use search_recipes first to find the slug. (Migusto is Migros' recipe site at migusto.migros.ch.)", GetRecipeDetailsSchema.shape, (args) => getRecipeDetails(args));
22
22
  register(server, "get_recipe_products", "Fetch the Migros products needed for a Migusto recipe — returns product UIDs you can pass directly to add_to_basket. Bridges recipes to shopping. Use the recipe ID from search_recipes (NOT the slug).", GetRecipeProductsSchema.shape, (args) => getRecipeProducts(args));
23
23
  // --- Authenticated: account ---
24
+ register(server, "authenticate", "Log in to Migros with the current six-digit 2FA code from the user's authenticator app (ask the user for it, or read it from a password manager you have access to). Only needed when an authenticated tool reports fresh_code_required, which happens when no TOTP secret is configured. Omit totpCode to reuse a cached session, or if the account has no 2FA. The code is never stored or returned.", AuthenticateSchema.shape, (args) => authenticate(args));
24
25
  register(server, "get_profile", "Get the logged-in customer's basic profile (name, email, language, cooperative). Requires authentication.", {}, () => getProfile());
25
26
  register(server, "get_addresses", "Get the user's saved delivery and billing addresses. Requires authentication.", {}, () => getAddresses());
26
27
  // --- Authenticated: cart ---
27
- register(server, "get_basket", "Fetch the items currently in the user's shopping basket (Migros calls this a shopping list). Returns product IDs and quantities; use get_product_details to enrich. Requires authentication.", GetBasketSchema.shape, (args) => getBasket(args));
28
+ register(server, "get_shopping_lists", "List the user's Migros shopping lists (id and name). Call this when the user mentions a specific list or has several: pass the chosen shoppingListId to the basket tools. Requires authentication.", {}, () => getShoppingLists());
29
+ register(server, "get_basket", "Fetch the items currently in the user's shopping basket (Migros calls this a shopping list). Returns product IDs and quantities; use get_product_details to enrich. If the user has several lists, use get_shopping_lists and pass shoppingListId. Requires authentication.", GetBasketSchema.shape, (args) => getBasket(args));
28
30
  register(server, "add_to_basket", "Add a product to the user's basket (or set its quantity if already present). The underlying API is upsert-to-target, not increment. Returns the updated basket. Requires authentication.", AddToBasketSchema.shape, (args) => addToBasket(args));
29
31
  register(server, "update_basket_quantity", "Set an item's exact quantity in the basket. quantity=0 removes the item. Returns the updated basket. Requires authentication.", UpdateBasketQuantitySchema.shape, (args) => updateBasketQuantity(args));
30
32
  register(server, "remove_from_basket", "Remove a product from the user's basket. Returns the updated basket. Requires authentication.", RemoveFromBasketSchema.shape, (args) => removeFromBasket(args));
31
33
  // --- Authenticated: orders ---
32
34
  register(server, "get_orders", "List the user's online orders, paginated, filtered by status. Use to find an order id, then call get_order_details. Requires authentication.", GetOrdersSchema.shape, (args) => getOrders(args));
33
35
  register(server, "get_order_details", "Fetch the full details of a single order by id. Requires authentication.", GetOrderDetailsSchema.shape, (args) => getOrderDetails(args));
34
- register(server, "get_checkout_link", "Return the URL the user should open in their browser to complete checkout (review basket, confirm address/slot, pay). Order placement requires payment confirmation in a real browser, so this tool hands off rather than firing the order automatically. Returns a basket summary alongside the URL. Requires authentication.", {}, () => getCheckoutLink());
36
+ register(server, "get_checkout_link", "Return the URL the user should open in their browser to complete checkout (review basket, confirm address/slot, pay). Order placement requires payment confirmation in a real browser, so this tool hands off rather than firing the order automatically. Returns a basket summary alongside the URL. Requires authentication.", GetCheckoutLinkSchema.shape, (args) => getCheckoutLink(args));
35
37
  // --- Authenticated: Cumulus / in-store ---
36
38
  register(server, "get_cumulus_status", "Get the user's Cumulus loyalty card status: points balance, level, cardholder, lifetime stats. Requires authentication.", {}, () => getCumulusStatus());
37
39
  register(server, "get_in_store_receipts", "List the user's in-store Migros receipts (Kassenbons) over a date range. Default: last 30 days. Use get_receipt_details with an id for line items. Requires authentication.", GetInStoreReceiptsSchema.shape, (args) => getInStoreReceipts(args));
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/migros.d.ts CHANGED
File without changes
package/dist/migros.js CHANGED
File without changes
File without changes