Ionhour Docs

MCP Server

Connect an MCP client to https://mcp.ionhour.com — transport, API-key authentication and permission levels, per-client setup, safety boundaries, and the full tool reference grouped by resource.

The Ionhour MCP server lets compatible clients inspect and manage resources in your Ionhour workspace. Connect once, then use the client's normal conversation interface to create monitors, triage incidents, configure alerting, and work with the rest of the workspace.

Server URL: https://mcp.ionhour.com

If you are an agent working from a human request, start with the Agent Quick Start. This page is the connection and tool reference it links to.

Protocol support

  • Streamable HTTP with JSON responses. POST to the server URL; GET returns a human-readable landing page.
  • Stateless: the server never issues Mcp-Session-Id. Every request is self-contained.
  • The same tools are available over stdio through the @ionhour/mcp-server npm package, which proxies to the hosted server.

Clients using an MCP SDK do not need to care about any of this; connect and use the tools.

Authentication and permissions

The server authenticates with an Ionhour API key: a Bearer token starting with ionh_, created under Developer Console → Credentials in the dashboard. The key decides the workspace. Every call is scoped to that workspace and you never pass a workspace id.

Permission levelRole it maps toWhat it can do
read_onlyviewerRead tools only (list_*, get_*, find_*, whoami)
read_writeadmin (cap)Read plus create, update, pause, resume, resolve, and delete

Owner-only actions are unreachable over MCP with any key. A key can additionally be restricted to a subset of resources (for example only mcp:checks and mcp:jobs); a call outside the allowed set returns a structured forbidden error with code KEY_SCOPE_DENIED and is written to the workspace audit log. Changing or revoking a key takes effect on the next request.

OAuth sign-in is not available yet. Hosted clients that cannot send a private header, such as Claude.ai, Claude Desktop connectors, and ChatGPT, cannot connect until it ships.

Rate limits

Two layers apply: the global API limit of 100 requests per 60 seconds per client IP, and a per-key limit whose size depends on the workspace plan. A per-key deny is an HTTP 429 with body { statusCode, code: "RATE_LIMIT_EXCEEDED_KEY", limit, plan, message } and a Retry-After header. Wait that long and retry once.

Error shapes

Tool failures return an MCP result with isError: true whose single text block is JSON of the form { "error": "<message>" }. Three families matter to an agent:

  • Plan limits: "Your <plan> plan allows a maximum of N <resource>. Please upgrade your plan to add more." Stop and report it; do not retry with other values. get_workspace returns the limits and current usage ahead of time.
  • Deprecated tombstone: { "error": "TOOL_DEPRECATED", "message": … } from register_check. Nothing was created.
  • Validation and scope: invalid input, a missing projectId/dependencyId choice, or a resource that does not belong to the workspace.

Safety and data boundaries

Use the MCP server as a control plane for inspecting and managing Ionhour resources. It does not replace runtime instrumentation: Jobs must send heartbeats from the workload's real execution path through an Ionhour SDK or a direct ping to the signal URL.

Start with read-only summary tools. Signal payloads, incident notes, and private status-page configuration can contain customer data, so request them only when they are needed and the human has approved that access.

register_job returns a token and ping URL. The token is the Job's only credential; keep it out of chat transcripts and source control, and store it in the runtime's environment or secret manager.

Control plane, not data plane

For a Job, the durable sequence is:

  1. Call register_job with a stable name and interval.
  2. Have the monitored workload report to the returned ping URL, preferably through an Ionhour SDK, or with curl from the scheduler command. get_job_integration_guide returns snippets with the Job's real token.
  3. Let that workload report only after each useful-work checkpoint. Send /fail on failure and optionally /start when a run begins.
  4. Use MCP later to inspect status or change configuration.

Never send telemetry through the MCP server. send_heartbeat and send_failure_signal exist for the agent's own operational use, but a heartbeat from the agent session proves nothing about the runtime. If the client or its MCP connection stops, Ionhour must still hold the deadline and detect the missing direct ping.

