@access-mcp/system-status 0.5.0 → 0.6.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 +16 -132
- package/dist/__tests__/server.integration.test.js +66 -40
- package/dist/__tests__/server.test.js +183 -86
- package/dist/index.js +1 -1
- package/dist/server.d.ts +11 -56
- package/dist/server.js +135 -67
- package/dist/web-server.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# System Status MCP Server
|
|
2
2
|
|
|
3
|
-
MCP server
|
|
3
|
+
MCP server for real-time ACCESS-CI system status including current outages, scheduled maintenance, and operational status.
|
|
4
4
|
|
|
5
5
|
## Usage Examples
|
|
6
6
|
|
|
7
|
-
###
|
|
8
|
-
|
|
7
|
+
### Current Status
|
|
9
8
|
```
|
|
10
9
|
"Current ACCESS-CI outages"
|
|
11
10
|
"Delta operational status"
|
|
@@ -13,8 +12,7 @@ MCP server providing real-time system status information for ACCESS-CI resources
|
|
|
13
12
|
"GPU systems status check"
|
|
14
13
|
```
|
|
15
14
|
|
|
16
|
-
###
|
|
17
|
-
|
|
15
|
+
### Maintenance & Incidents
|
|
18
16
|
```
|
|
19
17
|
"Scheduled maintenance this week"
|
|
20
18
|
"Next Expanse maintenance window"
|
|
@@ -24,36 +22,33 @@ MCP server providing real-time system status information for ACCESS-CI resources
|
|
|
24
22
|
|
|
25
23
|
## Tools
|
|
26
24
|
|
|
27
|
-
### get_infrastructure_news
|
|
25
|
+
### `get_infrastructure_news`
|
|
28
26
|
|
|
29
|
-
|
|
27
|
+
Get infrastructure status, outages, and maintenance information for ACCESS-CI resources.
|
|
30
28
|
|
|
31
29
|
**Parameters:**
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
| Parameter | Type | Description |
|
|
31
|
+
|-----------|------|-------------|
|
|
32
|
+
| `resource` | string | Filter by resource name (e.g., "delta", "bridges2") |
|
|
33
|
+
| `time` | enum | Time period: `current`, `scheduled`, `past`, `all` (default: "current") |
|
|
34
|
+
| `resource_ids` | array | Check status for specific resource IDs |
|
|
35
|
+
| `limit` | number | Max results (default: 50 for "all", 100 for "past") |
|
|
36
|
+
| `use_group_api` | boolean | Use resource group API for status checking (default: false) |
|
|
38
37
|
|
|
39
38
|
**Examples:**
|
|
40
|
-
|
|
41
|
-
```typescript
|
|
39
|
+
```javascript
|
|
42
40
|
// Get current outages across all resources
|
|
43
41
|
get_infrastructure_news({})
|
|
44
42
|
|
|
45
43
|
// Get scheduled maintenance
|
|
46
44
|
get_infrastructure_news({ time: "scheduled" })
|
|
47
45
|
|
|
48
|
-
// Get comprehensive overview
|
|
46
|
+
// Get comprehensive overview
|
|
49
47
|
get_infrastructure_news({ time: "all" })
|
|
50
48
|
|
|
51
49
|
// Check current status for specific resource
|
|
52
50
|
get_infrastructure_news({ resource: "delta", time: "current" })
|
|
53
51
|
|
|
54
|
-
// Get all news for specific resource
|
|
55
|
-
get_infrastructure_news({ resource: "delta", time: "all" })
|
|
56
|
-
|
|
57
52
|
// Check operational status of specific resources
|
|
58
53
|
get_infrastructure_news({
|
|
59
54
|
resource_ids: ["delta.ncsa.access-ci.org", "bridges2.psc.access-ci.org"]
|
|
@@ -63,10 +58,6 @@ get_infrastructure_news({
|
|
|
63
58
|
get_infrastructure_news({ time: "past", limit: 50 })
|
|
64
59
|
```
|
|
65
60
|
|
|
66
|
-
## Resources
|
|
67
|
-
|
|
68
|
-
- `accessci://system-status`: Current operational status of all ACCESS-CI resources
|
|
69
|
-
|
|
70
61
|
## Installation
|
|
71
62
|
|
|
72
63
|
```bash
|
|
@@ -75,8 +66,6 @@ npm install -g @access-mcp/system-status
|
|
|
75
66
|
|
|
76
67
|
## Configuration
|
|
77
68
|
|
|
78
|
-
Add to your Claude Desktop configuration:
|
|
79
|
-
|
|
80
69
|
```json
|
|
81
70
|
{
|
|
82
71
|
"mcpServers": {
|
|
@@ -88,111 +77,6 @@ Add to your Claude Desktop configuration:
|
|
|
88
77
|
}
|
|
89
78
|
```
|
|
90
79
|
|
|
91
|
-
##
|
|
92
|
-
|
|
93
|
-
### 🚨 **Monitor Current Issues**
|
|
94
|
-
|
|
95
|
-
- "Are there any current outages on ACCESS-CI?"
|
|
96
|
-
- "Is Delta currently operational?"
|
|
97
|
-
- "What systems are experiencing issues right now?"
|
|
98
|
-
|
|
99
|
-
### 🔧 **Track Maintenance Windows**
|
|
100
|
-
|
|
101
|
-
- "When is the next maintenance for Expanse?"
|
|
102
|
-
- "Show me all scheduled maintenance for this week"
|
|
103
|
-
- "Is there upcoming maintenance on Bridges-2?"
|
|
104
|
-
|
|
105
|
-
### 📢 **System Announcements**
|
|
106
|
-
|
|
107
|
-
- "What are the latest system announcements?"
|
|
108
|
-
- "Are there any important notices for ACCESS users?"
|
|
109
|
-
- "Show me recent updates about system changes"
|
|
110
|
-
|
|
111
|
-
### ✅ **Check Resource Status**
|
|
112
|
-
|
|
113
|
-
- "What's the current status of Anvil?"
|
|
114
|
-
- "Is Frontera available for job submission?"
|
|
115
|
-
- "Check if all GPU systems are operational"
|
|
116
|
-
|
|
117
|
-
## Detailed Usage Examples
|
|
118
|
-
|
|
119
|
-
### Checking Current Outages
|
|
120
|
-
|
|
121
|
-
**Natural Language**: "Are there any systems down right now?"
|
|
122
|
-
|
|
123
|
-
**Tool Call**:
|
|
124
|
-
```typescript
|
|
125
|
-
const outages = await get_infrastructure_news({});
|
|
126
|
-
// or explicitly: get_infrastructure_news({ time: "current" })
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
**Returns**: List of active outages with:
|
|
130
|
-
- Affected resources
|
|
131
|
-
- Severity categorization (high/medium/low)
|
|
132
|
-
- Start time and expected resolution
|
|
133
|
-
- Impact description
|
|
134
|
-
- Summary statistics (total outages, affected resources)
|
|
135
|
-
|
|
136
|
-
### Finding Scheduled Maintenance
|
|
137
|
-
|
|
138
|
-
**Natural Language**: "When is Delta scheduled for maintenance?"
|
|
139
|
-
|
|
140
|
-
**Tool Call**:
|
|
141
|
-
```typescript
|
|
142
|
-
const maintenance = await get_infrastructure_news({
|
|
143
|
-
resource: "delta",
|
|
144
|
-
time: "scheduled"
|
|
145
|
-
});
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
**Returns**: Upcoming maintenance windows including:
|
|
149
|
-
- Scheduled start and end times
|
|
150
|
-
- Systems affected
|
|
151
|
-
- Duration in hours
|
|
152
|
-
- Hours until maintenance starts
|
|
153
|
-
- Summary (upcoming in 24h, upcoming this week)
|
|
154
|
-
|
|
155
|
-
### Getting Comprehensive System Overview
|
|
156
|
-
|
|
157
|
-
**Natural Language**: "What are the latest announcements?"
|
|
158
|
-
|
|
159
|
-
**Tool Call**:
|
|
160
|
-
```typescript
|
|
161
|
-
const announcements = await get_infrastructure_news({
|
|
162
|
-
time: "all",
|
|
163
|
-
limit: 10
|
|
164
|
-
});
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
**Returns**: Comprehensive overview including:
|
|
168
|
-
- Current outages
|
|
169
|
-
- Scheduled maintenance
|
|
170
|
-
- Recent past outages (last 30 days)
|
|
171
|
-
- Category breakdown
|
|
172
|
-
- Sorted by relevance (current issues first)
|
|
173
|
-
|
|
174
|
-
### Checking Specific Resource Status
|
|
175
|
-
|
|
176
|
-
**Natural Language**: "Is Expanse available?"
|
|
177
|
-
|
|
178
|
-
**Tool Call**:
|
|
179
|
-
```typescript
|
|
180
|
-
const status = await get_infrastructure_news({
|
|
181
|
-
resource_ids: ["expanse.sdsc.access-ci.org"]
|
|
182
|
-
});
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
**Returns**: Current operational status:
|
|
186
|
-
- Overall status ("operational" or "affected")
|
|
187
|
-
- Severity level if affected
|
|
188
|
-
- Number of active outages
|
|
189
|
-
- Outage details with subjects
|
|
190
|
-
- Timestamp of status check
|
|
191
|
-
|
|
192
|
-
## API Endpoints
|
|
193
|
-
|
|
194
|
-
This server connects to the ACCESS-CI Operations API at `https://operations-api.access-ci.org`
|
|
195
|
-
|
|
196
|
-
## License
|
|
80
|
+
## Resources
|
|
197
81
|
|
|
198
|
-
|
|
82
|
+
- `accessci://system-status` - Current operational status of all ACCESS-CI resources
|
|
@@ -8,12 +8,14 @@ describe("SystemStatusServer Integration Tests", () => {
|
|
|
8
8
|
describe("Real API Integration", () => {
|
|
9
9
|
it("should fetch current outages from real API", async () => {
|
|
10
10
|
const result = await server["handleToolCall"]({
|
|
11
|
+
method: "tools/call",
|
|
11
12
|
params: {
|
|
12
13
|
name: "get_infrastructure_news",
|
|
13
|
-
arguments: { time: "current", limit: 5 }
|
|
14
|
-
}
|
|
14
|
+
arguments: { time: "current", limit: 5 },
|
|
15
|
+
},
|
|
15
16
|
});
|
|
16
|
-
const
|
|
17
|
+
const content = result.content[0];
|
|
18
|
+
const responseData = JSON.parse(content.text);
|
|
17
19
|
expect(responseData).toHaveProperty("total_outages");
|
|
18
20
|
expect(responseData).toHaveProperty("affected_resources");
|
|
19
21
|
expect(responseData).toHaveProperty("severity_counts");
|
|
@@ -32,11 +34,14 @@ describe("SystemStatusServer Integration Tests", () => {
|
|
|
32
34
|
}, 10000);
|
|
33
35
|
it("should fetch scheduled maintenance from real API", async () => {
|
|
34
36
|
const result = await server["handleToolCall"]({
|
|
37
|
+
method: "tools/call",
|
|
35
38
|
params: {
|
|
36
|
-
name: "get_infrastructure_news",
|
|
37
|
-
|
|
39
|
+
name: "get_infrastructure_news",
|
|
40
|
+
arguments: { time: "scheduled", limit: 5 },
|
|
41
|
+
},
|
|
38
42
|
});
|
|
39
|
-
const
|
|
43
|
+
const content = result.content[0];
|
|
44
|
+
const responseData = JSON.parse(content.text);
|
|
40
45
|
expect(responseData).toHaveProperty("total_scheduled");
|
|
41
46
|
expect(responseData).toHaveProperty("upcoming_24h");
|
|
42
47
|
expect(responseData).toHaveProperty("upcoming_week");
|
|
@@ -52,11 +57,14 @@ describe("SystemStatusServer Integration Tests", () => {
|
|
|
52
57
|
}, 10000);
|
|
53
58
|
it("should fetch past outages from real API", async () => {
|
|
54
59
|
const result = await server["handleToolCall"]({
|
|
60
|
+
method: "tools/call",
|
|
55
61
|
params: {
|
|
56
|
-
name: "get_infrastructure_news",
|
|
57
|
-
|
|
62
|
+
name: "get_infrastructure_news",
|
|
63
|
+
arguments: { time: "past", limit: 5 },
|
|
64
|
+
},
|
|
58
65
|
});
|
|
59
|
-
const
|
|
66
|
+
const content = result.content[0];
|
|
67
|
+
const responseData = JSON.parse(content.text);
|
|
60
68
|
expect(responseData).toHaveProperty("total_past_outages");
|
|
61
69
|
expect(responseData).toHaveProperty("recent_outages_30_days");
|
|
62
70
|
expect(responseData).toHaveProperty("affected_resources");
|
|
@@ -74,12 +82,14 @@ describe("SystemStatusServer Integration Tests", () => {
|
|
|
74
82
|
}, 10000);
|
|
75
83
|
it("should get comprehensive system announcements", async () => {
|
|
76
84
|
const result = await server["handleToolCall"]({
|
|
85
|
+
method: "tools/call",
|
|
77
86
|
params: {
|
|
78
87
|
name: "get_infrastructure_news",
|
|
79
|
-
arguments: { time: "all", limit: 20 }
|
|
80
|
-
}
|
|
88
|
+
arguments: { time: "all", limit: 20 },
|
|
89
|
+
},
|
|
81
90
|
});
|
|
82
|
-
const
|
|
91
|
+
const content = result.content[0];
|
|
92
|
+
const responseData = JSON.parse(content.text);
|
|
83
93
|
expect(responseData).toHaveProperty("total_announcements");
|
|
84
94
|
expect(responseData).toHaveProperty("current_outages");
|
|
85
95
|
expect(responseData).toHaveProperty("scheduled_maintenance");
|
|
@@ -97,17 +107,19 @@ describe("SystemStatusServer Integration Tests", () => {
|
|
|
97
107
|
}
|
|
98
108
|
}, 15000);
|
|
99
109
|
it("should check resource status with direct method", async () => {
|
|
100
|
-
// Test with
|
|
110
|
+
// Test with human-readable names - these get resolved to full IDs
|
|
101
111
|
const result = await server["handleToolCall"]({
|
|
112
|
+
method: "tools/call",
|
|
102
113
|
params: {
|
|
103
114
|
name: "get_infrastructure_news",
|
|
104
115
|
arguments: {
|
|
105
|
-
ids: ["
|
|
106
|
-
use_group_api: false
|
|
107
|
-
}
|
|
108
|
-
}
|
|
116
|
+
ids: ["Anvil", "Delta", "Expanse"],
|
|
117
|
+
use_group_api: false,
|
|
118
|
+
},
|
|
119
|
+
},
|
|
109
120
|
});
|
|
110
|
-
const
|
|
121
|
+
const content = result.content[0];
|
|
122
|
+
const responseData = JSON.parse(content.text);
|
|
111
123
|
expect(responseData).toHaveProperty("checked_at");
|
|
112
124
|
expect(responseData).toHaveProperty("resources_checked", 3);
|
|
113
125
|
expect(responseData).toHaveProperty("operational");
|
|
@@ -115,32 +127,36 @@ describe("SystemStatusServer Integration Tests", () => {
|
|
|
115
127
|
expect(responseData).toHaveProperty("api_method", "direct_outages_check");
|
|
116
128
|
expect(Array.isArray(responseData.resource_status)).toBe(true);
|
|
117
129
|
expect(responseData.resource_status).toHaveLength(3);
|
|
118
|
-
// Check resource status structure
|
|
130
|
+
// Check resource status structure - IDs should be resolved to full format
|
|
119
131
|
responseData.resource_status.forEach((resource) => {
|
|
120
132
|
expect(resource).toHaveProperty("resource_id");
|
|
133
|
+
expect(resource.resource_id).toContain(".access-ci.org"); // Resolved to full ID
|
|
121
134
|
expect(resource).toHaveProperty("status");
|
|
122
135
|
expect(["operational", "affected"]).toContain(resource.status);
|
|
123
136
|
expect(resource).toHaveProperty("active_outages");
|
|
124
137
|
expect(Array.isArray(resource.outage_details)).toBe(true);
|
|
125
138
|
});
|
|
126
|
-
},
|
|
139
|
+
}, 15000);
|
|
127
140
|
it("should test group API functionality", async () => {
|
|
128
|
-
// Test group API with a
|
|
141
|
+
// Test group API with a human-readable name
|
|
129
142
|
const result = await server["handleToolCall"]({
|
|
143
|
+
method: "tools/call",
|
|
130
144
|
params: {
|
|
131
145
|
name: "get_infrastructure_news",
|
|
132
146
|
arguments: {
|
|
133
|
-
ids: ["
|
|
134
|
-
use_group_api: true
|
|
135
|
-
}
|
|
136
|
-
}
|
|
147
|
+
ids: ["Anvil"],
|
|
148
|
+
use_group_api: true,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
137
151
|
});
|
|
138
|
-
const
|
|
152
|
+
const content = result.content[0];
|
|
153
|
+
const responseData = JSON.parse(content.text);
|
|
139
154
|
expect(responseData).toHaveProperty("api_method", "resource_group_api");
|
|
140
155
|
expect(responseData).toHaveProperty("resources_checked", 1);
|
|
141
156
|
expect(responseData.resource_status).toHaveLength(1);
|
|
142
157
|
const resourceStatus = responseData.resource_status[0];
|
|
143
|
-
expect(resourceStatus).
|
|
158
|
+
expect(resourceStatus.resource_id).toContain("anvil"); // Resolved ID contains anvil
|
|
159
|
+
expect(resourceStatus.resource_id).toContain(".access-ci.org");
|
|
144
160
|
expect(resourceStatus).toHaveProperty("api_method");
|
|
145
161
|
expect(["group_specific", "group_specific_failed"]).toContain(resourceStatus.api_method);
|
|
146
162
|
// If it succeeded, check structure
|
|
@@ -153,15 +169,17 @@ describe("SystemStatusServer Integration Tests", () => {
|
|
|
153
169
|
expect(resourceStatus.status).toBe("unknown");
|
|
154
170
|
expect(resourceStatus).toHaveProperty("error");
|
|
155
171
|
}
|
|
156
|
-
},
|
|
172
|
+
}, 15000);
|
|
157
173
|
it("should filter outages by resource correctly", async () => {
|
|
158
174
|
const result = await server["handleToolCall"]({
|
|
175
|
+
method: "tools/call",
|
|
159
176
|
params: {
|
|
160
177
|
name: "get_infrastructure_news",
|
|
161
|
-
arguments: { time: "current", query: "anvil" }
|
|
162
|
-
}
|
|
178
|
+
arguments: { time: "current", query: "anvil" },
|
|
179
|
+
},
|
|
163
180
|
});
|
|
164
|
-
const
|
|
181
|
+
const content = result.content[0];
|
|
182
|
+
const responseData = JSON.parse(content.text);
|
|
165
183
|
expect(responseData).toHaveProperty("total_outages");
|
|
166
184
|
// If there are any results, they should match the filter
|
|
167
185
|
if (responseData.outages.length > 0) {
|
|
@@ -178,11 +196,12 @@ describe("SystemStatusServer Integration Tests", () => {
|
|
|
178
196
|
"accessci://system-status",
|
|
179
197
|
"accessci://outages/current",
|
|
180
198
|
"accessci://outages/scheduled",
|
|
181
|
-
"accessci://outages/past"
|
|
199
|
+
"accessci://outages/past",
|
|
182
200
|
];
|
|
183
201
|
for (const uri of resources) {
|
|
184
202
|
const result = await server["handleResourceRead"]({
|
|
185
|
-
|
|
203
|
+
method: "resources/read",
|
|
204
|
+
params: { uri },
|
|
186
205
|
});
|
|
187
206
|
expect(result.contents).toHaveLength(1);
|
|
188
207
|
expect(result.contents[0]).toHaveProperty("uri", uri);
|
|
@@ -190,7 +209,10 @@ describe("SystemStatusServer Integration Tests", () => {
|
|
|
190
209
|
expect(result.contents[0]).toHaveProperty("text");
|
|
191
210
|
if (uri !== "accessci://system-status") {
|
|
192
211
|
// JSON resources should have valid JSON
|
|
193
|
-
|
|
212
|
+
const content = result.contents[0];
|
|
213
|
+
if ("text" in content) {
|
|
214
|
+
expect(() => JSON.parse(content.text)).not.toThrow();
|
|
215
|
+
}
|
|
194
216
|
}
|
|
195
217
|
}
|
|
196
218
|
}, 15000);
|
|
@@ -199,24 +221,28 @@ describe("SystemStatusServer Integration Tests", () => {
|
|
|
199
221
|
it("should handle empty API responses", async () => {
|
|
200
222
|
// This tests the robustness of our logic with potentially empty responses
|
|
201
223
|
const result = await server["handleToolCall"]({
|
|
224
|
+
method: "tools/call",
|
|
202
225
|
params: {
|
|
203
226
|
name: "get_infrastructure_news",
|
|
204
|
-
arguments: { time: "current", query: "nonexistent-resource-xyz-12345" }
|
|
205
|
-
}
|
|
227
|
+
arguments: { time: "current", query: "nonexistent-resource-xyz-12345" },
|
|
228
|
+
},
|
|
206
229
|
});
|
|
207
|
-
const
|
|
230
|
+
const content = result.content[0];
|
|
231
|
+
const responseData = JSON.parse(content.text);
|
|
208
232
|
expect(responseData).toHaveProperty("total_outages", 0);
|
|
209
233
|
expect(responseData.outages).toHaveLength(0);
|
|
210
234
|
expect(responseData.affected_resources).toHaveLength(0);
|
|
211
235
|
}, 10000);
|
|
212
236
|
it("should handle large limit values gracefully", async () => {
|
|
213
237
|
const result = await server["handleToolCall"]({
|
|
238
|
+
method: "tools/call",
|
|
214
239
|
params: {
|
|
215
240
|
name: "get_infrastructure_news",
|
|
216
|
-
arguments: { time: "past", limit: 1000 }
|
|
217
|
-
}
|
|
241
|
+
arguments: { time: "past", limit: 1000 },
|
|
242
|
+
},
|
|
218
243
|
});
|
|
219
|
-
const
|
|
244
|
+
const content = result.content[0];
|
|
245
|
+
const responseData = JSON.parse(content.text);
|
|
220
246
|
expect(responseData).toHaveProperty("total_past_outages");
|
|
221
247
|
// Should not crash or timeout
|
|
222
248
|
expect(responseData.outages.length).toBeLessThanOrEqual(1000);
|