Steam MCP Server
Steam MCP Server lets you query Steam store and player data via MCP tools, mostly without credentials, covering search, prices, reviews, discovery, profiles, libraries, achievements, and more.
Search games by title to get appids, prices, Metacritic scores, platforms, and store links.
Get full store details for a game: price, genres, release date, developers, DLC, age rating, requirements, and more.
Batch price, discount, review percentage, tags, and Steam Deck/SteamOS/Machine/Frame compatibility for up to 50 appids (or 250 for price-only).
Discover catalog-wide games by discount, recency, user tags, native platform, compatibility, and review quality.
Read review summaries, recent reviews, and review trends over time.
Fetch recent news/patch notes, global achievement rarity, live player counts, and Steam charts.
Use a free Steam Web API key for player tools: profile, ban status, owned games, playtime, recently played, wishlist, followed games, friends, and achievements.
Get personalized game recommendations from your library, compare two players' shared games, and find friends who own specific games.
Resolve vanity profile names to SteamID64.
Use guided prompts like
what_should_i_play,is_it_worth_buying, anddeals_digest.Everything is read-only, uses official Steam APIs, requires no login or purchases, and works over stdio with any MCP client.
Provides tools for searching games, retrieving store details, prices, reviews, discounts, news, player profiles, libraries, achievements, and more via the Steam Web API.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Steam MCP Servershow me the current top sellers on Steam"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Steam MCP Server
An MCP server for Steam: search games and read store details, prices, reviews, discounts and news (no key), plus player profiles, libraries and achievements via the official Steam Web API (free key).
Read-only · official Steam APIs only · most tools need no key · open source.
Nobody logs in; the only credential is a free Steam Web API key you set yourself, and the server never writes, trades, posts, launches games, or makes purchases.
Works with any MCP client (Claude Desktop/Code, Cursor, VS Code, Cline, …) over stdio.
Once it's connected, just ask your agent in natural language.
No credentials needed (store, search & discovery):
"Find Hollow Knight and tell me its price, genres and age rating."
"What are recent reviews saying about Baldur's Gate 3?"
"Have Cyberpunk 2077's reviews recovered since launch?"
"Which games are >80% off right now with 90%+ positive reviews?"
"Find roguelike deckbuilders on sale."
"What discounted games run natively on macOS?"
"Which recent, well-reviewed games run on Steam Deck?"
"What well-reviewed games run on SteamOS?"
"Any games verified for the Steam Machine on sale?"
"Any Steam Frame-Verified VR games on sale?"
"What's discounted on Steam's front page right now?"
"Show me Steam's top sellers and newest releases."
"Any recent patch notes for No Man's Sky?"
"How rare is each achievement in Elden Ring?"
"How many people are playing Counter-Strike 2 right now?"
"What are the most played games on Steam right now?"
"Get current prices for appids 620, 413150 and 1145360."
"For appids 1245620 and 1086940, show price, review % and Deck / SteamOS / Machine / Frame status."With a free API key + your STEAM_ID (your account; see Getting your credentials):
"Show my Steam profile."
"List my games by playtime."
"What have I played in the last two weeks?"
"Recommend something I'd like based on my library, on a good discount."
"Do I already own Hollow Knight and Hades?"
"What's on my wishlist that's discounted and well-reviewed?"
"List Hollow Knight's achievements and how rare each one is."
"How far am I through Elden Ring's achievements?"
"What's the SteamID64 for the profile name 'gabelogannewell'?"
"Which of my friends own Portal 2, and how many hours have they played?"
"What games do my friend and I both own, and who's played them more?"
"Show me my Steam friends list."
"Is SteamID 76561197960287930 VAC banned?"
"What games am I following that aren't on my wishlist?"Install
Add it to your MCP client's config. Store/search tools work with no credentials; player tools need a free Steam Web API key.
{
"mcpServers": {
"steam": {
"command": "npx",
"args": ["-y", "steam-games-mcp"],
"env": {
"STEAM_API_KEY": "your-steam-web-api-key (optional — enables player tools)",
"STEAM_ID": "your-steamid64-or-vanity-name (optional — default 'you' for player tools)",
"STEAM_COUNTRY": "US (optional — store price region)",
"STEAM_LANGUAGE": "english (optional — store language)"
}
}
}
}Replace each value with your own; remove the optional lines you don't need. A free key comes from https://steamcommunity.com/dev/apikey. From source:
npm ci && npm run build, then use"command": "node","args": ["/ABS/PATH/steam-games-mcp/dist/index.js"].
One-click install (Claude Desktop)
Download steam-games-mcp.mcpb
(always the latest release) and open it in Claude Desktop (Settings → Extensions), then
fill the optional fields (API key, Steam ID, country, language) in the install form. No JSON editing.
Also listed in the MCP Registry
as io.github.Grinv/steam-games-mcp.
Related MCP server: steam-mcp
Getting your credentials
Store, search and discovery tools need nothing; skip this section if that's
all you want. The player tools (profile, library, achievements)
need a free API key, and most also need a public profile — though get_wishlist
and get_followed_games need no key, and profile/ban lookups work on private
profiles. Three short steps:
Get a free Steam Web API key. Sign in at https://steamcommunity.com/dev/apikey, enter any domain (e.g.
localhost), and copy the key intoSTEAM_API_KEY.Find your Steam ID. Set
STEAM_IDto either:your vanity name: the custom part of your profile URL
steamcommunity.com/id/YOUR_NAME→YOUR_NAME(resolved automatically), oryour 17-digit SteamID64 (
steamcommunity.com/profiles/7656…; or look it up at https://steamid.io).
With
STEAM_IDset you can just ask "my wishlist / library"; without it, give the agent a SteamID64 each time (useresolve_vanity_urlto convert a name).Make your profile public (for your own library/achievements): Steam → profile → Edit Profile → Privacy Settings → set My profile and Game details to Public.
The key and Steam ID go in your MCP client config (the
envblock above). See docs/clients.md for per-client examples. Never commit them.
Tools
Key: – no credentials · K Steam Web API key.
Tool | Key | Purpose |
| – | Find games by title → appid (with price) |
| – | Store details by appid or name: price, genres, platforms, Metacritic, age rating, DLC, requirements |
| – | Batch store card (price, review %, Deck/SteamOS/Machine/Frame compat, native platforms, tags) — up to 50 appids |
| – | Find games catalog-wide by discount, recency, Deck/SteamOS/Machine/Frame, platform, tags, rating |
| – | Review summary + recent reviews |
| – | Review trend over time (history + recent) |
| – | Batch current price/discount — up to 250 appids |
| – | Steam front-page discounts |
| – | Featured sections (top sellers, new releases, …) |
| – | Recent news / patch notes |
| – | Global achievement unlock rates (rarity) — top 200 |
| – | Live concurrent player count |
| – | What's popular now: weekly top sellers, most played, live concurrent top 100 (ranks + appids; price/reviews via |
| – | A player's wishlist — appids, or full cards + on-sale filter with |
| – | A player's followed games (Steam's "follow" feature, separate from the wishlist) — appids (public profiles) |
| K | Achievement list (names, descriptions) + rarity — first 150, definition order |
| K | Custom profile name → SteamID64 |
| K | Player public profile (incl. Steam level) |
| K | VAC/game/community/economy ban status (works even on private profiles) |
| K | A player's games + playtime (50 by playtime, |
| K | Games played in the last two weeks (top 50 by recent playtime) |
| K | Personalized picks from playtime-weighted tags + review quality, excluding owned games |
| K | A player's achievement progress in a game — achievement list capped at top 200, unlocked first |
| K | A player's friends — name, online state, current game (public friends list) |
| K | Which friends own given appid(s) + their playtime — each friend's FULL library, first 200 friends ( |
| K | Games two players both own, with each one's playtime — checks each player's FULL library, not just top 50 |
Two tiers. Store/search + discovery tools (store/api.steampowered.com)
need no credentials — including catalog-wide discovery (discover_games:
deals, new releases, Deck / SteamOS / Machine / Frame compatibility, tags, rating) and batch
price/review checks (get_items).
Player tools need a free
STEAM_API_KEY and a public profile; they return a clear message when the
key is unset. The two exceptions are get_wishlist and get_followed_games,
marked – above: they work with no key at all. Set STEAM_ID (a SteamID64
or vanity name — a vanity name resolves without a key too) to make those tools
default to you, so "my wishlist / library" works without passing an ID each time.
No third-party services: deal discovery and reviews come from Steam's own (keyless) store APIs. SteamDB is not used (no public API + scraping disallowed). Steam has no price-history API, so that isn't offered. Not affiliated with Valve.
Prompts
Guided one-shot prompts that orchestrate several tools for a common question. Use these when your client exposes MCP prompts, instead of describing the steps yourself:
Prompt | Args | What it does |
|
| Recommends catalog games from your library/taste, excluding what you own |
|
| Price, review trend and Steam Deck compatibility → a buy/wait/skip verdict |
|
| A curated list of well-reviewed discounted games |
Develop
npm install
npm run build # type-check + bundle to dist/index.js
npm test # node:test (mocked, offline)
npm run lint
npm run format
npm run check:api # live upstream health-check (key-gated checks need STEAM_API_KEY; a public STEAM_ID verifies player fields)
npm run inspector # run under the MCP InspectorRuntime requires Node ≥ 20.11. Contributor/agent guidance: AGENTS.md. Security policy: SECURITY.md. Per-client config and all tunables: docs/clients.md.
Updating
npx: unpinned
npx -y steam-games-mcpfetches the latest on the next run..mcpbbundle: download the new bundle from the releases page and reinstall.From source:
git pull && npm ci && npm run build.
Privacy Policy
steam-games-mcp runs entirely on your own machine and collects no data of
its own. See PRIVACY.md for exactly what it sends to Steam and
what (if anything) it stores locally.
License
MIT © Grinv
Available Tools
26 toolscompare_playersCompare two players' librariesARead-only
Find games two players both own, with each one's playtime — 'what can my friend and I both play', 'do we have anything in common'. Checks each player's FULL library to find every shared game, unlike get_owned_games whose own list stops at 50 by playtime by default — but the returned list here is itself capped at the top 50 shared games by combined playtime (check returned vs shared_count). Requires STEAM_API_KEY and both profiles' game-details to be public — otherwise it returns found:false, which ALSO covers one player's library lookup failing transiently; read reason, which says which case it is and whether retrying is worth it. Omit steamid to compare against yourself (STEAM_ID).
| Name | Required | Description | Default |
|---|---|---|---|
| steamid | No | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. | |
| other_steamid | Yes | The other player's 17-digit SteamID64 to compare against. Convert a vanity/custom profile name with resolve_vanity_url first. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and openWorldHint=true, so the safety profile is already covered. The description adds substantial behavioral context: the returned list caps at top 50 by combined playtime while shared_count shows the full total, the found:false ambiguity covering transient failures, and how to interpret reason to decide whether retrying is worthwhile. Slight deduction: it doesn't specify pagination or how to access beyond the cap, but the found:false/reason explanation is rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core purpose, then a targeted contrast with a sibling, then a compact but information-dense note about limitations and failure modes. Every sentence earns its place; no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists and the annotations cover readability/safety, the description covers what an agent needs: what it returns, the cap caveat, failure modes, and prerequisites. It could mention how to access the full shared list beyond 50, but that's a minor gap for a tool whose returned list is explicitly capped and whose output schema likely includes shared_count.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both parameters have descriptions including the 17-digit pattern and conversion advice. The description adds the key semantic that omitting steamid compares against the configured STEAM_ID, and reinforces how to convert vanity URL names via resolve_vanity_url. This goes beyond the schema's own parameter docs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: 'Find games two players both own, with each one's playtime.' It differentiates itself from get_owned_games by explicitly noting the 50-game limit difference. The description makes the tool's purpose immediately identifiable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use phrasing ('what can my friend and I both play', 'do we have anything in common'), contrasts with get_owned_games, and mentions requirements (STEAM_API_KEY, public profiles) plus the fallback behavior when conditions aren't met. It also says omitting steamid compares against yourself, giving clear usage routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
discover_gamesDiscover gamesARead-only
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). Note: min_discount is filtered server-side and re-checked client-side (so it holds at any value); setting released_after/released_within_days excludes not-yet-released games server-side, but the exact date cutoff — plus compat, platform, review and tag filtering — has no server-side support in the Steam catalog API, so those are scanned popularity-first and applied afterward over that same window — great for popular titles; a niche match may fall outside the top count (raise count for stricter filters). 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.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | 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. | |
| count | No | 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`.) | |
| start | No | Pagination offset into the catalog (default 0). | |
| country | No | 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. | |
| language | No | 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`. | |
| platform | No | 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. | |
| steam_os | No | 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. | |
| min_review | No | 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. | |
| steam_deck | No | Steam Deck compatibility (runs via Proton): 'verified' = Deck-Verified only; 'playable' = Playable or Verified. Not a native Linux build — see `platform` for that. | |
| min_reviews | No | Minimum review count, e.g. 500 — filters out games too obscure to trust a % on. Applied over the scanned `count` window, like min_review. | |
| steam_frame | No | Steam Frame (VR headset) compatibility: 'verified' = Frame-Verified only; 'playable' = Playable or Verified. | |
| min_discount | No | Minimum discount %, e.g. 80 for '80%+ off' — this is the 'deals' filter. Omit to include full-price games. | |
| steam_machine | No | 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. | |
| released_after | No | Keep only games released on/after this date (YYYY-MM-DD). | |
| released_within_days | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| deals | Yes | |
| matched | Yes | How many results survived every filter, out of the scanned window (see `count`). |
| returned | Yes | 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. |
| total_matching | Yes | 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover only readOnlyHint/openWorldHint, but the description discloses the non-obvious execution model: min_discount is server-side, released_after/released_within_days exclude unreleased titles server-side, while compat/platform/review/tag filters are applied client-side over a popularity-first scan window. It also warns that niche matches may fall outside `count`, that results cap at 50, and how to detect capping via `returned` vs `matched`. That is exactly the behavioral context annotations cannot supply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and filter inventory are front-loaded, then examples, then alternatives, then the execution caveat, then result capping — a sensible progression. It is dense and long, and a couple of clauses (repeated 'raise count for stricter filters' phrasing) could be trimmed, but nearly every sentence carries load-bearing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 discovery tool, the description covers the filter model, the scan-window caveat, pagination, and cross-tool routing. An output schema exists, yet the description still summarizes returned fields (price/discount, review %, compat statuses, vr_support, store_url, discount_end), so 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema baseline is 3, but the description adds real value by mapping natural-language intents onto parameter combinations (sale → min_discount, new games → released_within_days, 'games like X' → tags) and by noting released_after wins over released_within_days. It stops short of adding syntax the schema lacks, since the schema already documents each field thoroughly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('find games across the whole Steam catalog'), names the keyless scope, and enumerates the filter dimensions. It explicitly distinguishes itself from get_items ('prices a list you already have') and get_recommended_games ('taste inferred from the player's WHOLE library'), so an agent can route 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides concrete when-to-use mappings via three natural-language examples ('>80% off with 90%+ reviews' → min_discount + min_review), states an explicit exclusion (DLC/soundtracks/demos filtered out, use get_items for a known DLC appid), and routes to get_items/get_recommended_games for adjacent questions. When-not guidance is explicit, not implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_friends_who_ownFind friends who own a gameARead-only
Check which of a player's Steam friends own one or more games by appid, with each owner's playtime_hours — 'which of my friends have Portal 2 and how long have they played'. Checks each friend's FULL library, unlike get_owned_games whose own list stops at 50 games by playtime by default — so a friend's rarely-played or unplayed copy is never missed (its playtime_hours may still be low or 0). For the PLAYER'S OWN ownership instead of a friend's, use get_owned_games's check_appids. Requires STEAM_API_KEY and the player's OWN friends list to be public — otherwise the whole call returns found:false, which also covers a SteamID64 with no account behind it; read reason. A friend's individually private library is a different, per-friend case: that friend is listed in private_friends (can't be checked) rather than silently counted as a non-owner. Likewise, a friend whose own library lookup failed (e.g. rate-limited) lands in unavailable_friends with a reason instead of failing the whole call — every other friend's result still comes through. Each of owners, private_friends and unavailable_friends is capped at 100 entries (a sibling _total field appears only when it was actually truncated). On a big account only 200 friends are looked up at all (one Steam call per friend would otherwise run past an MCP client's request timeout), and they are the most-recently-added ones — the same ordering and the same prefix get_friend_list shows, so 'the friends checked' is a set you can actually name — compare friends_checked against total_friends, and treat a friend missing from all three lists as unchecked, not as a non-owner. Get appids from search_games.
| Name | Required | Description | Default |
|---|---|---|---|
| appids | Yes | Steam appids to check (1-10). An appid that doesn't exist is not an error — it comes back with an empty `owners` list, indistinguishable from 'no friend owns it'. Confirm it with get_game first if that matters. | |
| steamid | No | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint=true, but the description adds substantial behavioral context beyond that: full-library checking, the 200-friend cap, per-friend failure handling into private_friends/unavailable_friends, 100-entry caps with _total fields, and the found:false behavior for insufficient permissions. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but front-loaded with the core function in the first sentence and every subsequent sentence covers a real edge case needed to use the tool correctly. The density is justified by the tool's complexity, though a slightly tighter structure would improve scannability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with this complexity, the description covers all relevant context: authentication requirements, public/private friend list semantics, failure modes, truncation indicators, ordering, interpretation of missing friends, and cross-references to sibling tools. An output schema exists, so the description's avoidance of detailed return-value documentation is appropriate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% – both appids and steamid have detailed schema descriptions, including effects of nonexistent appids and how to resolve vanity URLs. The description reinforces that appids are game IDs and references search_games, but adds no parameter meaning beyond what the schema already provides. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: 'Check which of a player's Steam friends own one or more games by appid, with each owner's playtime_hours.' It names the exact scope (friends' libraries) and immediately distinguishes itself from get_owned_games, making sibling differentiation explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use and when-not-to-use guidance: 'Unlike get_owned_games...' and 'For the PLAYER'S OWN ownership instead of a friend's, use get_owned_games's check_appids.' It also points to search_games for appid lookup and resolve_vanity_url for SteamID conversion, leaving no ambiguity about alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_chartsGet Steam chartsARead-only
Get what is popular on Steam right now as a ranked list. chart picks one: top_sellers (weekly best-sellers, with weeks on chart), most_played (top 100 by peak players on the last full day, with the rank a week earlier) or concurrent_players (top 100 by players in game right now, live). Use for 'what's hot / top selling / most played on Steam'; for one known game's live count use get_current_players, for the store front page's curated sections (also hardware and bundles) use get_featured, to FILTER the catalog by discount, tags or compat use discover_games. Returns only rank, appid, name, store_url and chart metrics (no price/reviews/Deck status) — pass the appids to get_items for those. last_week_rank null means a new entry; concurrent_players has none. Player-chart names come from a best-effort lookup and may be null. Results are cached for a few minutes. All three are global rankings (the same in every country). No API key required.
| Name | Required | Description | Default |
|---|---|---|---|
| chart | Yes | top_sellers = weekly best-sellers; most_played = yesterday's peak players; concurrent_players = live players now. | |
| limit | No | How many top entries to return (1-100). Default 20. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover read-only/open-world, but the description adds real behavioral context: results are cached for a few minutes, all charts are global (identical in every country), no API key is required, names from a best-effort lookup may be null, and last_week_rank being null signals a new entry. These are traits no annotation or schema conveys.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and routing come first, with behavioral caveats trailing. Packed but efficient; most sentences carry distinct information, though a few clauses (the return-field enumeration) crowd the middle.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, yet the description still clarifies the returned field subset and where to go for price/review data (get_items), plus nullability and caching. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the enum and limit are already documented, but the description adds meaning beyond the schema -- what each chart actually ranks (weeks on chart, peak players on the last full day, live players now), the 100-entry cap nature, and the null semantics of chart metrics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get what is popular on Steam right now as a ranked list') and enumerates the three chart modes with their distinct meanings. It explicitly distinguishes itself from get_current_players, get_featured, and discover_games, so an agent can select it without opening sibling schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives the triggering intent ('what's hot / top selling / most played') and then names three alternatives with the exact condition that selects each: per-game live count, storefront curated sections, and filtered catalog search. Both when-to-use and when-not-to-use are explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_current_playersGet current player countARead-only
Get how many people are playing a game right now (live concurrent player count) by appid. Get the appid from search_games. No API key required. Errors clearly if the appid is unknown/invalid rather than returning a null count.
| Name | Required | Description | Default |
|---|---|---|---|
| appid | Yes | Steam application id (appid). Get it from search_games. |
Output Schema
| Name | Required | Description |
|---|---|---|
| appid | Yes | |
| player_count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true. The description adds valuable behavior beyond that: no API key required, and clear errors on unknown/invalid appid instead of returning a null count. This is useful operational context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences, each earning its place: what the tool does, where to get the required parameter, and expected error behavior. Information is front-loaded and there is no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read-only tool with a full output schema and annotations covering safety, the description covers the prerequisite, error behavior, and authentication requirement. Nothing essential is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the appid parameter already has a description that says to get it from search_games. The description mostly repeats this, adding only the 'by appid' framing. Baseline 3 is appropriate since the schema carries the semantic weight.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action (get live concurrent player count) and the resource (a game identified by appid). It distinguishes itself from sibling tools like get_items and get_game by focusing on current player counts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent to obtain the appid from search_games, which is a clear prerequisite. It does not name alternatives or exclusions, but none are necessary given the unique purpose of this tool among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_featuredGet featured store sectionsARead-only
Get the Steam store's featured sections: specials, top sellers, new releases and coming soon (each a list of games with appid and price), all in one call — for a general 'what's on the store front page' overview. For just current discounts use get_specials (lighter), or discover_games for catalog-wide deals with filters. No API key required.
| Name | Required | Description | Default |
|---|---|---|---|
| country | No | 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. | |
| language | No | 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`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| specials | Yes | |
| coming_soon | Yes | |
| top_sellers | Yes | |
| new_releases | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal read-only and open-world behavior; the description adds that all four sections come in one call, includes appid/price per game, and requires no API key. This adds useful behavioral context beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences deliver purpose, contents, use-case guidance, alternatives, and auth requirement with no filler. The core action and included sections are front-loaded in the first sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With only two optional parameters, fully documented schema, an output schema, and strong annotations, nothing needed for correct invocation is missing. Regional/language fallback details that are not in the description are already present in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both country and language have detailed explanations including fallback behavior and typo handling. The description itself does not add parameter-level detail, which is fine because the schema already carries the full burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 Steam store's featured sections'. It enumerates exactly which sections are included (specials, top sellers, new releases, coming soon) and what data they contain, so an agent knows precisely what this tool returns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly defines the intended use as a general front-page overview and names the alternatives: get_specials for current discounts and discover_games for catalog-wide filtered deals. Also notes that no API key is required, removing a common prerequisite question.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_followed_gamesGet a player's followed gamesARead-only
List the games a player 'follows' on the Steam store, by SteamID64 — a lighter opt-in (get sale/update notifications) that's separate from the wishlist; many players follow more games than they wishlist. No API key required, but the follows/profile must be public — otherwise it returns found:false, which is ALSO what a public account following nothing returns; read reason to tell those apart. Returns appids + store_url only (no price/name), capped at 200 in whatever order Steam sends them — unlike every other capped list here there is no ranking, so a game past the cut is not 'less followed' (check returned vs total); pass the appids to get_items for price, review % and compat. Convert a vanity name with resolve_vanity_url first (that conversion itself needs STEAM_API_KEY, even though this tool doesn't).
| Name | Required | Description | Default |
|---|---|---|---|
| steamid | No | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavior beyond annotations: no API key required, public profile requirement, the found:false ambiguity and how to resolve it with reason, 200-item cap, no ranking semantics, returned vs total, and the limited return fields. This is exactly the kind of context agents need.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence carries unique operational information: purpose, key requirement, ambiguity caveat, return shape, cap/ranking behavior, and linked tools. The core purpose is front-loaded, and later details earn their place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one optional parameter and an output schema, the description covers everything an agent needs: required auth, failure modes, list semantics, how to interpret results, and next-step tool routing. Nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already fully describes the steamid parameter, including the 17-digit format, omission behavior, and vanity URL conversion. The description repeats this rather than adding new parameter-level semantics, so the high schema coverage baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'List the games a player follows on the Steam store, by SteamID64.' It also distinguishes the tool from the wishlist concept, making it clear this is about follow notifications rather than wishlisted games.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when this tool is appropriate (no API key, public profile required), when to use an alternative (get_items for prices, resolve_vanity_url for vanity names), and clarifies that the follows list is separate from the wishlist. It also warns about the 'no ranking' difference from other capped list tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_friend_listGet a player's friend listARead-only
List a player's Steam friends by SteamID64: name, online state, current game and how long they've been friends, most-recently-added first (capped at the 100 most-recently-added; check returned vs total). Requires STEAM_API_KEY and the friends list to be public — otherwise it returns found:false, which also covers a SteamID64 with no account behind it; read reason. For 'which of my friends own game X', use find_friends_who_own instead — it checks each friend's full library, not just this list. Get the SteamID64 from resolve_vanity_url.
| Name | Required | Description | Default |
|---|---|---|---|
| steamid | No | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal readOnlyHint and openWorldHint, and the description adds substantial behavioral context beyond them: the result cap at 100, the returned-vs-total check, the found:false case covering both private lists and nonexistent accounts, and the instruction to read reason. This gives the agent accurate expectations for failure modes and data truncation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: the first states purpose and return fields, the second covers prerequisites and failure semantics, the third distinguishes the sibling tool, and the fourth closes the parameter provenance loop. No filler or redundant restatement.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-optional-parameter read-only tool with an output schema already available, the description is complete: it covers sorting, truncation, failure behavior, authentication prerequisite, the alternative tool, and how to construct the parameter. Nothing needed 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The sole parameter steamid is already fully described in the schema with pattern and default behavior (omitting uses the server-configured STEAM_ID), so schema coverage is 100%. The description reinforces using resolve_vanity_url but does not add significant meaning beyond the schema, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') with a clear resource ('a player's Steam friends by SteamID64') and names the exact fields returned (name, online state, current game, friendship duration). It also explicitly differentiates itself from find_friends_who_own, so an agent can distinguish it from its closest sibling without inspecting schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use context (listing a player's friends) and an explicit when-not-to-use instruction: for 'which of my friends own game X', use find_friends_who_own instead. It also states prerequisites (STEAM_API_KEY, public friends list) and tells the agent how to obtain the required SteamID64 via resolve_vanity_url.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_gameGet game detailsARead-only
Get full store details for one game: description, price/discount, genres, platforms, release date, developers/publishers, Metacritic, age rating, DLC (the dlc appid list is capped at 50 — read dlc_total for the real count, and pass the appids to get_items for names and prices), PC requirements and a small highlighted-achievements sample (achievements_highlighted). Identify the game by appid (from search_games) OR by name — a title is resolved to the closest store match. Both forms error rather than returning an empty result when nothing matches, and an appid can fail for two different reasons: it may not exist, or it may not be sold in the given country. The error names the country and both causes — retry with another country before concluding the game doesn't exist. No API key required.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Game title to look up instead of an appid — resolved to the closest store match. Provide appid OR name; appid wins if both are given. | |
| appid | No | Steam appid (from search_games). Provide appid OR name. | |
| country | No | 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. | |
| language | No | 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`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| dlc | Yes | Appids of this game's DLC, capped — a DLC-heavy game can list hundreds, which would dwarf every other field. Compare against dlc_total, and pass the appids to get_items for their names and prices. |
| name | No | |
| type | Yes | |
| appid | No | |
| demos | Yes | |
| price | Yes | |
| genres | Yes | |
| is_free | Yes | |
| website | Yes | |
| base_game | Yes | |
| dlc_total | Yes | How many DLC this game has in total, before the `dlc` cap. |
| platforms | Yes | |
| store_url | Yes | |
| categories | Yes | |
| developers | Yes | |
| drm_notice | Yes | |
| metacritic | Yes | |
| publishers | Yes | |
| coming_soon | Yes | |
| header_image | Yes | |
| release_date | Yes | |
| required_age | Yes | |
| account_notice | Yes | |
| metacritic_url | Yes | |
| recommendations | Yes | |
| short_description | Yes | |
| achievements_total | Yes | |
| controller_support | Yes | |
| content_descriptors | Yes | |
| pc_requirements_min | Yes | |
| supported_languages | Yes | |
| achievements_highlighted | Yes | A small keyless sample of named achievements Steam highlights for this game, not the full list — for every achievement with rarity and a hidden flag, use get_game_achievements instead. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as readOnly, and the description adds substantial non-obvious behavior: both lookup forms error rather than return empty, appid failures split into two distinct causes, unrecognized language codes silently return English/empty tags, and the DLC list is capped at 50 with dlc_total as the real count. This goes well beyond what 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a dense single paragraph, but every clause carries actionable information and it is front-loaded with the primary purpose. It could be slightly better organized with separate sentences for the error and language caveats, but there is no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description does not need to explain return fields, and it covers the full complexity of 4 optional parameters, error cases, regional pricing, language fallback, and DLC behavior. No important decision-relevant information for correctly invoking the tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 high-value semantics for every parameter: name is 'resolved to the closest store match,' appid must come from search_games, country typo returns US prices rather than an error, and language requires Steam's own names with concrete examples and the empty-tags pitfall. This transforms the parameters from raw schema into usable guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 full store details for one game') and enumerates the exact fields returned, making the tool's purpose unmistakable. It also distinguishes itself from siblings by naming search_games as the source of appids and get_items as the place to resolve DLC appids to names and prices.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states both ways to identify a game (appid from search_games or name), which maps directly to the two alternative tool flows. It also gives concrete when-not/what-to-do guidance: retry with another country before concluding the game doesn't exist, and pass DLC appids to get_items for names/prices.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_game_achievementsGet a game's full achievement listARead-only
List a game's achievements by appid with their names, descriptions, hidden flag and global unlock % (rarity), in the game's own definition order (capped at the first 150; check returned vs total — most games have far fewer). An empty achievements list with total:0 means this appid has no achievement schema at all — a DLC, soundtrack, tool or demo, or an appid that doesn't exist; the two are not reported separately here, so use get_game to confirm the appid is a real base game. Requires STEAM_API_KEY (the achievement schema needs a key). For just the rarity by internal id without a key, use get_global_achievements; for a few named highlights, see get_game's achievements_highlighted; for a specific player's own unlock progress instead of the catalog-wide list, use get_player_achievements. Get the appid from search_games.
| Name | Required | Description | Default |
|---|---|---|---|
| appid | Yes | Steam application id (appid). Get it from search_games. | |
| language | No | Language for achievement names/descriptions; overrides STEAM_LANGUAGE. 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.) |
Output Schema
| Name | Required | Description |
|---|---|---|
| game | Yes | The game's name from Valve's achievement schema — occasionally an internal dev codename rather than the store title (e.g. 'Fiber' for Persona 5 Royal). Treat the appid you passed as the reliable identifier, or get the store title from get_game. |
| total | Yes | |
| returned | Yes | |
| achievements | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: the 150-item cap, the need to compare `returned` vs `total`, the ambiguous empty-list meaning, the key requirement, and the language fallback behavior. It does not contradict annotations. A 4 is appropriate because it adds rich context without being exhaustive about every edge case.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized: the core behavior is front-loaded, followed by the cap/empty-list caveat, the key requirement, and sibling routing. Every sentence earns its place, though the sibling list is long and could arguably be trimmed. It is appropriately sized for a tool with this many caveats.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, the description doesn't need to explain return values. It covers the key requirement, the cap, the ambiguous empty-list case, the language fallback, and how to get the appid. For a read-only list tool with two parameters and a rich output 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.
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 adds meaning beyond the schema by explaining the cap, the empty-list semantics, and the language fallback behavior (unrecognized language returns English and empty tags). It also clarifies that the appid must be a real base game. This pushes it above the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('List a game's achievements by appid') and enumerates exactly what is returned (names, descriptions, hidden flag, global unlock %, order, cap). It also distinguishes itself from siblings by naming get_global_achievements, get_game, and get_player_achievements, so an agent can tell them apart without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: it requires STEAM_API_KEY, tells the agent to use get_global_achievements when only rarity by internal id is needed without a key, get_game for confirming a real base game, get_player_achievements for a specific player's progress, and search_games to obtain the appid. It also explains the empty-list/total:0 case and how to disambiguate it, which is exactly the kind of routing an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_game_newsGet game newsARead-only
Get recent news / patch notes for a game by appid (title, date, author, excerpt, link). Each excerpt is the first ~400 characters of the post with HTML stripped — follow url for the full text. An unknown/unassigned appid comes back as an empty list rather than an error, the same as get_global_achievements. Get the appid from search_games. No API key required.
| Name | Required | Description | Default |
|---|---|---|---|
| appid | Yes | Steam application id (appid). Get it from search_games. | |
| limit | No | How many news items (1-20). Default 5. |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and openWorldHint annotations, the description adds important behavioral details: excerpts are the first ~400 characters with HTML stripped, full text is behind the url, unknown appids return an empty list rather than an error, and no API key is required. This genuinely enriches the agent's understanding of runtime behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence in the description earns its place: purpose, excerpt truncation behavior, empty-list behavior, appid source, and auth requirement. It is appropriately sized, front-loaded, and contains no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter tool with an output schema, the description is remarkably complete. It covers what the tool returns, how the excerpt is truncated, what happens for unknown appids, how to obtain the appid, and that no authentication is needed. Nothing essential for invoking it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 appid and limit, including defaults and ranges. The description repeats the 'get appid from search_games' guidance but adds no new parameter semantics beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 recent news / patch notes for a game by appid'. It lists the returned fields (title, date, author, excerpt, link), making it clearly distinct from sibling tools like get_game_reviews or get_global_achievements.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: it is for recent news/patch notes, the appid should come from search_games, and an unknown appid yields an empty list. It does not explicitly name alternative tools or state when not to use this tool, but the context is sufficient for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_game_reviewsGet game reviewsARead-only
Get the review summary (score label, positive/negative counts, %) and a few recent reviews for a game by appid. Review text over 600 characters is truncated. An unknown appid comes back as summary 'No user reviews' with zero counts rather than an error — Steam answers success for any id — so that result means either no such appid or a game nobody has reviewed yet; confirm the appid with get_game if that distinction matters. For long-term trend instead of a snapshot, use get_review_histogram. Get the appid from search_games. No API key required.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Only positive or negative reviews. Default 'all'. Steam only computes the summary (score label, totals, %) for 'all' — filtering to positive/negative nulls those fields out, leaving only the review excerpts. | all |
| appid | Yes | Steam application id (appid). Get it from search_games. | |
| limit | No | How many recent reviews (1-20). Default 5. | |
| review_language | No | Filter reviews by language. Use Steam's full language name — english, russian, schinese — NOT an ISO code like en/ru/zh: Steam answers an unrecognized value with zero reviews rather than an error, so a 9M-review game reads as having none. Default 'all'. Setting this ALSO rescopes the summary counts (total_reviews / positive / negative / %) to that language — they are no longer the game's global totals. Leave it at 'all' when you want those. | all |
Output Schema
| Name | Required | Description |
|---|---|---|
| reviews | Yes | |
| summary | Yes | |
| positive_pct | Yes | |
| total_reviews | Yes | |
| total_negative | Yes | |
| total_positive | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry readOnlyHint and openWorldHint, and the description adds significant behavior beyond that: 600-character truncation, no API key required, unknown appids returning a zero-count summary instead of an error, and language filtering rescoping summary counts. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded with the core behavior, then adds edge cases, alternatives, input sourcing, and auth-free confirmation. Every sentence earns its place and none merely restates the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers result contents, truncation, unknown-appid behavior, the alternative tool for trends, appid provenance, and the side effect of language filtering. The output schema handles return shape, so no redundant explanation is needed. An agent has everything required to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 goes further by explaining that an unknown appid yields a zero-count result rather than an error and by clarifying that language filtering changes the meaning of the summary counts, which adds practical semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 the review summary (score label, positive/negative counts, %) and a few recent reviews for a game by appid. It explicitly differentiates from the sibling get_review_histogram by naming it as the trend alternative, so an agent can distinguish snapshot vs trend use cases.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-not-to-use guidance: 'For long-term trend instead of a snapshot, use get_review_histogram.' It also tells the agent where to source the appid (search_games) and when to confirm an ambiguous empty result with get_game. Clear context with an exclusion and alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_global_achievementsGet global achievement ratesARead-only
Get the global unlock percentage of each achievement in a game by appid — how rare each achievement is across all players. Returns each achievement's internal name and its unlock percent (no display names/descriptions — for those, use get_game_achievements), most-common first, capped at the first 200 (check returned vs count — most games have far fewer). An unknown appid, or one with no achievement schema (e.g. a DLC/soundtrack), comes back as an empty list rather than an error, the same as get_game_news. Get the appid from search_games. No API key required.
| Name | Required | Description | Default |
|---|---|---|---|
| appid | Yes | Steam application id (appid). Get it from search_games. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| returned | Yes | |
| achievements | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses several behavioral traits beyond the readOnlyHint and openWorldHint annotations: results are capped at 200, ordered most-common first, empty list is returned instead of an error for unknown appids, and no API key is required. This gives the agent a clear model of what the tool will do in practice.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: purpose, output format, ordering, cap, edge-case behavior, alternative tool, appid source, and auth requirement. It is front-loaded with the core purpose and remains readable despite covering many details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and the annotations cover safety, the description fills all remaining gaps: it explains the return fields, the cap, the ordering, the empty-list behavior, the appid source, and the lack of auth requirements. Nothing an agent needs to call this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully documents the single appid parameter with 100% coverage, including the instruction to get it from search_games. The description reinforces this but adds little new semantic meaning beyond what the schema 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.
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 the global unlock percentage of each achievement in a game by appid' and clarifies what that means ('how rare each achievement is across all players'). It also explicitly distinguishes itself from get_game_achievements by noting it returns internal names and unlock percents, not display names/descriptions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear when-to-use guidance and names the alternative: 'no display names/descriptions — for those, use get_game_achievements'. It also tells the agent where to get the appid ('Get the appid from search_games') and explains edge-case behavior for unknown appids, which helps the agent decide when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_itemsBatch store card for many gamesARead-only
Get price/discount, review % (positive), hardware compatibility, popular user tags and release date for a LIST of games by appid in ONE keyless call. The efficient way to price-, rating-, tag- and compat-check a wishlist or library without a request per game. For a bigger batch (up to 250 appids) when you only need price, use get_prices instead. An unknown/invalid appid comes back as its own row marked available:false — rows stay in the order you passed them, one per id, never dropped, same as get_prices. Each item carries four compatibility fields, each verified/playable/unsupported/unknown: steam_deck (Steam Deck), steam_os (SteamOS in general), steam_machine (the Steam Machine console specifically), and steam_frame (Steam Frame VR headset); a vr_support flag (none/supported/required — distinct from steam_frame, which is a Steam Frame HARDWARE compat rating, not whether the game itself has a VR mode); a tags list (top user tags like 'Roguelike', 'Souls-like', most-relevant first); a clickable store_url to the game's Steam page; and, when on sale, discount_end (ISO UTC time the discount expires — for 'how long is this deal valid'). To find NEW games by filter (discount, rating, tags, compat) instead of pricing a list you already have, use discover_games instead. Get appids from search_games / get_wishlist / get_owned_games.
| Name | Required | Description | Default |
|---|---|---|---|
| appids | Yes | Steam appids (1-50). Split a longer list across calls. | |
| country | No | 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. | |
| language | No | 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`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| items | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the call read-only. The description adds important behavior beyond that: unknown appids come back as available:false rows, row order is preserved, no rows are dropped, discount_end is ISO UTC, and language failures silently return English/empty tags. It also clarifies the VR/compat distinction. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but dense and front-loaded with the core purpose. Every major behavioral detail earns its place, though a couple of parenthetical clarifications could be tightened. It is appropriately structured for a tool with this many edge-case semantics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter tool with an output schema, the description covers the remaining context completely: batch limits, alternatives, error/edge behavior, field semantics, and input gotchas. An agent has everything needed to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema coverage is 100%, the description adds meaning beyond the schema: appids are positional and never dropped, country typos silently resolve to US prices, and language must be a Steam language name rather than an ISO code, with empty tags as a failure symptom. This materially improves correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 price/discount, review %, hardware compatibility, tags, and release date for a list of appids in one call. It also differentiates itself from get_prices and discover_games, so an agent can tell which tool is which.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use an alternative: use get_prices for price-only batches up to 250 appids, and use discover_games to find new games by filter. It also points to search_games, get_wishlist, and get_owned_games as sources for appids. This is strong routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_owned_gamesGet owned gamesARead-only
List the games a player owns with playtime (hours), ordered by playtime — most-played first by default, least-played first with sort='playtime_asc' (the games list is capped to 50 entries by default, so the far end of that ordering may not appear there; raise limit to widen the cap, or flip sort to keep the never-played end instead, which is what a 'what have I never got round to playing' question needs). To reliably check whether the player owns one or more SPECIFIC appids regardless of that cap — 'do I own game X' — pass check_appids; the owns field then checks the FULL, uncapped library, with each result's own playtime_hours (null if not owned). For the last two weeks of play instead of the all-time library, use get_recently_played. For checking a FRIEND's ownership instead of the player's own, use find_friends_who_own. Requires STEAM_API_KEY and a public profile + game-details visibility. Get the SteamID64 from resolve_vanity_url.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Which end of the library the cap keeps: 'playtime_desc' (default) the most-played, 'playtime_asc' the least-played and never-played first. | |
| limit | No | How many games to return (1-300, default 50). Raise it only when a wider slice of the library is genuinely needed — the ceiling is a response-size budget, so even a 4000-game account never comes back whole. To check specific appids past the cap, use check_appids rather than a bigger limit. | |
| steamid | No | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. | |
| check_appids | No | Steam appids to check ownership of (1-50), regardless of the 50-entry cap on `games` (or of whichever end `sort` keeps). Prefer this over raising `limit`: it reads the FULL library, and its own cost is bounded by this list's length. Adds an `owns` field: [{appid, owned, playtime_hours}]. One upstream gap to know about: Steam omits free-to-play titles the player owns but has NEVER launched, so those report owned:false — as does an appid that doesn't exist, so this field can't tell 'no such game' from 'doesn't own it'. A private profile reports no `owns` at all (ownership unknown) rather than a false owned:false. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations carry readOnlyHint=true and openWorldHint=true, but the description adds substantial behavior beyond that: the 50-entry cap is a 'response-size budget' that never returns a full 4000-game account, and the edge cases for check_appids are disclosed — free-to-play titles never launched report owned:false, nonexistent appids also report owned:false, and a private profile reports no 'owns' at all rather than a false negative. These are genuine, non-obvious behavioral disclosures that materially change how an agent should interpret results. No contradiction with the read-only annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but every sentence earns its place — it tackles real complexity (cap ordering, uncapped checks, edge cases, sibling routing). It is front-loaded with the core purpose and sorts precedence, then flows into cap behavior, check_appids, alternatives, and requirements in a logical order. It skirts length but never pads; it borders on dense rather than bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 0 required parameters, 4 optional params, an output schema (so return values need not be spelled out), and high edge-case complexity, the description is complete. It covers the cap and ordering behavior, the uncapped ownership check with its caveats, all three sibling differentiators, requirements, and the steamid source. An agent has 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema descriptions are themselves detailed (sort enum semantics, limit ceiling of 300 as a budget, steamid pattern). The description adds guidance over and above the schema: 'raise it only when a wider slice of the library is genuinely needed', 'Prefer this over raising limit' for check_appids, and the owns-field format. This exceeds the baseline 3 because the description clarifies when and why to use each parameter, not just what it means.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'List the games a player owns with playtime (hours), ordered by playtime'. It immediately distinguishes itself from siblings by naming the alternatives — 'For the last two weeks of play... use get_recently_played' and 'For checking a FRIEND's ownership... use find_friends_who_own'. An agent can separate this from the 24 sibling tools 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage guidance is explicit and conditional: when to use get_recently_played (last-two-weeks scenarios), when to use find_friends_who_own (friend ownership), and when to pick check_appids over a bigger limit ('To check specific appids past the cap, use check_appids rather than a bigger limit'). It also states prerequisites (STEAM_API_KEY, public profile, game-details visibility) and tells how to obtain the steamid. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_player_achievementsGet a player's achievementsARead-only
Get a player's achievement progress for one game (unlocked count, % complete, per-achievement unlock dates) by SteamID64 + appid — unlocked/completion_pct always reflect the full list, but the per-achievement achievements array is capped at 200, unlocked first (check returned vs total — most games have far fewer). For the game's full achievement list (names, descriptions, global rarity) independent of any player, use get_game_achievements instead; for just the rarity without a key, use get_global_achievements. Requires STEAM_API_KEY and a public profile with game-details visibility — otherwise it returns found:false — which is also what an appid with no achievements, or no such appid at all, returns; the three are not reported separately, so confirm the appid with get_game.
| Name | Required | Description | Default |
|---|---|---|---|
| appid | Yes | Steam application id (appid). Get it from search_games. | |
| steamid | No | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. | |
| language | No | Language for achievement names/descriptions; overrides STEAM_LANGUAGE. 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.) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnlyHint annotation by disclosing the 200-item cap on the achievements array with unlocked-first ordering, the need to compare returned vs total, and the ambiguous found:false return for three distinct failure conditions. It also explains the language-parameter edge case (unrecognized value returns English with empty tags). These are non-obvious behaviors that annotations alone do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each dense with essential information: purpose and output cap in the first, sibling routing in the second, prerequisites and failure modes in the third. No filler or repetition; the most actionable information (what the tool does) is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with an output schema and read-only annotations, the description covers all operational essentials: requirements, ambiguity handling, result-cap semantics, and alternative routes. It explains the three indistinguishable failure cases and directs the agent to confirm appids with get_game, which is exactly the kind of contextual guidance an agent needs. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter already has a full description (e.g., steamid omission default, language name format). The tool description adds contextual output details but no new parameter-specific meaning beyond what the schema provides. Baseline 3 is appropriate because the schema carries the parameter documentation burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 a player's achievement progress for one game') and enumerates the exact outputs (unlocked count, % complete, per-achievement unlock dates). It explicitly names sibling tools get_game_achievements and get_global_achievements and states what each alternative does, so an agent can distinguish them without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit routing: 'For the game's full achievement list... use get_game_achievements instead; for just the rarity without a key, use get_global_achievements.' It also states prerequisites (STEAM_API_KEY, public profile with game-details visibility) and recommends confirming ambiguous appids with get_game. This leaves no ambiguity about when to invoke this tool versus its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_player_bansGet a player's ban statusARead-only
Check a player's VAC, game, community and economy (trade) ban status by SteamID64 — 'is this player banned', useful before trading or adding a friend. Ban status is always public — this works even when the rest of the profile is private. days_since_last_ban is null for a player who has never been banned — Steam sends 0 there, which would otherwise read as 'banned today'. Requires STEAM_API_KEY.
| Name | Required | Description | Default |
|---|---|---|---|
| steamid | No | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, but the description adds valuable behavioral details: ban status is always public regardless of profile privacy, and the null-vs-0 nuance for days_since_last_ban (which prevents misinterpreting 'never banned' as 'banned today'). It also discloses the STEAM_API_KEY requirement. These go well beyond the annotations and significantly improve correct interpretation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero fluff. The primary purpose is front-loaded, the public-status clarification follows naturally, and the critical output nuance is placed last. Every clause contributes new information; no redundancy with the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema (so return values need no explanation), the description covers all necessary invocation details: purpose, parameter guidance, environmental requirement (API key), and a data-interpretation quirk. Nothing an agent needs to correctly select and use this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (the steamid parameter is fully documented), so baseline is 3. The description adds extra meaning by explaining the optionality (omit to use configured STEAM_ID) and by directing users to resolve_vanity_url for vanity names. This enriches the schema's plain pattern/type description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb 'Check' and explicitly lists the resource: 'VAC, game, community and economy (trade) ban status by SteamID64'. It also states the practical use case ('useful before trading or adding a friend'), which clearly distinguishes this from other player-related siblings like get_player_summary. No ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear usage context: 'useful before trading or adding a friend' and notes that ban status works even when profiles are private. The schema adds an explicit routing instruction to 'Convert a vanity/custom URL name with resolve_vanity_url first'. However, it does not explicitly name other alternatives or state when NOT to use this tool, 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.
get_player_summaryGet player profileARead-only
Get a player's profile by SteamID64: display name, online state, country, account age, Steam level (a separate lookup that degrades to null on failure, independently of profile privacy), and the game they're currently in. found:false here means exactly one thing — no account with that SteamID64 — since this tool reads private profiles fine. Requires STEAM_API_KEY, but works even for a private profile (visibility reports 'private') — country, account age and the current game only populate when the profile is public. For VAC/game/trade ban status instead, use get_player_bans.
| Name | Required | Description | Default |
|---|---|---|---|
| steamid | No | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, but the description adds valuable behavioral nuances beyond those: the found:false semantics (no account vs. private), the separate Steam-level lookup that degrades to null, and the visibility-dependent field population. This is far beyond the minimal annotation coverage and gives the agent critical operational expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: purpose, field list, found:false clarification, private-profile behavior, prerequisites, and a sibling pointer. Information is front-loaded and there is zero fluff, making it concise despite its length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's relative simplicity (one optional param), the description covers all essential context: prerequisites (API key), edge cases (private profiles, found:false), field nuances (public-only fields, Steam-level degradation), and an alternative tool. The existence of an output schema means return values don't need explanation, and the description fills in all other gaps adequately.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% coverage for the single parameter 'steamid' with a clear description (17-digit pattern, omission fallback, and vanity resolution hint). The tool description adds no additional parameter-level meaning, 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.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific verb 'Get' and resource 'player's profile', enumerating the exact fields (display name, online state, country, account age, Steam level, current game). It also distinguishes itself from the sibling get_player_bans by explicitly noting the ban-status alternative, so an agent can easily select the right tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance: it mentions the required STEAM_API_KEY, clarifies that it works on private profiles, notes which fields only populate for public profiles, and explicitly directs to get_player_bans for ban status. This provides strong when-to-use and alternative tool routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_pricesGet prices for many gamesARead-only
Get current price and discount for a batch of games by appid in one call — efficient for checking a whole list (e.g. a wishlist) for deals. Handles up to 250 appids; if you also need review %, hardware compatibility or tags, use get_items instead (max 50 appids). Rows come back in the same order as the given appids, one per id (unavailable ones marked available:false — no such appid, not sold in that country, or a transient upstream failure on the chunk it fell in, so retry before concluding a game is unavailable — never dropped). A priced row carries final/initial price and discount_percent. A row marked priced:false has no price block at all, which is how BOTH free-to-play and not-yet-released titles come back: this endpoint cannot tell them apart, so never report priced:false as 'free' — pass those appids to get_items, whose is_free/coming_soon do separate them. No API key required. Get appids from search_games or get_wishlist.
| Name | Required | Description | Default |
|---|---|---|---|
| appids | Yes | Steam appids to price (1-250). Split a longer list across calls. | |
| country | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| prices | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even though annotations already declare readOnlyHint and openWorldHint, the description adds substantial behavioral context: rows preserve input order, unavailable rows are marked available:false, transient upstream failures should be retried, and priced:false does not mean free. It also warns that the endpoint cannot distinguish free-to-play from not-yet-released titles. This goes well beyond the annotations and prevents serious misinterpretation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence carries necessary operational information, and the structure is logical: purpose, capacity/alternative, row ordering and failure semantics, priced:false ambiguity, auth, and source of appids. The most important caveats are front-loaded and there is no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's tricky edge cases, the description is complete: it covers batching limits, ordering, unavailable rows, retry behavior, the free-to-play/not-yet-released ambiguity, and how to resolve it via get_items. An output schema exists, so return-value details are already structured, and the description adds the semantic context an agent needs to use the results correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 appids and country, including the 250 limit, splitting longer lists, country code format, and the typo-to-US-prices behavior. The description reinforces the batch size and mentions country in the availability caveat, but it does not add new parameter-level 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.
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 current price and discount for a batch of games by appid in one call.' It clearly distinguishes this from siblings by naming get_items as the alternative for review %, hardware compatibility, or tags. An agent can immediately tell what this tool does and how it differs from nearby tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: efficient for checking a whole list like a wishlist, handles up to 250 appids, and directs to get_items when other metadata is needed. It also tells the agent to pass priced:false appids to get_items when free-to-play vs. not-yet-released must be distinguished. This is model guidance with clear alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recently_playedGet recently played gamesARead-only
List the games a player has played in the last two weeks, with recent and total playtime, most-played-in-those-two-weeks first (capped at 50; check returned vs total) — the ordering is what decides which games the cap keeps, and it is playtime, not recency. For the all-time library by playtime instead (capped at 50 entries by default, either end of that ordering via sort), use get_owned_games. Requires STEAM_API_KEY and a public profile with game-details visibility (same requirement as get_owned_games) — otherwise it returns found:false.
| Name | Required | Description | Default |
|---|---|---|---|
| steamid | No | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, but the description adds crucial behavioral details: the cap of 50 with returned vs total check, the fact that ordering is by playtime not recency, the auth/visibility requirement, and the failure mode. This goes well beyond the annotations and fully discloses behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is information-dense but every sentence earns its place. It front-loads the core action and scope, then covers the cap, ordering, alternative, and requirements without repetition or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering safety, the description supplies all missing context: ordering logic, cap semantics, failure mode, and alternative routing. An agent has everything needed to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is only one parameter (steamid), and the schema description already covers its semantics completely (format, omission behavior, vanity URL conversion). The tool description adds no additional parameter-level meaning, so the baseline of 3 applies given 100% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List') and resource ('games a player has played in the last two weeks') with precise scope (recent vs total playtime, ordering by most-played). It explicitly distinguishes itself from get_owned_games, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear when-to-use context ('last two weeks') and explicitly names the alternative (get_owned_games) with the condition that selects it ('all-time library by playtime'). It also states the prerequisite (STEAM_API_KEY, public profile) and failure mode (found:false), leaving no ambiguity about when to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recommended_gamesGet personalized game recommendationsARead-only
Recommend unowned Steam catalog games personalized to this player: tags on their own most-played owned games become weighted preferences (more playtime on a tag = more weight), discounted by each candidate's review score so a tag match on a poorly-received game doesn't outrank a better one, then ranked against a broad catalog page, excluding anything already owned. based_on_tags shows which of the player's own top tags drove the ranking; each result carries matched_tags and match_score alongside the usual price/review/compat card. Set exclude_tags to steer away from a genre despite it matching by playtime, and/or min_discount for a minimum deal size (e.g. 'suggest games on sale, not RPGs or shooters' → exclude_tags:['RPG','Shooter','FPS'], min_discount:30). Different from discover_games (which needs YOU to name the filters) — this infers taste from the player's WHOLE library instead, for 'what should I play next' / 'recommend me something'. For 'something like THIS ONE game' (a single named title), get its tags via get_items and call discover_games with them instead. Recommends base games only — DLC, soundtracks and demos are never suggested, the same filter discover_games applies. Note: taste is weighted from only the player's 30 most-played owned games, and candidates come from a fixed 300-entry catalog scan, so a heavy exclude_tags/min_discount combination can return fewer than limit — there's no larger scan to fall back to. Requires STEAM_API_KEY and a public profile with game-details visible (same requirement as get_owned_games) — found:false is also returned if the player owns no games at all, or if too few of their played games have resolvable tags to build a taste profile.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many recommendations to return (1-25). Default 10. | |
| steamid | No | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. | |
| exclude_tags | No | Drop any candidate carrying ANY of these tags (case-insensitive), e.g. ['Souls-like'] for 'recommend me something except Souls-like'. Use exact Steam tag names — a misspelled/unrecognized one isn't an error, it just drops nothing. | |
| min_discount | No | Minimum discount %, e.g. 30 for '30%+ off'. Omit to include full-price games too. Filtered server-side and re-checked client-side, so it holds at any value including 100. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint, but the description adds rich behavioral detail: the 30 most-played games weighting, fixed 300-entry catalog scan, possibility of fewer results than limit, requirements for STEAM_API_KEY and public profile, and failure modes (found:false). It also describes result fields (matched_tags, match_score, based_on_tags) and the base-games-only filter. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence carries meaning: algorithm, differentiation, examples, limitations, and error conditions. It is front-loaded with the core purpose and then layers details. Slightly dense but not redundant; it could be tightened but remains efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the description covers purpose, usage, parameters, output fields, limitations, prerequisites, and edge cases. The output schema exists (so return format is partly structured), but the description adds the algorithmic context and failure modes. Nothing essential is missing for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds significant value: it explains the purpose of exclude_tags with an example ('steer away from a genre despite it matching by playtime'), clarifies min_discount semantics with an example, and notes that limit may be under-filled due to the fixed catalog scan. This goes well beyond the schema's plain parameter definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise statement: 'Recommend unowned Steam catalog games personalized to this player', then explains the recommendation algorithm (weighted tags, review-score discount) and explicitly distinguishes itself from discover_games. The verb, resource, and personalization are all clear, and the differentiation from siblings is direct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use this tool ('what should I play next' / 'recommend me something') and when not to ('something like THIS ONE game' → use get_items + discover_games instead). It also provides a concrete example with exclude_tags and min_discount. This is exemplary guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_review_histogramGet review trend over timeARead-only
Get how a game's reviews trend over time by appid: a long-term history (rollup_type reports each entry's granularity, e.g. 'week' or 'month', chosen server-side by Steam; capped at the most recent 24 entries) and the recent per-day breakdown (capped at the most recent 30 days), each with positive/negative counts and positive %. Good for 'are reviews improving / did an update hurt reception'. An unknown appid comes back as empty history/recent arrays rather than an error — Steam answers success for any id — so an empty result means either no such appid or a game nobody has reviewed yet; confirm the appid with get_game if that distinction matters. For a current summary and example review text instead of a trend, use get_game_reviews. Get the appid from search_games. No API key required.
| Name | Required | Description | Default |
|---|---|---|---|
| appid | Yes | Steam application id (appid). Get it from search_games. |
Output Schema
| Name | Required | Description |
|---|---|---|
| recent | Yes | |
| history | Yes | |
| rollup_type | Yes | Granularity of each `history` entry's date bucket, e.g. 'week' or 'month' — chosen server-side by Steam and passed through as a free-form string (not validated or enumerated here), so don't assume a fixed set of possible values. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and openWorldHint annotations, the description discloses key behaviors: server-side rollup granularity, caps of 24 long-term entries and 30 recent days, empty arrays for unknown appids instead of errors, Steam's success-for-any-id behavior, and no API key requirement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: core behavior first, then caps, then empty-result semantics, then sibling routing, then appid sourcing, then auth. It is front-loaded with the most important operational detail before caveats.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers what the tool returns, how results are capped, the rollup_type semantics, the empty-array ambiguity, how to disambiguate with get_game, and which sibling to use for non-trend data. With an output schema also present, 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents the appid parameter and tells the agent to get it from search_games. The description adds the empty-result caveat for unknown appids, but that is more behavioral than parameter-level meaning, 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.
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 how a game's reviews trend over time by appid'. It also distinguishes itself from the sibling get_game_reviews, which returns a current summary and example review text instead of a trend.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly gives use cases ('Good for are reviews improving / did an update hurt reception') and names the alternative get_game_reviews when trend data is not what is needed. It also instructs the agent to get appid from search_games and to confirm unknown appids with get_game.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_specialsGet current discountsARead-only
List games currently on special (discounted) on the Steam store front page, with the discount % and original/final price. For ALL catalog discounts (not just the front page), use discover_games with min_discount. No API key required.
| Name | Required | Description | Default |
|---|---|---|---|
| country | No | 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. | |
| language | No | 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`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| specials | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, covering safety. The description adds the scope constraint (front page only) and the no-key requirement, but does not disclose any other behavioral traits (e.g., pagination, limits, edge cases). With annotations carrying the main 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero waste. The core purpose and output are front-loaded, followed by the alternative and a key requirement. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, has an output schema (so return values need no description), and the schema fully documents parameters. The description covers scope and the alternative. With readOnly annotations covering safety, 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters have detailed descriptions including edge-case behavior (unrecognized country returns US prices, unrecognized language returns empty tags). The description adds nothing about parameters, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('List games currently on special (discounted) on the Steam store front page') and details the output (discount % and original/final price). It explicitly differentiates from a sibling by directing to discover_games for all-catalog discounts, making it unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly states when to use this tool (front-page specials) and when not (all catalog discounts → discover_games with min_discount). It also notes 'No API key required,' a practical usage hint. This is explicit routing to the correct alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_wishlistGet a player's wishlistARead-only
List a player's Steam wishlist by SteamID64. No API key required, but the wishlist/profile must be public — otherwise it returns found:false, which is ALSO what an empty but public wishlist returns; read reason to tell those apart. By default returns a light list of appids (sorted by priority, no names), capped at the first 100 (check returned vs total). Set include_details for full store cards in ONE call (name, price/discount, review %, Deck/SteamOS/Machine/Frame compat, vr_support, tags, release) — no need to follow up with get_items. Narrow it in the SAME call with tags (e.g. ['Metroidvania']), platform (NATIVE windows/mac/linux build), steam_deck/steam_os/steam_machine/steam_frame (Proton compatibility — see each field), min_review, min_discount / on_sale_only, or country / language. Any of these filters switches to the detailed card view, since the light appid list has no price/tags/compat to filter on. Filters apply before the output cap (the detailed card list returns at most 50 items), so a deeply-discounted niche match past the display cap is never hidden by it (e.g. 'top metroidvanias on my wishlist with a good discount and reviews' → tags:['Metroidvania'] + min_discount + min_review). Results ranked by discount when a discount filter is set, else by wishlist priority; matched reports the pre-cap count. Steam itself only attaches store data to roughly the first 100 wishlist entries per call — on a bigger wishlist, enriched reports how many of total got checked, and note explains when some were skipped (their filter/price data isn't available at all, not that they don't match). Convert a vanity name with resolve_vanity_url first (that conversion itself needs STEAM_API_KEY, even though this tool doesn't).
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Keep only wishlist items carrying ALL of these user tags (case-insensitive), e.g. ['Metroidvania']. Use exact Steam tag names — a misspelled/unrecognized one isn't an error, it just matches nothing. Implies include_details. | |
| country | No | Country (cc) for prices; overrides STEAM_COUNTRY. Implies include_details. 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. | |
| steamid | No | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. | |
| language | No | Store language; overrides STEAM_LANGUAGE. Implies include_details. 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.) | |
| platform | No | 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. | |
| steam_os | No | 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. | |
| min_review | No | Keep only items with at least this positive-review %. Implies include_details. | |
| steam_deck | No | Steam Deck compatibility (runs via Proton): 'verified' = Deck-Verified only; 'playable' = Playable or Verified. Not a native Linux build — see `platform` for that. | |
| steam_frame | No | Steam Frame (VR headset) compatibility: 'verified' = Frame-Verified only; 'playable' = Playable or Verified. | |
| min_discount | No | Keep only items discounted at least this %, ranked by discount. Implies include_details. | |
| on_sale_only | No | Only wishlist items currently discounted, ranked by discount %. Implies include_details. | |
| steam_machine | No | 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. | |
| include_details | No | Return full store cards (name, price, discount, reviews, compatibility, tags) per item in one call, instead of just appids. Implied by any filter below. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint; the description adds substantial unsurfaced behavior: found:false ambiguity between private and empty-public, the reason disambiguator, the 100/50 caps, Steam's ~100-entry enrichment limit with enriched/note reporting, and silent-failure semantics for bad language/country.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded correctly (what it does, then caveats, then filters), and nearly every sentence carries real information. But it is a single ~350-word paragraph dense with em-dash parentheticals, making it hard to scan; it could be broken into labeled blocks without losing any content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still explains the output contract an agent needs to reason about (returned vs total, matched, enriched, note). For a 13-parameter tool with 0 required params and complex filter interactions, nothing material is left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and already carries rich per-parameter docs, so baseline is 3. The description still adds cross-parameter semantics the schema states individually: any filter implies include_details, filters apply before the output cap, and results rank by discount when a discount filter is set else by priority.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+key ('List a player's Steam wishlist by SteamID64') and immediately distinguishes itself from a sibling by stating there's no need to follow up with get_items. An agent can identify scope and output shape 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing guidance: resolve_vanity_url must come first for a vanity name (and that call needs an API key even though this one doesn't). It also states when filters switch the view, and gives a concrete example ('top metroidvanias... + min_discount + min_review').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolve_vanity_urlResolve vanity URL to SteamIDARead-only
Convert a Steam custom (vanity) profile name — the part after /id/ in a profile URL — into the 17-digit SteamID64 that the player tools need. Requires STEAM_API_KEY. Returns found:false if the name doesn't resolve to a profile.
| Name | Required | Description | Default |
|---|---|---|---|
| vanity | Yes | Vanity name, e.g. 'gabelogannewell' from steamcommunity.com/id/gabelogannewell. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint and openWorldHint. Description adds key behavioral details: requiring an API key and returning a specific false flag. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no wasted words. First sentence informs purpose and input, second covers prerequisite and a possible output. Front-loaded with action and result.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With one parameter, 100% schema coverage, existing annotations, and an output schema present, the description covers the input format, a prerequisite, and a failure case. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers the parameter fully; description adds a concrete example ('gabelogannewell') and explains its origin from the URL. Provides meaning beyond the schema description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly specifies the action (convert/ resolve), the resource (vanity profile name), and the result (17-digit SteamID64). Distinguishes itself from sibling tools which are about games, reviews, or player lists; this is the only one that resolves vanity URLs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States requirement for STEAM_API_KEY and describes behavior when the name doesn't resolve (found:false). Implicitly tells when to use (when you have a vanity URL part) but could be more explicit about when not to use (e.g., if already have SteamID64).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_gamesSearch gamesARead-only
Search the Steam store by title — term can be partial or approximate, not an exact match; returns matches with their appid (needed by the other game tools), price, Metacritic score, platforms, type and a clickable store_url. Note type is Steam's storesearch value, which is 'app' for every store item — it does NOT distinguish a game from its DLC or soundtrack; call get_game on the appid for the real type (game/dlc/music/…). Returns only Steam's own first page of matches (~10, no pagination) — refine the term if the game you want isn't listed. No API key required.
| Name | Required | Description | Default |
|---|---|---|---|
| term | Yes | Game title to search for. | |
| country | No | 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. | |
| language | No | 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`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | |
| results | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations only declare readOnlyHint and openWorldHint, so the description carries the burden of behavioral detail. It adds substantial context: no API key required, no pagination (only ~10 first-page matches), the misleading nature of the 'type' field, and the need to refine terms. This goes well beyond the annotations and prevents false expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: core behavior, return fields, the type caveat, the pagination limitation, and the auth requirement. It is front-loaded with the main purpose and uses clear signposting for caveats. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers what the tool returns, its limitations, the follow-up tool to call, and the absence of an API key requirement. An output schema exists, so return-value details don't need to be repeated. There is no critical missing information for an agent to invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 beyond the schema: it clarifies that the term can be partial or approximate and explains that the returned 'type' is not the real content type. The country and language parameters are already richly documented in the schema, so the description's incremental value is moderate but real.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Search the Steam store by title' and immediately clarifies the match semantics (partial/approximate, not exact). It also names the key output (appid, price, Metacritic score, platforms, type, store_url) and distinguishes itself from get_game by noting the real type requires a follow-up call.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: use this to search by title, refine the term if the target isn't on the first page, and call get_game on the appid to get the real type. It does not explicitly contrast with discovery-oriented siblings like discover_games or get_featured, but the title-search scope is clear enough for an agent to select it appropriately.
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 tool update
v0.15.0- Added
get_charts
24 tool updates
v0.14.0- Changed
compare_players1 field changed- changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "games": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "playtime_hours_a": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "playtime_hours_b": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "name", - "playtime_hours_a", - "playtime_hours_b" - ], - "type": "object" - }, - "type": "array" - }, - "returned": { - "type": "number" - }, - "shared_count": { - "type": "number" - } - }, - "required": [ - "found", - "shared_count", - "returned", - "games" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "games": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "playtime_hours_a": { + "type": [ + "number", + "null" + ] + }, + "playtime_hours_b": { + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "name", + "playtime_hours_a", + "playtime_hours_b" + ], + "type": "object" + }, + "type": "array" + }, + "returned": { + "type": "number" + }, + "shared_count": { + "type": "number" + } + }, + "required": [ + "found", + "shared_count", + "returned", + "games" + ], + "type": "object" + } +]
- Changed
discover_games28 fields changed- changed
Input schema / properties / country / descriptionPrevious 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." - changed
Input schema / properties / language / descriptionPrevious 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`." - changed
Input schema / properties / min_review / descriptionPrevious 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." - changed
Input schema / properties / min_reviews / descriptionPrevious 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." - added
Input schema / properties / released_after / formatAdded value: +"date" - changed
Input schema / properties / released_after / patternPrevious 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])))$" - changed
Input schema / properties / released_within_days / descriptionPrevious 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." - removed
Output schema / properties / deals / items / properties / discount_end / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / deals / items / properties / discount_end / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / deals / items / properties / name / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / deals / items / properties / name / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / deals / items / properties / original / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / deals / items / properties / original / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / deals / items / properties / price / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / deals / items / properties / price / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / deals / items / properties / release_date / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / deals / items / properties / release_date / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / deals / items / properties / review_count / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / deals / items / properties / review_count / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / deals / items / properties / review_label / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / deals / items / properties / review_label / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / deals / items / properties / review_percent / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / deals / items / properties / review_percent / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / deals / items / properties / store_url / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / deals / items / properties / store_url / typeAdded value: +[ + "string", + "null" +] - added
Output schema / properties / deals / items / properties / tags / descriptionAdded 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." - removed
Output schema / properties / total_matching / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / total_matching / typeAdded value: +[ + "number", + "null" +]
- Changed
find_friends_who_own2 fields changed- changed
Input schema / properties / appids / descriptionPrevious value: -"Steam appids to check (1-10)."New value: +"Steam appids to check (1-10). An appid that doesn't exist is not an error — it comes back with an empty `owners` list, indistinguishable from 'no friend owns it'. Confirm it with get_game first if that matters." - changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "friends_checked": { - "description": "How many of `total_friends` were actually looked up. Lower than total_friends on a very large friend list, where checking every one would exceed an MCP client's request timeout — the unchecked friends are simply absent from all three lists below, so treat a gap here as 'not checked', never as 'doesn't own it'.", - "type": "number" - }, - "matches": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "owners": { - "items": { - "additionalProperties": false, - "properties": { - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "playtime_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "steamid": { - "type": "string" - } - }, - "required": [ - "steamid", - "name", - "playtime_hours" - ], - "type": "object" - }, - "type": "array" - }, - "owners_total": { - "type": "number" - } - }, - "required": [ - "appid", - "owners" - ], - "type": "object" - }, - "type": "array" - }, - "private_friends": { - "items": { - "additionalProperties": false, - "properties": { - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "steamid": { - "type": "string" - } - }, - "required": [ - "steamid", - "name" - ], - "type": "object" - }, - "type": "array" - }, - "private_friends_total": { - "type": "number" - }, - "total_friends": { - "type": "number" - }, - "unavailable_friends": { - "items": { - "additionalProperties": false, - "properties": { - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "reason": { - "type": "string" - }, - "steamid": { - "type": "string" - } - }, - "required": [ - "steamid", - "name", - "reason" - ], - "type": "object" - }, - "type": "array" - }, - "unavailable_friends_total": { - "type": "number" - } - }, - "required": [ - "found", - "total_friends", - "friends_checked", - "matches", - "private_friends", - "unavailable_friends" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "friends_checked": { + "description": "How many of `total_friends` were actually looked up. Lower than total_friends on a very large friend list, where checking every one would exceed an MCP client's request timeout — the unchecked friends are simply absent from all three lists below, so treat a gap here as 'not checked', never as 'doesn't own it'.", + "type": "number" + }, + "matches": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "owners": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": [ + "string", + "null" + ] + }, + "playtime_hours": { + "type": [ + "number", + "null" + ] + }, + "steamid": { + "type": "string" + } + }, + "required": [ + "steamid", + "name", + "playtime_hours" + ], + "type": "object" + }, + "type": "array" + }, + "owners_total": { + "type": "number" + } + }, + "required": [ + "appid", + "owners" + ], + "type": "object" + }, + "type": "array" + }, + "private_friends": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": [ + "string", + "null" + ] + }, + "steamid": { + "type": "string" + } + }, + "required": [ + "steamid", + "name" + ], + "type": "object" + }, + "type": "array" + }, + "private_friends_total": { + "type": "number" + }, + "total_friends": { + "type": "number" + }, + "unavailable_friends": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": [ + "string", + "null" + ] + }, + "reason": { + "type": "string" + }, + "steamid": { + "type": "string" + } + }, + "required": [ + "steamid", + "name", + "reason" + ], + "type": "object" + }, + "type": "array" + }, + "unavailable_friends_total": { + "type": "number" + } + }, + "required": [ + "found", + "total_friends", + "friends_checked", + "matches", + "private_friends", + "unavailable_friends" + ], + "type": "object" + } +]
- Changed
get_current_players2 fields changed- removed
Output schema / properties / player_count / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / player_count / typeAdded value: +[ + "number", + "null" +]
- Changed
get_featured26 fields changed- changed
Input schema / properties / country / descriptionPrevious 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." - changed
Input schema / properties / language / descriptionPrevious 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`." - removed
Output schema / properties / coming_soon / items / properties / final_price / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / coming_soon / items / properties / final_price / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / coming_soon / items / properties / original_price / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / coming_soon / items / properties / original_price / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / coming_soon / items / properties / store_url / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / coming_soon / items / properties / store_url / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / new_releases / items / properties / final_price / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / new_releases / items / properties / final_price / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / new_releases / items / properties / original_price / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / new_releases / items / properties / original_price / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / new_releases / items / properties / store_url / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / new_releases / items / properties / store_url / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / specials / items / properties / final_price / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / specials / items / properties / final_price / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / specials / items / properties / original_price / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / specials / items / properties / original_price / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / specials / items / properties / store_url / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / specials / items / properties / store_url / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / top_sellers / items / properties / final_price / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / top_sellers / items / properties / final_price / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / top_sellers / items / properties / original_price / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / top_sellers / items / properties / original_price / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / top_sellers / items / properties / store_url / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / top_sellers / items / properties / store_url / typeAdded value: +[ + "string", + "null" +]
- Changed
get_followed_games1 field changed- changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "games": { - "items": { - "not": {} - }, - "type": "array" - }, - "reason": { - "type": "string" - }, - "total": { - "const": 0, - "type": "number" - } - }, - "required": [ - "found", - "reason", - "total", - "games" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "games": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "store_url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "appid", - "store_url" - ], - "type": "object" - }, - "type": "array" - }, - "returned": { - "type": "number" - }, - "total": { - "type": "number" - } - }, - "required": [ - "found", - "total", - "returned", - "games" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "games": { + "items": { + "not": {} + }, + "type": "array" + }, + "reason": { + "type": "string" + }, + "total": { + "const": 0, + "type": "number" + } + }, + "required": [ + "found", + "reason", + "total", + "games" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "games": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "store_url": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "appid", + "store_url" + ], + "type": "object" + }, + "type": "array" + }, + "returned": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "found", + "total", + "returned", + "games" + ], + "type": "object" + } +]
- Changed
get_friend_list1 field changed- changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "friends": { - "items": { - "additionalProperties": false, - "properties": { - "friends_since": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "in_game": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "profile_url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "state": { - "enum": [ - "offline", - "online", - "busy", - "away", - "snooze", - "looking to trade", - "looking to play" - ], - "type": "string" - }, - "steamid": { - "type": "string" - } - }, - "required": [ - "name", - "state", - "in_game", - "profile_url", - "friends_since" - ], - "type": "object" - }, - "type": "array" - }, - "returned": { - "type": "number" - }, - "total": { - "type": "number" - } - }, - "required": [ - "found", - "total", - "returned", - "friends" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "friends": { + "items": { + "additionalProperties": false, + "properties": { + "friends_since": { + "type": [ + "string", + "null" + ] + }, + "in_game": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "profile_url": { + "type": [ + "string", + "null" + ] + }, + "state": { + "enum": [ + "offline", + "online", + "busy", + "away", + "snooze", + "looking to trade", + "looking to play" + ], + "type": "string" + }, + "steamid": { + "type": "string" + } + }, + "required": [ + "name", + "state", + "in_game", + "profile_url", + "friends_since" + ], + "type": "object" + }, + "type": "array" + }, + "returned": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "found", + "total", + "returned", + "friends" + ], + "type": "object" + } +]
- Changed
get_game38 fields changed- changed
Input schema / properties / country / descriptionPrevious 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." - changed
Input schema / properties / language / descriptionPrevious 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`." - removed
Output schema / properties / account_notice / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / account_notice / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / achievements_total / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / achievements_total / typeAdded value: +[ + "number", + "null" +] - changed
Output schema / properties / base_game / anyOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "appid", - "name" - ], - "type": "object" - }, - { - "type": "null" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "name": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "appid", + "name" + ], + "type": "object" + }, + { + "type": "null" + } +] - removed
Output schema / properties / content_descriptors / properties / notes / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / content_descriptors / properties / notes / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / controller_support / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / controller_support / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / drm_notice / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / drm_notice / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / header_image / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / header_image / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / metacritic / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / metacritic / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / metacritic_url / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / metacritic_url / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / pc_requirements_min / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / pc_requirements_min / typeAdded value: +[ + "string", + "null" +] - changed
Output schema / properties / price / anyOfPrevious value: -[ - { - "oneOf": [ - { - "additionalProperties": false, - "properties": { - "is_free": { - "const": true, - "type": "boolean" - } - }, - "required": [ - "is_free" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "currency": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "discount_percent": { - "type": "number" - }, - "final": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "initial": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "is_free": { - "const": false, - "type": "boolean" - } - }, - "required": [ - "currency", - "final", - "initial", - "discount_percent", - "is_free" - ], - "type": "object" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "is_free": { + "const": true, + "type": "boolean" + } + }, + "required": [ + "is_free" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "currency": { + "type": [ + "string", + "null" + ] + }, + "discount_percent": { + "type": "number" + }, + "final": { + "type": [ + "string", + "null" + ] + }, + "initial": { + "type": [ + "string", + "null" + ] + }, + "is_free": { + "const": false, + "type": "boolean" + } + }, + "required": [ + "currency", + "final", + "initial", + "discount_percent", + "is_free" + ], + "type": "object" + } + ] + }, + { + "type": "null" + } +] - removed
Output schema / properties / recommendations / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / recommendations / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / release_date / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / release_date / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / required_age / anyOfRemoved value: -[ - { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - } - ] - }, - { - "type": "null" - } -] - added
Output schema / properties / required_age / typeAdded value: +[ + "number", + "string", + "null" +] - removed
Output schema / properties / short_description / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / short_description / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / store_url / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / store_url / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / supported_languages / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / supported_languages / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / type / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / type / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / website / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / website / typeAdded value: +[ + "string", + "null" +]
- Changed
get_game_achievements9 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Language for achievement names/descriptions; overrides STEAM_LANGUAGE."New value: +"Language for achievement names/descriptions; overrides STEAM_LANGUAGE. 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.)" - removed
Output schema / properties / achievements / items / properties / description / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / achievements / items / properties / description / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / achievements / items / properties / global_unlock_pct / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / achievements / items / properties / global_unlock_pct / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / achievements / items / properties / name / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / achievements / items / properties / name / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / game / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / game / typeAdded value: +[ + "string", + "null" +]
- Changed
get_game_news12 fields changed- removed
Output schema / properties / items / items / properties / author / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / items / items / properties / author / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / items / items / properties / date / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / items / items / properties / date / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / items / items / properties / excerpt / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / items / items / properties / excerpt / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / items / items / properties / feed / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / items / items / properties / feed / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / items / items / properties / title / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / items / items / properties / title / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / items / items / properties / url / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / items / items / properties / url / typeAdded value: +[ + "string", + "null" +]
- Changed
get_game_reviews16 fields changed- removed
Output schema / properties / positive_pct / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / positive_pct / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / reviews / items / properties / author_playtime_hours / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / reviews / items / properties / author_playtime_hours / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / reviews / items / properties / text / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / reviews / items / properties / text / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / reviews / items / properties / voted_up / anyOfRemoved value: -[ - { - "type": "boolean" - }, - { - "type": "null" - } -] - added
Output schema / properties / reviews / items / properties / voted_up / typeAdded value: +[ + "boolean", + "null" +] - removed
Output schema / properties / summary / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / summary / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / total_negative / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / total_negative / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / total_positive / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / total_positive / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / total_reviews / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / total_reviews / typeAdded value: +[ + "number", + "null" +]
- Changed
get_global_achievements2 fields changed- removed
Output schema / properties / achievements / items / properties / percent / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / achievements / items / properties / percent / typeAdded value: +[ + "number", + "null" +]
- Changed
get_items3 fields changed- changed
Input schema / properties / country / descriptionPrevious 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." - changed
Input schema / properties / language / descriptionPrevious 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`." - changed
Output schema / properties / items / items / anyOfPrevious value: -[ - { - "additionalProperties": false, - "description": "No store data for this appid: either it doesn't exist, or it isn't sold in the requested country. Never dropped from the list, so rows line up with the given appids.", - "properties": { - "appid": { - "type": "number" - }, - "available": { - "const": false, - "type": "boolean" - } - }, - "required": [ - "appid", - "available" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "available": { - "const": true, - "type": "boolean" - }, - "coming_soon": { - "type": "boolean" - }, - "is_free": { - "type": "boolean" - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "platforms": { - "items": { - "type": "string" - }, - "type": "array" - }, - "price": { - "anyOf": [ - { - "anyOf": [ - { - "additionalProperties": false, - "properties": { - "discount_end": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "discount_pct": { - "type": "number" - }, - "final": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "original": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "discount_pct", - "discount_end", - "final", - "original" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "is_free": { - "const": true, - "type": "boolean" - } - }, - "required": [ - "is_free" - ], - "type": "object" - } - ] - }, - { - "type": "null" - } - ], - "description": "null does NOT mean free: Steam returns no price block when the game isn't sold in the requested country, isn't released yet, or has no purchase option. Check is_free and coming_soon before concluding anything, and re-check under another `country`." - }, - "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", - "available", - "is_free", - "price", - "coming_soon" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "description": "No store data for this appid: either it doesn't exist, or it isn't sold in the requested country. Never dropped from the list, so rows line up with the given appids.", + "properties": { + "appid": { + "type": "number" + }, + "available": { + "const": false, + "type": "boolean" + } + }, + "required": [ + "appid", + "available" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "available": { + "const": true, + "type": "boolean" + }, + "coming_soon": { + "type": "boolean" + }, + "is_free": { + "type": "boolean" + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "platforms": { + "items": { + "type": "string" + }, + "type": "array" + }, + "price": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "discount_end": { + "type": [ + "string", + "null" + ] + }, + "discount_pct": { + "type": "number" + }, + "final": { + "type": [ + "string", + "null" + ] + }, + "original": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "discount_pct", + "discount_end", + "final", + "original" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "is_free": { + "const": true, + "type": "boolean" + } + }, + "required": [ + "is_free" + ], + "type": "object" + } + ] + }, + { + "type": "null" + } + ], + "description": "null does NOT mean free: Steam returns no price block when the game isn't sold in the requested country, isn't released yet, or has no purchase option. Check is_free and coming_soon before concluding anything, and re-check under another `country`." + }, + "release_date": { + "type": [ + "string", + "null" + ] + }, + "review_count": { + "type": [ + "number", + "null" + ] + }, + "review_label": { + "type": [ + "string", + "null" + ] + }, + "review_percent": { + "type": [ + "number", + "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": { + "type": [ + "string", + "null" + ] + }, + "tags": { + "description": "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.", + "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", + "available", + "is_free", + "price", + "coming_soon" + ], + "type": "object" + } +]
- Changed
get_owned_games4 fields changed- changed
Input schema / properties / check_appids / descriptionPrevious value: -"Steam appids to check ownership of (1-50), regardless of the top-50-by-playtime cap on `games`. Adds an `owns` field: [{appid, owned, playtime_hours}]. One upstream gap to know about: Steam omits free-to-play titles the player owns but has NEVER launched, so those report owned:false. A private profile reports no `owns` at all (ownership unknown) rather than a false owned:false."New value: +"Steam appids to check ownership of (1-50), regardless of the 50-entry cap on `games` (or of whichever end `sort` keeps). Prefer this over raising `limit`: it reads the FULL library, and its own cost is bounded by this list's length. Adds an `owns` field: [{appid, owned, playtime_hours}]. One upstream gap to know about: Steam omits free-to-play titles the player owns but has NEVER launched, so those report owned:false — as does an appid that doesn't exist, so this field can't tell 'no such game' from 'doesn't own it'. A private profile reports no `owns` at all (ownership unknown) rather than a false owned:false." - added
Input schema / properties / limitAdded value: +{ + "description": "How many games to return (1-300, default 50). Raise it only when a wider slice of the library is genuinely needed — the ceiling is a response-size budget, so even a 4000-game account never comes back whole. To check specific appids past the cap, use check_appids rather than a bigger limit.", + "exclusiveMinimum": 0, + "maximum": 300, + "type": "integer" +} - added
Input schema / properties / sortAdded value: +{ + "description": "Which end of the library the cap keeps: 'playtime_desc' (default) the most-played, 'playtime_asc' the least-played and never-played first.", + "enum": [ + "playtime_desc", + "playtime_asc" + ], + "type": "string" +} - changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "game_count": { - "type": "null" - }, - "games": { - "items": { - "not": {} - }, - "type": "array" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason", - "game_count", - "games" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "game_count": { - "type": "number" - }, - "games": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "playtime_2weeks_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "playtime_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "name", - "playtime_hours", - "playtime_2weeks_hours" - ], - "type": "object" - }, - "type": "array" - }, - "owns": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "owned": { - "type": "boolean" - }, - "playtime_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "appid", - "owned", - "playtime_hours" - ], - "type": "object" - }, - "type": "array" - }, - "returned": { - "type": "number" - } - }, - "required": [ - "found", - "game_count", - "returned", - "games" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "game_count": { + "type": "null" + }, + "games": { + "items": { + "not": {} + }, + "type": "array" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason", + "game_count", + "games" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "game_count": { + "type": "number" + }, + "games": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "playtime_2weeks_hours": { + "type": [ + "number", + "null" + ] + }, + "playtime_hours": { + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "name", + "playtime_hours", + "playtime_2weeks_hours" + ], + "type": "object" + }, + "type": "array" + }, + "owns": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "owned": { + "type": "boolean" + }, + "playtime_hours": { + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "appid", + "owned", + "playtime_hours" + ], + "type": "object" + }, + "type": "array" + }, + "returned": { + "type": "number" + } + }, + "required": [ + "found", + "game_count", + "returned", + "games" + ], + "type": "object" + } +]
- Changed
get_player_achievements2 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Language for achievement names/descriptions; overrides STEAM_LANGUAGE."New value: +"Language for achievement names/descriptions; overrides STEAM_LANGUAGE. 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.)" - changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "achievements": { - "items": { - "additionalProperties": false, - "properties": { - "achieved": { - "type": "boolean" - }, - "name": { - "description": "Display name, falling back to the achievement's internal api name when Valve's schema has no localized title for it.", - "type": "string" - }, - "unlocked_at": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "achieved", - "unlocked_at" - ], - "type": "object" - }, - "type": "array" - }, - "completion_pct": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "found": { - "const": true, - "type": "boolean" - }, - "game": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "The game's name from Valve's achievement schema — occasionally an internal dev codename rather than the store title (e.g. 'Fiber' for Persona 5 Royal). Treat the appid you passed as the reliable identifier, or get the store title from get_game." - }, - "returned": { - "type": "number" - }, - "total": { - "type": "number" - }, - "unlocked": { - "type": "number" - } - }, - "required": [ - "found", - "game", - "total", - "unlocked", - "completion_pct", - "returned", - "achievements" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "achievements": { + "items": { + "additionalProperties": false, + "properties": { + "achieved": { + "type": "boolean" + }, + "name": { + "description": "Display name, falling back to the achievement's internal api name when Valve's schema has no localized title for it.", + "type": "string" + }, + "unlocked_at": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "achieved", + "unlocked_at" + ], + "type": "object" + }, + "type": "array" + }, + "completion_pct": { + "type": [ + "number", + "null" + ] + }, + "found": { + "const": true, + "type": "boolean" + }, + "game": { + "description": "The game's name from Valve's achievement schema — occasionally an internal dev codename rather than the store title (e.g. 'Fiber' for Persona 5 Royal). Treat the appid you passed as the reliable identifier, or get the store title from get_game.", + "type": [ + "string", + "null" + ] + }, + "returned": { + "type": "number" + }, + "total": { + "type": "number" + }, + "unlocked": { + "type": "number" + } + }, + "required": [ + "found", + "game", + "total", + "unlocked", + "completion_pct", + "returned", + "achievements" + ], + "type": "object" + } +]
- Changed
get_player_bans1 field changed- changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "community_banned": { - "type": "boolean" - }, - "days_since_last_ban": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "economy_ban": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "found": { - "const": true, - "type": "boolean" - }, - "game_ban_count": { - "type": "number" - }, - "steamid": { - "type": "string" - }, - "vac_ban_count": { - "type": "number" - }, - "vac_banned": { - "type": "boolean" - } - }, - "required": [ - "found", - "vac_banned", - "vac_ban_count", - "game_ban_count", - "community_banned", - "economy_ban", - "days_since_last_ban" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "community_banned": { + "type": "boolean" + }, + "days_since_last_ban": { + "type": [ + "number", + "null" + ] + }, + "economy_ban": { + "type": [ + "string", + "null" + ] + }, + "found": { + "const": true, + "type": "boolean" + }, + "game_ban_count": { + "type": "number" + }, + "steamid": { + "type": "string" + }, + "vac_ban_count": { + "type": "number" + }, + "vac_banned": { + "type": "boolean" + } + }, + "required": [ + "found", + "vac_banned", + "vac_ban_count", + "game_ban_count", + "community_banned", + "economy_ban", + "days_since_last_ban" + ], + "type": "object" + } +]
- Changed
get_player_summary1 field changed- changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "avatar": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "country": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "created": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "found": { - "const": true, - "type": "boolean" - }, - "in_game": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "level": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "profile_url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "real_name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "state": { - "enum": [ - "offline", - "online", - "busy", - "away", - "snooze", - "looking to trade", - "looking to play" - ], - "type": "string" - }, - "steamid": { - "type": "string" - }, - "visibility": { - "enum": [ - "public", - "private" - ], - "type": "string" - } - }, - "required": [ - "found", - "name", - "real_name", - "state", - "visibility", - "country", - "level", - "created", - "in_game", - "profile_url", - "avatar" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "avatar": { + "type": [ + "string", + "null" + ] + }, + "country": { + "type": [ + "string", + "null" + ] + }, + "created": { + "type": [ + "string", + "null" + ] + }, + "found": { + "const": true, + "type": "boolean" + }, + "in_game": { + "type": [ + "string", + "null" + ] + }, + "level": { + "type": [ + "number", + "null" + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "profile_url": { + "type": [ + "string", + "null" + ] + }, + "real_name": { + "type": [ + "string", + "null" + ] + }, + "state": { + "enum": [ + "offline", + "online", + "busy", + "away", + "snooze", + "looking to trade", + "looking to play" + ], + "type": "string" + }, + "steamid": { + "type": "string" + }, + "visibility": { + "enum": [ + "public", + "private" + ], + "type": "string" + } + }, + "required": [ + "found", + "name", + "real_name", + "state", + "visibility", + "country", + "level", + "created", + "in_game", + "profile_url", + "avatar" + ], + "type": "object" + } +]
- Changed
get_prices2 fields changed- changed
Input schema / properties / country / descriptionPrevious 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." - changed
Output schema / properties / prices / items / anyOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "available": { - "const": false, - "type": "boolean" - } - }, - "required": [ - "appid", - "available" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "available": { - "const": true, - "type": "boolean" - }, - "is_free": { - "const": true, - "type": "boolean" - } - }, - "required": [ - "appid", - "available", - "is_free" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "available": { - "const": true, - "type": "boolean" - }, - "currency": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "discount_percent": { - "type": "number" - }, - "final": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "initial": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "is_free": { - "const": false, - "type": "boolean" - } - }, - "required": [ - "currency", - "final", - "initial", - "discount_percent", - "appid", - "available", - "is_free" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "description": "No usable store entry came back for this appid: it doesn't exist, it isn't sold in the requested country (try another `country`), or the batch chunk it fell in failed transiently — this tool chunks large lists, so a retry can turn these rows into prices. Same row shape as get_items' available:false.", + "properties": { + "appid": { + "type": "number" + }, + "available": { + "const": false, + "type": "boolean" + } + }, + "required": [ + "appid", + "available" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Steam returned no price block for this appid. That is how a free-to-play title AND a not-yet-released or not-purchasable one both come back, and this endpoint cannot tell them apart — so this is NOT a claim that the game is free. Call get_items on the appid (its `is_free` and `coming_soon` separate the two) before reporting anything as free.", + "properties": { + "appid": { + "type": "number" + }, + "available": { + "const": true, + "type": "boolean" + }, + "priced": { + "const": false, + "type": "boolean" + } + }, + "required": [ + "appid", + "available", + "priced" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "available": { + "const": true, + "type": "boolean" + }, + "currency": { + "type": [ + "string", + "null" + ] + }, + "discount_percent": { + "type": "number" + }, + "final": { + "type": [ + "string", + "null" + ] + }, + "initial": { + "type": [ + "string", + "null" + ] + }, + "is_free": { + "const": false, + "type": "boolean" + } + }, + "required": [ + "currency", + "final", + "initial", + "discount_percent", + "appid", + "available", + "is_free" + ], + "type": "object" + } +]
- Changed
get_recently_played1 field changed- changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "games": { - "items": { - "not": {} - }, - "type": "array" - }, - "reason": { - "type": "string" - }, - "total": { - "const": 0, - "type": "number" - } - }, - "required": [ - "found", - "reason", - "total", - "games" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "games": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "playtime_2weeks_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "playtime_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "name", - "playtime_hours", - "playtime_2weeks_hours" - ], - "type": "object" - }, - "type": "array" - }, - "returned": { - "type": "number" - }, - "total": { - "type": "number" - } - }, - "required": [ - "found", - "total", - "returned", - "games" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "games": { + "items": { + "not": {} + }, + "type": "array" + }, + "reason": { + "type": "string" + }, + "total": { + "const": 0, + "type": "number" + } + }, + "required": [ + "found", + "reason", + "total", + "games" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "games": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "playtime_2weeks_hours": { + "type": [ + "number", + "null" + ] + }, + "playtime_hours": { + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "name", + "playtime_hours", + "playtime_2weeks_hours" + ], + "type": "object" + }, + "type": "array" + }, + "returned": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "found", + "total", + "returned", + "games" + ], + "type": "object" + } +]
- Changed
get_recommended_games1 field changed- changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "based_on_tags": { - "items": { - "type": "string" - }, - "type": "array" - }, - "count": { - "type": "number" - }, - "found": { - "const": true, - "type": "boolean" - }, - "recommendations": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "discount_end": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "discount_pct": { - "type": "number" - }, - "match_score": { - "description": "An internal ranking weight (playtime-on-matched-tags, discounted by review score) — not a percentage or 0-100 scale. Only meaningful relative to the other scores in this same response, to explain why one pick outranks another.", - "type": "number" - }, - "matched_tags": { - "items": { - "type": "string" - }, - "type": "array" - }, - "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", - "matched_tags", - "match_score" - ], - "type": "object" - }, - "type": "array" - } - }, - "required": [ - "found", - "based_on_tags", - "count", - "recommendations" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "based_on_tags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "count": { + "type": "number" + }, + "found": { + "const": true, + "type": "boolean" + }, + "recommendations": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "discount_end": { + "type": [ + "string", + "null" + ] + }, + "discount_pct": { + "type": "number" + }, + "match_score": { + "description": "An internal ranking weight (playtime-on-matched-tags, discounted by review score) — not a percentage or 0-100 scale. Only meaningful relative to the other scores in this same response, to explain why one pick outranks another.", + "type": "number" + }, + "matched_tags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "original": { + "type": [ + "string", + "null" + ] + }, + "platforms": { + "items": { + "type": "string" + }, + "type": "array" + }, + "price": { + "type": [ + "string", + "null" + ] + }, + "release_date": { + "type": [ + "string", + "null" + ] + }, + "review_count": { + "type": [ + "number", + "null" + ] + }, + "review_label": { + "type": [ + "string", + "null" + ] + }, + "review_percent": { + "type": [ + "number", + "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": { + "type": [ + "string", + "null" + ] + }, + "tags": { + "description": "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.", + "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", + "matched_tags", + "match_score" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "found", + "based_on_tags", + "count", + "recommendations" + ], + "type": "object" + } +]
- Changed
get_review_histogram10 fields changed- removed
Output schema / properties / history / items / properties / date / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / history / items / properties / date / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / history / items / properties / positive_pct / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / history / items / properties / positive_pct / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / recent / items / properties / date / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / recent / items / properties / date / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / recent / items / properties / positive_pct / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / recent / items / properties / positive_pct / typeAdded value: +[ + "number", + "null" +] - removed
Output schema / properties / rollup_type / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / rollup_type / typeAdded value: +[ + "string", + "null" +]
- Changed
get_specials8 fields changed- changed
Input schema / properties / country / descriptionPrevious 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." - changed
Input schema / properties / language / descriptionPrevious 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`." - removed
Output schema / properties / specials / items / properties / final_price / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / specials / items / properties / final_price / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / specials / items / properties / original_price / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / specials / items / properties / original_price / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / specials / items / properties / store_url / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / specials / items / properties / store_url / typeAdded value: +[ + "string", + "null" +]
- Changed
get_wishlist3 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"Country (cc) for prices; overrides STEAM_COUNTRY. Implies include_details."New value: +"Country (cc) for prices; overrides STEAM_COUNTRY. Implies include_details. 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." - changed
Input schema / properties / language / descriptionPrevious value: -"Store language; overrides STEAM_LANGUAGE. Implies include_details."New value: +"Store language; overrides STEAM_LANGUAGE. Implies include_details. 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.)" - changed
Output schema / anyOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "items": { - "items": { - "not": {} - }, - "type": "array" - }, - "reason": { - "type": "string" - }, - "total": { - "const": 0, - "type": "number" - } - }, - "required": [ - "found", - "reason", - "total", - "items" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "items": { - "items": { - "additionalProperties": false, - "properties": { - "added": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "appid": { - "type": "number" - }, - "priority": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "store_url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "store_url", - "priority", - "added" - ], - "type": "object" - }, - "type": "array" - }, - "returned": { - "type": "number" - }, - "total": { - "type": "number" - } - }, - "required": [ - "found", - "total", - "returned", - "items" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "enriched": { - "description": "How many of `total` Steam actually attached store data to (it caps around the first 100) — every filter below only runs over these, never the full `total`.", - "type": "number" - }, - "found": { - "const": true, - "type": "boolean" - }, - "items": { - "items": { - "additionalProperties": false, - "properties": { - "added": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "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" - } - ] - }, - "priority": { - "anyOf": [ - { - "type": "number" - }, - { - "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", - "priority", - "added" - ], - "type": "object" - }, - "type": "array" - }, - "matched": { - "description": "How many of the enriched items satisfied the filters, BEFORE the display cap — a big gap between this and `returned` means results were capped, not that fewer items matched.", - "type": "number" - }, - "note": { - "type": "string" - }, - "returned": { - "description": "How many items are actually in `items` below, after the display cap.", - "type": "number" - }, - "total": { - "description": "The player's full wishlist size, including entries Steam never sent store data for (see `enriched`).", - "type": "number" - } - }, - "required": [ - "found", - "total", - "enriched", - "matched", - "returned", - "items" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "items": { + "items": { + "not": {} + }, + "type": "array" + }, + "reason": { + "type": "string" + }, + "total": { + "const": 0, + "type": "number" + } + }, + "required": [ + "found", + "reason", + "total", + "items" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "items": { + "items": { + "additionalProperties": false, + "properties": { + "added": { + "type": [ + "string", + "null" + ] + }, + "appid": { + "type": "number" + }, + "priority": { + "type": [ + "number", + "null" + ] + }, + "store_url": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "store_url", + "priority", + "added" + ], + "type": "object" + }, + "type": "array" + }, + "returned": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "found", + "total", + "returned", + "items" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "enriched": { + "description": "How many of `total` Steam actually attached store data to (it caps around the first 100) — every filter below only runs over these, never the full `total`.", + "type": "number" + }, + "found": { + "const": true, + "type": "boolean" + }, + "items": { + "items": { + "additionalProperties": false, + "properties": { + "added": { + "type": [ + "string", + "null" + ] + }, + "appid": { + "type": "number" + }, + "discount_end": { + "type": [ + "string", + "null" + ] + }, + "discount_pct": { + "type": "number" + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "original": { + "type": [ + "string", + "null" + ] + }, + "platforms": { + "items": { + "type": "string" + }, + "type": "array" + }, + "price": { + "type": [ + "string", + "null" + ] + }, + "priority": { + "type": [ + "number", + "null" + ] + }, + "release_date": { + "type": [ + "string", + "null" + ] + }, + "review_count": { + "type": [ + "number", + "null" + ] + }, + "review_label": { + "type": [ + "string", + "null" + ] + }, + "review_percent": { + "type": [ + "number", + "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": { + "type": [ + "string", + "null" + ] + }, + "tags": { + "description": "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.", + "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", + "priority", + "added" + ], + "type": "object" + }, + "type": "array" + }, + "matched": { + "description": "How many of the enriched items satisfied the filters, BEFORE the display cap — a big gap between this and `returned` means results were capped, not that fewer items matched.", + "type": "number" + }, + "note": { + "type": "string" + }, + "returned": { + "description": "How many items are actually in `items` below, after the display cap.", + "type": "number" + }, + "total": { + "description": "The player's full wishlist size, including entries Steam never sent store data for (see `enriched`).", + "type": "number" + } + }, + "required": [ + "found", + "total", + "enriched", + "matched", + "returned", + "items" + ], + "type": "object" + } +]
- Changed
search_games9 fields changed- changed
Input schema / properties / country / descriptionPrevious 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." - changed
Input schema / properties / language / descriptionPrevious 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`." - removed
Output schema / properties / results / items / properties / metascore / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / results / items / properties / metascore / typeAdded value: +[ + "string", + "null" +] - changed
Output schema / properties / results / items / properties / price / anyOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "currency": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "discount_percent": { - "type": "number" - }, - "final": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "initial": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "currency", - "final", - "initial", - "discount_percent" - ], - "type": "object" - }, - { - "type": "null" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "currency": { + "type": [ + "string", + "null" + ] + }, + "discount_percent": { + "type": "number" + }, + "final": { + "type": [ + "string", + "null" + ] + }, + "initial": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "currency", + "final", + "initial", + "discount_percent" + ], + "type": "object" + }, + { + "type": "null" + } +] - removed
Output schema / properties / results / items / properties / store_url / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / results / items / properties / store_url / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / results / items / properties / type / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / results / items / properties / type / typeAdded value: +[ + "string", + "null" +]
17 tool updates
v0.13.1- Changed
compare_players1 field changed- changed
Input schema / properties / other_steamid / descriptionPrevious value: -"The other player's 17-digit SteamID64 to compare against."New value: +"The other player's 17-digit SteamID64 to compare against. Convert a vanity/custom profile name with resolve_vanity_url first."
- Changed
discover_games4 fields changed- changed
Input schema / properties / count / descriptionPrevious 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`.)" - added
Output schema / properties / matchedAdded value: +{ + "description": "How many results survived every filter, out of the scanned window (see `count`).", + "type": "number" +} - changed
Output schema / properties / returned / descriptionPrevious 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." - changed
Output schema / requiredPrevious value: -[ - "total_matching", - "returned", - "deals" -]New value: +[ + "total_matching", + "matched", + "returned", + "deals" +]
- Changed
find_friends_who_own1 field changed- changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "matches": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "owners": { - "items": { - "additionalProperties": false, - "properties": { - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "playtime_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "steamid": { - "type": "string" - } - }, - "required": [ - "steamid", - "name", - "playtime_hours" - ], - "type": "object" - }, - "type": "array" - }, - "owners_total": { - "type": "number" - } - }, - "required": [ - "appid", - "owners" - ], - "type": "object" - }, - "type": "array" - }, - "private_friends": { - "items": { - "additionalProperties": false, - "properties": { - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "steamid": { - "type": "string" - } - }, - "required": [ - "steamid", - "name" - ], - "type": "object" - }, - "type": "array" - }, - "private_friends_total": { - "type": "number" - }, - "total_friends": { - "type": "number" - }, - "unavailable_friends": { - "items": { - "additionalProperties": false, - "properties": { - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "reason": { - "type": "string" - }, - "steamid": { - "type": "string" - } - }, - "required": [ - "steamid", - "name", - "reason" - ], - "type": "object" - }, - "type": "array" - }, - "unavailable_friends_total": { - "type": "number" - } - }, - "required": [ - "found", - "total_friends", - "matches", - "private_friends", - "unavailable_friends" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "friends_checked": { + "description": "How many of `total_friends` were actually looked up. Lower than total_friends on a very large friend list, where checking every one would exceed an MCP client's request timeout — the unchecked friends are simply absent from all three lists below, so treat a gap here as 'not checked', never as 'doesn't own it'.", + "type": "number" + }, + "matches": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "owners": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "playtime_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "steamid": { + "type": "string" + } + }, + "required": [ + "steamid", + "name", + "playtime_hours" + ], + "type": "object" + }, + "type": "array" + }, + "owners_total": { + "type": "number" + } + }, + "required": [ + "appid", + "owners" + ], + "type": "object" + }, + "type": "array" + }, + "private_friends": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "steamid": { + "type": "string" + } + }, + "required": [ + "steamid", + "name" + ], + "type": "object" + }, + "type": "array" + }, + "private_friends_total": { + "type": "number" + }, + "total_friends": { + "type": "number" + }, + "unavailable_friends": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "reason": { + "type": "string" + }, + "steamid": { + "type": "string" + } + }, + "required": [ + "steamid", + "name", + "reason" + ], + "type": "object" + }, + "type": "array" + }, + "unavailable_friends_total": { + "type": "number" + } + }, + "required": [ + "found", + "total_friends", + "friends_checked", + "matches", + "private_friends", + "unavailable_friends" + ], + "type": "object" + } +]
- Changed
get_featured4 fields changed- added
Output schema / properties / coming_soon / items / properties / final_price / descriptionAdded value: +"Current price, or null when this section's payload carries no price — which is every `coming_soon` entry (not yet priced, NOT free) and any free-to-play title. Call get_game or get_items on the appid when you need to tell those two apart." - added
Output schema / properties / new_releases / items / properties / final_price / descriptionAdded value: +"Current price, or null when this section's payload carries no price — which is every `coming_soon` entry (not yet priced, NOT free) and any free-to-play title. Call get_game or get_items on the appid when you need to tell those two apart." - added
Output schema / properties / specials / items / properties / final_price / descriptionAdded value: +"Current price, or null when this section's payload carries no price — which is every `coming_soon` entry (not yet priced, NOT free) and any free-to-play title. Call get_game or get_items on the appid when you need to tell those two apart." - added
Output schema / properties / top_sellers / items / properties / final_price / descriptionAdded value: +"Current price, or null when this section's payload carries no price — which is every `coming_soon` entry (not yet priced, NOT free) and any free-to-play title. Call get_game or get_items on the appid when you need to tell those two apart."
- Changed
get_game3 fields changed- added
Output schema / properties / dlc / descriptionAdded value: +"Appids of this game's DLC, capped — a DLC-heavy game can list hundreds, which would dwarf every other field. Compare against dlc_total, and pass the appids to get_items for their names and prices." - added
Output schema / properties / dlc_totalAdded value: +{ + "description": "How many DLC this game has in total, before the `dlc` cap.", + "type": "number" +} - changed
Output schema / requiredPrevious value: -[ - "type", - "short_description", - "is_free", - "price", - "release_date", - "coming_soon", - "developers", - "publishers", - "genres", - "categories", - "platforms", - "metacritic", - "metacritic_url", - "recommendations", - "required_age", - "controller_support", - "achievements_total", - "achievements_highlighted", - "supported_languages", - "dlc", - "demos", - "content_descriptors", - "base_game", - "drm_notice", - "account_notice", - "pc_requirements_min", - "website", - "header_image", - "store_url" -]New value: +[ + "type", + "short_description", + "is_free", + "price", + "release_date", + "coming_soon", + "developers", + "publishers", + "genres", + "categories", + "platforms", + "metacritic", + "metacritic_url", + "recommendations", + "required_age", + "controller_support", + "achievements_total", + "achievements_highlighted", + "supported_languages", + "dlc", + "dlc_total", + "demos", + "content_descriptors", + "base_game", + "drm_notice", + "account_notice", + "pc_requirements_min", + "website", + "header_image", + "store_url" +]
- Changed
get_game_achievements1 field changed- added
Output schema / properties / game / descriptionAdded value: +"The game's name from Valve's achievement schema — occasionally an internal dev codename rather than the store title (e.g. 'Fiber' for Persona 5 Royal). Treat the appid you passed as the reliable identifier, or get the store title from get_game."
- Changed
get_game_reviews2 fields changed- changed
Input schema / properties / review_language / descriptionPrevious value: -"Filter reviews by language, e.g. 'english'. Default 'all'."New value: +"Filter reviews by language. Use Steam's full language name — english, russian, schinese — NOT an ISO code like en/ru/zh: Steam answers an unrecognized value with zero reviews rather than an error, so a 9M-review game reads as having none. Default 'all'. Setting this ALSO rescopes the summary counts (total_reviews / positive / negative / %) to that language — they are no longer the game's global totals. Leave it at 'all' when you want those." - added
Input schema / properties / review_language / minLengthAdded value: +1
- Changed
get_items3 fields changed- changed
Input schema / properties / appids / descriptionPrevious value: -"Steam appids (1-100)."New value: +"Steam appids (1-50). Split a longer list across calls." - changed
Input schema / properties / appids / maxItemsPrevious value: -100New value: +50 - changed
Output schema / properties / items / items / anyOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "available": { - "const": false, - "type": "boolean" - } - }, - "required": [ - "appid", - "available" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "coming_soon": { - "type": "boolean" - }, - "is_free": { - "type": "boolean" - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "platforms": { - "items": { - "type": "string" - }, - "type": "array" - }, - "price": { - "anyOf": [ - { - "anyOf": [ - { - "additionalProperties": false, - "properties": { - "discount_end": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "discount_pct": { - "type": "number" - }, - "final": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "original": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "discount_pct", - "discount_end", - "final", - "original" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "is_free": { - "const": true, - "type": "boolean" - } - }, - "required": [ - "is_free" - ], - "type": "object" - } - ] - }, - { - "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", - "is_free", - "price", - "coming_soon" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "description": "No store data for this appid: either it doesn't exist, or it isn't sold in the requested country. Never dropped from the list, so rows line up with the given appids.", + "properties": { + "appid": { + "type": "number" + }, + "available": { + "const": false, + "type": "boolean" + } + }, + "required": [ + "appid", + "available" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "available": { + "const": true, + "type": "boolean" + }, + "coming_soon": { + "type": "boolean" + }, + "is_free": { + "type": "boolean" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "platforms": { + "items": { + "type": "string" + }, + "type": "array" + }, + "price": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "discount_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "discount_pct": { + "type": "number" + }, + "final": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "original": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "discount_pct", + "discount_end", + "final", + "original" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "is_free": { + "const": true, + "type": "boolean" + } + }, + "required": [ + "is_free" + ], + "type": "object" + } + ] + }, + { + "type": "null" + } + ], + "description": "null does NOT mean free: Steam returns no price block when the game isn't sold in the requested country, isn't released yet, or has no purchase option. Check is_free and coming_soon before concluding anything, and re-check under another `country`." + }, + "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", + "available", + "is_free", + "price", + "coming_soon" + ], + "type": "object" + } +]
- Changed
get_owned_games2 fields changed- changed
Input schema / properties / check_appids / descriptionPrevious value: -"Steam appids to reliably check ownership of (1-50), regardless of the top-50-by-playtime cap on `games`. Adds an `owns` field: [{appid, owned, playtime_hours}]."New value: +"Steam appids to check ownership of (1-50), regardless of the top-50-by-playtime cap on `games`. Adds an `owns` field: [{appid, owned, playtime_hours}]. One upstream gap to know about: Steam omits free-to-play titles the player owns but has NEVER launched, so those report owned:false. A private profile reports no `owns` at all (ownership unknown) rather than a false owned:false." - changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "game_count": { - "type": "null" - }, - "games": { - "items": { - "not": {} - }, - "type": "array" - }, - "owns": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "owned": { - "const": false, - "type": "boolean" - } - }, - "required": [ - "appid", - "owned" - ], - "type": "object" - }, - "type": "array" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason", - "game_count", - "games" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "game_count": { - "type": "number" - }, - "games": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "playtime_2weeks_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "playtime_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "name", - "playtime_hours", - "playtime_2weeks_hours" - ], - "type": "object" - }, - "type": "array" - }, - "owns": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "owned": { - "type": "boolean" - }, - "playtime_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "appid", - "owned", - "playtime_hours" - ], - "type": "object" - }, - "type": "array" - }, - "returned": { - "type": "number" - } - }, - "required": [ - "found", - "game_count", - "returned", - "games" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "game_count": { + "type": "null" + }, + "games": { + "items": { + "not": {} + }, + "type": "array" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason", + "game_count", + "games" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "game_count": { + "type": "number" + }, + "games": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "playtime_2weeks_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "playtime_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "name", + "playtime_hours", + "playtime_2weeks_hours" + ], + "type": "object" + }, + "type": "array" + }, + "owns": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "owned": { + "type": "boolean" + }, + "playtime_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "appid", + "owned", + "playtime_hours" + ], + "type": "object" + }, + "type": "array" + }, + "returned": { + "type": "number" + } + }, + "required": [ + "found", + "game_count", + "returned", + "games" + ], + "type": "object" + } +]
- Changed
get_player_achievements1 field changed- changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "achievements": { - "items": { - "additionalProperties": false, - "properties": { - "achieved": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "unlocked_at": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "achieved", - "unlocked_at" - ], - "type": "object" - }, - "type": "array" - }, - "completion_pct": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "found": { - "const": true, - "type": "boolean" - }, - "game": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "returned": { - "type": "number" - }, - "total": { - "type": "number" - }, - "unlocked": { - "type": "number" - } - }, - "required": [ - "found", - "game", - "total", - "unlocked", - "completion_pct", - "returned", - "achievements" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "achievements": { + "items": { + "additionalProperties": false, + "properties": { + "achieved": { + "type": "boolean" + }, + "name": { + "description": "Display name, falling back to the achievement's internal api name when Valve's schema has no localized title for it.", + "type": "string" + }, + "unlocked_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "achieved", + "unlocked_at" + ], + "type": "object" + }, + "type": "array" + }, + "completion_pct": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "found": { + "const": true, + "type": "boolean" + }, + "game": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The game's name from Valve's achievement schema — occasionally an internal dev codename rather than the store title (e.g. 'Fiber' for Persona 5 Royal). Treat the appid you passed as the reliable identifier, or get the store title from get_game." + }, + "returned": { + "type": "number" + }, + "total": { + "type": "number" + }, + "unlocked": { + "type": "number" + } + }, + "required": [ + "found", + "game", + "total", + "unlocked", + "completion_pct", + "returned", + "achievements" + ], + "type": "object" + } +]
- Changed
get_player_bans1 field changed- changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - } - }, - "required": [ - "found" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "community_banned": { - "type": "boolean" - }, - "days_since_last_ban": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "economy_ban": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "found": { - "const": true, - "type": "boolean" - }, - "game_ban_count": { - "type": "number" - }, - "steamid": { - "type": "string" - }, - "vac_ban_count": { - "type": "number" - }, - "vac_banned": { - "type": "boolean" - } - }, - "required": [ - "found", - "vac_banned", - "vac_ban_count", - "game_ban_count", - "community_banned", - "economy_ban", - "days_since_last_ban" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "community_banned": { + "type": "boolean" + }, + "days_since_last_ban": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "economy_ban": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "found": { + "const": true, + "type": "boolean" + }, + "game_ban_count": { + "type": "number" + }, + "steamid": { + "type": "string" + }, + "vac_ban_count": { + "type": "number" + }, + "vac_banned": { + "type": "boolean" + } + }, + "required": [ + "found", + "vac_banned", + "vac_ban_count", + "game_ban_count", + "community_banned", + "economy_ban", + "days_since_last_ban" + ], + "type": "object" + } +]
- Changed
get_player_summary1 field changed- changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - } - }, - "required": [ - "found" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "avatar": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "country": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "created": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "found": { - "const": true, - "type": "boolean" - }, - "in_game": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "level": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "profile_url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "real_name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "state": { - "enum": [ - "offline", - "online", - "busy", - "away", - "snooze", - "looking to trade", - "looking to play" - ], - "type": "string" - }, - "steamid": { - "type": "string" - }, - "visibility": { - "enum": [ - "public", - "private" - ], - "type": "string" - } - }, - "required": [ - "found", - "name", - "real_name", - "state", - "visibility", - "country", - "level", - "created", - "in_game", - "profile_url", - "avatar" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "avatar": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "country": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "created": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "found": { + "const": true, + "type": "boolean" + }, + "in_game": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "level": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "profile_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "real_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "state": { + "enum": [ + "offline", + "online", + "busy", + "away", + "snooze", + "looking to trade", + "looking to play" + ], + "type": "string" + }, + "steamid": { + "type": "string" + }, + "visibility": { + "enum": [ + "public", + "private" + ], + "type": "string" + } + }, + "required": [ + "found", + "name", + "real_name", + "state", + "visibility", + "country", + "level", + "created", + "in_game", + "profile_url", + "avatar" + ], + "type": "object" + } +]
- Changed
get_prices2 fields changed- changed
Input schema / properties / appids / descriptionPrevious value: -"Steam appids to price (1-500)."New value: +"Steam appids to price (1-250). Split a longer list across calls." - changed
Input schema / properties / appids / maxItemsPrevious value: -500New value: +250
- Changed
get_recently_played1 field changed- changed
Output schema / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "games": { - "items": { - "not": {} - }, - "type": "array" - }, - "reason": { - "type": "string" - }, - "total": { - "const": 0, - "type": "number" - } - }, - "required": [ - "found", - "reason", - "total", - "games" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "games": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "playtime_2weeks_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "playtime_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "name", - "playtime_hours", - "playtime_2weeks_hours" - ], - "type": "object" - }, - "type": "array" - }, - "total": { - "type": "number" - } - }, - "required": [ - "found", - "total", - "games" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "games": { + "items": { + "not": {} + }, + "type": "array" + }, + "reason": { + "type": "string" + }, + "total": { + "const": 0, + "type": "number" + } + }, + "required": [ + "found", + "reason", + "total", + "games" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "games": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "playtime_2weeks_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "playtime_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "name", + "playtime_hours", + "playtime_2weeks_hours" + ], + "type": "object" + }, + "type": "array" + }, + "returned": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "found", + "total", + "returned", + "games" + ], + "type": "object" + } +]
- Changed
get_recommended_games3 fields changed- removed
Input schema / properties / countRemoved value: -{ - "default": 10, - "description": "How many recommendations to return (1-25). Default 10.", - "exclusiveMinimum": 0, - "maximum": 25, - "type": "integer" -} - added
Input schema / properties / limitAdded value: +{ + "default": 10, + "description": "How many recommendations to return (1-25). Default 10.", + "exclusiveMinimum": 0, + "maximum": 25, + "type": "integer" +} - changed
Input schema / properties / min_discount / descriptionPrevious value: -"Minimum discount %, e.g. 30 for '30%+ off'. Omit to include full-price games too."New value: +"Minimum discount %, e.g. 30 for '30%+ off'. Omit to include full-price games too. Filtered server-side and re-checked client-side, so it holds at any value including 100."
- Changed
get_specials1 field changed- added
Output schema / properties / specials / items / properties / final_price / descriptionAdded value: +"Current price, or null when this section's payload carries no price — which is every `coming_soon` entry (not yet priced, NOT free) and any free-to-play title. Call get_game or get_items on the appid when you need to tell those two apart."
- Changed
get_wishlist2 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"Country (cc) for prices; overrides STEAM_COUNTRY. Only meaningful for store cards, so setting it implies include_details — the light appid list carries no price."New value: +"Country (cc) for prices; overrides STEAM_COUNTRY. Implies include_details." - changed
Input schema / properties / language / descriptionPrevious value: -"Store language; overrides STEAM_LANGUAGE. Only meaningful for store cards, so setting it implies include_details — the light appid list carries no price."New value: +"Store language; overrides STEAM_LANGUAGE. Implies include_details."
25 tool updates
v0.12.1- Changed
compare_players3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Output schema / anyOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "games": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "playtime_hours_a": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "playtime_hours_b": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "name", - "playtime_hours_a", - "playtime_hours_b" - ], - "type": "object" - }, - "type": "array" - }, - "returned": { - "type": "number" - }, - "shared_count": { - "type": "number" - } - }, - "required": [ - "found", - "shared_count", - "returned", - "games" - ], - "type": "object" - } -] - added
Output schema / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "games": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "playtime_hours_a": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "playtime_hours_b": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "name", + "playtime_hours_a", + "playtime_hours_b" + ], + "type": "object" + }, + "type": "array" + }, + "returned": { + "type": "number" + }, + "shared_count": { + "type": "number" + } + }, + "required": [ + "found", + "shared_count", + "returned", + "games" + ], + "type": "object" + } +]
- Changed
discover_games12 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / count / defaultAdded value: +50 - changed
Input schema / properties / count / descriptionPrevious 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." - added
Input schema / properties / count / exclusiveMinimumAdded value: +0 - removed
Input schema / properties / count / minimumRemoved value: -1 - added
Input schema / properties / min_discount / exclusiveMinimumAdded value: +0 - removed
Input schema / properties / min_discount / minimumRemoved value: -1 - added
Input schema / properties / released_within_days / exclusiveMinimumAdded value: +0 - removed
Input schema / properties / released_within_days / minimumRemoved value: -1 - added
Input schema / properties / start / defaultAdded value: +0 - changed
Input schema / properties / start / descriptionPrevious value: -"Pagination offset into the catalog."New value: +"Pagination offset into the catalog (default 0)." - changed
Input schema / properties / tags / descriptionPrevious 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."
- Changed
find_friends_who_own3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Output schema / anyOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "matches": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "owners": { - "items": { - "additionalProperties": false, - "properties": { - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "playtime_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "steamid": { - "type": "string" - } - }, - "required": [ - "steamid", - "name", - "playtime_hours" - ], - "type": "object" - }, - "type": "array" - }, - "owners_total": { - "type": "number" - } - }, - "required": [ - "appid", - "owners" - ], - "type": "object" - }, - "type": "array" - }, - "private_friends": { - "items": { - "additionalProperties": false, - "properties": { - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "steamid": { - "type": "string" - } - }, - "required": [ - "steamid", - "name" - ], - "type": "object" - }, - "type": "array" - }, - "private_friends_total": { - "type": "number" - }, - "total_friends": { - "type": "number" - }, - "unavailable_friends": { - "items": { - "additionalProperties": false, - "properties": { - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "reason": { - "type": "string" - }, - "steamid": { - "type": "string" - } - }, - "required": [ - "steamid", - "name", - "reason" - ], - "type": "object" - }, - "type": "array" - }, - "unavailable_friends_total": { - "type": "number" - } - }, - "required": [ - "found", - "total_friends", - "matches", - "private_friends", - "unavailable_friends" - ], - "type": "object" - } -] - added
Output schema / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "matches": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "owners": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "playtime_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "steamid": { + "type": "string" + } + }, + "required": [ + "steamid", + "name", + "playtime_hours" + ], + "type": "object" + }, + "type": "array" + }, + "owners_total": { + "type": "number" + } + }, + "required": [ + "appid", + "owners" + ], + "type": "object" + }, + "type": "array" + }, + "private_friends": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "steamid": { + "type": "string" + } + }, + "required": [ + "steamid", + "name" + ], + "type": "object" + }, + "type": "array" + }, + "private_friends_total": { + "type": "number" + }, + "total_friends": { + "type": "number" + }, + "unavailable_friends": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "reason": { + "type": "string" + }, + "steamid": { + "type": "string" + } + }, + "required": [ + "steamid", + "name", + "reason" + ], + "type": "object" + }, + "type": "array" + }, + "unavailable_friends_total": { + "type": "number" + } + }, + "required": [ + "found", + "total_friends", + "matches", + "private_friends", + "unavailable_friends" + ], + "type": "object" + } +]
- Changed
get_current_players1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_featured1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_followed_games3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Output schema / anyOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "games": { - "items": { - "not": {} - }, - "type": "array" - }, - "reason": { - "type": "string" - }, - "total": { - "const": 0, - "type": "number" - } - }, - "required": [ - "found", - "reason", - "total", - "games" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "games": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "store_url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "appid", - "store_url" - ], - "type": "object" - }, - "type": "array" - }, - "returned": { - "type": "number" - }, - "total": { - "type": "number" - } - }, - "required": [ - "found", - "total", - "returned", - "games" - ], - "type": "object" - } -] - added
Output schema / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "games": { + "items": { + "not": {} + }, + "type": "array" + }, + "reason": { + "type": "string" + }, + "total": { + "const": 0, + "type": "number" + } + }, + "required": [ + "found", + "reason", + "total", + "games" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "games": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "store_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "appid", + "store_url" + ], + "type": "object" + }, + "type": "array" + }, + "returned": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "found", + "total", + "returned", + "games" + ], + "type": "object" + } +]
- Changed
get_friend_list3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Output schema / anyOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "friends": { - "items": { - "additionalProperties": false, - "properties": { - "friends_since": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "in_game": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "profile_url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "state": { - "type": "string" - }, - "steamid": { - "type": "string" - } - }, - "required": [ - "name", - "state", - "in_game", - "profile_url", - "friends_since" - ], - "type": "object" - }, - "type": "array" - }, - "returned": { - "type": "number" - }, - "total": { - "type": "number" - } - }, - "required": [ - "found", - "total", - "returned", - "friends" - ], - "type": "object" - } -] - added
Output schema / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "friends": { + "items": { + "additionalProperties": false, + "properties": { + "friends_since": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "in_game": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "profile_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "state": { + "enum": [ + "offline", + "online", + "busy", + "away", + "snooze", + "looking to trade", + "looking to play" + ], + "type": "string" + }, + "steamid": { + "type": "string" + } + }, + "required": [ + "name", + "state", + "in_game", + "profile_url", + "friends_since" + ], + "type": "object" + }, + "type": "array" + }, + "returned": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "found", + "total", + "returned", + "friends" + ], + "type": "object" + } +]
- Changed
get_game3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Output schema / properties / achievements_highlighted / descriptionAdded value: +"A small keyless sample of named achievements Steam highlights for this game, not the full list — for every achievement with rarity and a hidden flag, use get_game_achievements instead." - changed
Output schema / properties / price / anyOfPrevious value: -[ - { - "anyOf": [ - { - "additionalProperties": false, - "properties": { - "is_free": { - "const": true, - "type": "boolean" - } - }, - "required": [ - "is_free" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "currency": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "discount_percent": { - "type": "number" - }, - "final": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "initial": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "is_free": { - "const": false, - "type": "boolean" - } - }, - "required": [ - "currency", - "final", - "initial", - "discount_percent", - "is_free" - ], - "type": "object" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "is_free": { + "const": true, + "type": "boolean" + } + }, + "required": [ + "is_free" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "currency": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "discount_percent": { + "type": "number" + }, + "final": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "initial": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "is_free": { + "const": false, + "type": "boolean" + } + }, + "required": [ + "currency", + "final", + "initial", + "discount_percent", + "is_free" + ], + "type": "object" + } + ] + }, + { + "type": "null" + } +]
- Changed
get_game_achievements1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_game_news4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limit / defaultAdded value: +5 - added
Input schema / properties / limit / exclusiveMinimumAdded value: +0 - removed
Input schema / properties / limit / minimumRemoved value: -1
- Changed
get_game_reviews6 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limit / defaultAdded value: +5 - added
Input schema / properties / limit / exclusiveMinimumAdded value: +0 - removed
Input schema / properties / limit / minimumRemoved value: -1 - added
Input schema / properties / review_language / defaultAdded value: +"all" - added
Input schema / properties / type / defaultAdded value: +"all"
- Changed
get_global_achievements1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_items1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_owned_games3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Output schema / anyOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "game_count": { - "type": "null" - }, - "games": { - "items": { - "not": {} - }, - "type": "array" - }, - "owns": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "owned": { - "const": false, - "type": "boolean" - } - }, - "required": [ - "appid", - "owned" - ], - "type": "object" - }, - "type": "array" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason", - "game_count", - "games" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "game_count": { - "type": "number" - }, - "games": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "playtime_2weeks_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "playtime_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "name", - "playtime_hours", - "playtime_2weeks_hours" - ], - "type": "object" - }, - "type": "array" - }, - "owns": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "owned": { - "type": "boolean" - }, - "playtime_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "appid", - "owned", - "playtime_hours" - ], - "type": "object" - }, - "type": "array" - }, - "returned": { - "type": "number" - } - }, - "required": [ - "found", - "game_count", - "returned", - "games" - ], - "type": "object" - } -] - added
Output schema / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "game_count": { + "type": "null" + }, + "games": { + "items": { + "not": {} + }, + "type": "array" + }, + "owns": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "owned": { + "const": false, + "type": "boolean" + } + }, + "required": [ + "appid", + "owned" + ], + "type": "object" + }, + "type": "array" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason", + "game_count", + "games" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "game_count": { + "type": "number" + }, + "games": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "playtime_2weeks_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "playtime_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "name", + "playtime_hours", + "playtime_2weeks_hours" + ], + "type": "object" + }, + "type": "array" + }, + "owns": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "owned": { + "type": "boolean" + }, + "playtime_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "appid", + "owned", + "playtime_hours" + ], + "type": "object" + }, + "type": "array" + }, + "returned": { + "type": "number" + } + }, + "required": [ + "found", + "game_count", + "returned", + "games" + ], + "type": "object" + } +]
- Changed
get_player_achievements3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Output schema / anyOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "achievements": { - "items": { - "additionalProperties": false, - "properties": { - "achieved": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "unlocked_at": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "achieved", - "unlocked_at" - ], - "type": "object" - }, - "type": "array" - }, - "completion_pct": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "found": { - "const": true, - "type": "boolean" - }, - "game": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "returned": { - "type": "number" - }, - "total": { - "type": "number" - }, - "unlocked": { - "type": "number" - } - }, - "required": [ - "found", - "game", - "total", - "unlocked", - "completion_pct", - "returned", - "achievements" - ], - "type": "object" - } -] - added
Output schema / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "achievements": { + "items": { + "additionalProperties": false, + "properties": { + "achieved": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "unlocked_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "achieved", + "unlocked_at" + ], + "type": "object" + }, + "type": "array" + }, + "completion_pct": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "found": { + "const": true, + "type": "boolean" + }, + "game": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "returned": { + "type": "number" + }, + "total": { + "type": "number" + }, + "unlocked": { + "type": "number" + } + }, + "required": [ + "found", + "game", + "total", + "unlocked", + "completion_pct", + "returned", + "achievements" + ], + "type": "object" + } +]
- Changed
get_player_bans3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Output schema / anyOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - } - }, - "required": [ - "found" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "community_banned": { - "type": "boolean" - }, - "days_since_last_ban": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "economy_ban": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "found": { - "const": true, - "type": "boolean" - }, - "game_ban_count": { - "type": "number" - }, - "steamid": { - "type": "string" - }, - "vac_ban_count": { - "type": "number" - }, - "vac_banned": { - "type": "boolean" - } - }, - "required": [ - "found", - "vac_banned", - "vac_ban_count", - "game_ban_count", - "community_banned", - "economy_ban", - "days_since_last_ban" - ], - "type": "object" - } -] - added
Output schema / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + } + }, + "required": [ + "found" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "community_banned": { + "type": "boolean" + }, + "days_since_last_ban": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "economy_ban": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "found": { + "const": true, + "type": "boolean" + }, + "game_ban_count": { + "type": "number" + }, + "steamid": { + "type": "string" + }, + "vac_ban_count": { + "type": "number" + }, + "vac_banned": { + "type": "boolean" + } + }, + "required": [ + "found", + "vac_banned", + "vac_ban_count", + "game_ban_count", + "community_banned", + "economy_ban", + "days_since_last_ban" + ], + "type": "object" + } +]
- Changed
get_player_summary3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Output schema / anyOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - } - }, - "required": [ - "found" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "avatar": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "country": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "created": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "found": { - "const": true, - "type": "boolean" - }, - "in_game": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "level": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "profile_url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "real_name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "state": { - "type": "string" - }, - "steamid": { - "type": "string" - }, - "visibility": { - "enum": [ - "public", - "private" - ], - "type": "string" - } - }, - "required": [ - "found", - "name", - "real_name", - "state", - "visibility", - "country", - "level", - "created", - "in_game", - "profile_url", - "avatar" - ], - "type": "object" - } -] - added
Output schema / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + } + }, + "required": [ + "found" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "avatar": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "country": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "created": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "found": { + "const": true, + "type": "boolean" + }, + "in_game": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "level": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "profile_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "real_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "state": { + "enum": [ + "offline", + "online", + "busy", + "away", + "snooze", + "looking to trade", + "looking to play" + ], + "type": "string" + }, + "steamid": { + "type": "string" + }, + "visibility": { + "enum": [ + "public", + "private" + ], + "type": "string" + } + }, + "required": [ + "found", + "name", + "real_name", + "state", + "visibility", + "country", + "level", + "created", + "in_game", + "profile_url", + "avatar" + ], + "type": "object" + } +]
- Changed
get_prices1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_recently_played3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Output schema / anyOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "games": { - "items": { - "not": {} - }, - "type": "array" - }, - "reason": { - "type": "string" - }, - "total": { - "const": 0, - "type": "number" - } - }, - "required": [ - "found", - "reason", - "total", - "games" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "games": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "playtime_2weeks_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "playtime_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "name", - "playtime_hours", - "playtime_2weeks_hours" - ], - "type": "object" - }, - "type": "array" - }, - "total": { - "type": "number" - } - }, - "required": [ - "found", - "total", - "games" - ], - "type": "object" - } -] - added
Output schema / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "games": { + "items": { + "not": {} + }, + "type": "array" + }, + "reason": { + "type": "string" + }, + "total": { + "const": 0, + "type": "number" + } + }, + "required": [ + "found", + "reason", + "total", + "games" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "games": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "playtime_2weeks_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "playtime_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "name", + "playtime_hours", + "playtime_2weeks_hours" + ], + "type": "object" + }, + "type": "array" + }, + "total": { + "type": "number" + } + }, + "required": [ + "found", + "total", + "games" + ], + "type": "object" + } +]
- Changed
get_recommended_games10 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / count / defaultAdded value: +10 - changed
Input schema / properties / count / descriptionPrevious value: -"How many recommendations to return (default 10)."New value: +"How many recommendations to return (1-25). Default 10." - added
Input schema / properties / count / exclusiveMinimumAdded value: +0 - removed
Input schema / properties / count / minimumRemoved value: -1 - changed
Input schema / properties / exclude_tags / descriptionPrevious value: -"Drop any candidate carrying ANY of these tags (case-insensitive), e.g. ['Souls-like'] for 'recommend me something except Souls-like'."New value: +"Drop any candidate carrying ANY of these tags (case-insensitive), e.g. ['Souls-like'] for 'recommend me something except Souls-like'. Use exact Steam tag names — a misspelled/unrecognized one isn't an error, it just drops nothing." - added
Input schema / properties / min_discount / exclusiveMinimumAdded value: +0 - removed
Input schema / properties / min_discount / minimumRemoved value: -1 - removed
Output schema / anyOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "based_on_tags": { - "items": { - "type": "string" - }, - "type": "array" - }, - "count": { - "type": "number" - }, - "found": { - "const": true, - "type": "boolean" - }, - "recommendations": { - "items": { - "additionalProperties": false, - "properties": { - "appid": { - "type": "number" - }, - "discount_end": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "discount_pct": { - "type": "number" - }, - "match_score": { - "description": "An internal ranking weight (playtime-on-matched-tags, discounted by review score) — not a percentage or 0-100 scale. Only meaningful relative to the other scores in this same response, to explain why one pick outranks another.", - "type": "number" - }, - "matched_tags": { - "items": { - "type": "string" - }, - "type": "array" - }, - "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", - "matched_tags", - "match_score" - ], - "type": "object" - }, - "type": "array" - } - }, - "required": [ - "found", - "based_on_tags", - "count", - "recommendations" - ], - "type": "object" - } -] - added
Output schema / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "based_on_tags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "count": { + "type": "number" + }, + "found": { + "const": true, + "type": "boolean" + }, + "recommendations": { + "items": { + "additionalProperties": false, + "properties": { + "appid": { + "type": "number" + }, + "discount_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "discount_pct": { + "type": "number" + }, + "match_score": { + "description": "An internal ranking weight (playtime-on-matched-tags, discounted by review score) — not a percentage or 0-100 scale. Only meaningful relative to the other scores in this same response, to explain why one pick outranks another.", + "type": "number" + }, + "matched_tags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "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", + "matched_tags", + "match_score" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "found", + "based_on_tags", + "count", + "recommendations" + ], + "type": "object" + } +]
- Changed
get_review_histogram1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_specials1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_wishlist4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / min_discount / exclusiveMinimumAdded value: +0 - removed
Input schema / properties / min_discount / minimumRemoved value: -1 - changed
Input schema / properties / tags / descriptionPrevious value: -"Keep only wishlist items carrying ALL of these user tags (case-insensitive), e.g. ['Metroidvania']. Implies include_details."New value: +"Keep only wishlist items carrying ALL of these user tags (case-insensitive), e.g. ['Metroidvania']. Use exact Steam tag names — a misspelled/unrecognized one isn't an error, it just matches nothing. Implies include_details."
- Changed
resolve_vanity_url3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Output schema / anyOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "found": { - "const": true, - "type": "boolean" - }, - "steamid": { - "type": "string" - } - }, - "required": [ - "found", - "steamid" - ], - "type": "object" - } -] - added
Output schema / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "found": { + "const": true, + "type": "boolean" + }, + "steamid": { + "type": "string" + } + }, + "required": [ + "found", + "steamid" + ], + "type": "object" + } +]
- Changed
search_games1 field changed- added
Input schema / additionalPropertiesAdded value: +false
4 tool updates
v0.10.5- Added
get_friend_list - Added
get_owned_games - Added
get_specials - Added
resolve_vanity_url
9 tool updates
v0.10.4- Added
discover_games - Added
find_friends_who_own - Added
get_featured - Added
get_followed_games - Removed
get_friend_list - Removed
get_owned_games - Added
get_prices - Added
get_review_histogram - Removed
get_specials
13 tool updates
v0.10.4- Removed
find_friends_who_own - Added
get_game - Changed
get_game_achievements2 fields changed- added
Output schema / properties / returnedAdded value: +{ + "type": "number" +} - changed
Output schema / requiredPrevious value: -[ - "game", - "total", - "achievements" -]New value: +[ + "game", + "total", + "returned", + "achievements" +]
- Added
get_game_news - Added
get_global_achievements - Added
get_items - Added
get_owned_games - Changed
get_player_achievements1 field changed- changed
Output schema / anyOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "found": { - "const": false, - "type": "boolean" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "found", - "reason" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "achievements": { - "items": { - "additionalProperties": false, - "properties": { - "achieved": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "unlocked_at": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "achieved", - "unlocked_at" - ], - "type": "object" - }, - "type": "array" - }, - "completion_pct": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "found": { - "const": true, - "type": "boolean" - }, - "game": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "total": { - "type": "number" - }, - "unlocked": { - "type": "number" - } - }, - "required": [ - "found", - "game", - "total", - "unlocked", - "completion_pct", - "achievements" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "found": { + "const": false, + "type": "boolean" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "found", + "reason" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "achievements": { + "items": { + "additionalProperties": false, + "properties": { + "achieved": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "unlocked_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "achieved", + "unlocked_at" + ], + "type": "object" + }, + "type": "array" + }, + "completion_pct": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "found": { + "const": true, + "type": "boolean" + }, + "game": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "returned": { + "type": "number" + }, + "total": { + "type": "number" + }, + "unlocked": { + "type": "number" + } + }, + "required": [ + "found", + "game", + "total", + "unlocked", + "completion_pct", + "returned", + "achievements" + ], + "type": "object" + } +]
- Removed
get_prices - Added
get_recommended_games - Added
get_specials - Added
get_wishlist - Removed
resolve_vanity_url
12 tool updates
v0.10.2- Added
compare_players - Removed
discover_games - Added
find_friends_who_own - Removed
get_featured - Removed
get_followed_games - Added
get_game_achievements - Added
get_game_reviews - Removed
get_items - Added
get_player_achievements - Removed
get_recommended_games - Removed
get_wishlist - Added
search_games
13 tool updates
v0.10.2- Changed
discover_games2 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - changed
Output 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" +}
- Added
get_current_players - Added
get_featured - Added
get_followed_games - Added
get_friend_list - Added
get_items - Added
get_player_bans - Added
get_player_summary - Added
get_prices - Added
get_recently_played - Added
get_recommended_games - Added
get_wishlist - Added
resolve_vanity_url
13 tool updates
v0.9.0- Added
discover_games - Removed
get_featured - Removed
get_friend_list - Removed
get_game - Removed
get_game_news - Removed
get_game_reviews - Removed
get_global_achievements - Removed
get_prices - Removed
get_recently_played - Removed
get_review_histogram - Removed
get_specials - Removed
resolve_vanity_url - Removed
search_games
4 tool updates
v0.8.1- Removed
compare_players - Added
get_friend_list - Removed
get_items - Added
resolve_vanity_url
8 tool updates
v0.8.0- Added
compare_players - Removed
discover_games - Removed
get_current_players - Added
get_game - Added
get_game_reviews - Added
get_recently_played - Added
get_review_histogram - Added
search_games
15 tool updates
v0.8.0- Removed
find_friends_who_own - Removed
get_followed_games - Removed
get_friend_list - Removed
get_game - Removed
get_game_achievements - Removed
get_game_reviews - Removed
get_owned_games - Removed
get_player_achievements - Removed
get_player_bans - Removed
get_player_summary - Removed
get_recently_played - Removed
get_review_histogram - Removed
get_wishlist - Removed
resolve_vanity_url - Removed
search_games
4 tool updates
v0.7.0- Changed
discover_games2 fields changed- added
Input schema / properties / steam_machineAdded 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" +} - changed
Input schema / properties / steam_os / descriptionPrevious 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."
- Added
get_followed_games - Added
get_player_bans - Changed
get_wishlist2 fields changed- added
Input schema / properties / steam_machineAdded 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" +} - changed
Input schema / properties / steam_os / descriptionPrevious 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."
2 tool updates
v0.6.0- Added
find_friends_who_own - Added
get_friend_list
3 tool updates
v0.5.0- Changed
discover_games7 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"Country (cc) for prices; overrides STEAM_COUNTRY."New value: +"Country (cc) for prices/currency; overrides STEAM_COUNTRY for this call." - changed
Input schema / properties / language / descriptionPrevious value: -"Store language; overrides STEAM_LANGUAGE."New value: +"Store language (e.g. english, russian); overrides STEAM_LANGUAGE for this call." - added
Input schema / properties / platformAdded 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" +} - changed
Input schema / properties / steam_deck / descriptionPrevious 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." - added
Input schema / properties / steam_frameAdded value: +{ + "description": "Steam Frame (VR headset) compatibility: 'verified' = Frame-Verified only; 'playable' = Playable or Verified.", + "enum": [ + "playable", + "verified" + ], + "type": "string" +} - added
Input schema / properties / steam_osAdded 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" +} - added
Input schema / properties / tagsAdded 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" +}
- Changed
get_items2 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"Country (cc) for prices; overrides STEAM_COUNTRY."New value: +"Country (cc) for prices/currency; overrides STEAM_COUNTRY for this call." - changed
Input schema / properties / language / descriptionPrevious value: -"Store language; overrides STEAM_LANGUAGE."New value: +"Store language (e.g. english, russian); overrides STEAM_LANGUAGE for this call."
- Changed
get_wishlist11 fields changed- added
Input schema / properties / countryAdded value: +{ + "description": "Country (cc) for prices; overrides STEAM_COUNTRY. Only meaningful for store cards, so setting it implies include_details — the light appid list carries no price.", + "pattern": "^[A-Za-z]{2}$", + "type": "string" +} - added
Input schema / properties / include_detailsAdded value: +{ + "description": "Return full store cards (name, price, discount, reviews, compatibility, tags) per item in one call, instead of just appids. Implied by any filter below.", + "type": "boolean" +} - added
Input schema / properties / languageAdded value: +{ + "description": "Store language; overrides STEAM_LANGUAGE. Only meaningful for store cards, so setting it implies include_details — the light appid list carries no price.", + "minLength": 2, + "type": "string" +} - added
Input schema / properties / min_discountAdded value: +{ + "description": "Keep only items discounted at least this %, ranked by discount. Implies include_details.", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / min_reviewAdded value: +{ + "description": "Keep only items with at least this positive-review %. Implies include_details.", + "maximum": 100, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / on_sale_onlyAdded value: +{ + "description": "Only wishlist items currently discounted, ranked by discount %. Implies include_details.", + "type": "boolean" +} - added
Input schema / properties / platformAdded 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" +} - added
Input schema / properties / steam_deckAdded value: +{ + "description": "Steam Deck compatibility (runs via Proton): 'verified' = Deck-Verified only; 'playable' = Playable or Verified. Not a native Linux build — see `platform` for that.", + "enum": [ + "playable", + "verified" + ], + "type": "string" +} - added
Input schema / properties / steam_frameAdded value: +{ + "description": "Steam Frame (VR headset) compatibility: 'verified' = Frame-Verified only; 'playable' = Playable or Verified.", + "enum": [ + "playable", + "verified" + ], + "type": "string" +} - added
Input schema / properties / steam_osAdded 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" +} - added
Input schema / properties / tagsAdded value: +{ + "description": "Keep only wishlist items carrying ALL of these user tags (case-insensitive), e.g. ['Metroidvania']. Implies include_details.", + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" +}
8 tool updates
v0.3.0- Removed
discover_deals - Added
discover_games - Changed
get_game3 fields changed- changed
Input schema / properties / appid / descriptionPrevious value: -"Steam application id (appid). Get it from search_games."New value: +"Steam appid (from search_games). Provide appid OR name." - added
Input schema / properties / nameAdded value: +{ + "description": "Game title to look up instead of an appid — resolved to the closest store match. Provide appid OR name; appid wins if both are given.", + "minLength": 1, + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "appid" -]
- Changed
get_owned_games2 fields changed- changed
Input schema / properties / steamid / descriptionPrevious value: -"17-digit SteamID64. Convert a vanity/custom URL name with resolve_vanity_url first."New value: +"17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first." - removed
Input schema / requiredRemoved value: -[ - "steamid" -]
- Changed
get_player_achievements3 fields changed- added
Input schema / properties / languageAdded value: +{ + "description": "Language for achievement names/descriptions; overrides STEAM_LANGUAGE.", + "minLength": 2, + "type": "string" +} - changed
Input schema / properties / steamid / descriptionPrevious value: -"17-digit SteamID64. Convert a vanity/custom URL name with resolve_vanity_url first."New value: +"17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first." - changed
Input schema / requiredPrevious value: -[ - "steamid", - "appid" -]New value: +[ + "appid" +]
- Changed
get_player_summary2 fields changed- changed
Input schema / properties / steamid / descriptionPrevious value: -"17-digit SteamID64. Convert a vanity/custom URL name with resolve_vanity_url first."New value: +"17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first." - removed
Input schema / requiredRemoved value: -[ - "steamid" -]
- Changed
get_recently_played2 fields changed- changed
Input schema / properties / steamid / descriptionPrevious value: -"17-digit SteamID64. Convert a vanity/custom URL name with resolve_vanity_url first."New value: +"17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first." - removed
Input schema / requiredRemoved value: -[ - "steamid" -]
- Changed
get_wishlist2 fields changed- changed
Input schema / properties / steamid / descriptionPrevious value: -"17-digit SteamID64. Convert a vanity/custom URL name with resolve_vanity_url first."New value: +"17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first." - removed
Input schema / requiredRemoved value: -[ - "steamid" -]
5 tool updates
v0.2.0- Added
discover_deals - Removed
get_current_prices - Removed
get_deals - Removed
get_game_info - Removed
get_price_history
TDQS
Scored across 26 tools
Descriptions are unusually careful about boundaries (e.g., get_items vs get_prices, get_game_reviews vs get_review_histogram, find_friends_who_own vs get_owned_games), so agents can usually choose correctly. However, with 26 Steam endpoints, several tools remain close cousins in batch pricing, store trends, and achievement variants, leaving some misselection risk.
All names use snake_case and almost all follow verb_noun or verb_phrase conventions: get_*, search_*, discover_games, resolve_vanity_url, find_friends_who_own, compare_players. There is no camelCase or chaotic mixed style.
26 tools is just above the heavy threshold for a single server; although the Steam domain is broad and many tools target distinct resources, the set includes consolidatable pairs such as get_prices/get_items and get_featured/get_specials/get_charts. It is borderline heavy rather than tightly scoped.
The surface covers store search, game details, pricing, reviews, charts, achievements, player profile/bans, libraries, wishlists, friends, comparisons and recommendations, which is strong for Steam's read-only API. Gaps remain around some niche Steam data (e.g., market/inventory or deeper per-game user stats), but core workflows are covered.
Maintenance
Related MCP Connectors
Steam profiles, SteamID conversion, bans, FACEIT stats, friends and comparisons. Free, no API key.
Live Steam Market API docs, schemas, products, games, markets and endpoint search.
Live Steam market data for AI agents: top sellers, deals, player counts. Paid per call via x402.
Steam backlog, account value, buy-or-skip verdicts and Steam Machine checks. Hosted, keyless.
Related MCP Servers
- AlicenseBqualityCmaintenanceProvides tools for interacting with the Steam Web API to access player profiles, game libraries, achievements, statistics, inventories, and game information through natural language.63458 npm5MIT
- AlicenseAqualityBmaintenanceExposes Steam Web API tools as MCP resources for Claude Code, Claude Desktop, and Gemini CLI, enabling profile lookups, game searches, achievement tracking, and more.1115 npm1MIT
- AlicenseAqualityCmaintenanceIntegrates with Steam Web API to enable querying user profiles, game libraries, store data, and community features like reviews and workshop items.16MIT
- AlicenseNot gradedqualityDmaintenanceProvides Steam Web API integration for querying owned games, player achievements, app news, and store details. Part of the Pipeworx MCP gateway enabling natural language queries to Steam data.31 npmMIT