My AI agent set up our nonprofit's monitoring
Outside of Atomic Van, I’m the president of the Griffin Arts Council, a nonprofit here in Griffin, Georgia. I also built its website, which makes it the perfect place to test Pingstack in production. If something’s off with a new feature, I’m the one who finds out first, and I’m the one who fixes it.
Every check on that site was created by an AI coding agent.
How it works
Pingstack has an MCP server. MCP is the way AI coding tools like Claude Code and GitHub Copilot connect to outside services. You add the server once, sign in through your browser, and from then on your agent can work with Pingstack using your account and your permissions.
For Claude Code, the setup is one line:
claude mcp add --transport http pingstack https://pingstack.io/mcp
After that, I asked the agent to set up monitoring for the Griffin Arts site, and it did.
What it set up
The agent created eight checks and put them on one dashboard:
- GriffinArts.org, a website check on the main site
- GriffinArts.org Assets, a website check on the server that hosts images and files
- GriffinArts.org SSL, which counts down to the certificate’s expiry
- GriffinArts.org Domain, which counts down to the domain renewal
- GriffinArts.org DNS, WWW DNS, and MX DNS, which watch the records for the main domain, the www address, and email
- Daily Production Refresh, a heartbeat for the nightly rebuild and deploy of the site
That last one is my favorite. A heartbeat is a check that expects a scheduled job to report in. If the job doesn’t call its ping URL on time, Pingstack opens an incident. When the agent writes a new scheduled job, it can create the heartbeat for it in the same change. The job and its monitoring ship together, so there’s never a gap where something’s running unwatched.
The agent can’t publish anything on its own. I published the dashboard myself as a public status page at status.griffinarts.org, so anyone can check on the site without logging in.
The daily refresh
Every night after midnight Eastern, a scheduled GitHub Actions workflow rebuilds griffinarts.org. It runs the site’s validation checks, builds it, and deploys it to GitHub Pages. Then it reports to Pingstack through our heartbeat action, which is free and open source under the MIT license.
The report is its own job at the very end, and it waits for both the validation and the deploy to finish:
heartbeat:
if: always() && github.ref == 'refs/heads/production' && github.event_name == 'workflow_dispatch'
needs: [production-validation, production]
runs-on: ubuntu-latest
steps:
- name: Report to Pingstack
uses: pingstack-io/heartbeat-action@v1
with:
ping-url: ${{ secrets.PINGSTACK_PING_URL }}
status: ${{ contains(needs.*.result, 'failure') && 'failure' || contains(needs.*.result, 'cancelled') && 'cancelled' || 'success' }}
fail-on-error: true
Reporting once from a final job means one job’s success can’t hide another’s failure. A ping means the site was actually checked, built, and deployed. If either job fails, Pingstack alerts right away with a link to the run. And if GitHub delays or skips the run, or the schedule gets turned off, Pingstack notices when the next report is overdue. That’s the case people miss. A workflow that never runs never fails, either.
A few details in there are worth stealing:
if: always()makes the report run even when an earlier job failed. Without it, a failure would skip the report and Pingstack would only find out once the run was overdue.github.event_name == 'workflow_dispatch'limits reports to dispatched runs, which is how the nightly refresh starts the deploy. An ordinary push to production doesn’t count as the nightly check-in.fail-on-error: truefails the job if the report can’t be delivered, so a monitoring problem shows up in GitHub too. The action’s default is off, so monitoring never breaks your build unless you ask it to.
The action itself is a short bash script with no dependencies, and it keeps the ping URL out of your logs. The basic setup takes three steps, and they’re written out in the GitHub Actions recipe. There are recipes for plenty of other schedulers too, from plain crontab and Kubernetes to Laravel, Rails, and Vercel.
The guardrails
Letting an agent loose on your monitoring sounds a little scary, so we built limits into the MCP server.
The agent gets my permissions and my plan’s limits, nothing more. It can create and update checks, attach them to dashboards, and read incidents and uptime. It can’t delete checks, publish a dashboard, or buy anything. If it hits a plan limit, it hands me an upgrade link to open myself.
Those limits were the whole point. I want the agent doing the tedious setup. I don’t want it making decisions that belong to a person.
What it caught
On October 17, Pingstack warned that the site’s SSL certificate would expire in 30 days. We fixed it the next day, and the certificate now has about 80 days left.
Nobody needed a calendar reminder for it.
Over the last 30 days, those eight checks recorded 58,911 results. All eight are healthy as I write this, and the main site answers in about 23 milliseconds.
Try it on your own project
Pingstack’s MCP server and API are on every plan, including the free one with 15 checks. If you already use an AI coding tool, next time it adds a scheduled job, ask it to add the heartbeat too. The setup docs cover Claude Code and Copilot.