Checks need no runtime integration: Ionhour probes the target from the configured regions. Use run_check_probe to test one on demand and get_check_status to read the result.

Connect your MCP client

Every snippet below keeps the key out of the configuration file by referencing an environment variable or a masked prompt. Set IONHOUR_API_KEY in your shell first. For a temporary Bash or Zsh session, this non-echoing prompt keeps the value out of the command and out of history:

printf 'Paste the Ionhour API key: ' >&2
IFS= read -r -s IONHOUR_API_KEY
printf '\n' >&2
export IONHOUR_API_KEY

Start a command-line client from that shell so it inherits the variable, and run unset IONHOUR_API_KEY when you are done. GUI apps do not inherit a terminal's environment; use the client's secret input where it has one.

Claude Code

Hosted server, user scope. The single-quoted JSON saves the environment-variable placeholder, not the secret value:

claude mcp add-json --scope user ionhour \
  '{"type":"http","url":"https://mcp.ionhour.com","headers":{"Authorization":"Bearer ${IONHOUR_API_KEY}"}}'
claude mcp get ionhour

Or run the stdio package, which uses the key stored by npx @ionhour/mcp-server login:

claude mcp add ionhour -- npx -y @ionhour/mcp-server

Start claude from the same injected environment and use /mcp to verify the connection.

Codex

Add this secret-free entry to ~/.codex/config.toml:

[mcp_servers.ionhour]
url = "https://mcp.ionhour.com"
bearer_token_env_var = "IONHOUR_API_KEY"

Start codex from the same shell and use codex mcp list or /mcp to verify the connection.

Cursor

Add this secret-free entry to the global ~/.cursor/mcp.json:

{
  "mcpServers": {
    "ionhour": {
      "url": "https://mcp.ionhour.com",
      "headers": {
        "Authorization": "Bearer ${env:IONHOUR_API_KEY}"
      }
    }
  }
}

Quit Cursor, then run cursor . from the same shell so it starts with the variable. Open Settings → MCP and confirm that ionhour connects.

VS Code / GitHub Copilot

Run MCP: Open User Configuration and use this configuration. VS Code prompts for the key with hidden input and stores it securely; do not put this in a workspace .vscode/mcp.json:

{
  "inputs": [
    {
      "type": "promptString",
      "id": "ionhour-api-key",
      "description": "Ionhour API key (ionh_…)",
      "password": true
    }
  ],
  "servers": {
    "ionhour": {
      "type": "http",
      "url": "https://mcp.ionhour.com",
      "headers": {
        "Authorization": "Bearer ${input:ionhour-api-key}"
      }
    }
  }
}

Run MCP: List Servers, start ionhour, and paste the key only into the masked prompt.

Claude Desktop, Windsurf, and other stdio clients

Use the stdio package. Run npx @ionhour/mcp-server login once to store a key, or npx @ionhour/mcp-server setup to let the wizard detect installed editors and write their configuration. The manual entry is:

{
  "mcpServers": {
    "ionhour": {
      "command": "npx",
      "args": ["-y", "@ionhour/mcp-server"]
    }
  }
}

The package also exposes whoami (show the stored workspace and key prefix) and logout (remove the stored credentials). Credentials live at ~/.config/ionhour/credentials.json with mode 600.

MCP Inspector and other Streamable HTTP clients

Select Streamable HTTP, enter https://mcp.ionhour.com, and add an Authorization: Bearer <key> header from the client's secret input. Standards-compliant clients are supported on a best-effort basis.

Tools

Every tool is listed under the resource that authorizes it. Read tools work with both permission levels; the rest need read_write. The live schema an MCP client receives is authoritative; the ionhour://tools/catalog resource returns the same list as JSON.

