screeps-world-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/README.md ADDED
@@ -0,0 +1,135 @@
1
+ # Screeps World MCP Service
2
+
3
+ ![Made with AI](https://img.shields.io/badge/Made%20with-AI-lightgrey?style=for-the-badge)
4
+
5
+ Integrates live Screeps server data directly into AI development workflows.
6
+
7
+ ## Features
8
+
9
+ - **Comprehensive API Coverage**: Room operations, user data, market information, map analytics, and utilities
10
+ - **AI-Optimized**: Enhanced responses with loop detection, caching, and completion indicators
11
+ - **Rate Limit Aware**: Monitoring and guidance to prevent API limit issues
12
+ - **TypeScript**: Full type safety with zod schema validation
13
+ - **MCP Protocol**: Compatible with MCP-enabled clients
14
+
15
+ ## Setup
16
+
17
+ 1. Install dependencies:
18
+ ```bash
19
+ npm install
20
+ ```
21
+
22
+ 2. Configure your Screeps credentials:
23
+ ```bash
24
+ cp .env.example .env
25
+ # Edit .env with your Screeps config
26
+ ```
27
+
28
+ 3. Build the project:
29
+ ```bash
30
+ npm run build
31
+ ```
32
+
33
+ 4. Start the service:
34
+ ```bash
35
+ npm start
36
+ ```
37
+
38
+ ## Configuration
39
+
40
+ The service can be configured via environment variables or constructor parameters:
41
+
42
+ - `SCREEPS_BASE_URL`: API base URL (defaults to official server)
43
+ - `SCREEPS_TOKEN`: Your Screeps authentication token
44
+ - `SCREEPS_USERNAME`: Your Screeps username (optional)
45
+
46
+ ### Getting Your Screeps Token
47
+
48
+ 1. Go to [Screeps Account Settings](https://screeps.com/a/#!/account/auth-tokens)
49
+ 2. Create a new auth token
50
+ 3. Add it to your `.env` file
51
+
52
+ ## Development
53
+
54
+ Run TypeScript in watch mode:
55
+ ```bash
56
+ npm run dev
57
+ ```
58
+
59
+ Format code with Prettier:
60
+ ```bash
61
+ npm run format
62
+ ```
63
+
64
+ ## Usage Examples
65
+
66
+ After completing the [setup](#setup), add to your `mcp.json`:
67
+
68
+ ```json
69
+ {
70
+ "mcpServers": {
71
+ "screeps-world": {
72
+ "command": "node",
73
+ "args": ["/path/to/screeps-world-mcp/dist/index.js"],
74
+ "env": {
75
+ "SCREEPS_TOKEN": "${env:SCREEPS_TOKEN}"
76
+ }
77
+ }
78
+ }
79
+ }
80
+ ```
81
+
82
+ ## AI Usage Guidelines
83
+
84
+ 1. **Follow Response Guidance**: Each response includes completion indicators and suggested next steps
85
+ 2. **Avoid Redundant Calls**: The server detects and warns against repetitive identical calls
86
+ 3. **Start with Resources**: Get foundational data (version, shards) before using tools for specific queries
87
+ 4. **Respect Rate Limits**: Monitor remaining API calls shown in responses
88
+
89
+ ## Available Resources
90
+
91
+ Resources provide static or server-wide data:
92
+
93
+ - **auth_me**: Current authenticated user information
94
+ - **game_time**: Current game time and tick information
95
+ - **world_size**: World dimensions and size information
96
+ - **shards_info**: Information about available shards
97
+ - **user_world_status**: Current user world status and statistics
98
+ - **market_stats**: Market statistics and trading information
99
+ - **version**: API version and server information
100
+
101
+ ## Available Tools
102
+
103
+ Tools allow interactive queries with parameters:
104
+
105
+ ### Room Information
106
+ - **get_room_terrain**: Get terrain information for a specific room
107
+ - **get_room_objects**: Get objects and users in a specific room
108
+ - **get_room_overview**: Get room overview and statistics
109
+ - **get_room_status**: Get room status information
110
+
111
+ ### Market Information
112
+ - **get_market_orders_index**: Get market orders index
113
+ - **get_my_market_orders**: Get user's market orders
114
+ - **get_market_orders**: Get market orders for a specific resource
115
+ - **get_money_history**: Get user money transaction history
116
+
117
+ ### User Data
118
+ - **get_user_name**: Get user name
119
+ - **get_user_stats**: Get user statistics with optional interval
120
+ - **get_user_rooms**: Get user rooms by user ID
121
+ - **find_user**: Find user by ID or username
122
+ - **get_user_overview**: Get user overview statistics with interval and stat filtering
123
+ - **get_user_memory**: Get user memory data
124
+ - **execute_console_command**: Execute console command in Screeps
125
+
126
+ ### Map & Analytics
127
+ - **get_map_stats**: Get map statistics for specified rooms
128
+
129
+ ### Experimental Features
130
+ - **get_pvp_info**: Get PvP information
131
+ - **get_nukes_info**: Get active nukes information by shard
132
+
133
+ ### Utilities
134
+ - **calculate_distance**: Calculate distance between two rooms
135
+ - **auth_signin**: Sign in to Screeps to get authentication token
@@ -0,0 +1,45 @@
1
+ export const DEFAULT_CONFIG = {
2
+ baseUrl: process.env.SCREEPS_BASE_URL || 'https://screeps.com/api',
3
+ token: process.env.SCREEPS_TOKEN,
4
+ username: process.env.SCREEPS_USERNAME,
5
+ };
6
+ export class ConfigManager {
7
+ config;
8
+ constructor(config = {}) {
9
+ this.config = { ...DEFAULT_CONFIG, ...config };
10
+ }
11
+ getConfig() {
12
+ return { ...this.config };
13
+ }
14
+ updateConfig(updates) {
15
+ this.config = { ...this.config, ...updates };
16
+ }
17
+ getBaseUrl() {
18
+ return this.config.baseUrl;
19
+ }
20
+ getToken() {
21
+ return this.config.token;
22
+ }
23
+ getUsername() {
24
+ return this.config.username;
25
+ }
26
+ hasAuthentication() {
27
+ return !!(this.config.token || this.config.username);
28
+ }
29
+ setToken(token) {
30
+ this.config.token = token;
31
+ }
32
+ getAuthHeaders() {
33
+ const headers = {
34
+ 'Content-Type': 'application/json',
35
+ };
36
+ if (this.config.token) {
37
+ headers['X-Token'] = this.config.token;
38
+ }
39
+ if (this.config.username) {
40
+ headers['X-Username'] = this.config.username;
41
+ }
42
+ return headers;
43
+ }
44
+ }
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAkB;IAC3C,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,yBAAyB;IAClE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;IAChC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB;CACvC,CAAC;AAEF,MAAM,OAAO,aAAa;IAChB,MAAM,CAAgB;IAE9B,YAAY,SAAiC,EAAE;QAC7C,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;IACjD,CAAC;IAED,SAAS;QACP,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;IAED,YAAY,CAAC,OAA+B;QAC1C,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC;IAC/C,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;IAC3B,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;IAC9B,CAAC;IAED,iBAAiB;QACf,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvD,CAAC;IAED,QAAQ,CAAC,KAAa;QACpB,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;IAC5B,CAAC;IAED,cAAc;QACZ,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;SACnC,CAAC;QAEF,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QACzC,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACzB,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC/C,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { ScreepsWorldMcp } from './server/screeps.js';
3
+ const service = new ScreepsWorldMcp();
4
+ service.start().catch(console.error);
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC;AACtC,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ export class AuthResourceHandlers {
2
+ apiClient;
3
+ constructor(apiClient) {
4
+ this.apiClient = apiClient;
5
+ }
6
+ async handleAuthMe(uri) {
7
+ try {
8
+ const endpoint = '/auth/me';
9
+ const data = await this.apiClient.makeApiCall(endpoint);
10
+ const additionalGuidance = [
11
+ 'Use this authentication info to verify user identity',
12
+ 'Username and user ID are stable - safe to cache long-term',
13
+ 'This resource confirms your API token is valid and active',
14
+ ];
15
+ return this.apiClient.createEnhancedResourceContent(uri.href, data, endpoint, 'Current User Authentication Info', additionalGuidance);
16
+ }
17
+ catch (error) {
18
+ return this.apiClient.createErrorResourceContent(uri.href, error);
19
+ }
20
+ }
21
+ }
22
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/resources/auth.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,oBAAoB;IACX;IAApB,YAAoB,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IAAG,CAAC;IAE5C,KAAK,CAAC,YAAY,CAAC,GAAQ;QACzB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,UAAU,CAAC;YAC5B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAExD,MAAM,kBAAkB,GAAG;gBACzB,sDAAsD;gBACtD,2DAA2D;gBAC3D,2DAA2D;aAC5D,CAAC;YAEF,OAAO,IAAI,CAAC,SAAS,CAAC,6BAA6B,CACjD,GAAG,CAAC,IAAI,EACR,IAAI,EACJ,QAAQ,EACR,kCAAkC,EAClC,kBAAkB,CACnB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,SAAS,CAAC,0BAA0B,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,85 @@
1
+ export class GameResourceHandlers {
2
+ apiClient;
3
+ constructor(apiClient) {
4
+ this.apiClient = apiClient;
5
+ }
6
+ async handleGameTime(uri) {
7
+ try {
8
+ const endpoint = '/game/time';
9
+ const data = await this.apiClient.makeApiCall(endpoint);
10
+ const additionalGuidance = [
11
+ 'Game time advances every tick (approximately every 3 seconds)',
12
+ 'Use this timestamp for synchronizing with game events',
13
+ 'Time data is cached briefly to optimize performance',
14
+ ];
15
+ return this.apiClient.createEnhancedResourceContent(uri.href, data, endpoint, 'Current Game Time and Tick Information', additionalGuidance);
16
+ }
17
+ catch (error) {
18
+ return this.apiClient.createErrorResourceContent(uri.href, error);
19
+ }
20
+ }
21
+ async handleWorldSize(uri) {
22
+ try {
23
+ const endpoint = '/game/world-size';
24
+ const data = await this.apiClient.makeApiCall(endpoint);
25
+ const additionalGuidance = [
26
+ 'World dimensions never change - this is static configuration data',
27
+ 'Use width/height for room coordinate calculations and map boundaries',
28
+ 'Safe to cache this data indefinitely in your applications',
29
+ ];
30
+ return this.apiClient.createEnhancedResourceContent(uri.href, data, endpoint, 'World Dimensions and Size Information', additionalGuidance);
31
+ }
32
+ catch (error) {
33
+ return this.apiClient.createErrorResourceContent(uri.href, error);
34
+ }
35
+ }
36
+ async handleShardsInfo(uri) {
37
+ try {
38
+ const endpoint = '/game/shards/info';
39
+ const data = await this.apiClient.makeApiCall(endpoint);
40
+ const additionalGuidance = [
41
+ `Available shards: ${data?.shards?.length || 'unknown'} shards detected`,
42
+ 'Shard list changes rarely - only when server adds/removes shards',
43
+ 'Use shard info for multi-shard strategies and server selection',
44
+ 'Check shard status and tick rates for performance planning',
45
+ ];
46
+ return this.apiClient.createEnhancedResourceContent(uri.href, data, endpoint, 'Available Shards Information', additionalGuidance);
47
+ }
48
+ catch (error) {
49
+ return this.apiClient.createErrorResourceContent(uri.href, error);
50
+ }
51
+ }
52
+ async handleMarketStats(uri) {
53
+ try {
54
+ const endpoint = '/game/market/stats';
55
+ const data = await this.apiClient.makeApiCall(endpoint);
56
+ const additionalGuidance = [
57
+ 'Market statistics provide global economy overview',
58
+ 'Credit totals and transaction volumes update regularly',
59
+ 'Use for economic analysis and market trend identification',
60
+ 'Combine with specific market orders for detailed trading data',
61
+ ];
62
+ return this.apiClient.createEnhancedResourceContent(uri.href, data, endpoint, 'Global Market Statistics and Trading Information', additionalGuidance);
63
+ }
64
+ catch (error) {
65
+ return this.apiClient.createErrorResourceContent(uri.href, error);
66
+ }
67
+ }
68
+ async handleVersion(uri) {
69
+ try {
70
+ const endpoint = '/version';
71
+ const data = await this.apiClient.makeApiCall(endpoint);
72
+ const additionalGuidance = [
73
+ 'Server version and features are static until server updates',
74
+ 'Use feature flags to determine available API capabilities',
75
+ 'User count and shard info provide server health insights',
76
+ 'Safe to cache version data for the duration of your session',
77
+ ];
78
+ return this.apiClient.createEnhancedResourceContent(uri.href, data, endpoint, 'API Version and Server Information', additionalGuidance);
79
+ }
80
+ catch (error) {
81
+ return this.apiClient.createErrorResourceContent(uri.href, error);
82
+ }
83
+ }
84
+ }
85
+ //# sourceMappingURL=game.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"game.js","sourceRoot":"","sources":["../../src/resources/game.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import { AuthResourceHandlers } from './auth.js';
2
+ import { GameResourceHandlers } from './game.js';
3
+ import { UserResourceHandlers } from './user.js';
4
+ export class ResourceRegistry {
5
+ apiClient;
6
+ authHandlers;
7
+ gameHandlers;
8
+ userHandlers;
9
+ constructor(apiClient) {
10
+ this.apiClient = apiClient;
11
+ this.authHandlers = new AuthResourceHandlers(apiClient);
12
+ this.gameHandlers = new GameResourceHandlers(apiClient);
13
+ this.userHandlers = new UserResourceHandlers(apiClient);
14
+ }
15
+ registerAll(server) {
16
+ // Authentication Resources
17
+ server.registerResource('auth_me', 'screeps://auth/me', {
18
+ title: 'Current User Info',
19
+ description: 'Get current authenticated user information',
20
+ mimeType: 'application/json',
21
+ }, (uri) => this.authHandlers.handleAuthMe(uri));
22
+ // Game Resources
23
+ server.registerResource('game_time', 'screeps://game/time', {
24
+ title: 'Game Time',
25
+ description: 'Current game time and tick information',
26
+ mimeType: 'application/json',
27
+ }, (uri) => this.gameHandlers.handleGameTime(uri));
28
+ server.registerResource('world_size', 'screeps://game/world-size', {
29
+ title: 'World Size',
30
+ description: 'Get world dimensions and size information',
31
+ mimeType: 'application/json',
32
+ }, (uri) => this.gameHandlers.handleWorldSize(uri));
33
+ server.registerResource('shards_info', 'screeps://game/shards/info', {
34
+ title: 'Shard Information',
35
+ description: 'Get information about available shards',
36
+ mimeType: 'application/json',
37
+ }, (uri) => this.gameHandlers.handleShardsInfo(uri));
38
+ server.registerResource('market_stats', 'screeps://game/market/stats', {
39
+ title: 'Market Statistics',
40
+ description: 'Get market statistics and trading information',
41
+ mimeType: 'application/json',
42
+ }, (uri) => this.gameHandlers.handleMarketStats(uri));
43
+ server.registerResource('version', 'screeps://version', {
44
+ title: 'API Version',
45
+ description: 'Get API version and server information including features, shards, and user count',
46
+ mimeType: 'application/json',
47
+ }, (uri) => this.gameHandlers.handleVersion(uri));
48
+ // User Resources
49
+ server.registerResource('user_world_status', 'screeps://user/world-status', {
50
+ title: 'User World Status',
51
+ description: 'Get current user world status and statistics',
52
+ mimeType: 'application/json',
53
+ }, (uri) => this.userHandlers.handleUserWorldStatus(uri));
54
+ }
55
+ }
56
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEjD,MAAM,OAAO,gBAAgB;IAKP;IAJZ,YAAY,CAAuB;IACnC,YAAY,CAAuB;IACnC,YAAY,CAAuB;IAE3C,YAAoB,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;QACtC,IAAI,CAAC,YAAY,GAAG,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC;QACxD,IAAI,CAAC,YAAY,GAAG,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC;QACxD,IAAI,CAAC,YAAY,GAAG,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;IAED,WAAW,CAAC,MAAiB;QAC3B,2BAA2B;QAC3B,MAAM,CAAC,gBAAgB,CACrB,SAAS,EACT,mBAAmB,EACnB;YACE,KAAK,EAAE,mBAAmB;YAC1B,WAAW,EAAE,4CAA4C;YACzD,QAAQ,EAAE,kBAAkB;SAC7B,EACD,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,CAC7C,CAAC;QAEF,iBAAiB;QACjB,MAAM,CAAC,gBAAgB,CACrB,WAAW,EACX,qBAAqB,EACrB;YACE,KAAK,EAAE,WAAW;YAClB,WAAW,EAAE,wCAAwC;YACrD,QAAQ,EAAE,kBAAkB;SAC7B,EACD,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,CAC/C,CAAC;QAEF,MAAM,CAAC,gBAAgB,CACrB,YAAY,EACZ,2BAA2B,EAC3B;YACE,KAAK,EAAE,YAAY;YACnB,WAAW,EAAE,2CAA2C;YACxD,QAAQ,EAAE,kBAAkB;SAC7B,EACD,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,GAAG,CAAC,CAChD,CAAC;QAEF,MAAM,CAAC,gBAAgB,CACrB,aAAa,EACb,4BAA4B,EAC5B;YACE,KAAK,EAAE,mBAAmB;YAC1B,WAAW,EAAE,wCAAwC;YACrD,QAAQ,EAAE,kBAAkB;SAC7B,EACD,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,GAAG,CAAC,CACjD,CAAC;QAEF,MAAM,CAAC,gBAAgB,CACrB,cAAc,EACd,6BAA6B,EAC7B;YACE,KAAK,EAAE,mBAAmB;YAC1B,WAAW,EAAE,+CAA+C;YAC5D,QAAQ,EAAE,kBAAkB;SAC7B,EACD,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAClD,CAAC;QAEF,MAAM,CAAC,gBAAgB,CACrB,SAAS,EACT,mBAAmB,EACnB;YACE,KAAK,EAAE,aAAa;YACpB,WAAW,EAAE,mFAAmF;YAChG,QAAQ,EAAE,kBAAkB;SAC7B,EACD,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,GAAG,CAAC,CAC9C,CAAC;QAEF,iBAAiB;QACjB,MAAM,CAAC,gBAAgB,CACrB,mBAAmB,EACnB,6BAA6B,EAC7B;YACE,KAAK,EAAE,mBAAmB;YAC1B,WAAW,EAAE,8CAA8C;YAC3D,QAAQ,EAAE,kBAAkB;SAC7B,EACD,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,qBAAqB,CAAC,GAAG,CAAC,CACtD,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,23 @@
1
+ export class UserResourceHandlers {
2
+ apiClient;
3
+ constructor(apiClient) {
4
+ this.apiClient = apiClient;
5
+ }
6
+ async handleUserWorldStatus(uri) {
7
+ try {
8
+ const endpoint = '/user/world-status';
9
+ const data = await this.apiClient.makeApiCall(endpoint);
10
+ const additionalGuidance = [
11
+ 'User world status shows your global presence and empire state',
12
+ 'Status includes GCL, power level, and overall progression metrics',
13
+ 'Data updates periodically - cached for performance optimization',
14
+ 'Use for empire management and strategic planning decisions',
15
+ ];
16
+ return this.apiClient.createEnhancedResourceContent(uri.href, data, endpoint, 'User World Status and Statistics', additionalGuidance);
17
+ }
18
+ catch (error) {
19
+ return this.apiClient.createErrorResourceContent(uri.href, error);
20
+ }
21
+ }
22
+ }
23
+ //# sourceMappingURL=user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/resources/user.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,oBAAoB;IACX;IAApB,YAAoB,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IAAG,CAAC;IAE5C,KAAK,CAAC,qBAAqB,CAAC,GAAQ;QAClC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,oBAAoB,CAAC;YACtC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAExD,MAAM,kBAAkB,GAAG;gBACzB,+DAA+D;gBAC/D,mEAAmE;gBACnE,iEAAiE;gBACjE,4DAA4D;aAC7D,CAAC;YAEF,OAAO,IAAI,CAAC,SAAS,CAAC,6BAA6B,CACjD,GAAG,CAAC,IAAI,EACR,IAAI,EACJ,QAAQ,EACR,kCAAkC,EAClC,kBAAkB,CACnB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,SAAS,CAAC,0BAA0B,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,50 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { ConfigManager } from '../config/index.js';
4
+ import { ApiClient } from '../utils/api.js';
5
+ import { ResourceRegistry } from '../resources/index.js';
6
+ import { ToolRegistry } from '../tools/index.js';
7
+ export class ScreepsWorldMcp {
8
+ server;
9
+ configManager;
10
+ apiClient;
11
+ resourceRegistry;
12
+ toolRegistry;
13
+ constructor(config = {}) {
14
+ this.configManager = new ConfigManager(config);
15
+ this.apiClient = new ApiClient(this.configManager);
16
+ this.server = new McpServer({
17
+ name: 'screeps-world-mcp',
18
+ version: '1.0.0',
19
+ description: 'MCP server for Screeps World Web API access',
20
+ });
21
+ this.resourceRegistry = new ResourceRegistry(this.apiClient);
22
+ this.toolRegistry = new ToolRegistry(this.apiClient, this.configManager);
23
+ this.setupHandlers();
24
+ }
25
+ setupHandlers() {
26
+ // Register all resources and tools
27
+ this.resourceRegistry.registerAll(this.server);
28
+ this.toolRegistry.registerAll(this.server);
29
+ }
30
+ async start() {
31
+ if (!this.configManager.getToken()) {
32
+ console.log('No token found, set the SCREEPS_TOKEN environment variable and try again');
33
+ return;
34
+ }
35
+ const transport = new StdioServerTransport();
36
+ await this.server.connect(transport);
37
+ console.log('Screeps World MCP Service is running...');
38
+ console.log('Screeps Server:', this.configManager.getBaseUrl());
39
+ }
40
+ getConfig() {
41
+ return this.configManager.getConfig();
42
+ }
43
+ updateConfig(updates) {
44
+ this.configManager.updateConfig(updates);
45
+ }
46
+ getServer() {
47
+ return this.server;
48
+ }
49
+ }
50
+ //# sourceMappingURL=screeps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screeps.js","sourceRoot":"","sources":["../../src/server/screeps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,MAAM,OAAO,eAAe;IAClB,MAAM,CAAY;IAClB,aAAa,CAAgB;IAC7B,SAAS,CAAY;IACrB,gBAAgB,CAAmB;IACnC,YAAY,CAAe;IAEnC,YAAY,SAAiC,EAAE;QAC7C,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAEnD,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC;YAC1B,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,OAAO;YAChB,WAAW,EAAE,6CAA6C;SAC3D,CAAC,CAAC;QAEH,IAAI,CAAC,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAEzE,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEO,aAAa;QACnB,mCAAmC;QACnC,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC;YACxF,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAErC,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC;IAClE,CAAC;IAEM,SAAS;QACd,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;IACxC,CAAC;IAEM,YAAY,CAAC,OAA+B;QACjD,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IAEM,SAAS;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,152 @@
1
+ import { RoomToolHandlers } from './room.js';
2
+ import { UserToolHandlers } from './user.js';
3
+ import { MarketToolHandlers } from './market.js';
4
+ import { MiscToolHandlers } from './misc.js';
5
+ export class ToolRegistry {
6
+ apiClient;
7
+ configManager;
8
+ roomHandlers;
9
+ userHandlers;
10
+ marketHandlers;
11
+ miscHandlers;
12
+ constructor(apiClient, configManager) {
13
+ this.apiClient = apiClient;
14
+ this.configManager = configManager;
15
+ this.roomHandlers = new RoomToolHandlers(apiClient);
16
+ this.userHandlers = new UserToolHandlers(apiClient);
17
+ this.marketHandlers = new MarketToolHandlers(apiClient);
18
+ this.miscHandlers = new MiscToolHandlers(apiClient);
19
+ }
20
+ async convertResult(resultPromise) {
21
+ const result = await resultPromise;
22
+ return result;
23
+ }
24
+ registerAll(server) {
25
+ const roomSchemas = RoomToolHandlers.getSchemas();
26
+ const userSchemas = UserToolHandlers.getSchemas();
27
+ const marketSchemas = MarketToolHandlers.getSchemas();
28
+ const miscSchemas = MiscToolHandlers.getSchemas();
29
+ // Room Tools
30
+ server.registerTool('get_room_terrain', {
31
+ title: 'Get Room Terrain',
32
+ description: 'Get terrain information for a specific room. Call this tool ONCE per room - terrain data is static and complete in a single response.',
33
+ inputSchema: roomSchemas.roomTerrain,
34
+ }, (params) => this.roomHandlers.handleGetRoomTerrain(params));
35
+ server.registerTool('get_room_objects', {
36
+ title: 'Get Room Objects',
37
+ description: 'Get objects and users in a specific room. Call this tool ONCE per room - the response contains complete room data. Do NOT call repeatedly for the same room.',
38
+ inputSchema: roomSchemas.roomObjects,
39
+ }, (params) => this.roomHandlers.handleGetRoomObjects(params));
40
+ server.registerTool('get_room_overview', {
41
+ title: 'Get Room Overview',
42
+ description: 'Get room overview and statistics. Call this tool ONCE per room/interval combination - provides complete statistical data in a single response.',
43
+ inputSchema: roomSchemas.roomOverview,
44
+ }, (params) => this.roomHandlers.handleGetRoomOverview(params));
45
+ server.registerTool('get_room_status', {
46
+ title: 'Get Room Status',
47
+ description: 'Get room status information. Call this tool ONCE per room - status data is complete and rarely changes.',
48
+ inputSchema: roomSchemas.roomStatus,
49
+ }, (params) => this.roomHandlers.handleGetRoomStatus(params));
50
+ server.registerTool('calculate_distance', {
51
+ title: 'Calculate Distance',
52
+ description: 'Calculate distance between two rooms',
53
+ inputSchema: roomSchemas.calculateDistance,
54
+ }, (params) => this.roomHandlers.handleCalculateDistance(params));
55
+ // User Tools
56
+ server.registerTool('get_user_name', {
57
+ title: 'Get User Name',
58
+ description: 'Get user name',
59
+ inputSchema: userSchemas.getUserName,
60
+ }, () => this.userHandlers.handleGetUserName());
61
+ server.registerTool('get_user_stats', {
62
+ title: 'Get User Statistics',
63
+ description: 'Get user statistics',
64
+ inputSchema: userSchemas.getUserStats,
65
+ }, (params) => this.userHandlers.handleGetUserStats(params));
66
+ server.registerTool('get_user_rooms', {
67
+ title: 'Get User Rooms',
68
+ description: 'Get user rooms by user ID. Use find_user tool first to get the user ID from username.',
69
+ inputSchema: userSchemas.getUserRooms,
70
+ }, (params) => this.userHandlers.handleGetUserRooms(params));
71
+ server.registerTool('find_user', {
72
+ title: 'Find User',
73
+ description: 'Find user by ID or username',
74
+ inputSchema: userSchemas.findUser,
75
+ }, (params) => this.userHandlers.handleFindUser(params));
76
+ server.registerTool('get_user_overview', {
77
+ title: 'Get User Overview',
78
+ description: 'Get user overview statistics',
79
+ inputSchema: userSchemas.getUserOverview,
80
+ }, (params) => this.userHandlers.handleGetUserOverview(params));
81
+ server.registerTool('execute_console_command', {
82
+ title: 'Execute Console Command',
83
+ description: 'Execute console command in Screeps',
84
+ inputSchema: userSchemas.executeConsoleCommand,
85
+ }, (params) => this.userHandlers.handleExecuteConsoleCommand(params));
86
+ server.registerTool('get_user_memory', {
87
+ title: 'Get User Memory',
88
+ description: 'Get user memory data',
89
+ inputSchema: userSchemas.getUserMemory,
90
+ }, (params) => this.userHandlers.handleGetUserMemory(params));
91
+ server.registerTool('auth_signin', {
92
+ title: 'Sign In',
93
+ description: 'Sign in to get authentication token on private servers',
94
+ inputSchema: userSchemas.authSignin,
95
+ }, async (params) => {
96
+ const result = await this.userHandlers.handleAuthSignin(params);
97
+ // Handle token update if signin was successful
98
+ try {
99
+ // We need to extract the token from the API response
100
+ const data = await this.apiClient.makeApiCall('/auth/signin', {
101
+ method: 'POST',
102
+ body: JSON.stringify({ email: params.email, password: params.password }),
103
+ });
104
+ if (data.token) {
105
+ this.configManager.setToken(data.token);
106
+ }
107
+ }
108
+ catch (error) {
109
+ // Token update failed, but the original result is still valid
110
+ }
111
+ return result;
112
+ });
113
+ // Market Tools
114
+ server.registerTool('get_market_orders_index', {
115
+ title: 'Get Market Orders Index',
116
+ description: 'Get market orders index',
117
+ inputSchema: marketSchemas.getMarketOrdersIndex,
118
+ }, () => this.marketHandlers.handleGetMarketOrdersIndex());
119
+ server.registerTool('get_my_market_orders', {
120
+ title: 'Get My Market Orders',
121
+ description: "Get user's market orders",
122
+ inputSchema: marketSchemas.getMyMarketOrders,
123
+ }, () => this.marketHandlers.handleGetMyMarketOrders());
124
+ server.registerTool('get_market_orders', {
125
+ title: 'Get Market Orders',
126
+ description: 'Get market orders for a specific resource',
127
+ inputSchema: marketSchemas.getMarketOrders,
128
+ }, (params) => this.marketHandlers.handleGetMarketOrders(params));
129
+ server.registerTool('get_money_history', {
130
+ title: 'Get Money History',
131
+ description: 'Get user money transaction history',
132
+ inputSchema: marketSchemas.getMoneyHistory,
133
+ }, (params) => this.marketHandlers.handleGetMoneyHistory(params));
134
+ server.registerTool('get_map_stats', {
135
+ title: 'Get Map Statistics',
136
+ description: 'Get map statistics for specified rooms',
137
+ inputSchema: marketSchemas.getMapStats,
138
+ }, (params) => this.marketHandlers.handleGetMapStats(params));
139
+ // Miscellaneous Tools
140
+ server.registerTool('get_pvp_info', {
141
+ title: 'Get PvP Information',
142
+ description: 'Get PvP information from experimental endpoint',
143
+ inputSchema: miscSchemas.getPvpInfo,
144
+ }, (params) => this.miscHandlers.handleGetPvpInfo(params));
145
+ server.registerTool('get_nukes_info', {
146
+ title: 'Get Nukes Information',
147
+ description: 'Get active nukes information by shard',
148
+ inputSchema: miscSchemas.getNukesInfo,
149
+ }, () => this.miscHandlers.handleGetNukesInfo());
150
+ }
151
+ }
152
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}