untappd-mcp 1.8.3 → 1.8.5

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.8.3"
10
+ "version": "1.8.5"
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.8.3",
18
+ "version": "1.8.5",
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.8.3",
4
+ "version": "1.8.5",
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
@@ -52,21 +52,6 @@ your own app's traffic with an HTTPS proxy:
52
52
 
53
53
  Keep these values private; do not commit them.
54
54
 
55
- ## Remote connector
56
-
57
- This server can also run as a hosted Cloudflare Worker — an unlisted, shareable
58
- "remote connector" you add to claude.ai (Settings → Connectors) instead of
59
- running it locally. It works on Claude web, desktop, and mobile alike, since
60
- connectors added on any of those sync to the rest. Each person you share it
61
- with logs in with their *own* Untappd username and password; the operator only
62
- ever supplies the shared Untappd app credentials, never anyone's personal
63
- login. The `.mcpb` / stdio install above remains the desktop-only alternative
64
- if you'd rather run it locally against just your own account.
65
-
66
- Setting this up requires a Cloudflare account and is a manual, one-time
67
- process for whoever hosts it — see
68
- [`docs/DEPLOY-CONNECTOR.md`](docs/DEPLOY-CONNECTOR.md) for the full runbook.
69
-
70
55
  ## Tools
71
56
 
72
57
  Reads: `untappd_search_beer`, `untappd_beer_info`, `untappd_beer_activity`,
@@ -92,9 +77,9 @@ The Untappd API only exposes paged lists (50 per page) and has **no** "has this
92
77
  user ever had beer X?" lookup — answering that from the API alone means paging an
93
78
  entire history (often 11k+ check-ins) against a tight ~100-calls/hour rate limit.
94
79
  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.
80
+ offline, with zero API calls. The mirror is a local file
81
+ (`node:sqlite`, path via `UNTAPPD_CACHE_DB`); the store is injectable, so another
82
+ deployment can back it differently without the tools changing.
98
83
 
99
84
  Two sync sources fill the cache:
100
85
 
@@ -147,13 +132,9 @@ Syncing **another** user goes through the same authed endpoint as
147
132
  account is public or your friend. Otherwise the sync returns a clear error
148
133
  telling you to add them as a friend first.
149
134
 
150
- On the remote connector each logged-in user gets their **own** durable cache
151
- (keyed by their account), holding only the check-ins their account was allowed
152
- to fetch one user can never read another's cache. See
153
- [`docs/DEPLOY-CONNECTOR.md`](docs/DEPLOY-CONNECTOR.md) for the one-time deploy
154
- step this adds. `untappd_healthcheck` reports the running version and the exact
155
- tool set (count + names + a stable hash), so you can confirm which build a
156
- connector is serving.
135
+ A cache holds only the check-ins the account it belongs to was allowed to
136
+ fetch. `untappd_healthcheck` reports the running version and the exact tool set
137
+ (count + names + a stable hash), so you can confirm which build is serving.
157
138
 
158
139
  ## Development
159
140
 
package/dist/bundle.js CHANGED
@@ -31232,7 +31232,7 @@ function toolAnnotations(opts = {}) {
31232
31232
  }
31233
31233
 
31234
31234
  // src/version.ts
31235
- var VERSION = "1.8.3";
31235
+ var VERSION = "1.8.5";
31236
31236
 
31237
31237
  // src/client.ts
31238
31238
  import { dirname, join } from "path";
