albert-heijn-mcp 1.5.0 β†’ 1.6.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 (2) hide show
  1. package/README.md +171 -114
  2. package/package.json +2 -1
package/README.md CHANGED
@@ -9,7 +9,9 @@
9
9
 
10
10
  **Your Albert Heijn account, in your AI assistant.**
11
11
 
12
- albert-heijn-mcp is a [Model Context Protocol](https://modelcontextprotocol.io) server for Albert Heijn πŸ‡³πŸ‡±. Connect it to any MCP client and just ask: find products and bonus deals, plan meals from Allerhande recipes, keep your shopping list and delivery order up to date, and look back at what you've bought.
12
+ Connect your Albert Heijn account to an AI assistant such as Claude, ChatGPT or Cursor, and do your grocery shopping by just asking. Find products and bonus deals, plan meals from Allerhande recipes, keep your shopping list and delivery order up to date, and look back at what you've bought.
13
+
14
+ Technically, it's a [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server for Albert Heijn πŸ‡³πŸ‡±. MCP is the standard way AI apps connect to other services, so it works with any app that supports MCP.
13
15
 
14
16
  > [!NOTE]
15
17
  > An unofficial project, not affiliated with or endorsed by Albert Heijn. It uses the same API as the AH mobile app, which may change without notice.
@@ -18,15 +20,18 @@ albert-heijn-mcp is a [Model Context Protocol](https://modelcontextprotocol.io)
18
20
 
19
21
  ## Contents
20
22
 
23
+ **For everyone**
24
+
21
25
  - [What you can ask](#what-you-can-ask)
22
- - [Quick start](#quick-start)
23
- - [Logging in](#logging-in)
24
- - [Connecting a client](#connecting-a-client)
26
+ - [Getting started](#getting-started): [connect your app](#connecting-a-client), then [log in](#logging-in)
27
+ - [Troubleshooting](#troubleshooting)
28
+
29
+ **Technical details**
30
+
31
+ - [Running it on a server](#running-it-on-a-server) for ChatGPT and Claude.ai
25
32
  - [Configuration](#configuration)
26
- - [Deploying to a server](#deploying-to-a-server)
27
33
  - [Tools](#tools) and [limitations](#limitations)
28
34
  - [Development](#development)
29
- - [Troubleshooting](#troubleshooting)
30
35
 
31
36
  ## What you can ask
32
37
 
@@ -76,48 +81,51 @@ Ask in Dutch, English or any language your assistant speaks:
76
81
 
77
82
  > *"Show the receipt from my last shop and list anything I bought more than once."*
78
83
 
79
- ## Quick start
84
+ ## Getting started
80
85
 
81
- **Requirements:** Node.js 24 (LTS) and an Albert Heijn account.
86
+ You need an Albert Heijn account. Then:
82
87
 
83
- There's nothing to install: [connect a client](#connecting-a-client) with `npx -y albert-heijn-mcp`, which downloads and runs the [latest version](https://www.npmjs.com/package/albert-heijn-mcp), then ask it to log you in to Albert Heijn.
88
+ 1. **[Connect your app](#connecting-a-client)**: pick yours below.
89
+ 2. **[Log in to Albert Heijn](#logging-in)**: ask your assistant to log you in, once.
90
+ 3. **Ask away.** See [what you can ask](#what-you-can-ask).
84
91
 
85
- To install it permanently instead, run `npm install --global albert-heijn-mcp` and use the `albert-heijn-mcp` command. To [build from source](#development), clone the repository.
92
+ ## Connecting a client
86
93
 
87
- ## Logging in
94
+ | Your app | How |
95
+ |---|---|
96
+ | **Claude Desktop** | [Download and double-click](#claude-desktop). Easiest; nothing else to install. |
97
+ | **Cursor**, **VS Code** | [One-click install button](#cursor-and-vs-code) |
98
+ | **ChatGPT**, **Claude.ai** (web and mobile) | [Needs your own server](#chatgpt-and-claudeai) (technical) |
99
+ | **Other apps** | [Add a command to the app's settings](#other-apps) |
88
100
 
89
- AH's login page has a captcha that only works on AH's own site, so logging in takes two steps:
101
+ ### Claude Desktop
90
102
 
91
- 1. **Ask your assistant to log you in.** It calls `ah_login` and gives you a link to AH's login page; locally, it also opens in your browser. Log in as usual.
92
- 2. **Paste the code back.** After you log in, AH redirects to a link meant for its iPhone app, which the browser can't open, so the page stays put. Open the developer console (Chrome: <kbd>⌘</kbd> <kbd>βŒ₯</kbd> <kbd>J</kbd> on Mac, <kbd>Ctrl</kbd> <kbd>Shift</kbd> <kbd>J</kbd> on Windows/Linux) and find this line:
103
+ 1. Download [`albert-heijn-mcp.mcpb`](https://github.com/olekpuchka/albert-heijn-mcp/releases/latest/download/albert-heijn-mcp.mcpb).
104
+ 2. Double-click it and choose **Install**. If it doesn't open in Claude, go to Settings β†’ Extensions β†’ Advanced settings β†’ Install Extension… and pick the file.
93
105
 
94
- ```
95
- Failed to launch 'appie://login-exit?code=…' because the scheme does not have a registered handler.
96
- ```
106
+ That's it: the file contains everything it needs. To update, do the same with the file from the newest release.
97
107
 
98
- Copy the `appie://login-exit?code=…` link into the chat. The code works once and expires quickly, so paste it right away.
108
+ Other desktop apps that support [MCP Bundles](https://github.com/modelcontextprotocol/mcpb) (`.mcpb` files) install it the same way.
99
109
 
100
- You only log in once. Tokens are stored on your machine and refreshed automatically:
110
+ ### Cursor and VS Code
101
111
 
102
- | OS | Location |
103
- |---|---|
104
- | macOS | `~/Library/Application Support/albert-heijn-mcp/tokens.json` |
105
- | Linux | `~/.config/albert-heijn-mcp/tokens.json` |
106
- | Windows | `%AppData%\albert-heijn-mcp\tokens.json` |
112
+ Install [Node.js 24 (LTS)](https://nodejs.org) first, then click:
107
113
 
108
- The file is readable only by your user. Override the location with `AH_TOKENS_PATH`.
114
+ [![Install in Cursor](https://img.shields.io/badge/Cursor-Install_server-000000?logo=cursor&logoColor=white)](https://cursor.com/en/install-mcp?name=ah&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImFsYmVydC1oZWlqbi1tY3AiXX0%3D)
115
+ [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_server-0098FF)](https://insiders.vscode.dev/redirect/mcp/install?name=ah&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22albert-heijn-mcp%22%5D%7D)
109
116
 
110
- ## Connecting a client
117
+ ### ChatGPT and Claude.ai
111
118
 
112
- albert-heijn-mcp works with any MCP client. It runs locally over stdio, or on a server over Streamable HTTP.
119
+ Web and mobile apps can't run anything on your computer; they only connect to servers on the internet. So you first need to [run it on a server](#running-it-on-a-server), which takes some technical know-how. Then add it as a connector:
113
120
 
114
- ### Local clients (stdio)
121
+ - **ChatGPT** needs Developer mode (Plus, Pro, Business, Enterprise and Education). Open Settings β†’ advanced settings, turn on Developer mode, and create a connector with `https://your-server/mcp`. Set authentication to **OAuth**.
122
+ - **Claude.ai**: Settings β†’ Connectors β†’ Add custom connector, paste `https://your-server/mcp` and choose Connect.
115
123
 
116
- Install it in one click:
124
+ The app then opens a login page on your server: enter your `AH_MCP_TOKEN` there, once.
117
125
 
118
- [![Install in Cursor](https://img.shields.io/badge/Cursor-Install_server-000000?logo=cursor&logoColor=white)](https://cursor.com/en/install-mcp?name=ah&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImFsYmVydC1oZWlqbi1tY3AiXX0%3D)
119
- [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_server-0098FF)](https://insiders.vscode.dev/redirect/mcp/install?name=ah&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22albert-heijn-mcp%22%5D%7D)
120
- Other clients that start MCP servers as a local command run `npx -y albert-heijn-mcp`. Most of them take this JSON in their MCP settings:
126
+ ### Other apps
127
+
128
+ Apps that start MCP servers as a local command need [Node.js 24 (LTS)](https://nodejs.org) and run `npx -y albert-heijn-mcp`, which downloads and runs the [latest version](https://www.npmjs.com/package/albert-heijn-mcp). Most of them take this JSON in their MCP settings:
121
129
 
122
130
  ```json
123
131
  {
@@ -130,49 +138,118 @@ Other clients that start MCP servers as a local command run `npx -y albert-heijn
130
138
  }
131
139
  ```
132
140
 
133
- Where the settings live differs per client; see its documentation. Clients with a CLI usually have an add command instead, e.g. `<client> mcp add ah -- npx -y albert-heijn-mcp`. It is also listed in the [MCP Registry](https://registry.modelcontextprotocol.io), which some clients install from.
141
+ Where the settings live differs per app; see its documentation. Apps with a command line usually have an add command instead, e.g. `<client> mcp add ah -- npx -y albert-heijn-mcp`. It is also listed in the [MCP Registry](https://registry.modelcontextprotocol.io), which some apps install from.
142
+
143
+ To install it permanently instead, run `npm install --global albert-heijn-mcp` and use the `albert-heijn-mcp` command; run the same command again to update.
134
144
 
135
145
  > [!TIP]
136
- > Desktop apps don't load your shell profile, so they may not find `npx` (common with nvm). Then set `command` to the output of `which npx`. For a source checkout, use `node` with the argument `/path/to/albert-heijn-mcp/dist/index.js`.
146
+ > Desktop apps don't load your shell profile, so they may not find `npx` (common with nvm). Then set `command` to the output of `which npx`.
137
147
 
138
- ### Remote clients (Streamable HTTP)
148
+ ## Logging in
139
149
 
140
- Web apps such as ChatGPT and Claude.ai only connect to servers on the internet. Set one up first ([Deploying to a server](#deploying-to-a-server)). The endpoint is `https://your-server/mcp`.
150
+ AH's login page has a captcha that only works on AH's own website, so logging in takes two steps. You only do this once.
141
151
 
142
- Clients log in with OAuth: add the endpoint with OAuth (or automatic) authentication, and the client opens a login page on your server. Enter your `AH_MCP_TOKEN` there once; the client then gets its own tokens and renews them. The server accepts only these OAuth tokens, not `AH_MCP_TOKEN` itself, so clients without OAuth support can't connect over HTTP; run them locally over [stdio](#local-clients-stdio) instead.
152
+ 1. **Ask your assistant to log you in.** It gives you a link to AH's login page, and on your own computer it also opens it in your browser. Log in as usual.
153
+ 2. **Copy the code back into the chat.** After you log in, AH tries to open its phone app, which your browser can't do, so the page seems stuck. The code you need is in the browser's developer console, a panel for web developers that you can open safely:
154
+ - Open it in Chrome with <kbd>⌘</kbd> <kbd>βŒ₯</kbd> <kbd>J</kbd> on Mac, or <kbd>Ctrl</kbd> <kbd>Shift</kbd> <kbd>J</kbd> on Windows and Linux.
155
+ - Find this red line:
143
156
 
144
- **ChatGPT**: needs Developer mode (Plus, Pro, Business, Enterprise and Education). Open Settings β†’ advanced settings, turn on Developer mode, and create a connector with the endpoint. Set authentication to **OAuth**.
157
+ ```
158
+ Failed to launch 'appie://login-exit?code=…' because the scheme does not have a registered handler.
159
+ ```
145
160
 
146
- **Claude.ai**: Settings β†’ Connectors β†’ Add custom connector, then paste the endpoint and choose Connect.
161
+ - Copy the part from `appie://` up to the closing quote and paste it into the chat. The code works once and expires quickly, so paste it right away.
147
162
 
148
- > [!IMPORTANT]
149
- > Anyone with `AH_MCP_TOKEN` can log in and use your Albert Heijn account. Use a long random value (`openssl rand -hex 32`). Changing it logs out every client.
163
+ No line there? See [Troubleshooting](#troubleshooting).
150
164
 
151
- ## Configuration
165
+ <details>
166
+ <summary><b>Where your login is stored</b></summary>
152
167
 
153
- Settings are environment variables. They can also go in a `.env` file in the working directory (see [`.env.example`](.env.example)); variables already set in the environment take precedence.
168
+ Your login is saved on your own computer and renewed automatically, in a file only your user can read:
154
169
 
155
- | Variable | Default | Description |
156
- |---|---|---|
157
- | `AH_REMOTE` | `false` | Don't open a browser on login (same as `--remote`). Always on with `streamable-http`. |
158
- | `AH_TOKENS_PATH` | [per OS](#logging-in) | Where to store login tokens. |
159
- | `AH_MCP_HOST` | `127.0.0.1` | Interface the HTTP server listens on. Keep the default behind a reverse proxy. |
160
- | `AH_MCP_PORT` | `3000` | HTTP server port. |
161
- | `AH_MCP_BASE_URL` | `http://localhost:3000` | Public URL of the HTTP server. Set it on a server: OAuth clients are sent to this URL to log in, and for a non-local URL the localhost-only `Host` check is turned off so a reverse proxy can forward requests. |
162
- | `AH_MCP_TOKEN` | β€” | Secret for the HTTP transport, at least 32 characters; the transport doesn't start without it. You enter it on the OAuth login page; it also signs the OAuth tokens. |
163
- | `AH_LOG_FILE` | β€” | Also append logs to this file. Logs always go to stderr. |
170
+ | OS | Location |
171
+ |---|---|
172
+ | macOS | `~/Library/Application Support/albert-heijn-mcp/tokens.json` |
173
+ | Linux | `~/.config/albert-heijn-mcp/tokens.json` (or under `$XDG_CONFIG_HOME`) |
174
+ | Windows | `%AppData%\albert-heijn-mcp\tokens.json` |
164
175
 
165
- Command-line flags:
176
+ Override the location with `AH_TOKENS_PATH`.
177
+ </details>
166
178
 
167
- ```
168
- node dist/index.js [--transport stdio|streamable-http] [--remote] [--version] [--help]
169
- ```
179
+ ## Troubleshooting
170
180
 
171
- `stdio` (the default) is for local clients; `streamable-http` serves MCP at `/mcp`, with OAuth login at `/authorize`.
181
+ <details>
182
+ <summary><b>No "Failed to launch" line after logging in</b></summary>
183
+
184
+ Open the developer console before you submit the login form, or look for the `appie://login-exit?code=…` request in the Network tab. Browsers other than Chrome may show the link in an error page or dialog instead.
185
+ </details>
186
+
187
+ <details>
188
+ <summary><b>Login fails with "exchange code"</b></summary>
189
+
190
+ Codes work once and expire quickly. Ask to log in again and paste the new link straight away.
191
+ </details>
192
+
193
+ <details>
194
+ <summary><b>"Not logged in", or the session seems broken</b></summary>
195
+
196
+ Ask your assistant to log you out and back in, or delete `tokens.json` from the [login location](#logging-in) and log in again.
197
+ </details>
198
+
199
+ <details>
200
+ <summary><b>"Already connected as …" when pasting a login code</b></summary>
201
+
202
+ A code never replaces a working login, so a code from someone else's account can't switch you over. To switch accounts, ask to log out first, then log in again.
203
+ </details>
204
+
205
+ <details>
206
+ <summary><b>"There is no active delivery order to change"</b></summary>
207
+
208
+ AH accepts order changes only once an order exists. Choose a delivery slot in the AH app or on ah.nl first.
209
+ </details>
210
+
211
+ <details>
212
+ <summary><b>"The shopping list is not available while a delivery order is active"</b></summary>
213
+
214
+ Choosing a slot moved your list into the order. Ask your assistant to change the order instead (`ah_get_cart`, `ah_update_cart_item`) until it is delivered or cancelled.
215
+ </details>
216
+
217
+ <details>
218
+ <summary><b>The server doesn't start: "needs AH_MCP_TOKEN of at least 32 characters"</b></summary>
219
+
220
+ Set `AH_MCP_TOKEN` to a long random value, e.g. the output of `openssl rand -hex 32`, and restart. Changing it logs out every client; reconnect them once.
221
+ </details>
222
+
223
+ <details>
224
+ <summary><b>Server login page shows "This login link is not valid"</b></summary>
225
+
226
+ Start connecting again from the app. If it keeps happening right after you enter the token, check that `AH_MCP_BASE_URL` is exactly the address in your browser, including `https://`: the login form is only accepted from that address.
227
+ </details>
228
+
229
+ <details>
230
+ <summary><b>Server login opens at localhost, or the app can't reach it</b></summary>
231
+
232
+ Set `AH_MCP_BASE_URL` to the server's public `https://` URL and restart it. Apps are sent there to log in.
233
+ </details>
234
+
235
+ <details>
236
+ <summary><b>Port 3000 is in use</b></summary>
237
+
238
+ Set `AH_MCP_PORT` to another port, in the environment or `.env`.
239
+ </details>
172
240
 
173
- ## Deploying to a server
241
+ ---
242
+
243
+ ## Running it on a server
244
+
245
+ Web and mobile apps such as ChatGPT and Claude.ai need the server on the internet, over Streamable HTTP with HTTPS. The endpoint is `https://your-server/mcp`.
174
246
 
175
- albert-heijn-mcp runs as a hardened systemd service behind a reverse proxy, installed from npm.
247
+ Apps log in with OAuth: add the endpoint with OAuth (or automatic) authentication, and the app opens a login page on your server. Enter your `AH_MCP_TOKEN` there once; the app then gets its own tokens and renews them. The server accepts only these OAuth tokens, not `AH_MCP_TOKEN` itself, so apps without OAuth support can't connect over HTTP; run them [locally](#other-apps) instead.
248
+
249
+ > [!IMPORTANT]
250
+ > Anyone with `AH_MCP_TOKEN` can log in and use your Albert Heijn account. Use a long random value (`openssl rand -hex 32`). Changing it logs out every client.
251
+
252
+ It runs as a hardened systemd service behind a reverse proxy, installed from npm:
176
253
 
177
254
  1. **Prepare the server.** Install Node.js 24 and create a service user:
178
255
 
@@ -210,13 +287,35 @@ albert-heijn-mcp runs as a hardened systemd service behind a reverse proxy, inst
210
287
 
211
288
  The service can write only to `/home/albert-heijn-mcp`, where it keeps its tokens. If you point `AH_LOG_FILE` elsewhere, add that path to `ReadWritePaths` in the unit file.
212
289
 
290
+ ## Configuration
291
+
292
+ Settings are environment variables. They can also go in a `.env` file in the working directory (see [`.env.example`](.env.example)); variables already set in the environment take precedence.
293
+
294
+ | Variable | Default | Description |
295
+ |---|---|---|
296
+ | `AH_REMOTE` | `false` | Don't open a browser on login (same as `--remote`). Always on with `streamable-http`. |
297
+ | `AH_TOKENS_PATH` | [per OS](#logging-in) | Where to store login tokens. |
298
+ | `AH_MCP_HOST` | `127.0.0.1` | Interface the HTTP server listens on. Keep the default behind a reverse proxy. |
299
+ | `AH_MCP_PORT` | `3000` | HTTP server port. |
300
+ | `AH_MCP_BASE_URL` | `http://localhost:3000` | Public URL of the HTTP server. Set it on a server: OAuth clients are sent to this URL to log in, and for a non-local URL the localhost-only `Host` check is turned off so a reverse proxy can forward requests. |
301
+ | `AH_MCP_TOKEN` | β€” | Secret for the HTTP transport, at least 32 characters; the transport doesn't start without it. You enter it on the OAuth login page; it also signs the OAuth tokens. |
302
+ | `AH_LOG_FILE` | β€” | Also append logs to this file. Logs always go to stderr. |
303
+
304
+ Command-line flags:
305
+
306
+ ```
307
+ node dist/index.js [--transport stdio|streamable-http] [--remote] [--version] [--help]
308
+ ```
309
+
310
+ `stdio` (the default) is for local clients; `streamable-http` serves MCP at `/mcp`, with OAuth login at `/authorize`.
311
+
213
312
  ## Tools
214
313
 
215
- Read-only tools are marked as such, so clients can run them without asking. Tools that remove data are marked destructive, so clients ask for confirmation first.
314
+ These are what your assistant uses behind the scenes; you don't call them yourself. Read-only tools are marked as such, so apps can run them without asking. Tools that remove data are marked destructive, so apps ask for confirmation first.
216
315
 
217
316
  Tools that return data also return it as [structured output](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#structured-content) with a declared schema, for clients that use it. Products and recipes in tool results include a `url` to their page on ah.nl, and the server asks the assistant to link their names to it.
218
317
 
219
- <details open>
318
+ <details>
220
319
  <summary><b>Account</b></summary>
221
320
 
222
321
  | Tool | Description |
@@ -227,7 +326,7 @@ Tools that return data also return it as [structured output](https://modelcontex
227
326
 
228
327
  </details>
229
328
 
230
- <details open>
329
+ <details>
231
330
  <summary><b>Products & offers</b></summary>
232
331
 
233
332
  | Tool | Description |
@@ -242,18 +341,18 @@ Tools that return data also return it as [structured output](https://modelcontex
242
341
 
243
342
  </details>
244
343
 
245
- <details open>
344
+ <details>
246
345
  <summary><b>Recipes</b></summary>
247
346
 
248
347
  | Tool | Description |
249
348
  |---|---|
250
349
  | `ah_search_recipes` | Search Allerhande recipes; Dutch terms work best. |
251
350
  | `ah_get_recipe` | Ingredients, steps, and nutrition per serving. `servings` scales the ingredients. |
252
- | `ah_add_recipe_to_shopping_list` | Match a recipe's ingredients to products and add them to the list in one step. `skip` leaves out what you have; `dry_run=true` previews the matches. |
351
+ | `ah_add_recipe_to_shopping_list` | Match a recipe's ingredients to products and add them to the list in one step. It prefers products on bonus (`prefer_bonus=false` turns that off); `skip` leaves out what you have, and `dry_run=true` previews the matches. |
253
352
 
254
353
  </details>
255
354
 
256
- <details open>
355
+ <details>
257
356
  <summary><b>Shopping list & favourites</b></summary>
258
357
 
259
358
  | Tool | Description |
@@ -271,7 +370,7 @@ Tools that return data also return it as [structured output](https://modelcontex
271
370
 
272
371
  </details>
273
372
 
274
- <details open>
373
+ <details>
275
374
  <summary><b>Delivery order</b></summary>
276
375
 
277
376
  Choosing a delivery or pick-up slot in the AH app moves your shopping list into an order. `ah_get_delivery_slots` shows when delivery is possible; the other tools work on that order.
@@ -286,7 +385,7 @@ Choosing a delivery or pick-up slot in the AH app moves your shopping list into
286
385
 
287
386
  </details>
288
387
 
289
- <details open>
388
+ <details>
290
389
  <summary><b>Orders & receipts</b></summary>
291
390
 
292
391
  | Tool | Description |
@@ -304,6 +403,7 @@ Choosing a delivery or pick-up slot in the AH app moves your shopping list into
304
403
  - **Delivery orders can't be started through the API.** `ah_get_delivery_slots` lists the windows, but booking one, which starts the order, happens in the AH app or on ah.nl. While the order is active, AH doesn't serve the shopping list; the tools say so and point to the order tools.
305
404
  - **Ticking off shopping-list items isn't supported:** the API returns no usable item IDs.
306
405
  - **Bonus Box**, AH's personal weekly deals, is not available: its API is unknown.
406
+ - **Limits per call:** at most 99 of a product, 50 items, and 100 characters for a free-text item or list name.
307
407
 
308
408
  ## Development
309
409
 
@@ -322,11 +422,12 @@ Run it from the checkout with `node dist/index.js`, or use `/path/to/albert-heij
322
422
  | [`src/index.ts`](src/index.ts), [`src/config.ts`](src/config.ts) | Entry point, flags and settings |
323
423
  | [`src/ahapi/`](src/ahapi) | Client for AH's REST and GraphQL API, on Node's built-in `fetch` |
324
424
  | [`src/auth/`](src/auth) | Login code exchange, token storage and refresh |
325
- | [`src/server/`](src/server) | Streamable HTTP transport and token check |
425
+ | [`src/server/`](src/server) | Streamable HTTP transport and OAuth login |
326
426
  | [`src/tools/`](src/tools) | The MCP tools, one file per area |
327
427
  | [`deploy/`](deploy) | systemd unit, shipped in the package |
428
+ | [`manifest.json`](manifest.json), [`.mcpbignore`](.mcpbignore) | Manifest of the `.mcpb` bundle, and the files it leaves out |
328
429
  | [`listing/`](listing) | Name, descriptions and icon to use in connector settings and app directories ([how](listing/README.md)) |
329
- | [`.github/`](.github) | CI, release workflow and Dependabot |
430
+ | [`.github/`](.github) | CI, release workflow, Dependabot and the pinned `mcp-publisher` install |
330
431
  | [`assets/`](assets) | Logo for this README and the server icon shown by MCP clients |
331
432
 
332
433
  The only runtime dependencies are the official [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) and Zod, which the SDK uses for tool schemas.
@@ -339,51 +440,7 @@ npx @modelcontextprotocol/inspector node dist/index.js
339
440
 
340
441
  Before deploying a change, run a quick check against a real account: log in, search for `melk`, add a product to your shopping list and remove it again, then view your cart and orders.
341
442
 
342
- To release, set the new version in `package.json` and in both places in [`server.json`](server.json), merge it to `main`, and push a tag: `git tag v1.2.3 && git push origin v1.2.3`. The [release workflow](.github/workflows/release.yml) checks that the versions match, builds the package, attaches it to the GitHub release as `albert-heijn-mcp.tgz`, and stages it on npm through [trusted publishing](https://docs.npmjs.com/trusted-publishers), so no npm token is stored. Approve the staged version on npmjs.com (or with `npm stage approve`) to make it live; the workflow then updates the [MCP Registry](https://registry.modelcontextprotocol.io) entry.
343
-
344
- ## Troubleshooting
345
-
346
- <details>
347
- <summary><b>Login fails with "exchange code"</b></summary>
348
-
349
- Codes work once and expire quickly. Ask to log in again and paste the new link straight away.
350
- </details>
351
-
352
- <details>
353
- <summary><b>No "Failed to launch" line after logging in</b></summary>
354
-
355
- Open the developer console before you submit the login form, or look for the `appie://login-exit?code=…` request in the Network tab. Browsers other than Chrome may show the link in an error page or dialog instead.
356
- </details>
357
-
358
- <details>
359
- <summary><b>"Not logged in", or the session seems broken</b></summary>
360
-
361
- Log out and back in through the assistant, or delete `tokens.json` from the [token location](#logging-in) and log in again.
362
- </details>
363
-
364
- <details>
365
- <summary><b>"There is no active delivery order to change"</b></summary>
366
-
367
- AH accepts order changes only once an order exists. Choose a delivery slot in the AH app or on ah.nl first.
368
- </details>
369
-
370
- <details>
371
- <summary><b>"The shopping list is not available while a delivery order is active"</b></summary>
372
-
373
- Choosing a slot moved your list into the order. Use `ah_get_cart` and `ah_update_cart_item` until the order is delivered or cancelled.
374
- </details>
375
-
376
- <details>
377
- <summary><b>OAuth login opens at localhost, or the client can't reach it</b></summary>
378
-
379
- Set `AH_MCP_BASE_URL` to the server's public `https://` URL and restart it. Clients are sent there to log in.
380
- </details>
381
-
382
- <details>
383
- <summary><b>Port 3000 is in use</b></summary>
384
-
385
- Set `AH_MCP_PORT` to another port, in the environment or `.env`.
386
- </details>
443
+ To release, set the new version with `npm version 1.2.3 --no-git-tag-version` and in both places in [`server.json`](server.json) and in [`manifest.json`](manifest.json), merge it to `main`, and push a tag: `git tag v1.2.3 && git push origin v1.2.3`. Only repository admins can create `v*` tags. The [release workflow](.github/workflows/release.yml) checks that the versions match, builds the package, attaches it to the GitHub release as `albert-heijn-mcp.tgz` together with the `albert-heijn-mcp.mcpb` bundle, and stages the package on npm through [trusted publishing](https://docs.npmjs.com/trusted-publishers), so no npm token is stored. Approve the staged version on npmjs.com (or with `npm stage approve`) to make it live; the workflow then updates the [MCP Registry](https://registry.modelcontextprotocol.io) entry. The release starts without notes; write them on GitHub.
387
444
 
388
445
  ## License
389
446
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "albert-heijn-mcp",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Unofficial MCP server for Albert Heijn: products, bonus deals, Allerhande recipes, your shopping list and orders in any AI assistant",
5
5
  "keywords": [
6
6
  "mcp",
@@ -47,6 +47,7 @@
47
47
  "zod": "^4.6.5"
48
48
  },
49
49
  "devDependencies": {
50
+ "@anthropic-ai/mcpb": "^2.1.2",
50
51
  "@types/node": "^24.19.1",
51
52
  "typescript": "^7.0.2"
52
53
  }