Skip to content
LastPing

Release history

Changelog

What's shipped in LastPing, most recent first. The project lives at github.com/lastping-dev/lastping-app.

2026

Feature

LastPing is in the Claude Connectors Directory

LastPing is listed in Anthropic's Claude Connectors Directory. In claude.ai, Claude Desktop, the mobile apps and Cowork, open LastPing's listing or search for LastPing under Settings, Connectors, Discover, then connect it and sign in. The connector's tool descriptions now state what each tool does and returns, and get_ping_instructions returns a coding agent's hook install only when the tool argument names that agent, which makes a plain call about a third of the size.

Feature

Antigravity CLI: runs and traces

A hook script now reports each Antigravity CLI turn as a run, with a step per tool call. Store a tracing key and the same script sends spans for model and tool calls. There are no token counts or cost, because Antigravity does not expose them. Install it from the monitor's Connect page, or ask your assistant to call get_ping_instructions with the tool antigravity.

Fix

Cursor tracing set-up fixed

Cursor tracing set up before today sent nothing, because the runner posted to the wrong address. Run the set-up on the monitor's Connect page again (or ask your assistant to call get_trace_setup) and the next turn arrives.

Feature

Set up LastPing from your coding agent with one command

npx skills add lastping-dev/skills adds the LastPing skill to Claude Code, Codex, Antigravity CLI, VS Code and other agents. Ask Monitor this project with LastPing and it connects LastPing, proposes a monitor for each scheduled job it finds, and creates them once you agree.

Feature

Continue with Google; manage sign-in methods (password, GitHub, Google) in Settings

The sign-in page has a Continue with Google button beside GitHub and email. Settings, Profile now lists the sign-in methods on your account (password, GitHub, Google), and you manage them there.

From Google we keep your email address, whether Google verified it, and the account id. Nothing from your Google profile is stored.

Feature

Incident timeline

The incident page, GET /api/v1/incidents/{id} and the MCP tool get_incident now show every recorded event about an incident in order: the run starting and its steps, the failing ping, which alerts went out and to whom, notes, and resolution.

Nothing is inferred: a timeline with no run events means no run was recorded.

Improvement

A Slack destination now has to point at Slack

Destinations with a brand on them are pinned to that brand's hosts: slack to hooks.slack.com, discord to discord.com or discordapp.com, msteams to webhook.office.com, outlook.office.com, logic.azure.com, logic.azure.us or environment.api.powerplatform.com, googlechat to chat.googleapis.com. Every destination URL must use https.

To deliver alerts somewhere else, use the webhook kind. It takes any https endpoint and signs the payload with your shared secret, and it is what the console, the API, MCP and Terraform will point you at if a branded URL is refused. ntfy is unpinned, so a self-hosted ntfy server keeps working.

A destination's config must also name only the fields its kind accepts, each exactly once. A stray or repeated key used to be silently dropped, which is how a setting you thought you had saved turned out never to have applied. It is now an explicit refusal that names the fields the kind takes.

Nothing you already have stops working. A destination stored before this change keeps delivering, and renaming it is unaffected. The rules apply the moment you edit its config. Alongside this, a project now holds at most 25 destinations.

Being on a vendor's host is a labelling rule, not proof of ownership: every one of those domains is multi-tenant and anyone can obtain an endpoint under one. What the pin removes is a destination labelled Slack quietly feeding your whole alert stream somewhere else.

The same check at send time (refusing to deliver to a grandfathered destination that is off-host) is built and ships switched off. Turning it on would silence exactly the destinations deliberately left alone above, so it waits on evidence: until then the notifier logs each delivery the rule would have stopped, and nobody's alerts go quiet without warning.

Feature

API keys have scopes, and revoking one revokes what it created

Every API key now carries a scope: read, write or admin. read is every GET except the API-key list, which counts as key management. write is everything a job or an agent actually does: ping, create monitors, edit routes. admin adds the one thing the other two cannot do: manage API keys.

Nothing you have changes. Every key that existed before this release is admin, so every script, agent and Terraform run keeps working exactly as it did. New keys default to write on every surface (the console, the REST API, the MCP server, the connect page) because a credential handed to CI or to an agent should be able to do the work and not be able to mint itself a replacement. Ask for admin explicitly when you want it. A key can never create a key that outranks it; the refusal tells you the highest tier you may ask for.

