untappd-mcp 2.4.0 → 2.5.1

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 Untappd — beers, breweries, venues, check-ins, wishlists, and your friend feed",
10
- "version": "2.4.0"
10
+ "version": "2.5.1"
11
11
  },
12
12
  "plugins": [
13
13
  {
@@ -15,7 +15,7 @@
15
15
  "displayName": "Untappd",
16
16
  "source": "./",
17
17
  "description": "MCP server for Untappd — search beers/breweries/venues, read profiles/check-ins/wishlists, and post check-ins, toasts, and comments",
18
- "version": "2.4.0",
18
+ "version": "2.5.1",
19
19
  "author": {
20
20
  "name": "Chris Hall"
21
21
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "untappd-mcp",
3
3
  "displayName": "Untappd",
4
- "version": "2.4.0",
4
+ "version": "2.5.1",
5
5
  "description": "MCP server for Untappd — search beers/breweries/venues, read check-ins and wishlists, and post check-ins, toasts, and comments",
6
6
  "author": {
7
7
  "name": "Chris Hall",
package/README.md CHANGED
@@ -39,6 +39,7 @@ it goes stale.
39
39
  | `UNTAPPD_PHOTO_DIR` | no | The directory `untappd_checkin`'s `photo_path` must be inside (several allowed, separated by `:`). Defaults to `~/Downloads/untappd-mcp` — put a photo there to attach it. Any other file is refused, so a prompt-injected shout or comment can't publish an arbitrary image from your disk. |
40
40
  | `UNTAPPD_CACHE_DB` | no | Path to the local check-in cache SQLite file (default `~/.untappd-mcp/checkins.db`). A relative path or leading `~` resolves against your **home** directory, never the working directory, so every host (Claude Desktop, Claude Code, …) finds the same file; the resolved path is logged to stderr at startup. The db file is always made owner-only (`0600`), and so are any directories the server creates plus the default `~/.untappd-mcp`; a directory you point this into that already exists keeps its permissions. Local/stdio only. |
41
41
  | `UNTAPPD_CACHE_DIR` | no | Directory for the cache instead of `~/.untappd-mcp` (the file is `checkins.db` inside it). `UNTAPPD_CACHE_DB` wins if both are set. |
42
+ | `UNTAPPD_RATE_LIMIT_PER_HOUR` | no | The hourly call limit the syncs' stop-before-429 guard enforces (default `100`, Untappd's documented per-token limit). Only change it if Untappd gives your token a different limit. |
42
43
 
43
44
  Copy `.env.example` to `.env` and fill it in for local use.
44
45
 
@@ -89,7 +90,65 @@ Writes (each asks you to confirm first — see [Confirmations](#confirmations)):
89
90
 
90
91
  Check-in cache: `untappd_sync_checkins`, `untappd_sync_user_beers`,
91
92
  `untappd_cache_has_had`, `untappd_cache_has_had_many`, `untappd_cache_not_had`,
92
- `untappd_cache_query`, `untappd_top_not_had`, `untappd_cache_status`, `untappd_cache_forget`.
93
+ `untappd_cache_query`, `untappd_top_not_had`, `untappd_cache_status`, `untappd_cache_forget`,
94
+ `untappd_sync_wishlist` (mirrors a user's wishlist locally so picks can boost wishlisted beers),
95
+ `untappd_sync_brewery_likes` (mirrors the breweries a user likes/follows on Untappd, as "untappd" favorites),
96
+ `untappd_sync_user_venues` + `untappd_cache_has_visited` (a user's full venue history — "has this person
97
+ been here?" — which pages fully for any public/friend account, unlike their check-ins).
98
+
99
+ Trip planning: `untappd_trip_check` takes a user (or `usernames` + `mode`) and up to 25 stops — each a
100
+ `venue_id`, a `name` (+ `city`/`state`), a `lat`/`lng`, and/or a `brewery_id` — and returns per stop:
101
+ whether they've been there (first/recent visit, total visits, the matched venues incl. Untappd's
102
+ "(duplicate of …)" copies; a brewery stop is matched by the brewery's name), how many of the brewery's
103
+ beers they've had, and the top N (default 4) **not-had** beers by Untappd global rating, with an
104
+ optional `style` filter (out-of-production beers skipped unless asked). Visits and has-had are answered
105
+ from the cache only; the one API call it may make is `brewery/beer_list` for a brewery whose list isn't
106
+ cached or is past its 7-day TTL — at most `api_budget` (default 5; `0` = strictly cache-only, using a
107
+ stale list flagged `stale`), under the rate-limit guard. Favorite venues and breweries are flagged,
108
+ `prefer_favorites` (default true) boosts wishlisted and favorite-brewery beers (liked on Untappd, derived or
109
+ manual), and a stop within
110
+ `near_favorite_radius_m` (default 2 km) of a favorite venue gets `near_favorites` and a "Near a
111
+ favorite: …" hint.
112
+
113
+ Group checks: `untappd_cache_has_had_many` and `untappd_top_not_had` accept `usernames` (up to 10)
114
+ with `mode: "none_had"` (default — beers new to everyone) or `"any_not_had"` (beers at least one of
115
+ them still needs); each beer says who has and hasn't had it.
116
+
117
+ What they drank at a venue (opt-in, costs calls): `untappd_sync_venue_drinks` fetches the beer from
118
+ each cached venue's first and most-recent visit check-in (`checkin/view`, budgeted by `max_calls`,
119
+ stops before the rate limit). It's a partial picture — two check-ins per venue at most — shown in
120
+ `untappd_cache_has_visited` as `drinks`.
121
+
122
+ Favorites (cache only, never written to Untappd): `untappd_favorites_list` lists a user's favorite
123
+ beers, breweries and venues, each once with its `sources` and a `reason`. **Derived** favorites come
124
+ from the synced history — venues with ≥5 check-ins or visits spanning ≥3 distinct months; breweries
125
+ with ≥5 beers had and an average rating ≥3.75, or ≥15 beers; beers rated ≥4.25 or had ≥3 times —
126
+ and every threshold can be overridden per call. **Manual** favorites are added and removed with
127
+ `untappd_favorite_add` / `untappd_favorite_remove` (local table, optional note). Results from
128
+ `untappd_cache_has_had`, `untappd_cache_has_had_many`, `untappd_cache_has_visited`, `untappd_brewery_beers`, `untappd_venue_menu`
129
+ and `untappd_top_not_had` carry a `favorite` field `{is_favorite, sources, reason}`, and
130
+ `untappd_top_not_had` ranks wishlisted beers and beers from favorite breweries higher by default
131
+ (`prefer_favorites: false` turns that off); `untappd_trip_check` carries the same flags and boost.
132
+
133
+ **Untappd** favorites (breweries only): `untappd_sync_brewery_likes` mirrors the breweries a user
134
+ "likes" on Untappd (`user/brewerylikes` — the app calls them "followings"; works for another user's
135
+ public/friend account, ~50 per call). Like the wishlist sync it's a full pass from the top, resumable
136
+ (cursor saved every page, `another_run_needed`, `percent`), stops before the rate limit with
137
+ `stopped_for_rate_limit` + resume info, and only drops unliked breweries once a pass finishes. Liked
138
+ breweries then carry the source `untappd` everywhere favorites appear — merged with `derived` and
139
+ `manual`, each source listed once — and count for the `prefer_favorites` boost and trip_check's flags.
140
+ `untappd_cache_status` reports each user's `brewery_likes` coverage, and `untappd_cache_forget` removes them.
141
+
142
+ Untappd has **no followed or favorite *venue* list** at all (no web or API route; `venue/info` has no
143
+ per-user flag), so venue favorites are derived + manual only. `brewery/info`'s
144
+ `claimed_status.follow_status` describes the **signed-in** account, like `have_had` below, so it is
145
+ never used for anyone else — the synced likes list is how to see another user's.
146
+
147
+ Cached reads (to stretch the ~100 calls/hour limit): `untappd_brewery_beers` keeps each brewery's
148
+ list for 7 days, and `untappd_venue_menu` / `untappd_venue_activity` keep results for 6 hours; each
149
+ reports where the answer came from and takes `refresh: true` to re-fetch. Untappd's `have_had` on a
150
+ brewery's beer list describes the **signed-in** account, never the user you're asking about, so it
151
+ isn't cached or returned — use `untappd_cache_has_had_many` for any user.
93
152
 
94
153
  Menu picks: `untappd_menu_pick` (tap-list lines in, ranked not-had beers out),
95
154
  `untappd_venue_pick` (same, from a venue's Untappd menu).
@@ -227,6 +286,18 @@ Both are resumable: they fetch `max_pages` per call (default 10), persist
227
286
  progress after every page, and set `another_run_needed: true` until done — just
228
287
  call again until it's `false`.
229
288
 
289
+ **Rate limit.** Every API response is recorded (time, status and any
290
+ `X-Ratelimit-*` / `Retry-After` headers) and, once the cache is open, logged in
291
+ the cache file so every process sharing it — and the next one — counts the same
292
+ hour. The syncs check that count **before every page** and stop cleanly with
293
+ `stopped_for_rate_limit: true` and `rate_limit.resume_at` when the next call
294
+ would leave fewer than 2 of the ~100 hourly calls; a 429 that slips through also
295
+ stops the run cleanly instead of failing it. Progress is already saved, so
296
+ re-run after `resume_at`. `untappd_cache_status` shows the current picture under
297
+ `rate_limit`. Note: the v4 API sends `X-Ratelimit-Remaining: 0` on every
298
+ successful response, so that header is ignored until it reports a live
299
+ (non-zero) value; the estimate rests on the local call count.
300
+
230
301
  **Query** the cache with no further API calls. The has-had tools consult **both**
231
302
  sources (a hit in either counts as had):
232
303
 
@@ -263,7 +334,8 @@ telling you to add them as a friend first.
263
334
  user's dated check-ins, comments and venues — stay until you remove them. The
264
335
  file is created owner-only (directory `0700`, database `0600`, and older
265
336
  installs are tightened on open). `untappd_cache_forget` deletes one user's
266
- cached check-ins, distinct-beers list and sync state after a confirmation
337
+ cached check-ins, distinct-beers list, venue history, wishlist copy, liked
338
+ breweries, local favorites, venue drinks and sync state after a confirmation
267
339
  (preview shows the username and row counts); it touches only the local cache,
268
340
  never Untappd, and a later sync can re-fetch. Deleting the file removes
269
341
  everything.