untappd-mcp 1.5.0 → 1.7.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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +56 -38
- package/SKILL.md +24 -18
- package/dist/bundle.js +922 -418
- package/dist/cache/store.js +288 -87
- package/dist/cache/sync-beers.js +113 -0
- package/dist/cache/sync.js +104 -58
- package/dist/index.js +1 -1
- package/dist/tools/beer.js +27 -1
- package/dist/tools/cache.js +235 -52
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -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.
|
|
10
|
+
"version": "1.7.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.
|
|
18
|
+
"version": "1.7.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
|
+
"version": "1.7.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,47 +82,65 @@ 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`, `
|
|
86
|
-
`untappd_cache_has_had_many`, `untappd_cache_not_had`,
|
|
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`, `untappd_top_not_had`.
|
|
87
88
|
|
|
88
89
|
## Check-in cache
|
|
89
90
|
|
|
90
|
-
The Untappd API only exposes paged
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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_top_not_had` — from a list of `bids`, return the **top N not-had
|
|
129
|
+
beers ranked by Untappd global rating**, with an optional `style` filter (the
|
|
130
|
+
"what should I order off this tap list?" tool). Not-had filtering is
|
|
131
|
+
cache-only; beer ratings come from a metadata cache (`beer_meta`) that's seeded
|
|
132
|
+
opportunistically by `untappd_beer_info` / `untappd_search_beer` and topped up
|
|
133
|
+
via `beer/info` only on a cache miss or entries older than 30 days — capped at
|
|
134
|
+
`api_budget` calls/run (default 25), returning `partial: true` /
|
|
135
|
+
`another_run_needed: true` when more are needed.
|
|
136
|
+
- `untappd_cache_query` — filter cached **check-ins** by brewery, style,
|
|
137
|
+
`min_rating`, venue, and/or date range, with sorting and a limit.
|
|
138
|
+
|
|
139
|
+
Every read result carries a `freshness` block that reports **each source's
|
|
140
|
+
completeness separately** (`checkins.backfill_complete` / `history_truncated`,
|
|
141
|
+
`beers.complete`, per-source percentages) plus `coverage_complete`, and a
|
|
142
|
+
`caveat` while coverage is incomplete — so a "not found" can be flagged as
|
|
143
|
+
possibly a false negative until the relevant sync finishes.
|
|
126
144
|
|
|
127
145
|
Syncing **another** user goes through the same authed endpoint as
|
|
128
146
|
`untappd_user_checkins`, so Untappd's privacy rules apply: it only works if that
|
package/SKILL.md
CHANGED
|
@@ -54,25 +54,31 @@ 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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
|
70
|
-
|
|
71
|
-
- `
|
|
72
|
-
|
|
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.
|
|
75
|
+
- `untappd_top_not_had` — from a list of `bids`, the top N NOT-had beers by
|
|
76
|
+
Untappd rating, with an optional `style` filter ("what should I order off this
|
|
77
|
+
tap list?"). Uses a `beer_meta` cache; calls `beer/info` only on miss/stale,
|
|
78
|
+
capped at `api_budget` per run (partial/another_run_needed when exceeded).
|
|
73
79
|
- `untappd_cache_query` — filter cached check-ins by brewery, style, `min_rating`,
|
|
74
|
-
venue, and date range
|
|
80
|
+
venue, and date range.
|
|
75
81
|
|
|
76
|
-
Every cache read returns a `freshness` block
|
|
77
|
-
|
|
78
|
-
sync finishes.
|
|
82
|
+
Every cache read returns a `freshness` block reporting each source's completeness
|
|
83
|
+
separately (plus `coverage_complete` and a `caveat` when incomplete), so you can
|
|
84
|
+
flag a "not found" as possibly a false negative until the relevant sync finishes.
|