untappd-mcp 1.4.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.
@@ -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": "1.4.0"
10
+ "version": "1.6.0"
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": "1.4.0",
18
+ "version": "1.6.0",
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": "1.4.0",
4
+ "version": "1.6.0",
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
@@ -82,45 +82,57 @@ Writes (confirm-gated — return a dry-run preview unless called with
82
82
  `untappd_wishlist_add`, `untappd_wishlist_remove`, `untappd_delete_checkin`,
83
83
  `untappd_add_friend`, `untappd_accept_friend`, `untappd_reject_friend`, `untappd_remove_friend`.
84
84
 
85
- Check-in cache: `untappd_sync_checkins`, `untappd_cache_has_had`,
86
- `untappd_cache_has_had_many`, `untappd_cache_query`.
85
+ Check-in cache: `untappd_sync_checkins`, `untappd_sync_user_beers`,
86
+ `untappd_cache_has_had`, `untappd_cache_has_had_many`, `untappd_cache_not_had`,
87
+ `untappd_cache_query`.
87
88
 
88
89
  ## Check-in cache
89
90
 
90
- The Untappd API only exposes paged, most-recent-first check-in lists (50 per
91
- page) and has **no** "has this user ever had beer X?" lookup — answering that
92
- from the API alone means paging an entire history (often 11k+ check-ins) against
93
- a tight ~100-calls/hour rate limit. These tools maintain a SQLite mirror of a
94
- user's check-ins so the question is answered instantly, offline, with zero API
95
- calls. The mirror is a local file on the stdio/desktop server (`node:sqlite`,
96
- path via `UNTAPPD_CACHE_DB`) and a per-user Durable Object on the remote
97
- connector — the tools and behaviour are identical either way.
98
-
99
- **Recommended workflow — sync first, then query:**
100
-
101
- 1. **Sync** with `untappd_sync_checkins` (omit `username` for your own account).
102
- It is incremental (stops as soon as it reaches already-cached check-ins) and
103
- resumable: while the initial backfill is incomplete it pages backwards up to
104
- `max_pages` per call (default 10) and **persists progress after every page**,
105
- so an interrupted run never loses data. The summary reports `rows_added`,
106
- `pages_fetched`, a `backfill_percent` estimate, and `another_run_needed`if
107
- that is `true`, just call it again (and again) until it is `false`. That
108
- covers both extending the backfill downwards and catching up a burst of new
109
- check-ins too large for one run (`catchup_in_progress`). Spreading the work
110
- across several runs keeps you under the rate limit.
111
- 2. **Query** the cache with no further API calls:
112
- - `untappd_cache_has_had` — has the user had a beer, by exact `bid` or a
113
- case-insensitive `beer_name` substring; returns count, best rating, last
114
- date, and the matching check-ins.
115
- - `untappd_cache_has_had_many` cross-check a whole list of `bids` in one
116
- call (e.g. a venue's menu) → had/not-had per beer.
117
- - `untappd_cache_query` filter cached check-ins by brewery, style,
118
- `min_rating`, venue, and/or date range, with sorting and a limit.
119
-
120
- Every read result carries a `freshness` block (`last_synced_at`,
121
- `backfill_complete`, `backfill_percent`) and, when the backfill is
122
- incomplete, a `caveat` so a "not found" can be reported as possibly a false
123
- negative for older history until the sync finishes.
91
+ The Untappd API only exposes paged lists (50 per page) and has **no** "has this
92
+ user ever had beer X?" lookup — answering that from the API alone means paging an
93
+ entire history (often 11k+ check-ins) against a tight ~100-calls/hour rate limit.
94
+ These tools maintain a SQLite mirror so the question is answered instantly,
95
+ offline, with zero API calls. The mirror is a local file on the stdio/desktop
96
+ server (`node:sqlite`, path via `UNTAPPD_CACHE_DB`) and a per-user Durable Object
97
+ on the remote connector the tools and behaviour are identical either way.
98
+
99
+ Two sync sources fill the cache:
100
+
101
+ - **`untappd_sync_user_beers`** pages `user/beers` — the user's **complete
102
+ distinct-beers list** (thousands of rows, not tens of thousands of check-ins).
103
+ This is the **cheapest way to get full "has had" coverage** and, unlike
104
+ `user/checkins`, it pages fully for any public/friend account. **Start here**
105
+ for has-had questions.
106
+ - **`untappd_sync_checkins`** pages `user/checkins` for detailed check-ins
107
+ (venue, date, comment). Only your **own** account pages fully Untappd returns
108
+ just the ~50 most recent for anyone else and won't page further, which the tool
109
+ reports as `history_truncated` (it never falsely claims `backfill_complete`).
110
+ Pass `force_backfill: true` to reset a cache wrongly marked complete and
111
+ re-page from newest (cached rows are kept). Use this for recent venue/date
112
+ detail; use `untappd_sync_user_beers` for coverage.
113
+
114
+ Both are resumable: they fetch `max_pages` per call (default 10), persist
115
+ progress after every page, and set `another_run_needed: true` until done — just
116
+ call again until it's `false`.
117
+
118
+ **Query** the cache with no further API calls. The has-had tools consult **both**
119
+ sources (a hit in either counts as had):
120
+
121
+ - `untappd_cache_has_had` has the user had a beer, by exact `bid` or a
122
+ case-insensitive `beer_name` substring; returns count, best rating, last date,
123
+ matching sources, and any detailed check-ins.
124
+ - `untappd_cache_has_had_many` cross-check a whole list of `bids` in one call
125
+ (e.g. a venue's menu) → had/not-had per beer.
126
+ - `untappd_cache_not_had` — given a list of `bids`, return just the ones the user
127
+ has **not** had — the "what's new to me on this menu?" filter.
128
+ - `untappd_cache_query` — filter cached **check-ins** by brewery, style,
129
+ `min_rating`, venue, and/or date range, with sorting and a limit.
130
+
131
+ Every read result carries a `freshness` block that reports **each source's
132
+ completeness separately** (`checkins.backfill_complete` / `history_truncated`,
133
+ `beers.complete`, per-source percentages) plus `coverage_complete`, and a
134
+ `caveat` while coverage is incomplete — so a "not found" can be flagged as
135
+ possibly a false negative until the relevant sync finishes.
124
136
 
125
137
  Syncing **another** user goes through the same authed endpoint as
126
138
  `untappd_user_checkins`, so Untappd's privacy rules apply: it only works if that
package/SKILL.md CHANGED
@@ -54,23 +54,27 @@ question is answered instantly with **no** API calls. On the stdio server the
54
54
  mirror is a local file (`UNTAPPD_CACHE_DB`, default `~/.untappd-mcp/checkins.db`);
55
55
  on the remote connector it's a per-user Durable Object. Same tools either way.
56
56
 
57
- **Sync first, then query:**
58
-
59
- - `untappd_sync_checkins` fetch check-ins into the cache. Incremental (stops at
60
- already-cached check-ins) and resumable: while the backfill is incomplete it
61
- pages backwards up to `max_pages` per call (default 10) and saves progress
62
- after every page. If the returned `another_run_needed` is true, call it again
63
- until it is false (covers both the backfill and catching up large bursts of
64
- new check-ins). Omit `username` for your own account;
65
- syncing another user needs their account public or a friend (friends-only, same
66
- as `untappd_user_checkins`).
57
+ **Sync first, then query.** Two sources; both resumable (`max_pages`/call,
58
+ progress saved per page, `another_run_needed` until done). Omit `username` for
59
+ your own account; another user must be public or your friend.
60
+
61
+ - `untappd_sync_user_beers` **start here for has-had questions.** Pages the
62
+ user's COMPLETE distinct-beers list (cheap, and pages fully for anyone).
63
+ - `untappd_sync_checkins` detailed check-ins (venue/date). Only your OWN
64
+ account pages fully; for anyone else Untappd returns just the recent ~50 and
65
+ the result reports `history_truncated` (it won't falsely claim
66
+ `backfill_complete`). `force_backfill: true` resets a cache wrongly marked
67
+ complete and re-pages (rows kept).
68
+
69
+ Query tools (has-had ones consult BOTH sources — a hit in either = had):
70
+
67
71
  - `untappd_cache_has_had` — has the user had a beer? By exact `bid` or a
68
72
  case-insensitive `beer_name` substring.
69
- - `untappd_cache_has_had_many` — batch had/not-had for a list of `bids` in one
70
- call (venue-menu cross-check).
73
+ - `untappd_cache_has_had_many` — batch had/not-had for a list of `bids`.
74
+ - `untappd_cache_not_had` — from a list of `bids`, the ones NOT had.
71
75
  - `untappd_cache_query` — filter cached check-ins by brewery, style, `min_rating`,
72
- venue, and date range, with sort + limit.
76
+ venue, and date range.
73
77
 
74
- Every cache read returns a `freshness` block (and a `caveat` when the backfill is
75
- incomplete) so you can flag that a "not found" may be a false negative until the
76
- sync finishes.
78
+ Every cache read returns a `freshness` block reporting each source's completeness
79
+ separately (plus `coverage_complete` and a `caveat` when incomplete), so you can
80
+ flag a "not found" as possibly a false negative until the relevant sync finishes.