Skip to main content
Glama

Discover games

discover_games
Read-only

Find Steam games across the full catalog by combining filters like discount, release recency, review quality, Steam Deck compatibility, OS, and tags. Returns price, reviews, compat status, and store links in one call.

Instructions

Find games across the whole Steam catalog (keyless), filtered by ANY combination of: discount (min_discount — for 'what's on sale'), release recency (released_after / released_within_days — for 'new games'), hardware compatibility (steam_deck/steam_os/steam_machine/steam_frame — see each field's own description), native OS build (platform — windows/mac/linux), review quality (min_review / min_reviews), and user tags (tags — e.g. ['Roguelike', 'Deckbuilding'] for 'games like X'). Each result returns price/discount, review %, all four compat statuses, a vr_support flag (none/supported/required), popular tags, a clickable store_url, discount_end (when a deal expires) and release date in one call. Examples: '>80% off with 90%+ reviews' → set min_discount + min_review; 'recent well-reviewed games that run on Steam Deck' → set released_within_days + steam_deck + min_review; 'roguelike deckbuilders on sale' → tags:['Roguelike','Deckbuilding'] + min_discount. Base games only: DLC, soundtracks, demos and tools are filtered out, so a 'find DLC on sale' question returns nothing here — price a known DLC appid with get_items instead. No appids needed — unlike get_items, which prices a list you already have. For 'games like X' from a SINGLE named title, get its tags via get_items and pass them here; for taste inferred from the player's WHOLE library instead, use get_recommended_games (key-gated). Filtering: min_discount, released_after/released_within_days, tags, min_review and ONE of steam_deck/steam_machine/steam_frame are applied by Steam across the whole catalog, so a niche combination still finds its games, most popular first (total_matching is Steam's count of them). steam_os, platform, min_reviews and a second hardware filter have no server-side form and are applied afterwards to the count entries fetched, so those can return fewer — raise count for them. min_review only counts games with a Steam rating (10+ reviews). At most 50 results come back per call, best discount first: compare returned against matched to see whether the list was capped, and narrow the filters or page with start for the rest.

Input Schema

