@witchpot/steamboard-mcp 0.1.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/CHANGELOG.md +30 -0
- package/LICENSE +21 -0
- package/README.md +282 -0
- package/build/clients/steam-api-client.d.ts +112 -0
- package/build/clients/steam-api-client.d.ts.map +1 -0
- package/build/clients/steam-api-client.js +171 -0
- package/build/clients/steam-api-client.js.map +1 -0
- package/build/clients/types.d.ts +174 -0
- package/build/clients/types.d.ts.map +1 -0
- package/build/clients/types.js +5 -0
- package/build/clients/types.js.map +1 -0
- package/build/index.d.ts +7 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +176 -0
- package/build/index.js.map +1 -0
- package/build/tools/analyze-related-tags.d.ts +39 -0
- package/build/tools/analyze-related-tags.d.ts.map +1 -0
- package/build/tools/analyze-related-tags.js +114 -0
- package/build/tools/analyze-related-tags.js.map +1 -0
- package/build/tools/analyze-tag-combinations.d.ts +54 -0
- package/build/tools/analyze-tag-combinations.d.ts.map +1 -0
- package/build/tools/analyze-tag-combinations.js +73 -0
- package/build/tools/analyze-tag-combinations.js.map +1 -0
- package/build/tools/find-similar-games.d.ts +30 -0
- package/build/tools/find-similar-games.d.ts.map +1 -0
- package/build/tools/find-similar-games.js +72 -0
- package/build/tools/find-similar-games.js.map +1 -0
- package/build/tools/get-app-snapshots.d.ts +27 -0
- package/build/tools/get-app-snapshots.d.ts.map +1 -0
- package/build/tools/get-app-snapshots.js +54 -0
- package/build/tools/get-app-snapshots.js.map +1 -0
- package/build/tools/get-review-growth.d.ts +42 -0
- package/build/tools/get-review-growth.d.ts.map +1 -0
- package/build/tools/get-review-growth.js +78 -0
- package/build/tools/get-review-growth.js.map +1 -0
- package/build/tools/index.d.ts +10 -0
- package/build/tools/index.d.ts.map +1 -0
- package/build/tools/index.js +10 -0
- package/build/tools/index.js.map +1 -0
- package/build/tools/search-games.d.ts +63 -0
- package/build/tools/search-games.d.ts.map +1 -0
- package/build/tools/search-games.js +92 -0
- package/build/tools/search-games.js.map +1 -0
- package/package.json +52 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2025-02-14
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release
|
|
12
|
+
- `search_games` tool - Search Steam games with advanced filters
|
|
13
|
+
- Filter by tags, price range, review count, ratings
|
|
14
|
+
- Support for release date filtering
|
|
15
|
+
- Flexible sorting options
|
|
16
|
+
- `analyze_tag_combinations` tool - Analyze tag combinations for market research
|
|
17
|
+
- Group by primary tag, tag pairs, or tag triples
|
|
18
|
+
- Calculate success rates with custom criteria
|
|
19
|
+
- Identify oversaturated/undersaturated markets
|
|
20
|
+
- `find_similar_games` tool - Find games similar to a specific title
|
|
21
|
+
- Tag-based similarity scoring
|
|
22
|
+
- Configurable generic tag exclusion
|
|
23
|
+
- Minimum review filtering
|
|
24
|
+
- `analyze_related_tags` tool - Analyze tag co-occurrence patterns
|
|
25
|
+
- Find tags that complement a given tag set
|
|
26
|
+
- Calculate success rate impact (delta)
|
|
27
|
+
- Discover differentiation opportunities
|
|
28
|
+
|
|
29
|
+
### Notes
|
|
30
|
+
- Time-series analysis tools (`get_app_snapshots`, `get_review_growth`) are temporarily disabled pending sufficient historical data collection
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Witchpot Studio
|
|
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,282 @@
|
|
|
1
|
+
# @witchpot/steamboard-mcp
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@witchpot/steamboard-mcp)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
A Model Context Protocol (MCP) server for Steam game market research and analytics. This server provides AI assistants with tools to search Steam games, analyze tag combinations, find similar games, and discover related tags.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **search_games** - Search Steam games with advanced filters (tags, price, reviews, ratings, release date)
|
|
11
|
+
- **analyze_tag_combinations** - Discover successful niche markets and identify oversaturated/undersaturated genre combinations
|
|
12
|
+
- **find_similar_games** - Find games similar to a specific title based on tag matching
|
|
13
|
+
- **analyze_related_tags** - Discover which tags work well together and their impact on success rates
|
|
14
|
+
|
|
15
|
+
## Design Philosophy
|
|
16
|
+
|
|
17
|
+
This MCP exposes **absolute value parameters** (reviewsMin, priceMax, etc.) rather than predefined buckets. This allows AI agents to define their own criteria based on context, user preferences, and domain knowledge.
|
|
18
|
+
|
|
19
|
+
## Requirements
|
|
20
|
+
|
|
21
|
+
- Node.js >= 18.0.0
|
|
22
|
+
- Access to a SteamDashboard API instance (provides the underlying data)
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
### Using npx (Recommended)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx @witchpot/steamboard-mcp
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Global Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install -g @witchpot/steamboard-mcp
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Local Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install @witchpot/steamboard-mcp
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Configuration
|
|
45
|
+
|
|
46
|
+
The server requires the following environment variables:
|
|
47
|
+
|
|
48
|
+
| Variable | Required | Default | Description |
|
|
49
|
+
|----------|----------|---------|-------------|
|
|
50
|
+
| `STEAM_DASHBOARD_API_KEY` | Yes | - | API key for SteamDashboard authentication |
|
|
51
|
+
| `STEAM_DASHBOARD_API_URL` | No | `http://localhost:3001` | SteamDashboard API base URL |
|
|
52
|
+
|
|
53
|
+
## Usage with Claude Desktop
|
|
54
|
+
|
|
55
|
+
Add the following to your Claude Desktop configuration file:
|
|
56
|
+
|
|
57
|
+
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
58
|
+
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"mcpServers": {
|
|
63
|
+
"steamboard": {
|
|
64
|
+
"command": "npx",
|
|
65
|
+
"args": ["-y", "@witchpot/steamboard-mcp"],
|
|
66
|
+
"env": {
|
|
67
|
+
"STEAM_DASHBOARD_API_URL": "https://your-steamdashboard-api.com",
|
|
68
|
+
"STEAM_DASHBOARD_API_KEY": "your-api-key"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Usage with Claude Code
|
|
76
|
+
|
|
77
|
+
Add to your project's `.mcp.json`:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"mcpServers": {
|
|
82
|
+
"steamboard": {
|
|
83
|
+
"type": "stdio",
|
|
84
|
+
"command": "npx",
|
|
85
|
+
"args": ["-y", "@witchpot/steamboard-mcp"],
|
|
86
|
+
"env": {
|
|
87
|
+
"STEAM_DASHBOARD_API_URL": "https://your-steamdashboard-api.com",
|
|
88
|
+
"STEAM_DASHBOARD_API_KEY": "your-api-key"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Available Tools
|
|
96
|
+
|
|
97
|
+
### search_games
|
|
98
|
+
|
|
99
|
+
Search Steam games with advanced filters including tags, price ranges, review counts, ratings, and scale buckets.
|
|
100
|
+
|
|
101
|
+
**Parameters:**
|
|
102
|
+
| Parameter | Type | Description |
|
|
103
|
+
|-----------|------|-------------|
|
|
104
|
+
| `tags` | string[] | Filter by Steam tags (e.g., ["roguelike", "action"]) |
|
|
105
|
+
| `tagMode` | "and" \| "or" | Tag matching mode (default: "and") |
|
|
106
|
+
| `minReviews` / `maxReviews` | number | Review count range |
|
|
107
|
+
| `minRating` / `maxRating` | number | Rating percentage range (0-100) |
|
|
108
|
+
| `minPrice` / `maxPrice` | number | Price range in cents |
|
|
109
|
+
| `popularityBuckets` | string[] | Filter by popularity tier |
|
|
110
|
+
| `productionBuckets` | string[] | Filter by production scale |
|
|
111
|
+
| `releasedAfter` / `releasedBefore` | string | Release date range (YYYY-MM-DD) |
|
|
112
|
+
| `sort` | string | Sort order (reviews_desc, rating_desc, price_asc, etc.) |
|
|
113
|
+
| `limit` | number | Max results (default: 20, max: 100) |
|
|
114
|
+
|
|
115
|
+
**Example:**
|
|
116
|
+
```
|
|
117
|
+
Search for roguelike action games with at least 1000 reviews
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
### analyze_tag_combinations
|
|
123
|
+
|
|
124
|
+
Analyze tag combinations to discover successful niche markets and identify oversaturated/undersaturated genre combinations.
|
|
125
|
+
|
|
126
|
+
**Parameters:**
|
|
127
|
+
| Parameter | Type | Description |
|
|
128
|
+
|-----------|------|-------------|
|
|
129
|
+
| `groupBy` | string | **Required.** Grouping: "primary_tag", "tag_pair", "tag_triple" |
|
|
130
|
+
| `tags` | string[] | Filter to combinations containing these tags |
|
|
131
|
+
| `tagMode` | "and" \| "or" | Tag matching mode |
|
|
132
|
+
| `popularityBuckets` | string[] | Filter by popularity tier |
|
|
133
|
+
| `productionBuckets` | string[] | Filter by production scale |
|
|
134
|
+
| `minReviews` | number | Minimum reviews for inclusion |
|
|
135
|
+
| `ratingMin` | number | Minimum rating for inclusion |
|
|
136
|
+
| `successReviewsMin` | number | Reviews threshold for "success" |
|
|
137
|
+
| `successRatingMin` | number | Rating threshold for "success" |
|
|
138
|
+
| `limit` | number | Max results (default: 20, max: 100) |
|
|
139
|
+
|
|
140
|
+
**Example:**
|
|
141
|
+
```
|
|
142
|
+
Analyze tag pairs containing "roguelike" to find underserved niches
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
### find_similar_games
|
|
148
|
+
|
|
149
|
+
Find games similar to a specific game based on tag matching. Returns games sorted by similarity score (tag overlap).
|
|
150
|
+
|
|
151
|
+
**Parameters:**
|
|
152
|
+
| Parameter | Type | Description |
|
|
153
|
+
|-----------|------|-------------|
|
|
154
|
+
| `appid` | number | **Required.** Steam App ID of the base game |
|
|
155
|
+
| `limit` | number | Max results (default: 20, max: 100) |
|
|
156
|
+
| `excludeGeneric` | boolean | Exclude generic tags from calculation (default: true) |
|
|
157
|
+
| `minReviews` | number | Minimum reviews for similar games (default: 0) |
|
|
158
|
+
|
|
159
|
+
**Example:**
|
|
160
|
+
```
|
|
161
|
+
Find games similar to Hades (appid: 1145360)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
### analyze_related_tags
|
|
167
|
+
|
|
168
|
+
Analyze tag co-occurrence to find tags that work well with a given tag set. Shows which tags appear frequently with your base tags and how they affect success rate.
|
|
169
|
+
|
|
170
|
+
**Parameters:**
|
|
171
|
+
| Parameter | Type | Description |
|
|
172
|
+
|-----------|------|-------------|
|
|
173
|
+
| `baseTags` | string[] | **Required.** Base tags to analyze (e.g., ["roguelike", "action"]) |
|
|
174
|
+
| `baseTagMode` | "and" \| "or" | Tag matching mode for base tags (default: "and") |
|
|
175
|
+
| `excludeGeneric` | boolean | Exclude generic tags from results (default: true) |
|
|
176
|
+
| `minCoOccurrence` | number | Minimum games with the related tag (default: 5) |
|
|
177
|
+
| `successReviewsMin` | number | Reviews threshold for "success" |
|
|
178
|
+
| `successRatingMin` | number | Rating threshold for "success" |
|
|
179
|
+
| `limit` | number | Max results (default: 30, max: 100) |
|
|
180
|
+
|
|
181
|
+
**Response includes:**
|
|
182
|
+
- `co_occurrence_rate` - How often this tag appears with base tags
|
|
183
|
+
- `success_rate` - Success rate of games with base tags + this tag
|
|
184
|
+
- `success_rate_delta` - Change in success rate when adding this tag
|
|
185
|
+
|
|
186
|
+
**Example:**
|
|
187
|
+
```
|
|
188
|
+
What tags work well with "roguelike + action"?
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Recommended Thresholds
|
|
192
|
+
|
|
193
|
+
Since this MCP uses absolute values, here are recommended thresholds that agents can use as guidelines:
|
|
194
|
+
|
|
195
|
+
### Popularity (by review count)
|
|
196
|
+
| Category | Review Count | Description |
|
|
197
|
+
|----------|-------------|-------------|
|
|
198
|
+
| Niche/New | 0-100 | Recently released or very niche |
|
|
199
|
+
| Small | 100-1,000 | Small but established audience |
|
|
200
|
+
| Medium | 1,000-10,000 | Growing audience |
|
|
201
|
+
| Popular | 10,000-100,000 | Well-known games |
|
|
202
|
+
| Massive | 100,000+ | Mainstream hits |
|
|
203
|
+
|
|
204
|
+
### Production Scale (by price in USD)
|
|
205
|
+
| Category | Price Range | Description |
|
|
206
|
+
|----------|-------------|-------------|
|
|
207
|
+
| F2P | $0 | Free-to-play |
|
|
208
|
+
| Indie | $0.01-25 | Small team / solo dev |
|
|
209
|
+
| AA | $25-50 | Mid-size studio |
|
|
210
|
+
| AAA | $50+ | Large studio |
|
|
211
|
+
|
|
212
|
+
### Success Criteria
|
|
213
|
+
| Level | Reviews | Rating | Description |
|
|
214
|
+
|-------|---------|--------|-------------|
|
|
215
|
+
| Minimum Viable | 500+ | 70%+ | Has some traction |
|
|
216
|
+
| Successful | 1,000+ | 80%+ | Clearly successful |
|
|
217
|
+
| Hit | 10,000+ | 85%+ | Major success |
|
|
218
|
+
|
|
219
|
+
## Use Cases
|
|
220
|
+
|
|
221
|
+
### For Game Developers
|
|
222
|
+
|
|
223
|
+
- **Market Research**: Identify underserved niches with high success rates
|
|
224
|
+
- **Competitive Analysis**: Find similar games to understand your competition
|
|
225
|
+
- **Tag Optimization**: Discover which tag combinations lead to better visibility and success
|
|
226
|
+
- **Trend Analysis**: Explore popular and emerging genre combinations
|
|
227
|
+
|
|
228
|
+
### For Market Analysts
|
|
229
|
+
|
|
230
|
+
- **Genre Mapping**: Understand the Steam game landscape by tag combinations
|
|
231
|
+
- **Success Patterns**: Identify what makes games successful in specific niches
|
|
232
|
+
- **Market Gaps**: Find opportunities in undersaturated markets
|
|
233
|
+
|
|
234
|
+
## Architecture
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
AI Agent (Claude / other LLMs)
|
|
238
|
+
↓
|
|
239
|
+
MCP Protocol (stdio)
|
|
240
|
+
↓
|
|
241
|
+
@witchpot/steamboard-mcp (this package)
|
|
242
|
+
↓
|
|
243
|
+
SteamDashboard REST API
|
|
244
|
+
↓
|
|
245
|
+
Supabase (PostgreSQL)
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## API Backend
|
|
249
|
+
|
|
250
|
+
This MCP server requires a running instance of SteamDashboard API. The SteamDashboard is a separate service that:
|
|
251
|
+
|
|
252
|
+
- Collects and stores Steam game data via ETL pipeline
|
|
253
|
+
- Provides REST API endpoints for game search and analysis
|
|
254
|
+
- Maintains daily snapshots for time-series analysis
|
|
255
|
+
|
|
256
|
+
Contact Witchpot Studio for API access or self-hosting options.
|
|
257
|
+
|
|
258
|
+
## Troubleshooting
|
|
259
|
+
|
|
260
|
+
### "STEAM_DASHBOARD_API_KEY environment variable is required"
|
|
261
|
+
Set the API key in your environment or MCP configuration.
|
|
262
|
+
|
|
263
|
+
### "Steamboard API error (401)"
|
|
264
|
+
Check that your API key is valid.
|
|
265
|
+
|
|
266
|
+
### "Connection refused"
|
|
267
|
+
Ensure SteamDashboard API is running and accessible at the configured URL.
|
|
268
|
+
|
|
269
|
+
## Roadmap
|
|
270
|
+
|
|
271
|
+
- [ ] Time-series analysis tools (tracking historical data)
|
|
272
|
+
- [ ] VLM integration for visual analysis
|
|
273
|
+
- [ ] Caching layer for expensive queries
|
|
274
|
+
- [ ] Rate limiting and request optimization
|
|
275
|
+
|
|
276
|
+
## License
|
|
277
|
+
|
|
278
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
279
|
+
|
|
280
|
+
## Support
|
|
281
|
+
|
|
282
|
+
For support and inquiries, contact Witchpot Studio.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SteamDashboard API Client
|
|
3
|
+
* Provides typed access to SteamDashboard REST API endpoints
|
|
4
|
+
*/
|
|
5
|
+
import type { SearchAppsResponse, AppSnapshotsResponse, ReviewGrowthResponse, TagAnalysisResponse, SimilarGamesResponse, RelatedTagsResponse, SortOption, TagMode } from './types.js';
|
|
6
|
+
export interface SteamApiClientConfig {
|
|
7
|
+
apiUrl: string;
|
|
8
|
+
apiKey: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SearchGamesParams {
|
|
11
|
+
keyword?: string;
|
|
12
|
+
tags?: string[];
|
|
13
|
+
tagMode?: TagMode;
|
|
14
|
+
priceMin?: number;
|
|
15
|
+
priceMax?: number;
|
|
16
|
+
reviewsMin?: number;
|
|
17
|
+
reviewsMax?: number;
|
|
18
|
+
ratingMin?: number;
|
|
19
|
+
discountMin?: number;
|
|
20
|
+
releaseFrom?: string;
|
|
21
|
+
releaseTo?: string;
|
|
22
|
+
upcomingOnly?: boolean;
|
|
23
|
+
sort?: SortOption;
|
|
24
|
+
page?: number;
|
|
25
|
+
limit?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface GetSnapshotsParams {
|
|
28
|
+
appid: number;
|
|
29
|
+
from?: string;
|
|
30
|
+
to?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface GetReviewGrowthParams {
|
|
33
|
+
from: string;
|
|
34
|
+
to: string;
|
|
35
|
+
tags?: string[];
|
|
36
|
+
tagMode?: TagMode;
|
|
37
|
+
reviewsMin?: number;
|
|
38
|
+
reviewsMax?: number;
|
|
39
|
+
sortBy?: 'growth_rate' | 'absolute_growth';
|
|
40
|
+
limit?: number;
|
|
41
|
+
}
|
|
42
|
+
export interface AnalyzeTagsParams {
|
|
43
|
+
groupBy: 'single_tag' | 'tag_combination';
|
|
44
|
+
tags?: string[];
|
|
45
|
+
tagMode?: TagMode;
|
|
46
|
+
reviewsMin?: number;
|
|
47
|
+
reviewsMax?: number;
|
|
48
|
+
priceMin?: number;
|
|
49
|
+
priceMax?: number;
|
|
50
|
+
ratingMin?: number;
|
|
51
|
+
successReviewsMin?: number;
|
|
52
|
+
successRatingMin?: number;
|
|
53
|
+
combinationSize?: number;
|
|
54
|
+
limit?: number;
|
|
55
|
+
}
|
|
56
|
+
export interface GetSimilarGamesParams {
|
|
57
|
+
appid: number;
|
|
58
|
+
limit?: number;
|
|
59
|
+
excludeGeneric?: boolean;
|
|
60
|
+
minReviews?: number;
|
|
61
|
+
}
|
|
62
|
+
export interface GetRelatedTagsParams {
|
|
63
|
+
baseTags: string[];
|
|
64
|
+
baseTagMode?: TagMode;
|
|
65
|
+
excludeGeneric?: boolean;
|
|
66
|
+
minCoOccurrence?: number;
|
|
67
|
+
successReviewsMin?: number;
|
|
68
|
+
successRatingMin?: number;
|
|
69
|
+
limit?: number;
|
|
70
|
+
}
|
|
71
|
+
export declare class SteamApiClient {
|
|
72
|
+
private readonly apiUrl;
|
|
73
|
+
private readonly apiKey;
|
|
74
|
+
constructor(config: SteamApiClientConfig);
|
|
75
|
+
/**
|
|
76
|
+
* Build URL with query parameters
|
|
77
|
+
*/
|
|
78
|
+
private buildUrl;
|
|
79
|
+
/**
|
|
80
|
+
* Make authenticated GET request
|
|
81
|
+
*/
|
|
82
|
+
private request;
|
|
83
|
+
/**
|
|
84
|
+
* Make authenticated POST request with JSON body
|
|
85
|
+
*/
|
|
86
|
+
private postRequest;
|
|
87
|
+
/**
|
|
88
|
+
* Search Steam games with filters
|
|
89
|
+
*/
|
|
90
|
+
searchGames(params: SearchGamesParams): Promise<SearchAppsResponse>;
|
|
91
|
+
/**
|
|
92
|
+
* Get time-series snapshot data for a specific app
|
|
93
|
+
*/
|
|
94
|
+
getAppSnapshots(params: GetSnapshotsParams): Promise<AppSnapshotsResponse>;
|
|
95
|
+
/**
|
|
96
|
+
* Get review growth analytics between two dates
|
|
97
|
+
*/
|
|
98
|
+
getReviewGrowth(params: GetReviewGrowthParams): Promise<ReviewGrowthResponse>;
|
|
99
|
+
/**
|
|
100
|
+
* Analyze tag combinations and success rates
|
|
101
|
+
*/
|
|
102
|
+
analyzeTags(params: AnalyzeTagsParams): Promise<TagAnalysisResponse>;
|
|
103
|
+
/**
|
|
104
|
+
* Find games similar to a specific app based on tag matching
|
|
105
|
+
*/
|
|
106
|
+
getSimilarGames(params: GetSimilarGamesParams): Promise<SimilarGamesResponse>;
|
|
107
|
+
/**
|
|
108
|
+
* Analyze related tags (co-occurrence) for a given tag set
|
|
109
|
+
*/
|
|
110
|
+
getRelatedTags(params: GetRelatedTagsParams): Promise<RelatedTagsResponse>;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=steam-api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steam-api-client.d.ts","sourceRoot":"","sources":["../../src/clients/steam-api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SteamDashboard API Client
|
|
3
|
+
* Provides typed access to SteamDashboard REST API endpoints
|
|
4
|
+
*/
|
|
5
|
+
export class SteamApiClient {
|
|
6
|
+
apiUrl;
|
|
7
|
+
apiKey;
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.apiUrl = config.apiUrl.replace(/\/$/, ''); // Remove trailing slash
|
|
10
|
+
this.apiKey = config.apiKey;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Build URL with query parameters
|
|
14
|
+
*/
|
|
15
|
+
buildUrl(endpoint, params) {
|
|
16
|
+
const url = new URL(endpoint, this.apiUrl);
|
|
17
|
+
if (params) {
|
|
18
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
19
|
+
if (value !== undefined && value !== null) {
|
|
20
|
+
if (Array.isArray(value)) {
|
|
21
|
+
url.searchParams.set(key, value.join(','));
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
url.searchParams.set(key, String(value));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return url.toString();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Make authenticated GET request
|
|
33
|
+
*/
|
|
34
|
+
async request(endpoint, params) {
|
|
35
|
+
const url = this.buildUrl(endpoint, params);
|
|
36
|
+
const response = await fetch(url, {
|
|
37
|
+
headers: {
|
|
38
|
+
'X-API-Key': this.apiKey,
|
|
39
|
+
'Content-Type': 'application/json',
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
const errorText = await response.text();
|
|
44
|
+
throw new Error(`SteamDashboard API error (${response.status}): ${errorText}`);
|
|
45
|
+
}
|
|
46
|
+
return response.json();
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Make authenticated POST request with JSON body
|
|
50
|
+
*/
|
|
51
|
+
async postRequest(endpoint, body) {
|
|
52
|
+
const url = `${this.apiUrl}${endpoint}`;
|
|
53
|
+
// Filter out undefined values from body
|
|
54
|
+
const filteredBody = Object.fromEntries(Object.entries(body).filter(([_, value]) => value !== undefined && value !== null));
|
|
55
|
+
const response = await fetch(url, {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
headers: {
|
|
58
|
+
'X-API-Key': this.apiKey,
|
|
59
|
+
'Content-Type': 'application/json',
|
|
60
|
+
},
|
|
61
|
+
body: JSON.stringify(filteredBody),
|
|
62
|
+
});
|
|
63
|
+
if (!response.ok) {
|
|
64
|
+
const errorText = await response.text();
|
|
65
|
+
throw new Error(`SteamDashboard API error (${response.status}): ${errorText}`);
|
|
66
|
+
}
|
|
67
|
+
return response.json();
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Search Steam games with filters
|
|
71
|
+
*/
|
|
72
|
+
async searchGames(params) {
|
|
73
|
+
return this.request('/api/v1/apps', {
|
|
74
|
+
q: params.keyword,
|
|
75
|
+
tags: params.tags,
|
|
76
|
+
tagMode: params.tagMode,
|
|
77
|
+
priceMin: params.priceMin,
|
|
78
|
+
priceMax: params.priceMax,
|
|
79
|
+
reviewsMin: params.reviewsMin,
|
|
80
|
+
reviewsMax: params.reviewsMax,
|
|
81
|
+
ratingMin: params.ratingMin,
|
|
82
|
+
discountMin: params.discountMin,
|
|
83
|
+
releaseFrom: params.releaseFrom,
|
|
84
|
+
releaseTo: params.releaseTo,
|
|
85
|
+
upcomingOnly: params.upcomingOnly,
|
|
86
|
+
sort: params.sort,
|
|
87
|
+
page: params.page,
|
|
88
|
+
pageSize: params.limit,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get time-series snapshot data for a specific app
|
|
93
|
+
*/
|
|
94
|
+
async getAppSnapshots(params) {
|
|
95
|
+
return this.request(`/api/v1/apps/${params.appid}/snapshots`, {
|
|
96
|
+
from: params.from,
|
|
97
|
+
to: params.to,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get review growth analytics between two dates
|
|
102
|
+
*/
|
|
103
|
+
async getReviewGrowth(params) {
|
|
104
|
+
return this.request('/api/v1/analytics/review-growth', {
|
|
105
|
+
from: params.from,
|
|
106
|
+
to: params.to,
|
|
107
|
+
tags: params.tags,
|
|
108
|
+
tagMode: params.tagMode,
|
|
109
|
+
// Map MCP params to API params
|
|
110
|
+
minReviewsFrom: params.reviewsMin,
|
|
111
|
+
// Note: reviewsMax is not currently supported by the API
|
|
112
|
+
sortBy: params.sortBy,
|
|
113
|
+
limit: params.limit,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Analyze tag combinations and success rates
|
|
118
|
+
*/
|
|
119
|
+
async analyzeTags(params) {
|
|
120
|
+
// Build successMetric object if success criteria provided
|
|
121
|
+
const successMetric = params.successReviewsMin || params.successRatingMin
|
|
122
|
+
? {
|
|
123
|
+
minReviews: params.successReviewsMin,
|
|
124
|
+
minRating: params.successRatingMin,
|
|
125
|
+
}
|
|
126
|
+
: undefined;
|
|
127
|
+
return this.postRequest('/api/v1/analyze', {
|
|
128
|
+
groupBy: params.groupBy,
|
|
129
|
+
tags: params.tags,
|
|
130
|
+
tagMode: params.tagMode,
|
|
131
|
+
reviewsMin: params.reviewsMin,
|
|
132
|
+
reviewsMax: params.reviewsMax,
|
|
133
|
+
priceMin: params.priceMin,
|
|
134
|
+
priceMax: params.priceMax,
|
|
135
|
+
ratingMin: params.ratingMin,
|
|
136
|
+
successMetric,
|
|
137
|
+
combinationSize: params.combinationSize,
|
|
138
|
+
outputLimit: params.limit,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Find games similar to a specific app based on tag matching
|
|
143
|
+
*/
|
|
144
|
+
async getSimilarGames(params) {
|
|
145
|
+
return this.request(`/api/v1/apps/${params.appid}/similar`, {
|
|
146
|
+
limit: params.limit,
|
|
147
|
+
excludeGeneric: params.excludeGeneric,
|
|
148
|
+
minReviews: params.minReviews,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Analyze related tags (co-occurrence) for a given tag set
|
|
153
|
+
*/
|
|
154
|
+
async getRelatedTags(params) {
|
|
155
|
+
const successMetric = params.successReviewsMin || params.successRatingMin
|
|
156
|
+
? {
|
|
157
|
+
minReviews: params.successReviewsMin,
|
|
158
|
+
minRating: params.successRatingMin,
|
|
159
|
+
}
|
|
160
|
+
: undefined;
|
|
161
|
+
return this.postRequest('/api/v1/analyze/related-tags', {
|
|
162
|
+
baseTags: params.baseTags,
|
|
163
|
+
baseTagMode: params.baseTagMode,
|
|
164
|
+
excludeGeneric: params.excludeGeneric,
|
|
165
|
+
minCoOccurrence: params.minCoOccurrence,
|
|
166
|
+
successMetric,
|
|
167
|
+
limit: params.limit,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=steam-api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steam-api-client.js","sourceRoot":"","sources":["../../src/clients/steam-api-client.ts"],"names":[],"mappings":"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"}
|