Building with MCP: plugging LiveStatus into Claude Desktop
How we built an MCP server for LiveStatus so you can manage your status page from Claude Desktop. What MCP actually is, the tools we expose, and the honest limits of the beta.
Quick disclosure up top, because I hate the thing where people ship a blog post about a feature that doesn't exist. The MCP server for LiveStatus is in beta as of the date on this post. It runs, it handles the basic read and write paths, and I've been dogfooding it for a few weeks. But it's not GA yet. Some tools return placeholder errors when you try to do something weird. I'll flag what's shipped and what's not as we go. Nothing in this post is vaporware, but not all of it is polished.
With that out of the way, let me show you the cool part.
What is MCP, in two paragraphs
Model Context Protocol (MCP) is an open protocol from Anthropic that lets LLM clients like Claude Desktop talk to external tools in a standardized way. You run a small server process that exposes a set of "tools" (functions the LLM can call) and "resources" (data the LLM can read). Claude connects to your server, learns the tool schema, and can invoke tools when a user asks for something the tool could handle.
The thing that makes it useful instead of just a function-calling gimmick is that it's client-side and local-first. Your MCP server runs on your own machine (or somewhere you control). The LLM is the brains, but the actual I/O, credentials, and side effects all stay on your side of the wire. You don't hand Claude your API keys; you hand a local process your API keys, and Claude talks to the local process. That distinction matters a lot once you start connecting real services.
Why bother for a status page
Honestly? Because I got tired of opening a browser tab every time I wanted to post an incident update. My workflow during an outage was: notice problem, open laptop, open browser, find the LiveStatus tab, navigate to the page, click "New incident", fill the form, submit, close tab. All of that while my phone is buzzing and I'm trying to think clearly.
With the MCP server plugged into Claude Desktop, the same flow is: press ⌘ Space, type "ask claude to post an incident about the API being down because of the postgres failover", hit enter. Claude writes a clean update in my voice, calls the post_incident tool, gets a confirmation back with the incident URL, pastes it into my clipboard. Twenty seconds instead of two minutes. More importantly, zero context switches.
The thing I didn't expect is that it's also really good for reading. "Claude, what are all the unresolved incidents across my pages" returns a clean summary in seconds. "What was our longest outage in March" gives me a correct answer without me having to open the analytics page. Once it's wired up you stop using the web dashboard for lookups.
Configuration
If you're on Claude Desktop, the config lives at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %APPDATA%\Claude\claude_desktop_config.json on Windows. Add the LiveStatus entry like this:
{
"mcpServers": {
"livestatus": {
"command": "npx",
"args": ["-y", "@livestatus/mcp-server@beta"],
"env": {
"LIVESTATUS_API_KEY": "lsk_live_your_key_here",
"LIVESTATUS_BASE_URL": "https://mcp.livestatus.dev"
}
}
}
}
Restart Claude Desktop. You should see "livestatus" appear in the tool list at the bottom of the input box. If it doesn't, check the Claude Desktop logs at ~/Library/Logs/Claude/mcp*.log. The most common issue is a bad API key, which the server reports as a 401 on the first tool call.
Get your API key from Dashboard then API keys in LiveStatus. Scope it to the pages you want Claude to have access to. I'd suggest making a dedicated key called "claude-desktop" so you can revoke it without nuking your other integrations.
What the tools do
As of this week, the server exposes these tools. The ones marked shipped are in the beta build. The ones marked in progress are on the tip of main but not published yet, and I'll drop them into the npm package once they've survived a few more days of dogfooding.
list_pages (shipped). Returns every status page the API key has access to, with basic metadata. Useful when Claude is figuring out which page to act on.
list_services (shipped). For a given page, lists services with current status. Claude uses this automatically when you ask something like "is the API up".
list_incidents (shipped). Filterable by page, status (open, resolved, all), and time range. This is the one I use most for lookups.
get_incident (shipped). Full detail for a specific incident including all updates, affected services, and timestamps.
post_incident (shipped). Creates a new incident with a title, affected services, severity, and initial update. Returns the public URL.
update_incident (shipped). Appends a new update to an existing incident. This is the one I use every five minutes during an active outage, see my other post on incident communication for why.
resolve_incident (shipped). Marks an incident resolved and posts a final update. Takes an optional postmortem_url so you can link the full writeup.
set_service_status (shipped). Changes a single service's status. Useful for "mark the API as degraded without creating a full incident".
list_subscribers (in progress). Subscriber lookup for debugging "why didn't I get the email". Currently returns only counts, not the actual list, because I'm still thinking about the privacy model for exposing subscriber emails to an LLM client.
query_uptime (in progress). Returns uptime percentage for a service over a date range. Works in my local dev build, not yet in the published beta.
post_maintenance (in progress). Schedules a maintenance window. Schema is stable, implementation is 80% there.
Everything else, like analytics queries, bulk operations, and integrations management, is not in the MCP server yet. File a request on GitHub if you want something specific.
A real session
Here's an actual conversation from last week, slightly trimmed. I was debugging a reported problem on my own status page.
Me: hey can you check if livestatus has had any incidents in the last 7 days?
Claude: (calls
list_incidentswith page_slug="livestatus" and since="7d") One incident: "Elevated push notification latency", investigating status, opened about 3 hours ago. Two updates so far. Want me to pull the detail?Me: yeah
Claude: (calls
get_incident) Opened at 10:14 today. Affected service: Push Notifications. First update flagged a queue backlog on the Expo side. Second update at 11:02 said the queue has drained but they're monitoring. No resolution posted yet. The incident has 42 affected subscribers per the metadata. Want me to post a resolution update?Me: yes, say we've confirmed it's stable for an hour and we're closing it
Claude: (calls
resolve_incidentwith a final update message) Done. Final update posted, incident marked resolved. Public URL: https://livestatus.dev/livestatus/incidents/elevated-push-latency-apr-03. Anything else?
That's the whole interaction. Three tool calls, zero browser tabs. The "final update" Claude wrote was better than what I would have typed in a rush because it actually read the two previous updates and referenced them in the resolution.
Security notes
A few things worth knowing if you're going to try this:
- The MCP server talks to the LiveStatus API over HTTPS. Your key never leaves your machine except to reach api.livestatus.dev over TLS. Claude Desktop only sees the tool schemas and the responses, never the raw key.
- The API key respects your existing permission scopes. If you scope the key to one page, Claude can't touch the others. Use this.
- The server is open source at github.com/livestatusdev/mcp-server. Audit it if you're paranoid. I would be.
- Tool calls are logged to your LiveStatus audit log with a "source: mcp" tag. You can see exactly what Claude did, when, and to which resources.
One thing I'm still figuring out is how much I want the LLM to be able to do without asking. Right now post_incident and resolve_incident both trigger a confirmation dialog in Claude Desktop before they run. You can disable that, but I don't recommend it. The whole point is that the human stays in the loop on anything that customers will see.
The honest limits
Since this is a beta, here's what doesn't work well yet:
- Rate limiting on the server side is generous, which means if you build a weird loop you could spam your own status page. Don't build weird loops.
- Error messages are sometimes cryptic because I'm passing through the raw API errors instead of wrapping them. Will fix.
- Multiple pages in one org are supported, but if the API key has access to more than 10 pages Claude sometimes picks the wrong one. I'm thinking about adding a required "confirm which page" step for destructive tools.
- Windows paths in the config file. I've only tested macOS. The code should work on Windows and Linux, but I haven't put it through the paces there.
If you hit any of these, email me or file an issue on GitHub. This is the kind of thing that gets polished by real usage.
Why nobody else does this
As far as I can tell, no other status page product has an MCP server. Statuspage.io, Instatus, Better Stack, PagerDuty, none of them. I checked. If I'm wrong and one of them ships it tomorrow, I'll update this post. But as of right now, you can't ask Claude to manage a Statuspage.io page, because there's nothing for Claude to talk to.
That's the same pattern as the mobile app thing. There's a feature users would obviously benefit from, nobody's built it, and I can't figure out why not other than "status page companies move slowly". I'm going to keep finding these gaps until someone tells me to stop.
If you want to try the beta, grab an API key, install the MCP server, and send me any feedback. The install command is in the config snippet above. It's genuinely useful already, warts and all.
More posts
Why we built a mobile app for status pages
Email alerts go to spam. People check their phones. Here's why LiveStatus ships a native mobile app and why no one else does.
Migrating from Statuspage.io in 30 seconds
A walkthrough of the LiveStatus import flow. Paste your Statuspage export, keep your services, incidents, and subscribers. Done before your coffee cools.
What 500 errors teach you about incident communication
Silence is the worst outage response. Here's the 5-minute rule, the severity vs impact split, and how to write updates that don't read like a legal document.