@access-mcp/system-status 0.2.3 → 0.3.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 CHANGED
@@ -1,4 +1,4 @@
1
- # ACCESS-CI System Status MCP Server
1
+ # System Status MCP Server
2
2
 
3
3
  MCP server providing real-time system status information for ACCESS-CI resources.
4
4
 
@@ -9,27 +9,35 @@ This server provides critical operational information about ACCESS-CI systems, i
9
9
  ## Tools
10
10
 
11
11
  ### get_current_outages
12
+
12
13
  Get current system outages and issues affecting ACCESS-CI resources.
13
14
 
14
15
  **Parameters:**
16
+
15
17
  - `resource_filter` (string, optional): Filter by specific resource name or ID
16
18
 
17
19
  ### get_scheduled_maintenance
20
+
18
21
  Get scheduled maintenance and future outages for ACCESS-CI resources.
19
22
 
20
23
  **Parameters:**
24
+
21
25
  - `resource_filter` (string, optional): Filter by specific resource name or ID
22
26
 
23
27
  ### get_system_announcements
28
+
24
29
  Get all system announcements (current and scheduled).
25
30
 
26
31
  **Parameters:**
32
+
27
33
  - `limit` (number, optional): Maximum number of announcements to return (default: 50)
28
34
 
29
35
  ### get_resource_status
36
+
30
37
  Get the current operational status of a specific resource.
31
38
 
32
39
  **Parameters:**
40
+
33
41
  - `resource_id` (string): The resource ID to check status for
34
42
 
35
43
  ## Resources
@@ -42,7 +50,7 @@ Get the current operational status of a specific resource.
42
50
  npm install -g @access-mcp/system-status
43
51
  ```
44
52
 
45
- ## Usage
53
+ ## Configuration
46
54
 
47
55
  Add to your Claude Desktop configuration:
48
56
 
@@ -50,16 +58,111 @@ Add to your Claude Desktop configuration:
50
58
  {
51
59
  "mcpServers": {
52
60
  "access-system-status": {
53
- "command": "access-mcp-system-status"
61
+ "command": "npx",
62
+ "args": ["@access-mcp/system-status"]
54
63
  }
55
64
  }
56
65
  }
57
66
  ```
58
67
 
68
+ ## Usage Examples
69
+
70
+ ### 🚨 **Monitor Current Issues**
71
+
72
+ - "Are there any current outages on ACCESS-CI?"
73
+ - "Is Delta currently operational?"
74
+ - "What systems are experiencing issues right now?"
75
+
76
+ ### 🔧 **Track Maintenance Windows**
77
+
78
+ - "When is the next maintenance for Expanse?"
79
+ - "Show me all scheduled maintenance for this week"
80
+ - "Is there upcoming maintenance on Bridges-2?"
81
+
82
+ ### 📢 **System Announcements**
83
+
84
+ - "What are the latest system announcements?"
85
+ - "Are there any important notices for ACCESS users?"
86
+ - "Show me recent updates about system changes"
87
+
88
+ ### ✅ **Check Resource Status**
89
+
90
+ - "What's the current status of Anvil?"
91
+ - "Is Frontera available for job submission?"
92
+ - "Check if all GPU systems are operational"
93
+
94
+ ## Detailed Usage Examples
95
+
96
+ ### Checking Current Outages
97
+
98
+ **Natural Language**: "Are there any systems down right now?"
99
+
100
+ **Tool Call**:
101
+ ```typescript
102
+ const outages = await get_current_outages();
103
+ ```
104
+
105
+ **Returns**: List of active outages with:
106
+ - Affected resources
107
+ - Start time and expected resolution
108
+ - Impact description
109
+ - Workaround information if available
110
+
111
+ ### Finding Scheduled Maintenance
112
+
113
+ **Natural Language**: "When is Delta scheduled for maintenance?"
114
+
115
+ **Tool Call**:
116
+ ```typescript
117
+ const maintenance = await get_scheduled_maintenance({
118
+ resource_filter: "delta"
119
+ });
120
+ ```
121
+
122
+ **Returns**: Upcoming maintenance windows including:
123
+ - Scheduled start and end times
124
+ - Systems affected
125
+ - Type of maintenance
126
+ - Expected impact on users
127
+
128
+ ### Getting System Announcements
129
+
130
+ **Natural Language**: "What are the latest announcements?"
131
+
132
+ **Tool Call**:
133
+ ```typescript
134
+ const announcements = await get_system_announcements({
135
+ limit: 10
136
+ });
137
+ ```
138
+
139
+ **Returns**: Recent announcements about:
140
+ - Policy changes
141
+ - New features or services
142
+ - Important deadlines
143
+ - System-wide updates
144
+
145
+ ### Checking Specific Resource Status
146
+
147
+ **Natural Language**: "Is Expanse available?"
148
+
149
+ **Tool Call**:
150
+ ```typescript
151
+ const status = await get_resource_status({
152
+ resource_id: "expanse.sdsc.xsede.org"
153
+ });
154
+ ```
155
+
156
+ **Returns**: Current operational status:
157
+ - Overall system health
158
+ - Service availability
159
+ - Performance metrics
160
+ - Any active issues or limitations
161
+
59
162
  ## API Endpoints