Refusing a request that reaches past its scope is switched on separately, and is not on yet. Until it is, the scope is recorded on the key and a would-be refusal is logged, so the switch gets thrown on evidence rather than on a guess about whose automation is about to break.

Keys also remember who made them. A key created by another key records that parent, and both the API and the console show it: the key list in Settings has a Created by column. That record does one job: revoking a key now revokes every key descended from it: the keys it created, the keys those keys created, all the way down, in a single step. This is the gap that made a leaked key worth more than it looked: a credential that can make credentials can quietly leave one behind and outlive its own revocation. It cannot any more. A key you made in the console has no parent, so it is never swept up by someone else's revoke, and the revoke never reaches outside your project.

Regenerate is deliberately not a cascade. Rotating a key is "same key, new secret", not "destroy everything this key ever made", so anything that key created keeps working and simply loses its parent.

Improvement

Everyone is signed out once, and sessions get an idle timeout

You will be asked to sign in again after this release. Once. Your monitors, keys, destinations and history are untouched: only the browser session ends.

The reason is worth stating plainly. Until now, the console stored your session token as it was: the value in your browser was the value in our database. Anything that could read that table (a backup, a restored snapshot, a support query) was reading live credentials. It now stores only a one-way hash, so the value in the database cannot be used to sign in as you. A stored token cannot be converted into a hash of itself, so the existing rows had to go, and that is the single sign-out.

Sessions also gained a second clock. A session you do not use for 7 days now ends on its own, and is deleted rather than left sitting in the table. Using the console slides that window forward, so a console you work in daily does not sign you out. The outer limit moved the other way: a session now lasts up to 30 days of continuous use, where before it ended after a day whatever you did. The practical effect for most people is fewer sign-ins, not more, with a shorter leash on a browser left alone.

API keys are unaffected. They were already stored as hashes, they have their own expiry, and nothing about this release changes a key, a script, an agent, or a Terraform run.

One operational note: our own admin dashboard counts a signed-in user by whether a live session row still exists, so this cutover and the new idle timeout will make that internal count dip on their own, with no change in who is actually using LastPing.

Improvement

Keys made by agents now expire, and no key outlives its creator

The 31 August entry below said keys created through the REST API, MCP or Terraform still default to no expiry. That is no longer true of MCP. A key created by an agent through create_api_key, and a key created from the connect page, now default to 90 days, or to the creating key's own expiry, if that comes sooner.

The bigger change is a ceiling rather than a default: a key created by a key may not be given a later expiry than the key that creates it. Ask for a longer one and the request is refused, and the refusal tells you the latest date you may ask for. A leaked credential can no longer be spent on minting a longer-lived replacement for itself before anyone notices and revokes it.

Omitting expires_at is unchanged everywhere it already worked: in the console, and through the REST API or Terraform, an omitted value still means no expiry. Only the ceiling is new. A future release will let an omitted value take the creating key's expiry instead of no expiry at all, once the Terraform provider can represent that.

Feature

API keys: regenerate in one click, and a default expiry

A new API key is shown once and stored only as a hash, so a key you did not copy cannot be recovered. That is still true, but losing one no longer means leaving a live key behind and creating a second. Every key now has a Regenerate action that issues a replacement under the same name and stops the old one immediately.

Keys created in the console now carry an expiry, 90 days by default, with 30 days, a year, and “never” also available. The expiry date is shown in the key list. Keys created through the REST API, MCP or Terraform are unchanged: those surfaces take an explicit expires_at and still default to no expiry.

Feature

Find the jobs nobody is watching

An agent can now scan a repository or a host, work out what ought to be monitored, and hand LastPing the list. Cron tables, GitHub Actions schedules, Kubernetes CronJobs and systemd timers. Nobody fills in a form.

All the scanning happens on the agent's side: LastPing never reads your repository. It supplies three things: what to look for, a diff of a scan against what already exists, and a bulk create.

The important property is that it is safe to re-run. Sources already monitored come back untouched: not the name, not the schedule, not a threshold you tuned by hand. Monitors whose source has disappeared are reported, never deleted. So you can run it nightly, and the second run tells you what has appeared and what has gone: a scan that runs once is a setup wizard, a scan that is safe on a schedule is drift detection.

Discovered monitors say where they came from, on the monitor's own page. And because a crontab job fires in its host's local time rather than UTC, a scan that finds one must state the zone it read: guessing puts the deadline about twenty hours off and pages you every day. The reconcile step ships as one MCP tool, discover_monitors_reconcile, which takes the server to 36 tools.

Improvement

Exit codes are kept, not thrown away

A job that reports its exit code was having the number discarded at the front door: 137, 124 and 1 all became simply "failed". They are not the same failure. 137 is the OOM killer, 124 is a timeout, and 1 is whatever the program decided.

The code is now recorded and shown on the incident, translated where the meaning is unambiguous ("killed by SIGKILL" rather than a bare 137) and left plain where it is application-defined, because a confident wrong explanation is worse than a number. Runs that reported no code say nothing rather than claiming a clean exit.

Feature

Is this new, and was it slow?

An incident now says how many times that exact failure has happened and when it was first seen. Failures are matched by normalising the body first (timestamps, request IDs, IP addresses, file paths and numbers are replaced before comparison) so two runs that failed the same way an hour apart, with different retry counts and different request IDs, are recognised as the same failure rather than two unrelated ones.

That answer outlives its evidence. The comparison is kept separately from the pings it came from, so it still works after those pings age out of retention. "First time" and "the fortieth time" need different responses, and until now nothing told you which one you were looking at.

A monitor's runs are also compared against its typical duration: each day's own median run, then the median of those. A run materially slower than usual is marked, showing both durations and how many days it was measured over, so the comparison is checkable rather than something to take on trust. A monitor too young to have a baseline says so instead of implying the run was normal.

Feature

The agent reads why it failed, and writes back what it found

An agent can now start a run by asking what its previous runs left behind: GET /api/v1/agents/{id}/open-incidents returns each open incident with the cause, the failure body, the step it died on, how many times that same failure has occurred, and how the run's duration compared to normal. "Your check failed" is worth nothing to an agent that already knows; what it cannot work out for itself is whether this has happened before.

It can then write back an explanation, which appears on the incident attributed to the agent. Instead of "check failed at 03:04", the person reading the alert gets "failed because the upstream API returned 503; same failure as the last three nights; I retried twice and stopped."

Notes are append-only. A correction is a new note, never an edit: a diagnosis whose history a reader cannot trust is not evidence. Reading the inbox and writing a note are available over both REST and MCP (list_open_incidents and add_incident_note), and the agent is told about them in its ping instructions. Those two take the MCP server from 33 to 35 tools.

Feature

An agent can no longer grade its own run

An agent reports its own success by calling the success ping. That is self-grading, and it is the failure liveness monitoring cannot see: an agent that finishes confidently and produces garbage looks exactly like one that worked.

With declare_run_expectations, an agent commits at the start of a run to the criteria that run will be judged by, before it can see how things turn out. A success ping whose body does not meet them is recorded as a failed run, whatever the exit code says, and the incident names the criterion that was not met.

The declaration is immutable: a second attempt for the same run is refused and the first one stands. An agent that could revise its criteria once it saw the outcome coming would simply be grading itself again, with extra steps. Declaring nothing is still allowed: an agent that says nothing leaves the monitor's own assertions in force. It is one new MCP tool, taking the server from 32 to 33.

Improvement

Hooks report failure too, and the console stops guessing at connection state

Claude Code's hook install (hook_install) wired up Stop for success but nothing for failure: Stop fires for any turn that ends, cleanly or not, so a turn that died on an API error still reported as a success. StopFailure, the hook Claude Code fires instead of Stop when that happens, is now wired up too. Monitors also gained a notification duration floor (notify_min_run_s): a run shorter than the floor is still recorded but does not notify, so a fleet of fast jobs stops paging on every completion; a failure is never suppressed by it, regardless of duration.

The connect page and the agent detail page now show whether MCP is actually connected instead of assuming it from a key being present, which caught a real bug: an invalid API key used to return a green "connected" state with the full tool list attached. The MCP server now validates the bearer token and returns 401 for anything invalid.

Feature

Incidents say what happened

An incident used to be titled by the rule that fired it: silence, overrun, assertion. It now reads as a sentence built from what was actually recorded: Stopped reporting 42m ago, Stopped 52s into a run, last step: export, Ran, but rows processed was 3 (expected at least 10).

Where the data does not support a sentence the plain cause is shown instead. There is no confidence score: detection here is deterministic (a deadline passed or it did not) and a percentage would suggest the alert might be wrong when it cannot be.

Feature

A silence floor, so a quiet agent cannot read healthy

