agent-vitals

agent-vitals

Local-first observability for AI agent stacks. Provides MCP tools for agents to check health, shadow configs, and burnout metrics proactively.

Category
Visit Server

README

<div align="center">

<span style="color:#00d992">⚡ agent-vitals</span>

<span style="color:#f2f2f2">Give your AI agent a memory of its own infrastructure.</span>

<p> <a href="https://github.com/anirudhprashant/agent-vitals/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-00d992?style=flat-square" alt="License"></a>  <a href="https://github.com/anirudhprashant/agent-vitals/releases"><img src="https://img.shields.io/badge/version-v0.5.0-3d3a39?style=flat-square" alt="Version"></a>  <a href="https://github.com/anirudhprashant/agent-vitals"><img src="https://img.shields.io/badge/python-3.11%2B-2fd6a1?style=flat-square" alt="Python"></a>  <a href="https://github.com/anirudhprashant/agent-vitals"><img src="https://img.shields.io/badge/LOC-%7E2700-8b949e?style=flat-square" alt="LOC"></a>  <a href="https://modelcontextprotocol.io"><img src="https://img.shields.io/badge/MCP-stdio-00d992?style=flat-square" alt="MCP"></a> </p>

<p> <code style="color:#00d992">5 MCP tools · 6 CLI tools</code>  ·  <code style="color:#b8b3b0">wires pi · Claude Code · Cursor · OpenCode · Codex CLI</code>  ·  <code style="color:#b8b3b0">~2700 LOC · 200 tests · MIT · no daemon · no cloud</code> </p>

<p> <a href="https://anirudhprashant.github.io/agent-vitals/" style="color:#00d992">→ landing page (anirudhprashant.github.io/agent-vitals)</a> </p>

</div>


<span style="color:#00d992">▍</span> What your agent sees

When your agent (pi, Claude Code, OpenCode, Cursor, Codex) calls vitals_summary, it gets:

  ▄▀ agent-vitals — local agent stack health

  shadow: 13 autonomous thing(s) configured (mcp: 8, systemd: 5)
  subagent burnout (7d): 5 runs, 100% completion ✓
  claude code (7d): 170 sessions, 45,626 events, ⚠ 36 stuck
    - biggest stuck-looking session: 7,118 events

That's not a CLI you read. That's a tool your agent calls from inside its own loop — before it does anything risky.


<span style="color:#00d992">▍</span> Before / after

<table> <tr> <th width="50%" align="left"><span style="color:#fb565b">▍ Without agent-vitals</span></th> <th width="50%" align="left"><span style="color:#00d992">▍ With agent-vitals</span></th> </tr> <tr> <td valign="top">

User: schedule a daily backup at 2am

Agent: yep, done.

  0 2 * * * /home/me/backup.sh
        >> /tmp/backup.log 2>&1

… and /home/me/backup.sh doesn't exist. Crontab fails silently forever.

</td> <td valign="top">

User: schedule a daily backup at 2am

Agent: one moment — verifying first.

  → shadow_stale       (no other cron broken)
  → check backup.sh    (exists? writable?)
  → write crontab entry
  → shadow_stale       (confirm no breakage)

  ✓ crontab updated.

</td> </tr> <tr> <td valign="top">

User: is my agent setup healthy?

Agent: looks fine to me!

(blind vibes)

</td> <td valign="top">

User: is my agent setup healthy?

Agent: → vitals_summary

  shadow: 13 autonomous thing(s) configured
  claude code (7d): ⚠ 36 stuck sessions
    - biggest: 7,118 events

  ⚠ 36 sessions look stuck. want me to triage?

</td> </tr> </table>

The diff is vibes vs. data.


<span style="color:#00d992">▍</span> Install

uv tool install git+https://github.com/anirudhprashant/agent-vitals
av init     # detects every agent host on your box and wires them up
            # restart your agent host so it picks up the new MCP server

That's the whole setup. <span style="color:#00d992">30 seconds.</span>


<span style="color:#00d992">▍</span> Pre-action hooks (v0.3.0)

Priming asks the agent to call vitals. Hooks refuse the operation when it hasn't.

av hooks install     # one-time setup (~3 seconds)
av hooks status      # check freshness
av hooks disable     # temporarily turn off (rename to *.disabled)
av hooks uninstall   # full removal