NameRequiredDescriptionDefault
tagsNoKeep only games carrying ALL of these user tags (case-insensitive), e.g. ['Roguelike','Deckbuilding']. Use exact Steam tag names — a misspelled/unrecognized one isn't an error, it just matches nothing. Filtered by Steam across the whole catalog.
countNoHow many matching catalog entries to fetch (1-200). Default 50. Most filters run server-side, so these already match them; steam_os, platform, min_reviews and a second hardware filter are then applied to this page and can leave fewer — raise it for those. Not the result cap (see the tool description). (Tools that cap what they RETURN call that `limit`.)
startNoPagination offset into the catalog (default 0).
countryNoCountry (cc) for prices/currency and regional availability; overrides STEAM_COUNTRY for this call. Must be a real Steam store region — the two-letter shape is all that's checked here, and Steam answers an unrecognized code with US prices rather than an error, so a typo returns plausible numbers for the wrong country.
languageNoStore language for the text fields. Use Steam's own language NAME — english, russian, schinese/tchinese — not an ISO code like en/ru/zh. An unrecognized value is never an error: text comes back in English and any `tags` list comes back EMPTY, which reads as 'this game has no tags' rather than as a bad language. (Filtering BY tags is the one loud case — it fails outright.) Overrides STEAM_LANGUAGE for this call. This is the content language only — prices and regional availability follow `country`.
platformNoNATIVE-build filter: keep only games shipping a native build for this OS (windows/mac/linux). 'linux' = a native Linux/SteamOS port. This is NOT Proton — for games that run via Proton compatibility use steam_os / steam_deck instead. Each result's `platforms` field lists its native builds, while steam_os/steam_deck report Proton compatibility, so native vs Proton stay distinct.
steam_osNoSteamOS compatibility — how well it runs on SteamOS in general (via Proton): 'verified' = SteamOS-Verified only; 'playable' = Playable or Verified. For a NATIVE Linux build instead, use platform:'linux'; for the Steam Machine console specifically, use steam_machine.
min_reviewNoMinimum positive-review %, e.g. 85. Filtered by Steam across the catalog (by its rating bucket) and re-checked exactly; only games with a Steam rating (10+ reviews) qualify.
steam_deckNoSteam Deck compatibility (runs via Proton): 'verified' = Deck-Verified only; 'playable' = Playable or Verified. Not a native Linux build — see `platform` for that.
min_reviewsNoMinimum review count, e.g. 500 — filters out games too obscure to trust a % on. No server-side form: applied to the `count` entries fetched, so raise `count` if it returns too few.
steam_frameNoSteam Frame (VR headset) compatibility: 'verified' = Frame-Verified only; 'playable' = Playable or Verified.
min_discountNoMinimum discount %, e.g. 80 for '80%+ off' — this is the 'deals' filter. Omit to include full-price games.
steam_machineNoSteam Machine (Valve's console) compatibility (via Proton): 'verified' = Steam-Machine-Verified only; 'playable' = Playable or Verified. Its own rating, distinct from the general steam_os one.
released_afterNoKeep only games released on/after this date (YYYY-MM-DD).
released_within_daysNoAlternative to released_after: released within the last N days, as a rolling window from now. The two are alternatives, not a combination — pass both and released_after wins and this is ignored, so pick whichever one the question actually asks for.

Output Schema

NameRequiredDescriptionDefault
dealsYes
matchedYesHow many results in the fetched page (see `count`) survived every filter.
returnedYesHow many of `matched` are in `deals` below. Lower than `matched` when the result was capped for response size — narrow the filters (or page with `start`) to see the rest.
total_matchingYesSteam's count of catalog games matching the server-side filters (min_discount, release date, tags, min_review's rating bucket, one hardware filter). Filters with no server-side form (steam_os, platform, min_reviews, a second hardware filter) and the exact review-% check are not reflected, so this can overstate; `matched` is exact for the fetched page. null when a requested tag isn't a Steam tag (nothing could match, so the catalog wasn't queried).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv0.17.0
    • changedInput schema / properties / count / description
      Previous value: -"How many catalog entries to SCAN (1-200). Default 50. Not a result count — the filters below are applied over this window, so a strict combination can return far fewer than this; raise it for stricter filters. (Tools that cap what they RETURN call that `limit`.)"New value: +"How many matching catalog entries to fetch (1-200). Default 50. Most filters run server-side, so these already match them; steam_os, platform, min_reviews and a second hardware filter are then applied to this page and can leave fewer — raise it for those. Not the result cap (see the tool description). (Tools that cap what they RETURN call that `limit`.)"
    • changedInput schema / properties / min_review / description
      Previous value: -"Minimum positive-review %, e.g. 85. Like every filter here except min_discount, it is applied over the scanned `count` window, not server-side — raise `count` if a strict value returns too few."New value: +"Minimum positive-review %, e.g. 85. Filtered by Steam across the catalog (by its rating bucket) and re-checked exactly; only games with a Steam rating (10+ reviews) qualify."
    • changedInput schema / properties / min_reviews / description
      Previous value: -"Minimum review count, e.g. 500 — filters out games too obscure to trust a % on. Applied over the scanned `count` window, like min_review."New value: +"Minimum review count, e.g. 500 — filters out games too obscure to trust a % on. No server-side form: applied to the `count` entries fetched, so raise `count` if it returns too few."
    • changedInput schema / properties / tags / description
      Previous value: -"Keep only games carrying ALL of these user tags (case-insensitive), e.g. ['Roguelike','Deckbuilding']. Use exact Steam tag names — a misspelled/unrecognized one isn't an error, it just matches nothing. Applied over the scanned popularity window, so raise `count` when combining niche tags."New value: +"Keep only games carrying ALL of these user tags (case-insensitive), e.g. ['Roguelike','Deckbuilding']. Use exact Steam tag names — a misspelled/unrecognized one isn't an error, it just matches nothing. Filtered by Steam across the whole catalog."
    • changedOutput schema / properties / matched / description
      Previous value: -"How many results survived every filter, out of the scanned window (see `count`)."New value: +"How many results in the fetched page (see `count`) survived every filter."
    • changedOutput schema / properties / total_matching / description
      Previous value: -"Count from whichever filters Steam actually applies server-side — min_discount, and (if released_after/released_within_days was set) excluding not-yet-released games — or the whole catalog's size if neither was given. NOT the number of games matching tags/platform/compat/review/the exact release-date cutoff, which have no server-side filter and this tool applies only over the scanned `count`-sized window below. Don't read this as 'N games match all my filters' — use `returned` for that instead."New value: +"Steam's count of catalog games matching the server-side filters (min_discount, release date, tags, min_review's rating bucket, one hardware filter). Filters with no server-side form (steam_os, platform, min_reviews, a second hardware filter) and the exact review-% check are not reflected, so this can overstate; `matched` is exact for the fetched page. null when a requested tag isn't a Steam tag (nothing could match, so the catalog wasn't queried)."
  2. Changed28 schema fields changedv0.14.0
    • changedInput schema / properties / country / description
      Previous value: -"Country (cc) for prices/currency; overrides STEAM_COUNTRY for this call."New value: +"Country (cc) for prices/currency and regional availability; overrides STEAM_COUNTRY for this call. Must be a real Steam store region — the two-letter shape is all that's checked here, and Steam answers an unrecognized code with US prices rather than an error, so a typo returns plausible numbers for the wrong country."
    • changedInput schema / properties / language / description
      Previous value: -"Store language (e.g. english, russian); overrides STEAM_LANGUAGE for this call."New value: +"Store language for the text fields. Use Steam's own language NAME — english, russian, schinese/tchinese — not an ISO code like en/ru/zh. An unrecognized value is never an error: text comes back in English and any `tags` list comes back EMPTY, which reads as 'this game has no tags' rather than as a bad language. (Filtering BY tags is the one loud case — it fails outright.) Overrides STEAM_LANGUAGE for this call. This is the content language only — prices and regional availability follow `country`."
    • changedInput schema / properties / min_review / description
      Previous value: -"Minimum positive-review %, e.g. 85. Applied over the returned page."New value: +"Minimum positive-review %, e.g. 85. Like every filter here except min_discount, it is applied over the scanned `count` window, not server-side — raise `count` if a strict value returns too few."
    • changedInput schema / properties / min_reviews / description
      Previous value: -"Minimum review count (filters out games with too few reviews)."New value: +"Minimum review count, e.g. 500 — filters out games too obscure to trust a % on. Applied over the scanned `count` window, like min_review."
    • addedInput schema / properties / released_after / format
      Added value: +"date"
    • changedInput schema / properties / released_after / pattern
      Previous value: -"^\\d{4}-\\d{2}-\\d{2}$"New value: +"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
    • changedInput schema / properties / released_within_days / description
      Previous value: -"Alternative to released_after: released within the last N days."New value: +"Alternative to released_after: released within the last N days, as a rolling window from now. The two are alternatives, not a combination — pass both and released_after wins and this is ignored, so pick whichever one the question actually asks for."
    • removedOutput schema / properties / deals / items / properties / discount_end / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / deals / items / properties / discount_end / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / deals / items / properties / name / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / deals / items / properties / name / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / deals / items / properties / original / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / deals / items / properties / original / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / deals / items / properties / price / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / deals / items / properties / price / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / deals / items / properties / release_date / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / deals / items / properties / release_date / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / deals / items / properties / review_count / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / deals / items / properties / review_count / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / deals / items / properties / review_label / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / deals / items / properties / review_label / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / deals / items / properties / review_percent / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / deals / items / properties / review_percent / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / deals / items / properties / store_url / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / deals / items / properties / store_url / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • addedOutput schema / properties / deals / items / properties / tags / description
      Added value: +"The game's most-weighted user tags, most-relevant first — a display sample capped well below the full set, not the complete list. Tag FILTERS (discover_games' and get_wishlist's `tags`) match against the game's COMPLETE tag list, so a filtered result can legitimately not show the tag you filtered on in this array. Absence here is not evidence the game lacks that tag."
    • removedOutput schema / properties / total_matching / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / total_matching / type
      Added value: +[
      +  "number",
      +  "null"
      +]
  3. Changed4 schema fields changedv0.13.1
    • changedInput schema / properties / count / description
      Previous value: -"How many catalog entries to scan (1-200). Default 50. Raise for stricter filters."New value: +"How many catalog entries to SCAN (1-200). Default 50. Not a result count — the filters below are applied over this window, so a strict combination can return far fewer than this; raise it for stricter filters. (Tools that cap what they RETURN call that `limit`.)"
    • addedOutput schema / properties / matched
      Added value: +{
      +  "description": "How many results survived every filter, out of the scanned window (see `count`).",
      +  "type": "number"
      +}
    • changedOutput schema / properties / returned / description
      Previous value: -"How many results survived every filter, out of the scanned window (see `count`)."New value: +"How many of `matched` are in `deals` below. Lower than `matched` when the result was capped for response size — narrow the filters (or page with `start`) to see the rest."
    • changedOutput schema / required
      Previous value: -[
      -  "total_matching",
      -  "returned",
      -  "deals"
      -]New value: +[
      +  "total_matching",
      +  "matched",
      +  "returned",
      +  "deals"
      +]
  4. Changed12 schema fields changedv0.12.1
    • addedInput schema / additionalProperties
      Added value: +false
    • addedInput schema / properties / count / default
      Added value: +50
    • changedInput schema / properties / count / description
      Previous value: -"How many catalog entries to scan (default 50). Raise for stricter filters."New value: +"How many catalog entries to scan (1-200). Default 50. Raise for stricter filters."
    • addedInput schema / properties / count / exclusiveMinimum
      Added value: +0
    • removedInput schema / properties / count / minimum
      Removed value: -1
    • addedInput schema / properties / min_discount / exclusiveMinimum
      Added value: +0
    • removedInput schema / properties / min_discount / minimum
      Removed value: -1
    • addedInput schema / properties / released_within_days / exclusiveMinimum
      Added value: +0
    • removedInput schema / properties / released_within_days / minimum
      Removed value: -1
    • addedInput schema / properties / start / default
      Added value: +0
    • changedInput schema / properties / start / description
      Previous value: -"Pagination offset into the catalog."New value: +"Pagination offset into the catalog (default 0)."
    • changedInput schema / properties / tags / description
      Previous value: -"Keep only games carrying ALL of these user tags (case-insensitive), e.g. ['Roguelike','Deckbuilding']. Use exact Steam tag names. Applied over the scanned popularity window, so raise `count` when combining niche tags."New value: +"Keep only games carrying ALL of these user tags (case-insensitive), e.g. ['Roguelike','Deckbuilding']. Use exact Steam tag names — a misspelled/unrecognized one isn't an error, it just matches nothing. Applied over the scanned popularity window, so raise `count` when combining niche tags."
  5. Addedv0.10.4
  6. Removedv0.10.2
  7. Changed2 schema fields changedv0.10.2
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "https://json-schema.org/draft/2020-12/schema",
      +  "additionalProperties": false,
      +  "properties": {
      +    "deals": {
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "appid": {
      +            "type": "number"
      +          },
      +          "discount_end": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "discount_pct": {
      +            "type": "number"
      +          },
      +          "name": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "original": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "platforms": {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "price": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "release_date": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "review_count": {
      +            "anyOf": [
      +              {
      +                "type": "number"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "review_label": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "review_percent": {
      +            "anyOf": [
      +              {
      +                "type": "number"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "steam_deck": {
      +            "enum": [
      +              "unknown",
      +              "unsupported",
      +              "playable",
      +              "verified"
      +            ],
      +            "type": "string"
      +          },
      +          "steam_frame": {
      +            "enum": [
      +              "unknown",
      +              "unsupported",
      +              "playable",
      +              "verified"
      +            ],
      +            "type": "string"
      +          },
      +          "steam_machine": {
      +            "enum": [
      +              "unknown",
      +              "unsupported",
      +              "playable",
      +              "verified"
      +            ],
      +            "type": "string"
      +          },
      +          "steam_os": {
      +            "enum": [
      +              "unknown",
      +              "unsupported",
      +              "playable",
      +              "verified"
      +            ],
      +            "type": "string"
      +          },
      +          "store_url": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "tags": {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "vr_support": {
      +            "enum": [
      +              "none",
      +              "supported",
      +              "required"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "appid",
      +          "name",
      +          "store_url",
      +          "review_percent",
      +          "review_count",
      +          "review_label",
      +          "platforms",
      +          "steam_deck",
      +          "steam_os",
      +          "steam_machine",
      +          "steam_frame",
      +          "vr_support",
      +          "tags",
      +          "release_date",
      +          "discount_pct",
      +          "discount_end",
      +          "original",
      +          "price"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "returned": {
      +      "description": "How many results survived every filter, out of the scanned window (see `count`).",
      +      "type": "number"
      +    },
      +    "total_matching": {
      +      "anyOf": [
      +        {
      +          "type": "number"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "Count from whichever filters Steam actually applies server-side — min_discount, and (if released_after/released_within_days was set) excluding not-yet-released games — or the whole catalog's size if neither was given. NOT the number of games matching tags/platform/compat/review/the exact release-date cutoff, which have no server-side filter and this tool applies only over the scanned `count`-sized window below. Don't read this as 'N games match all my filters' — use `returned` for that instead."
      +    }
      +  },
      +  "required": [
      +    "total_matching",
      +    "returned",
      +    "deals"
      +  ],
      +  "type": "object"
      +}
  8. Addedv0.9.0
  9. Removedv0.8.0
  10. Changed2 schema fields changedv0.7.0
    • addedInput schema / properties / steam_machine
      Added value: +{
      +  "description": "Steam Machine (Valve's console) compatibility (via Proton): 'verified' = Steam-Machine-Verified only; 'playable' = Playable or Verified. Its own rating, distinct from the general steam_os one.",
      +  "enum": [
      +    "playable",
      +    "verified"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / steam_os / description
      Previous value: -"SteamOS compatibility — how well it runs on SteamOS / the Steam Machine (via Proton): 'verified' = SteamOS-Verified only; 'playable' = Playable or Verified. For a NATIVE Linux build instead, use platform:'linux'."New value: +"SteamOS compatibility — how well it runs on SteamOS in general (via Proton): 'verified' = SteamOS-Verified only; 'playable' = Playable or Verified. For a NATIVE Linux build instead, use platform:'linux'; for the Steam Machine console specifically, use steam_machine."
  11. Changed7 schema fields changedv0.5.0
    • changedInput schema / properties / country / description
      Previous value: -"Country (cc) for prices; overrides STEAM_COUNTRY."New value: +"Country (cc) for prices/currency; overrides STEAM_COUNTRY for this call."
    • changedInput schema / properties / language / description
      Previous value: -"Store language; overrides STEAM_LANGUAGE."New value: +"Store language (e.g. english, russian); overrides STEAM_LANGUAGE for this call."
    • addedInput schema / properties / platform
      Added value: +{
      +  "description": "NATIVE-build filter: keep only games shipping a native build for this OS (windows/mac/linux). 'linux' = a native Linux/SteamOS port. This is NOT Proton — for games that run via Proton compatibility use steam_os / steam_deck instead. Each result's `platforms` field lists its native builds, while steam_os/steam_deck report Proton compatibility, so native vs Proton stay distinct.",
      +  "enum": [
      +    "windows",
      +    "mac",
      +    "linux"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / steam_deck / description
      Previous value: -"Keep only Deck-capable games: 'verified' = Deck-Verified only; 'playable' = Playable or Verified."New value: +"Steam Deck compatibility (runs via Proton): 'verified' = Deck-Verified only; 'playable' = Playable or Verified. Not a native Linux build — see `platform` for that."
    • addedInput schema / properties / steam_frame
      Added value: +{
      +  "description": "Steam Frame (VR headset) compatibility: 'verified' = Frame-Verified only; 'playable' = Playable or Verified.",
      +  "enum": [
      +    "playable",
      +    "verified"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / steam_os
      Added value: +{
      +  "description": "SteamOS compatibility — how well it runs on SteamOS / the Steam Machine (via Proton): 'verified' = SteamOS-Verified only; 'playable' = Playable or Verified. For a NATIVE Linux build instead, use platform:'linux'.",
      +  "enum": [
      +    "playable",
      +    "verified"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / tags
      Added value: +{
      +  "description": "Keep only games carrying ALL of these user tags (case-insensitive), e.g. ['Roguelike','Deckbuilding']. Use exact Steam tag names. Applied over the scanned popularity window, so raise `count` when combining niche tags.",
      +  "items": {
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  "minItems": 1,
      +  "type": "array"
      +}
  12. Addedv0.3.0

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only declare readOnlyHint and openWorldHint; the description goes much further. It discloses the server-side vs post-fetch split ('min_discount, released_after, tags, min_review and ONE hardware filter are applied by Steam...; steam_os, platform, min_reviews and a second hardware filter... applied afterwards to the `count` entries fetched, so those can return fewer'), the 50-result cap and best-discount ordering, and how to detect capping via `returned` vs `matched`.

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 and the any-combination filter list are front-loaded, and the later filtering/pagination paragraph is genuinely load-bearing. However, the return-field enumeration ('price/discount, review %, all four compat statuses, a vr_support flag...') duplicates what the output schema already provides, and some server-side notes are restated from the parameter descriptions.

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 15-parameter, zero-required, open-world search tool, everything an agent needs to call it correctly is present: filter composition rules, cap and pagination strategy, edge cases like unrecognized tags matching nothing, and the base-games-only restriction. Return values are covered by the output schema, so the brief restatement is redundancy rather than a gap.

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; this description earns above it by giving cross-parameter guidance the schema cannot: which filters compose, that released_after wins over released_within_days, that only ONE hardware filter runs server-side, and worked examples. It does repeat some per-field facts already in the schema (min_review's 10+ review rule), so it is not maximally efficient.

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+resource+scope: 'Find games across the whole Steam catalog (keyless)', then enumerates the filterable dimensions. It explicitly separates itself from siblings ('No appids needed — unlike get_items', 'use get_recommended_games'). An agent can route between discover_games, get_items and get_recommended_games 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?

States when to use it, when NOT to (DLC/soundtracks/demos/tools are excluded, so 'find DLC on sale' returns nothing — use get_items with an appid), and names the two alternatives with the exact condition that selects each. It also maps common natural-language questions ('>80% off with 90%+ reviews', 'runs on Steam Deck') to concrete filter combinations.

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