@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.
Files changed (44) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/LICENSE +21 -0
  3. package/README.md +282 -0
  4. package/build/clients/steam-api-client.d.ts +112 -0
  5. package/build/clients/steam-api-client.d.ts.map +1 -0
  6. package/build/clients/steam-api-client.js +171 -0
  7. package/build/clients/steam-api-client.js.map +1 -0
  8. package/build/clients/types.d.ts +174 -0
  9. package/build/clients/types.d.ts.map +1 -0
  10. package/build/clients/types.js +5 -0
  11. package/build/clients/types.js.map +1 -0
  12. package/build/index.d.ts +7 -0
  13. package/build/index.d.ts.map +1 -0
  14. package/build/index.js +176 -0
  15. package/build/index.js.map +1 -0
  16. package/build/tools/analyze-related-tags.d.ts +39 -0
  17. package/build/tools/analyze-related-tags.d.ts.map +1 -0
  18. package/build/tools/analyze-related-tags.js +114 -0
  19. package/build/tools/analyze-related-tags.js.map +1 -0
  20. package/build/tools/analyze-tag-combinations.d.ts +54 -0
  21. package/build/tools/analyze-tag-combinations.d.ts.map +1 -0
  22. package/build/tools/analyze-tag-combinations.js +73 -0
  23. package/build/tools/analyze-tag-combinations.js.map +1 -0
  24. package/build/tools/find-similar-games.d.ts +30 -0
  25. package/build/tools/find-similar-games.d.ts.map +1 -0
  26. package/build/tools/find-similar-games.js +72 -0
  27. package/build/tools/find-similar-games.js.map +1 -0
  28. package/build/tools/get-app-snapshots.d.ts +27 -0
  29. package/build/tools/get-app-snapshots.d.ts.map +1 -0
  30. package/build/tools/get-app-snapshots.js +54 -0
  31. package/build/tools/get-app-snapshots.js.map +1 -0
  32. package/build/tools/get-review-growth.d.ts +42 -0
  33. package/build/tools/get-review-growth.d.ts.map +1 -0
  34. package/build/tools/get-review-growth.js +78 -0
  35. package/build/tools/get-review-growth.js.map +1 -0
  36. package/build/tools/index.d.ts +10 -0
  37. package/build/tools/index.d.ts.map +1 -0
  38. package/build/tools/index.js +10 -0
  39. package/build/tools/index.js.map +1 -0
  40. package/build/tools/search-games.d.ts +63 -0
  41. package/build/tools/search-games.d.ts.map +1 -0
  42. package/build/tools/search-games.js +92 -0
  43. package/build/tools/search-games.js.map +1 -0
  44. 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
+ [![npm version](https://badge.fury.io/js/%40witchpot%2Fsteamboard-mcp.svg)](https://www.npmjs.com/package/@witchpot/steamboard-mcp)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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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"}