Skip to main content
Glama

get_steam_review

Retrieve Steam game reviews and statistics by application ID to analyze user feedback and game information.

Instructions

Retrieves reviews and game information for a specific Steam application. Returns formatted review data including review scores, positive/negative counts, review texts, and basic game information.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
appidYesSteam application ID
filterNorecent: sorted by creation time, updated: sorted by last updated time,all: (default) sorted by helpfulness, with sliding windows based on day_range parameter, will always find results to return.all
languageNoLanguage filter (e.g. english, french, schinese). Default is all languages.all
day_rangeNorange from now to n days ago to look for helpful reviews. Only applicable for the all filter.
cursorNoreviews are returned in batches of 20, so pass * for the first set, then the value of cursor that was returned in the response for the next set, etc. Note that cursor values may contain characters that need to be URLEncoded for use in the querystring.*
review_typeNoall:all reviews (default), positive: only positive reviews, negative: only negative reviewsall
purchase_typeNoall: all reviews, non_steam_purchase: reviews written by users who did not pay for the product on Steam,steam: reviews written by users who paid for the product on Steam (default)steam
num_per_pageNonumber of reviews to get, max 100, default 50

Implementation Reference

  • Handler function for 'get_steam_review' tool. Fetches Steam app reviews and game details using Steam API, processes review texts with cleanReviewText, formats into JSON with game_reviews (scores, counts, cleaned reviews) and game_info (name, description), returns as text content.
    async (params) => {
      try {
        // Fetch game reviews
        const reviewsUrl = new URL(`appreviews/${params.appid}`, STEAM_API_BASE);
        reviewsUrl.searchParams.append("json", "1");
        reviewsUrl.searchParams.append("filter", params.filter);
        reviewsUrl.searchParams.append("language", params.language);
        reviewsUrl.searchParams.append("day_range", params.day_range.toString());
        reviewsUrl.searchParams.append("cursor", params.cursor);
        reviewsUrl.searchParams.append("review_type", params.review_type);
        reviewsUrl.searchParams.append("purchase_type", params.purchase_type);
        reviewsUrl.searchParams.append("num_per_page", params.num_per_page.toString());
        
        const reviewsResponse = await fetch(reviewsUrl, {
          headers: { "User-Agent": USER_AGENT }
        });
        
        if (!reviewsResponse.ok) {
          throw new Error(`Failed to fetch reviews: ${reviewsResponse.statusText}`);
        }
        
        const reviewsData = await reviewsResponse.json();
        
        // Extract required review information and review texts
        const game_reviews = {
          success: reviewsData.success,
          review_score: reviewsData.query_summary?.review_score,
          review_score_desc: reviewsData.query_summary?.review_score_desc,
          total_positive: reviewsData.query_summary?.total_positive,
          total_negative: reviewsData.query_summary?.total_negative,
          reviews: reviewsData.reviews ? reviewsData.reviews.map((review: any) => cleanReviewText(review.review)) : []
        };
        
        // Fetch game info
        const infoUrl = new URL("api/appdetails", STEAM_API_BASE);
        infoUrl.searchParams.append("appids", params.appid);
        
        const infoResponse = await fetch(infoUrl, {
          headers: { "User-Agent": USER_AGENT }
        });
        
        if (!infoResponse.ok) {
          throw new Error(`Failed to fetch game info: ${infoResponse.statusText}`);
        }
        
        const infoData = await infoResponse.json();
        
        // Extract required game information
        const game_info = {
          name: infoData[params.appid]?.data?.name,
          detailed_description: infoData[params.appid]?.data?.detailed_description
        };
        
        // To be compatible with models such as DeepSeek R1 and DeepSeek V3, convert the format
        const formattedJsonData = JSON.stringify({ game_reviews, game_info }, null, 2);
        
        return {
          content: [
            {
              type: "text",
              text: formattedJsonData
            }
          ]
        };
      } catch (error) {
        console.error(error);
        throw error;
      }
    }
  • Zod schema defining input parameters for the get_steam_review tool, including appid, filter, language, day_range, cursor, review_type, purchase_type, num_per_page.
    const SteamReviewParamsSchema = {
      appid: z.string().describe("Steam application ID"),
      filter: z.string().default("all").describe("recent: sorted by creation time, updated: sorted by last updated time,all: (default) sorted by helpfulness, with sliding windows based on day_range parameter, will always find results to return."),
      language: z.enum([
        "all", "arabic", "bulgarian", "schinese", "tchinese", "czech", "danish", 
        "dutch", "english", "finnish", "french", "german", "greek", "hungarian", 
        "indonesian", "italian", "japanese", "koreana", "norwegian", "polish", 
        "portuguese", "brazilian", "romanian", "russian", "spanish", "latam", 
        "swedish", "thai", "turkish", "ukrainian", "vietnamese"
      ]).default("all").describe("Language filter (e.g. english, french, schinese). Default is all languages."),
      day_range: z.number().default(365).describe("range from now to n days ago to look for helpful reviews. Only applicable for the all filter."),
      cursor: z.string().default("*").describe("reviews are returned in batches of 20, so pass * for the first set, then the value of cursor that was returned in the response for the next set, etc. Note that cursor values may contain characters that need to be URLEncoded for use in the querystring."),
      review_type: z.string().default("all").describe("all:all reviews (default), positive: only positive reviews, negative: only negative reviews"),
      purchase_type: z.string().default("steam").describe("all: all reviews, non_steam_purchase: reviews written by users who did not pay for the product on Steam,steam: reviews written by users who paid for the product on Steam (default)"),
      num_per_page: z.number().default(50).describe("number of reviews to get, max 100, default 50"),
    };
  • src/index.ts:65-138 (registration)
    Registers the 'get_steam_review' tool on the MCP server using server.tool(name, description, SteamReviewParamsSchema, handler).
    server.tool(
      "get_steam_review",
      "Retrieves reviews and game information for a specific Steam application. Returns formatted review data including review scores, positive/negative counts, review texts, and basic game information.",
      SteamReviewParamsSchema,
      async (params) => {
        try {
          // Fetch game reviews
          const reviewsUrl = new URL(`appreviews/${params.appid}`, STEAM_API_BASE);
          reviewsUrl.searchParams.append("json", "1");
          reviewsUrl.searchParams.append("filter", params.filter);
          reviewsUrl.searchParams.append("language", params.language);
          reviewsUrl.searchParams.append("day_range", params.day_range.toString());
          reviewsUrl.searchParams.append("cursor", params.cursor);
          reviewsUrl.searchParams.append("review_type", params.review_type);
          reviewsUrl.searchParams.append("purchase_type", params.purchase_type);
          reviewsUrl.searchParams.append("num_per_page", params.num_per_page.toString());
          
          const reviewsResponse = await fetch(reviewsUrl, {
            headers: { "User-Agent": USER_AGENT }
          });
          
          if (!reviewsResponse.ok) {
            throw new Error(`Failed to fetch reviews: ${reviewsResponse.statusText}`);
          }
          
          const reviewsData = await reviewsResponse.json();
          
          // Extract required review information and review texts
          const game_reviews = {
            success: reviewsData.success,
            review_score: reviewsData.query_summary?.review_score,
            review_score_desc: reviewsData.query_summary?.review_score_desc,
            total_positive: reviewsData.query_summary?.total_positive,
            total_negative: reviewsData.query_summary?.total_negative,
            reviews: reviewsData.reviews ? reviewsData.reviews.map((review: any) => cleanReviewText(review.review)) : []
          };
          
          // Fetch game info
          const infoUrl = new URL("api/appdetails", STEAM_API_BASE);
          infoUrl.searchParams.append("appids", params.appid);
          
          const infoResponse = await fetch(infoUrl, {
            headers: { "User-Agent": USER_AGENT }
          });
          
          if (!infoResponse.ok) {
            throw new Error(`Failed to fetch game info: ${infoResponse.statusText}`);
          }
          
          const infoData = await infoResponse.json();
          
          // Extract required game information
          const game_info = {
            name: infoData[params.appid]?.data?.name,
            detailed_description: infoData[params.appid]?.data?.detailed_description
          };
          
          // To be compatible with models such as DeepSeek R1 and DeepSeek V3, convert the format
          const formattedJsonData = JSON.stringify({ game_reviews, game_info }, null, 2);
          
          return {
            content: [
              {
                type: "text",
                text: formattedJsonData
              }
            ]
          };
        } catch (error) {
          console.error(error);
          throw error;
        }
      }
    );
  • Helper function to clean and format review text: removes HTML tags, decodes entities, handles newlines, removes quotes, normalizes spaces. Used in handler to process review texts.
    function cleanReviewText(text: string): string {
      if (!text) return "";
      
      // Remove HTML tags
      let cleanText = text.replace(/<\/?[^>]+(>|$)/g, "");
      
      // Decode common HTML entities
      cleanText = cleanText.replace(/&/g, "&")
                           .replace(/</g, "<")
                           .replace(/>/g, ">")
                           .replace(/"/g, "")
                           .replace(/'/g, "")
                           .replace(/ /g, " ");
      
      // Handle newlines and other control characters
      cleanText = cleanText.replace(/\r\n/g, "\\n")
                           .replace(/\n/g, "\\n")
                           .replace(/\r/g, "\\n");
      
      // Remove quotes
      cleanText = cleanText.replace(/["']/g, "");
      
      // Replace multiple spaces with a single space
      cleanText = cleanText.replace(/\s+/g, " ");
      
      // Trim extra spaces
      return cleanText.trim();
    }
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions that the tool 'returns formatted review data' including specific elements like scores and texts, which is helpful. However, it lacks critical behavioral details such as rate limits, authentication requirements, error conditions, or whether this is a read-only operation (though 'retrieves' implies it).

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

Conciseness4/5

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

The description is appropriately concise with two sentences that efficiently convey the purpose and return value. The first sentence states what the tool does, and the second describes the return format. There's no unnecessary repetition or verbose language, though it could be slightly more structured with explicit sections.

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

Completeness3/5

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

Given the tool's moderate complexity (8 parameters, no output schema, no annotations), the description is minimally adequate. It covers the basic purpose and return format but lacks important contextual information about behavioral traits, error handling, and usage scenarios. The absence of an output schema means the description should ideally explain the return structure more thoroughly.

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

Parameters3/5

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

The schema description coverage is 100%, meaning all parameters are well-documented in the schema itself. The description adds minimal value beyond the schema by mentioning 'basic game information' which isn't explicitly in the parameter documentation, but doesn't provide additional parameter context or usage examples. This meets the baseline for high schema coverage.

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

Purpose4/5

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

The description clearly states the tool's purpose: retrieving reviews and game information for a specific Steam application. It specifies the verb 'retrieves' and resource 'reviews and game information', and distinguishes the scope with 'for a specific Steam application'. However, it doesn't differentiate from siblings since none exist, preventing a perfect score.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. There are no explicit statements about appropriate contexts, prerequisites, or exclusions. While no sibling tools exist, the description fails to mention any usage scenarios or constraints beyond what's implied by the purpose.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/fenxer/steam-review-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server