incidentrelay-mcp
by NikGariel
README.md
# incidentrelay-mcp
An [MCP](https://modelcontextprotocol.io) server for
[IncidentRelay](https://github.com/roxy-wi/incidentrelay) — self-hosted on-call
scheduling, alert routing, and incident management.
It exposes IncidentRelay's **entire REST API (279 operations)** to MCP clients
(Claude Desktop, Claude Code, Cursor, …) through two layers:
- **3 gateway tools** that make *every* operation reachable, driven by the
server's own OpenAPI document.
- **25 curated tools** that wrap the common on-call workflows (acknowledge/
resolve alerts, incidents, on-call schedule, silences, maintenance windows)
with typed, ergonomic inputs.
The server never modifies IncidentRelay. It is a pure REST client that
authenticates with a bearer token you provide.
## Run
No install needed — run it with `npx` (Node.js ≥ 20):
```bash
# from GitHub (works today)
IR_BASE_URL=https://incidentrelay.example.com IR_TOKEN=<token> \
npx -y github:NikGariel/IncidentRelay-mcp
# from npm (after the package is published)
IR_BASE_URL=https://incidentrelay.example.com IR_TOKEN=<token> \
npx -y incidentrelay-mcp
```
`npx` builds the package automatically on first run (a `prepare` script compiles
TypeScript), so no separate build step is required.
### From source
```bash
npm install # runs the build via the prepare script
npm start
```
## Configure
The server needs the IncidentRelay base URL and a bearer token (a JWT access
token or a **personal API token** created in IncidentRelay under
*Profile → API tokens*, with the scopes you want to allow).
| Setting | Env | Flag | Required | Default |
|---|---|---|---|---|
| Base URL | `IR_BASE_URL` | `--base-url` | yes | — |
| Bearer token | `IR_TOKEN` | `--token` | yes¹ | — |
| Transport | `IR_TRANSPORT` | `--transport` | no | `stdio` |
| HTTP port | `IR_PORT` | `--port` | no | `3000` |
| HTTP host | `IR_HOST` | `--host` | no | `127.0.0.1` |
| Read-only | `IR_READONLY` | `--readonly` | no | `false` |
| Request timeout (ms) | `IR_TIMEOUT_MS` | — | no | `30000` |
| OpenAPI URL override | `IR_OPENAPI_URL` | — | no | `{base}/api/openapi.json` |
| TLS verification | `IR_VERIFY_TLS` | — | no | `true` |
¹ The token is optional only if you never call write operations.
At startup the server fetches `{IR_BASE_URL}/api/openapi.json` (a public
endpoint) to build its operation catalog, so it always matches the deployed
IncidentRelay version. If that fetch fails, it falls back to a bundled
snapshot and logs a warning.
## Use with Claude Desktop / Claude Code (stdio)
Add to your MCP client config (e.g. `claude_desktop_config.json`).
**Recommended — run the prebuilt binary directly** (starts in <0.5s, so it never
hits the client's startup timeout):
```json
{
"mcpServers": {
"incidentrelay": {
"command": "node",
"args": ["/absolute/path/to/incidentrelay-mcp/dist/index.js"],
"env": {
"IR_BASE_URL": "https://incidentrelay.example.com",
"IR_TOKEN": "<personal-api-token>"
}
}
}
}
```
Build it once with `npm install && npm run build` (or `npm install -g .`).
**Alternative — `npx`.** Once published to npm:
```json
{ "command": "npx", "args": ["-y", "incidentrelay-mcp"], "env": { "…": "…" } }
```
> ⚠️ Avoid `npx -y github:…` in a client config: its **first** run clones the
> repo, installs dependencies, and compiles TypeScript, which can exceed an MCP
> client's ~30s connection timeout on a cold cache. Use the prebuilt binary (or
> the npm form after publishing) for a client that spawns the server on demand.
The server itself starts instantly regardless of network: it loads a bundled
OpenAPI snapshot synchronously, then refreshes the catalog from the live server
in the background.
## Use over HTTP (Streamable HTTP)
```bash
IR_BASE_URL=https://incidentrelay.example.com IR_TOKEN=... \
npx -y github:NikGariel/IncidentRelay-mcp --transport http --port 3000
# serves MCP at http://127.0.0.1:3000/mcp
```
The HTTP transport is stateless (one server per request), binds to
`127.0.0.1` by default, and has DNS-rebinding protection enabled.
## Tools
### Gateway (cover all 279 operations)
| Tool | Purpose |
|---|---|
| `ir_list_operations` | Search/list the API catalog by query, tag, or method. |
| `ir_describe_operation` | Show one operation's params and request-body schema. |
| `ir_call` | Execute any operation by `operationId` (or `method`+`path`). |
Typical flow: `ir_list_operations` → `ir_describe_operation` → `ir_call`.
### Curated (common on-call workflows)
Alerts: `ir_list_alerts`, `ir_get_alert`, `ir_ack_alert`, `ir_resolve_alert`,
`ir_comment_alert` ·
Incidents: `ir_list_incidents`, `ir_get_incident`, `ir_create_incident`,
`ir_add_incident_responder`, `ir_set_incident_priority` ·
On-call: `ir_who_is_on_call`, `ir_oncall_health`, `ir_list_rotations`,
`ir_create_rotation_override` ·
Silences: `ir_list_silences`, `ir_create_silence`, `ir_remove_silence` ·
Maintenance: `ir_list_maintenance_windows`, `ir_create_maintenance_window` ·
Context: `ir_list_teams`, `ir_list_routes`, `ir_list_channels`, `ir_whoami` ·
Heartbeats: `ir_list_heartbeats`, `ir_send_heartbeat`.
## Safety
- **Confirm-guard.** Destructive operations (`DELETE`, and paths with
`disable`/`remove`/`delete`/`reset`/`regenerate-token`/`intake-token`/
`cancel`/`merge`/`revoke`) do **not** run unless you pass `confirm: true`.
Without it, the tool returns a dry-run preview.
- **Read-only mode.** Set `IR_READONLY=true` to refuse every non-`GET`
operation at the tool layer.
- **Token redaction.** Bearer tokens are stripped from logs and error output.
## Security
`IR_VERIFY_TLS=false` disables TLS certificate verification for outbound calls
to IncidentRelay. This exposes traffic to man-in-the-middle attacks and should
only be used on a trusted network. For self-hosted self-signed certificates,
**prefer adding the server's CA to your trust store** (or use a properly-issued
certificate) instead of disabling verification. When disabled, the server
prints a warning at startup.
## Development
```bash
npm test # run the vitest suite
npm run dev # run from source with tsx
npm run build # typecheck + emit dist/ + copy the OpenAPI snapshot
```
Regenerating the bundled OpenAPI snapshot: see
[`scripts/generate-snapshot.md`](scripts/generate-snapshot.md).
## Design & plan
- Design spec: [`docs/superpowers/specs/2026-08-17-incidentrelay-mcp-design.md`](docs/superpowers/specs/2026-08-17-incidentrelay-mcp-design.md)
- Implementation plan: [`docs/superpowers/plans/2026-08-17-incidentrelay-mcp.md`](docs/superpowers/plans/2026-08-17-incidentrelay-mcp.md)
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues