steam-review-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 fenx
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # Steam Review MCP
2
+
3
+ **English** | [中文](./README.zh.md)
4
+
5
+ Access Steam game reviews using Model Context Protocol (MCP).
6
+
7
+ ## Features
8
+
9
+ Helps LLMs retrieve Steam game reviews and information:
10
+
11
+ - Get game reviews (positive/negative counts, review scores, review content, etc.)
12
+ - Get game basic information (name, detailed description)
13
+ - Analyze game reviews and summarize pros and cons
14
+
15
+ ## Installation
16
+
17
+ Or run it directly with npx:
18
+
19
+ ```bash
20
+ npx steam-review-mcp
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ### Tools
26
+
27
+ This MCP service provides the `get_steam_review` tool, which retrieves reviews and game information by passing a Steam game appid.
28
+
29
+ For more details, check the Steamwork API: [User Reviews - Get List](https://partner.steamgames.com/doc/store/getreviews)
30
+
31
+ The returned data contains two parts:
32
+
33
+ 1. `game_reviews`:
34
+ - `success`: Whether the query was successful
35
+ - `review_score`: Review score
36
+ - `review_score_desc`: Review score description
37
+ - `total_positive`: Total positive reviews
38
+ - `total_negative`: Total negative reviews
39
+ - `reviews`: All review text content (without other metadata)
40
+
41
+ 2. `game_info`:
42
+ - `name`: Game name
43
+ - `detailed_description`: Detailed game description
44
+
45
+ ### Prompts
46
+
47
+ #### summarize-reviews
48
+
49
+ For overall game review analysis, summarizing the pros and cons of the game.
50
+
51
+ ##### Parameters
52
+
53
+ - `appid` (required): Steam game ID, e.g., `570` (Dota 2)
54
+
55
+
56
+ #### recent-reviews-analysis
57
+
58
+ For analyzing recent game reviews, summarizing the current state of the game and player feedback.
59
+
60
+ ##### Parameters
61
+
62
+ - `appid` (required): Steam game ID, e.g., `570` (Dota 2)
63
+
64
+
65
+ ## Development
66
+
67
+ ```bash
68
+ # Install dependencies
69
+ npm install
70
+
71
+ # Build project
72
+ npm run build
73
+
74
+ # Run service
75
+ npm start
76
+ ```
package/README.zh.md ADDED
@@ -0,0 +1,76 @@
1
+ # Steam Review MCP
2
+
3
+ [English](./README.md) | **中文**
4
+
5
+ 使用 Model Context Protocol (MCP) 获取 Steam 游戏评测。
6
+
7
+ ## 功能
8
+
9
+ 帮助 LLM 获取 Steam 游戏的评测和游戏信息:
10
+
11
+ - 获取游戏评测(正面/负面评价数量、评测分数、评测内容等)
12
+ - 获取游戏基本信息(名称、详细描述)
13
+ - 分析游戏评测,总结游戏的优缺点
14
+
15
+ ## 安装
16
+
17
+ 或者直接使用 npx 运行:
18
+
19
+ ```bash
20
+ npx steam-review-mcp
21
+ ```
22
+
23
+ ## 使用方法
24
+
25
+ ### 工具 (Tools)
26
+
27
+ 这个 MCP 服务提供了 `get_steam_review` 工具,可以通过传入 Steam 游戏的 appid 来获取评测和游戏信息。
28
+
29
+ 详细可查看 Steamwork API: [User Reviews - Get List](https://partner.steamgames.com/doc/store/getreviews)
30
+
31
+ 返回的数据包含两部分:
32
+
33
+ 1. `game_reviews`:
34
+ - `success`:查询是否成功
35
+ - `review_score`:评测分数
36
+ - `review_score_desc`:评测分数描述
37
+ - `total_positive`:正面评测总数
38
+ - `total_negative`:负面评测总数
39
+ - `reviews`:所有评测的文本内容(不包含其他元数据)
40
+
41
+ 2. `game_info`:
42
+ - `name`:游戏名称
43
+ - `detailed_description`:游戏详细描述
44
+
45
+ ### 提示模板 (Prompts)
46
+
47
+ #### summarize-reviews
48
+
49
+ 用于游戏的整体分析游戏评测,总结游戏的优缺点。
50
+
51
+ ##### 参数
52
+
53
+ - `appid`(必需):Steam 游戏的 ID,例如 `570`(Dota 2)
54
+
55
+
56
+ #### recent-reviews-analysis
57
+
58
+ 用于分析游戏的最近评测,总结游戏的当前状态和玩家反馈。
59
+
60
+ ##### 参数
61
+
62
+ - `appid`(必需):Steam 游戏的 ID,例如 `570`(Dota 2)
63
+
64
+
65
+ ## 开发
66
+
67
+ ```bash
68
+ # 安装依赖
69
+ npm install
70
+
71
+ # 构建项目
72
+ npm run build
73
+
74
+ # 运行服务
75
+ npm start
76
+ ```
package/build/index.js ADDED
@@ -0,0 +1,272 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ const STEAM_API_BASE = "https://store.steampowered.com/";
6
+ const USER_AGENT = "steam-mcp/1.0";
7
+ // Helper function to clean and format review text for JSON
8
+ function cleanReviewText(text) {
9
+ if (!text)
10
+ return "";
11
+ // Remove HTML tags
12
+ let cleanText = text.replace(/<\/?[^>]+(>|$)/g, "");
13
+ // Decode common HTML entities
14
+ cleanText = cleanText.replace(/&amp;/g, "&")
15
+ .replace(/&lt;/g, "<")
16
+ .replace(/&gt;/g, ">")
17
+ .replace(/&quot;/g, "")
18
+ .replace(/&#39;/g, "")
19
+ .replace(/&nbsp;/g, " ");
20
+ // Handle newlines and other control characters
21
+ cleanText = cleanText.replace(/\r\n/g, "\\n")
22
+ .replace(/\n/g, "\\n")
23
+ .replace(/\r/g, "\\n");
24
+ // Remove quotes
25
+ cleanText = cleanText.replace(/["']/g, "");
26
+ // Replace multiple spaces with a single space
27
+ cleanText = cleanText.replace(/\s+/g, " ");
28
+ // Trim extra spaces
29
+ return cleanText.trim();
30
+ }
31
+ // Create server instance
32
+ const server = new McpServer({
33
+ name: "steam-review-mcp",
34
+ version: "1.0.0",
35
+ });
36
+ // Define the schema for the input parameters
37
+ const SteamReviewParamsSchema = {
38
+ appid: z.string().describe("Steam application ID"),
39
+ 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."),
40
+ language: z.enum([
41
+ "all", "arabic", "bulgarian", "schinese", "tchinese", "czech", "danish",
42
+ "dutch", "english", "finnish", "french", "german", "greek", "hungarian",
43
+ "indonesian", "italian", "japanese", "koreana", "norwegian", "polish",
44
+ "portuguese", "brazilian", "romanian", "russian", "spanish", "latam",
45
+ "swedish", "thai", "turkish", "ukrainian", "vietnamese"
46
+ ]).default("all").describe("Language filter (e.g. english, french, schinese). Default is all languages."),
47
+ 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."),
48
+ 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."),
49
+ review_type: z.string().default("all").describe("all:all reviews (default), positive: only positive reviews, negative: only negative reviews"),
50
+ 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)"),
51
+ num_per_page: z.number().default(50).describe("number of reviews to get, max 100, default 50"),
52
+ };
53
+ // Add the tool to get steam reviews
54
+ server.tool("get_steam_review", SteamReviewParamsSchema, async (params) => {
55
+ try {
56
+ // Fetch game reviews
57
+ const reviewsUrl = new URL(`appreviews/${params.appid}`, STEAM_API_BASE);
58
+ reviewsUrl.searchParams.append("json", "1");
59
+ reviewsUrl.searchParams.append("filter", params.filter);
60
+ reviewsUrl.searchParams.append("language", params.language);
61
+ reviewsUrl.searchParams.append("day_range", params.day_range.toString());
62
+ reviewsUrl.searchParams.append("cursor", params.cursor);
63
+ reviewsUrl.searchParams.append("review_type", params.review_type);
64
+ reviewsUrl.searchParams.append("purchase_type", params.purchase_type);
65
+ reviewsUrl.searchParams.append("num_per_page", params.num_per_page.toString());
66
+ const reviewsResponse = await fetch(reviewsUrl, {
67
+ headers: { "User-Agent": USER_AGENT }
68
+ });
69
+ if (!reviewsResponse.ok) {
70
+ throw new Error(`Failed to fetch reviews: ${reviewsResponse.statusText}`);
71
+ }
72
+ const reviewsData = await reviewsResponse.json();
73
+ // Extract required review information and review texts
74
+ const game_reviews = {
75
+ success: reviewsData.success,
76
+ review_score: reviewsData.query_summary?.review_score,
77
+ review_score_desc: reviewsData.query_summary?.review_score_desc,
78
+ total_positive: reviewsData.query_summary?.total_positive,
79
+ total_negative: reviewsData.query_summary?.total_negative,
80
+ reviews: reviewsData.reviews ? reviewsData.reviews.map((review) => cleanReviewText(review.review)) : []
81
+ };
82
+ // Fetch game info
83
+ const infoUrl = new URL("api/appdetails", STEAM_API_BASE);
84
+ infoUrl.searchParams.append("appids", params.appid);
85
+ const infoResponse = await fetch(infoUrl, {
86
+ headers: { "User-Agent": USER_AGENT }
87
+ });
88
+ if (!infoResponse.ok) {
89
+ throw new Error(`Failed to fetch game info: ${infoResponse.statusText}`);
90
+ }
91
+ const infoData = await infoResponse.json();
92
+ // Extract required game information
93
+ const game_info = {
94
+ name: infoData[params.appid]?.data?.name,
95
+ detailed_description: infoData[params.appid]?.data?.detailed_description
96
+ };
97
+ // Return combined result in the format expected by MCP
98
+ return {
99
+ content: [
100
+ {
101
+ type: "text",
102
+ text: JSON.stringify({ game_reviews, game_info }, null, 2)
103
+ }
104
+ ]
105
+ };
106
+ }
107
+ catch (error) {
108
+ console.error(error);
109
+ throw error;
110
+ }
111
+ });
112
+ // Add prompt for analyzing reviews
113
+ server.prompt("summarize-reviews", { appid: z.string().describe("Steam application ID") }, async ({ appid }) => {
114
+ try {
115
+ // Fetch game reviews and info
116
+ const reviewsUrl = new URL(`appreviews/${appid}`, STEAM_API_BASE);
117
+ reviewsUrl.searchParams.append("json", "1");
118
+ reviewsUrl.searchParams.append("filter", "all");
119
+ reviewsUrl.searchParams.append("language", "all");
120
+ reviewsUrl.searchParams.append("day_range", "365");
121
+ reviewsUrl.searchParams.append("cursor", "*");
122
+ reviewsUrl.searchParams.append("review_type", "all");
123
+ reviewsUrl.searchParams.append("purchase_type", "all");
124
+ reviewsUrl.searchParams.append("num_per_page", "50");
125
+ const reviewsResponse = await fetch(reviewsUrl, {
126
+ headers: { "User-Agent": USER_AGENT }
127
+ });
128
+ if (!reviewsResponse.ok) {
129
+ throw new Error(`Failed to fetch reviews: ${reviewsResponse.statusText}`);
130
+ }
131
+ const reviewsData = await reviewsResponse.json();
132
+ // Extract required review information and review texts
133
+ const game_reviews = {
134
+ success: reviewsData.success,
135
+ review_score: reviewsData.query_summary?.review_score,
136
+ review_score_desc: reviewsData.query_summary?.review_score_desc,
137
+ total_positive: reviewsData.query_summary?.total_positive,
138
+ total_negative: reviewsData.query_summary?.total_negative,
139
+ reviews: reviewsData.reviews ? reviewsData.reviews.map((review) => cleanReviewText(review.review)) : []
140
+ };
141
+ // Fetch game info
142
+ const infoUrl = new URL("api/appdetails", STEAM_API_BASE);
143
+ infoUrl.searchParams.append("appids", appid);
144
+ const infoResponse = await fetch(infoUrl, {
145
+ headers: { "User-Agent": USER_AGENT }
146
+ });
147
+ if (!infoResponse.ok) {
148
+ throw new Error(`Failed to fetch game info: ${infoResponse.statusText}`);
149
+ }
150
+ const infoData = await infoResponse.json();
151
+ // Extract required game information
152
+ const game_info = {
153
+ name: infoData[appid]?.data?.name,
154
+ detailed_description: infoData[appid]?.data?.detailed_description
155
+ };
156
+ // Return prompt with game data
157
+ return {
158
+ messages: [{
159
+ role: "user",
160
+ content: {
161
+ type: "text",
162
+ text: `You are an experienced video game industry professional and game developer who has played many games on Steam. You are skilled at summarizing a game's **pros** and **cons** from game reviews {{game_reviews}} combined with game descriptions {{game_info}}. List them in an unordered list format.
163
+ ====
164
+ # Features
165
+ - Don't extract too much information from a single review; try to summarize from **multiple reviews and multiple perspectives**.
166
+ - **Don't include too much game introduction content**; focus on finding common points in each review as game features.
167
+ - **Don't just summarize the game description content**; extract pros and cons from the reviews, keeping the content relevant.
168
+ ====
169
+ # Format
170
+ Pros:
171
+ - Pro 1
172
+ - Pro 2
173
+ Cons:
174
+ - Con 1
175
+ - Con 2
176
+ The unordered list format should be arranged from top to bottom according to the **number of times each pro or con is mentioned**.
177
+
178
+ Game Info: ${JSON.stringify(game_info, null, 2)}
179
+ Game Reviews: ${JSON.stringify(game_reviews.reviews, null, 2)}`
180
+ }
181
+ }]
182
+ };
183
+ }
184
+ catch (error) {
185
+ console.error(error);
186
+ throw error;
187
+ }
188
+ });
189
+ // Add prompt for analyzing recent reviews
190
+ server.prompt("recent-reviews-analysis", { appid: z.string().describe("Steam application ID") }, async ({ appid }) => {
191
+ try {
192
+ // Fetch game reviews and info
193
+ const reviewsUrl = new URL(`appreviews/${appid}`, STEAM_API_BASE);
194
+ reviewsUrl.searchParams.append("json", "1");
195
+ reviewsUrl.searchParams.append("filter", "recent");
196
+ reviewsUrl.searchParams.append("language", "all");
197
+ reviewsUrl.searchParams.append("day_range", "365");
198
+ reviewsUrl.searchParams.append("cursor", "*");
199
+ reviewsUrl.searchParams.append("review_type", "all");
200
+ reviewsUrl.searchParams.append("purchase_type", "all");
201
+ reviewsUrl.searchParams.append("num_per_page", "50");
202
+ const reviewsResponse = await fetch(reviewsUrl, {
203
+ headers: { "User-Agent": USER_AGENT }
204
+ });
205
+ if (!reviewsResponse.ok) {
206
+ throw new Error(`Failed to fetch reviews: ${reviewsResponse.statusText}`);
207
+ }
208
+ const reviewsData = await reviewsResponse.json();
209
+ // Extract required review information and review texts
210
+ const game_reviews = {
211
+ success: reviewsData.success,
212
+ review_score: reviewsData.query_summary?.review_score,
213
+ review_score_desc: reviewsData.query_summary?.review_score_desc,
214
+ total_positive: reviewsData.query_summary?.total_positive,
215
+ total_negative: reviewsData.query_summary?.total_negative,
216
+ reviews: reviewsData.reviews ? reviewsData.reviews.map((review) => cleanReviewText(review.review)) : []
217
+ };
218
+ // Fetch game info
219
+ const infoUrl = new URL("api/appdetails", STEAM_API_BASE);
220
+ infoUrl.searchParams.append("appids", appid);
221
+ const infoResponse = await fetch(infoUrl, {
222
+ headers: { "User-Agent": USER_AGENT }
223
+ });
224
+ if (!infoResponse.ok) {
225
+ throw new Error(`Failed to fetch game info: ${infoResponse.statusText}`);
226
+ }
227
+ const infoData = await infoResponse.json();
228
+ // Extract required game information
229
+ const game_info = {
230
+ name: infoData[appid]?.data?.name,
231
+ detailed_description: infoData[appid]?.data?.detailed_description
232
+ };
233
+ // Return prompt with game data
234
+ return {
235
+ messages: [{
236
+ role: "user",
237
+ content: {
238
+ type: "text",
239
+ text: `You are an experienced video game industry professional and game developer who has played many games on Steam. You are skilled at summarizing a game's **recent performance and player feedback** from the most recent game reviews {{game_reviews}} combined with game descriptions {{game_info}}. List them in an unordered list format.
240
+ ====
241
+ # Features
242
+ - Don't extract too much information from a single review; try to summarize from **multiple reviews and multiple perspectives**.
243
+ - **Don't include too much game introduction content**; focus on finding common points in each review as game features.
244
+ - **Don't just summarize the game description content**; extract pros and cons from the reviews, keeping the content relevant.
245
+ - Specifically focus on **recent changes, updates, and current player sentiment**.
246
+ ====
247
+ # Format
248
+ Pros:
249
+ - Pro 1
250
+ - Pro 2
251
+ Cons:
252
+ - Con 1
253
+ - Con 2
254
+ Current Player Sentiment:
255
+ - Key point about current state of the game
256
+ The unordered list format should be arranged from top to bottom according to the **number of times each point is mentioned**.
257
+
258
+ Game Info: ${JSON.stringify(game_info, null, 2)}
259
+ Game Reviews: ${JSON.stringify(game_reviews.reviews, null, 2)}`
260
+ }
261
+ }]
262
+ };
263
+ }
264
+ catch (error) {
265
+ console.error(error);
266
+ throw error;
267
+ }
268
+ });
269
+ // Start the server
270
+ const transport = new StdioServerTransport();
271
+ server.connect(transport).catch(console.error);
272
+ console.log("Steam Review MCP Server started");
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "steam-review-mcp",
3
+ "version": "1.0.0",
4
+ "description": "Get reviews from steam store with appid",
5
+ "main": "build/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "steam-review-mcp": "./build/index.js"
9
+ },
10
+ "scripts": {
11
+ "test": "echo \"Error: no test specified\" && exit 1",
12
+ "build": "tsc",
13
+ "start": "node build/index.js",
14
+ "dev": "tsc && node build/index.js",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/fenxer/steam-review-mcp.git"
20
+ },
21
+ "keywords": [
22
+ "mcp",
23
+ "steam",
24
+ "review",
25
+ "modelcontextprotocol"
26
+ ],
27
+ "author": "",
28
+ "license": "ISC",
29
+ "bugs": {
30
+ "url": "https://github.com/fenxer/steam-review-mcp/issues"
31
+ },
32
+ "homepage": "https://github.com/fenxer/steam-review-mcp#readme",
33
+ "dependencies": {
34
+ "@modelcontextprotocol/sdk": "^1.7.0",
35
+ "zod": "^3.24.2"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^22.13.10",
39
+ "typescript": "^5.8.2"
40
+ },
41
+ "files": [
42
+ "build/**/*"
43
+ ],
44
+ "engines": {
45
+ "node": ">=16.0.0"
46
+ }
47
+ }