Skip to main content
Glama
untappd-mcp

untappd-mcp

by chrischall

untappd-mcp

An MCP server for Untappd. It talks to Untappd's mobile (v4) API using your own account — search beers, breweries, and venues; read profiles, check-ins, wishlists, distinct beers, badges, friends, and your friend activity feed; and post check-ins, toasts, and comments.

Developed and maintained by AI (Claude Code). Use at your own discretion. This is an unofficial client that uses Untappd's private mobile API; it is not affiliated with or endorsed by Untappd.

How it works

Untappd's iPad/iPhone app authenticates with a username/password xauth login (POST https://api.untappd.com/v4/xauth) that returns an access token, then calls the v4 API. This server reproduces that, except where the token goes:

  • Reads carry the token as an Authorization: Bearer header, never in the URL (the app uses an access_token query param; the API accepts both).

  • Writes carry it as an Authorization: Bearer header (with the app's client credentials in the query), matching the app's real requests.

The token is fetched on demand, cached in memory, and refreshed automatically if it goes stale.

Related MCP server: Polvenn MCP Server

Configuration

Variable

Required

Description

UNTAPPD_ACCESS_TOKEN

no

An access token you already hold. Supply this and no password is needed — the xauth login is skipped entirely.

UNTAPPD_USERNAME

if no token

Your Untappd username or login email.

UNTAPPD_PASSWORD

if no token

Your Untappd password (used only for the xauth login that mints a token).

UNTAPPD_CLIENT_ID

for login & writes

The Untappd mobile app client id (see below). A pre-seeded access token can read without it.

UNTAPPD_CLIENT_SECRET

for login & writes

The Untappd mobile app client secret.

UNTAPPD_DEVICE_ID

no

Stable device UUID the token is keyed to (a default is provided).

UNTAPPD_UTV

no

API version param (default 4.0.0).

UNTAPPD_USER_AGENT

no

Override the User-Agent (default mimics the app).

UNTAPPD_TIMEZONE

no

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.

UNTAPPD_PHOTO_DIR

no

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.

UNTAPPD_CACHE_DB

no

Path to the local check-in cache SQLite file (default ~/.untappd-mcp/checkins.db). A relative path or leading ~ resolves against your home directory, never the working directory, so every host (Claude Desktop, Claude Code, …) finds the same file; the resolved path is logged to stderr at startup. The db file is always made owner-only (0600), and so are any directories the server creates plus the default ~/.untappd-mcp; a directory you point this into that already exists keeps its permissions. Local/stdio only.

UNTAPPD_CACHE_DIR

no

Directory for the cache instead of ~/.untappd-mcp (the file is checkins.db inside it). UNTAPPD_CACHE_DB wins if both are set.

UNTAPPD_RATE_LIMIT_PER_HOUR

no

The hourly call limit the syncs' stop-before-429 guard enforces (default 100, Untappd's documented per-token limit). Only change it if Untappd gives your token a different limit.

Copy .env.example to .env and fill it in for local use.

Confirmations

Every write asks you to confirm it first. A client that can show a confirmation prompt (Claude Code) shows one (unless MCP_CONFIRM_ELICITATION=off). Elsewhere the write takes two calls: the first does nothing and returns a preview of the exact request plus a confirmToken, and only a repeat call with the same arguments and that token performs it. A token works once, for that tool and those arguments only; change anything and the call is refused with a fresh preview.

variable

default

MCP_CONFIRM_MODE

ask-user

What a write does on a client that cannot show a confirmation prompt (claude.ai, Claude Desktop). ask-user: two steps — the first call does nothing and returns a preview plus a token, and the model must get your approval in chat before calling again with it. auto: the same two steps, but the model may use the token after reviewing the preview itself. refuse: writes are refused on such clients. A client that can show prompts (Claude Code) always gets the real prompt, unless MCP_CONFIRM_ELICITATION=off. An unrecognised value is treated as refuse.

MCP_CONFIRM_ELICITATION

on

off never shows a confirmation prompt, so every client gets the MCP_CONFIRM_MODE behaviour. Set it for a client that says it can show prompts but never does (the write hangs — opencode 2.0.x). Any other value is treated as on, with a warning on stderr.

MCP_CONFIRM_TTL_SECONDS

600

How long a token stays valid.

MCP_CONFIRM_SECRET

random per process

Signing key; set it only if tokens must survive a server restart.

Obtaining the client id / secret