@@ -33772,9 +33772,8 @@ await runMcp({
33772
33772
  (s) => registerWishlistTools(s, client),
33773
33773
  (s) => registerCheckinTools(s, client),
33774
33774
  (s) => registerUtilityTools(s, client),
33775
- // The stdio server backs the cache with a local `node:sqlite` file; the
33776
- // remote Cloudflare connector (src/worker.ts) backs the same cache tools
33777
- // with a per-user Durable Object instead.
33775
+ // The cache is backed by a local `node:sqlite` file here; the provider is
33776
+ // injectable, so another deployment can back the same tools differently.
33778
33777
  (s) => registerCacheTools(s, client, nodeCacheProvider),
33779
33778
  // Keep last: logs the full registered toolset (count + names) at startup.
33780
33779
  (s) => logRegisteredTools(s, "stdio")
package/dist/cache/db.js CHANGED
@@ -7,8 +7,8 @@ import { CheckinStoreCore, LocalCacheStore } from './store.js';
7
7
  // The `node:sqlite` backend for the check-in cache — a local on-disk SQLite file
8
8
  // used by the stdio/desktop server. The query logic lives in CheckinStoreCore
9
9
  // (src/cache/store.ts); this file only adapts `node:sqlite` to the SqlDriver
10
- // surface and manages the file handle. (The remote Cloudflare connector uses a
11
- // Durable Object backend instead see src/cache/durable.ts.)
10
+ // surface and manages the file handle. Another deployment can adapt a
11
+ // different driver to the same surface.
12
12
  /** Adapts a `node:sqlite` DatabaseSync to the driver surface the core needs. */
13
13
  class NodeSqlDriver {
14
14
  db;
@@ -14,9 +14,9 @@
14
14
  // anyone — this is what gives full "has had" coverage.
15
15
  //
16
16
  // The SQL lives here ONCE, over a tiny synchronous {@link SqlDriver}, so the same
17
- // schema/queries back both engines: `node:sqlite` on the stdio server and a
18
- // Durable Object's SQLite on the connector. This module imports nothing
19
- // platform-specific.
17
+ // schema/queries back any engine: `node:sqlite` is the one that ships, and a
18
+ // different deployment can adapt another driver to the same surface. This
19
+ // module imports nothing platform-specific.
20
20
  function asDict(v) {
21
21
  return v && typeof v === 'object' && !Array.isArray(v) ? v : {};
22
22
  }
package/dist/client.js CHANGED
@@ -61,9 +61,8 @@ function xauthHeaders(userAgent) {
61
61
  /**
62
62
  * Performs the one-shot Untappd xauth login POST (username/password →
63
63
  * access token). Standalone so it can be reused both by `UntappdClient`'s
64
- * own on-demand login and by the Cloudflare-connector login flow
65
- * (`src/untappd-auth.ts`), which authenticates a user before a client even
66
- * exists — without duplicating the request/parsing logic.
64
+ * own on-demand login and by any login flow that authenticates a user before
65
+ * a client even exists without duplicating the request/parsing logic.
67
66
  */
68
67
  export async function xauthLogin(creds, opts = {}) {
69
68
  const fetchImpl = opts.fetchImpl ?? fetch;
package/dist/index.js CHANGED
@@ -40,9 +40,8 @@ await runMcp({
40
40
  (s) => registerWishlistTools(s, client),
41
41
  (s) => registerCheckinTools(s, client),
42
42
  (s) => registerUtilityTools(s, client),
43
- // The stdio server backs the cache with a local `node:sqlite` file; the
44
- // remote Cloudflare connector (src/worker.ts) backs the same cache tools
45
- // with a per-user Durable Object instead.
43
+ // The cache is backed by a local `node:sqlite` file here; the provider is
44
+ // injectable, so another deployment can back the same tools differently.
46
45
  (s) => registerCacheTools(s, client, nodeCacheProvider),
47
46
  // Keep last: logs the full registered toolset (count + names) at startup.
48
47
  (s) => logRegisteredTools(s, 'stdio'),
@@ -79,8 +79,8 @@ async function freshness(cache, username) {
79
79
  }
80
80
  /**
81
81
  * Register the check-in cache tools. `cacheProvider` supplies the backing store
82
- * (a `node:sqlite` file on the stdio server, a Durable Object on the remote
83
- * connector) and is required so this module imports no platform-specific code.
82
+ * (a `node:sqlite` file here) and is required so this module imports no
83
+ * platform-specific code.
84
84
  */
85
85
  export function registerCacheTools(server, client, cacheProvider) {
86
86
  server.registerTool('untappd_sync_checkins', {
@@ -1,7 +1,7 @@
1
1
  // Small helpers so the live build's exact toolset is visible from the client
2
2
  // (via untappd_healthcheck) and from server logs (a startup line). This is how
3
3
  // you confirm a deploy actually shipped the tools you expect — e.g. that the
4
- // remote connector is exposing the cache tools, not a stale 37-tool build.
4
+ // server is exposing the cache tools, not a stale 37-tool build.
5
5
  /** The names of every tool registered on `server`, sorted. Defensive if the SDK internal shape drifts. */
6
6
  export function registeredToolNames(server) {
7
7
  const reg = server._registeredTools;
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.8.3'; // x-release-please-version
6
+ export const VERSION = '1.8.5'; // x-release-please-version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "untappd-mcp",
3
- "version": "1.8.3",
3
+ "version": "1.8.5",
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>",
@@ -37,29 +37,20 @@
37
37
  "dev": "node dist/index.js",
38
38
  "test": "vitest run",
39
39
  "test:watch": "vitest",
40
- "test:coverage": "vitest run --coverage",
41
- "worker:dev": "wrangler dev",
42
- "worker:deploy": "wrangler deploy",
43
- "worker:test": "vitest run --config vitest.workers.config.ts"
40
+ "test:coverage": "vitest run --coverage"
44
41
  },
45
42
  "dependencies": {
46
- "@chrischall/mcp-utils": "^0.13.1",
43
+ "@chrischall/mcp-utils": "^0.14.0",
47
44
  "@modelcontextprotocol/sdk": "^1.29.0",
48
45
  "ai": "^7.0.19",
49
46
  "dotenv": "^17.4.0",
50
47
  "zod": "^4.4.2"
51
48
  },
52
49
  "devDependencies": {
53
- "@chrischall/mcp-connector": "^1.1.1",
54
- "@cloudflare/vitest-pool-workers": "^0.19.0",
55
- "@cloudflare/workers-oauth-provider": "^0.8.1",
56
- "@cloudflare/workers-types": "^5.20260708.1",
57
50
  "@types/node": "^26.1.1",
58
51
  "@vitest/coverage-v8": "^4.1.2",
59
- "agents": "^0.19.0",
60
52
  "esbuild": "^0.28.0",
61
53
  "typescript": "^7.0.2",
62
- "vitest": "^4.1.2",
63
- "wrangler": "^4.110.0"
54
+ "vitest": "^4.1.2"
64
55
  }
65
56
  }
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.8.3",
9
+ "version": "1.8.5",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "untappd-mcp",
14
- "version": "1.8.3",
14
+ "version": "1.8.5",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },
@@ -58,7 +58,7 @@ The API can't answer "has this user ever had beer X?" without paging their whole
58
58
  history (50/page, rate-limited). These tools keep a SQLite mirror so that
59
59
  question is answered instantly with **no** API calls. On the stdio server the
60
60
  mirror is a local file (`UNTAPPD_CACHE_DB`, default `~/.untappd-mcp/checkins.db`);
61
- on the remote connector it's a per-user Durable Object. Same tools either way.
61
+ the store is injectable, so another deployment can back it differently. Same tools either way.
62
62
 
63
63
  **Sync first, then query.** Two sources; both resumable (`max_pages`/call,
64
64
  progress saved per page, `another_run_needed` until done). Omit `username` for