An on-demand monitor has no cadence, so between runs it armed nothing at all: an agent that simply stopped reporting stayed green. That is the one failure this product exists to catch, so it is now catchable: set expect_every_s and the monitor alerts if nothing at all arrives inside that window.

It is opt-in, and it stands down while a run is in flight (that window belongs to the run budget) and while the agent is blocked waiting on a person.

Feature

lastping run: reporting you cannot forget

Asking a job (or an AI agent) to remember to report works until it does not. The new CLI wraps whatever you already run and reports from the process itself.

curl -fsSL https://raw.githubusercontent.com/\
      lastping-dev/lastping-app/main/install.sh | sh

    lastping run --monitor <id> -- python nightly_etl.py
    lastping run --monitor <id> -- ./backup.sh

A start ping, then the exit code as success or failure with the tail of stderr attached. Your exit code always propagates, and a ping that cannot be sent never touches your command. No Go toolchain needed: the installer fetches a prebuilt binary for macOS and Linux and verifies its checksum.

Improvement

Connect your agent in one step, and 32 MCP tools

The console used to hand you a server URL and an auth header and leave you to work out the rest. There is now a connect page that asks which client you use (Claude Code, Claude Desktop, Cursor, Windsurf, Codex) and gives you the exact command or config file for it, with the key already filled in.

The MCP server grew from 27 tools to 32: status pages are now manageable from an agent, destinations can be deleted, routing can be read before it is replaced, and get_ping_instructions returns the wrapper and hook setups rather than only the manual protocol.

Fix

blocked alerts now reach you by default

blocked means an agent has stopped mid-task and is waiting on a person: approval, a credential, a decision. It was not in the set of events routed to a new monitor's default destination, so by default nobody was told. It is now, and existing monitors still on their defaults were updated.

Feature

Output assertions and metric guards

A job that runs on time, exits zero and does nothing was a green check. Assertions read the ping body a job already sends and turn a success into a failure when it does not say what it should: a substring, a regular expression, or a JSON path compared against a value. The incident quotes what it got against what it expected.

Metric guards do the same for numbers. Report cost_usd or a token count in the body and alert when the sum, max or average crosses a ceiling over a trailing window. An agent that loops and burns money is no longer a monitor that says everything is fine.

Feature

The agent registry, on-demand monitors, and blocked

Register an agent and every monitor it owns rolls up into one live state, worst first: down, blocked, late, running, up, pending, idle. The one that matters most is blocked: a run that stopped to ask you something and is still waiting.

Agent work does not run on a schedule, so on_demand monitors do no absence detection between runs; they bound a run once one starts. Run history now covers agent runs too, not only CI, so an agent can ask where its own last run got to. The Terraform provider gained a lastping_agent resource to match.

Feature

Stall detection: catch a run that stops making progress

A long job that hangs has always been caught by overrun detection, but only once its whole run budget expires, and the alert could not say where it wedged. Runs can now report progress, and a run that stops reporting opens a stalled incident that names the last step it reached.

RID=$(uuidgen)
    curl -fsS "$URL/start?rid=$RID"
    curl -fsS "$URL/step?rid=$RID&step=dump"
    curl -fsS "$URL/step?rid=$RID&step=upload"
    curl -fsS "$URL?rid=$RID"

Set step_timeout_s on the monitor to the longest gap you expect between steps. Exceed it and an incident opens immediately ("hung at upload, no step in 12m") instead of at the end of the run budget. The monitor detail page shows each recent run's timeline with the gap between steps, and the new {last_step}, {step_count} and {run_duration} template variables put the same context in your own alert copy.

This is opt-in. A monitor that sets no step_timeout_s behaves exactly as it did before: nothing changes for jobs you do not instrument. A step never extends the run budget either: a job that reports progress forever still overruns.

Available on the REST API, the dashboard, and the MCP server: create_monitor and update_monitor take step_timeout_s, get_ping_instructions hands an agent a ready-to-run curl_step snippet, and get_run_history returns each run's steps.

Milestone

Terraform provider: monitoring as code

The LastPing Terraform provider is live on the public Terraform Registry as lastping-dev/lastping v0.1.0. Monitors, destinations, alert routing, alert messages, status pages and API keys are all manageable as code: reviewed in a pull request, applied by your pipeline, and diffable like the rest of your infrastructure.

terraform {
      required_providers {
        lastping = {
          source  = "lastping-dev/lastping"
          version = "~> 0.1"
        }
      }
    }

