untappd-mcp 2.3.0 → 2.3.2
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 +2 -2
- package/.mcp.json +3 -2
- package/README.md +7 -6
- package/dist/bundle.js +290 -102
- package/dist/cache/db.js +15 -6
- package/dist/cache/store.js +13 -11
- package/dist/cache/sync.js +6 -0
- package/dist/client.js +68 -25
- package/dist/tools/cache.js +22 -4
- package/dist/tools/checkin.js +53 -30
- package/dist/tools/confirm.js +3 -0
- package/dist/tools/friends.js +3 -1
- package/dist/tools/utilities.js +8 -2
- package/dist/tools/wishlist.js +6 -2
- package/dist/version.js +1 -1
- package/package.json +2 -3
- package/server.json +59 -10
- package/skills/untappd-mcp/SKILL.md +25 -9
package/dist/tools/wishlist.js
CHANGED
|
@@ -11,13 +11,15 @@ export function registerWishlistTools(server, client) {
|
|
|
11
11
|
bid: BidSchema,
|
|
12
12
|
confirmToken: confirmTokenParam,
|
|
13
13
|
}),
|
|
14
|
-
}, async (
|
|
14
|
+
}, async (args, ctx) => {
|
|
15
|
+
const { bid, confirmToken } = args;
|
|
15
16
|
const request = { method: 'GET', path: '/user/wishlist/add', query: { bid } };
|
|
16
17
|
const gate = await confirmWrite(ctx, {
|
|
17
18
|
tool: 'untappd_wishlist_add',
|
|
18
19
|
action: 'untappd.wishlist_add',
|
|
19
20
|
message: 'Review and confirm adding this beer to your Untappd wishlist:',
|
|
20
21
|
confirmToken,
|
|
22
|
+
args,
|
|
21
23
|
target: bid,
|
|
22
24
|
payload: request,
|
|
23
25
|
preview: { action: 'wishlist_add', bid, ...request, note: 'Adds this beer to your Untappd wishlist.' },
|
|
@@ -35,13 +37,15 @@ export function registerWishlistTools(server, client) {
|
|
|
35
37
|
bid: BidSchema,
|
|
36
38
|
confirmToken: confirmTokenParam,
|
|
37
39
|
}),
|
|
38
|
-
}, async (
|
|
40
|
+
}, async (args, ctx) => {
|
|
41
|
+
const { bid, confirmToken } = args;
|
|
39
42
|
const request = { method: 'GET', path: '/user/wishlist/delete', query: { bid } };
|
|
40
43
|
const gate = await confirmWrite(ctx, {
|
|
41
44
|
tool: 'untappd_wishlist_remove',
|
|
42
45
|
action: 'untappd.wishlist_remove',
|
|
43
46
|
message: 'Review and confirm removing this beer from your Untappd wishlist:',
|
|
44
47
|
confirmToken,
|
|
48
|
+
args,
|
|
45
49
|
target: bid,
|
|
46
50
|
payload: request,
|
|
47
51
|
preview: { action: 'wishlist_remove', bid, ...request, note: 'Removes this beer from your Untappd wishlist.' },
|
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 = '2.3.
|
|
6
|
+
export const VERSION = '2.3.2'; // x-release-please-version
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "untappd-mcp",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.2",
|
|
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>",
|
|
@@ -45,9 +45,8 @@
|
|
|
45
45
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@chrischall/mcp-utils": "^
|
|
48
|
+
"@chrischall/mcp-utils": "^3.0.3",
|
|
49
49
|
"@modelcontextprotocol/server": "^2.3.0",
|
|
50
|
-
"ai": "^7.0.19",
|
|
51
50
|
"dotenv": "^18.0.1",
|
|
52
51
|
"zod": "^4.6.5"
|
|
53
52
|
},
|
package/server.json
CHANGED
|
@@ -6,43 +6,92 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/untappd-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "2.3.
|
|
9
|
+
"version": "2.3.2",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "untappd-mcp",
|
|
14
|
-
"version": "2.3.
|
|
14
|
+
"version": "2.3.2",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|
|
18
18
|
"environmentVariables": [
|
|
19
|
+
{
|
|
20
|
+
"name": "UNTAPPD_ACCESS_TOKEN",
|
|
21
|
+
"description": "An Untappd access token you already hold. Supply it and no password is needed (username/password become optional).",
|
|
22
|
+
"isRequired": false,
|
|
23
|
+
"format": "string",
|
|
24
|
+
"isSecret": true
|
|
25
|
+
},
|
|
19
26
|
{
|
|
20
27
|
"name": "UNTAPPD_USERNAME",
|
|
21
|
-
"description": "Your Untappd username or login email.",
|
|
22
|
-
"isRequired":
|
|
28
|
+
"description": "Your Untappd username or login email. Required unless UNTAPPD_ACCESS_TOKEN is set.",
|
|
29
|
+
"isRequired": false,
|
|
23
30
|
"format": "string",
|
|
24
31
|
"isSecret": false
|
|
25
32
|
},
|
|
26
33
|
{
|
|
27
34
|
"name": "UNTAPPD_PASSWORD",
|
|
28
|
-
"description": "Your Untappd account password (used only for xauth login).",
|
|
29
|
-
"isRequired":
|
|
35
|
+
"description": "Your Untappd account password (used only for xauth login). Required unless UNTAPPD_ACCESS_TOKEN is set.",
|
|
36
|
+
"isRequired": false,
|
|
30
37
|
"format": "string",
|
|
31
38
|
"isSecret": true
|
|
32
39
|
},
|
|
33
40
|
{
|
|
34
41
|
"name": "UNTAPPD_CLIENT_ID",
|
|
35
|
-
"description": "Untappd mobile app client id (obtained by intercepting the app; see README).",
|
|
36
|
-
"isRequired":
|
|
42
|
+
"description": "Untappd mobile app client id (obtained by intercepting the app; see README). Needed to log in with username/password and for every write; a pre-seeded access token can read without it.",
|
|
43
|
+
"isRequired": false,
|
|
37
44
|
"format": "string",
|
|
38
45
|
"isSecret": true
|
|
39
46
|
},
|
|
40
47
|
{
|
|
41
48
|
"name": "UNTAPPD_CLIENT_SECRET",
|
|
42
|
-
"description": "Untappd mobile app client secret.",
|
|
43
|
-
"isRequired":
|
|
49
|
+
"description": "Untappd mobile app client secret. Needed to log in with username/password and for every write; a pre-seeded access token can read without it.",
|
|
50
|
+
"isRequired": false,
|
|
44
51
|
"format": "string",
|
|
45
52
|
"isSecret": true
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "UNTAPPD_DEVICE_ID",
|
|
56
|
+
"description": "Stable device UUID the token is keyed to (a default is provided).",
|
|
57
|
+
"isRequired": false,
|
|
58
|
+
"format": "string",
|
|
59
|
+
"isSecret": false
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"name": "UNTAPPD_UTV",
|
|
63
|
+
"description": "API version param (default 4.0.0).",
|
|
64
|
+
"isRequired": false,
|
|
65
|
+
"format": "string",
|
|
66
|
+
"isSecret": false
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"name": "UNTAPPD_USER_AGENT",
|
|
70
|
+
"description": "Override the User-Agent (default mimics the app).",
|
|
71
|
+
"isRequired": false,
|
|
72
|
+
"format": "string",
|
|
73
|
+
"isSecret": false
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"name": "UNTAPPD_TIMEZONE",
|
|
77
|
+
"description": "IANA timezone (e.g. America/New_York) that check-ins are stamped with when the call doesn't pass timezone. Set it when the server runs somewhere other than the drinker's zone (e.g. a hosted connector, usually UTC). Defaults to the server process's zone.",
|
|
78
|
+
"isRequired": false,
|
|
79
|
+
"format": "string",
|
|
80
|
+
"isSecret": false
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"name": "UNTAPPD_PHOTO_DIR",
|
|
84
|
+
"description": "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.",
|
|
85
|
+
"isRequired": false,
|
|
86
|
+
"format": "string",
|
|
87
|
+
"isSecret": false
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"name": "UNTAPPD_CACHE_DB",
|
|
91
|
+
"description": "Path to the local check-in cache SQLite file (default ~/.untappd-mcp/checkins.db; created owner-only — dir 0700, file 0600). Local/stdio only.",
|
|
92
|
+
"isRequired": false,
|
|
93
|
+
"format": "string",
|
|
94
|
+
"isSecret": false
|
|
46
95
|
}
|
|
47
96
|
]
|
|
48
97
|
}
|
|
@@ -5,19 +5,35 @@ description: Search Untappd beers, breweries, and venues; read user profiles, ch
|
|
|
5
5
|
|
|
6
6
|
# Untappd MCP
|
|
7
7
|
|
|
8
|
-
Talks to Untappd's mobile (v4) API using your own account
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
Talks to Untappd's mobile (v4) API using your own account, calling the same
|
|
9
|
+
endpoints the iPad app uses. Authenticates with an access token you already
|
|
10
|
+
hold, or mints one via the app's `xauth` endpoint (username + password).
|
|
11
11
|
|
|
12
12
|
## Setup
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Environment variables (the README has the full table and how to capture the
|
|
15
|
+
client credentials):
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
| Variable | Needed | Purpose |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| `UNTAPPD_ACCESS_TOKEN` | no | A token you already hold. With it, **no password is needed** — xauth is skipped. When it expires, the server says so; supply a fresh one. |
|
|
20
|
+
| `UNTAPPD_USERNAME`, `UNTAPPD_PASSWORD` | if no token | Your Untappd login, used only to mint a token. Accounts with 2FA can't log in this way. |
|
|
21
|
+
| `UNTAPPD_CLIENT_ID`, `UNTAPPD_CLIENT_SECRET` | for login & writes | The Untappd mobile app's client credentials. A pre-seeded token can read without them. |
|
|
22
|
+
| `UNTAPPD_TIMEZONE` | no | IANA zone check-ins are stamped with when a call omits `timezone`. Defaults to the server's zone. |
|
|
23
|
+
| `UNTAPPD_PHOTO_DIR` | no | Directory (or `:`-separated list) a check-in's `photo_path` must be inside. Default `~/Downloads/untappd-mcp`. |
|
|
24
|
+
| `UNTAPPD_CACHE_DB` | no | Local check-in cache file (default `~/.untappd-mcp/checkins.db`). Local/stdio only. |
|
|
19
25
|
|
|
20
|
-
|
|
26
|
+
Two things the server enforces that you should plan around:
|
|
27
|
+
|
|
28
|
+
- **Photos:** `untappd_checkin`'s `photo_path` must be a file inside
|
|
29
|
+
`UNTAPPD_PHOTO_DIR` (default `~/Downloads/untappd-mcp`); anything else (e.g.
|
|
30
|
+
`~/Pictures/beer.jpg`) is refused. Ask the user to move the photo there first.
|
|
31
|
+
- **Time zone:** on a hosted connector the server usually runs in UTC, so pass
|
|
32
|
+
`timezone` (the drinker's IANA zone, e.g. `America/New_York`) on
|
|
33
|
+
`untappd_checkin` unless `UNTAPPD_TIMEZONE` is set — otherwise the check-in is
|
|
34
|
+
stamped in the server's zone.
|
|
35
|
+
|
|
36
|
+
Run `untappd_healthcheck` to confirm auth works.
|
|
21
37
|
|
|
22
38
|
## Read tools
|
|
23
39
|
|
|
@@ -143,7 +159,7 @@ parameter, because an undeclared key is dropped by zod without a warning:
|
|
|
143
159
|
## Write tools (confirmation-gated — these post to your public account)
|
|
144
160
|
|
|
145
161
|
Each asks the user to confirm first. Where the client can show a confirmation
|
|
146
|
-
prompt, it does. Otherwise the first call makes NO network call and returns
|
|
162
|
+
prompt, it does (unless the server sets `MCP_CONFIRM_ELICITATION=off`). Otherwise the first call makes NO network call and returns
|
|
147
163
|
`status: "confirmation-required"` with a `preview` of the exact request and a
|
|
148
164
|
`confirmToken`; show the preview to the user, and only after they approve call
|
|
149
165
|
the tool again with the same arguments plus `confirmToken`. A token works once
|