60
163
 
61
164
  This server connects to the ACCESS-CI Operations API at `https://operations-api.access-ci.org`
62
165
 
63
166
  ## License
64
167
 
65
- MIT
168
+ MIT
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { SystemStatusServer } from './server.js';
3
- import { startWebServer } from './web-server.js';
2
+ import { SystemStatusServer } from "./server.js";
3
+ import { startWebServer } from "./web-server.js";
4
4
  async function main() {
5
5
  // Check if we should run as web server (for deployment)
6
6
  const port = process.env.PORT;
package/dist/server.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { BaseAccessServer } from '@access-mcp/shared';
1
+ import { BaseAccessServer } from "@access-mcp/shared";
2
2
  export declare class SystemStatusServer extends BaseAccessServer {
3
3
  constructor();
4
4
  protected getTools(): ({
package/dist/server.js CHANGED
@@ -1,65 +1,65 @@
1
- import { BaseAccessServer, handleApiError } from '@access-mcp/shared';
1
+ import { BaseAccessServer, handleApiError } from "@access-mcp/shared";
2
2
  export class SystemStatusServer extends BaseAccessServer {
3
3
  constructor() {
4
- super('access-mcp-system-status', '0.1.0', 'https://operations-api.access-ci.org');
4
+ super("access-mcp-system-status", "0.3.0", "https://operations-api.access-ci.org");
5
5
  }
6
6
  getTools() {
7
7
  return [
8
8
  {
9
- name: 'get_current_outages',
10
- description: 'Get current system outages and issues affecting ACCESS-CI resources',
9
+ name: "get_current_outages",
10
+ description: "Get current system outages and issues affecting ACCESS-CI resources",
11
11
  inputSchema: {
12
- type: 'object',
12
+ type: "object",
13
13
  properties: {
14
14
  resource_filter: {
15
- type: 'string',
16
- description: 'Optional: filter by specific resource name or ID',
15
+ type: "string",
16
+ description: "Optional: filter by specific resource name or ID",
17
17
  },
18
18
  },
19
19
  required: [],
20
20
  },
21
21
  },
22
22
  {
23
- name: 'get_scheduled_maintenance',
24
- description: 'Get scheduled maintenance and future outages for ACCESS-CI resources',
23
+ name: "get_scheduled_maintenance",
24
+ description: "Get scheduled maintenance and future outages for ACCESS-CI resources",
25
25
  inputSchema: {
26
- type: 'object',
26
+ type: "object",
27
27
  properties: {
28
28
  resource_filter: {
29
- type: 'string',
30
- description: 'Optional: filter by specific resource name or ID',
29
+ type: "string",
30
+ description: "Optional: filter by specific resource name or ID",
31
31
  },
32
32
  },
33
33
  required: [],
34
34
  },
35
35
  },
36
36
  {
37
- name: 'get_system_announcements',
38
- description: 'Get all system announcements (current and scheduled)',
37
+ name: "get_system_announcements",
38
+ description: "Get all system announcements (current and scheduled)",
39
39
  inputSchema: {
40
- type: 'object',
40
+ type: "object",
41
41
  properties: {
42
42
  limit: {
43
- type: 'number',
44
- description: 'Maximum number of announcements to return (default: 50)',
43
+ type: "number",
44
+ description: "Maximum number of announcements to return (default: 50)",
45
45
  },
46
46
  },
47
47
  required: [],
48
48
  },
49
49
  },
50
50
  {
51
- name: 'check_resource_status',
52
- description: 'Check the operational status of specific ACCESS-CI resources',
51
+ name: "check_resource_status",
52
+ description: "Check the operational status of specific ACCESS-CI resources",
53
53
  inputSchema: {
54
- type: 'object',
54
+ type: "object",
55
55
  properties: {
56
56
  resource_ids: {
57
- type: 'array',
58
- items: { type: 'string' },
59
- description: 'List of resource IDs to check status for',
57
+ type: "array",
58
+ items: { type: "string" },
59
+ description: "List of resource IDs to check status for",
60
60
  },
61
61
  },
62
- required: ['resource_ids'],
62
+ required: ["resource_ids"],
63
63
  },
64
64
  },
65
65
  ];
@@ -67,22 +67,22 @@ export class SystemStatusServer extends BaseAccessServer {
67
67
  getResources() {
68
68
  return [
69
69
  {
70
- uri: 'accessci://system-status',
71
- name: 'ACCESS-CI System Status',
72
- description: 'Real-time status of ACCESS-CI infrastructure, outages, and maintenance',
73
- mimeType: 'application/json',
70
+ uri: "accessci://system-status",
71
+ name: "ACCESS-CI System Status",
72
+ description: "Real-time status of ACCESS-CI infrastructure, outages, and maintenance",
73
+ mimeType: "application/json",
74
74
  },
75
75
  {
76
- uri: 'accessci://outages/current',
77
- name: 'Current Outages',
78
- description: 'Currently active outages and system issues',
79
- mimeType: 'application/json',
76
+ uri: "accessci://outages/current",
77
+ name: "Current Outages",
78
+ description: "Currently active outages and system issues",
79
+ mimeType: "application/json",
80
80
  },
81
81
  {
82
- uri: 'accessci://outages/scheduled',
83
- name: 'Scheduled Maintenance',
84
- description: 'Upcoming scheduled maintenance and planned outages',
85
- mimeType: 'application/json',
82
+ uri: "accessci://outages/scheduled",
83
+ name: "Scheduled Maintenance",
84
+ description: "Upcoming scheduled maintenance and planned outages",
85
+ mimeType: "application/json",
86
86
  },
87
87
  ];
88
88
  }
@@ -90,13 +90,13 @@ export class SystemStatusServer extends BaseAccessServer {
90
90
  const { name, arguments: args = {} } = request.params;
91
91
  try {
92
92
  switch (name) {
93
- case 'get_current_outages':
93
+ case "get_current_outages":
94
94
  return await this.getCurrentOutages(args.resource_filter);
95
- case 'get_scheduled_maintenance':
95
+ case "get_scheduled_maintenance":
96
96
  return await this.getScheduledMaintenance(args.resource_filter);
97
- case 'get_system_announcements':
97
+ case "get_system_announcements":
98
98
  return await this.getSystemAnnouncements(args.limit);
99
- case 'check_resource_status':
99
+ case "check_resource_status":
100
100
  return await this.checkResourceStatus(args.resource_ids);
101
101
  default:
102
102
  throw new Error(`Unknown tool: ${name}`);
@@ -106,7 +106,7 @@ export class SystemStatusServer extends BaseAccessServer {
106
106
  return {
107
107
  content: [
108
108
  {
109
- type: 'text',
109
+ type: "text",
110
110
  text: `Error: ${handleApiError(error)}`,
111
111
  },
112
112
  ],
@@ -116,34 +116,34 @@ export class SystemStatusServer extends BaseAccessServer {
116
116
  async handleResourceRead(request) {
117
117
  const { uri } = request.params;
118
118
  switch (uri) {
119
- case 'accessci://system-status':
119
+ case "accessci://system-status":
120
120
  return {
121
121
  contents: [
122
122
  {
123
123
  uri,
124
- mimeType: 'text/plain',
125
- text: 'ACCESS-CI System Status API - Monitor real-time status, outages, and maintenance for ACCESS-CI resources.',
124
+ mimeType: "text/plain",
125
+ text: "ACCESS-CI System Status API - Monitor real-time status, outages, and maintenance for ACCESS-CI resources.",
126
126
  },
127
127
  ],
128
128
  };
129
- case 'accessci://outages/current':
129
+ case "accessci://outages/current":
130
130
  const currentOutages = await this.getCurrentOutages();
131
131
  return {
132
132
  contents: [
133
133
  {
134
134
  uri,
135
- mimeType: 'application/json',
135
+ mimeType: "application/json",
136
136
  text: currentOutages.content[0].text,
137
137
  },
138
138
  ],
139
139
  };
140
- case 'accessci://outages/scheduled':
140
+ case "accessci://outages/scheduled":
141
141
  const scheduledMaintenance = await this.getScheduledMaintenance();
142
142
  return {
143
143
  contents: [
144
144
  {
145
145
  uri,
146
- mimeType: 'application/json',
146
+ mimeType: "application/json",
147
147
  text: scheduledMaintenance.content[0].text,
148
148
  },
149
149
  ],
@@ -153,7 +153,7 @@ export class SystemStatusServer extends BaseAccessServer {
153
153
  }
154
154
  }
155
155
  async getCurrentOutages(resourceFilter) {
156
- const response = await this.httpClient.get('/wh2/news/v1/affiliation/access-ci.org/current_outages/');
156
+ const response = await this.httpClient.get("/wh2/news/v1/affiliation/access-ci.org/current_outages/");
157
157
  let outages = response.data.results || [];
158
158
  // Filter by resource if specified
159
159
  if (resourceFilter) {
@@ -172,16 +172,17 @@ export class SystemStatusServer extends BaseAccessServer {
172
172
  affectedResources.add(resource.ResourceName);
173
173
  });
174
174
  // Categorize severity (basic heuristic)
175
- const subject = outage.Subject?.toLowerCase() || '';
176
- let severity = 'unknown';
177
- if (subject.includes('emergency') || subject.includes('critical')) {
178
- severity = 'high';
175
+ const subject = outage.Subject?.toLowerCase() || "";
176
+ let severity = "unknown";
177
+ if (subject.includes("emergency") || subject.includes("critical")) {
178
+ severity = "high";
179
179
  }
180
- else if (subject.includes('maintenance') || subject.includes('scheduled')) {
181
- severity = 'low';
180
+ else if (subject.includes("maintenance") ||
181
+ subject.includes("scheduled")) {
182
+ severity = "low";
182
183
  }
183
184
  else {
184
- severity = 'medium';
185
+ severity = "medium";
185
186
  }
186
187
  severityCounts[severity]++;
187
188
  return {
@@ -195,22 +196,22 @@ export class SystemStatusServer extends BaseAccessServer {
195
196
  total_outages: outages.length,
196
197
  affected_resources: Array.from(affectedResources),
197
198
  severity_counts: severityCounts,
198
- outages: enhancedOutages
199
+ outages: enhancedOutages,
199
200
  };
200
201
  return {
201
202
  content: [
202
203
  {
203
- type: 'text',
204
+ type: "text",
204
205
  text: JSON.stringify({
205
206
  ...summary,
206
- affected_resources: summary.affected_resources
207
+ affected_resources: summary.affected_resources,
207
208
  }, null, 2),
208
209
  },
209
210
  ],
210
211
  };
211
212
  }
212
213
  async getScheduledMaintenance(resourceFilter) {
213
- const response = await this.httpClient.get('/wh2/news/v1/affiliation/access-ci.org/future_outages/');
214
+ const response = await this.httpClient.get("/wh2/news/v1/affiliation/access-ci.org/future_outages/");
214
215
  let maintenance = response.data.results || [];
215
216
  // Filter by resource if specified
216
217
  if (resourceFilter) {
@@ -250,18 +251,19 @@ export class SystemStatusServer extends BaseAccessServer {
250
251
  hours_until_start: Math.max(0, Math.round(hoursUntil)),
251
252
  duration_hours: item.OutageEndDateTime && item.OutageStartDateTime
252
253
  ? Math.round((new Date(item.OutageEndDateTime).getTime() -
253
- new Date(item.OutageStartDateTime).getTime()) / (1000 * 60 * 60))
254
+ new Date(item.OutageStartDateTime).getTime()) /
255
+ (1000 * 60 * 60))
254
256
  : null,
255
257
  };
256
- })
258
+ }),
257
259
  };
258
260
  return {
259
261
  content: [
260
262
  {
261
- type: 'text',
263
+ type: "text",
262
264
  text: JSON.stringify({
263
265
  ...summary,
264
- affected_resources: summary.affected_resources
266
+ affected_resources: summary.affected_resources,
265
267
  }, null, 2),
266
268
  },
267
269
  ],
@@ -270,8 +272,8 @@ export class SystemStatusServer extends BaseAccessServer {
270
272
  async getSystemAnnouncements(limit = 50) {
271
273
  // Get both current and future announcements
272
274
  const [currentResponse, futureResponse] = await Promise.all([
273
- this.httpClient.get('/wh2/news/v1/affiliation/access-ci.org/current_outages/'),
274
- this.httpClient.get('/wh2/news/v1/affiliation/access-ci.org/future_outages/')
275
+ this.httpClient.get("/wh2/news/v1/affiliation/access-ci.org/current_outages/"),
276
+ this.httpClient.get("/wh2/news/v1/affiliation/access-ci.org/future_outages/"),
275
277
  ]);
276
278
  const currentOutages = currentResponse.data.results || [];
277
279
  const futureOutages = futureResponse.data.results || [];
@@ -286,12 +288,12 @@ export class SystemStatusServer extends BaseAccessServer {
286
288
  return {
287
289
  content: [
288
290
  {
289
- type: 'text',
291
+ type: "text",
290
292
  text: JSON.stringify({
291
293
  total_announcements: allAnnouncements.length,
292
294
  current_outages: currentOutages.length,
293
295
  scheduled_maintenance: futureOutages.length,
294
- announcements: allAnnouncements
296
+ announcements: allAnnouncements,
295
297
  }, null, 2),
296
298
  },
297
299
  ],
@@ -301,21 +303,21 @@ export class SystemStatusServer extends BaseAccessServer {
301
303
  // Get current outages to check against resource IDs
302
304
  const currentOutages = await this.getCurrentOutages();
303
305
  const outageData = JSON.parse(currentOutages.content[0].text);
304
- const resourceStatus = resourceIds.map(resourceId => {
306
+ const resourceStatus = resourceIds.map((resourceId) => {
305
307
  const affectedOutages = outageData.outages.filter((outage) => outage.AffectedResources?.some((resource) => resource.ResourceID?.toString() === resourceId ||
306
308
  resource.ResourceName?.toLowerCase().includes(resourceId.toLowerCase())));
307
- let status = 'operational';
309
+ let status = "operational";
308
310
  let severity = null;
309
311
  if (affectedOutages.length > 0) {
310
- status = 'affected';
312
+ status = "affected";
311
313
  // Get highest severity
312
314
  const severities = affectedOutages.map((o) => o.severity);
313
- if (severities.includes('high'))
314
- severity = 'high';
315
- else if (severities.includes('medium'))
316
- severity = 'medium';
315
+ if (severities.includes("high"))
316
+ severity = "high";
317
+ else if (severities.includes("medium"))
318
+ severity = "medium";
317
319
  else
318
- severity = 'low';
320
+ severity = "low";
319
321
  }
320
322
  return {
321
323
  resource_id: resourceId,
@@ -325,20 +327,21 @@ export class SystemStatusServer extends BaseAccessServer {
325
327
  outage_details: affectedOutages.map((outage) => ({
326
328
  subject: outage.Subject,
327
329
  severity: outage.severity,
328
- posted: outage.posted_time
329
- }))
330
+ posted: outage.posted_time,
331
+ })),
330
332
  };
331
333
  });
332
334
  return {
333
335
  content: [
334
336
  {
335
- type: 'text',
337
+ type: "text",
336
338
  text: JSON.stringify({
337
339
  checked_at: new Date().toISOString(),
338
340
  resources_checked: resourceIds.length,
339
- operational: resourceStatus.filter(r => r.status === 'operational').length,
340
- affected: resourceStatus.filter(r => r.status === 'affected').length,
341
- resource_status: resourceStatus
341
+ operational: resourceStatus.filter((r) => r.status === "operational").length,
342
+ affected: resourceStatus.filter((r) => r.status === "affected")
343
+ .length,
344
+ resource_status: resourceStatus,
342
345
  }, null, 2),
343
346
  },
344
347
  ],
@@ -1,46 +1,46 @@
1
- import express from 'express';
2
- import path from 'path';
3
- import { SystemStatusServer } from './server.js';
1
+ import express from "express";
2
+ import path from "path";
3
+ import { SystemStatusServer } from "./server.js";
4
4
  export function startWebServer(port = 3000) {
5
5
  const app = express();
6
6
  const server = new SystemStatusServer();
7
7
  // Serve static files from public directory
8
- const publicDir = path.join(__dirname, '../../../public');
8
+ const publicDir = path.join(__dirname, "../../../public");
9
9
  app.use(express.static(publicDir));
10
10
  // Health check endpoint
11
- app.get('/health', (req, res) => {
12
- res.json({ status: 'ok', service: 'access-mcp-system-status' });
11
+ app.get("/health", (req, res) => {
12
+ res.json({ status: "ok", service: "access-mcp-system-status" });
13
13
  });
14
14
  // API endpoint to list tools (for documentation)
15
- app.get('/api/tools', (req, res) => {
15
+ app.get("/api/tools", (req, res) => {
16
16
  res.json({
17
- server: 'ACCESS-CI System Status MCP Server',
18
- version: '0.1.0',
17
+ server: "ACCESS-CI System Status MCP Server",
18
+ version: "0.3.0",
19
19
  tools: [
20
20
  {
21
- name: 'get_current_outages',
22
- description: 'Get current system outages and issues affecting ACCESS-CI resources'
21
+ name: "get_current_outages",
22
+ description: "Get current system outages and issues affecting ACCESS-CI resources",
23
23
  },
24
24
  {
25
- name: 'get_scheduled_maintenance',
26
- description: 'Get scheduled maintenance and future outages for ACCESS-CI resources'
25
+ name: "get_scheduled_maintenance",
26
+ description: "Get scheduled maintenance and future outages for ACCESS-CI resources",
27
27
  },
28
28
  {
29
- name: 'get_system_announcements',
30
- description: 'Get all system announcements (current and scheduled)'
29
+ name: "get_system_announcements",
30
+ description: "Get all system announcements (current and scheduled)",
31
31
  },
32
32
  {
33
- name: 'check_resource_status',
34
- description: 'Check the operational status of specific ACCESS-CI resources'
35
- }
33
+ name: "check_resource_status",
34
+ description: "Check the operational status of specific ACCESS-CI resources",
35
+ },
36
36
  ],
37
37
  resources: [
38
38
  {
39
- uri: 'accessci://system-status',
40
- name: 'ACCESS-CI System Status',
41
- description: 'Real-time status of ACCESS-CI infrastructure, outages, and maintenance'
42
- }
43
- ]
39
+ uri: "accessci://system-status",
40
+ name: "ACCESS-CI System Status",
41
+ description: "Real-time status of ACCESS-CI infrastructure, outages, and maintenance",
42
+ },
43
+ ],
44
44
  });
45
45
  });
46
46
  // Start server
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@access-mcp/system-status",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "MCP server for ACCESS-CI System Status and Outages API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -36,7 +36,7 @@
36
36
  "node": ">=18.0.0"
37
37
  },
38
38
  "dependencies": {
39
- "@access-mcp/shared": "^0.2.2",
39
+ "@access-mcp/shared": "^0.3.0",
40
40
  "express": "^4.18.0"
41
41
  }
42
42
  }