After av hooks install, the one-liner above is appended to your ~/.bashrc / ~/.zshrc. Open a new terminal and crontab -e or systemctl --user enable foo will be refused at the OS level unless an agent (or av doctor) refreshed the vitals stamp in the last 60 seconds.

  ⚡ agent-vitals hook: refused `crontab -e`

  reason:   vitals stamp is 5m12s old — exceeds 60s window.
  stamp:    5m12s ago

  refresh:  call any vitals tool or run `av doctor`
  bypass:   VITALS_BYPASS=1 crontab -e

What's gated: crontab -e/-r/-i/<file>/- and systemctl --user {enable,disable,start,stop,restart,reload,mask,unmask,daemon-reload,...}.

What's NOT gated: crontab -l (reads), systemctl status / list-* / is-active / show / cat (reads), and power management (reboot, poweroff, suspend) — a stale stamp must never block a reboot.

Bypass for emergencies: VITALS_BYPASS=1 crontab -e skips the check.

<span style="color:#00d992">▍</span> What av init does

  $ av init
                    detected 3 agent host(s)
  ┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
  ┃ host        ┃ config                           ┃ status   ┃
  ┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
  │ pi          │ /home/anirudh/.pi/agent/mcp.json │ detected │
  │ Claude Code │ /home/anirudh/.claude/.mcp.json  │ detected │
  │ Codex CLI   │ /home/anirudh/.codex/config.toml │ detected │
  └─────────────┴──────────────────────────────────┴────────━━┘

  installing:

  ┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
  ┃ host        ┃ mcp config         ┃ skill/rule        ┃
  ┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
  │ pi          │ added              │ installed         ┃
  │ Claude Code │ added              │ already installed ┃
  │ Codex CLI   │ added              │ installed         ┃
  └─────────────┴────────────────────┴────────────────━━━┛

  ✓ done. Restart your agent host.
Host MCP config Priming
<span style="color:#00d992">pi</span> ~/.pi/agent/mcp.json ~/.claude/skills/agent-vitals/SKILL.md
<span style="color:#00d992">Claude Code</span> ~/.claude/.mcp.json ~/.claude/skills/agent-vitals/SKILL.md
<span style="color:#00d992">Cursor</span> ~/.cursor/mcp.json ~/.cursor/rules/agent-vitals.md
<span style="color:#00d992">OpenCode</span> ~/.config/opencode/mcp.json ~/.config/opencode/AGENTS.md
<span style="color:#00d992">Codex CLI</span> ~/.codex/config.toml ~/.codex/AGENTS.md

[!NOTE] Idempotent. Re-run av init any time — existing entries are skipped, never duplicated. TOML configs (Codex CLI) get TOML sections; JSON configs get JSON entries.


<span style="color:#00d992">▍</span> The five tools

Tool Returns When the agent should reach for it
vitals_summary() plain English always first — health check, before tasks, when stuck
shadow_list() JSON array before infra changes — see everything running on the user's behalf
shadow_stale() JSON array before claiming "your crontab is fine" or scheduling new cron work
burnout_summary(days=7) JSON object after long tasks, to compare to baseline
burnout_stuck_sessions(days=7, limit=10) JSON array when suspecting a loop, to see if other sessions are stuck too

All tools are local-only, read-only, safe to call repeatedly. None of them modify state.


<span style="color:#00d992">▍</span> The trigger table

The table av init installs into your priming skill — so the agent knows when to reach for each tool without you asking:

Trigger Tool
Starting any non-trivial task vitals_summary
About to schedule cron / timer / systemd work shadow_stale
After a long task completes burnout_summary
Suspect you're in a loop vitals_summary + burnout_stuck_sessions
User asks "is X working?" shadow_list or vitals_summary
About to claim "all cron is fine" shadow_stale (verify first)
About to recommend an MCP install shadow_list (check duplicates)
User asks "what's broken?" vitals_summary → shadow_stale + burnout_stuck_sessions

[!WARNING] Honesty note. Priming isn't enforcement. The SKILL.md puts these triggers in front of the agent's face, but the agent still has to remember to follow them. In practice this catches ~30–40% of cases — better than nothing, not a magic bullet.

v0.3.0 changes this. av hooks install deploys PATH-level wrappers around crontab and systemctl --user that refuse any mutation when the vitals stamp is older than 60 seconds. Read operations (crontab -l, systemctl status, etc.) are never gated. See Pre-action hooks below.


<span style="color:#fb565b">▍</span> Anti-patterns this exists to prevent

