universal-agent-recovery
This MCP server lets an agent register and manage recoverable coding tasks while a watchdog monitors and resumes them after interruptions.
Register tasks with task/session/process metadata and working directory.
Send progress heartbeats and save verified checkpoints with structured details.
Report errors/interruptions so recovery can be scheduled.
Query full task status, recovery attempts, checkpoint, and recent events.
Mark tasks completed only with a verification note.
Cancel tasks and stop further recovery attempts.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@universal-agent-recoveryregister this task so it auto-resumes if my session crashes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Universal Agent Recovery
Your coding agent crashed at 80% of the task. Who restarts it? This package does.
universal-agent-recovery is an MCP server + independent watchdog (npm package: s-universal-agent-recovery) that automatically detects when a coding agent task is interrupted (crash, timeout, lost session) and resumes it — from the same session when possible, or from a saved checkpoint otherwise.
Agent doing work ── crash ──> watchdog detects ──> resumes from checkpoint
│
┌───────────────────┘
▼
recovered → agent continues the taskComponent | CLI | Role |
MCP Server |
| Tools for the agent to register tasks, report progress, save checkpoints |
Watchdog |
| Independent process that detects interruptions and launches recovery |
State dump |
| Read-only JSON snapshot of tasks/leases/retries for debugging |
Works with OpenCode, Claude Code, and any agent via a generic CLI template adapter.
No native dependencies — uses Node's built-in SQLite (
node >= 22.5, 22.x only).The watchdog never depends on the agent being alive to perform recovery.
Node version: this package targets Node.js 22.x (
>=22.5.0 <23) because storage uses the built-innode:sqlitemodule, whose behavior can change between major lines. Node 23+/24+ may work but is untested; the(node:xxx) ExperimentalWarning: SQLite is an experimental featuremessage at startup is expected and harmless.
Quick start
npm install -g s-universal-agent-recovery1. Register the MCP server in your MCP client
OpenCode — add to ~/.config/opencode/opencode.json (or project opencode.json):
{
"mcp": {
"universal-agent-recovery": {
"type": "local",
"command": ["uar-mcp"],
"enabled": true
}
}
}Claude Code:
claude mcp add universal-agent-recovery -- uar-mcpAny other MCP client — command uar-mcp, transport stdio.
2. Start the watchdog in the background
uar-watchdogThat's it. From now on, whenever the agent calls register_task at the start of significant work, the task is monitored and auto-resumed on interruption.
3. Optional: try the demo
npm run demo # scripted end-to-end recovery with a mock agentRelated MCP server: Aletheia Token Guard (ATG)
How it works
The agent (via MCP tools) records what it is doing; the watchdog watches the record and recovers when the record goes stale.
┌─────────────────────────┐
│ SQLite state store │
│ (shared, WAL mode) │
└──────────┬──────────────┘
register/heartbeat │ poll + claim
┌────────────────────────┴──────────────────────┐
│ │
MCP Server (uar-mcp) Watchdog (uar-watchdog)
- register_task - detects stale heartbeat / dead pid
- report_progress / save_checkpoint - verifies the session still exists
- report_interruption - resumes: same session → checkpoint fallback
- mark_completed / cancel_task - retry budget + backoff + single-owner lockRecovery lifecycle
Register — agent calls
register_task(session id, adapter, working directory).Progress — agent calls
report_progress/save_checkpointas work proceeds.Detect — watchdog sees a stale heartbeat (and/or dead pid) → task is
INTERRUPTED.Verify — watchdog checks the session still exists (adapters that support it).
Resume — watchdog launches the agent with the same session id + a self-contained recovery instruction.
Fallback — resume failed? A fresh session is started from the persisted checkpoint.
Verify — recovery succeeded only when the agent resumes making progress or reports completion.
Repeat — until
COMPLETED,BLOCKED(retry budget exhausted), orCANCELLED.
Interruption scenarios → when recovery triggers
Scenario | Detected by | Resumed? |
Network loss → agent CLI crashes → process dies |
| ✅ ≤ ~30s (next poll) |
Network loss → CLI hangs, process alive, no pid known | stale heartbeat ( | ✅ after 10 min (default) |
Agent retries internally, then exits | dead pid | ✅ ≤ ~30s |
Agent retries internally, then goes silent with process still alive | heartbeat stale but pid alive | ❌ classified |
Agent reports | tool call | ✅ immediately (next poll) |
Design note: a live process with a stale heartbeat is deliberately classified as
IDLE, notINTERRUPTED. From the outside, "running a 15-minute test suite", "stuck waiting for the network", and "waiting for the user to type the next instruction" look identical — so the watchdog only resumes when it can prove the agent is gone (dead pid), or when the agent itself reports the interruption. The agent's own contract: try to recover on your own first, and callreport_interruptionwhen you give up — the watchdog then takes over with its own retry budget and backoff.
Task state machine
REGISTERED → RUNNING → INTERRUPTED
↓ ↓ ↓
└──────────┴──→ RECOVERING → RUNNING
↓
COMPLETED
or BLOCKED (exhausted)
or CANCELLED (human)MCP tools (7)
Tool | Description |
| Register a task for monitoring |
| Heartbeat / progress report |
| Persist verified progress (files touched, steps done, next steps) |
| Report an error or crash |
| Query full task state + event log |
| Mark complete — requires evidence of work |
| Cancel and stop recovery |
Configuration
All settings are environment variables (copy .env.example → .env if you use a dotenv loader; both uar-mcp and uar-watchdog must see the same values):
Variable | Default | Description |
|
| SQLite database shared by MCP + watchdog (must match between the two processes) |
| (empty = unrestricted) | Comma-separated root dirs; tasks outside are rejected |
|
| Global recovery killswitch |
|
| Heartbeat considered stale after 10 minutes |
|
| Max simultaneous recoveries |
|
| Hard runtime cap per recovery launch |
|
| Retry budget per task |
|
| Initial backoff between retries |
|
| Backoff cap |
|
| Recovery ownership lease |
|
| Watchdog polling interval |
|
|
|
| (none) | Optional JSON log file |
|
| OpenCode binary path |
|
| Claude Code binary path |
| (empty) | Resume template, e.g. |
| (empty) | New-session template, e.g. |
Running the watchdog as a service
macOS (launchd): copy
launchd/com.github.universal-agent-recovery.plistto~/Library/LaunchAgents/, adjust the paths, thenlaunchctl load ....Linux (systemd): create a user unit running
uar-watchdogwith the desiredRECOVERY_*environment.Windows: use a scheduled task (
schtasks /create ... /sc onstart) or a service wrapper.
Windows notes
npm shims (
opencode.cmd,claude.cmd) cannot be spawned directly by Node. Point the env at the real.exe:
setx OPENCODE_BIN "C:\path\to\nodejs\node_modules\@opencode\cli\bin\opencode.exe"Process-tree cancellation uses
taskkill /T /Fautomatically;tasklistis the process-health fallback.
Supported agents
Agent | Resume flag | Session inspection | Completion detection | Status |
OpenCode |
|
| No (verified via MCP) | ✅ Tier 1 validated |
Claude Code |
| No documented CLI |
| ✅ Tier 1 validated |
Generic CLI | Template-driven | No | No | ✅ Available |
Security
Working directories are validated against
RECOVERY_ALLOWED_DIRS.Agent processes are launched with argument arrays only (
shell: false) — no command injection from task metadata.Credential-like environment variables (
*TOKEN*,*SECRET*,*PASSWORD*,*CREDENTIAL*,*API_KEY*, ...) are stripped from agent processes; provider keys agent CLIs need (e.g.ANTHROPIC_API_KEY) are preserved via an explicit allowlist.API keys / tokens are never logged (structured logger redacts secrets).
RECOVERY_ENABLED=falseis the global killswitch.
Troubleshooting
Symptom | Likely cause | Fix |
Task not recovered |
| Set to |
"Recovery disabled" in logs | Global switch off |
|
Task stuck in RECOVERING | Watchdog died mid-recovery |
|
Agent resumes but task stays INTERRUPTED | Watchdog not running | Start |
Slow agents restarted |
| Increase it (default 10 min) |
| Binary not resolvable | Set |
"SQLite database is locked"
Another uar-mcp / uar-watchdog process holds a long write transaction, or the database
lives on a network filesystem (NFS/SMB — WAL mode requires local disk). Steps:
Check for stale processes:
ps aux | grep uar-and kill leftovers.Inspect the current state read-only:
uar-state(shows tasks, lease holders, retry counts).Confirm both processes point at the same
RECOVERY_DB_PATH.Move
RECOVERY_DB_PATHto a local disk if it is on a network mount.
"Task 'X' already exists (state: ...)"
Task IDs are unique forever, including terminal states (COMPLETED/CANCELLED/BLOCKED).
Use a new ID for a fresh run, or call cancel_task/mark_completed on the existing one.
"Task is BLOCKED; interruption not accepted"
The task exhausted its retry budget (maxAttempts, default 5) or failed with a
non-recoverable error class. Inspect lastError / recent events:
uar-state --task <taskId> # includes the last 50 eventsThen either fix the underlying problem and register a new task, or cancel it. There is currently no "unblock" tool — re-registering is intentional friction.
"outside the configured allowed directories"
RECOVERY_ALLOWED_DIRS is set and the task's working directory is outside every root.
Add the project root to the comma-separated list (both uar-mcp and uar-watchdog
must see the same value).
Config warnings at startup
Invalid numeric env values (e.g. RECOVERY_MAX_ATTEMPTS=-3) and unknown log levels are
replaced by defaults with a configuration warning log line at startup — check the logs
if behavior doesn't match what you configured.
Debugging snapshot
uar-state # pretty JSON of everything
uar-state --db ./data/recovery.db # explicit database path
uar-state --task my-task # single task + last 50 events
uar-state --compact | jq '.tasksByState'The dump is read-only and safe to run while the MCP server and watchdog are live.
Known limitations
Claude Code session inspection: no documented non-interactive command to list sessions; an invalid session id falls back to a new session.
Session inspection failure vs. missing session: a CLI failure during inspection makes the watchdog defer (never drop session context on a hiccup).
Completion detection (OpenCode): no structured output; completion is verified via MCP
mark_completed, not process exit.Generic CLI adapter: disabled unless templates are explicitly configured.
Documentation
Document | Content |
System architecture and design principles | |
MCP tool contracts and schemas | |
Use cases and scenarios | |
Recovery workflow details | |
Source code structure guide |
Development
npm install
npm run lint # ESLint
npm run typecheck # tsc --noEmit
npm test # unit + integration tests
npm run test:coverage # same tests + V8 coverage report
npm run build # compile to dist/Current coverage (V8): ~76% statements / ~71% branches overall; storage core
(src/storage) at ~90% statements. The thinner areas are the adapter binaries'
process plumbing (covered mainly by integration tests) and the uar-state CLI
(covered at the dumpState function level).
Integration tests against a real OpenCode binary run automatically when the binary exists; the live end-to-end test (needs provider credentials) is opt-in:
UAR_INTEGRATION=1 npm testProject structure
universal-agent-recovery/
├── bin/ # CLI shims: uar-mcp, uar-watchdog, uar-state
├── src/
│ ├── core/ # Types, state machine, error classifier, logger
│ ├── storage/ # SQLite, task/event/attempt repositories, leader lock
│ ├── adapters/ # OpenCode, Claude Code, Generic CLI, Mock (testing)
│ ├── mcp/ # MCP server (7 tools, stdio transport) + entry point
│ ├── watchdog/ # Supervisor, monitor, recovery policy, instructions
│ ├── cli/ # uar-state: read-only JSON state dump for debugging
│ └── examples/ # Demo script
├── docs/ # Design documents
├── tests/ # Unit + integration tests
└── launchd/ # macOS launchd plistLicense
Available Tools
7 toolscancel_taskCancel TaskC
Cancel a task and stop any further recovery attempts for it.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | ||
| taskId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description bears full behavioral burden. It usefully discloses that cancellation stops further recovery attempts, but omits whether cancellation is reversible, what task state results, whether it applies to running vs interrupted tasks, and what permissions or error conditions apply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler. Every phrase contributes either the core action or a behavioral consequence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no annotations, no output schema, and 0% parameter documentation, the description is too thin. It should clarify the resulting task state, reversibility, and the role of the reason parameter to be complete enough for reliable invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description says nothing about either parameter. It does not explain the required taskId or clarify the optional reason parameter, including whether the reason is recorded or affects behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Cancel a task') and adds a distinguishing behavioral detail ('stop any further recovery attempts'), which separates it from siblings like mark_completed and report_interruption. However, it does not explicitly name or contrast those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no indication of when to prefer cancel_task over mark_completed, report_interruption, or other lifecycle siblings, nor does it state prerequisites or exclusions. Usage is only implied by the verb 'Cancel'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_task_statusGet Task StatusB
Get full task status: state, progress, checkpoint, recovery attempts, recent events.
| Name | Required | Description | Default |
|---|---|---|---|
| taskId | Yes | ||
| includeEvents | No | Include recent event log (default true) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden. It usefully discloses the returned content, including recovery attempts and recent events, and the includeEvents parameter implies an event log. However, it never states that the call is read-only with no side effects, nor anything about cost, pagination, or permissions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with a colon-delimited field list; zero filler and every phrase conveys information. Ideal density for a simple retrieval tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description's enumeration of returned fields is valuable, and no annotations mean behavior must be inferred from 'Get'. But the required taskId and the includeEvents toggle are left unexplained, so an agent cannot fully understand the call contract from the text alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: includeEvents has a description and a default, but taskId is undocumented in both schema and description. The description mentions neither parameter, so it adds no meaning over the structured fields and fails to compensate for the undocumented required taskId.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Get') and resource ('task status'), then enumerates the fields returned (state, progress, checkpoint, recovery attempts, recent events). This clearly distinguishes it from the sibling tools, which are all mutation/reporting operations (register_task, report_progress, save_checkpoint, etc.), though it never names them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the agent can infer this is the read-only status lookup among write-oriented siblings, but the description never says when to call it, whether polling is expected, or what alternatives exist. Minimum viable guidance, no exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mark_completedMark CompletedA
Mark a task completed after verifying the final state. Requires a verification note; completion is never inferred from process exit.
| Name | Required | Description | Default |
|---|---|---|---|
| taskId | Yes | ||
| verification | Yes | How completion was verified (tests run, outputs checked, etc.) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses a useful behavioral rule (completion requires evidence, never inferred from exit codes) but says nothing about irreversibility, resulting task state, permissions, or whether the task can be reopened.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, both front-loaded with the action and the constraint; nothing is wasted or repetitive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A two-parameter mutation tool with no output schema is adequately covered: the agent knows what it needs and the key gating rule. Missing only the post-completion effects (state transition, reversibility).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: the 'verification' parameter is documented in the schema, while 'taskId' is undocumented anywhere. The description reinforces that verification is mandatory but adds no format or identifier guidance beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('mark a task completed') and adds a precondition that no other sibling performs. It is not confused with report_progress or cancel_task, though it never names those siblings explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'After verifying the final state' states the trigger condition, and 'completion is never inferred from process exit' rules out a tempting wrong usage. It still lacks explicit routing against alternatives such as cancel_task when work is abandoned rather than finished.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
register_taskRegister TaskA
Register a coding-agent task for monitoring and automatic recovery. The agent (or its launcher) calls this when starting a task so the watchdog can resume it after interruptions.
| Name | Required | Description | Default |
|---|---|---|---|
| taskId | Yes | Unique task identifier | |
| adapterId | Yes | Adapter id, e.g. 'opencode', 'claude-code' | |
| agentType | No | Agent type label (defaults to adapterId) | |
| sessionId | No | Existing agent session id to resume, when known | |
| processPid | No | Agent process id, when launched by the caller | |
| description | Yes | Original task description used as recovery context | |
| maxAttempts | No | Recovery attempt budget (default from configuration) | |
| workingDirectory | Yes | Absolute working directory the agent runs in |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses that registration enrolls the task in watchdog monitoring and recovery, but omits key traits: whether registering an existing taskId fails or overwrites, idempotency, and whether registration implies any process ownership. These gaps matter for a stateful registration call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero padding, with the action and its monitoring purpose front-loaded before the call-site guidance. Nothing is restated redundantly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter, no-annotation, no-output-schema registration tool, the description covers purpose and trigger but leaves out duplicate-registration behavior and what a caller gets back (task id, status, error). Adequate but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and all eight parameters carry inline descriptions, so the schema already does the work. The description adds no additional meaning about required fields, defaults, or how sessionId/processPid affect recovery behavior, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Register') and resource ('a coding-agent task') and adds the purpose ('for monitoring and automatic recovery'), which clearly separates it from siblings like report_progress or save_checkpoint. It stops short of explicitly naming an alternative tool, but the intent is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the trigger ('The agent (or its launcher) calls this when starting a task') and the rationale (so the watchdog can resume it after interruptions), which is a clear use context. It does not cover when-not-to-use, re-registration semantics, or whether a launcher should call it instead of the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
report_interruptionReport InterruptionB
Report an error or interruption for a task. The watchdog verifies and schedules recovery.
| Name | Required | Description | Default |
|---|---|---|---|
| error | Yes | Error or interruption description | |
| taskId | Yes | ||
| exitCode | No | Agent process exit code, when known |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses that a watchdog verifies the report and schedules recovery, but it omits key mutation behavior such as idempotency, permissions, task status changes, and what the caller should expect after submission.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the action and followed by one behavioral detail. There is no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a reporting/mutation tool with no annotations and no output schema, the description is too thin. It does not explain what 'verifies and schedules recovery' means operationally, whether the task is retried or cancelled, or what response the caller receives.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is moderate at 67%: error and exitCode are documented in the schema, while taskId is self-explanatory. The description loosely maps to the 'error' parameter but adds no meaning beyond the schema and says nothing about exitCode or taskId usage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Report') and resource ('error or interruption for a task'), making the tool's core purpose clear. It does not explicitly distinguish itself from siblings such as report_progress, cancel_task, or mark_completed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the purpose: report when a task has an error or interruption. However, the description gives no explicit when-to-use/when-not guidance, no prerequisites, and does not name alternatives such as report_progress or cancel_task.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
report_progressReport ProgressB
Report task progress (acts as a heartbeat). Keeps the watchdog from considering the task stale.
| Name | Required | Description | Default |
|---|---|---|---|
| taskId | Yes | ||
| progress | Yes | What has been done so far |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden; it does disclose the important non-obvious behavior that the call resets a stale-task watchdog. It says nothing about how often to call, whether progress overwrites or appends, or what happens if the task is already completed or cancelled.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact clauses with the heartbeat semantics front-loaded right after the purpose. No filler; the parenthetical is slightly awkward but earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-param tool with no output schema, purpose plus heartbeat semantics is the essential core. Missing cadence guidance and the undocumented taskId leave real gaps for what is meant to be a periodic keepalive call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 50%: progress is documented in the schema while taskId is undocumented in both places, and the description adds no meaning for either parameter. With a coverage gap, the description should compensate and does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (report task progress) and adds the key framing that it acts as a heartbeat. It is not explicitly contrasted with siblings like save_checkpoint or get_task_status, but the purpose is unambiguous on its own.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The watchdog sentence implies when to call (periodically, to avoid being marked stale), but there is no explicit when-not, no suggested cadence, and no routing away from save_checkpoint or report_interruption, which an agent could easily confuse with this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_checkpointSave CheckpointA
Persist verified progress so a new session can continue the task after a restart. Include concrete details: steps completed, files touched, next steps. Do not paste raw last output.
| Name | Required | Description | Default |
|---|---|---|---|
| taskId | Yes | ||
| details | No | Structured details: files touched, steps completed, next steps | |
| summary | Yes | Verified progress summary — what is actually done | |
| verified | No | Whether this checkpoint reflects verified state (default false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries the burden. It does disclose a real behavioral trait — the checkpoint survives a restart and is meant for a fresh session — which is genuinely useful context. It omits whether saves overwrite a prior checkpoint, whether 'verified' gates anything, and what the call returns, which are material for a persistence tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each earning its place: the purpose first, then content requirements, then a single prohibition. Nothing redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter write with no output schema, the description covers intent, content shape, and a key content exclusion, which is enough to call it correctly. The missing piece is how checkpoints relate to existing ones and to the progress-reporting siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 75%, so the schema already documents summary, details, and verified. The description adds the useful negative constraint ('do not paste raw last output') and enumerates the content expected inside details, but says nothing about taskId or the semantics of the verified flag beyond what the schema states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (persist verified progress) plus the reason it exists: letting a new session continue after a restart. It does not explicitly distinguish itself from the sibling report_progress, which is the nearest confusable tool, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The purpose sentence implies the trigger (end of a work segment, before a restart) but never states when to use this versus report_progress or report_interruption. The remaining sentences are content guidance ('include concrete details', 'do not paste raw last output') rather than usage routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v0.1.4- First observed
cancel_task - First observed
get_task_status - First observed
mark_completed - First observed
register_task - First observed
report_interruption - First observed
report_progress - First observed
save_checkpoint
TDQS
Scored across 7 tools
Each tool maps to a distinct lifecycle action, but report_progress (heartbeat) and save_checkpoint (durable state) are close enough that an agent could misuse one for the other; the descriptions do clarify the difference. register_task vs report_interruption vs mark_completed are clearly separated by intent.
All seven tools follow a strict snake_case verb_noun pattern (register_task, report_progress, save_checkpoint, report_interruption, get_task_status, mark_completed, cancel_task). No deviations or mixed conventions.
Seven tools cleanly covers the register→progress→checkpoint→recover→complete/cancel lifecycle without redundancy. Each tool earns its place in the watchdog workflow.
Core task lifecycle is fully covered, including recovery and terminal states. Minor gap: no way to enumerate or query multiple tasks (no list_tasks) and no explicit manual recovery trigger, though the watchdog handles recovery automatically.
Maintenance
Related MCP Connectors
Checkpoint and resume for AI agent runs, so crashed runs pick up where they left off.
Agent checkpoints. Resume after context resets and handoffs with retry-safe, versioned saves.
Task tracking built for coding agents. Work is leased, so two agents never take the same SubTask.
Watchdog for unattended AI agents: alerts, evidence checks and a verifiable proof per run.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides operational continuity for AI coding agents, preserving task state, decisions, checkpoints, and project context across sessions and model switches via MCP.1Apache 2.0
- AlicenseAqualityBmaintenanceEnables agents to monitor token/usage limits and persist work checkpoints, allowing them to pause, resume, and track progress across sessions.5MIT

genpark-long-horizonofficial
AlicenseNot gradedqualityBmaintenanceEnables long-horizon autonomous task checkpointing and resumption through cryptographic event-sourced state persistence, idempotency key deduplication, timeout heartbeats, human-in-the-loop pause/resume tokens, and fail-safe recovery.7MIT- AlicenseNot gradedqualityBmaintenanceEnables agents to persist and resume long-horizon tasks using cryptographic event-sourced checkpoints, idempotency deduplication, scheduled heartbeats, pause/resume tokens, and fail-safe recovery.7MIT