Workspace

  • get_workspace — Workspace name, plan, the plan's resource limits, and current usage. Call before bulk creation.
  • whoami — The authenticated key's workspace, user, and permission level.
  • get_workspace_summary — Project count, monitors grouped by status (Jobs and Checks separately), and active incident count.
  • get_workspace_reliability — Uptime, incident count, and MTTR over daysBack days.
  • list_team_members — Workspace members and roles.
  • list_invitations, send_invitation, revoke_invitation — Pending invitations and their lifecycle (admin).
  • get_resource_audit_history — Audit-log rows for a resource.

Projects

  • list_projects, create_project, update_project, delete_project — Projects group monitors and own the escalation policy. delete_project is a soft delete.
  • list_deleted_projects, restore_project — Discover and restore soft-deleted projects.

Checks (outbound probes)

Ionhour probes a target you own on a schedule and alerts on failure. Status lifecycle: NEW → OK → LATE → DOWN → OK (also PAUSED).

  • create_check — Create a check. checkType selects HTTP (default, needs url), DNS (dns), TCP (tcp), or SSL certificate expiry (ssl). Exactly one of projectId or dependencyId. Accepts interval ("every 5 minutes") or intervalSeconds (10–3600) and the full probe configuration: method, timeout, expected status range, redirects, failure and recovery thresholds, latency warning, body assertions, custom headers, severity, and regions.
  • update_check — Change any of the same fields on an existing check. Pass only what changes.
  • run_check_probe — Probe a check now from every configured region. Asynchronous; read the result with get_check_status. A failing probe counts toward the failure threshold.
  • list_checks, list_checks_by_status, find_check_by_name — Enumerate and resolve checks.
  • get_check_status — Live status with recent signals.
  • get_check — Stored configuration: assertions, thresholds, regions, alerting.
  • list_regions — Probe regions served by this environment plus the default set. Choose regions only from this list.
  • get_check_uptime — Time-weighted, incident-based uptime with daily buckets over daysBack days.
  • get_check_response_time — Average, p50, p95, min, and max response time over range (1h, 24h, 7d, 30d).
  • get_check_integration_guide — The monitored target and configuration summary.
  • pause_check, resume_check — Stop and restart probing.
  • delete_check — Soft delete. Signal and incident history is purged and not recovered on restore.
  • list_deleted_checks, restore_check — Discover and restore soft-deleted checks.
  • register_check — Deprecated tombstone. Returns an error and creates nothing. Use register_job for a heartbeat monitor or create_check for an outbound probe.

Jobs (inbound heartbeat monitors)

Your cron, worker, or scheduled script pings Ionhour; Ionhour alerts when a ping is late or missing. Same status lifecycle as checks.

  • register_job — Create a Job and receive its token and ping URL. Accepts interval ("daily") or intervalSeconds (10 seconds to 7 days) and graceSeconds.
  • update_job — Rename, or change the interval or grace period.
  • list_jobs, find_job_by_name — Enumerate and resolve jobs.
  • get_job_status — Live status with recent heartbeats.
  • get_job_uptime — Time-weighted, incident-based uptime with daily buckets over daysBack days.
  • get_job_integration_guide — Ping URL and code snippets for the Job's real token.
  • pause_job, resume_job — Stop and restart deadline tracking.
  • delete_job — Soft delete. Signal and incident history is purged and not recovered on restore.
  • list_deleted_jobs, restore_job — Discover and restore soft-deleted jobs.

Signals (heartbeat pings)

  • send_heartbeat, send_failure_signal — Send a success or failure signal for a Job token from the agent. Operational use only; this is not runtime verification.
  • list_signals — Paged signal history for a Job token.

Incidents

