Skip to main content
Glama
untappd-mcp

untappd-mcp

by chrischall

Top-rated beers a user has NOT had, from a candidate list

untappd_top_not_had

Rank a candidate beer list by Untappd global rating and return the top beers you or a group have not had, with optional style filtering and favorite boosts.

Instructions

The "what should I order off this tap list?" tool. From a list of candidate beer ids, return the top N the user has NOT yet had, ranked by Untappd global rating, with an optional style filter. Not-had filtering uses the cache only (both sources, no API call). Beer ratings/styles come from a metadata cache; a beer/info API call is made only on a cache miss or if the cached metadata is >30 days old, capped at api_budget calls per run (~100 calls/hour limit) — if more are needed it returns partial: true / another_run_needed: true, so re-running fills the rest. A beer whose refresh is deferred or fails is still ranked on its older cached metadata and marked stale: true. Reports the same freshness/caveat block as untappd_cache_not_had. Omit username for your own account. For a GROUP pass usernames: mode "none_had" (default) ranks only beers new to everyone, "any_not_had" ranks beers at least one of them still needs (each ranked beer lists not_had_by / had_by). prefer_favorites (default true) lifts wishlisted beers (+0.5) and beers from a favorite brewery (+0.25) — liked on Untappd, derived or manual, any user's in a group; the wishlist needs untappd_sync_wishlist and Untappd likes untappd_sync_brewery_likes — and says so per beer (score, boosted_by, wishlisted, brewery_favorite/favorite).

Input Schema

NameRequiredDescriptionDefault
bidsYesCandidate beer ids (1–100)
modeNoWith usernames: "none_had" (default) keeps beers NONE of them has had (new to everyone); "any_not_had" keeps beers at least one of them has not had.
styleNoCase-insensitive substring filter; matches EITHER the beer style or its parent style (e.g. "ipa")
top_nNoHow many top beers to return (default 2, max 10)
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
usernamesNoCheck a GROUP of users (1–10) instead of one — e.g. everyone at the table. Use instead of username; each must be synced (untappd_sync_user_beers).
api_budgetNoMax beer/info API calls this run for uncached/stale metadata (default 25). Keep modest to respect the ~100 calls/hour rate limit.
prefer_favoritesNoBoost beers on the wishlist (+0.5) or from a favorite brewery (+0.25) when ranking (default true). false ranks by global rating alone.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changedv2.6.1
    • addedInput schema / properties / mode
      Added value: +{
      +  "description": "With usernames: \"none_had\" (default) keeps beers NONE of them has had (new to everyone); \"any_not_had\" keeps beers at least one of them has not had.",
      +  "enum": [
      +    "none_had",
      +    "any_not_had"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / prefer_favorites
      Added value: +{
      +  "description": "Boost beers on the wishlist (+0.5) or from a favorite brewery (+0.25) when ranking (default true). false ranks by global rating alone.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / usernames
      Added value: +{
      +  "description": "Check a GROUP of users (1–10) instead of one — e.g. everyone at the table. Use instead of username; each must be synced (untappd_sync_user_beers).",
      +  "items": {
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  "maxItems": 10,
      +  "minItems": 1,
      +  "type": "array"
      +}
  2. Changed1 schema field changedv2.0.0
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
  3. Addedv1.7.1

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it discloses that not-had filtering is cache-only, that beer metadata may trigger a beer/info API call on cache miss or >30-day staleness, the api_budget cap and ~100 calls/hour rate limit, and the partial: true / another_run_needed: true degradation path. It also explains that deferred or failed refreshes still rank on older metadata and are marked stale: true, which is exactly the operational caveat an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The hook is well front-loaded, but the body is a single dense block that mixes caching, rate limits, group modes, and scoring in one paragraph with no structural breaks. It also restates schema content (mode values, prefer_favorites weights) in prose, which adds length without new information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of describing returns and does so: partial, another_run_needed, stale, score, boosted_by, wishlisted, brewery_favorite/favorite, and not_had_by/had_by. Combined with the cache and rate-limit disclosure, an agent has everything needed to call and interpret this 8-parameter tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so the baseline is 3, but the description adds real meaning: the group semantics of mode ("none_had" vs "any_not_had" and the not_had_by/had_by output), the exact boost weights behind prefer_favorites (+0.5 wishlist, +0.25 favorite brewery), and why api_budget should stay modest. These go beyond the schema's one-line parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a concrete situational framing ("what should I order off this tap list?") and then states the exact operation: rank candidate beer ids by Untappd global rating and return the top N the user has not had. It is clearly distinct from sibling tools like untappd_cache_not_had (cache-only lookup) and untappd_menu_pick (no personal not-had filtering).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives strong when-to-use context (ordering off a tap list), explains the two modes for single vs. group usage, says to omit username for your own account, and names prerequisites (untappd_sync_wishlist, untappd_sync_brewery_likes, untappd_sync_user_beers). It stops short of explicitly routing away from alternatives such as untappd_cache_not_had or untappd_menu_pick when no ranking is needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.