[!IMPORTANT] These are the failure modes that made us build agent-vitals. If you see an agent doing any of these, it's a sign the priming didn't reach them — or they need v0.3.0 hooks.

  • ❌ "Your crontab is fine" — without calling shadow_stale first
  • ❌ Scheduling cron / systemd work — without verifying the target binary exists
  • ❌ Starting a 4-hour task — while 6 other sessions are stuck on the same box
  • ❌ Pretending a task completed — without checking burnout_summary
  • ❌ Recommending an MCP install — without shadow_list to check for duplicates
  • ❌ Debugging slowness — without first checking vitals_summary

<span style="color:#00d992">▍</span> What it scans

Source Path What it finds
Crontab crontab -l flags targets that no longer exist
systemd user timers systemctl --user list-timers systemd-v255 quirk-resistant (computes next - now itself)
MCP configs ~/.pi/agent/mcp.json, ~/.claude/.mcp.json, ~/.cursor/mcp.json, ~/.config/opencode/mcp.json one entry per host registration
Codex CLI ~/.codex/config.toml TOML-aware, appends [mcp_servers.agent-vitals]
Skill frontmatter ~/.claude/skills/*/SKILL.md surfaces skills with schedule: / cron: / interval: triggers
pi subagent history ~/.pi/agent/run-history.jsonl per-agent completion + trend
Claude Code sessions ~/.claude/projects/*/*.jsonl session counts + stuck-loop heuristic

<span style="color:#00d992">▍</span> CLI (humans only — for verification)

av                # one-shot health summary
av doctor         # summary + actionable recommendations
av shadow         # what's configured on your box
av shadow --watch # live refresh every 2s
av burnout        # completion metrics, last 7 days
av burnout --days 30
av detect         # list detected agent hosts
av init           # wire agent-vitals into every detected host
av mcp            # start the MCP server (stdio)
av --help

<span style="color:#00d992">▍</span> Stack

Python 3.11+    ──  type hints, tomllib, asyncio
uv              ──  one-tool install / build / publish
typer           ──  CLI
rich            ──  terminal rendering
pyyaml          ──  SKILL.md frontmatter parsing
mcp (FastMCP)   ──  MCP server, stdio transport
pytest          ──  104 tests across 3 modules

~1200 LOC of Python + the priming SKILL.md + 104 tests. MIT licensed.


<span style="color:#00d992">▍</span> Roadmap

  • [x] v0.1.0 — shadow + burnout CLI commands
  • [x] v0.2.0 — MCP server + av init for 5 host types
  • [x] v0.2.1 — fix false-positive duplicate detection across hosts
  • [x] v0.3.0 — <span style="color:#00d992">pre-action hooks</span> for crontab + systemctl (priming → enforcement, with bypass)
  • [x] v0.4.0 — <span style="color:#00d992">the full suite</span>: interactive av install, av drift, av cost, av sessions, av snapshot
  • [x] v0.5.0 — <span style="color:#00d992">efficiency suite</span>: av loops (doom-loop detection), av unused (registered-but-unused MCP tool detector), GitHub's Effective Tokens (ET) metric in av cost. 200 tests total.
  • [ ] v0.6.0 — expose drift / cost / sessions / snapshot / loops / unused as MCP tools (currently CLI-only)
  • [ ] v0.7.0 — shadow live (running agent processes, ps-tree view)
  • [ ] v0.8.0 — cross-session "agent déjà vu" detector (you researched this codebase 3 weeks ago)

<span style="color:#00d992">▍</span> Contributing

Issues and PRs welcome. Two things to know:

  1. Scanners in src/agent_vitals/scanners.py are independent and fail gracefully. Add a new source by writing one scan_*() function and adding it to scan_all().
  2. MCP tool docstrings are the product. The docstring on vitals_summary is the instruction the agent reads. Write it as a directive to the agent ("always call this first when…"), not API docs.

When you open a PR, paste the output of av shadow on your box so we can see what surfaces in your environment.


<span style="color:#00d992">▍</span> License

MIT. See LICENSE.

<br/>

<sub> <span style="color:#3d3a39">─────────────────────────────────────────────</span> <br/> <span style="color:#8b949e">built by</span> <span style="color:#f2f2f2">anirudh prashant</span> <span style="color:#8b949e">·</span> <span style="color:#00d992">agent-vitals v0.2.1</span> <span style="color:#8b949e">·</span> <span style="color:#b8b3b0">2026</span> </sub>

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured