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.
POSTto the server URL;GETreturns 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-servernpm 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 level | Role it maps to | What it can do |
|---|---|---|
read_only | viewer | Read tools only (list_*, get_*, find_*, whoami) |
read_write | admin (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.
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_workspacereturns the limits and current usage ahead of time. - Deprecated tombstone:
{ "error": "TOOL_DEPRECATED", "message": … }fromregister_check. Nothing was created. - Validation and scope: invalid input, a missing
projectId/dependencyIdchoice, 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:
- Call
register_jobwith a stable name and interval. - Have the monitored workload report to the returned ping URL, preferably through an Ionhour SDK, or with
curlfrom the scheduler command.get_job_integration_guidereturns snippets with the Job's real token. - Let that workload report only after each useful-work checkpoint. Send
/failon failure and optionally/startwhen a run begins. - 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_KEYStart 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 ionhourOr run the stdio package, which uses the key stored by npx @ionhour/mcp-server login:
claude mcp add ionhour -- npx -y @ionhour/mcp-serverStart 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 overdaysBackdays.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_projectis 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.checkTypeselects HTTP (default, needsurl), DNS (dns), TCP (tcp), or SSL certificate expiry (ssl). Exactly one ofprojectIdordependencyId. Acceptsinterval("every 5 minutes") orintervalSeconds(10–3600) and the full probe configuration: method, timeout, expected status range, redirects, failure and recovery thresholds, latency warning, body assertions, custom headers, severity, andregions.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 withget_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. Chooseregionsonly from this list.get_check_uptime— Time-weighted, incident-based uptime with daily buckets overdaysBackdays.get_check_response_time— Average, p50, p95, min, and max response time overrange(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. Useregister_jobfor a heartbeat monitor orcreate_checkfor 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. Acceptsinterval("daily") orintervalSeconds(10 seconds to 7 days) andgraceSeconds.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 overdaysBackdays.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 byACTIVEorRESOLVED), search by title, and read one incident.get_incident_timeline— Incident history for exactly one ofcheckIdorjobId.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_dependencylist_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. Theslugforms the public URL;visibilityisPUBLICorPRIVATE. 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 onecheckId,jobId,projectId(withprojectDisplayModeROLLUPorEXPANDED), ordependencyId. 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 anemail(to) orwebhook(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_ruleadds a step for onealertChannelIdwith adelayMinutes; update and delete requireprojectIdand treatruleIdas the step id. Read the policy back withget_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:
| URI | Description |
|---|---|
ionhour://tools/catalog | Every tool grouped by domain with descriptions |
ionhour://guides/workflows | Workflow patterns: setup, incident response, safe deploy, weekly review |
ionhour://help/ping-formats | How to send Job heartbeats: curl, cron, CI, Node, Python |
ionhour://checks/schema | Check creation schema and the status lifecycle |
ionhour://enums | Monitor 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_checkis a tombstoned alias: it returnsTOOL_DEPRECATEDand creates nothing. Useregister_job(heartbeats) orcreate_check(outbound probes).- The four
*_escalation_ruletools are deprecated aliases over the policy and step model but remain the only MCP-callable write path for escalation.get_escalation_policyreads the canonical shape.
Dependencies API
Manage external service dependencies through the Ionhour API — create, update, and categorize them, and track their real impact on every service you monitor.
Integrations
Build on Ionhour from your own product — declare incidents, post status updates, and receive Ionhour events into your IMS, plus base URL and API conventions.