untappd-mcp 1.4.0 → 1.5.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 +3 -1
- package/SKILL.md +2 -0
- package/dist/bundle.js +35 -1
- package/dist/tools/cache.js +38 -0
- 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.5.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.5.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.5.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
|
@@ -83,7 +83,7 @@ Writes (confirm-gated — return a dry-run preview unless called with
|
|
|
83
83
|
`untappd_add_friend`, `untappd_accept_friend`, `untappd_reject_friend`, `untappd_remove_friend`.
|
|
84
84
|
|
|
85
85
|
Check-in cache: `untappd_sync_checkins`, `untappd_cache_has_had`,
|
|
86
|
-
`untappd_cache_has_had_many`, `untappd_cache_query`.
|
|
86
|
+
`untappd_cache_has_had_many`, `untappd_cache_not_had`, `untappd_cache_query`.
|
|
87
87
|
|
|
88
88
|
## Check-in cache
|
|
89
89
|
|
|
@@ -114,6 +114,8 @@ connector — the tools and behaviour are identical either way.
|
|
|
114
114
|
date, and the matching check-ins.
|
|
115
115
|
- `untappd_cache_has_had_many` — cross-check a whole list of `bids` in one
|
|
116
116
|
call (e.g. a venue's menu) → had/not-had per beer.
|
|
117
|
+
- `untappd_cache_not_had` — given a list of `bids`, return just the ones the
|
|
118
|
+
user has **not** had — the "what's new to me on this menu?" filter.
|
|
117
119
|
- `untappd_cache_query` — filter cached check-ins by brewery, style,
|
|
118
120
|
`min_rating`, venue, and/or date range, with sorting and a limit.
|
|
119
121
|
|
package/SKILL.md
CHANGED
|
@@ -68,6 +68,8 @@ on the remote connector it's a per-user Durable Object. Same tools either way.
|
|
|
68
68
|
case-insensitive `beer_name` substring.
|
|
69
69
|
- `untappd_cache_has_had_many` — batch had/not-had for a list of `bids` in one
|
|
70
70
|
call (venue-menu cross-check).
|
|
71
|
+
- `untappd_cache_not_had` — given a list of `bids`, return only the ones the user
|
|
72
|
+
has NOT had ("what's new to me on this menu?").
|
|
71
73
|
- `untappd_cache_query` — filter cached check-ins by brewery, style, `min_rating`,
|
|
72
74
|
venue, and date range, with sort + limit.
|
|
73
75
|
|
package/dist/bundle.js
CHANGED
|
@@ -31184,7 +31184,7 @@ function toolAnnotations(opts = {}) {
|
|
|
31184
31184
|
}
|
|
31185
31185
|
|
|
31186
31186
|
// src/version.ts
|
|
31187
|
-
var VERSION = "1.
|
|
31187
|
+
var VERSION = "1.5.0";
|
|
31188
31188
|
|
|
31189
31189
|
// src/client.ts
|
|
31190
31190
|
import { dirname, join } from "path";
|
|
@@ -32938,6 +32938,40 @@ function registerCacheTools(server, client2, cacheProvider) {
|
|
|
32938
32938
|
});
|
|
32939
32939
|
}
|
|
32940
32940
|
);
|
|
32941
|
+
server.registerTool(
|
|
32942
|
+
"untappd_cache_not_had",
|
|
32943
|
+
{
|
|
32944
|
+
title: "From a list of beers, return the ones a user has NOT had",
|
|
32945
|
+
description: 'Given a list of beer ids, return only the ones the user has NOT checked in \u2014 the "what here is new to me?" filter for a venue menu, a brewery lineup, or a festival list. Reads the cache only, NO API call. Returns the not-had bids (plus the had bids and counts) and cache freshness. Run untappd_sync_checkins first; if the cache is incomplete the freshness caveat flags that a "not had" may be a false negative.',
|
|
32946
|
+
annotations: toolAnnotations({ title: "From a list of beers, return the ones a user has NOT had", readOnly: true, idempotent: true, openWorld: false }),
|
|
32947
|
+
inputSchema: {
|
|
32948
|
+
username: UsernameArg2,
|
|
32949
|
+
bids: external_exports.array(external_exports.number().int().positive()).min(1).max(500).describe("Candidate beer ids to filter (1\u2013500)")
|
|
32950
|
+
}
|
|
32951
|
+
},
|
|
32952
|
+
async ({ username, bids }) => {
|
|
32953
|
+
const user = resolveUser2(username, client2.loginName);
|
|
32954
|
+
const cache = cacheProvider();
|
|
32955
|
+
const seen = /* @__PURE__ */ new Set();
|
|
32956
|
+
const notHad = [];
|
|
32957
|
+
const had = [];
|
|
32958
|
+
for (const bid of bids) {
|
|
32959
|
+
if (seen.has(bid)) continue;
|
|
32960
|
+
seen.add(bid);
|
|
32961
|
+
if ((await cache.hasHad(user, { bid })).had) had.push(bid);
|
|
32962
|
+
else notHad.push(bid);
|
|
32963
|
+
}
|
|
32964
|
+
return textResult({
|
|
32965
|
+
username: user,
|
|
32966
|
+
checked: seen.size,
|
|
32967
|
+
not_had_count: notHad.length,
|
|
32968
|
+
had_count: had.length,
|
|
32969
|
+
not_had: notHad,
|
|
32970
|
+
had,
|
|
32971
|
+
freshness: await freshness(cache, user)
|
|
32972
|
+
});
|
|
32973
|
+
}
|
|
32974
|
+
);
|
|
32941
32975
|
server.registerTool(
|
|
32942
32976
|
"untappd_cache_query",
|
|
32943
32977
|
{
|
package/dist/tools/cache.js
CHANGED
|
@@ -137,6 +137,44 @@ export function registerCacheTools(server, client, cacheProvider) {
|
|
|
137
137
|
freshness: await freshness(cache, user),
|
|
138
138
|
});
|
|
139
139
|
});
|
|
140
|
+
server.registerTool('untappd_cache_not_had', {
|
|
141
|
+
title: 'From a list of beers, return the ones a user has NOT had',
|
|
142
|
+
description: 'Given a list of beer ids, return only the ones the user has NOT checked in — the "what here is new to me?" ' +
|
|
143
|
+
'filter for a venue menu, a brewery lineup, or a festival list. Reads the cache only, NO API call. Returns ' +
|
|
144
|
+
'the not-had bids (plus the had bids and counts) and cache freshness. Run untappd_sync_checkins first; if the ' +
|
|
145
|
+
'cache is incomplete the freshness caveat flags that a "not had" may be a false negative.',
|
|
146
|
+
annotations: toolAnnotations({ title: 'From a list of beers, return the ones a user has NOT had', readOnly: true, idempotent: true, openWorld: false }),
|
|
147
|
+
inputSchema: {
|
|
148
|
+
username: UsernameArg,
|
|
149
|
+
bids: z.array(z.number().int().positive()).min(1).max(500).describe('Candidate beer ids to filter (1–500)'),
|
|
150
|
+
},
|
|
151
|
+
}, async ({ username, bids }) => {
|
|
152
|
+
const user = resolveUser(username, client.loginName);
|
|
153
|
+
const cache = cacheProvider();
|
|
154
|
+
// De-dupe the input, preserving first-seen order, so a repeated bid is
|
|
155
|
+
// looked up once and reported once.
|
|
156
|
+
const seen = new Set();
|
|
157
|
+
const notHad = [];
|
|
158
|
+
const had = [];
|
|
159
|
+
for (const bid of bids) {
|
|
160
|
+
if (seen.has(bid))
|
|
161
|
+
continue;
|
|
162
|
+
seen.add(bid);
|
|
163
|
+
if ((await cache.hasHad(user, { bid })).had)
|
|
164
|
+
had.push(bid);
|
|
165
|
+
else
|
|
166
|
+
notHad.push(bid);
|
|
167
|
+
}
|
|
168
|
+
return textResult({
|
|
169
|
+
username: user,
|
|
170
|
+
checked: seen.size,
|
|
171
|
+
not_had_count: notHad.length,
|
|
172
|
+
had_count: had.length,
|
|
173
|
+
not_had: notHad,
|
|
174
|
+
had,
|
|
175
|
+
freshness: await freshness(cache, user),
|
|
176
|
+
});
|
|
177
|
+
});
|
|
140
178
|
server.registerTool('untappd_cache_query', {
|
|
141
179
|
title: 'Query cached check-ins with filters',
|
|
142
180
|
description: "Query a user's cached check-ins by brewery, style, minimum rating, venue, and/or date range, with sorting " +
|
package/dist/version.js
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
// json's `extra-files`), and `versionSyncTest` guards that it stays equal to
|
|
4
4
|
// package.json. Import VERSION wherever the version is needed rather than
|
|
5
5
|
// re-declaring it.
|
|
6
|
-
export const VERSION = '1.
|
|
6
|
+
export const VERSION = '1.5.0'; // x-release-please-version
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "untappd-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"mcpName": "io.github.chrischall/untappd-mcp",
|
|
5
5
|
"description": "Untappd MCP server for Claude — developed and maintained by AI (Claude Code)",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/untappd-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.5.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "untappd-mcp",
|
|
14
|
-
"version": "1.
|
|
14
|
+
"version": "1.5.0",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|