Untappd does not publish these; they live in the mobile app. Capture them from your own app's traffic with an HTTPS proxy:

  1. Install a proxy such as mitmproxy and trust its CA certificate on the device running the Untappd app.

  2. Point the device (or, on an Apple-silicon Mac running the iPad app, the Mac's system HTTP/HTTPS proxy) at the proxy.

  3. Open Untappd and sign in. Find the POST https://api.untappd.com/v4/xauth request — its query string contains client_id and client_secret.

  4. Put those into UNTAPPD_CLIENT_ID / UNTAPPD_CLIENT_SECRET.

Keep these values private; do not commit them.

Tools

Reads: untappd_search_beer, untappd_beer_info, untappd_beer_activity, untappd_search_brewery, untappd_brewery_info, untappd_brewery_beers, untappd_search_venue, untappd_venue_info, untappd_venue_activity, untappd_user_info, untappd_user_checkins, untappd_user_wishlist, untappd_user_beers, untappd_user_badges, untappd_user_friends, untappd_pending_friends, untappd_activity_feed, untappd_checkin_info, untappd_resolve, untappd_open_url, untappd_user_venues, untappd_venue_by_foursquare, untappd_trending, untappd_notifications, untappd_local_checkins, untappd_upload_slots, untappd_healthcheck.

Writes (each asks you to confirm first — see Confirmations): untappd_toast, untappd_add_comment, untappd_delete_comment, untappd_checkin, untappd_wishlist_add, untappd_wishlist_remove, untappd_delete_checkin, untappd_add_friend, untappd_accept_friend, untappd_reject_friend, untappd_remove_friend.

Check-in photos

untappd_checkin takes one photo (JPEG or PNG, max 15 MB) through exactly one of:

  • photo_path — a file on the machine the server runs on, inside UNTAPPD_PHOTO_DIR. Local installs only: on the hosted connector the server can't see your files, so a path is refused with directions to the slot flow below.

  • photo_inline — {filename, contentBase64, mimeType?}. Works anywhere; fine for a small photo, but every byte rides inside the tool call.

  • photo_blob_key — the hosted connector's route. untappd_upload_slots (slots: [{filename}]) returns a signed upload URL and a ready curl per photo; PUT the photo with it, then pass the slot's blobKey. It refuses on a deployment with no blob store.

Every route is checked the same way (image type, size cap, bytes that really are a JPEG/PNG), and the confirmation preview names the photo and its SHA-256 — a blob that changes between the preview and the confirmed call is refused (DRAFT_CHANGED). An uploaded blob is deleted only after the check-in and its photo succeed (photo_blob: {deleted: true}); otherwise it is kept (kept: true) so you can retry.

Check-in cache: untappd_sync_checkins, untappd_sync_user_beers, untappd_cache_has_had, untappd_cache_has_had_many, untappd_cache_not_had, untappd_cache_query, untappd_top_not_had, untappd_cache_status, untappd_cache_forget, untappd_sync_wishlist (mirrors a user's wishlist locally so picks can boost wishlisted beers), untappd_sync_brewery_likes (mirrors the breweries a user likes/follows on Untappd, as "untappd" favorites), untappd_sync_user_venues + untappd_cache_has_visited (a user's full venue history — "has this person been here?" — which pages fully for any public/friend account, unlike their check-ins).

Trip planning: untappd_trip_check takes a user (or usernames + mode) and up to 25 stops — each a venue_id, a name (+ city/state), a lat/lng, and/or a brewery_id — and returns per stop: whether they've been there (first/recent visit, total visits, the matched venues incl. Untappd's "(duplicate of …)" copies; a brewery stop is matched by the brewery's name), how many of the brewery's beers they've had, and the top N (default 4) not-had beers by Untappd global rating, with an optional style filter (out-of-production beers skipped unless asked). Visits and has-had are answered from the cache only; the one API call it may make is brewery/beer_list for a brewery whose list isn't cached or is past its 7-day TTL — at most api_budget (default 5; 0 = strictly cache-only, using a stale list flagged stale), under the rate-limit guard. Favorite venues and breweries are flagged, prefer_favorites (default true) boosts wishlisted and favorite-brewery beers (liked on Untappd, derived or manual), and a stop within near_favorite_radius_m (default 2 km) of a favorite venue gets near_favorites and a "Near a favorite: …" hint.

Group checks: untappd_cache_has_had_many and untappd_top_not_had accept usernames (up to 10) with mode: "none_had" (default — beers new to everyone) or "any_not_had" (beers at least one of them still needs); each beer says who has and hasn't had it.

What they drank at a venue (opt-in, costs calls): untappd_sync_venue_drinks fetches the beer from each cached venue's first and most-recent visit check-in (checkin/view, budgeted by max_calls, stops before the rate limit). It's a partial picture — two check-ins per venue at most — shown in untappd_cache_has_visited as drinks.

Favorites (cache only, never written to Untappd): untappd_favorites_list lists a user's favorite beers, breweries and venues, each once with its sources and a reason. Derived favorites come from the synced history — venues with ≥5 check-ins or visits spanning ≥3 distinct months; breweries with ≥5 beers had and an average rating ≥3.75, or ≥15 beers; beers rated ≥4.25 or had ≥3 times — and every threshold can be overridden per call. Manual favorites are added and removed with untappd_favorite_add / untappd_favorite_remove (local table, optional note). Results from untappd_cache_has_had, untappd_cache_has_had_many, untappd_cache_has_visited, untappd_brewery_beers, untappd_venue_menu and untappd_top_not_had carry a favorite field {is_favorite, sources, reason}, and untappd_top_not_had ranks wishlisted beers and beers from favorite breweries higher by default (prefer_favorites: false turns that off); untappd_trip_check carries the same flags and boost.

Untappd favorites (breweries only): untappd_sync_brewery_likes mirrors the breweries a user "likes" on Untappd (user/brewerylikes — the app calls them "followings"; works for another user's public/friend account, ~50 per call). Like the wishlist sync it's a full pass from the top, resumable (cursor saved every page, another_run_needed, percent), stops before the rate limit with stopped_for_rate_limit + resume info, and only drops unliked breweries once a pass finishes. Liked breweries then carry the source untappd everywhere favorites appear — merged with derived and manual, each source listed once — and count for the prefer_favorites boost and trip_check's flags. untappd_cache_status reports each user's brewery_likes coverage, and untappd_cache_forget removes them.

Untappd has no followed or favorite venue list at all (no web or API route; venue/info has no per-user flag), so venue favorites are derived + manual only. brewery/info's claimed_status.follow_status describes the signed-in account, like have_had below, so it is never used for anyone else — the synced likes list is how to see another user's.

Cached reads (to stretch the ~100 calls/hour limit): untappd_brewery_beers keeps each brewery's list for 7 days, and untappd_venue_menu / untappd_venue_activity keep results for 6 hours; each reports where the answer came from and takes refresh: true to re-fetch. Untappd's have_had on a brewery's beer list describes the signed-in account, never the user you're asking about, so it isn't cached or returned — use untappd_cache_has_had_many for any user.

Menu picks: untappd_menu_pick (tap-list lines in, ranked not-had beers out), untappd_venue_pick (same, from a venue's Untappd menu).

Picking a beer off a menu

untappd_menu_pick turns "find Mer a beer" from a menu photo into one call. Give it the lines as read off the board:

{
  "username": "mer",
  "items": [
    "HAP & HARRY'S TENNESSEE LAGER $6",
    "I BELIEVE IN NASHVILLE BLONDE",
    "JACKALOPE FENNARIO IPA",
    "BEARDED IRIS HOMESTYLE",
    "BLACK ABBEY SEASONAL",
    "ROTATING CIDER"
  ],
  "venue_city": "Nashville",
  "top_n": 2
}

In one call it:

  1. Freshens the cache. If the user's distinct-beers list is already complete it does an incremental refresh, stopping at the first beer that's cached and unchanged (usually one page). If the list is empty or partial it backfills in the same call until done or api_budget (default 60 calls, shared by every step) runs out. You never need to call a sync tool first.

  2. Resolves each line to a beer. It strips prices, sizes, ABV and punctuation, searches Untappd (falling back to a query without the style word, because Untappd search matches every term), and scores the candidates on brewery match, beer-name match (so "Homestyle" isn't read as "Double Homestyle"), check-in volume (the canonical entry wins over a 3-check-in duplicate) and venue_city. Up to 4 searches run at once, and a 429 is retried with backoff. Resolutions are cached on disk, so the next visit to the same venue costs no searches.

  3. Handles generic lines. <Brewery> SEASONAL / ROTATING becomes a possible list of that brewery's seasonal-looking beers, marked needs_confirmation. A line with no brewery (ROTATING CIDER) comes back unresolved: "ask bartender".

  4. Checks every beer against the cache (both sources, as has_had_many does).

  5. Ranks the not-had beers by global rating, applies style_filter, and returns the top top_n as picks.

Output for the call above, with Mer having had Fennario (abridged: not_had also lists the Tennessee Lager at 3.33, possible lists six candidates, and a freshness block is appended):

{
  "picks": [
    { "item": "BEARDED IRIS HOMESTYLE", "bid": 1502190, "name": "Homestyle", "brewery": "Bearded Iris Brewing",
      "style": "IPA - New England / Hazy", "abv": 6, "global_rating": 3.98,
      "reason": "not had · 3.98 global rating · #1 of 3 not-had beers on this list" },
    { "item": "I BELIEVE IN NASHVILLE BLONDE", "bid": 3780741, "name": "I Believe In Nashville",
      "brewery": "I Believe Brewing Company", "style": "Blonde / Golden Ale - American", "abv": 4.5,
      "global_rating": 3.54, "reason": "not had · 3.54 global rating · #2 of 3 not-had beers on this list" }
  ],
  "had": [
    { "item": "JACKALOPE FENNARIO IPA", "bid": 1893601, "name": "Fennario", "brewery": "Jackalope Brewing Company",
      "count": 3, "last_date": "2025-08-01T20:00:00.000Z", "user_rating": 3.75 }
  ],
  "possible": [
    { "item": "BLACK ABBEY SEASONAL", "brewery": "The Black Abbey Brewing Company",
      "reason": "seasonal-looking beers from this brewery",
      "candidates": [
        { "bid": 1223176, "name": "Chronicles Festbier", "style": "Festbier", "abv": 4.9, "global_rating": 3.672, "had": false }
      ],
      "needs_confirmation": true }
  ],
  "unresolved": [{ "item": "ROTATING CIDER", "reason": "ask bartender" }],
  "sync": { "mode": "backfill", "api_calls": 1 },
  "api_calls": 11,
  "api_budget": 60,
  "another_run_needed": false
}

sync says what the refresh did; coverage lives in freshness. If the budget runs out before the backfill finishes, freshness.coverage_complete is false, another_run_needed is true, and the freshness caveat warns that a "not had" may be a false negative. Calling again continues from where it stopped.

Quota. When an Untappd response carries X-Ratelimit-Remaining, the server remembers it for the hour, and every budgeted tool (menu_pick, venue_pick, top_not_had, both syncs) caps its budget to what's left. The result then includes quota_remaining, plus budget_clamped_to_quota: true when the cap applied. Untappd's public API documents the header; if the private API this server uses doesn't send it, budgets work exactly as before.

untappd_venue_pick takes an Untappd venue URL (https://untappd.com/v/<slug>/<id>) or id instead of items. It pages through the venue's whole verified menu, takes the venue's city from it, and runs the same check and ranking. Menu items already carry beer ids, so there is no search step.

Check-in cache

The Untappd API only exposes paged lists (50 per page) and has no "has this user ever had beer X?" lookup — answering that from the API alone means paging an entire history (often 11k+ check-ins) against a tight ~100-calls/hour rate limit. These tools maintain a SQLite mirror so the question is answered instantly, offline, with zero API calls. The mirror is a local SQLite file (node:sqlite, default ~/.untappd-mcp/checkins.db, overridable with UNTAPPD_CACHE_DB / UNTAPPD_CACHE_DIR). The store is injectable, so another deployment can back it differently without the tools changing.

Persistence. The file survives restarts, and a backfill that was cut off (rate limit, crash, host quit) resumes from its saved offset on the next sync. The file runs in WAL mode with a busy timeout and does every write in a transaction, so two hosts open at the same time can share it. The schema is versioned (PRAGMA user_version) and only ever migrated forward, adding columns and tables, so an upgrade never wipes it. untappd_cache_status shows the resolved path, size, schema version and per-user coverage.

Two sync sources fill the cache:

  • untappd_sync_user_beers pages user/beers — the user's complete distinct-beers list (thousands of rows, not tens of thousands of check-ins). This is the cheapest way to get full "has had" coverage and, unlike user/checkins, it pages fully for any public/friend account. Start here for has-had questions.

  • untappd_sync_checkins pages user/checkins for detailed check-ins (venue, date, comment). Only your own account pages fully — Untappd returns just the ~50 most recent for anyone else and won't page further, which the tool reports as history_truncated (it never falsely claims backfill_complete). Pass force_backfill: true to reset a cache wrongly marked complete and re-page from newest (cached rows are kept). Use this for recent venue/date detail; use untappd_sync_user_beers for coverage.

Both are resumable: they fetch max_pages per call (default 10), persist progress after every page, and set another_run_needed: true until done — just call again until it's false.

Rate limit. Every API response is recorded (time, status and any X-Ratelimit-* / Retry-After headers) and, once the cache is open, logged in the cache file so every process sharing it — and the next one — counts the same hour. The syncs check that count before every page and stop cleanly with stopped_for_rate_limit: true and rate_limit.resume_at when the next call would leave fewer than 2 of the ~100 hourly calls; a 429 that slips through also stops the run cleanly instead of failing it. Progress is already saved, so re-run after resume_at. untappd_cache_status shows the current picture under rate_limit. Note: the v4 API sends X-Ratelimit-Remaining: 0 on every successful response, so that header is ignored until it reports a live (non-zero) value; the estimate rests on the local call count.

Query the cache with no further API calls. The has-had tools consult both sources (a hit in either counts as had):

  • untappd_cache_has_had — has the user had a beer, by exact bid or a case-insensitive beer_name substring; returns count, best rating, last date, matching sources, and any detailed check-ins.

  • untappd_cache_has_had_many — cross-check a whole list of bids in one call (e.g. a venue's menu) → had/not-had per beer.

  • untappd_cache_not_had — given a list of bids, return just the ones the user has not had — the "what's new to me on this menu?" filter.

  • untappd_top_not_had — from a list of bids, return the top N not-had beers ranked by Untappd global rating, with an optional style filter (the "what should I order off this tap list?" tool). Not-had filtering is cache-only; beer ratings come from a metadata cache (beer_meta) that's seeded opportunistically by untappd_beer_info / untappd_search_beer and topped up via beer/info only on a cache miss or entries older than 30 days — capped at api_budget calls/run (default 25), returning partial: true / another_run_needed: true when more are needed.

  • untappd_cache_query — filter cached check-ins by brewery, style, min_rating, venue, and/or date range, with sorting and a limit.

Every read result carries a freshness block that reports each source's completeness separately (checkins.backfill_complete / history_truncated, beers.complete, per-source percentages) plus coverage_complete, and a caveat while coverage is incomplete — so a "not found" can be flagged as possibly a false negative until the relevant sync finishes.

Syncing another user goes through the same authed endpoint as untappd_user_checkins, so Untappd's privacy rules apply: it only works if that account is public or your friend. Otherwise the sync returns a clear error telling you to add them as a friend first.

Retention. Nothing in the cache expires: synced rows — including another user's dated check-ins, comments and venues — stay until you remove them. The file is created owner-only (directory 0700, database 0600, and older installs are tightened on open). untappd_cache_forget deletes one user's cached check-ins, distinct-beers list, venue history, wishlist copy, liked breweries, local favorites, venue drinks and sync state after a confirmation (preview shows the username and row counts); it touches only the local cache, never Untappd, and a later sync can re-fetch. Deleting the file removes everything.

A cache holds only the check-ins the account it belongs to was allowed to fetch. untappd_healthcheck reports the running version and the exact tool set (count + names + a stable hash), so you can confirm which build is serving.

Development

npm install
npm run build
npm test

License

MIT

Available Tools

59 tools
untappd_accept_friendAccept an Untappd friend requestA
DestructiveIdempotent

Accepts an incoming friend request (see untappd_pending_friends for pending uids). Acts on YOUR account and affects a real relationship with another person. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE). Note: this endpoint path is taken from the Untappd app but is not otherwise independently verified.

NameRequiredDescriptionDefault
target_uidYesThe target user id (uid) — from a user profile (response.user.uid) or a friends-list item
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.5/5.0
Behavior5/5

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

Beyond annotations, the description reveals that the action affects a real relationship with another person, requires user confirmation, and uses a two-step confirmToken fallback. It also discloses that the endpoint path is not independently verified, adding trust-relevant context.

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

Conciseness5/5

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

The description is compact and front-loaded, with each sentence serving a distinct purpose: core action, usage context, confirmation flow, and a validation caveat. No redundant or filler content.

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?

Despite lacking an output schema, the description explains the confirmation response behavior ('preview and confirmToken') and the fallback flow, which is the critical context for calling this tool correctly. Combined with the schema and annotations, nothing essential is missing.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already fully documents both target_uid and confirmToken. The description adds no additional parameter-level meaning, which meets the baseline but does not exceed it.

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?

The description uses a specific verb ('Accepts') and resource ('incoming friend request'), and points to a sibling tool (untappd_pending_friends) for pending uids. It clearly distinguishes this accept action from related friend-management tools.

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?

It states when to use the tool: when accepting an incoming friend request, and where to find the target uids. It does not explicitly contrast with reject_friend or add_friend, but the action is unambiguous and the reference to pending requests provides sufficient context.

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

untappd_activity_feedGet Untappd friend activity feedA
Read-only

Get your Untappd friend activity feed — the recent check-ins from people you follow, newest first. Page backwards with max_id (the pagination.max_id from a prior call). Read-only.

NameRequiredDescriptionDefault
viewNoResponse shape: "compact" (default) projects each check-in to {id, user, beer, brewery, venue, rating, comment, toast/comment counts}; "full" returns Untappd's whole ~5 KB record; "brief" returns one line per check-in: <user>: <beer> (<brewery>) at <venue> — <ISO date or "no date"> — <rated N|not rated>, inside the untrusted-data envelope as data: string[], with "-- " note lines ("-- none", "-- more").
limitNoMax check-ins (1–50, default 25)
max_idNoReturn check-ins older than this id (for paging)

TDQS

A4.4/5.0
Behavior4/5

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

Beyond the annotations, it discloses newest-first ordering and backward pagination, including where to obtain the continuation value. The final "Read-only" merely repeats readOnlyHint, and operational details such as feed freshness or rate limits are not provided.

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

Conciseness4/5

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

The description is compact and front-loaded, presenting purpose and scope first and pagination next. "Read-only" is redundant with the structured annotation, but it adds almost no bulk.

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?

For a three-parameter read-only feed, the description supplies the resource scope, ordering, and pagination workflow needed to invoke it correctly. Although there is no output schema, the view parameter documents the response shapes in detail, while the description identifies the pagination field used for continuation.

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 100%, so the baseline is 3, and the schema already documents all three parameters thoroughly. The description adds useful meaning by explaining that max_id should be taken from pagination.max_id in a prior response and used to page backward.

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?

The description pairs a clear verb and resource with a precise scope: "recent check-ins from people you follow," ordered newest first. This distinguishes the friend feed from sibling user, venue, beer, and local check-in or activity tools without needing to name each one.

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?

It establishes the context for using the friend feed and gives concrete guidance for retrieving older pages with max_id from a prior call's pagination.max_id. It does not explicitly route agents to alternatives such as untappd_user_checkins or untappd_venue_activity when they want a different scope.

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

untappd_add_commentComment on an Untappd check-inA
Destructive

Post a comment on a check-in from YOUR account. Writes to your Untappd account and is visible to others. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

NameRequiredDescriptionDefault
commentYesComment text to post
checkin_idYesUntappd check-in id
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already cover the write/destructive/non-idempotent profile, yet the description adds substantial context beyond them: the comment is publicly visible, a user confirmation is required, and the exact two-phase fallback (preview + confirmToken on repeat call) is spelled out with a pointer to MCP_CONFIRM_MODE.

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

Conciseness5/5

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

Three sentences, front-loaded with the action and audience, then the side effect, then the confirmation mechanics. No redundant or filler content.

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?

There is no output schema, but the description compensates by describing what the phase-1 response returns (a preview and a confirmToken) and how it is consumed. Nothing needed to call the tool correctly is missing.

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

Parameters3/5

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

Schema description coverage is 100%, and the confirmToken semantics are documented in detail in the schema itself, so the description adds little parameter meaning beyond it. Baseline 3 is appropriate when the schema carries the load.

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?

States a specific verb and resource ('Post a comment on a check-in') and scopes it to the authenticated account ('from YOUR account'), which cleanly separates it from untappd_delete_comment and read-only check-in siblings. An agent can identify the operation without opening the schema.

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 clear context for invocation (posting a comment from your own account, visible to others) and lays out the mandatory confirmation workflow. It does not name an alternative or state when-not to use it, so it stops short of explicit routing guidance.

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

untappd_add_friendSend an Untappd friend requestA
DestructiveIdempotent

Sends a friend request to another user, who will be notified. Acts on YOUR account and affects a real relationship with another person. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE). Note: this endpoint path is taken from the Untappd app but is not otherwise independently verified.

NameRequiredDescriptionDefault
target_uidYesThe target user id (uid) — from a user profile (response.user.uid) or a friends-list item
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.4/5.0
Behavior5/5

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

Beyond the annotations (destructiveHint, idempotentHint, etc.), the description discloses that the action 'affects a real relationship with another person,' describes the two-step confirmation flow with confirmToken, and honestly notes that the endpoint path is not independently verified. This is substantial behavioral context that helps the agent anticipate side effects and safety requirements.

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

Conciseness5/5

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

Three sentences, each earning its place: the core action, the real-world impact and confirmation flow, and the verification caveat. The most important information is front-loaded, and there is no filler or redundant repetition of schema details.

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

Completeness4/5

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

For a tool with no output schema, the description covers the essential operational context: confirmation behavior, response preview/confirmToken, and safety caveat. It could further explain what the preview contains or common error conditions, but it is complete enough for an agent to invoke the tool correctly.

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 100%, so the baseline is 3, and the schema already provides detailed descriptions for both target_uid and confirmToken. The description adds value by explaining the two-step confirmation flow and when the confirmToken is relevant, reinforcing the parameter semantics beyond the raw schema.

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?

The description clearly states the action ('Sends a friend request to another user'), identifies the resource ('another user'), and notes the consequence ('who will be notified'). It is readily distinguishable from sibling tools like accept_friend, reject_friend, and remove_friend, which handle different relationship actions.

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

Usage Guidelines3/5

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

The description implies when to use this tool (to initiate a friend request) and gives important context about confirmation behavior, but it does not explicitly contrast it with alternatives or state when not to use it (e.g., for accepting/rejecting pending requests). The usage is clear from the verb and resource, but exclusion guidance is absent.

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

untappd_beer_activityGet recent check-ins for a beerA
Read-only

Get the recent public check-ins for a beer by its bid — who drank it, their rating, comment, and venue. Page backwards with max_id (the pagination.max_id from a prior call). Read-only.

NameRequiredDescriptionDefault
bidYesUntappd beer id (bid)
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact projects each check-in to {id, user, beer, brewery, venue, rating, comment, toast/comment counts}; "full" returns Untappd's whole ~5 KB record.
limitNoMax check-ins (1–50, default 25)
max_idNoReturn check-ins older than this id (for paging)

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, and the description reinforces this with 'Read-only.' It also adds useful behavioral context beyond the schema: check-ins are public, paging is backwards using max_id, and max_id comes from a prior call's pagination data. This gives the agent a clear mental model of how the endpoint behaves.

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

Conciseness5/5

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

The description is two focused sentences with no filler. It front-loads the action and resource, then packs the key behavioral details (paging, max_id source, read-only) into the second sentence. Every phrase earns its place.

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

Completeness4/5

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

There is no output schema, so the description partially compensates by listing the returned fields (user, rating, comment, venue) and explaining paging. It is adequate for an agent to call the tool correctly, though it could additionally note that results are ordered or that 'comment' may be absent for some check-ins.

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

Parameters3/5

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

Schema coverage is 100% and every parameter (bid, view, limit, max_id) already has a meaningful description. The main description adds only a slight clarification about max_id coming from prior pagination, which is helpful but does not substantially add beyond what the schema already documents.

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?

The description uses a specific verb ('Get'), a specific resource ('recent public check-ins for a beer'), and an identifier ('bid'), making the tool's purpose immediately clear. It also lists what the response contains (user, rating, comment, venue), which distinguishes it from beer metadata tools like untappd_beer_info.

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

Usage Guidelines3/5

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

The description clearly implies when to use it: whenever you need recent check-in activity for a specific beer. However, it does not explicitly name alternatives or state when not to use it, such as choosing untappd_checkin_info for a single check-in, untappd_user_checkins for a user's activity, or untappd_venue_activity for venue-level activity.

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

untappd_beer_infoGet Untappd beer detailA
Read-onlyIdempotent

Get full detail for a beer by its Untappd beer id (bid): description, style, ABV, IBU, brewery, rating, total check-in count, and — on view:"full" — recent activity. Get a bid from untappd_search_beer. Read-only.

NameRequiredDescriptionDefault
bidYesUntappd beer id (bid)
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact asks Untappd for its own slim record, dropping the embedded recent-activity (media/check-in) block server side; "full" returns the whole record including that activity. No local projection — the beer fields themselves are identical on both rungs.

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safe read behavior is covered. The description adds an explicit output-field list and the view:'full' recent-activity behavior, giving the agent a concrete sense of what the call returns beyond the schema; no contradiction with annotations.

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

Conciseness5/5

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

Three short sentences front-load the purpose and output fields, then add the bid-source instruction and read-only note. Every sentence earns its place and there is no redundant elaboration.

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?

For a simple lookup with robust annotations and a 100%-documented schema, the description supplies the missing output contract (fields returned) and the view-dependent variation. An agent has enough to select and invoke the tool correctly even without an output schema.

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

Parameters3/5

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

Schema coverage is 100% and the view parameter already has a thorough description of compact/full behavior and no local projection. The description contributes little beyond the bid provenance tip ('Get a bid from untappd_search_beer'), so the schema remains the primary source of parameter meaning.

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

Purpose4/5

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

The description names a specific verb and resource ('Get full detail for a beer'), enumerates the returned fields, and explicitly ties the id to untappd_search_beer. It is clear, but it doesn't explicitly contrast itself with the sibling untappd_beer_activity, which also covers beer activity, so sibling differentiation is left to the tool name and 'full detail' wording.

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

Usage Guidelines3/5

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

The only usage guidance is 'Get a bid from untappd_search_beer', which addresses how to obtain the input rather than when to prefer this tool over siblings such as untappd_beer_activity or untappd_brewery_info. The intended context is implied by 'full detail' but no exclusions or alternatives are stated.

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

untappd_brewery_beersGet a brewery's beer listA
Read-onlyIdempotent

Get the beers a brewery makes, by brewery id, with per-beer global rating, check-in count, ABV, style and in_production. Supports sorting and paging. Get an id from untappd_search_brewery. Lists are CACHED locally for 7 days (source:"cache"|"api", fetched_at, expires_at): a fresh cached list answers without an API call — the default popularity order from the cached top-of-list, other sorts once the whole list is cached (sorted locally). refresh:true re-fetches. The compact result has the same keys with or without the cache (source:"api" and null fetched_at/expires_at when no cache is available), with pagination {offset, limit, next_offset}. Untappd's per-beer has_had / your-count on this endpoint describe the AUTHENTICATED account, never the user you are asking about, so have_had / your_count are never cached or returned on either path — use untappd_cache_has_had_many for any user. With the cache, the result carries favorite {is_favorite, sources, reason} for the brewery and on each favorite beer (derived from username's history or added with untappd_favorite_add; default your account). view:"full" always calls Untappd and returns its raw page. Read-only.

NameRequiredDescriptionDefault
sortNoSort order (default by popularity)
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact keeps each beer's identity, rating and counts and drops the description, label URLs and the copy of this brewery repeated on every row; "full" returns Untappd's whole page (always fetched live).
limitNoMax beers (1–50, default 25)
offsetNoResult offset for paging (default 0)
refreshNoRe-fetch from Untappd even if a fresh cached list exists (default false)
usernameNoWhose favorites to mark (cache only; default your configured account)
brewery_idYesUntappd brewery id

TDQS

A4.4/5.0
Behavior4/5

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

Goes well beyond the readOnly/idempotent/openWorld annotations by disclosing the 7-day local cache, the source/fetched_at/expires_at markers, the pagination envelope {offset, limit, next_offset}, and the important caveat that Untappd's has_had/your_count reflect the authenticated account and are never cached or returned. It does not describe rate limiting or error behavior when the brewery id is unknown, which is why this is a 4 rather than a 5.

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

Conciseness4/5

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

Purpose is front-loaded in the first clause and every subsequent sentence carries substantive cache, paging or account-scoping information. It is dense and parenthetical-heavy, and the closing 'Read-only.' merely restates the readOnlyHint annotation, but there is very little genuine padding.

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?

For a 7-parameter tool with a two-path (cache vs live) execution model and no output schema, the description covers return shape, cache metadata fields, pagination, and the favorite annotation structure. An agent can call it correctly and interpret the response without further documentation.

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

Parameters3/5

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

Schema coverage is 100%, so the schema already documents every parameter including enums, bounds and defaults; baseline is 3. The description does add real semantics the schema lacks — that sorting is local once the full list is cached, that refresh:true bypasses the cache, that view:"full" forces a live call, and that username only affects favorite marking on the cache path — but these are stated in prose rather than tied explicitly to each parameter.

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 specific verb and resource — 'Get the beers a brewery makes, by brewery id' — and immediately enumerates the per-beer fields returned (rating, check-in count, ABV, style, in_production). This clearly separates it from untappd_brewery_info (brewery metadata) and untappd_search_beer (lookup by name).

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

Usage Guidelines5/5

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

Explicitly routes the agent to untappd_search_brewery to obtain the id, states that a fresh cached list answers without an API call and when sorts become local, and specifies refresh:true for re-fetching and view:"full" for a live raw page. It even names the correct alternative for the has_had question (untappd_cache_has_had_many).

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

untappd_brewery_infoGet Untappd brewery detailA
Read-onlyIdempotent

Get full detail for a brewery by its Untappd brewery id: description, location, type, rating, total check-ins, and popular beers. Get an id from untappd_search_brewery. Read-only. Its claimed_status.follow_status is whether the SIGNED-IN account follows/likes the brewery — never another user's; for theirs, run untappd_sync_brewery_likes and read untappd_favorites_list (source "untappd").

NameRequiredDescriptionDefault
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact also asks Untappd for its own slim record, dropping the embedded activity/list blocks; "full" returns everything.
brewery_idYesUntappd brewery id

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already cover read-only and idempotency, so "Read-only" is partly redundant, but the description adds real context beyond them: the shape of what comes back and a scope warning that claimed_status.follow_status reflects the signed-in account only. It stops short of noting auth requirements or rate limits, so a 4 rather than 5.

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

Conciseness5/5

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

Front-loads purpose and returned fields, then hands off id acquisition and the follow-status caveat in short declarative sentences. No filler; every clause carries an actionable fact.

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

Completeness4/5

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

With no output schema, listing the returned fields is the right compensation, and the per-user scope caveat prevents a plausible misread. Omitting any mention of the view parameter leaves a small hole given it alters the response, but the schema covers it well.

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

Parameters3/5

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

Schema description coverage is 100% and the enum view parameter is fully explained in the schema, so baseline applies. The description adds only that brewery_id is an Untappd id sourced from search_brewery; it says nothing about the view=compact/full choice, which matters since it changes response shape.

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?

States a specific verb+resource ("Get full detail for a brewery by its Untappd brewery id") and enumerates the returned content (description, location, type, rating, check-ins, popular beers). That distinguishes it from untappd_search_brewery and untappd_brewery_beers without requiring the schema.

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?

Tells the agent where the required id comes from ("Get an id from untappd_search_brewery") and explicitly routes a related but different question (another user's follow status) to untappd_sync_brewery_likes plus untappd_favorites_list. No explicit when-not-to-use for this tool itself, which is the only gap.

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

untappd_cache_forgetForget a user's cached check-insA
DestructiveIdempotent

Delete everything the LOCAL cache holds for one user — their cached check-ins (beer, rating, comment, venue, date), distinct-beers list, venue history, wishlist copy, local favorites, venue drinks and sync state — e.g. after syncing a friend you no longer want a history of. Only the local cache is touched; nothing on Untappd changes, and a later sync can re-fetch it (manual favorites cannot be re-fetched). Shared beer, venue and brewery facts are kept. The preview shows the username and exactly how many rows will be removed. Omit username for your own account. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

NameRequiredDescriptionDefault
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.6/5.0
Behavior5/5

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

Annotations only declare destructiveHint/idempotentHint; the description goes well beyond by spelling out exactly what rows are destroyed, what is preserved (shared beer, venue and brewery facts), and the reversibility split — re-fetchable by a later sync except manual favorites, which are lost permanently. It also discloses the confirmation protocol and the elicitation-less fallback with confirmToken, which is essential for a destructive tool.

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

Conciseness4/5

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

Front-loaded with the destructive action and its scope, then the caveats, then the confirmation mechanics — a sensible order. The single dense paragraph with stacked em-dashes and parentheticals is heavier than it needs to be, but no sentence is filler given the destructive nature of the tool.

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?

For a destructive, two-phase tool with no output schema, the description covers everything an agent needs: what is removed, what survives, reversibility, preview contents, default-account behavior, and the exact confirmation flow. Nothing material is left to guesswork.

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 100% and the schema already documents both parameters in detail, so the baseline is 3. The description adds tool-level meaning by framing username omission as 'your own account' in contrast to targeting another user, and by reinforcing the phase-1/preview → phase-2/token protocol at the tool level rather than leaving it buried in a property description.

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?

States a specific verb and scope: delete everything the LOCAL cache holds for one user, then enumerates the affected record types (check-ins, distinct beers, venue history, wishlist copy, favorites, venue drinks, sync state). It explicitly contrasts with the write-through siblings by stating that nothing on Untappd changes, so an agent can separate it from delete_checkin, favorite_remove or the sync_* tools without opening a schema.

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 a concrete trigger case ('after syncing a friend you no longer want a history of') and a negative scope ('only the local cache is touched'). It does not name competing siblings such as untappd_cache_status or untappd_favorite_remove, so the agent must infer alternatives, but the context for use is clear.

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

untappd_cache_has_hadCheck if a user has had a beer (from the cache)A
Read-onlyIdempotent

Answer "has this user ever checked in this beer?" from the cache only — NO API call. Consults BOTH cached sources (check-ins and the distinct-beers list); a hit in either counts as had. Match by exact bid or a case-insensitive substring of the beer name. Returns whether they had it, the times-had count, best rating, last date, which sources matched, any detailed check-ins, and favorite {is_favorite, sources, reason} (rated ≥4.25 / had ≥3 times, or added with untappd_favorite_add). Reports per-source freshness so you can caveat incomplete data. Requires bid or beer_name. Run untappd_sync_user_beers first for full coverage.

NameRequiredDescriptionDefault
bidNoExact Untappd beer id to look for
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
beer_nameNoCase-insensitive substring match on the beer name

TDQS

A4.6/5.0
Behavior5/5

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

Annotations only declare readOnly/idempotent/closed-world; the description goes well beyond them by disclosing that BOTH cached sources are consulted and a hit in either counts, that matching is exact-bid or case-insensitive substring, how the favorite flag is derived (≥4.25 rating / ≥3 times / explicit untappd_favorite_add), and that freshness is reported per source so results can be caveated.

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

Conciseness4/5

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

Front-loaded with the core question and the no-API constraint, then matching rules, then return shape, then prerequisite — a sensible ordering with no filler sentences. It is dense and the favorite-derivation parenthetical is long, but that detail is functional rather than decorative.

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 return contract and does so thoroughly: had/not-had, times-had count, best rating, last date, matched sources, detailed check-ins, favorite object, and freshness metadata. Combined with the sync prerequisite and the either-or input requirement, an agent has everything needed to call and interpret it.

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 100%, so the baseline is 3, but the description adds real meaning: matching semantics for bid vs beer_name and the cross-field constraint "Requires bid or beer_name" — a requirement not expressed in the schema, where zero parameters are marked required. The username fallback to the configured account is left to the schema.

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?

States a specific question it answers ("has this user ever checked in this beer?") plus the defining constraint "from the cache only — NO API call." That scope immediately separates it from API-backed siblings like untappd_beer_info or untappd_user_checkins, and the singular "this beer" separates it from untappd_cache_has_had_many.

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 clear operating context (cache-only, no API) and an explicit prerequisite: "Run untappd_sync_user_beers first for full coverage." It also frames the caveat workflow via per-source freshness. It stops short of naming the alternative to use when the cache is stale or when you need live data, so it is clear but not fully routing.

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

untappd_cache_has_had_manyBatch-check many beers against the cacheA
Read-onlyIdempotent

Cross-check a list of beer ids against a user's cached history in ONE call — NO API call. Consults BOTH sources (check-ins + distinct beers). Returns had/not-had per bid (with count and last date when had), plus favorite {is_favorite, sources, reason} per bid and brewery_favorite when its brewery (from cached beer metadata) is a favorite. Ideal for checking a whole venue menu at once. Pass usernames (instead of username) to check a GROUP: each bid then lists had_by / not_had_by and qualifies per mode — "none_had" (default: new to everyone) or "any_not_had" (at least one of them still needs it) — with qualifying_bids and a per-user freshness block. Run untappd_sync_user_beers first (for every user); the freshness block flags if coverage is incomplete.

NameRequiredDescriptionDefault
bidsYesBeer ids to check (1–500)
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.
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).

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already cover read-only/idempotent/closed-world, yet the description still adds substantial behavior: no network call is made, two cache sources are consulted, results include count and last date, favorite/brewery_favorite annotations are returned, and a per-user freshness block flags incomplete coverage. It stops short of explaining edge cases such as what happens for unsynced users or malformed bids, so it is not quite a 5.

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

Conciseness4/5

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

Front-loads the core operation and the 'no API call' guarantee, then layers group mode and prerequisites in logical order. It is dense with em-dashes and parentheticals in a single paragraph, which slightly impedes scannability, but nearly every clause carries information an agent needs.

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?

No output schema exists, so the description carries the return-shape burden and does so: per-bid had/not-had plus count and last date, favorite objects, brewery_favorite, qualifying_bids, and a freshness block. Combined with the sync prerequisite, an agent has enough to invoke and interpret this tool correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so the baseline is 3. The description does add output-level meaning per parameter — the group form produces had_by/not_had_by per bid and drives the mode semantics, and omitting username falls back to the configured account — but it largely restates the mode enum that the schema already documents.

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?

States a specific verb and resource — cross-check a list of beer ids against a user's cached history — and adds differentiating scope ('in ONE call — NO API call', both check-ins and distinct beers). An agent can distinguish it from untappd_cache_has_had (singular) and untappd_cache_not_had without opening any schema.

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

Usage Guidelines5/5

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

Gives an explicit use case ('Ideal for checking a whole venue menu at once'), a prerequisite ('Run untappd_sync_user_beers first (for every user)'), and a routing rule for the alternative parameterization ('Pass usernames (instead of username) to check a GROUP'). When-not guidance is implicit in the freshness warning, but the selection logic between single vs group mode is fully spelled out.

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

untappd_cache_has_visitedCheck if a user has been to a venue (from the cache)A
Read-onlyIdempotent

Answer "has this user been here?" for one or many places in ONE call, from the cached venue history only — NO API call. Each query matches by exact venue_ids, by name (case-insensitive substring or all significant words, optionally narrowed by city/state), and/or by lat/lng within radius_m (default 150 m); venue_ids are unioned with the name/geo match, and name + lat/lng together must both hold. Name/location matching matters because a brewery_id is NOT its taproom's venue_id, a brewery can have several venues, and Untappd keeps "… (duplicate of …)" venues — so expect, and check, several matches. Returns per query: visited, the matched venues (first_visit, recent_visit, total_count, is_duplicate, distance_m, and — once untappd_sync_venue_drinks has fetched them — drinks: the beer from the first/recent visit check-ins — and favorite {is_favorite, sources, reason}: derived from the visit history or added with untappd_favorite_add), and total_visits; plus a freshness block (last_synced_at, coverage_complete, caveat). Run untappd_sync_user_venues first.

NameRequiredDescriptionDefault
queriesYesPlaces to check (1–50); each needs venue_ids, name, or lat+lng
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
max_matchesNoMost matched venues listed per query (default 10)

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/closed-world, and the description goes well beyond them: it discloses the exact matching algebra (venue_ids unioned with name/geo, name + lat/lng must both hold), warns that duplicate "(duplicate of …)" venues and multi-venue breweries mean multiple matches should be expected, and describes the freshness block (last_synced_at, coverage_complete, caveat) that signals staleness risk.

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

Conciseness4/5

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

Front-loaded with the purpose and the no-API constraint, and every paragraph carries real information. The middle return-value sentence is heavily nested with parentheticals and em-dashes, which makes it dense to parse, but nothing is redundant enough to cut outright.

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?

There is no output schema, so the description must carry the return contract — and it does, enumerating visited, matched venues with first/recent visit fields, drinks, favorite provenance, total_visits, and the freshness block. For a cached read-only lookup with a 100%-documented schema, nothing an agent needs to call it correctly is missing.

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 100%, so the baseline is 3, but the description adds the combinatorics the schema never states: union between venue_ids and name/geo, conjunction between name and lat/lng, and the 150 m default radius. It does not explain label echoing or max_matches behavior in the prose, keeping it just short of a 5.

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?

States a specific verb and resource ("Answer 'has this user been here?'") plus the crucial scope qualifier: one or many places in ONE call, from the cached venue history only, with NO API call. That scope clause alone separates it from live siblings like untappd_user_venues and untappd_venue_info.

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 a concrete prerequisite ("Run untappd_sync_user_venues first") and points at untappd_sync_venue_drinks for drink enrichment and untappd_favorite_add for favorites. It does not explicitly state the exclusion case (e.g. 'if the cache is stale, use the live venue tools instead'), so an agent must infer the fallback, but the context is otherwise clear.

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

untappd_cache_not_hadFrom a list of beers, return the ones a user has NOT hadA
Read-onlyIdempotent

Given a list of beer ids, return only the ones the user has NOT had — the "what here is new to me?" filter for a venue menu, a brewery lineup, or a festival list. Consults BOTH cached sources; reads the cache only, NO API call. Returns the not-had bids (plus the had bids and counts) and cache freshness. Run untappd_sync_user_beers first; if coverage is incomplete the freshness caveat flags that a "not had" may be a false negative.

NameRequiredDescriptionDefault
bidsYesCandidate beer ids to filter (1–500)
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already mark it readOnly and idempotent, and the description adds substantial context: it reads the cache only, makes NO API call, consults both cached sources, returns not-had and had bids plus counts and cache freshness, and flags the false-negative risk. This goes well beyond the annotations.

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

Conciseness5/5

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

The core purpose is front-loaded in the first clause, and every sentence earns its place: the use case, the cache-only behavior, the return contents, the prerequisite, and the caveat. It is dense but efficient.

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?

For a two-parameter read-only filter tool with no output schema, the description covers the return value, the data sources, the operational prerequisite, and the main failure mode. Nothing essential is missing for an agent to invoke it correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents bids and username adequately. The description adds no new parameter-level meaning beyond the schema, matching the baseline of 3.

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?

The description states a specific verb ('return') and resource ('beers a user has NOT had'), and clearly frames it as a filter for venue menus, brewery lineups, or festival lists. It distinguishes itself from opposite tools like untappd_cache_has_had through the explicit 'NOT had' framing.

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?

The description gives clear usage context ('what here is new to me?') and a concrete prerequisite: run untappd_sync_user_beers first. It also warns about false negatives when coverage is incomplete. It stops short of explicitly naming alternatives or saying when not to use it, so it misses the top bar.

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

untappd_cache_queryQuery cached check-ins with filtersA
Read-onlyIdempotent

Query a user's cached CHECK-INS by brewery, style, minimum rating, venue, and/or date range, with sorting and a limit — from the cache only, NO API call. Reflects the detailed check-ins table (venue/date), which for non-self accounts is only the recent window; for full coverage of which beers a user has had, use untappd_cache_has_had / not_had instead. Run untappd_sync_checkins first.

NameRequiredDescriptionDefault
sortNoSort order (default recent first)
limitNoMax rows (1–200, default 25)
styleNoCase-insensitive substring match on beer style (e.g. "IPA")
venueNoCase-insensitive substring match on venue name
breweryNoCase-insensitive substring match on brewery name
date_toNoOnly check-ins on/before this date (YYYY-MM-DD, UTC)
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
venue_idNoExact venue id
date_fromNoOnly check-ins on/after this date (YYYY-MM-DD, UTC)
brewery_idNoExact brewery id
min_ratingNoOnly check-ins you rated at least this (0–5)

TDQS

A4.7/5.0
Behavior5/5

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

The description adds significant behavioral context beyond the annotations: it explicitly says 'from the cache only, NO API call', explains the recent-window limitation for non-self accounts, and notes the detailed table includes venue/date. This helps the agent predict data freshness and scope without contradicting readOnlyHint or idempotentHint.

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

Conciseness5/5

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

Three dense, purposeful sentences cover scope, exclusions, limitations, and prerequisites without redundancy. Each sentence earns its place and the most important constraint ('cache only, NO API call') is front-loaded.

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?

For a complex 11-parameter tool with no output schema, the description covers the key operational context: cache-only behavior, freshness window, filtering surface, and the sync prerequisite. It also handles the main alternative routing, leaving no critical gap for an agent deciding whether to call this tool.

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

Parameters3/5

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

The input schema already documents all 11 parameters with 100% coverage, so the description doesn't need to restate each one. It usefully groups the filter categories and mentions sorting/limit, but it adds little detail beyond the comprehensive schema 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?

The description uses a specific verb ('Query') and resource ('a user's cached CHECK-INS'), enumerates filter dimensions, and explicitly contrasts with untappd_cache_has_had / not_had. This makes the tool's role immediately distinguishable from the many sibling tools.

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

Usage Guidelines5/5

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

It states when to use the tool (for filtered check-in queries from cache) and when not to (for full beer coverage, use cache_has_had/not_had). It also directs the agent to run untappd_sync_checkins first, which is crucial operational guidance.

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

untappd_cache_statusShow the local cache location, schema and per-user coverageA
Read-onlyIdempotent

Diagnostics for the LOCAL check-in cache — NO API call. Returns the resolved cache file path, its size on disk (db + WAL), journal mode, schema version, the number of cached menu-line resolutions and beer-metadata rows, cached venues, and for every cached user: cached vs total distinct beers, cached check-ins, coverage_complete, the resume offset of an unfinished user/beers backfill, last_synced_at, and venue-history coverage (venues: cached vs total, complete, percent, next_offset; null if never synced), wishlist and Untappd brewery-likes mirror coverage (wishlist / brewery_likes: cached vs total, complete; null if never synced). Also reports rate_limit: API calls made in the last hour (this process plus any other sharing the cache file), the ~100/hour limit, the estimated calls left, the raw X-Ratelimit-* headers (the v4 API sends Remaining: 0 on every success, so it is ignored until it reports a live value) and any 429 wait. Use it to confirm the cache persisted across restarts, to see how far a backfill has got, or to check whether a sync can run now.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare readOnly/openWorld=false/idempotent, and the description goes well beyond them: it enumerates the exact returned fields, notes that the rate limit is shared with any other process using the same cache file, and explains the non-obvious quirk that the v4 API sends Remaining: 0 on every success so the header is ignored until it reports a live value. That is the kind of caveat an agent could not infer from structured data and would otherwise misread as a hard quota.

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 front-loading is excellent — the no-API-call constraint and local scope come first. But the rest is a single enormous run-on sentence enumerating every returned field (menu-line resolutions, beer-metadata rows, venues, per-user beer coverage, resume offset, venue-history offsets, wishlist/brewery-likes mirrors, rate-limit headers). The content is largely necessary given no output schema, but it would read far better as a short structured list rather than one comma-spliced chain.

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 and no parameters, the description carries the full burden of describing the response, and it does so field-group by field-group, including null semantics ("null if never synced") and the meaning of coverage_complete and resume offset. Nothing an agent needs to interpret or act on the result is missing.

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?

The tool takes zero parameters, so the baseline is 4 and there is no syntax or meaning to add. The description correctly spends no space on inputs.

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?

"Diagnostics for the LOCAL check-in cache — NO API call" gives a specific verb (diagnose/report) and resource (local cache), and the explicit "NO API call" clause separates it from the untappd_sync_* siblings that do hit the network. The title reinforces the scope (path, schema, per-user coverage). An agent can pick this over untappd_cache_query or untappd_healthcheck without opening any schema.

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?

The final sentence gives three concrete triggers: confirm the cache persisted across restarts, see how far a backfill has got, and check whether a sync can run now (rate-limit headroom). That is clear positive guidance but it never explicitly names an alternative or a when-not-to-use case (e.g. "for actual data lookups use untappd_cache_query").

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

untappd_checkinCheck in a beer on UntappdA
Destructive

Post a NEW beer check-in to YOUR Untappd account — this publishes to your public feed. Provide the beer id (bid) from untappd_search_beer; optionally a rating (0–5 in 0.25 steps), a shout (comment), a venue via foursquare_id, and ONE photo (JPEG/PNG, max 15 MB) via exactly one of photo_path (a local file), photo_inline (base64, for a small photo) or photo_blob_key. On the hosted connector, use the slot flow: call untappd_upload_slots, PUT the photo with the returned curl, then pass its blobKey as photo_blob_key (a path cannot work there). The preview shows the exact fields and photo that will be posted. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

NameRequiredDescriptionDefault
bidYesUntappd beer id to check in (from untappd_search_beer)
shoutNoOptional shout / comment text for the check-in
geolatNoOptional latitude of the check-in
geolngNoOptional longitude of the check-in
ratingNoRating 0–5 in 0.25 increments (omit for no rating)
timezoneNoThe drinker's IANA timezone (e.g. America/New_York), which sets the check-in's local time. Defaults to UNTAPPD_TIMEZONE, else the server's own zone — which on a hosted connector is usually UTC, so pass it when you know where the user is.
photo_pathNoOptional path to a local JPEG/PNG photo (max 15 MB) to attach — it is published publicly. It must be inside the photo directory (UNTAPPD_PHOTO_DIR, default ~/Downloads/untappd-mcp). Only use a file the user explicitly chose; the preview shows the resolved path and size for them to confirm. Local installs only — refused on the hosted connector (use photo_blob_key).
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.
container_idNoOptional serving container id (e.g. 1 = draft, 2 = bottle, 3 = can)
photo_inlineNoOptional photo as base64: {filename, contentBase64, mimeType?}, JPEG or PNG, max 15 MB — it is published publicly. Works on any deployment; for anything but a small photo prefer the upload slot flow (photo_blob_key). Only use a photo the user explicitly chose.
foursquare_idNoOptional Foursquare venue id to tag the check-in location
photo_blob_keyNoOptional blobKey of a photo PUT to a slot from untappd_upload_slots (hosted connector) — it is published publicly. Deleted from the upload store once the check-in and its photo succeed; kept if they fail.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already flag destructive/openWorld/non-idempotent, and the description adds what the annotations cannot: the check-in is published publicly, a preview is shown before posting, the call may not proceed without explicit confirmation, and the uploaded blob is deleted on success but kept on failure. That is real behavioral context beyond the structured hints.

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

Conciseness4/5

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

Front-loaded with the action and the publish-to-feed consequence, and every clause carries operational weight. It is dense with parenthetical detail in a single block, which slightly hurts scanability and partially restates the confirmToken schema text.

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?

For a 12-parameter, nested-photo, publicly-destructive mutation with no output schema, the description covers everything an agent needs: source of the id, mutually exclusive photo channels, deployment restrictions, confirmation flow, and the preview. Nothing material is left unstated.

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

Parameters5/5

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

Schema coverage is 100%, so the baseline would be a 3, but the description adds cross-parameter semantics the schema does not encode: only ONE photo, supplied via exactly one of photo_path/photo_inline/photo_blob_key, with the deployment-dependent constraint on photo_path. It also clarifies the practical default behavior of timezone on a hosted connector.

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?

States a specific verb and resource ("Post a NEW beer check-in") plus scope ("to YOUR Untappd account — this publishes to your public feed"). This clearly separates it from read-side siblings like untappd_checkin_info and from untappd_delete_checkin.

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

Usage Guidelines5/5

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

Explicitly routes the agent: bid comes from untappd_search_beer, photos on a hosted connector go through untappd_upload_slots then a PUT then photo_blob_key, and local paths are refused there. It also spells out the confirmation protocol (client prompt vs preview + confirmToken) rather than leaving it to inference.

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

untappd_checkin_infoGet Untappd check-in detailA
Read-onlyIdempotent

Get full detail for a single check-in by its id: the beer, rating, comment, photos, venue, badges earned, toasts, and comments. Get a check-in id from a feed or user-checkins result. Read-only.

NameRequiredDescriptionDefault
checkin_idYesUntappd check-in id

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and openWorldHint=true. The description reinforces this with 'Read-only.' and adds value by enumerating the returned fields (beer, rating, comment, photos, venue, badges, toasts, comments), which gives the agent expectations about the response content beyond what annotations provide. This extra context justifies a 4 rather than a baseline 3.

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

Conciseness5/5

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

The description is two sentences, with the main purpose front-loaded and the extra field list and usage hint placed logically. There is no redundant wording, and every sentence earns its place. This is an excellent example of concise, structured tool documentation.

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?

Given only one required parameter, read-only annotations, and no output schema, the description is very complete. It enumerates the fields returned (compensating for the missing output schema), explains how to source the id, and confirms safety via the read-only hint. Nothing an agent needs to invoke this tool correctly is missing.

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 100% (checkin_id has a description), so the baseline is 3. The description adds extra meaning by explaining where to obtain the id ('from a feed or user-checkins result'), which helps the agent understand the relationship between this tool and other Untappd tools. That is genuinely useful beyond the schema, so a 4 is appropriate.

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?

The description states a specific verb ('Get') and resource ('full detail for a single check-in by its id'), and lists the fields included (beer, rating, comment, photos, venue, badges, toasts, comments). This clearly distinguishes it from sibling tools like untappd_checkin (probably a create) and feed-related tools, which is evident from the context.

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?

It gives clear guidance on how to obtain the input: 'Get a check-in id from a feed or user-checkins result.' This implies when to use the tool—after getting an id from a feed—but does not explicitly state exclusions or alternatives. It's clear context without explicit 'when not to' guidance, so not a 5.

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

untappd_delete_checkinDelete an Untappd check-inA
DestructiveIdempotent

Permanently delete one of YOUR check-ins by its id. This is destructive and cannot be undone. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

NameRequiredDescriptionDefault
checkin_idYesUntappd check-in id
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already flag destructiveHint=true, and the description adds crucial detail: permanence ('cannot be undone'), the requirement to ask the user first, and the preview/confirmToken fallback mechanism. This meaningfully exceeds what the annotations alone convey.

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

Conciseness5/5

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

The description is compact and front-loaded: purpose first, then safety, then confirmation mechanics. Every sentence adds necessary information without repeating schema content.

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?

For a destructive tool with no output schema, the description fully covers what an agent needs: what is deleted, irreversibility, user confirmation requirements, and how the confirmToken fallback sequence works. Nothing critical is missing for correct invocation.

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

Parameters3/5

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

Schema coverage is 100%, and both parameters already have detailed descriptions in the schema. The description adds ownership context for checkin_id and relates confirmToken to the confirmation flow, but the schema already carries most of the parameter semantics.

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?

The description states a specific verb and resource: 'delete one of YOUR check-ins by its id'. It clearly scopes the operation to the user's own check-ins, distinguishing it from sibling tools like untappd_delete_comment.

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?

The description clearly says this is a destructive, irreversible action and explains the confirmation flow, including the two-step fallback with a confirmToken. It provides strong context but does not explicitly name sibling alternatives or say when not to use it.

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

untappd_delete_commentDelete a comment from an Untappd check-inA
DestructiveIdempotent

Delete one of YOUR comments by its comment id (the id from a check-in's comments list). Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

NameRequiredDescriptionDefault
comment_idYesUntappd comment id (from a check-in's comments.items)
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.4/5.0
Behavior5/5

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

Beyond the annotations' destructive/idempotent hints, the description explains the confirmation prompt, the two-step fallback with preview and confirmToken, and the requirement that a repeat call must carry that token. It also stresses ownership ('YOUR comments'), which is important behavioral context.

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

Conciseness5/5

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

Two sentences front-load the core deletion action and ownership scope, then efficiently explain the confirmation behavior and the MCP_CONFIRM_MODE fallback. There is no filler or redundancy.

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

Completeness4/5

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

The description covers the confirmation protocol, token lifecycle, and ownership constraint, and the schema covers parameters. With no output schema, it could be even more explicit about the post-confirmation success response, but nothing essential to invoking the tool correctly is missing.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents both parameters thoroughly. The description restates the origin of comment_id and summarizes the confirmation flow, but adds little parameter-level meaning beyond the schema.

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?

The description names a specific action ('Delete one of YOUR comments'), the target resource ('a comment from an Untappd check-in'), and the identifier ('comment id from check-in's comments list'). This clearly distinguishes it from siblings like untappd_add_comment and untappd_delete_checkin.

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?

It clearly identifies the use case: deleting only the user's own comment when the comment id is known. It does not explicitly mention alternatives or when not to use this tool, but the ownership and id conditions make the context clear.

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

untappd_favorite_addMark a beer, brewery or venue as a favorite (local)A
Idempotent

Add a MANUAL favorite — a beer, brewery or venue — with an optional note, to the local cache. Local to the cache — NEVER writes to Untappd (Untappd has no favorites API for this). Re-adding an existing favorite updates its note (omit note to keep it) and keeps its created_at. Manual favorites show in untappd_favorites_list (source "manual") and as the favorite field on has_had, has_had_many, has_visited, brewery_beers, venue_menu, top_not_had and trip_check results; a favorite brewery also boosts its beers in untappd_top_not_had. Omit username for your own account.

NameRequiredDescriptionDefault
idYesThe Untappd bid / brewery_id / venue_id
kindYesWhat the id is: a beer (bid), brewery (brewery_id) or venue (venue_id)
noteNoWhy it is a favorite (shown as the reason)
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare idempotentHint=true and openWorldHint=false, but the description adds the concrete mechanics: the write stays local and never reaches Untappd, re-adding merges into the existing record by updating the note while preserving created_at, and the result surfaces in untappd_favorites_list and as a `favorite` field on seven named tools. That is materially more than the annotations provide.

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

Conciseness4/5

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

Front-loaded with the core action and the local-only constraint, then the update/merge rule, then the visibility list. Dense and mostly earning its place, though the long enumeration of downstream surfaces is the least essential clause.

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

Completeness4/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 correctly shifts to describing effects (what is created, what is preserved on re-add, where it appears), which is what an agent needs. It stops short of covering failure modes such as an id that does not exist in the local cache, so it is strong but not exhaustive for a mutation 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 100%, so the baseline would be 3, but the description adds real semantics beyond the schema: omitting `note` on a re-add preserves the existing note rather than clearing it, and the `kind` parameter's relationship to the id is implicitly enforced by the enumeration. `username` omission is restated from the schema rather than newly explained.

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?

Names a specific verb (add/favorite) and resource (beer, brewery or venue) and immediately pins the scope: 'MANUAL favorite ... to the local cache' with 'NEVER writes to Untappd'. That distinguishes it from a remote-write tool and from the sibling untappd_favorite_remove without opening either schema.

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 clear operating context: use it for local/manual favorites, re-adding is an update path, and username can be omitted for your own account. It does not explicitly contrast with the adjacent sibling untappd_wishlist_add, so an agent must infer favorite-vs-wishlist selection on its own.

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

untappd_favorite_removeRemove a manual favorite (local)A
Idempotent

Remove a MANUAL favorite (beer, brewery or venue) from the local cache. Local to the cache — NEVER writes to Untappd (Untappd has no favorites API for this). Returns removed:false when there was none. A DERIVED favorite (from the user's history) cannot be removed — it is computed from the thresholds; change them in untappd_favorites_list instead. Omit username for your own account.

NameRequiredDescriptionDefault
idYesThe Untappd bid / brewery_id / venue_id
kindYesWhat the id is: a beer (bid), brewery (brewery_id) or venue (venue_id)
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).

TDQS

A4.7/5.0
Behavior5/5

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

Goes well beyond the annotations (readOnly=false, destructive=false, idempotent=true, openWorld=false) by disclosing the local-only guarantee ('NEVER writes to Untappd'), the exact failure return ('removed:false' when nothing existed, consistent with idempotentHint), and the manual-vs-derived distinction that determines whether removal is even possible. No contradiction with annotations.

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

Conciseness5/5

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

Four short sentences, front-loaded with the core action and scope, then the local-only guarantee, then the edge cases (removed:false, derived favorites, username default). Every clause carries decision-relevant information; nothing is filler.

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?

For a 3-param mutation tool with no output schema, the description covers what it operates on, what it does not touch (upstream Untappd), the return behavior on no-op, and how derived favorites differ. An agent has everything needed to call it correctly and to interpret the result.

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

Parameters3/5

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

Schema description coverage is 100%, so all three parameters (id, kind enum, username) are already documented, giving a baseline of 3. The description's only added param guidance, 'Omit username for your own account,' essentially restates the schema's own wording, so it adds little beyond structured fields.

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?

States a specific verb (Remove), a specific resource (a MANUAL favorite of kind beer/brewery/venue), and its scope (local cache only). It immediately distinguishes the tool from untappd_favorite_add and untappd_favorites_list, so an agent can route correctly without opening the schema.

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

Usage Guidelines5/5

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

Gives explicit when-not guidance: a DERIVED favorite cannot be removed and must be adjusted via untappd_favorites_list thresholds instead, naming the sibling to use. It also states the default-account convention (omit username for your own account), leaving nothing to inference.

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

untappd_favorites_listList a user's favorite beers, breweries and venuesA
Read-onlyIdempotent

List a user's favorites from the cache only — NO API call. Each item appears ONCE with every source that names it (sources: "derived" = qualifies from their cached history, "manual" = added with untappd_favorite_add, "untappd" = a brewery the user likes/follows on Untappd, mirrored by untappd_sync_brewery_likes — breweries only: Untappd has no followed/favorite venue list) and a reason ("liked on Untappd (since 2021-03)", "12 check-ins since 2015", "avg 4.1 across 9 beers", "manual: "). Derived rules, each overridable via thresholds: venue = ≥5 check-ins OR visits spanning ≥3 distinct months (ranked by check-ins); brewery = ≥5 beers had AND avg rating ≥3.75, OR ≥15 beers (ranked by count blended with rating); beer = rated ≥4.25 OR had ≥3 times. Derived favorites are only as complete as the syncs behind them (untappd_sync_user_venues, untappd_sync_user_beers); "untappd" ones as the last untappd_sync_brewery_likes (freshness.brewery_likes). Filter by kind and source. Omit username for your own account.

NameRequiredDescriptionDefault
kindNoOnly this kind (default all three)
limitNoMost items per kind (default 50)
sourceNoOnly favorites carrying this source
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
thresholdsNoOverride the derived-favorite thresholds (each optional; omitted ones keep their defaults).

TDQS

A4.4/5.0
Behavior5/5

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

Goes well past the readOnly/idempotent annotations: cache-only with no network call, de-duplication guarantee ('each item appears ONCE with every source that names it'), the full meaning of each source value, sample reason strings, and an explicit freshness caveat tied to specific sync tools. This is exactly the behavioral context the annotations cannot express.

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 critical constraint ('cache only — NO API call') is front-loaded, which is good. But the remainder is one very long paragraph of nested parentheses mixing source definitions, threshold algebra and freshness caveats, with no line breaks or bullet structure — hard to scan and easy to misparse mid-sentence.

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

Completeness4/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 return-shape burden and does so reasonably: it explains per-item dedup across sources, the reason string and its formats, and ranking rules per kind. It stops short of describing the remaining per-item fields (identity, name, counts) or how the per-kind limit interacts with ordering after filtering.

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 100%, so the baseline is 3, but the description earns more by defining what 'derived', 'manual' and 'untappd' actually mean, noting the brewery-only limitation for 'untappd', and spelling out how threshold values combine (OR/AND rules per kind) — logic the schema's flat defaults cannot convey. The combination semantics are the main added value; individual defaults are already in the schema.

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?

States a specific verb and resource ('List a user's favorites') scoped to three kinds (beer, brewery, venue) and pins the execution model with 'from the cache only — NO API call'. That immediately separates it from live-fetch siblings like untappd_user_checkins or untappd_brewery_info.

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 concrete use conditions: filter by kind and source, omit username for your own account, and warns that derived results depend on prior untappd_sync_user_venues/untappd_sync_user_beers runs and that 'untappd' brewery likes depend on the last untappd_sync_brewery_likes. It never explicitly contrasts against neighbor tools like untappd_favorite_add or untappd_user_wishlist, so it stops short of full when/when-not routing.

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

untappd_healthcheckUntappd healthcheckA
Read-onlyIdempotent

Verify Untappd connectivity and that credentials are configured and can log in. Performs a lightweight authenticated request (your recent feed) and reports whether it succeeded, plus the running server version and the exact set of tools this build exposes (count, a stable hash, and their names) so you can confirm which build is live. Read-only.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already mark the tool read-only, idempotent, and open-world. The description adds meaningful behavioral detail beyond those hints: it performs a lightweight authenticated request to the recent feed, reports success/failure, and returns server version plus a hashed tool manifest. This fully discloses what the agent should expect.

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

Conciseness5/5

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

Two focused sentences, with the core purpose front-loaded and supporting output details in the second sentence. Every clause adds value: connectivity, credential login, request behavior, response contents, and read-only safety.

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?

Despite lacking an output schema, the description tells the agent exactly what will be reported: success, server version, tool count, stable hash, and tool names. For a no-input healthcheck tool, nothing needed for correct invocation is missing.

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?

The tool has zero parameters and its schema coverage is effectively 100%, so there is no parameter burden for the description to carry. The baseline of 4 for zero-param tools applies here; the description appropriately omits parameter details because none exist.

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?

The description uses specific verbs and resources: 'Verify Untappd connectivity', 'credentials are configured and can log in', and 'confirm which build is live'. It is clearly distinguishable from all sibling tools, which focus on beer, venue, user, or social operations rather than system health.

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?

The description makes the usage context evident: use this tool when you need to verify connectivity, credential validity, and the live build's tool set. It does not explicitly name alternatives or exclusions, but the healthcheck role is unique among siblings, so the absence of alternative routing is not a significant gap.

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

untappd_local_checkinsGet nearby Untappd check-insA
Read-only

Get recent check-ins near a location (lat/lng) — what people are drinking nearby right now. Optionally widen the search radius. Read-only.

NameRequiredDescriptionDefault
latYesLatitude of the location
lngYesLongitude of the location
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact projects each check-in to {id, user, beer, brewery, venue, rating, comment, toast/comment counts}; "full" returns Untappd's whole ~5 KB record.
limitNoMax check-ins (1–50, default 25)
radiusNoSearch radius (default per Untappd)

TDQS

A3.7/5.0
Behavior3/5

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

The description repeats the read-only annotation and adds that results are 'recent' and 'right now,' which hints at the live, non-idempotent nature of the data. It does not add operational details like auth requirements, rate limits, ordering, or response size; since annotations already cover the safety profile, this is adequate but not rich.

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

Conciseness4/5

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

The core description is a single, front-loaded sentence that conveys purpose, location scope, live freshness, and optional radius widening. The trailing 'Read-only.' is redundant with the readOnlyHint annotation and adds no new information, which prevents a perfect score.

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

Completeness4/5

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

For a five-parameter tool, completeness is mostly carried by the annotations and the fully descriptive input schema, including the view parameter's explanation of compact vs. full response shapes. The description is not burdened with re-documenting parameters and is sufficient for safe invocation, though it lacks explicit alternative routing and operational details like auth or rate limits.

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

Parameters3/5

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

Schema description coverage is 100%, with detailed descriptions for lat/lng ranges, the view enum's response shapes, the limit default, and radius defaults. The description adds only a minor reinforcement by saying 'near a location (lat/lng)' and 'Optionally widen the search radius,' so it provides no substantial meaning beyond the schema.

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?

The description opens with a specific verb and resource—'Get recent check-ins near a location (lat/lng)'—and clarifies the real-world intent with 'what people are drinking nearby right now.' This clearly distinguishes it from siblings like untappd_user_checkins, untappd_trending, or untappd_activity_feed by anchoring the tool to lat/lng proximity.

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

Usage Guidelines3/5

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

The description implies the tool is for location-scoped, current check-ins and mentions that the search radius can be widened, which gives some usage context. However, it never names alternatives or states when to prefer this over untappd_trending or untappd_activity_feed, so the when-to-use guidance remains implied rather than explicit.

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

untappd_menu_pickPick beers off a tap list that a user hasn't hadA

One call from a tap list to "order this": give the raw menu lines as read from a photo and get back the top-rated beers the user has NOT had. It (1) refreshes the user's distinct-beers cache — an incremental refresh when the cache is complete, otherwise it backfills automatically within api_budget, no separate sync needed; (2) resolves each line to an Untappd beer (prices/punctuation stripped, scored on brewery + name match and check-in volume, venue_city as tie-breaker; resolutions are cached locally so repeat venues are instant); (3) treats " SEASONAL/ROTATING" as a list of possible beers (needs_confirmation) and "ROTATING CIDER"-style lines as unresolved ("ask bartender"); (4) checks every beer against the cache; (5) ranks the not-had ones by global rating. Returns picks, not_had, had, possible, unresolved, a sync block (what the refresh did) and freshness (coverage); if coverage is still incomplete a "not had" may be a false negative and another_run_needed is true. api_budget is also capped to the quota Untappd reports, when it reports one. Omit username for your own account.

NameRequiredDescriptionDefault
itemsYesRaw menu lines as read from the menu, e.g. ["JACKALOPE FENNARIO IPA $7", "BLACK ABBEY SEASONAL", "ROTATING CIDER"].
top_nNoHow many picks to return (default 2, max 10).
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
api_budgetNoMax Untappd API calls this run, shared by the cache sync, searches and rating lookups (default 60; Untappd allows ~100/hour). If it runs out, the result says another_run_needed and a re-run continues from what was cached.
venue_cityNoCity of the venue (e.g. "Nashville") — breaks ties between same-named beers toward local breweries.
style_filterNoCase-insensitive substring filter on the beer style or parent style for the picks (e.g. "ipa", "stout").
refresh_resolutionsNoIgnore cached line→beer matches and re-search every line (default false).

TDQS

A4.6/5.0
Behavior5/5

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

With readOnlyHint=false and idempotentHint=false already declared, the description goes well beyond the annotations: it discloses the implicit cache write/backfill, api_budget consumption shared across sync/searches/lookups, the Untappd-reported quota cap, local resolution caching, and the false-negative risk when coverage is incomplete. That is exactly the mutation/rate-limit context an agent needs before calling.

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

Conciseness4/5

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

Purpose is front-loaded in the first clause and the numbered pipeline makes the five stages easy to scan. It is dense and long for a description, with some load-bearing detail (quota cap, cache refresh semantics) buried inside the step list rather than split into its own sentence.

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?

For a 7-parameter tool with no output schema, the description enumerates the returned block (picks, not_had, had, possible, unresolved, sync, freshness) plus the another_run_needed signal, and explains how partial coverage produces false negatives. Nothing an agent needs to call it correctly or interpret the response is missing.

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 100%, so baseline is 3; the description still adds meaning on top, notably that api_budget is also clamped to the quota Untappd reports, that venue_city acts as a same-name tie-breaker, and that omitting username targets the caller's own account. Items handling is deferred to the schema example, which is reasonable.

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?

States a concrete verb and resource: takes raw menu lines transcribed from a photo and returns top-rated beers the user has NOT had. The input/output framing (

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 a clear situational trigger (one call from a tap list to "order this") and explicitly says no separate sync step is needed, which preempts a likely wrong turn toward sync tools. It never names an alternative such as untappd_venue_pick or untappd_top_not_had, so there is no explicit when-not-to-use guidance.

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

untappd_notificationsGet your Untappd notificationsA
Read-only

Get your Untappd notifications — toasts, comments, friend requests, and badges earned on YOUR account, plus news items. Read-only.

NameRequiredDescriptionDefault
limitNoMax notifications (1–50, default 25)
offsetNoResult offset for paging (default 0)

TDQS

A4.1/5.0
Behavior3/5

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

The description states 'Read-only,' which matches the readOnlyHint annotation but adds no new behavioral information beyond it. It does provide useful context about the account scope and included item types, but does not disclose details such as ordering, pagination behavior beyond schema parameters, or whether the operation requires authentication.

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

Conciseness5/5

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

The description is a single sentence that front-loads the verb and resource, then adds a compact list of notification categories and scope. It is concise, direct, and contains no filler or repetition beyond the useful 'Read-only' note.

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?

For a simple, read-only, two-optional-parameter list operation, the description is complete: it states the resource, scope, and content types, and the schema already documents pagination. No output schema exists, but the description's category list sufficiently conveys what the response will contain.

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

Parameters3/5

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

Input schema coverage is 100%, with both limit and offset fully described including defaults, minimums, and maximums. The description adds no parameter-specific meaning, so the schema carries the weight; baseline 3 is appropriate.

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?

The description uses a specific verb ('Get') and resource ('your Untappd notifications'), scopes it to YOUR account, and enumerates the notification categories (toasts, comments, friend requests, badges, news items). This clearly distinguishes it from sibling user-lookup tools like untappd_user_badges or untappd_activity_feed by emphasizing the current user's notification feed rather than a generic or other-user resource.

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?

The description gives clear context: it is for the authenticated user's own notifications, including specific types. It does not explicitly name alternatives or say when not to use it, but the 'YOUR account' scoping and category list are enough to imply the appropriate use case and separate it from user-specific and activity-feed siblings.

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

untappd_open_urlOpen an Untappd URL (resolve + fetch)A
Read-onlyIdempotent

Resolve an untappd.com URL AND fetch the entity detail in one call — the convenience combination of untappd_resolve + the matching info tool. Returns { resolved, detail }. Read-only.

NameRequiredDescriptionDefault
urlYesAn untappd.com URL to resolve and fetch

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, openWorldHint, and idempotentHint. The description adds useful behavioral context beyond those: it performs two steps (resolve + fetch), does so in one call, and returns a { resolved, detail } shape. This is meaningful for an agent deciding whether this tool satisfies a need.

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

Conciseness5/5

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

The description is one efficient sentence that front-loads the core action, names its constituent tools, and gives the return shape. Every clause earns its place without redundancy or filler.

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

Completeness4/5

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

This is a simple one-parameter tool with strong annotations and no output schema. The description explains the return value shape and references the matching info tool, which is enough context to call it correctly. It could be more explicit about what 'detail' contains, but that gap is minor for invocation.

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

Parameters3/5

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

Schema coverage is 100%, with the single url parameter already described as 'An untappd.com URL to resolve and fetch.' The description adds no new format, normalization, or validation details, so it stays at the baseline 3 rather than earning extra credit.

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?

The description uses a specific verb combination—'resolve AND fetch'—and clearly names the resource: an untappd.com URL. It also distinguishes itself by explicitly presenting the tool as a convenience combination of untappd_resolve and the matching info tool, so an agent can separate it from those siblings.

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?

The description gives clear usage context: use this when you want both URL resolution and entity detail in a single call. It references the alternative tools (untappd_resolve and the matching info tool), though it doesn't explicitly state when to prefer those separate tools, so it stops short of full exclusions.

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

untappd_pending_friendsGet your pending friend requestsA
Read-onlyIdempotent

Get the incoming friend requests waiting on YOUR account — the users who have requested to be your friend. Read-only.

NameRequiredDescriptionDefault
limitNoMax requests (1–50, default 25)
offsetNoResult offset for paging (default 0)

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and openWorldHint=true, so the read-only nature is covered. The description adds meaningful behavioral context by specifying the requests are 'waiting on YOUR account' and are incoming, clarifying scope and direction beyond the annotations. It does not contradict annotations.

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

Conciseness5/5

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

A single sentence that is front-loaded with the verb and resource, followed by a clarifying clause. There is no fluff; the 'Read-only' note is a brief reinforcement of the annotation. Every part of the description earns its place.

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

Completeness4/5

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

For a simple read-only list operation with two optional, well-documented parameters and no output schema, the description sufficiently explains what the tool returns (incoming friend requests) and whose account it applies to. It lacks explicit mention of pagination behavior beyond the schema, but that is minor. The lack of an output schema means the description need not detail return fields, and the provided scope is enough for an agent to invoke correctly.

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

Parameters3/5

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

Schema description coverage is 100%: both limit and offset have complete descriptions with ranges and defaults. The tool description adds nothing about how these parameters behave in practice, but it doesn't need to since the schema fully documents them. Baseline 3 is appropriate.

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?

The description uses the specific verb 'Get' and clearly identifies the resource: incoming friend requests waiting on your account. It explicitly distinguishes these as incoming requests from users who have requested to be your friend, which differentiates it from sibling tools like untappd_user_friends or action tools like accept/reject.

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

Usage Guidelines3/5

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

The description clearly implies this tool is for viewing pending incoming friend requests, but it does not explicitly state when to use it instead of alternatives such as untappd_user_friends or untappd_notifications. There is no mention of exclusions or direction to accept/reject tools after fetching. Usage context is inferred rather than explicit.

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

untappd_reject_friendReject an Untappd friend requestA
DestructiveIdempotent

Rejects/ignores an incoming friend request (see untappd_pending_friends for pending uids). Acts on YOUR account and affects a real relationship with another person. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE). Note: this endpoint path is taken from the Untappd app but is not otherwise independently verified.

NameRequiredDescriptionDefault
target_uidYesThe target user id (uid) — from a user profile (response.user.uid) or a friends-list item
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.3/5.0
Behavior5/5

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

The description goes well beyond the annotations by explaining that the action affects a real relationship, requires user confirmation, has a two-step fallback with confirmToken, and notes the endpoint is not independently verified. This is rich behavioral context that annotations alone do not provide.

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

Conciseness4/5

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

The description is somewhat dense, especially the confirmation-workflow sentence, but each sentence contributes essential information: action, data source, relationship impact, confirmation behavior, and reliability caveat. Everything earns its place, but the phrasing could be tighter.

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?

For a destructive, confirmation-requiring tool with no output schema, the description covers the full invocation workflow: identifying pending uids, confirming with the user, and handling the two-step token fallback. The endpoint-verification caveat is an appropriate extra. Nothing critical is missing.

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 100% and both parameters have detailed descriptions, providing a solid baseline. The description adds meaningful guidance on where to find the target_uid (via untappd_pending_friends), which is directly relevant to this tool's use case and not fully captured in the schema.

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

Purpose4/5

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

The description uses a specific verb 'Rejects/ignores' and a clear resource 'incoming friend request', making the tool's purpose obvious. It is clearly distinct from accept_friend and remove_friend by the 'incoming' qualifier, though it does not explicitly name those siblings as alternatives.

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?

The description points to untappd_pending_friends as the source for pending uids, giving the agent a concrete place to obtain the target_uid. It clearly implies this tool is for rejecting/ignoring incoming requests, though it does not state when to prefer accept_friend or remove_friend.

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

untappd_remove_friendRemove an Untappd friendA
DestructiveIdempotent

Removes an existing friend, or cancels a friend request you sent. Acts on YOUR account and affects a real relationship with another person. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE). Note: this endpoint path is taken from the Untappd app but is not otherwise independently verified.

NameRequiredDescriptionDefault
target_uidYesThe target user id (uid) — from a user profile (response.user.uid) or a friends-list item
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.3/5.0
Behavior5/5

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

Beyond the annotations (destructiveHint=true, readOnlyHint=false, idempotentHint=true), the description discloses that it affects a real relationship, requires user confirmation (with a two-step token fallback), and notes that the endpoint path is not independently verified. This adds significant behavioral context not captured by the annotations.

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

Conciseness4/5

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

The description is a single, dense paragraph that front-loads the core purpose, then details the confirmation flow and caveat. It is not overly verbose, though it could be split into shorter sentences for easier scanning. Every sentence earns its place.

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

Completeness4/5

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

Given the tool's destructive nature and the lack of an output schema, the description adequately covers the action, the confirmation mechanism, and the verification caveat. It does not describe the success/error response format, but that is not required when no output schema is present and the core flow is clearly explained.

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

Parameters3/5

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

Schema description coverage is 100%, so both parameters are already well documented. The description does not add additional parameter-level detail beyond what the schema provides; the confirmToken explanation is already thorough in the schema. Thus the baseline of 3 is appropriate.

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?

The description uses a specific verb ('Removes') and resource ('an existing friend, or cancels a friend request'), which clearly distinguishes it from sibling tools like add_friend, accept_friend, and reject_friend. It states exactly what action occurs and on whose account.

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?

The description conveys when to use the tool: to remove an existing friend or cancel an outgoing request, which differentiates it from accept/reject (for incoming requests). It does not explicitly name alternatives, but the purpose is clear enough. The confirmation flow is also outlined, but no explicit 'when not to use' is given.

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

untappd_resolveResolve an Untappd URLA
Read-onlyIdempotent

Parse an untappd.com URL (a beer /b/, brewery /w/, venue /v/, user /user/, or check-in link) into its entity type and id, and name the tool to call next. Pure local parsing — no network. Read-only.

NameRequiredDescriptionDefault
urlYesAn untappd.com URL to resolve

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, and the description adds meaningful behavioral context: 'Pure local parsing — no network' and the fact that it returns a routing decision. There is no contradiction between the description and the annotations.

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

Conciseness5/5

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

Two sentences with no filler. The action, input scope, output, and key behavioral property (no network) are all front-loaded. Every sentence earns its place.

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

Completeness4/5

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

For a simple one-parameter resolver with no output schema, the description conveys the essential return semantics: entity type, entity id, and the next tool to call. It does not cover invalid/unsupported URL behavior, but that is a minor gap given the tool's simplicity.

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?

The schema already documents the 'url' parameter with 100% coverage, and the description adds value by explaining which URL forms are valid and what the resolver extracts from them. This goes beyond the schema's generic 'An untappd.com URL to resolve'.

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?

The description states a specific verb ('Parse'), a specific resource ('untappd.com URL'), and a concrete output ('entity type and id, and name the tool to call next'). The enumerated URL path forms (/b/, /w/, /v/, /user/, check-in) make its scope clear and distinguish it from sibling tools that fetch or search data.

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?

The description gives clear context for when to use this tool: when you have a raw Untappd URL and need to determine the entity type and route to the next appropriate tool. It also clarifies the local, no-network nature. However, it does not explicitly say when not to use it or compare it with the similar-looking sibling untappd_open_url.

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

untappd_search_beerSearch Untappd beersA
Read-onlyIdempotent

Search Untappd for beers by name (optionally "Brewery Beer"). Returns ranked matches with their beer id (bid), brewery, style, ABV, IBU, and global rating. Feed a bid into untappd_beer_info for full detail. Read-only.

NameRequiredDescriptionDefault
sortNoSort order: checkin (relevance, default), name, or count
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact projects each match to {bid, name, style, abv, ibu, brewery, checkin_count, have_had}; "full" returns Untappd's whole ~1.2 KB search item, including the long beer_description and the nested brewery record.
limitNoMax results (1–50, default 25)
queryYesBeer name to search for
offsetNoResult offset for paging (default 0)

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already cover read-only, idempotent, and open-world behavior. The description adds useful context beyond those: results are ranked matches carrying a compact field set, and the search response is intentionally not the full detail record—that is delegated to untappd_beer_info. It also restates 'Read-only' consistently without contradicting annotations.

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

Conciseness5/5

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

Three concise, front-loaded sentences: what it searches, what it returns, and where to go next. Every sentence adds value and there is no redundant repetition of schema details.

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?

There is no output schema, so the description properly enumerates the returned fields and the follow-up action for details. The input schema fully documents all parameters and defaults, leaving the agent with everything needed to select and invoke the tool correctly.

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 100%, so baseline is 3. The description adds the useful 'Brewery Beer' query format hint and clarifies the response includes ranked matches with specific fields, which enriches the query parameter semantics beyond the schema's generic 'beer name to search for'.

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?

The description clearly states the tool searches Untappd for beers by name, optionally in 'Brewery Beer' format, and lists the exact fields returned. This distinguishes it from sibling tools like untappd_search_brewery and untappd_beer_info, with an explicit pointer to untappd_beer_info for full detail.

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?

The description gives a clear usage context: use this to find beers by name, then feed a returned bid into untappd_beer_info for full detail. It does not explicitly enumerate when not to use sibling search tools, but the 'Brewery Beer' hint and the routing to beer_info provide clear practical guidance.

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

untappd_search_brewerySearch Untappd breweriesA
Read-onlyIdempotent

Search Untappd for breweries by name. Returns matches with their brewery id, location, type, and beer count. Feed a brewery id into untappd_brewery_info for full detail. Read-only.

NameRequiredDescriptionDefault
limitNoMax results (1–50, default 25)
queryYesBrewery name to search for
offsetNoResult offset for paging (default 0)

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and idempotentHint, so the 'Read-only' sentence adds no new safety information. However, the description adds useful behavioral context beyond the annotations by specifying what a match contains and that this is a lightweight search step before fetching full brewery detail.

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

Conciseness4/5

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

Three focused sentences with the core action first and the follow-up routing last. The only redundancy is 'Read-only', which duplicates the readOnlyHint annotation already present.

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

Completeness4/5

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

For a simple search tool with one required parameter and no output schema, the description gives enough return-value detail and next-step guidance. It could additionally mention pagination behavior, but the limit/offset fields are already documented in the schema.

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

Parameters3/5

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

Schema description coverage is 100%, and the input schema already documents 'query', 'limit', and 'offset' clearly. The description only restates that the search is by name and does not add parameter-level meaning beyond the schema.

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?

States a specific action and resource: search Untappd for breweries by name. It also describes the returned fields (brewery id, location, type, beer count) and explicitly routes the caller to untappd_brewery_info for full detail, which differentiates it from sibling tools like untappd_search_beer and untappd_brewery_info.

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?

The description makes clear this is the search-by-name entry point and that a brewery id should then go into untappd_brewery_info. It does not explicitly state when to choose this over untappd_search_beer, but the brewery-specific wording and follow-up routing provide clear context.

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

untappd_search_venueSearch Untappd venuesA
Read-onlyIdempotent

Search Untappd for venues (bars, breweries, restaurants) by name. Returns matches with their venue id, category, and location. Feed a venue id into untappd_venue_info for full detail. Read-only.

NameRequiredDescriptionDefault
limitNoMax results (1–50, default 25)
queryYesVenue name to search for

TDQS

A4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is covered. The description adds that results are matches containing venue id, category, and location, but it restates 'Read-only' without adding further behavioral context like matching semantics, rate limits, or empty-result behavior. There is no contradiction with annotations.

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

Conciseness4/5

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

The description is compact and front-loaded: action, resource, output, and next step in three short sentences. It is highly readable, though 'Read-only' duplicates the readOnlyHint annotation and does not earn its place when annotations are available.

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?

For a simple two-parameter, read-only search tool with no output schema, the description covers everything an agent needs: what to search, what the response contains (venue id, category, location), and the next step to get full detail. The schema already handles parameter constraints such as limit range and default.

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

Parameters3/5

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

Schema description coverage is 100%, with both query and limit documented (including min/max and default). The description reinforces that query means a venue name and that the result includes a venue id, but it does not add significant meaning beyond the schema. Baseline 3 is appropriate.

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?

The description states a specific verb ('Search'), resource ('venues'), and scope ('by name'), and clarifies venue types in parentheses (bars, breweries, restaurants). It also names the key output fields (venue id, category, location), which makes it immediately distinguishable from sibling search tools like untappd_search_beer and untappd_search_brewery.

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?

The description clearly frames when to use this tool: when you need to find a venue by name. It also provides a concrete follow-up path by saying to feed the returned venue id into untappd_venue_info for full detail. It does not explicitly list exclusions such as beer or brewery searches, but the context is clear enough.

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

untappd_sync_brewery_likesSync a user's liked (followed) breweries into the cacheA

Mirror the breweries a user "likes" on Untappd (user/brewerylikes — the app calls them "followings"; works for other users' public/friend accounts) into the local cache. Liked breweries then count as favorites with source "untappd" — in untappd_favorites_list, the favorite field on has_had / brewery_beers / venue_menu / top_not_had / trip_check results, and the prefer_favorites boost. Each sync is a full pass from the top (~50 breweries per call), adding new likes and — once the pass finishes — dropping unliked ones (a partial pass never deletes). Resumable: saves progress every page; run again until another_run_needed is false (reports cached/total and percent). Stops BEFORE the ~100 calls/hour rate limit (or cleanly on a 429) with stopped_for_rate_limit and rate_limit.resume_at. Only reads Untappd. Untappd has NO followed/favorite VENUE list, so venue favorites stay derived + manual. (brewery/info's follow_status is the signed-in account's, never another user's — this list is the way to see theirs.) Omit username for your own account.

NameRequiredDescriptionDefault
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
max_pagesNoPages (~50 breweries each) to fetch this run (default 10, max 50).

TDQS

A4.9/5.0
Behavior5/5

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

The description goes far beyond the annotations by explaining complex behavioral traits like resumability, progress tracking, and the 'full pass' update logic (adding and dropping items). It also handles operational concerns like rate limiting.

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

Conciseness4/5

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

While highly detailed, the definition is logically structured, front-loading the core purpose before descending into technical specifics about syncing and rate limits. Its length is a necessary byproduct of the tool's complexity.

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?

Given the complexity of cache syncing and the lack of an output schema, the description provides a maximal amount of context regarding its operational mechanics, scope, and state management.

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

Parameters5/5

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

The description adds significant semantic value by clarifying that omitting the username targets the local account, and it contextualizes the `max_pages` parameter by defining the rate at which breweries are processed.

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?

The description clearly states the specific action (sync) and resource (user liked breweries) while distinguishing it from other methods by focusing on caching and mirroring Untappd followings.

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

Usage Guidelines5/5

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

It provides crucial usage constraints, such as omitting the username to target the current account, and explicitly defines the limitation that venue favorites remain external to this sync mechanism.

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

untappd_sync_checkinsSync a user's check-ins into the cacheA

Fetch a user's detailed check-ins (venue, date, comment) into the cache from user/checkins. Incremental and resumable: pages backwards up to max_pages per call, persisting progress every page; run again until another_run_needed is false. NOTE: Untappd only returns the ~50 most recent check-ins for accounts other than your own and will not page further — such a sync reports history_truncated and you should use untappd_sync_user_beers for full has-had coverage. backfill_complete is only reported once ~all of total_checkins is cached. Pass force_backfill: true to reset a cache wrongly marked complete and re-page the whole history (cached rows are kept). Stops BEFORE the ~100 calls/hour rate limit (or cleanly on a 429) with stopped_for_rate_limit and rate_limit.resume_at — progress is saved; re-run after that time. Omit username for your own account.

NameRequiredDescriptionDefault
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
max_pagesNoPages (50 check-ins each) to fetch this run (default 10). Keep modest to respect the ~100 calls/hour rate limit.
force_backfillNoReset the sync state (clear backfill_complete + cursors) but KEEP cached rows, then re-page the whole history from newest. Use to recover a cache wrongly marked complete.

TDQS

A4.8/5.0
Behavior5/5

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

The annotations say nothing beyond write-capable, non-idempotent, non-destructive, and open-world. The description adds substantial behavioral context: incremental per-page persistence, the ~50-check-in truncation for third-party accounts, backfill_complete semantics, force_backfill keeping cached rows while resetting state, and the ~100 calls/hour rate-limit stop with rate_limit.resume_at and saved progress.

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

Conciseness4/5

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

It is dense but front-loaded: the purpose comes first, then resumability, then the truncation caveat, then backfill, then rate limits. A few clauses repeat the schema text (force_backfill definition) and the sentence is long, but nearly every clause carries operational value.

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?

For a stateful sync tool with no output schema, the description covers what the agent must know: how many pages per call, how to continue, what status signals are returned (another_run_needed, history_truncated, backfill_complete, stopped_for_rate_limit, rate_limit.resume_at), and how to recover from bad state. Nothing needed to invoke or sequence it correctly is missing.

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 100%, so all three parameters are already documented, and the description largely restates them (username omission, keeping max_pages modest for the rate limit, force_backfill keeping cached rows). It does add workflow meaning, such as framing force_backfill as recovery from a wrongly-marked-complete cache and max_pages as a per-run batch, which helps an agent sequence calls.

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?

The description names a specific verb (fetch ... into the cache), the resource (a user's detailed check-ins with venue, date, and comment), and the source endpoint (user/checkins). It is clearly distinguished from sibling read tools like untappd_user_checkins and from untappd_sync_user_beers, which is named as the alternative when history is truncated.

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

Usage Guidelines5/5

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

It explicitly states the usage loop (re-run until another_run_needed is false), the exclusion path (accounts other than your own truncate at ~50; use untappd_sync_user_beers for full has-had coverage), the recovery option (force_backfill for a wrongly-complete cache), and the default-account path (omit username). It also states the rate-limit stopping condition and when to resume.

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

untappd_sync_user_beersSync a user's complete distinct-beers list into the cacheA

Fetch a user's COMPLETE distinct-beers list (every unique beer they've ever had, with their rating, times-had count, and first/last dates) into the cache from user/beers. This is the cheapest way to get full "has had" coverage — thousands of beers instead of tens of thousands of check-ins — and, unlike user/checkins, it pages fully for any public/friend account. Offset-paged and resumable: fetches max_pages per call and persists progress; run again until another_run_needed is false. Feeds the same untappd_cache_has_had / has_had_many / not_had tools. Stops BEFORE the ~100 calls/hour rate limit (or cleanly on a 429) with stopped_for_rate_limit and rate_limit.resume_at — progress is saved; re-run after that time. Omit username for your own account.

NameRequiredDescriptionDefault
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
max_pagesNoPages (50 beers each) to fetch this run (default 10). Keep modest to respect the ~100 calls/hour rate limit.

TDQS

A4.4/5.0
Behavior4/5

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

Goes well beyond the annotations: offset-paged and resumable, progress persisted between calls, paging halts before the ~100 calls/hour limit or on a 429, and which fields signal that stop. That is exactly the operational context annotations cannot carry. It does not, however, say what happens to previously cached beers on a re-run or whether partial progress can be invalidated, so it falls just short of complete.

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

Conciseness4/5

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

Front-loaded with the core purpose, then layered with differentiation, resumability, downstream consumers, and rate-limit behavior — no filler sentences. It is dense to the point of being parenthesis-heavy, which slightly hurts scanability, but every clause carries information an agent would otherwise have to infer.

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?

There is no output schema, so the description carries the full burden of return semantics, and it names the signals an agent must branch on: another_run_needed, stopped_for_rate_limit, and rate_limit.resume_at. It also names the cache tools it feeds (has_had, has_had_many, not_had), closing the loop on what this sync is for.

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

Parameters3/5

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

Schema coverage is 100%, so both parameters are already documented — including the 'omit for own account' case, which the description partly repeats. The description does add real meaning for max_pages by tying it to per-call paging and persisted progress ('fetches max_pages per call and persists progress'), but that is a modest increment over the schema baseline.

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?

States a specific verb and resource ('Fetch a user's COMPLETE distinct-beers list ... into the cache from user/beers') and enumerates the fields returned (rating, times-had, first/last dates). It explicitly distinguishes itself from the sibling path user/checkins, so an agent can separate it from untappd_sync_checkins without opening either schema.

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

Usage Guidelines5/5

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

Gives positive usage ('cheapest way to get full has-had coverage'), an explicit alternative and why it wins ('unlike user/checkins, it pages fully for any public/friend account'), a re-run loop condition ('run again until another_run_needed is false'), and the default-account case ('Omit username for your own account').

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

untappd_sync_user_venuesSync a user's complete venue history into the cacheA

Fetch a user's COMPLETE venue history (every venue they've checked in at, with first/most-recent visit dates and visit count) into the cache from user/venues. Unlike user/checkins — which only returns the ~50 most recent check-ins for anyone but yourself — user/venues pages any public/friend account's whole history, so this is how to answer "has this person been here?" (via untappd_cache_has_visited). Untappd serves 25 venues per page, so a 2,700-venue history is ~110 calls: resumable — fetches max_pages per call, saves progress after every page; run again until another_run_needed is false. Once complete, a re-run is a cheap refresh from the top that stops at the first page with no changed visits (a refresh cut short resumes where it stopped; another_run_needed stays true until it finishes). Stops BEFORE the ~100 calls/hour rate limit (or cleanly on a 429) with stopped_for_rate_limit and rate_limit.resume_at. Omit username for your own account.

NameRequiredDescriptionDefault
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
max_pagesNoPages (25 venues each) to fetch this run (default 10, max 50). Keep modest to respect the ~100 calls/hour rate limit.

TDQS

A4.6/5.0
Behavior4/5

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

Goes well beyond the annotations by disclosing pagination (25 venues/page), a ~110-call example, resumability with progress saved after every page, the loop condition (another_run_needed), refresh-from-top semantics, and rate-limit stopping with stopped_for_rate_limit and rate_limit.resume_at. It is consistent with readOnlyHint=false since it writes to a local cache. The one gap is that the description never states plainly that it does not modify anything on Untappd itself, though the 'into the cache' phrasing implies it.

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

Conciseness4/5

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

Front-loaded with the purpose and the key differentiator before the operational detail, and nearly every sentence carries information an agent needs. The refresh-cut-short clause is dense and slightly convoluted, and the single unbroken paragraph could be split into usage and mechanics sections.

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?

For a long-running, resumable, rate-limited sync with no output schema, the description supplies the loop contract, the stop conditions, and the field names an agent must inspect. Nothing essential to calling it correctly across repeated invocations is missing.

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 100%, so the baseline is 3, but the description adds real meaning: max_pages is framed as a per-run batch inside a repeat-until-done loop, and username omission is tied to the caller's own account. It does not restate types or bounds, which is correct since the schema already carries them.

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?

States a specific verb and resource ('Fetch a user's COMPLETE venue history ... into the cache from user/venues') and explicitly contrasts it with the sibling endpoint user/checkins, which only returns ~50 recent check-ins. An agent can distinguish it from untappd_user_venues and untappd_sync_checkins without opening a schema.

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

Usage Guidelines5/5

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

Gives an explicit purpose statement tied to a downstream tool ('this is how to answer "has this person been here?" via untappd_cache_has_visited'), names the alternative endpoint and the condition that selects it, and covers the omit-username case for the caller's own account.

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

untappd_sync_venue_drinksFetch what a user drank on their first/latest visit to each venue (opt-in)A

OPT-IN, costs API calls: for a user's cached venue history (run untappd_sync_user_venues first), fetch the FIRST and MOST-RECENT visit check-ins of each venue via checkin/view (works for any public check-in) and cache the beer + date — a PARTIAL "what did they drink there" (two check-ins per venue at most, never the full list). One call per check-in, most-visited venues first, at most max_calls per run (default 10, max 50); already-cached check-ins are never re-fetched, and deleted/private ones (404) are remembered and skipped. Narrow with venue_ids and which. Stops BEFORE the ~100 calls/hour rate limit (or cleanly on a 429) with stopped_for_rate_limit and rate_limit.resume_at; run again until another_run_needed is false. Results appear in untappd_cache_has_visited under matches[].drinks. Stores only beer, brewery and date — never comments. Omit username for your own account.

NameRequiredDescriptionDefault
whichNoFetch each venue's first-visit check-in, most-recent one, or both (default both).
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
max_callsNocheckin/view calls this run (default 10, max 50). Each is one of the ~100 hourly calls.
venue_idsNoOnly these venues (from untappd_cache_has_visited). Default: every cached venue, most-visited first.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only declare the operation is non-read-only, open-world and non-idempotent; the description goes far beyond that by disclosing cost ('costs API calls', one call per check-in), quota protection (~100 calls/hour, stops cleanly on 429 with stopped_for_rate_limit and rate_limit.resume_at), cache-diffing ('already-cached check-ins are never re-fetched'), and 404 memoization. It also scopes what is persisted ('stores only beer, brewery and date — never comments'), which is exactly the kind of mutation detail the annotations cannot convey.

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

Conciseness5/5

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

Front-loaded with the two facts that gate the call ('OPT-IN, costs API calls') before any mechanics, and the remaining clauses cover distinct topics: prerequisite, scope limit, batching/rate limits, narrowing, and result location. Dense but every clause carries operational information an agent needs.

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 compensates by naming the exact result path (untappd_cache_has_visited -> matches[].drinks) and the control fields (stopped_for_rate_limit, rate_limit.resume_at, another_run_needed) an agent must branch on. For a mutating, rate-limited, cache-writing sync tool this covers everything needed to call and re-call it correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so venue_ids, which, max_calls and username are already documented with defaults and bounds. The description restates the same facts ('Narrow with venue_ids and which', 'at most max_calls per run (default 10, max 50)', 'Omit username for your own account') without adding format or edge-case semantics, so the baseline of 3 applies.

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?

States a specific verb and resource ('fetch the FIRST and MOST-RECENT visit check-ins of each venue via checkin/view') plus the scope limit ('two check-ins per venue at most, never the full list'), which cleanly separates it from untappd_sync_checkins and untappd_cache_has_visited. The parenthetical '(opt-in)' in the title reinforces that this is not a general-purpose fetch.

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

Usage Guidelines5/5

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

Gives an explicit prerequisite ('run untappd_sync_user_venues first'), a narrowing rule ('Narrow with venue_ids and which'), and an iteration protocol ('run again until another_run_needed is false'). It also names the downstream query for results ('untappd_cache_has_visited under matches[].drinks'), so the agent knows the full workflow.

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

untappd_sync_wishlistSync a user's wishlist into the cacheA

Mirror a user's Untappd wishlist (user/wishlist) into the local cache, so pick tools can boost wishlisted beers without an API call. Each sync is a full pass from the top (~25 beers per call; wishlists are small), adding new beers and — once the pass finishes — dropping ones no longer wishlisted (a partial pass never deletes). Resumable: saves progress every page; run again until another_run_needed is false. Stops BEFORE the ~100 calls/hour rate limit (or cleanly on a 429) with stopped_for_rate_limit and rate_limit.resume_at. Only reads Untappd — never changes the wishlist (that is untappd_wishlist_add / _remove). Omit username for your own account; another user's wishlist needs a public account or friendship.

NameRequiredDescriptionDefault
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
max_pagesNoPages (~25 beers each) to fetch this run (default 10, max 50).

TDQS

A4.6/5.0
Behavior5/5

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

Annotation coverage is thin on the details that matter here (readOnlyHint=false and idempotentHint=false only signal that cache writes occur), and the description fills the gap: full-pass semantics, ~25 beers per call, deletion of de-wishlisted beers only after a complete pass, per-page resumability, and rate-limit handling with a documented stop reason and resume_at. The only mild tension is destructiveHint=false versus post-pass cache deletions, but those are scoped cache maintenance rather than user-data destruction, so it reads as clarification rather than contradiction.

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

Conciseness4/5

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

Front-loaded with the core action and purpose, then layered with operational detail in a logical order. It is dense and long for a two-parameter tool, but nearly every clause carries behavioral information an agent cannot get from the schema or annotations.

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?

There is no output schema, so the description compensates by naming the key return signals (another_run_needed, stopped_for_rate_limit, rate_limit.resume_at) that drive correct looping and retry decisions. Nothing essential for correct invocation or follow-up behavior is missing.

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

Parameters3/5

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

Schema coverage is 100%, so both parameters (username, max_pages) are already documented with defaults and bounds, making 3 the baseline. The description adds useful pagination context (~25 beers per page, small wishlists) and the self-vs-other username rule, but does not explain default or maximum page counts beyond what the schema already says.

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?

States a specific verb and resource ("Mirror a user's Untappd wishlist (user/wishlist) into the local cache") and names the endpoint it reads from. It explicitly distinguishes itself from untappd_wishlist_add / _remove, which is the nearest confusing sibling, and from untappd_user_wishlist by being a cache-population rather than a read.

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

Usage Guidelines5/5

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

Gives concrete when/when-not guidance: run it so pick tools can boost wishlisted beers without an API call, re-run until another_run_needed is false, and use the add/remove tools instead for actually changing the wishlist. It also states the precondition for another user's wishlist (public account or friendship) and the username-omission case.

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

untappd_toastToast an Untappd check-inA
Destructive

Toast (like) a check-in on YOUR account. This endpoint is a TOGGLE: calling it on a check-in you have already toasted removes the toast. Writes to your Untappd account and is visible to others. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

NameRequiredDescriptionDefault
checkin_idYesUntappd check-in id
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.4/5.0
Behavior5/5

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

Goes well beyond the annotations by disclosing the non-obvious toggle semantics (which explains the idempotentHint=false), that the write is public/visible to others (destructiveHint=true), and the exact confirmation protocol including the MCP_CONFIRM_MODE fallback. This is exactly the behavioral context an agent needs before mutating a user's social account.

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

Conciseness4/5

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

Front-loads the core purpose and toggle behavior, then the side effects, then the confirmation flow. It is dense and slightly parenthetical-heavy, but every sentence carries functional information rather than filler.

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 in play, the description steps in to describe the two-phase return behavior (preview plus confirmToken) that an agent must understand to drive the fallback flow. Combined with the write-visibility disclosure, nothing critical for correct invocation is missing.

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

Parameters3/5

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

Schema description coverage is 100%, and both checkin_id and confirmToken are already fully documented in the schema, including the confirmToken's usage rules. The description's pointer to MCP_CONFIRM_MODE adds marginal context but no parameter detail the schema lacks, so the baseline 3 applies.

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?

States a specific verb+resource (toast a check-in) and scopes it to the user's own account, immediately distinguishing it from read-oriented siblings like untappd_checkin_info or untappd_activity_feed. The toggle nature is called out explicitly, so the agent knows the operation's semantics without opening the schema.

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?

Explains when the call performs a write versus an un-toast, and details the required confirmation path (elicitation or two-step confirmToken), which is essential usage guidance. It does not name an alternative sibling or state when not to use this tool, so it falls short of a 5.

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

untappd_top_not_hadTop-rated beers a user has NOT had, from a candidate listA

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).

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.

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.

untappd_trip_checkCheck a list of trip stops against a user’s history (cache)A
Read-onlyIdempotent

Plan a brewery/bar crawl in ONE call: for each place (venue_id, name + city/state, lat/lng, and/or brewery_id) return whether the user has been there (dates, total visits, matched venues incl. "(duplicate of …)" copies — from the cached venue history, run untappd_sync_user_venues first), and for a brewery_id: how many of its beers they have had and the top 4 (top_n) NOT-had beers by Untappd global rating, optionally filtered by style (out-of-production beers skipped unless include_out_of_production). Has-had and visits come from the cache ONLY; the only API calls are brewery/beer_list fetches for a brewery whose list is not cached or is past its 7-day TTL, at most api_budget (default 5; 0 = strictly cache-only, a stale list is then used and flagged) under the ~100 calls/hour guard — a missing list sets another_run_needed. Beer lists are global facts: Untappd's have_had on that endpoint is the AUTHENTICATED account's and is never used. Favorites (breweries liked on Untappd via untappd_sync_brewery_likes, derived from the cached history, or added with untappd_favorite_add) are flagged on matched venues, the brewery and beers; prefer_favorites (default true) lifts wishlisted beers (+0.5) and a favorite brewery's beers (+0.25); and a stop within near_favorite_radius_m (default 2000 m) of a favorite venue gets near_favorites + a "Near a favorite" hint. For a GROUP pass usernames + mode ("none_had" default / "any_not_had"). Returns has-had and venue freshness blocks.

NameRequiredDescriptionDefault
modeNoWith usernames: "none_had" (default) lists beers new to everyone; "any_not_had" beers someone still needs
styleNoCase-insensitive substring filter on the beer style (e.g. "ipa")
top_nNoNot-had beers listed per brewery stop (default 4)
placesYesThe stops (1–25); each needs venue_id, name, lat+lng, or brewery_id
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
usernamesNoCheck a GROUP (1–10) instead of one user; use instead of username
api_budgetNoMax brewery/beer_list calls for missing or stale lists (default 5; 0 = cache only)
max_matchesNoMost matched venues listed per user per stop (default 5)
prefer_favoritesNoBoost wishlisted beers (+0.5) and favorite-brewery beers (+0.25) (default true)
near_favorite_radius_mNoRadius for the "near a favorite" hint in metres (default 2000)
include_out_of_productionNoAlso rank beers Untappd marks out of production (default false)

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the readOnly/openWorld annotations, the description discloses the cache-vs-API split ('has-had and visits come from the cache ONLY'), the exact API exception (brewery/beer_list fetches when uncached or past 7-day TTL), api_budget semantics, the ~100 calls/hour guard, the another_run_needed outcome, and the scoring rules for favorites. These are substantial behavioral details an agent needs to predict results.

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 description is front-loaded and information-dense, but it is one very long, clause-heavy paragraph with semicolons and nested parentheticals that make it hard to parse. It earns its place informationally, but the structure could be broken into clearer sentences or bullets without losing content.

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?

For a complex 11-parameter batch tool with caching, API budgeting, group modes, and favorite-boost logic, the description covers the cache behavior, brewery beer-list fetching, group semantics, scoring, and return blocks ('Returns has-had and venue freshness blocks'). An agent has enough to invoke it correctly and interpret the main outputs.

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 100%, so the schema already documents every parameter. The description adds value by specifying that top_n returns NOT-had beers by global rating, that prefer_favorites applies +0.5 to wishlisted beers and +0.25 to favorite-brewery beers, and that api_budget=0 means strictly cache-only with a stale list used and flagged.

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?

The description opens with a specific verb and resource: 'Plan a brewery/bar crawl in ONE call' and then enumerates exactly what each stop returns (has-been-there, visits, matched venues, brewery beer counts, top not-had beers). This clearly distinguishes it from single-venue or single-brewery siblings like untappd_venue_info or untappd_brewery_beers.

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?

It gives a clear prerequisite ('run untappd_sync_user_venues first') and a group-checking mode ('For a GROUP pass usernames + mode'). It does not explicitly name a sibling to avoid or state when-not-to-use, but the batch-trip use case is unambiguously established.

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

untappd_upload_slotsGet upload URLs for Untappd check-in photosA
Read-only

Get signed upload URLs for check-in photos — the way to attach a photo on the HOSTED connector, which cannot read files on your machine. For each photo (JPEG or PNG, max 15 MB) it returns a blobKey and a ready curl command: run the curl with the path to the photo (it must send exactly the returned Content-Type), then pass the blobKey to untappd_checkin as photo_blob_key. URLs expire after 30 minutes. Posts nothing to Untappd. Only available where the deployment provides a blob store; on a local install use photo_path or photo_inline.

NameRequiredDescriptionDefault
slotsYesOne entry per photo to upload (at most 10): {filename, mimeType?}. JPEG or PNG only.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations declare readOnlyHint=true, and the description reinforces this with 'Posts nothing to Untappd', so there is no contradiction. Beyond annotations it adds operationally critical facts: 30-minute URL expiry, 15 MB cap, JPEG/PNG only, the requirement to send exactly the returned Content-Type, and the deployment dependency on a blob store.

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

Conciseness4/5

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

Front-loaded with the purpose, then constraints, then the downstream handoff and the fallback. Dense but nearly every clause carries information; the parenthetical curl/Content-Type detail is slightly crowded but operationally necessary.

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?

No output schema exists, yet the description explains what is returned (blobKey plus a ready curl command) and how to consume it. Combined with expiry, format, and deployment constraints, an agent has everything needed to call it and chain into untappd_checkin.

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 100%, so the baseline is 3. The description still adds value beyond the schema by stating the 15 MB size limit and by explaining what the returned blobKey is used for downstream, which the schema cannot convey.

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?

Specific verb plus resource: 'Get signed upload URLs for check-in photos', scoped to the HOSTED connector. It immediately separates itself from untappd_checkin by naming the downstream handoff (photo_blob_key) rather than duplicating the check-in action.

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

Usage Guidelines5/5

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

Explicit when-to-use: only on the hosted connector, which cannot read local files. Explicit alternatives for the other case: 'on a local install use photo_path or photo_inline'. It also states the exact next step (run the curl, then pass blobKey to untappd_checkin).

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

untappd_user_badgesGet Untappd user badgesA
Read-onlyIdempotent

Get the badges a user has earned, most recent first. Omit username for your own account. Read-only.

NameRequiredDescriptionDefault
limitNoMax badges (1–50, default 25)
offsetNoResult offset for paging (default 0)
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, and the description reinforces the read-only status without contradiction. It adds genuine value beyond the annotations by disclosing result ordering ('most recent first') and the self-account omission behavior, which are behavioral facts not captured in the structured fields.

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

Conciseness5/5

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

Three short, purposeful clauses with zero waste. The purpose is front-loaded, followed by the single non-obvious usage nuance (self-account omission) and the safety profile. Every word earns its place.

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

Completeness4/5

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

For a simple paginated read tool with all parameters documented in the schema and three strong annotations, the description covers purpose, ordering, and account handling. No output schema exists, so return-value explanation isn't required. The only minor gap is not mentioning pagination behavior, but limit/offset are already fully specified in the schema.

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

Parameters3/5

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

Schema coverage is 100% with informative descriptions for all three parameters (limit range/default, offset default, username falling back to the configured UNTAPPD_USERNAME). The description largely restates the username behavior already present in the schema, so it adds minimal meaning beyond the structured data — the baseline 3 applies.

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?

Uses the specific verb 'Get' with a concrete resource ('badges a user has earned') plus the ordering qualifier 'most recent first'. Among the large sibling family (user_info, user_checkins, user_wishlist, user_beers, user_friends, user_venues), 'badges' is a distinct resource, so an agent can unambiguously distinguish this tool without opening any schema.

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

Usage Guidelines3/5

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

The description clarifies the key usage nuance — 'Omit username for your own account' — which guides when to include the parameter. However, it never explicitly names alternatives or states when not to use this tool versus the other user_* siblings; the differentiation relies on the tool name itself being self-evident rather than on explicit routing guidance.

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

untappd_user_beersGet Untappd distinct beersA
Read-onlyIdempotent

Get the distinct (unique) beers a user has ever checked in, with their rating and check-in count per beer. Supports sorting and paging. Omit username for your own account. Read-only.

NameRequiredDescriptionDefault
sortNoSort order (default date, most recent first)
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact projects each distinct beer to {bid, name, style, abv, ibu, brewery, your_count, your_rating, global_rating, last_had}; "full" returns Untappd's whole ~1.2 KB beer record per entry, including the long beer_description and the nested brewery record.
limitNoMax beers (1–50, default 25)
offsetNoResult offset for paging (default 0)
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).

TDQS

A3.7/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and idempotentHint=true, and the description repeats 'Read-only.' It adds some useful context about deduplication and defaulting to the configured account, but does not disclose rate limits, pagination behavior beyond the schema, or any subtle aggregated-response behavior.

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

Conciseness4/5

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

The description is concise and front-loaded with the core purpose before secondary details like sorting/paging. The final 'Read-only.' is redundant with the readOnlyHint annotation, so it is not strictly earning its place, but the overall structure is efficient.

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

Completeness4/5

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

For a read-only aggregation tool with well-described parametershebdomad, the description covers the essential behavior: distinct beers, rating/count, sorting, paging, and self-account default. There is no output schema, so a bit more return-shape detail beyond the 'view' parameter would have been ideal, but the included preview and compact/full field list in the schema fill most of the gap.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema fully documents all five parameters. The description's mention of sorting, paging, and omitting username largely mirrors what the schema already provides, adding no meaningful new semantic value beyond a brief summary.

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?

The description names a specific verb ('Get'), resource ('distinct beers a user has ever checked in'), and the key returned data ('rating and check-in count per beer'). It clearly differentiates from siblings like untappd_user_checkins by emphasizing unique beers rather than individual check-ins.

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

Usage Guidelines3/5

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

The description gives a clear usage hint for omitting username when targeting the configured account, and mentions sorting/paging. However, it does not explicitly state when to prefer this tool over closely related siblings such as untappd_user_checkins or untappd_sync_user_beers.

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

untappd_user_checkinsGet Untappd user check-insA
Read-onlyIdempotent

Get a user's recent check-ins (most recent first): the beer, rating, comment, venue, and toasts/comments. Page backwards with max_id (the pagination.max_id from a prior call). Only your OWN history pages fully: for any other user Untappd returns just the ~50 most recent check-ins and ignores max_id — use untappd_user_beers (has had) or untappd_user_venues (has been) for their full history. Omit username for your own. Read-only.

NameRequiredDescriptionDefault
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact projects each check-in to {id, user, beer, brewery, venue, rating, comment, toast/comment counts}; "full" returns Untappd's whole ~5 KB record.
limitNoMax check-ins (1–50, default 25)
max_idNoReturn check-ins older than this id (for paging)
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint/idempotentHint/openWorldHint, so the 'Read-only' tagline is largely redundant. What the description uniquely adds is the non-obvious API quirk: for any user other than yourself Untappd returns only ~50 recent check-ins and silently ignores max_id, which prevents an agent from looping on max_id forever. It stops short of noting rate limits or how paging termination is detected, so it is strong rather than exhaustive.

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

Conciseness5/5

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

Four compact sentences, front-loaded with what the tool returns, then paging, then the scoping caveat, then the alternative route. Every sentence carries operational information; the only filler is the trailing 'Read-only' already covered by annotations.

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?

For a list tool with no output schema, the description covers what comes back, the ordering, paging mechanics, the cross-user limitation, and the fallback tools. The view enum's compact/full projection detail lives in the schema, so the description need not repeat it.

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 100%, so the baseline is 3, but the description adds meaning the schema does not: max_id must be fed the 'pagination.max_id from a prior call' (the schema only says 'return check-ins older than this id'), and it warns that max_id is ignored for other users. That linkage between a request param and a response field is real added value.

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?

Names a specific verb and resource ('Get a user's recent check-ins') and enumerates the returned fields (beer, rating, comment, venue, toasts/comments) plus ordering ('most recent first'). It also explicitly separates itself from the sibling history tools untappd_user_beers and untappd_user_venues, so an agent can pick correctly without opening other schemas.

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

Usage Guidelines5/5

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

Gives explicit when-to-use (recent check-ins, own history with paging) and when-not-to-use (other users' full history is unreachable here, so use untappd_user_beers or untappd_user_venues instead). The 'omit username for your own' instruction removes the main ambiguity in calling it.

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

untappd_user_friendsGet Untappd user friendsA
Read-onlyIdempotent

Get a user's friend list. Omit username for your own account. Read-only.

NameRequiredDescriptionDefault
limitNoMax friends (1–50, default 25)
offsetNoResult offset for paging (default 0)
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).

TDQS

A3.5/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and idempotentHint=true, so the description's 'Read-only' adds no new safety information. It does add the account-context detail that omitting username uses the configured account, which is useful beyond the structured annotations.

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

Conciseness4/5

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

The description is very short and front-loaded with the core purpose, then adds the key username guidance. 'Read-only' repeats what annotations already convey, which is minor redundancy, but overall the structure is efficient.

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

Completeness4/5

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

For a low-complexity read-only list tool with no required parameters and complete schema coverage, the description covers the main decision points: what it returns, how to target a user, and how to access your own account. It does not describe output shape or pagination, but those are not critical for selecting and invoking this tool.

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

Parameters3/5

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

Schema description coverage is 100%, and the parameter descriptions are already clear: limit/offset for paging and username with the 'omit for own account' instruction. The description essentially repeats schema content and adds no new parameter meaning.

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

Purpose4/5

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

The description uses a specific verb and resource ('Get a user's friend list'), making the tool's core function immediately clear. It differentiates implicitly from sibling tools like untappd_pending_friends by focusing on the friend list, but does not explicitly name or contrast those siblings.

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

Usage Guidelines3/5

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

The instruction 'Omit username for your own account' gives practical context for the username parameter)Skip and clarifies a common usage. However, there is no explicit when-to-use versus alternatives such as untappd_pending_friends or untappd_user_info, leaving the choice partly to inference.

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

untappd_user_infoGet Untappd user profileB
Read-onlyIdempotent

Get an Untappd user's profile: bio, location, total check-ins, distinct beers, badges, and stats. Omit username for your own account. Read-only.

NameRequiredDescriptionDefault
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact also asks Untappd for its own slim record, dropping the embedded activity/list blocks; 'full' returns everything.
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).

TDQS

B3.2/5.0
Behavior3/5

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

Annotations already declare readOnlyHint and idempotentHint, and the description repeats 'Read-only' without adding much beyond that. It does clarify the behavior of omitting username (using the configured account), which is useful, but it does not disclose rate limits, auth needs, or response variability beyond what annotations and schema already cover.

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

Conciseness4/5

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

The description is concise and front-loaded with the resource and purpose. The field list is informative, and the 'Omit username' sentence earns its place. 'Read-only' is slightly redundant with the annotations but harmless.

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

Completeness4/5

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

For a simple read-only profile lookup with two optional parameters, the description is largely complete: it names the returned fields, explains the default-account behavior, and the schema covers parameter semantics. The absence of an output schema is mitigated by the field list, though explicit routing to sibling list-oriented tools would make it more complete.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents both username and view parameters in detail. The description repeats the 'omit username' behavior but adds no new meaning for either parameter, so the baseline of 3 applies.

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

Purpose4/5

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

The description clearly states the verb and resource: 'Get an Untappd user's profile', and lists concrete fields such as bio, location, total check-ins, distinct beers, badges, and stats. It does not explicitly name or contrast sibling tools like untappd_user_checkins or untappd_user_badges, so it stops short of full sibling differentiation.

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

Usage Guidelines2/5

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

The only usage guidance is 'Omit username for your own account', which is a parameter-level instruction, not guidance on when to choose this tool over alternatives. There is no mention of using untappd_user_checkins for check-in lists or untappd_user_badges for badge lists, which would be valuable given the sibling set.

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

untappd_user_venuesGet venues a user has checked in atA
Read-onlyIdempotent

Get the venues a user has checked in at, most recent first, with per-venue first/recent visit and check-in counts. Pages fully for any public/friend account (unlike user check-ins, which stop at ~50 for other users). Untappd returns at most 25 venues per page whatever limit you ask for — advance by the returned pagination offset. Omit username for your own account. Read-only.

NameRequiredDescriptionDefault
sortNoSort order (default most recent). Untappd keys: date, recent, date_asc, venue_name_asc, venue_name_desc, highest_checkin, lowest_checkin. Aliases: name = venue_name_asc, checkin = highest_checkin. highest_rated is deprecated (Untappd has no venue rating sort) and is sent as highest_checkin.
limitNoMax venues (1–50; Untappd caps a page at 25)
offsetNoResult offset for paging (default 0)
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description adds genuinely non-obvious behavior: a hard 25-venues-per-page cap regardless of requested limit, and the need to advance by the returned pagination offset. It does not describe error or auth-failure behavior, keeping it short of a 5.

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

Conciseness5/5

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

Four tight sentences, front-loaded with what the tool returns, then the paging caveat, then the account shortcut, then the read-only note. No filler and no repetition of the title.

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 still names the returned fields (first/recent visit, check-in counts) and the ordering. Combined with the paging cap and offset guidance, an agent has everything needed to call and iterate correctly.

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 100%, so the baseline is 3, but the description adds operational meaning: the default sort is most recent, and paging must follow the returned offset rather than a computed one. The username omission rule is restated from the schema, which limits the added value slightly.

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?

States a specific verb and resource ('Get the venues a user has checked in at') plus the ordering and payload shape (per-venue first/recent visit and check-in counts). It explicitly distinguishes itself from the sibling untappd_user_checkins by contrasting paging behavior, so an agent can pick between them without opening a schema.

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 clear operating context: omit username for your own account, and it pages fully for public/friend accounts unlike user check-ins. It does not explicitly route to untappd_venue_info or untappd_sync_user_venues, so the when-not guidance is partial rather than exhaustive.

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

untappd_user_wishlistGet Untappd user wishlistA
Read-onlyIdempotent

Get the beers on a user's wishlist. Supports sorting and paging. Omit username for your own account. Read-only.

NameRequiredDescriptionDefault
sortNoSort order (default date added, newest first)
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact projects each wishlisted beer to {bid, name, style, abv, ibu, brewery, added_at}; "full" returns Untappd's whole ~1.2 KB beer record per entry, including the long beer_description and the nested brewery record.
limitNoMax beers (1–50, default 25)
offsetNoResult offset for paging (default 0)
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already provide readOnlyHint=true and idempotentHint=true, lowering the description's burden. The description adds useful behavioral context beyond annotations: it explicitly says "Read-only" and explains the username omission behavior for the configured account. It does not contradict the annotations.

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

Conciseness5/5

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

Three short sentences with no filler. The core purpose is front-loaded, and the additional behavioral notes about sorting, paging, and omitting username each carry useful information without redundancy.

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

Completeness4/5

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

Considering the moderate complexity of five optional parameters, full schema documentation, and read-only/idempotent annotations, the description is nearly complete for safe invocation. The main absence is a summary of the response shape, but the schema's view parameter already describes compact vs full response details.

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

Parameters3/5

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

Schema description coverage is 100%, and every parameter already has detailed descriptions covering defaults, enums, bounds, and semantics. The description only echoes "sorting and paging," adding no meaning beyond what the schema already provides, so a baseline 3 is appropriate.

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?

The description states a specific action and resource: "Get the beers on a user's wishlist." This clearly distinguishes the tool from sibling tools like untappd_user_checkins, untappd_user_beers, and the wishlist mutation tools untappd_wishlist_add/remove.

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?

The description gives clear context: the tool is for reading a user's wishlist, supports sorting and paging, and omitting username targets the current account. It does not explicitly name alternatives or say when not to use it, but the read-only framing and sibling names make the distinction clear enough.

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

untappd_venue_activityGet recent check-ins at a venueA
Read-only

Get the recent public check-ins at a venue by its id — who was there, what they drank, and their ratings. Page backwards with max_id (the pagination.max_id from a prior call). Cached locally for 6 hours per venue + limit + max_id (cache.hit, fetched_at, expires_at); refresh:true re-fetches. Read-only.

NameRequiredDescriptionDefault
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact projects each check-in to {id, user, beer, brewery, venue, rating, comment, toast/comment counts}; "full" returns Untappd's whole ~5 KB record.
limitNoMax check-ins (1–50, default 25)
max_idNoReturn check-ins older than this id (for paging)
refreshNoBypass the 6-hour local cache and call Untappd (default false)
venue_idYesUntappd venue id

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds genuinely new behavior: a 6-hour local cache keyed on venue + limit + max_id, the cache.hit/fetched_at/expires_at fields returned, and how to force a re-fetch. It stops short of noting rate limits or how much data a refresh pulls.

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

Conciseness4/5

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

Three dense sentences, front-loaded with the purpose before paging and cache mechanics. Every sentence carries information, though the parenthetical cache-field list is terse enough that an unfamiliar agent may need a second read.

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

Completeness4/5

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

There is no output schema, so the description does useful work describing the shape of returned check-ins (user, beer, rating, comment) and the cache metadata block. Coverage is strong for a read tool; only cross-tool routing to venue_info or venue_menu is left implicit.

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?

With 100% schema coverage the baseline is 3, but the description earns more by explaining the provenance of max_id (it comes from a prior call's pagination.max_id) and the cache-key semantics of refresh and limit, which the schema does not state. It does not describe the view enum's projection, though the schema already covers that thoroughly.

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?

States a specific verb and resource (recent public check-ins at a venue by id) and enumerates what the caller gets back: who was there, what they drank, ratings. This distinguishes it from untappd_user_checkins and untappd_activity_feed, which are user- and feed-scoped, without the agent needing to open either schema.

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 clear operational guidance on paging (walk backwards with max_id from a prior response's pagination.max_id) and on cache bypass (refresh:true). It does not, however, say when to prefer untappd_venue_info or untappd_venue_menu over this tool, so the alternative-selection guidance stops short of explicit exclusion.

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

untappd_venue_by_foursquareLook up an Untappd venue by Foursquare idA
Read-onlyIdempotent

Resolve a Foursquare venue id to its Untappd venue. Useful to turn a foursquare_id (e.g. from a check-in) into an Untappd venue you can pass to untappd_venue_info / untappd_venue_activity. Read-only.

NameRequiredDescriptionDefault
foursquare_idYesFoursquare venue id

TDQS

A4.3/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is covered. The description adds 'Read-only' and explains the output can be passed to other tools, which is useful context, but it does not go beyond that with other behavioral details like failure modes or rate limits.

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

Conciseness5/5

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

Three short sentences, with the core purpose front-loaded and no filler. Every sentence contributes: what it does, why it is useful, and its safety property.

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?

For a single-parameter read-only lookup, the description is complete. It explains the input, the output, the practical use case, and how to chain it with related tools, even in the absence of an output schema.

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 100% for the single parameter, so the baseline is 3. The description adds practical context by giving an example source of the ID (a check-in) and explaining how the resolved venue is used downstream, which is genuinely helpful beyond the schema's simple 'Foursquare venue id'.

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?

Description uses a specific verb ('Resolve') and names both the input (Foursquare venue id) and output (Untappd venue). It clearly differentiates from sibling tools by specifying this is a cross-reference lookup, not a search or info tool.

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?

The description gives clear context for when to use the tool: when you have a foursquare_id, e.g. from a check-in, and want to resolve it to an Untappd venue. It also points to follow-up tools (untappd_venue_info / untappd_venue_activity), though it does not explicitly exclude alternatives.

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

untappd_venue_infoGet Untappd venue detailA
Read-onlyIdempotent

Get full detail for a venue by its Untappd venue id: category, address, contact, rating, total check-ins, and — on view:"full" — top beers and recent activity. Get an id from untappd_search_venue. Read-only.

NameRequiredDescriptionDefault
viewNoResponse shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact also asks Untappd for its own slim record, dropping the embedded activity/list blocks; "full" returns everything.
venue_idYesUntappd venue id

TDQS

A3.9/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description confirms 'Read-only' and adds return-content context (full view includes top beers and recent activity), but does not disclose any additional behavior such as rate limits or auth requirements. No contradiction with annotations.

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

Conciseness4/5

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

The description is short, front-loaded with the main purpose, and avoids unnecessary detail. The final 'Read-only' is redundant with annotations, but it is brief and reinforces safety. Overall, it is well-structured and economical.

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

Completeness4/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 usefully enumerates the main returned data categories and explains the difference between compact and full views. It also tells the agent how to obtain the required venue_id. Minor details like pagination or response limits are absent, but they are not essential for this read-only lookup tool.

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

Parameters3/5

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

Schema description coverage is 100% and both parameters are well documented in the input schema, especially the 'view' enum. The description repeats the idea of 'full' view but adds no meaning beyond what the schema already provides, so the baseline of 3 is appropriate.

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?

The description states a specific verb and resource: 'Get full detail for a venue by its Untappd venue id', and enumerates the returned fields. It also distinguishes itself from untappd_search_venue by explaining where to obtain the id, and from untappd_venue_by_foursquare by specifying the id type.

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?

The description gives clear context: this tool retrieves venue details and should be used after obtaining an id from untappd_search_venue. It does not explicitly list exclusions relative to siblings like untappd_venue_menu or untappd_venue_activity, but the purpose is specific enough that an agent can infer when to use it.

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

untappd_venue_menuGet a venue's verified beer menu (section-paged)A
Read-onlyIdempotent

Return a venue's verified beer menu as a flat, compact list of beers. untappd_venue_info returns only the FIRST section of each menu (Untappd defaults the section list to one), so it silently under-reports any venue whose menu spans multiple sections — e.g. a 23-beer wall that comes back with 2 items. This tool forwards the section_limit / section_offset paging params venue/info echoes back but never receives, walks sections up to a per-call max_pages budget (respecting the ~100 calls/hour limit — it does NOT loop to completion in one call), and flattens to [{bid, name, brewery, brewery_id, style, abv, price, serving_type, menu, section}]. Like the sync tools it is resumable: when the budget runs out before full coverage it returns another_run_needed:true plus next_section_offset to pass back on the next call. truncated:true means the upstream returned no more sections short of total_count (e.g. it ignored the paging params) — not resumable. Results are cached locally for 6 hours per venue + paging params (cache.hit, fetched_at, expires_at) so repeated trip planning does not re-spend calls; refresh:true re-fetches. With the cache, the result also carries favorite {is_favorite, sources, reason} for the venue, and favorite / brewery_favorite on each beer that is one (derived from username's history or added with untappd_favorite_add; default your account) — applied on read, so never stale. Get an id from untappd_search_venue. Read-only.

NameRequiredDescriptionDefault
sortNoMenu sort key (e.g. 'publish_order', 'highest_rated'). Optional.
menu_idNoRestrict to a single menu id (from a prior result). Optional.
refreshNoBypass the 6-hour local cache and call Untappd (default false)
usernameNoWhose favorites to mark (cache only; default your configured account)
venue_idYesUntappd venue id
max_pagesNoAPI calls to spend THIS run — page budget, not page size (default 3). Resume with next_section_offset if another_run_needed.
section_limitNoSections fetched per API call — page size (default 50).
section_offsetNoSection offset to start from; pass a prior next_section_offset to resume (default 0).

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already cover read-only/open-world/idempotent, but the description adds substantial non-obvious behavior: a ~100 calls/hour limit, a per-call max_pages budget that deliberately does not loop to completion, resumability semantics, the distinction between another_run_needed (resumable) and truncated (upstream ignored paging), and a 6-hour cache with hit/fetched_at/expires_at. Slightly dense but genuinely informative beyond structured fields.

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?

It is front-loaded with the key differentiator, but the body is one long run-on paragraph of stacked parentheticals and em-dashes covering paging, truncation, caching and favorites. Each clause carries information, yet the density makes it harder to parse than a few short structured sentences would.

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?

For an 8-parameter, no-output-schema tool, the description covers the flattened beer record fields, the cache envelope fields, the favorite annotations applied on read, and both paging outcome flags. An agent has everything needed to call, resume, and interpret results.

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 100%, so per-field text already explains max_pages vs section_limit and refresh/username. The description still adds operational meaning the schema cannot: that these paging params are what venue/info echoes back but never receives, and that next_section_offset is the resume token to pass back.

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?

"Return a venue's verified beer menu as a flat, compact list of beers" names a specific verb, resource and output shape. It immediately contrasts itself with untappd_venue_info, so an agent can distinguish the two without reading either schema.

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

Usage Guidelines5/5

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

It states exactly when NOT to use the sibling (venue_info returns only the first section and silently under-reports) and names untappd_search_venue as the source of an id. It also gives the refresh:true condition for bypassing cache and the next_section_offset condition for resuming.

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

untappd_venue_pickPick beers off a venue's Untappd menu that a user hasn't hadA

Like untappd_menu_pick, but takes an Untappd venue (URL or id) instead of menu lines: it pulls the venue's FULL verified menu (walking every section page until complete, within api_budget), refreshes the user's distinct-beers cache (incremental, or an automatic backfill), checks every menu beer against it and ranks the not-had ones by global rating. Returns the same picks / not_had / had / sync shape plus a venue block (menu_complete is false only if the budget ran out mid-menu). A venue with no verified menu comes back unresolved — use untappd_menu_pick with the tap list instead. Omit username for your own account.

NameRequiredDescriptionDefault
top_nNoHow many picks to return (default 2, max 10).
venueYesUntappd venue URL (https://untappd.com/v/<slug>/<id>) or numeric venue id.
usernameNoUntappd username. Omit to use your own configured account (UNTAPPD_USERNAME).
api_budgetNoMax Untappd API calls this run, shared by the cache sync, searches and rating lookups (default 60; Untappd allows ~100/hour). If it runs out, the result says another_run_needed and a re-run continues from what was cached.
style_filterNoCase-insensitive substring filter on the beer style or parent style for the picks (e.g. "ipa", "stout").

TDQS

A4.4/5.0
Behavior4/5

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

Adds substantial context beyond annotations: the full-menu walk across section pages, the incremental or backfill cache refresh (which explains the readOnly=false and non-idempotent hints), budget exhaustion producing another_run_needed with a resumable cache, and menu_complete=false only when the budget runs out mid-menu. It stops just short of detailing rate limits or pagination nuances, but the safety and state-mutation profile is clearly disclosed.

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

Conciseness4/5

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

Front-loaded with the core differentiation, then the mechanics, then the fallback and the username default. It is dense but nearly every clause carries operational information. Slightly long sentences keep it from being maximally crisp.

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?

For a multi-step tool with no output schema, the description supplies the return shape (picks / not_had / had / sync plus a venue block), the unresolved-venue case, budget semantics, and resumability. An agent has enough to invoke it and to interpret the result without guessing.

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

Parameters3/5

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

Schema coverage is 100%, so venue, top_n, username, api_budget, and style_filter are already documented in structured fields. The description reinforces the venue-vs-menu-lines distinction and the budget's effect on menu completeness, but adds no format, syntax, or tie-breaking detail beyond the schema. Baseline 3 is appropriate.

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?

States a specific verb and resource chain: it pulls a venue's full verified menu, checks it against the user's distinct-beers cache, and ranks not-had beers by global rating. It explicitly distinguishes itself from untappd_menu_pick by input (venue instead of menu lines), so an agent can route without opening either schema.

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

Usage Guidelines5/5

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

Names the alternative tool and the exact condition that selects it: a venue with no verified menu comes back unresolved, and in that case use untappd_menu_pick with the tap list. It also covers the username omission case for the caller's own account, leaving no ambiguity about when to use this versus siblings.

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

untappd_wishlist_addAdd a beer to your wishlistA
Idempotent

Add a beer to YOUR Untappd wishlist by its bid. Writes to your account. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

NameRequiredDescriptionDefault
bidYesUntappd beer id (bid) — from untappd_search_beer
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.4/5.0
Behavior5/5

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

Beyond the annotations, the description clearly discloses the write behavior, the confirmation-first flow, and the two-step fallback with a preview and confirmToken. It also references MCP_CONFIRM_MODE, giving the agent actionable detail about when the actual write occurs.

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

Conciseness5/5

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

Three tightly packed sentences: the primary action, the write side-effect, and the confirmation protocol. No filler or repetition; the most important information is front-loaded.

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

Completeness4/5

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

The description covers the essential workflow, including the fallback token mechanism and confirmation requirement. Since there is no output schema, a small gap remains in describing what the final success response looks like, but the tool's behavior is otherwise sufficiently specified.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents both bid and confirmToken well. The description adds little param-specific meaning beyond 'by its bid' and the confirmToken fallback behavior, which the schema mostly covers.

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?

The verb 'Add' is specific, and the target resource is clearly 'YOUR Untappd wishlist', with the key input ('by its bid') included. It is readily distinguishable from siblings like untappd_wishlist_remove and untappd_user_wishlist.

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?

The description gives clear context: this writes to the user's own wishlist and requires confirmation before acting. It does not explicitly name alternatives or exclusion cases, but the 'YOUR' scoping and the confirmation requirement effectively guide selection.

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

untappd_wishlist_removeRemove a beer from your wishlistA
Idempotent

Remove a beer from YOUR Untappd wishlist by its bid. Writes to your account. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

NameRequiredDescriptionDefault
bidYesUntappd beer id (bid) — from untappd_search_beer
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the annotations, the description discloses that the operation writes to the user's account and explains the two-step confirmation flow, including the preview response, confirmToken, and repeat-call requirement. This is rich behavioral detail that materially helps an agent use the tool safely and correctly.

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

Conciseness5/5

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

The description is two sentences with no wasted words. The core purpose is front-loaded, and the confirmation behavior follows in a compact but complete sentence referencing MCP_CONFIRM_MODE where appropriate.

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?

For a state-changing tool with no output schema, the description covers the essential call flow: initial removal request, user confirmation, preview/confirmToken fallback, and the exact repeat-call condition. Combined with the rich parameter schema, an agent has enough information to invoke the tool correctly.

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

Parameters3/5

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

Schema description coverage is 100%, and both bid and confirmToken are already well described in the input schema. The description adds only marginal confirmation that bid is the identifier and restates the confirmToken fallback semantics, so the schema carries the parameter-meaning burden.

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?

The description states a specific verb and resource: 'Remove a beer from YOUR Untappd wishlist by its bid.' This clearly distinguishes the operation from siblings like untappd_wishlist_add and untappd_user_wishlist. The scope is unambiguous.

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?

The description gives clear context for when the tool applies: removing a beer from the user's own wishlist. It does not explicitly name alternative tools or exclusion conditions, but the operation is narrow enough that an agent can infer correct usage without confusion.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv2.7.0
    • Changeduntappd_checkin3 fields changed
      • addedInput schema / properties / photo_blob_key
        Added value: +{
        +  "description": "Optional blobKey of a photo PUT to a slot from untappd_upload_slots (hosted connector) — it is published publicly. Deleted from the upload store once the check-in and its photo succeed; kept if they fail.",
        +  "type": "string"
        +}
      • addedInput schema / properties / photo_inline
        Added value: +{
        +  "description": "Optional photo as base64: {filename, contentBase64, mimeType?}, JPEG or PNG, max 15 MB — it is published publicly. Works on any deployment; for anything but a small photo prefer the upload slot flow (photo_blob_key). Only use a photo the user explicitly chose.",
        +  "properties": {
        +    "contentBase64": {
        +      "description": "The file's bytes, standard base64 (line breaks and a \"data:<type>;base64,\" prefix are tolerated).",
        +      "type": "string"
        +    },
        +    "filename": {
        +      "description": "Filename the upstream will show — a bare name, no path, not starting with a dot. Its extension sets the MIME type when mimeType is omitted.",
        +      "type": "string"
        +    },
        +    "mimeType": {
        +      "description": "MIME type, e.g. \"image/jpeg\". Default: inferred from the filename extension.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "filename",
        +    "contentBase64"
        +  ],
        +  "type": "object"
        +}
      • changedInput schema / properties / photo_path / description
        Previous value: -"Optional path to a local JPEG/PNG photo (max 15 MB) to attach — it is published publicly. It must be inside the photo directory (UNTAPPD_PHOTO_DIR, default ~/Downloads/untappd-mcp). Only use a file the user explicitly chose; the preview shows the resolved path and size for them to confirm."New value: +"Optional path to a local JPEG/PNG photo (max 15 MB) to attach — it is published publicly. It must be inside the photo directory (UNTAPPD_PHOTO_DIR, default ~/Downloads/untappd-mcp). Only use a file the user explicitly chose; the preview shows the resolved path and size for them to confirm. Local installs only — refused on the hosted connector (use photo_blob_key)."
    • Addeduntappd_upload_slots
  2. 16 tool updatesv2.6.1
    • Changeduntappd_activity_feed2 fields changed
      • changedInput schema / properties / view / description
        Previous value: -"Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact projects each check-in to {id, user, beer, brewery, venue, rating, comment, toast/comment counts}; \"full\" returns Untappd's whole ~5 KB record."New value: +"Response shape: \"compact\" (default) projects each check-in to {id, user, beer, brewery, venue, rating, comment, toast/comment counts}; \"full\" returns Untappd's whole ~5 KB record; \"brief\" returns one line per check-in: <user>: <beer> (<brewery>) at <venue> — <ISO date or \"no date\"> — <rated N|not rated>, inside the untrusted-data envelope as data: string[], with \"-- \" note lines (\"-- none\", \"-- more\")."
      • changedInput schema / properties / view / enum
        Previous value: -[
        -  "compact",
        -  "full"
        -]New value: +[
        +  "compact",
        +  "full",
        +  "brief"
        +]
    • Changeduntappd_brewery_beers3 fields changed
      • addedInput schema / properties / refresh
        Added value: +{
        +  "description": "Re-fetch from Untappd even if a fresh cached list exists (default false)",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / username
        Added value: +{
        +  "description": "Whose favorites to mark (cache only; default your configured account)",
        +  "minLength": 1,
        +  "type": "string"
        +}
      • changedInput schema / properties / view / description
        Previous value: -"Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact keeps each beer's identity, rating and counts and drops the description, label URLs and the copy of this brewery repeated on every row; \"full\" returns Untappd's whole page."New value: +"Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact keeps each beer's identity, rating and counts and drops the description, label URLs and the copy of this brewery repeated on every row; \"full\" returns Untappd's whole page (always fetched live)."
    • Changeduntappd_cache_has_had_many2 fields changed
      • 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 / 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"
        +}
    • Addeduntappd_cache_has_visited
    • Addeduntappd_favorite_add
    • Addeduntappd_favorite_remove
    • Addeduntappd_favorites_list
    • Addeduntappd_sync_brewery_likes
    • Addeduntappd_sync_user_venues
    • Addeduntappd_sync_venue_drinks
    • Addeduntappd_sync_wishlist
    • Changeduntappd_top_not_had3 fields changed
      • 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"
        +}
    • Addeduntappd_trip_check
    • Changeduntappd_user_venues3 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Max venues (1–50, default 25)"New value: +"Max venues (1–50; Untappd caps a page at 25)"
      • changedInput schema / properties / sort / description
        Previous value: -"Sort order (default most recent)"New value: +"Sort order (default most recent). Untappd keys: date, recent, date_asc, venue_name_asc, venue_name_desc, highest_checkin, lowest_checkin. Aliases: name = venue_name_asc, checkin = highest_checkin. highest_rated is deprecated (Untappd has no venue rating sort) and is sent as highest_checkin."
      • changedInput schema / properties / sort / enum
        Previous value: -[
        -  "date",
        -  "name",
        -  "checkin",
        -  "highest_rated"
        -]New value: +[
        +  "date",
        +  "recent",
        +  "date_asc",
        +  "venue_name_asc",
        +  "venue_name_desc",
        +  "highest_checkin",
        +  "lowest_checkin",
        +  "name",
        +  "checkin",
        +  "highest_rated"
        +]
    • Changeduntappd_venue_activity1 field changed
      • addedInput schema / properties / refresh
        Added value: +{
        +  "description": "Bypass the 6-hour local cache and call Untappd (default false)",
        +  "type": "boolean"
        +}
    • Changeduntappd_venue_menu2 fields changed
      • addedInput schema / properties / refresh
        Added value: +{
        +  "description": "Bypass the 6-hour local cache and call Untappd (default false)",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / username
        Added value: +{
        +  "description": "Whose favorites to mark (cache only; default your configured account)",
        +  "minLength": 1,
        +  "type": "string"
        +}
  3. 3 tool updatesv2.4.0
    • Addeduntappd_cache_status
    • Addeduntappd_menu_pick
    • Addeduntappd_venue_pick
  4. 1 tool updatev2.3.2
    • Changeduntappd_checkin1 field changed
      • changedInput schema / properties / photo_path / description
        Previous value: -"Optional path to a local JPEG/PNG photo (max 15 MB) to attach — it is published publicly. Only use a file the user explicitly chose; the preview shows the resolved path and size for them to confirm."New value: +"Optional path to a local JPEG/PNG photo (max 15 MB) to attach — it is published publicly. It must be inside the photo directory (UNTAPPD_PHOTO_DIR, default ~/Downloads/untappd-mcp). Only use a file the user explicitly chose; the preview shows the resolved path and size for them to confirm."
  5. 12 tool updatesv2.2.1
    • Changeduntappd_accept_friend2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changeduntappd_add_comment2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changeduntappd_add_friend2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Addeduntappd_cache_forget
    • Changeduntappd_checkin3 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
      • changedInput schema / properties / photo_path / description
        Previous value: -"Optional path to a local JPEG/PNG photo (max 15 MB) to attach — it is published publicly. Only use a file the user explicitly chose; the dry run shows the resolved path and size for them to confirm."New value: +"Optional path to a local JPEG/PNG photo (max 15 MB) to attach — it is published publicly. Only use a file the user explicitly chose; the preview shows the resolved path and size for them to confirm."
    • Changeduntappd_delete_checkin2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changeduntappd_delete_comment2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changeduntappd_reject_friend2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changeduntappd_remove_friend2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changeduntappd_toast2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changeduntappd_wishlist_add2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changeduntappd_wishlist_remove2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
  6. 1 tool updatev2.1.3
    • Changeduntappd_checkin2 fields changed
      • changedInput schema / properties / photo_path / description
        Previous value: -"Optional path to a local JPEG/PNG photo to attach to the check-in"New value: +"Optional path to a local JPEG/PNG photo (max 15 MB) to attach — it is published publicly. Only use a file the user explicitly chose; the dry run shows the resolved path and size for them to confirm."
      • addedInput schema / properties / timezone
        Added value: +{
        +  "description": "The drinker's IANA timezone (e.g. America/New_York), which sets the check-in's local time. Defaults to UNTAPPD_TIMEZONE, else the server's own zone — which on a hosted connector is usually UTC, so pass it when you know where the user is.",
        +  "minLength": 1,
        +  "type": "string"
        +}
  7. 45 tool updatesv2.0.0
    • Changeduntappd_accept_friend1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_activity_feed1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_add_comment1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_add_friend1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_beer_activity1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_beer_info1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_brewery_beers1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_brewery_info1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_cache_has_had1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_cache_has_had_many1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_cache_not_had1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_cache_query1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_checkin1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_checkin_info1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_delete_checkin1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_delete_comment1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_healthcheck1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_local_checkins1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_notifications1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_open_url1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_pending_friends1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_reject_friend1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_remove_friend1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_resolve1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_search_beer1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_search_brewery1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_search_venue1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_sync_checkins1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_sync_user_beers1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_toast1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_top_not_had1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_trending1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_user_badges1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_user_beers1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_user_checkins1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_user_friends1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_user_info1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_user_venues1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_user_wishlist1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_venue_activity1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_venue_by_foursquare1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_venue_info1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_venue_menu1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_wishlist_add1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeduntappd_wishlist_remove1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
  8. 1 tool updatev1.11.0
    • Changeduntappd_brewery_beers1 field changed
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact keeps each beer's identity, rating and counts and drops the description, label URLs and the copy of this brewery repeated on every row; \"full\" returns Untappd's whole page.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
  9. 12 tool updatesv1.10.1
    • Changeduntappd_activity_feed2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Project each check-in to a slim summary to save context (default false)",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact projects each check-in to {id, user, beer, brewery, venue, rating, comment, toast/comment counts}; \"full\" returns Untappd's whole ~5 KB record.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changeduntappd_beer_activity2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Project each check-in to a slim summary (id, user, beer, rating, comment, venue, toast/comment counts) to save context (default false)",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact projects each check-in to {id, user, beer, brewery, venue, rating, comment, toast/comment counts}; \"full\" returns Untappd's whole ~5 KB record.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changeduntappd_beer_info2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Return a slimmer record without the embedded recent-activity lists (default false)",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact asks Untappd for its own slim record, dropping the embedded recent-activity (media/check-in) block server side; \"full\" returns the whole record including that activity. No local projection — the beer fields themselves are identical on both rungs.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changeduntappd_brewery_info2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Return a slimmer record without embedded activity (default false)",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact also asks Untappd for its own slim record, dropping the embedded activity/list blocks; \"full\" returns everything.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changeduntappd_local_checkins2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Project each check-in to a slim summary to save context (default false)",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact projects each check-in to {id, user, beer, brewery, venue, rating, comment, toast/comment counts}; \"full\" returns Untappd's whole ~5 KB record.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changeduntappd_search_beer2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Project each result to a slim summary (bid, name, brewery, style, abv, ibu, counts) to save context (default false)",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact projects each match to {bid, name, style, abv, ibu, brewery, checkin_count, have_had}; \"full\" returns Untappd's whole ~1.2 KB search item, including the long beer_description and the nested brewery record.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changeduntappd_user_beers2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Project each beer to a slim summary (bid, name, brewery, style, abv, ibu, your_count, your_rating, global_rating, last_had) to save context (default false)",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact projects each distinct beer to {bid, name, style, abv, ibu, brewery, your_count, your_rating, global_rating, last_had}; \"full\" returns Untappd's whole ~1.2 KB beer record per entry, including the long beer_description and the nested brewery record.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changeduntappd_user_checkins2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Project each check-in to a slim summary to save context (default false)",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact projects each check-in to {id, user, beer, brewery, venue, rating, comment, toast/comment counts}; \"full\" returns Untappd's whole ~5 KB record.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changeduntappd_user_info2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Return a slimmer record without embedded lists (default false)",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact also asks Untappd for its own slim record, dropping the embedded activity/list blocks; 'full' returns everything.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changeduntappd_user_wishlist2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Project each beer to a slim summary (bid, name, brewery, style, abv, added_at) to save context (default false)",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact projects each wishlisted beer to {bid, name, style, abv, ibu, brewery, added_at}; \"full\" returns Untappd's whole ~1.2 KB beer record per entry, including the long beer_description and the nested brewery record.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changeduntappd_venue_activity2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Project each check-in to a slim summary to save context (default false)",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact projects each check-in to {id, user, beer, brewery, venue, rating, comment, toast/comment counts}; \"full\" returns Untappd's whole ~5 KB record.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • Changeduntappd_venue_info2 fields changed
      • removedInput schema / properties / compact
        Removed value: -{
        -  "description": "Return a slimmer record without embedded activity (default false)",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Response shape: \"compact\" (default) drops fields the response already carries elsewhere; \"full\" returns every field this server understands. compact also asks Untappd for its own slim record, dropping the embedded activity/list blocks; \"full\" returns everything.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}

TDQS

A3.5/5.0

Scored across 59 tools

Disambiguation2/5

The set has many overlapping clusters: venue_info/venue_menu/venue_activity/venue_pick, brewery_info/brewery_beers, beer_info/beer_activity, user_checkins/user_beers/user_venues vs their sync_* counterparts, and multiple has-had/pick tools (cache_not_had, cache_has_had, cache_has_had_many, top_not_had, menu_pick, venue_pick, trip_check). Descriptions are detailed, but the sheer number of specialized variants makes misselection likely.

Naming Consistency3/5

All names use snake_case with the untappd_ prefix, which keeps them readable. However, conventions are mixed: some are verb-first (add_comment, search_venue, sync_checkins, cache_has_had) while many are entity-first (venue_info, brewery_beers, wishlist_add, checkin_info, cache_status).

Tool Count1/5

59 tools is far beyond the typical 3-15 well-scoped range and beyond the 25+ threshold for an overly heavy surface. The large number of cache, sync, pick, info, and activity variants makes the server difficult to navigate as a single coherent tool set.

Completeness4/5

The surface covers most Untappd workflows: search/info/activity for beers, breweries, venues, users, and check-ins; check-in creation/deletion; comments; toasts; friends; wishlist; favorites; notifications; badges; feeds; and extensive cache/sync/pick support. Minor gaps remain, such as no user-search tool and no update operations, but core workflows are workable.

Maintenance

ActivityActive
ResponsivenessUsually handled

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server for Android's Tasker automation app
    52
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    A local-first MCP server for tracking beer releases on Vinmonopolet, enabling users to search new and upcoming beers, check store stock, find nearby stores, and manage watchlists.
    8
    15 npm
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    A Node.js MCP server for X/Twitter that enables user profile queries, tweet search, tweet detail retrieval, and media downloads (images, videos, GIFs) via X's Web GraphQL API.
    6
    2
    ISC