Steam MCP Server
NPM · STEAM-GAMES-MCP · 2 COMPONENTS · SCANNED SEP 20
Steam store/game data (no key) plus player profiles, libraries and achievements (Steam Web API).
Available components
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security100
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- No install/post-install scripts declared.Pass
- 0 of 3 dependencies flagged as unhealthy. View diagnostics → Pass
Provenance & Transparency100
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Cryptographically verified build provenance (signed, bound to Grinv/steam-games-mcp). View diagnostics → Pass
- Clear OSI-approved license (MIT).Pass
- Actively maintained (last published 0 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability77
- 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 9158 tokens (~366/item across 25 items; 25 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management80
- Stability observed for 24 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
- Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- We read all 25 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
- An AI judge read all 26 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a current MCP spec version (2026-07-28).Pass
How do I install the Steam MCP Server server?
Steam MCP Server runs locally as an npm package, launched with npx -y steam-games-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
npm · steam-games-mcp
claude mcp add grinv-steam-games-mcp -- npx -y steam-games-mcp
{
"mcpServers": {
"grinv-steam-games-mcp": {
"command": "npx",
"args": [
"-y",
"steam-games-mcp"
]
}
}
} {
"servers": {
"grinv-steam-games-mcp": {
"command": "npx",
"args": [
"-y",
"steam-games-mcp"
]
}
}
} codex mcp add grinv-steam-games-mcp -- npx -y steam-games-mcp
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"grinv-steam-games-mcp": {
"type": "local",
"command": [
"npx",
"-y",
"steam-games-mcp"
],
"enabled": true
}
}
} openclaw mcp add grinv-steam-games-mcp --command npx --arg -y --arg steam-games-mcp
mcp_servers:
grinv-steam-games-mcp:
command: "npx"
args: ["-y", "steam-games-mcp"] {
"McpServers": {
"grinv-steam-games-mcp": {
"Transport": "stdio",
"Command": "npx",
"Arguments": [
"-y",
"steam-games-mcp"
]
}
}
} assistant mcp add grinv-steam-games-mcp -t stdio -c npx -a -y steam-games-mcp
{
"mcpServers": {
"grinv-steam-games-mcp": {
"command": "npx",
"args": [
"-y",
"steam-games-mcp"
]
}
}
} Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 20 Sept 26 −3
- Stability: pass → unverified ▼ security
- Tool safety: pass → unverified ▼ security
- Schema quality: 276 → 366 ▼ functional
- Tool coverage: 100 → unverified ▼ functional
- Schema quality: 100 → unverified ▼ functional
- Capabilities: pass → unverified ▼ functional
- Stability: pass → 0.80 functional
- Package version: 0.13.1 → 0.14.0 functional
- 19 Sept 26 0
- Stability: 0.97 → pass security
- 18 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 93 to 97. That category is still filling its 30-day observation window: 28 days of observed history at the previous scan, 29 at this one. The score rises as the window fills, whether or not the server changes.
- 16 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 87 to 90. That category is still filling its 30-day observation window: 26 days of observed history at the previous scan, 27 at this one. The score rises as the window fills, whether or not the server changes.
- 14 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 80 to 83. That category is still filling its 30-day observation window: 24 days of observed history at the previous scan, 25 at this one. The score rises as the window fills, whether or not the server changes.
- 13 Sept 26 −3
- Stability: pass → 0.80 functional
- 12 Sept 26 0
- Stability: 0.97 → pass security
- 11 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 93 to 97. That category is still filling its 30-day observation window: 28 days of observed history at the previous scan, 29 at this one. The score rises as the window fills, whether or not the server changes.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 20 Sept 2026 · Analysed npm/steam-games-mcp@0.14.0
Provenance Verified
A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.
| Result | Verified |
|---|---|
| Ecosystem | npm |
| Reason | Verified |
| Discovered via | Registry attestation endpoint |
| Source repo | Grinv/steam-games-mcp |
| Certificate issuer | https://token.actions.githubusercontent.com |
| Certificate SAN | https://github.com/Grinv/steam-games-mcp/.github/workflows/release.yml@refs/tags/v0.14.0 |
| Rekor log index | 2895213296 |
| Predicate type | https://slsa.dev/provenance/v1 |
| Subject digest | sha512:92ef9dcab0f0d7516bb65da255a626692c4111c92a9d4f0bdcbfc17629ef53198aac971fa797e8da5c13532ccb1059e961fc9848c73a5860739278681 |
Background: How many MCP packages publish verified provenance →
Dependencies 3 packages
| Packages resolved | 3 |
|---|---|
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
compare_players Compare two players' libraries ~234
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 | Type | Req | Description |
|---|---|---|---|
| other_steamid | string | yes | The other player's 17-digit SteamID64 to compare against. Convert a vanity/custom profile name with resolve_vanity_url first. |
| steamid | string | – | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Structured output declared, but exposes no named fields.
No examples provided.
discover_games Discover games ~1,337
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 60 results come back per call, best discount first: compare `returned` aga…
| Name | Type | Req | Description |
|---|---|---|---|
| count | integer | – | 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 stricte… |
| country | string | – | 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 answe… |
| language | string | – | 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 En… |
| min_discount | integer | – | Minimum discount %, e.g. 80 for '80%+ off' — this is the 'deals' filter. Omit to include full-price games. |
| min_review | integer | – | 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. |
| min_reviews | integer | – | Minimum review count, e.g. 500 — filters out games too obscure to trust a % on. Applied over the scanned `count` window, like min_review. |
| platform | string | – | 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 u… |
| released_after | string | – | Keep only games released on/after this date (YYYY-MM-DD). |
| released_within_days | integer | – | 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 p… |
| start | integer | – | Pagination offset into the catalog (default 0). |
| steam_deck | string | – | 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 | string | – | Steam Frame (VR headset) compatibility: 'verified' = Frame-Verified only; 'playable' = Playable or Verified. |
| steam_machine | string | – | 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. |
| steam_os | string | – | 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:'lin… |
| tags | array | – | 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 nothin… |
| Name | Type | Req | Description |
|---|---|---|---|
| deals | array | yes | – |
| matched | number | yes | How many results survived every filter, out of the scanned window (see `count`). |
| returned | number | 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 | number|null | 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… |
No examples provided.
find_friends_who_own Find friends who own a game ~470
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 | Type | Req | Description |
|---|---|---|---|
| appids | array | 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 th… |
| steamid | string | – | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Structured output declared, but exposes no named fields.
No examples provided.
get_current_players Get current player count ~78
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 | Type | Req | Description |
|---|---|---|---|
| appid | integer | yes | Steam application id (appid). Get it from search_games. |
| Name | Type | Req | Description |
|---|---|---|---|
| appid | number | yes | – |
| player_count | number|null | yes | – |
No examples provided.
get_featured Get featured store sections ~274
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 | Type | Req | Description |
|---|---|---|---|
| country | string | – | 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 answe… |
| language | string | – | 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 En… |
| Name | Type | Req | Description |
|---|---|---|---|
| coming_soon | array | yes | – |
| new_releases | array | yes | – |
| specials | array | yes | – |
| top_sellers | array | yes | – |
No examples provided.
get_followed_games Get a player's followed games ~230
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 | Type | Req | Description |
|---|---|---|---|
| steamid | string | – | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Structured output declared, but exposes no named fields.
No examples provided.
get_friend_list Get a player's friend list ~179
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 | Type | Req | Description |
|---|---|---|---|
| steamid | string | – | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Structured output declared, but exposes no named fields.
No examples provided.
get_game Get game details ~439
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 | Type | Req | Description |
|---|---|---|---|
| appid | integer | – | Steam appid (from search_games). Provide appid OR name. |
| country | string | – | 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 answe… |
| language | string | – | 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 En… |
| name | string | – | 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. |
| Name | Type | Req | Description |
|---|---|---|---|
| account_notice | string|null | yes | – |
| achievements_highlighted | array | 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. |
| achievements_total | number|null | yes | – |
| appid | number | – | – |
| base_game | – | yes | – |
| categories | array | yes | – |
| coming_soon | boolean | yes | – |
| content_descriptors | object | yes | – |
| controller_support | string|null | yes | – |
| demos | array | yes | – |
| developers | array | yes | – |
| dlc | array | 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. |
| dlc_total | number | yes | How many DLC this game has in total, before the `dlc` cap. |
| drm_notice | string|null | yes | – |
| genres | array | yes | – |
| header_image | string|null | yes | – |
| is_free | boolean | yes | – |
| metacritic | number|null | yes | – |
| metacritic_url | string|null | yes | – |
| name | string | – | – |
| pc_requirements_min | string|null | yes | – |
| platforms | array | yes | – |
| price | – | yes | – |
| publishers | array | yes | – |
| recommendations | number|null | yes | – |
| release_date | string|null | yes | – |
| required_age | number|string|null | yes | – |
| short_description | string|null | yes | – |
| store_url | string|null | yes | – |
| supported_languages | string|null | yes | – |
| type | string|null | yes | – |
| website | string|null | yes | – |
No examples provided.
get_game_achievements Get a game's full achievement list ~321
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 | Type | Req | Description |
|---|---|---|---|
| appid | integer | yes | Steam application id (appid). Get it from search_games. |
| language | string | – | 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 ne… |
| Name | Type | Req | Description |
|---|---|---|---|
| achievements | array | yes | – |
| game | string|null | 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 iden… |
| returned | number | yes | – |
| total | number | yes | – |
No examples provided.
get_game_news Get game news ~133
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 | Type | Req | Description |
|---|---|---|---|
| appid | integer | yes | Steam application id (appid). Get it from search_games. |
| limit | integer | – | How many news items (1-20). Default 5. |
| Name | Type | Req | Description |
|---|---|---|---|
| items | array | yes | – |
No examples provided.
get_game_reviews Get game reviews ~325
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 | Type | Req | Description |
|---|---|---|---|
| appid | integer | yes | Steam application id (appid). Get it from search_games. |
| limit | integer | – | How many recent reviews (1-20). Default 5. |
| review_language | string | – | 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… |
| type | string | – | 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 e… |
| Name | Type | Req | Description |
|---|---|---|---|
| positive_pct | number|null | yes | – |
| reviews | array | yes | – |
| summary | string|null | yes | – |
| total_negative | number|null | yes | – |
| total_positive | number|null | yes | – |
| total_reviews | number|null | yes | – |
No examples provided.
get_global_achievements Get global achievement rates ~159
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 | Type | Req | Description |
|---|---|---|---|
| appid | integer | yes | Steam application id (appid). Get it from search_games. |
| Name | Type | Req | Description |
|---|---|---|---|
| achievements | array | yes | – |
| count | number | yes | – |
| returned | number | yes | – |
No examples provided.
get_items Batch store card for many games ~532
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 | Type | Req | Description |
|---|---|---|---|
| appids | array | yes | Steam appids (1-50). Split a longer list across calls. |
| country | string | – | 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 answe… |
| language | string | – | 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 En… |
| Name | Type | Req | Description |
|---|---|---|---|
| count | number | yes | – |
| items | array | yes | – |
No examples provided.
get_owned_games Get owned games ~555
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 | Type | Req | Description |
|---|---|---|---|
| check_appids | array | – | 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… |
| limit | integer | – | 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… |
| sort | string | – | Which end of the library the cap keeps: 'playtime_desc' (default) the most-played, 'playtime_asc' the least-played and never-played first. |
| steamid | string | – | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Structured output declared, but exposes no named fields.
No examples provided.
get_player_achievements Get a player's achievements ~350
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 | Type | Req | Description |
|---|---|---|---|
| appid | integer | yes | Steam application id (appid). Get it from search_games. |
| language | string | – | 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 ne… |
| steamid | string | – | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Structured output declared, but exposes no named fields.
No examples provided.
get_player_bans Get a player's ban status ~142
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 | Type | Req | Description |
|---|---|---|---|
| steamid | string | – | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Structured output declared, but exposes no named fields.
No examples provided.
get_player_summary Get player profile ~170
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 | Type | Req | Description |
|---|---|---|---|
| steamid | string | – | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Structured output declared, but exposes no named fields.
No examples provided.
get_prices Get prices for many games ~319
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 | Type | Req | Description |
|---|---|---|---|
| appids | array | yes | Steam appids to price (1-250). Split a longer list across calls. |
| country | string | – | 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 answe… |
| Name | Type | Req | Description |
|---|---|---|---|
| count | number | yes | – |
| prices | array | yes | – |
No examples provided.
get_recently_played Get recently played games ~180
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 | Type | Req | Description |
|---|---|---|---|
| steamid | string | – | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Structured output declared, but exposes no named fields.
No examples provided.
get_recommended_games Get personalized game recommendations ~550
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 | Type | Req | Description |
|---|---|---|---|
| exclude_tags | array | – | 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 a… |
| limit | integer | – | How many recommendations to return (1-25). Default 10. |
| min_discount | integer | – | 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. |
| steamid | string | – | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
Structured output declared, but exposes no named fields.
No examples provided.
get_review_histogram Get review trend over time ~209
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 | Type | Req | Description |
|---|---|---|---|
| appid | integer | yes | Steam application id (appid). Get it from search_games. |
| Name | Type | Req | Description |
|---|---|---|---|
| history | array | yes | – |
| recent | array | yes | – |
| rollup_type | string|null | 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… |
No examples provided.
get_specials Get current discounts ~248
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 | Type | Req | Description |
|---|---|---|---|
| country | string | – | 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 answe… |
| language | string | – | 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 En… |
| Name | Type | Req | Description |
|---|---|---|---|
| specials | array | yes | – |
No examples provided.
get_wishlist Get a player's wishlist ~1,078
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 60 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 | Type | Req | Description |
|---|---|---|---|
| country | string | – | 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… |
| include_details | boolean | – | Return full store cards (name, price, discount, reviews, compatibility, tags) per item in one call, instead of just appids. Implied by any filter below. |
| language | string | – | 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… |
| min_discount | integer | – | Keep only items discounted at least this %, ranked by discount. Implies include_details. |
| min_review | integer | – | Keep only items with at least this positive-review %. Implies include_details. |
| on_sale_only | boolean | – | Only wishlist items currently discounted, ranked by discount %. Implies include_details. |
| platform | string | – | 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 u… |
| steam_deck | string | – | 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 | string | – | Steam Frame (VR headset) compatibility: 'verified' = Frame-Verified only; 'playable' = Playable or Verified. |
| steam_machine | string | – | 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. |
| steam_os | string | – | 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:'lin… |
| steamid | string | – | 17-digit SteamID64. Omit to use the STEAM_ID configured on the server. Convert a vanity/custom URL name with resolve_vanity_url first. |
| tags | array | – | 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.… |
Structured output declared, but exposes no named fields.
No examples provided.
resolve_vanity_url Resolve vanity URL to SteamID ~94
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 | Type | Req | Description |
|---|---|---|---|
| vanity | string | yes | Vanity name, e.g. 'gabelogannewell' from steamcommunity.com/id/gabelogannewell. |
Structured output declared, but exposes no named fields.
No examples provided.
search_games Search games ~342
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 | Type | Req | Description |
|---|---|---|---|
| country | string | – | 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 answe… |
| language | string | – | 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 En… |
| term | string | yes | Game title to search for. |
| Name | Type | Req | Description |
|---|---|---|---|
| results | array | yes | – |
| total | number | yes | – |
No examples provided.
What is the Steam MCP Server server?
Steam MCP Server is listed in the public MCP registry as io.github.Grinv/steam-games-mcp. Steam store/game data (no key) plus player profiles, libraries and achievements (Steam Web API). This page covers its npm package (steam-games-mcp).
Is the Steam MCP Server server safe to use?
Steam MCP Server scores 93 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 20 September 2026. It declares no install or post-install scripts. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the Steam MCP Server server expose?
Steam MCP Server exposes 25 tools: search_games, get_game, get_game_reviews, get_review_histogram, get_prices, and 20 more. Their descriptions and schemas cost roughly 8,948 tokens of context every time the server is loaded.
Is the Steam MCP Server server still maintained?
Steam MCP Server is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the Steam MCP Server server under?
Steam MCP Server declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.