MCP for agents
Point an MCP client at Perstat, and it answers “what is broken and who owns it” from your live
data, then acts within its authorization. The catalogue has seventeen tools: seven read state,
two act on an incident, and eight manage projects and monitors. The connected server’s
tools/list shows exactly which of them the credential in front of you may use. Every tool keeps
your record intact: retiring a service archives it.
Connecting
Section titled “Connecting”| Endpoint | https://api.perstat.io/mcp |
| Transport | Streamable HTTP, stateless |
| Protocol versions | 2025-06-18 (preferred), 2025-03-26, 2024-11-05 |
One JSON-RPC message in by POST, one JSON response out. GET /mcp answers 405, because the
server works request by response, without a server-initiated event stream. JSON-RPC batches,
dropped from the protocol in 2025-06-18, are rejected with a clear message.
In Claude Code:
claude mcp add --transport http perstat https://api.perstat.io/mcp \ --header "Authorization: Bearer pst_…"This form works in clients that accept a custom HTTP authorization header. The key lands in your shell history this way, so for interactive work the plugin’s browser sign-in is the cleaner route.
Or install the plugin
Section titled “Or install the plugin”For Claude Code there is a plugin. It wires the same server and adds four skills that turn the tools into workflows: handling an incident, managing monitors, reporting the current state, and a reference of every monitor type.
claude plugin marketplace add datargo/perstat-pluginclaude plugin install perstat@datargoOn the first Perstat tool call, Claude opens the OAuth sign-in in your browser. Choose the
organization for the connection, and you are done: no key to copy, no shell profile to edit. The
connection is bound to that organization and your current role. Check it with
claude mcp list, where Perstat should report Connected.
Use the API-key one-liner above for CI, cron, or a credential narrowed to specific projects. Use the plugin for interactive work with browser sign-in.
Authentication
Section titled “Authentication”Perstat accepts a scoped organization API key as a bearer credential:
Authorization: Bearer pst_…A client that supports OAuth can instead use Perstat’s published Authorization Code flow with
PKCE. Discovery is available at
https://api.perstat.io/.well-known/oauth-protected-resource/mcp and
https://api.perstat.io/.well-known/oauth-authorization-server, which also publish the refresh
and revocation endpoints. MCP always authenticates with a bearer token: the OAuth flow ends in
one, so a browser session cookie on its own is not enough.
OAuth clients are accepted from Claude, Claude Code, and ChatGPT, identified by their client
documents under https://claude.ai/oauth/ and https://chatgpt.com/oauth/. The consent screen
names the host the client comes from, in addition to the name it gives itself, and a client
receives exactly the permissions its tools need: monitors and incidents, each read or write.
An organization API key belongs to exactly one organization and carries scopes. Together that makes its rights predictable: it can never do more than the key says.
Owners and admins create keys in the app under Integrations, then API keys.
The tools
Section titled “The tools”tools/list shows what the current credential is allowed to do. tools/call checks the same
scope again, because a list is not a safeguard.
The catalogue has seventeen tools. Browser OAuth grants the monitor and incident scopes, and an
API key with status-pages:read adds list_status_pages. The connected server’s tools/list
is the reference for the credential in front of you.
| Tool | Scope | What it does |
|---|---|---|
get_organization_summary |
monitors:read |
The whole picture in one call: services by state, open incidents |
list_projects |
monitors:read |
Projects with their monitor counts. The entry point for create_monitor |
list_monitors |
monitors:read |
Services with their last confirmed state, filterable. Pass archived: true to see the archive |
get_monitor |
monitors:read |
One service with configuration, regions, and recent incidents. Custom request header values come back as [redacted] |
list_incidents |
incidents:read |
Open and resolved incidents, newest first |
get_incident |
incidents:read |
One incident in detail |
acknowledge_incident |
incidents:write |
Take the incident, which stops the alert and the escalation |
resolve_incident |
incidents:write |
Close an open incident by hand |
list_status_pages |
status-pages:read |
The organization’s status pages |
create_project |
monitors:write |
Create the folder monitors live in. Organization-wide credentials only |
create_monitor |
monitors:write |
Start monitoring a new service. Organization-wide keys only |
update_monitor |
monitors:write |
Change the name, settings, check interval, or regions |
set_monitor_enabled |
monitors:write |
Pause a monitor or put it back into service |
archive_monitor |
monitors:write |
Take a service out of service and free its slot in your plan |
restore_monitor |
monitors:write |
Bring an archived service back. It returns paused and needs a free plan slot |
get_heartbeat_endpoint |
monitors:write |
The secret ping URL of a heartbeat, to wire up its job. Every call is in the activity log |
rotate_heartbeat_endpoint |
monitors:write |
Issue a new ping URL for a heartbeat. The old one stops working at once |
write implies read on the same resource, never across resources.
create_monitor and update_monitor accept any check interval from your plan’s floor up to 24
hours, including 15 s on Command and 10 s on Enterprise. Values below the floor are raised to
it.
Everything the agent sees is English: tool names, descriptions, schema text, and error reasons. The activity log inside the app stays in your language, because people read that one.
create_project and create_monitor are the two tools that are not idempotent, and they
declare that to the client. Repeating either call can create a second resource or fail on the
name. Look first with list_projects or list_monitors.
Tools that change or end existing state (acknowledge_incident, resolve_incident,
update_monitor, set_monitor_enabled, archive_monitor, rotate_heartbeat_endpoint) are
marked as destructive, so a client may ask before it calls them. Creating and restoring only
add.
Custom request headers of a monitor are credentials and are never read back through a key or an
agent: get_monitor shows their names with the value [redacted]. Send a configuration back
through update_monitor with the placeholder in place, and the stored value is kept, as long as
the URL and the method stay exactly the same. After any change to either, the placeholder is
refused, so a credential never follows a request its author did not configure. The web app
still shows the values to signed-in members.
The ping URL of a heartbeat is a credential as well: whoever holds it can report success for the
job and so keep an outage green. An agent still needs it to finish the setup, so
create_monitor returns it for a new heartbeat, and get_heartbeat_endpoint returns it again
later. Both need monitors:write and a person behind the key who may still manage monitors,
and each hand-out is written to the activity log. get_heartbeat_endpoint carries no read-only
mark, so a client asks before it fetches a credential. The URL then sits in the agent’s
conversation. If that conversation is not one you trust, rotate the URL in the web app after the
setup, because rotate_heartbeat_endpoint would put the new one into the same conversation.
MCP archives and keeps the record
Section titled “MCP archives and keeps the record”An agent retires a service by archiving it, which keeps its history in place.
Use archive_monitor to retire a service and preserve its incidents, check history,
SLA rollups and exclusion windows. The same operation is available over the
REST API at POST /monitors/{monitor_id}/archive, with
POST /monitors/{monitor_id}/restore for the return. Archiving closes open incidents,
stops escalations and closes their external connector alerts. Permanent deletion by API key
is deprecated, announced on 2 October 2026, with removal no earlier than 1 January 2027
at 00:00 UTC. Successful DELETE responses link to the announcement.
archive_monitor stops the checks, removes the service from active lists, and frees its slot
in your plan while the resource stays restorable. Its history stays and follows the normal
object-specific retention rules. restore_monitor brings it back paused and claims a plan slot
again: on a full plan, the restore is refused with the same message as create_monitor until
another monitor is archived or the plan grows. The name is released on archive, so a new
monitor can take it.
For your quota, the difference counts: archiving frees a slot, pausing keeps it, because a paused monitor is still there and still meant.
The way back is always visible. list_monitors with archived: true shows the archive, and
get_monitor finds archived services too, so you can look before restoring, even without the ID
at hand. To change an archived monitor or switch it on, restore it first: update_monitor and
set_monitor_enabled answer “is archived, call restore_monitor first”, which tells the agent
exactly what to do next.
MCP writes focus on monitoring and incidents. Status pages, webhooks, and members are managed
through the REST API with a scoped key, and API keys and billing stay in the app.
list_status_pages reads status pages for API keys with status-pages:read.
Every action has a name
Section titled “Every action has a name”An action over MCP is attributed to the credential’s human identity, the API-key creator or the OAuth subject, so taking ownership during an incident carries a name and not just a token. The incident timeline additionally records that it came in over MCP. Monitors an agent creates or changes appear in your organization’s activity log the same way, under that identity’s name.
Because that identity is borrowed for attribution, it also governs permission. On every single write, the server re-checks that the identity is still a member of the organization and still carries the role the action needs. The threshold matches the app: handling incidents needs whoever is allowed to respond, down to a responder, while managing monitors needs whoever is allowed to manage projects, so an owner, admin, or developer. Downgrade or remove that identity, and its credential stops writing from the next call onward. Reading continues and depends on the credential’s scopes. If that person’s account has been deleted, the server refuses the write as well, and says why.
Narrowed keys
Section titled “Narrowed keys”A key restricted to specific projects or monitors sees its own resources in list_monitors and
list_incidents. Everything else is invisible to it, with no way to probe whether it exists.
The same holds when writing: update_monitor and set_monitor_enabled report that there is no
monitor with that ID rather than that it is forbidden.
Organization-wide tools, get_organization_summary, list_status_pages, create_project, and
create_monitor, stay with organization-wide keys. The two create tools would otherwise let a
narrowed key write into projects it knows nothing about.
Errors
Section titled “Errors”The list tools report total_matching and truncated alongside the rows, so a shortened answer
is recognizable as one instead of looking like a complete result.
A failure inside a tool comes back as a result marked as an error, with a plain-language reason, so the model sees what went wrong and can try something else. Protocol errors are reserved for malformed requests.
- MCP across a fleet: keys and boundaries for many services and teams.
- API: the full REST API with scoped keys.