Incidents open automatically when a monitor goes LATE or DOWN and resolve when it recovers. Lifecycle: ACTIVE → ACKNOWLEDGED → RESOLVED.

  • list_incidents, search_incidents, get_incident — Enumerate (filter by ACTIVE or RESOLVED), search by title, and read one incident.
  • get_incident_timeline — Incident history for exactly one of checkId or jobId.
  • diagnose_incident — AI root-cause summary. Available only where the workspace has the feature enabled.
  • acknowledge_incident, resolve_incident, reopen_incident — Lifecycle transitions.
  • create_incident — Declare a manual incident with a severity (P1–P4).
  • update_incident, set_incident_severity, add_incident_note — Edit title and summary, change severity, add a note.
  • publish_incident_to_status_page, create_incident_update, publish_incident_update — Stakeholder communication: publish the incident as a status-page announcement and post updates to it.

Dependencies

External services your checks rely on, used for root-cause attribution.

  • list_dependencies, get_dependency, create_dependency, update_dependency_status, delete_dependency
  • list_deleted_dependencies, restore_dependency

Deployments

  • create_deployment — Start a deployment window for a project. Auto-pauses the project's monitors.
  • end_deployment — End the window and resume the monitors.
  • list_deployments — Deployment history for a project.

Status pages

  • list_status_pages, create_status_page, update_status_page, delete_status_page — Pages. The slug forms the public URL; visibility is PUBLIC or PRIVATE. Password protection and custom domains are dashboard settings.
  • list_deleted_status_pages, restore_status_page — Discover and restore soft-deleted pages. Restore does not re-register a custom domain.
  • list_status_page_components, add_status_page_component, update_status_page_component, reorder_status_page_components, delete_status_page_component — Rows on a page. Each component links exactly one checkId, jobId, projectId (with projectDisplayMode ROLLUP or EXPANDED), or dependencyId. The per-page component count is plan-limited.
  • get_status_page_preview — The rendered page as the public sees it, including the real URL. Use to verify without a browser.
  • create_announcement, delete_announcement — Post and hard-delete status updates with a status (INVESTIGATING, …) and impact (MINOR, …).

Alert channels

  • list_alert_channels — Channels in the workspace, optionally filtered by type.
  • get_alert_routing — The routing read model: policies, rules, actions, and fallback semantics.
  • create_alert_channel — Create an email (to) or webhook (webhookUrl) channel (admin). Slack, Discord, Microsoft Teams, Telegram, SMS, and PagerDuty are connected in the dashboard.
  • update_alert_channel, delete_alert_channel — Rename, enable or disable, soft-delete.
  • list_deleted_alert_channels, restore_alert_channel — Discover and restore soft-deleted channels.

Escalation

  • get_escalation_policy — The canonical policy and step model for a project.
  • list_escalation_rules, create_escalation_rule, update_escalation_rule, delete_escalation_rule — Deprecated aliases that flatten the policy into single-channel rules. They remain the MCP-callable path to add, change, or remove an escalation step: create_escalation_rule adds a step for one alertChannelId with a delayMinutes; update and delete require projectId and treat ruleId as the step id. Read the policy back with get_escalation_policy.

Not exposed over MCP

Maintenance windows, on-call schedules, teams, and alert-routing rule edits are managed through the REST API or the dashboard.

Resources and prompts

The server publishes reference data a client can read without calling tools:

URIDescription
ionhour://tools/catalogEvery tool grouped by domain with descriptions
ionhour://guides/workflowsWorkflow patterns: setup, incident response, safe deploy, weekly review
ionhour://help/ping-formatsHow to send Job heartbeats: curl, cron, CI, Node, Python
ionhour://checks/schemaCheck creation schema and the status lifecycle
ionhour://enumsMonitor statuses, incident states, severities, and other enums

And prompt templates for multi-step work: setup_monitoring, diagnose_incident, deployment_checklist, weekly_reliability_report, triage_all_incidents, status_page_incident, and dependency_health_audit.

Deprecations

  • register_check is a tombstoned alias: it returns TOOL_DEPRECATED and creates nothing. Use register_job (heartbeats) or create_check (outbound probes).
  • The four *_escalation_rule tools are deprecated aliases over the policy and step model but remain the only MCP-callable write path for escalation. get_escalation_policy reads the canonical shape.