@ionhour/mcp-server 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +154 -0
- package/package.json +35 -0
- package/src/bin.d.ts +2 -0
- package/src/bin.js +51 -0
- package/src/bin.js.map +1 -0
- package/src/index.d.ts +17 -0
- package/src/index.js +115 -0
- package/src/index.js.map +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# @ionhour/mcp-server
|
|
2
|
+
|
|
3
|
+
Connect AI assistants to your [IonHour](https://ionhour.com) uptime monitoring workspace using the [Model Context Protocol](https://modelcontextprotocol.io).
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Set your API key
|
|
9
|
+
export IONHOUR_API_KEY=ionh_your_key_here
|
|
10
|
+
|
|
11
|
+
# Run with npx (no install needed)
|
|
12
|
+
npx @ionhour/mcp-server
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Setup with AI Assistants
|
|
16
|
+
|
|
17
|
+
### Claude Code
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
claude mcp add ionhour -- npx @ionhour/mcp-server
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Claude Desktop
|
|
24
|
+
|
|
25
|
+
Add to your `claude_desktop_config.json`:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"mcpServers": {
|
|
30
|
+
"ionhour": {
|
|
31
|
+
"command": "npx",
|
|
32
|
+
"args": ["@ionhour/mcp-server"],
|
|
33
|
+
"env": {
|
|
34
|
+
"IONHOUR_API_KEY": "ionh_your_key_here"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Cursor
|
|
42
|
+
|
|
43
|
+
Add to your `.cursor/mcp.json`:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"mcpServers": {
|
|
48
|
+
"ionhour": {
|
|
49
|
+
"command": "npx",
|
|
50
|
+
"args": ["@ionhour/mcp-server"],
|
|
51
|
+
"env": {
|
|
52
|
+
"IONHOUR_API_KEY": "ionh_your_key_here"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### VS Code (Copilot)
|
|
60
|
+
|
|
61
|
+
Add to your `.vscode/mcp.json`:
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"servers": {
|
|
66
|
+
"ionhour": {
|
|
67
|
+
"command": "npx",
|
|
68
|
+
"args": ["@ionhour/mcp-server"],
|
|
69
|
+
"env": {
|
|
70
|
+
"IONHOUR_API_KEY": "ionh_your_key_here"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Getting an API Key
|
|
78
|
+
|
|
79
|
+
1. Go to your IonHour workspace **Settings > API Keys**
|
|
80
|
+
2. Create a new key with **Read & Write** or **Read Only** permission
|
|
81
|
+
3. Copy the key (starts with `ionh_`)
|
|
82
|
+
|
|
83
|
+
## Available Tools
|
|
84
|
+
|
|
85
|
+
### Workspace
|
|
86
|
+
- `get_workspace` - Get workspace details
|
|
87
|
+
- `get_workspace_summary` - Overview of projects, checks, and incidents
|
|
88
|
+
- `get_workspace_reliability` - Uptime, incident count, and MTTR metrics
|
|
89
|
+
- `list_team_members` - List workspace members and roles
|
|
90
|
+
- `send_invitation` - Invite users to the workspace
|
|
91
|
+
|
|
92
|
+
### Projects
|
|
93
|
+
- `list_projects` / `create_project` / `update_project`
|
|
94
|
+
|
|
95
|
+
### Checks (Monitors)
|
|
96
|
+
- `register_check` - Create a new monitoring check
|
|
97
|
+
- `list_checks` / `list_checks_by_status` / `find_check_by_name`
|
|
98
|
+
- `get_check_status` - Detailed status with recent signals
|
|
99
|
+
- `get_check_uptime` - Uptime percentage with daily buckets
|
|
100
|
+
- `pause_check` / `resume_check`
|
|
101
|
+
|
|
102
|
+
### Signals (Heartbeats)
|
|
103
|
+
- `send_heartbeat` - Send a success signal
|
|
104
|
+
- `send_failure_signal` - Report a failure
|
|
105
|
+
- `list_signals` - View signal history
|
|
106
|
+
|
|
107
|
+
### Incidents
|
|
108
|
+
- `list_incidents` / `search_incidents` / `get_incident`
|
|
109
|
+
- `get_incident_timeline` - Incident history for a check
|
|
110
|
+
- `create_incident` / `acknowledge_incident` / `resolve_incident`
|
|
111
|
+
- `add_incident_note`
|
|
112
|
+
|
|
113
|
+
### Deployments
|
|
114
|
+
- `create_deployment` - Start a deployment window (auto-pauses checks)
|
|
115
|
+
- `end_deployment` - End deployment and resume checks
|
|
116
|
+
- `list_deployments`
|
|
117
|
+
|
|
118
|
+
### Dependencies
|
|
119
|
+
- `list_dependencies` / `get_dependency` / `create_dependency`
|
|
120
|
+
- `update_dependency_status`
|
|
121
|
+
|
|
122
|
+
### Status Pages & Alerts
|
|
123
|
+
- `list_status_pages` / `create_status_page` / `update_status_page`
|
|
124
|
+
- `create_announcement`
|
|
125
|
+
- `list_alert_channels` / `create_alert_channel` / `update_alert_channel`
|
|
126
|
+
- `list_escalation_rules` / `create_escalation_rule` / `update_escalation_rule`
|
|
127
|
+
|
|
128
|
+
## CLI Options
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
npx @ionhour/mcp-server [options]
|
|
132
|
+
|
|
133
|
+
Options:
|
|
134
|
+
--api-key KEY IonHour API key (or set IONHOUR_API_KEY env var)
|
|
135
|
+
--base-url URL API base URL (default: https://app.failsignal.com)
|
|
136
|
+
--help, -h Show help
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## How It Works
|
|
140
|
+
|
|
141
|
+
This package runs a local MCP server over **stdio** that proxies requests to the IonHour API. Your AI assistant communicates with this local server, which forwards tool calls to your IonHour workspace.
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
AI Assistant <--stdio--> @ionhour/mcp-server <--HTTPS--> IonHour API
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Requirements
|
|
148
|
+
|
|
149
|
+
- Node.js >= 18
|
|
150
|
+
- An IonHour account with an API key
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ionhour/mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "IonHour MCP Server -- connect AI assistants to your uptime monitoring workspace",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"bin": {
|
|
7
|
+
"ionhour-mcp": "./src/bin.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./src/index.js",
|
|
10
|
+
"types": "./src/index.d.ts",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=18"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"mcp",
|
|
17
|
+
"model-context-protocol",
|
|
18
|
+
"ionhour",
|
|
19
|
+
"monitoring",
|
|
20
|
+
"uptime"
|
|
21
|
+
],
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/ionhour/ionhour",
|
|
25
|
+
"directory": "libs/mcp-server"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://ionhour.com",
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@modelcontextprotocol/sdk": "^1.26.0"
|
|
33
|
+
},
|
|
34
|
+
"module": "./src/index.js"
|
|
35
|
+
}
|
package/src/bin.d.ts
ADDED
package/src/bin.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { startProxyServer, resolveConfig } from './index.js';
|
|
3
|
+
function parseArgs() {
|
|
4
|
+
const args = process.argv.slice(2);
|
|
5
|
+
const result = {};
|
|
6
|
+
for (let i = 0; i < args.length; i++) {
|
|
7
|
+
if (args[i] === '--api-key' && args[i + 1]) {
|
|
8
|
+
result.apiKey = args[++i];
|
|
9
|
+
}
|
|
10
|
+
else if (args[i] === '--base-url' && args[i + 1]) {
|
|
11
|
+
result.baseUrl = args[++i];
|
|
12
|
+
}
|
|
13
|
+
else if (args[i] === '--help' || args[i] === '-h') {
|
|
14
|
+
process.stderr.write(`
|
|
15
|
+
IonHour MCP Server v0.1.0
|
|
16
|
+
|
|
17
|
+
Connect AI assistants to your IonHour monitoring workspace.
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
npx @ionhour/mcp-server [options]
|
|
21
|
+
|
|
22
|
+
Options:
|
|
23
|
+
--api-key KEY IonHour API key (or set IONHOUR_API_KEY env var)
|
|
24
|
+
--base-url URL IonHour API base URL (default: https://app.failsignal.com)
|
|
25
|
+
--help, -h Show this help message
|
|
26
|
+
|
|
27
|
+
Setup with Claude Code:
|
|
28
|
+
claude mcp add ionhour -- npx @ionhour/mcp-server
|
|
29
|
+
|
|
30
|
+
Environment Variables:
|
|
31
|
+
IONHOUR_API_KEY API key for authentication
|
|
32
|
+
IONHOUR_BASE_URL Base URL override
|
|
33
|
+
`);
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
async function main() {
|
|
40
|
+
try {
|
|
41
|
+
const args = parseArgs();
|
|
42
|
+
const config = resolveConfig(args);
|
|
43
|
+
await startProxyServer(config);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
process.stderr.write(`Error: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
main();
|
|
51
|
+
//# sourceMappingURL=bin.js.map
|
package/src/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../../../libs/mcp-server/src/bin.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7D,SAAS,SAAS;IAChB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,MAAM,GAA0C,EAAE,CAAC;IAEzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC3C,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,YAAY,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACnD,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7B,CAAC;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;CAmB1B,CAAC,CAAC;YACG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CACrE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface IonHourMcpConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Resolve configuration from explicit overrides, environment variables, or defaults.
|
|
7
|
+
* Throws if no API key is available from any source.
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveConfig(overrides?: Partial<IonHourMcpConfig>): IonHourMcpConfig;
|
|
10
|
+
/**
|
|
11
|
+
* Start the stdio-to-HTTP MCP proxy server.
|
|
12
|
+
*
|
|
13
|
+
* 1. Connects to the remote IonHour MCP endpoint as a client
|
|
14
|
+
* 2. Exposes an MCP server over stdio
|
|
15
|
+
* 3. Proxies all tool/resource/prompt requests to the remote endpoint
|
|
16
|
+
*/
|
|
17
|
+
export declare function startProxyServer(config: IonHourMcpConfig): Promise<void>;
|
package/src/index.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
3
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
4
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
5
|
+
import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Resolve configuration from explicit overrides, environment variables, or defaults.
|
|
8
|
+
* Throws if no API key is available from any source.
|
|
9
|
+
*/
|
|
10
|
+
export function resolveConfig(overrides) {
|
|
11
|
+
const apiKey = overrides?.apiKey || process.env['IONHOUR_API_KEY'];
|
|
12
|
+
if (!apiKey) {
|
|
13
|
+
throw new Error('IonHour API key is required. Set IONHOUR_API_KEY environment variable or pass --api-key flag.');
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
apiKey,
|
|
17
|
+
baseUrl: overrides?.baseUrl ||
|
|
18
|
+
process.env['IONHOUR_BASE_URL'] ||
|
|
19
|
+
'https://app.failsignal.com',
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create an MCP Client connected to the remote IonHour API endpoint.
|
|
24
|
+
*/
|
|
25
|
+
async function createRemoteClient(config) {
|
|
26
|
+
const transport = new StreamableHTTPClientTransport(new URL(`${config.baseUrl}/mcp`), {
|
|
27
|
+
requestInit: {
|
|
28
|
+
headers: {
|
|
29
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
const client = new Client({ name: 'ionhour-mcp-proxy', version: '0.1.0' });
|
|
34
|
+
await client.connect(transport);
|
|
35
|
+
return client;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Start the stdio-to-HTTP MCP proxy server.
|
|
39
|
+
*
|
|
40
|
+
* 1. Connects to the remote IonHour MCP endpoint as a client
|
|
41
|
+
* 2. Exposes an MCP server over stdio
|
|
42
|
+
* 3. Proxies all tool/resource/prompt requests to the remote endpoint
|
|
43
|
+
*/
|
|
44
|
+
export async function startProxyServer(config) {
|
|
45
|
+
let remoteClient;
|
|
46
|
+
try {
|
|
47
|
+
remoteClient = await createRemoteClient(config);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
51
|
+
process.stderr.write(`Failed to connect to IonHour API at ${config.baseUrl}/mcp: ${message}\n`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
const server = new Server({ name: 'ionhour', version: '0.1.0' }, {
|
|
55
|
+
capabilities: {
|
|
56
|
+
tools: {},
|
|
57
|
+
resources: {},
|
|
58
|
+
prompts: {},
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
// Proxy tools/list
|
|
62
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
63
|
+
const result = await remoteClient.listTools();
|
|
64
|
+
return { tools: result.tools };
|
|
65
|
+
});
|
|
66
|
+
// Proxy tools/call
|
|
67
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
68
|
+
const result = await remoteClient.callTool({
|
|
69
|
+
name: request.params.name,
|
|
70
|
+
arguments: request.params.arguments,
|
|
71
|
+
});
|
|
72
|
+
return result;
|
|
73
|
+
});
|
|
74
|
+
// Proxy resources/list
|
|
75
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
76
|
+
try {
|
|
77
|
+
const result = await remoteClient.listResources();
|
|
78
|
+
return { resources: result.resources };
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return { resources: [] };
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
// Proxy resources/read
|
|
85
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
86
|
+
const result = await remoteClient.readResource({
|
|
87
|
+
uri: request.params.uri,
|
|
88
|
+
});
|
|
89
|
+
return result;
|
|
90
|
+
});
|
|
91
|
+
// Proxy prompts/list
|
|
92
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
93
|
+
try {
|
|
94
|
+
const result = await remoteClient.listPrompts();
|
|
95
|
+
return { prompts: result.prompts };
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return { prompts: [] };
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
// Proxy prompts/get
|
|
102
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
103
|
+
const result = await remoteClient.getPrompt({
|
|
104
|
+
name: request.params.name,
|
|
105
|
+
arguments: request.params.arguments,
|
|
106
|
+
});
|
|
107
|
+
return result;
|
|
108
|
+
});
|
|
109
|
+
// Connect local server to stdio transport
|
|
110
|
+
const transport = new StdioServerTransport();
|
|
111
|
+
await server.connect(transport);
|
|
112
|
+
// Log to stderr so stdout remains clean for MCP JSON-RPC protocol
|
|
113
|
+
process.stderr.write('IonHour MCP server started (stdio proxy mode)\n');
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/mcp-server/src/index.ts"],"names":[],"mappings":"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"}
|