There is also an ephemeral API-key resource. It mints a short-lived key for a single run and revokes it when the run ends, so no long-lived credential is ever written into Terraform state.

Already have monitors? Export as Terraform on the monitors list emits HCL for what you have, complete with import blocks, so adopting Terraform adopts your existing monitors rather than recreating them.

Feature

Monitor tags, CI run history, and a docs hub

Monitors can now carry tags, so a fleet that grew one job at a time can be grouped by service, team, or environment, in the console, over the API, and from an agent.

CI monitors keep a run history: the recent runs behind a monitor, each with its failing step, actor, commit, and a deep link to the provider's run page. Agents can read the same history through the get_run_history tool. A log excerpt is attached too, when you've added the optional if: failure() step to your own workflow: the run tracking itself needs no YAML change.

The documentation is now a hub rather than a single page, with setup guides per signal source and a section on the MCP server.

Feature

Dashboard improvements

First-run onboarding now shows a live listening for your first heartbeat card, so you can watch a new monitor come alive instead of guessing whether the ping landed. The monitors list gained one-click pause, resume, and delete, and relative timestamps tick live rather than going stale between refreshes.

Feature

Remote MCP server at mcp.lastping.dev

The MCP server is now hosted at mcp.lastping.dev over Streamable HTTP with bearer auth. Point an agent at the URL with an API key and it connects: nothing to install, no local process to keep running.

The endpoint is advertised in the discovery document and on the agents page, so an agent can find it without being told where to look.

Release

Agent-first: the MCP server and runaway detection

LastPing now ships an MCP server, lastping-mcp, that lets an AI agent create and manage monitors directly. The flagship tool is get_ping_instructions: an agent can instrument its own dead-man's-switch mid-conversation, without a human stopping to wire up monitoring first.

API errors are written for that reader too. Each one carries a machine-readable code and a fix hint, so an agent can correct a bad request instead of retrying it verbatim. A GET /.well-known/lastping.json discovery endpoint describes the service to whoever asks.

Runaway detection landed alongside it: a per-monitor ceiling that opens an incident when a job or an agent loops far more often than expected. Silence was already covered: this covers the opposite failure. More on the agents page.

Milestone

Project published on GitHub

The LastPing project repository is now live at github.com/lastping-dev/lastping-app. The CLI and the MCP server live there, and issues can be filed against them.

There is no open-core split. The hosted service at app.lastping.dev is free for individuals. Follow the project on the project page.

Feature

CI/CD signal sources

GitHub Actions, GitLab CI, and Jenkins can now send signed webhook events to LastPing: no YAML polling loop needed. Each event carries the pipeline run URL, so incidents deep-link directly to the failing build.

Signatures are verified with HMAC-SHA256 on the ingest service. A new ci monitor type tracks run outcomes (success / failure / timeout) and fires incidents on first miss.

Feature

Active HTTP monitoring

A new http monitor type lets you probe any URL on a configurable schedule. LastPing checks status code, response time, and optional keyword presence, SSRF-guarded to private address ranges.

Response-time charts are available in the console. Alerting follows the same incident model as heartbeat monitors: an incident opens on first failure and closes on recovery.

Redesign

The Slate redesign: console & new screens

The app console is now a dark observability console built on the Slate design system: command palette (⌘K), expandable sidebar, and a toast notification stack. The palette is amber-free: slate backgrounds, teal accents, semantic status colours.

Two new screens shipped with the redesign: an Incidents screen for managing open and resolved incidents in one place, and an Analytics screen with monitor health over time.

Feature

Alerting configuration: routing matrix & custom templates

Alert routing is now configured via a matrix: each row pairs a destination channel (email, Slack, Discord, Telegram, webhook) with one or more event types (incident opened, resolved, late). You can attach multiple channels to a monitor and route different events to different destinations in one view.

Custom message templates let you write per-event alert copy: runbook links, ownership context, whatever your on-call team needs. Templates use a safe, defensive rendering engine and fall back to defaults on any error.

2025

Launch

Initial release

LastPing launches with heartbeat / dead-man's-switch monitoring: send a ping after a job succeeds; LastPing alerts you if the ping stops arriving within the expected window.

Also in the initial release: alert channels (email, Slack, Discord, Telegram), public status pages per project, and a hosted service at app.lastping.dev, free for individuals.

Start monitoring in minutes

Free for individuals. One URL to ping, or let your AI assistant set it up.