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 +21 -0
- package/README.md +76 -0
- package/README.zh.md +76 -0
- package/build/index.js +272 -0
- package/package.json +47 -0
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(/&/g, "&")
|
|
15
|
+
.replace(/</g, "<")
|
|
16
|
+
.replace(/>/g, ">")
|
|
17
|
+
.replace(/"/g, "")
|
|
18
|
+
.replace(/'/g, "")
|
|
19
|
+
.replace(/ /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
|
+
}
|