dhp
DHP — Durable Handoff Protocol
Agent work that survives worker death. When a worker is kill -9'd, OOM-killed, or its spot instance is reclaimed mid-run, DHP hands the work to a standby that resumes from the last checkpoint — zero rework, zero lost results.
MCP standardized agent↔tool. A2A standardized agent↔agent. DHP is the missing layer: agent↔time — execution state that outlives any single worker.
pip install dhp-protocolOne-line install (pip + MCP registration + data dir):
curl -fsSL https://raw.githubusercontent.com/SIDDARTHAREDDY8/dhp/main/install.sh | bashDirect into your agent:
Tool | Command |
Claude Code |
|
Cursor | |
Windsurf / Zed | copy the JSON from MCP_SETUP.md |
Any MCP client |
|
Other ways to run: Docker (docker compose up -d for
supervisor + transport server) · from source (git clone + pip install -e ".[dev]")
Table of Contents
Related MCP server: L-Dopa
The Problem
You delegate a 20-minute task to an AI agent. At minute 14, the process is killed — OOM, spot reclaim, deploy, laptop lid. All 14 minutes of progress are gone. The agent restarts from zero, redoes everything, burns tokens twice.
Every agent framework today has the same hole: work is owned by the worker, not the handoff. When the worker dies, the work dies with it. Retries start from scratch. There is no primitive for "this unit of work exists independently of whoever is executing it right now."
DHP is that primitive.
What DHP Is
DHP (Durable Handoff Protocol) separates work ownership from worker identity:
Work is dispatched as a content-addressed handoff — a durable record of intent (task, inputs, output schema, budget).
Workers claim handoffs, hold time-bounded leases, and checkpoint progress as they go.
A supervisor watches leases. A silent worker is declared dead in ~6 seconds; its handoff is orphaned and a monotonic fence token is bumped — the dead worker's late writes are rejected, so two workers can never both believe they own the work.
Any standby recovers the orphaned handoff from the last checkpoint. Zero rework.
Checkpoints ship over TCP as they're made, so if the entire host dies, the peer already has everything.
It composes with the existing stack rather than replacing it:
Layer | Protocol | Concern |
Tools | MCP | agent↔tool calls |
Agents | A2A | agent↔agent messaging |
Durability | DHP | work survives worker death |
Five Guarantees
No lost results — every completed handoff's result is durable and retrievable.
No crossed inputs — handoff IDs are content-addressed over intent; inputs cannot be swapped mid-flight.
No untyped results — completions are validated against a JSON Schema before acceptance.
No silent budget overrun — hard caps on steps, spend, wall-clock, and attempts. Exhausted work parks in a dead-letter queue: intact, visible, never silently dropped.
No runner lock-in — suspend → ship → resume on any host, any runner. The wire format is plain JSON-lines.
Quickstart
import dhp
store = dhp.Store("./demo-dhp")
# 1. Dispatch durable work
hid = dhp.dispatch(
store,
task_kind="demo.count",
inputs={"target": 50},
output_schema={"type": "object",
"properties": {"counted": {"type": "integer"}},
"required": ["counted"]},
)
# 2. Work it — the context manager heartbeats automatically in the background
with dhp.claim(store, hid, worker_id="w1") as ctx:
state = dhp.last_checkpoint(store, hid) or {"n": 0}
while state["n"] < 50:
state["n"] += 1
ctx.checkpoint(state) # every step is a resume point
ctx.complete({"counted": state["n"]})Now kill the worker mid-run and watch recovery:
# terminal 1: supervisor watches leases, orphans the silent in ~7s
dhp-supervisor ./demo-dhp sup1 3600# terminal 2: any standby picks up exactly where the dead worker stopped
with dhp.recover(store, hid, worker_id="w2") as ctx:
state = dhp.last_checkpoint(store, hid) # {"n": 20} — resumes here
while state["n"] < 50:
state["n"] += 1
ctx.checkpoint(state)
ctx.complete({"counted": state["n"]})Steps already done are never recomputed. See QUICKSTART.md for the full 5-minute walkthrough.
How It Works
Leases and fencing
A worker holds a handoff under a time-bounded lease (default: 2s heartbeat interval, 3 misses ≈ 6s TTL). Heartbeats run in a background thread — slow LLM reasoning between checkpoints never false-orphans a healthy worker.
When the supervisor sees an expired lease, it orphans the handoff: ownership moves to a tombstone holder and a monotonic fence token increments. Every subsequent write carries the worker's fence token; a stale worker's late checkpoint is rejected with LeaseLost. This is the same fencing pattern used by Chubby, ZooKeeper, and etcd — exactly-once ownership without distributed consensus.
Ten simultaneous recoverers → exactly one wins (atomic compare-and-set).
Content-addressed envelopes
The handoff ID is a SHA-256 over the intent — task kind, inputs, output schema, budget — not the mutable state. A recovered handoff is verifiably the same work it was dispatched as. Tampered envelopes and checkpoints are rejected at ingest.
Append-only transport
Checkpoints are appended to a JSON-lines log — one envelope header, then one line per checkpoint. Two transports:
File (
dhp.transport): shared directory or volume.TCP (
dhp.net):TransportServeron the peer,NetShipperin the worker. Checkpoints arrive as they're made; the server verifies envelope identity and per-checkpoint hashes. The client also buffers locally, so a network partition loses nothing — it replays on reconnect.
Rework bound after any failure: ≤ 1 checkpoint.
Pluggable storage
All durability goes through the StoreBackend interface. The default is SQLite/WAL — zero dependencies, crash-safe, single-writer. Postgres (advisory locks + FOR UPDATE SKIP LOCKED give identical CAS semantics) is a clean extension, not a rewrite.
The Kill Demo
The demo that proves it — not a simulation:
python3 demo/run_mad_demo.pyWhat happens:
Host A: worker fetches 60 real Wikipedia pages, checkpointing + shipping each page over TCP to Host B as it's fetched.
At page 20:
kill -9on the worker. Real SIGKILL, mid-urlopen.Supervisor orphans the handoff in 6.5s.
Host B ingests the 20 shipped checkpoints from its TCP log.
Standby on Host B resumes at page 20 — pages 1–20 are never refetched.
60/60 complete. Real CSV dataset on disk.
=== MAD DEMO: 60 real pages, kill -9 at 20 ===
worker-A started (pid 4414)
*** kill -9 worker-A at 20 pages ***
supervisor orphaned after 6.5s
host B ingested: 20 checkpoints, 0 skipped
host B resumes from page 20 (worker-A died at 20)
worker-B started (pid 4444)
=== DONE: 60/60 pages, 60 fetched OK, zero refetched ===
MAD DEMO: GREENA network chaos harness (demo/net_chaos.py) SIGKILLs workers mid-ship across rounds: 24/24 checkpoints land on the peer, zero rework.
Architecture
flowchart TB
subgraph Interfaces
MCP[dhp-mcp<br/>18 MCP tools]
SDK[Python SDK<br/>dhp.dispatch/claim/recover]
A2A[A2A bridge<br/>stable Task ID]
end
subgraph Core
R[Runner<br/>lifecycle: dispatch → claim →<br/>checkpoint → complete]
S[Supervisor<br/>lease watchdog → orphan<br/>leader election]
end
subgraph Durability
SB[StoreBackend<br/>interface]
SQ[(SQLite/WAL<br/>default)]
PG[(Postgres<br/>extension)]
end
subgraph Portability
NET[TCP transport<br/>live checkpoint shipping]
LOG[JSON-lines log<br/>verified ingest]
end
MCP --> R
SDK --> R
A2A --> R
R --> SB
S --> SB
SB --> SQ
SB --> PG
R --> NET
NET --> LOGModule map (dhp/):
Module | Responsibility |
| Content-addressed handoff envelopes, identity verification |
| SQLite/WAL |
|
|
| Lifecycle: dispatch/claim/recover/checkpoint/complete; |
| Lease watchdog, orphaning, DLQ, leader election, metrics |
| Append-only JSON-lines log: ship/ingest with hash verification |
| TCP transport: |
| MCP server (18 tools + health) |
| A2A durability substrate |
| Tuning, typed errors, input validation, structured logging |
API Reference
Python SDK
import dhp
store = dhp.Store("./data") # or any StoreBackend
hid = dhp.dispatch(store, task_kind="...", # create durable work
inputs={...},
output_schema={...},
budget={"max_attempts": 5}) # optional caps
with dhp.claim(store, hid, worker_id="w1") as ctx: # claim + auto-heartbeat
state = dhp.last_checkpoint(store, hid) or {} # resume point
ctx.checkpoint(state) # per chunk
ctx.heartbeat() # manual (optional w/ ctx mgr)
ctx.complete(result) # schema-validated
ctx.release("reason") # cooperative handoff
with dhp.recover(store, hid, worker_id="w2") as ctx:# recover orphaned work
...
dhp.status(store, hid) # status/owner/checkpoints
dhp.approve(store, approval_id) # approve a gated action
dhp.deny(store, approval_id) # deny it (fail-closed)Reliability primitives (v1.2)
Effect log — no duplicate side effects. Record each side effect by step ID; the first write wins, and the standby checks before re-firing:
with dhp.claim(store, hid, worker_id="w1") as ctx:
if not ctx.effect_done("charge-card"):
tx = charge_card(...) # the side effect
ctx.record_effect("charge-card", {"tx": tx})If the worker dies between the charge and the next checkpoint, the standby sees effect_done("charge-card") and skips it. No double-charge.
Hard budget enforcement — no silent overrun. Declare caps at dispatch; the supervisor kills the handoff closed when they're hit:
hid = dhp.dispatch(store, ..., budget={"max_spend_usd": 5.0,
"max_steps": 1000,
"max_wallclock_s": 3600})
with dhp.claim(store, hid, worker_id="w1") as ctx:
ctx.note_spend(0.42) # real LLM API cost; supervisor fails closed on breachStall detection — catch livelocks, not just death. A worker can heartbeat forever while stuck. Report an activity digest; the supervisor orphans it as stalled when the digest repeats with no new checkpoint:
ctx.note_activity(sha256(tool_name + args)) # per tool callApproval gates — mechanism, not prompt-as-policy. Destructive/financial actions need an external approval record. Fail-closed on deny or timeout:
try:
ctx.request_approval("destructive", {"cmd": "drop table users"})
except ApprovalRequired as e:
approval_id = str(e).split(": ")[-1]
# human/policy engine: dhp.approve(store, approval_id)
ctx.await_approval(approval_id) # raises ApprovalDenied on deny/timeoutFailure-type-aware recovery (v1.3)
Not all failures deserve a retry. The supervisor classifies at orphan time:
Lease expired (heartbeat timeout) → transient/infra → normal retry.
Stalled (livelock) → bad plan → after
max_stall_retries(default 2), DLQ instead of another blind retry. A transient failure resets the stall counter.Schema validation failure at
complete()→ DLQ with the typed error, not stuck "running".
hid = dhp.dispatch(store, ..., max_stall_retries=1)Capability attenuation (v1.3)
Declare what the handoff may touch; everything else is denied fail-closed, and every check is audited:
hid = dhp.dispatch(store, ...,
capabilities={"network": ["api.stripe.com"],
"filesystem": ["/tmp/work"]})
with dhp.claim(store, hid, worker_id="w1") as ctx:
ctx.require_capability("network", "api.stripe.com") # ok
ctx.require_capability("network", "evil.example.com") # CapabilityDeniedCross-host shipping
from dhp import TransportServer, NetShipper
# peer host:
TransportServer("./peer-logs", port=8471).serve_forever()
# worker host:
shipper = NetShipper("peer.example.com", 8471,
local_logpath="./ship-w1.log") # partition buffer
shipper.ship_envelope(hid, envelope)
shipper.ship_checkpoint(hid, seq, state) # verified server-sideCLI
Command | Purpose |
| Lease watchdog (orphans the silent) |
| MCP server (stdio) |
| 10 protocol assertions |
| Randomized SIGKILL fault injection |
MCP tools
dhp_dispatch · dhp_claim · dhp_checkpoint · dhp_heartbeat ·
dhp_complete · dhp_recover · dhp_status · dhp_last_checkpoint ·
dhp_health · dhp_record_effect · dhp_effect_done · dhp_note_spend ·
dhp_note_activity · dhp_request_approval · dhp_approval_status ·
dhp_approve · dhp_deny · dhp_require_capability
Measured Performance
Not claims — chaos-tested numbers:
Event | Measured |
kill → orphan → standby resumes | ~7s |
Double kill (worker + supervisor leader) → recovery | 6.6s |
Host destroyed → peer ingests TCP log → resumes | ~6s |
Rework after any kill | 0 checkpoints |
20-agent MCP soak, 75% worker death rate | 20/20 completed |
Randomized SIGKILL chaos (14 worker + 5 supervisor kills) | all invariants held |
Verification: 59 pytest tests (lifecycle, concurrent CAS races, fuzzing, kill -9 integrity, network transport, v1.2/v1.3) · dhp-conform 10/10 · network chaos green.
Comparison
DHP | Temporal | LangGraph | CrewAI / AutoGen | |
Worker-death detection | ✅ leases + supervisor (~7s) | ✅ (~12s+) | ❌ | ❌ |
Resume from checkpoint, zero rework | ✅ | ✅ | partial (manual) | ❌ |
Cross-host, no shared DB | ✅ (TCP log shipping) | ❌ (needs cluster) | ❌ | ❌ |
Fencing (stale worker rejection) | ✅ monotonic tokens | ✅ | ❌ | ❌ |
Content-addressed work identity | ✅ | ❌ | ❌ | ❌ |
MCP-native | ✅ | ❌ | ❌ | ❌ |
A2A composition | ✅ | ❌ | ❌ | ❌ |
Zero-dependency single node | ✅ (SQLite) | ❌ (JVM cluster) | ✅ | ✅ |
DHP is not a workflow engine — it's the durability primitive workflow engines (and agent frameworks) can build on. If you run Temporal, keep it; DHP is for the agent layer Temporal doesn't reach.
MCP & A2A Integration
MCP — run dhp-mcp --root <dir> and point any MCP client at it. The skill at skills/dhp-durable-work/SKILL.md teaches agents the dispatch → checkpoint → recover pattern.
A2A — dhp.a2a_bridge makes DHP the durability substrate under A2A tasks: the A2A Task ID stays stable while DHP swaps dead workers underneath (closing A2A's documented "no consensus or global transaction semantics" gap). See BRIDGE_DEMO.md: Agent B killed mid-task → Agent C recovered → client saw WORKING → COMPLETED, the swap invisible.
Roadmap
Postgres
StoreBackendimplementationTLS for the TCP transport
OpenTelemetry tracing across handoff attempts
dhp dashboard— live handoff/lease/DLQ observabilityMulti-region supervisor quorum
Contributing
PRs welcome. The bar: every behavior change needs a chaos test or conformance assertion proving it under kill -9, not just in the happy path.
git clone https://github.com/SIDDARTHAREDDY8/dhp
cd dhp
pip install -e ".[dev]"
python -m pytest tests/ -q # 45 passed
dhp-conform # 10/10
python3 demo/run_mad_demo.py # the kill demoLicense
MIT — see LICENSE.
Available Tools
18 toolsdhp_approval_statusA
Check an approval's status: pending/approved/denied/expired. Only approved means the action may run.
| Name | Required | Description | Default |
|---|---|---|---|
| approval_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It usefully discloses the state machine (pending/approved/denied/expired) and the gating semantics of 'approved', but says nothing about whether this is a safe read, expiry timing, or whether polling is expected. Partial but meaningful coverage.
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, tightly worded sentence with the core action front-loaded and the decisive status semantics at the end. No filler.
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?
An output schema exists so return values need not be explained, and the description already previews the status set. For a one-parameter read tool this is nearly sufficient; only the approval_id's provenance is missing.
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 single required parameter 'approval_id' is undocumented in both schema and description. The description adds no meaning about the id's origin or format, so the coverage gap is not compensated.
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+resource ('Check an approval's status') and enumerates the four possible outcomes. This clearly separates it from sibling writers like dhp_request_approval, dhp_approve and dhp_deny without needing the schema.
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 clause 'Only approved means the action may run' gives important post-check decision guidance, but the description never states when to poll this vs. an alternative like dhp_status, nor any precondition (e.g. that an approval_id must first come from dhp_request_approval). Usage is implied rather than specified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_approveC
Approve a pending approval request (human / policy engine).
| Name | Required | Description | Default |
|---|---|---|---|
| approval_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral burden. It implies a state mutation but says nothing about who is authorized, whether approval is idempotent, what happens to the request afterward, or what error occurs if approval_id is not pending. The '(human / policy engine)' parenthetical hints at actor identity but is too terse to be actionable.
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 short sentence that front-loads the action and target, with zero padding. The trailing parenthetical is slightly cryptic and could be dropped or clarified.
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?
An output schema exists, so return values need not be explained, but this is a mutation tool with no annotations and no guidance on permissions, preconditions, or downstream effects. For a state-changing approval action, the description is too thin.
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%, so the description must compensate, and it does not explain approval_id format, provenance, or how to obtain one (likely from dhp_request_approval or dhp_approval_status). The parameter is largely self-evident from its name, which keeps this at a minimal 3.
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 (Approve) and resource (a pending approval request), which distinguishes it from dhp_deny and dhp_request_approval by implication. However it never explicitly names those siblings, so an agent must infer the boundary from the sibling list alone.
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?
There is no explicit when-to-use statement, no precondition that the approval must currently be pending, and no pointer to alternatives such as dhp_deny for rejection or dhp_approval_status for checking state. Usage is only implied by the word 'pending'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_checkpointC
Checkpoint worker progress. Call per chunk of work.
| Name | Required | Description | Default |
|---|---|---|---|
| state | Yes | ||
| worker_id | Yes | ||
| handoff_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It does not disclose what checkpointing actually does (persist? overwrite previous state? idempotent?), whether it has side effects, or any auth/rate constraints — critical gaps for a state-writing tool with zero annotation coverage.
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, front-loaded sentences with no filler or redundancy. It is efficiently structured, though its extreme brevity borders on under-specification rather than being a model of clarity.
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?
While an output schema exists (so return format need not be explained), the description is inadequate for a tool with three required parameters at 0% schema coverage, an opaque nested state object, and no annotations. An agent lacks enough context to call it correctly.
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% for three required parameters, and the description adds no clarification. The nested, open-ended "state" object (additionalProperties: true) is especially opaque — nothing explains what should go in it, only weakly implied by "worker progress".
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?
"Checkpoint worker progress" gives a specific verb (checkpoint) and resource (worker progress), so the intent of persisting a worker's state is inferable. However, it offers no differentiation from close siblings like dhp_heartbeat, dhp_complete, or dhp_last_checkpoint, leaving the agent to guess how this differs from merely signaling liveness or completion.
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?
"Call per chunk of work" provides a cadence/frequency hint that implies when to invoke it. Beyond that there is no explicit when-not guidance, no mention of alternatives (heartbeat vs checkpoint vs complete), and no prerequisites, so usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_claimB
Claim a handoff for a worker. Returns the lease and the last checkpointed state (resume point).
| Name | Required | Description | Default |
|---|---|---|---|
| worker_id | Yes | ||
| handoff_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 claiming yields a lease (exclusive ownership) and the last checkpointed state, but says nothing about contention when a handoff is already claimed, lease expiry, or required 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?
Two short sentences with zero filler; the action is front-loaded and the return value follows immediately. Nothing could be trimmed without losing content.
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?
An output schema exists, so the description is not obligated to detail return values (though it does, usefully). Against that, there are no annotations, no parameter documentation, and no failure or contention semantics for what is clearly a mutating lease-acquisition 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 description coverage is 0%, so both handoff_id and worker_id are undocumented in the schema, and the description does not compensate by explaining their formats, relationships, or constraints. The agent gets no help beyond the parameter names themselves.
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 (claim) and resource (handoff) plus the actor (worker), which is enough to distinguish it from dhp_dispatch or dhp_recover in intent. It stops short of explicitly contrasting itself with those siblings, so it is clear but not fully differentiated.
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?
There is no statement of when to claim versus dispatching, recovering, or checking status. The only implied guidance is that a claim precedes work, which the agent must infer from the sibling names and the resume-point mention.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_completeC
Complete the handoff with a schema-validated result.
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes | ||
| worker_id | Yes | ||
| handoff_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full behavioral burden. 'Complete the handoff' implies a terminal state transition, but the description never says whether it requires a claimed handoff, whether it is idempotent/reversible, or what happens on a non-validated result beyond the passing mention of 'schema-validated'.
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. It is efficiently sized, though the brevity reflects under-specification rather than economy.
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?
An output schema exists so return values need no explanation, but for a mutation-style handoff-completion tool with zero annotations, three undocumented required parameters, and a nested result object, the description is far too thin to call correctly.
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% across three required parameters (handoff_id, worker_id, result), including a nested free-form result object. The description adds no format, identity, or format-of-result guidance, so it fails to compensate for the coverage gap.
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 ('Complete the handoff'), making the basic purpose legible. However, it does nothing to differentiate this from completion-adjacent siblings such as dhp_effect_done or dhp_claim, so an agent cannot route confidently without opening schemas.
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?
There is no indication of when to call this versus alternatives like dhp_effect_done, dhp_checkpoint, or dhp_recover, nor any stated prerequisites such as first claiming a handoff. Usage is left entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_denyC
Deny a pending approval request (human / policy engine).
| Name | Required | Description | Default |
|---|---|---|---|
| approval_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It does not say whether a denial is final or reversible, who is permitted to deny (the parenthetical "human / policy engine" hints at the actor but is ambiguous), whether the requester is notified, or what happens if the request is no longer pending. For a state-changing operation with zero annotation coverage this is a real gap.
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?
Twelve words, one sentence, action front-loaded — nothing redundant. The parenthetical "(human / policy engine)" is too cryptic to immediately earn its place, which keeps this below a 5.
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?
An output schema exists, so return values need not be explained, but that is the only need covered. For a mutation tool with no annotations and an undocumented required identifier, the description should say something about authorization, the finality of the denial, and error conditions such as an already-decided request.
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%: approval_id has no description in the schema and the tool description never mentions it, its format, or where to obtain it (e.g., from dhp_request_approval or dhp_approval_status). The single required parameter is effectively undocumented everywhere.
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 (Deny) and resource (pending approval request), which is far more informative than a bare name. It does not, however, distinguish itself from the obvious siblings dhp_approve, dhp_request_approval, or dhp_approval_status, so the agent gets the what but not the contrast.
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?
"Pending" is an implicit precondition — the agent can infer this tool applies only to requests still awaiting decision. Beyond that there is no when-to-use guidance, no when-not-to-use case, and no mention of dhp_approve as the alternative action. Usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_dispatchC
Dispatch durable work. Returns a handoff_id. The work survives worker death from here on.
| Name | Required | Description | Default |
|---|---|---|---|
| inputs | Yes | ||
| task_kind | Yes | ||
| output_schema | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 does disclose two meaningful traits beyond the schema: the return of a handoff_id and the durability guarantee that work survives worker death. However, it omits idempotency, retry semantics, auth/permission needs, and error behavior, so substantial gaps remain.
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, front-loaded sentences with zero filler, leading with the action and immediately stating the return value and durability guarantee. Every sentence 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?
An output schema exists, so return values need not be re-explained beyond the handoff_id callout. But for a three-parameter dispatch tool with no annotations and no schema descriptions, the definition should say more about acceptable task_kind values, payload expectations, and failure behavior; as written it is under-specified.
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% across three required parameters (task_kind, inputs, output_schema), all nested or free-form. The description provides no meaning for any of them — not the valid values of task_kind, the shape of inputs, or the purpose of output_schema — so it fails to compensate for the coverage gap.
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 ('dispatch') and resource ('durable work'), which is clearly distinct from siblings like dhp_claim, dhp_checkpoint, dhp_complete, and dhp_recover. It does not, however, explicitly contrast itself with those siblings in the durable-work lifecycle, leaving the agent to infer where dispatch sits.
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?
There is no explicit when-to-use guidance, no prerequisites, and no mention of alternative tools such as dhp_claim or dhp_recover. The durable-work framing only implies usage; nothing tells the agent under what circumstances to dispatch versus claim or recover.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_effect_doneA
Check whether a side effect already happened. Returns the recorded result, or null. Call before re-executing a side effect after recovery.
| Name | Required | Description | Default |
|---|---|---|---|
| step_id | Yes | ||
| handoff_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does disclose the null-vs-recorded-result semantics and the intended idempotency-check role. It says nothing about permission requirements, whether the check mutates state, or any rate/locking behavior in a concurrent recovery workflow, leaving meaningful gaps.
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, purpose first, return behavior second, usage condition last. No filler and nothing 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?
The output schema covers the returned value so the description need not expand on return format, and it sensibly notes the null case. However, with no annotations and zero parameter documentation, the definition leaves the agent without enough to invoke it confidently on unfamiliar identifiers.
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 neither parameter is described in the schema, yet the description never mentions handoff_id or step_id. It conveys only that the check is scoped to a step, so the two required identifiers remain semantically unexplained.
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: checks whether a side effect already happened, and contrasts implicitly with the recording side of the pattern (dhp_record_effect). An agent can tell it is an idempotency lookup rather than a mutation, though no sibling is named 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?
Gives a concrete trigger condition: 'Call before re-executing a side effect after recovery.' That is actionable context with a clear lifecycle placement, but it does not state when not to use it or name a specific alternative tool such as dhp_record_effect.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_healthB
Server health: uptime, store stats.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 of behavioral disclosure. It implies a read-only probe but never states that it is non-destructive, requires no auth, or has side effects, and it says nothing about cost or rate limits.
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?
Extremely short and front-loaded: the resource and returned fields appear immediately. It is a sentence fragment rather than a sentence, but nothing is wasted.
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?
The tool is trivially simple (no params) and has an output schema, so return values need not be explained. Naming 'uptime' and 'store stats' covers the essentials, but with no annotations the description could still say more about when this differs from dhp_status.
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?
The tool takes zero parameters, so there is nothing to document and the baseline is 4. The description introduces no parameter-related confusion.
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 resource (server) and scope (health) and enumerates what it returns: uptime and store stats. An agent can tell it is a health read, but there is no differentiation from siblings like dhp_status or dhp_heartbeat, which may overlap.
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?
There is no when-to-use guidance, no mention of prerequisites, and no reference to which sibling (e.g. dhp_status, dhp_heartbeat) to prefer for related monitoring needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_heartbeatB
Heartbeat: prove the worker is alive. Call frequently; a silent worker is assumed dead.
| Name | Required | Description | Default |
|---|---|---|---|
| worker_id | Yes | ||
| handoff_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does disclose the key behavioral consequence: liveness is inferred and a silent worker is treated as dead. It omits whether the call needs to be from the same process/session holding handoff_id, and whether missed heartbeats trigger recovery.
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 front-loaded sentences, 'Heartbeat: prove the worker is alive' then the operational consequence. Slightly terse for a protocol call, but no filler.
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?
An output schema exists so return values need not be explained, and the liveness semantics are covered. However, required params at 0% coverage and no cadence/auth guidance leave meaningful gaps for a lifecycle-critical 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 0% and neither parameter is described in the schema or the description. The description never explains what handoff_id vs worker_id identify or which one scopes the liveness claim, leaving two required params undocumented.
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-effect ('prove the worker is alive') tied to the named resource dhp_heartbeat in a worker/handoff protocol. It is distinguishable from siblings like dhp_status or dhp_health, though it does not name them 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?
Says 'Call frequently' and gives the consequence of not calling (silent worker assumed dead), which implies the when. But it does not specify an interval, threshold, or relationship to other lifecycle calls like dhp_claim/dhp_complete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_last_checkpointC
Last checkpointed state, or null if none yet.
| Name | Required | Description | Default |
|---|---|---|---|
| handoff_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 one useful edge case (returns null when no checkpoint exists), but says nothing about read-only safety, whether it requires an active handoff_id, error behavior, or any access conditions.
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 short sentence with no filler, and the key return behavior is front-loaded. It is appropriately sized for a simple getter, though it is arguably too terse to be informative.
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?
An output schema exists, so return-shape explanation is not required, and the null fallback is covered. Still missing are any parameter meaning and usage context, which for a one-parameter lookup tool leaves a noticeable gap.
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 never mentions the single required parameter handoff_id. With one undocumented parameter, the description does nothing to explain what identifier the tool expects.
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 fragment 'Last checkpointed state' names the resource being retrieved, and 'or null if none yet' clarifies the return semantics, so the agent can tell it apart from the write-side dhp_checkpoint. However, it is a noun phrase with no verb and gives no hint of the read/fetch nature beyond implication, leaving some inference to the agent.
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?
There is no guidance on when to call this versus related siblings such as dhp_status, dhp_recover, or dhp_checkpoint. The agent must guess the workflow context in which the 'last checkpoint' is relevant.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_note_activityB
Report an activity digest (hash of tool name + args). The supervisor orphans the handoff as stalled if the digest repeats with no new checkpoint (livelock detection).
| Name | Required | Description | Default |
|---|---|---|---|
| digest | Yes | ||
| worker_id | Yes | ||
| handoff_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It does disclose genuinely useful system behavior — repeated digests trigger livelock detection and the handoff gets orphaned as stalled — but is silent on required permissions, idempotency, and what a call returns or changes.
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 tight sentences with no wasted words, and the core definition of the digest is front-loaded. It stays information-dense without padding.
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?
An output schema exists, so return values need not be described. The description covers the digest concept and the supervisor's reaction, but for a 3-required-param reporting tool with zero annotation coverage it omits the meaning of the handoff/worker identifiers and the intended call frequency.
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 0%, so the description must compensate for all three parameters. It explains only `digest` (hash of tool name + args); `handoff_id` and `worker_id` are left entirely undocumented in both schema and description, leaving two of three required inputs undefined.
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 clear verb+resource ("Report an activity digest") and helpfully defines the digest as a hash of tool name + args. It does not, however, distinguish itself from near-neighbours like dhp_heartbeat or dhp_checkpoint, which an agent could easily confuse with this liveness-reporting role.
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 via the consequence ("supervisor orphans the handoff as stalled if the digest repeats"), which tells the agent why reporting matters but not explicitly when to call this versus dhp_heartbeat or dhp_checkpoint. No call cadence or precondition is stated, so the agent must infer the moment to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_note_spendB
Record spend in USD against the handoff budget. The supervisor fails the handoff closed on budget breach.
| Name | Required | Description | Default |
|---|---|---|---|
| usd | Yes | ||
| worker_id | Yes | ||
| handoff_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden yet discloses genuinely useful behavior: the currency is USD and over-spend causes the supervisor to fail the handoff closed. It still omits whether calls accumulate, whether an over-budget call errors immediately, idempotency, and any permission requirements.
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 the consequence. No filler, though the breach sentence could be slightly tighter in phrasing.
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?
An output schema exists, so return values need not be explained. However, for a 3-required-param mutation tool with zero annotations and 0% schema coverage, the description should say more about accumulation semantics and failure behavior when the budget is breached.
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%, so the description must compensate and largely does not. It clarifies only that the amount is USD; handoff_id and worker_id are left to the parameter names alone, with no scope or format detail.
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: records spend in USD against a handoff's budget. It is clearly distinguishable from siblings like dhp_note_activity or dhp_record_effect by the budget-spend scope, though it never names or contrasts 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?
The description implies you call this when spend is incurred, but gives no when/when-not guidance, no prerequisites, and no routing against the many sibling note/record tools. The budget-breach sentence motivates the call but is a consequence, not usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_record_effectA
Record a side effect by step_id. First write wins; returns recorded=true if this call stored it, false if a previous attempt already did (do NOT re-fire the effect).
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes | ||
| step_id | Yes | ||
| worker_id | Yes | ||
| handoff_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does disclose the key trait: first-write-wins idempotency and the meaning of the recorded=true/false return. It omits auth/permission needs and where the effect is stored, so it is strong but not exhaustive.
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 purpose and immediately followed by the idempotency constraint and return contract. No filler.
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?
The output schema exists, so return-value explanation is not required, yet the description does correctly summarize the recorded flag. However, with 0% schema coverage and a nested 'result' object, the meaning of three of four inputs is left unaddressed.
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 0% with four required parameters, so the description must compensate for all of them. It only explains step_id; handoff_id, worker_id, and the free-form 'result' object are left entirely undocumented.
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 and resource ('Record a side effect by step_id') and its idempotent semantics, which separates it from siblings like dhp_effect_done. It does not explicitly name the sibling it must be distinguished from, 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 parenthetical 'do NOT re-fire the effect' gives a clear when-not rule and the semantics imply this is the checkpoint-recording step, but no alternative tool (e.g. dhp_effect_done) or prerequisite conditions are named. Usage is implied rather than spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_recoverB
Recover an orphaned handoff (worker died). Returns the lease and the last checkpointed state to resume from.
| Name | Required | Description | Default |
|---|---|---|---|
| worker_id | Yes | ||
| handoff_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses the precondition (orphaned handoff from a dead worker) and the return payload (lease plus last checkpointed state). It does not state the mutation side effects (lease re-assignment, state changes to the handoff record) or authorization requirements.
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 tight sentences: purpose and precondition front-loaded, return value second. Every clause earns its place with no filler.
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?
An output schema exists, so return values need not be explained (though the description mentions them anyway). Given no annotations and zero parameter coverage, the definition still leaves out mutation semantics and sibling routing, which matter for a lease-mutating recovery operation.
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% for both handoff_id and worker_id, so the description must compensate. It never mentions either parameter, leaving the agent to infer their meaning from names alone. Two undocumented required params at zero coverage is a real gap.
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 ('Recover an orphaned handoff') with the triggering condition ('worker died'). It does not name or distinguish itself from the closely-related sibling dhp_claim, which is likely the alternative for non-orphaned handoffs.
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 parenthetical '(worker died)' implies the usage condition, so the agent can infer when to reach for this tool. However, it never explicitly contrasts with dhp_claim or dhp_status, nor states any exclusion or prerequisite, leaving the choice between siblings to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_request_approvalA
Request approval for a destructive/financial action. Fail-closed: returns an approval_id; the action must NOT run until dhp_await_approval reports approved.
| Name | Required | Description | Default |
|---|---|---|---|
| details | Yes | ||
| worker_id | Yes | ||
| handoff_id | Yes | ||
| action_class | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it declares fail-closed semantics, states a return value (approval_id), and imposes a gating rule that prevents premature execution. It omits failure modes, error shapes, and any permission prerequisites, keeping it from a 5.
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 tight sentences, front-loaded with the trigger and the safety-critical gating constraint. Every clause earns its place; nothing is padding.
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?
The output schema exists, so return values need not be explained, and the workflow gate is covered. However, with zero annotation coverage and 0% parameter documentation for a call that gates destructive/financial operations, the definition leaves an agent without enough context on inputs or failure behavior.
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 handoff_id, worker_id, action_class, or the free-form nested details object. With four required but undocumented parameters, the description does not compensate for the schema gap at all.
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 ('Request approval for a destructive/financial action'), which separates it from decision siblings like dhp_approve/dhp_deny. It does not explicitly compare itself to those siblings, 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?
Gives a clear trigger condition (destructive or financial actions) and a mandatory follow-up gate ('must NOT run until dhp_await_approval reports approved'). It does not name exclusions or clarify the relationship to dhp_approval_status/dhp_approve, so it is clear but not fully routing-grade.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_require_capabilityA
Fail-closed capability check: verify the handoff's contract grants (domain, resource) before touching network, filesystem, or external services. Every check is audited.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | ||
| resource | Yes | ||
| worker_id | Yes | ||
| handoff_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden and does so well: 'fail-closed' declares behavior on a missing grant, and 'Every check is audited' discloses a side effect the agent would otherwise not know about. It leaves open whether failure manifests as an error or a false result, and says nothing about permissions needed to call it.
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 dense sentence front-loads the core semantics (fail-closed capability check) and then adds the usage constraint and audit note. No sentence is filler and nothing important is buried.
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?
An output schema exists, so return values need no explanation, and the description covers the safety-critical semantics of a guard check. The main remaining gap is the meaning/format of handoff_id and worker_id, plus an explicit statement of the failure surface, which for a fail-closed gate would be useful.
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% with four required parameters, so the description must compensate. It explicitly ties 'domain' and 'resource' to the contract grant, but handoff_id and worker_id are never explained, leaving half the required inputs to be inferred from their names alone.
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 and resource: verify that the handoff's contract grants (domain, resource). It is clearly a pre-flight authorization guard, which is distinguishable in spirit from mutation siblings like dhp_claim or dhp_record_effect, though it never names or contrasts those siblings directly.
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 gives a strong ordering rule – call this before touching network, filesystem, or external services – which tells the agent exactly when the check belongs in a workflow. It does not name alternatives or state when this check is unnecessary (i.e., purely local, read-only work), so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dhp_statusB
Status of a handoff: state, checkpoints, owner, result if completed.
| Name | Required | Description | Default |
|---|---|---|---|
| handoff_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden. It implicitly discloses the read-only nature by describing a pure status read and lists the fields returned, which is useful. However it says nothing about what happens with an unknown or expired handoff_id, whether results are cached, or any permissions required for a completed handoff's result.
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 tight sentence with no filler, front-loading the resource and then the returned facets. It is a noun fragment rather than a clause, which slightly weakens the lead, but nothing is wasted.
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?
An output schema exists, so enumerating state/checkpoints/owner/result in the description is partly redundant. With no annotations and an undocumented parameter, the definition leaves the agent to infer error behavior and handoff_id provenance; for a simple one-param read tool this is adequate but not fully rounded out.
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 0% with one required parameter, and the description never mentions handoff_id — no format (UUID? opaque token?), no source (returned by dhp_dispatch or dhp_claim), no existence requirement. The parameter name is self-explanatory, which is the only thing keeping this above a 1, but the description adds nothing.
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?
It names a specific resource (a handoff) and the read operation (fetching status), and enumerates the facets returned: state, checkpoints, owner, result. That distinguishes it from dhp_last_checkpoint (checkpoint-only) and dhp_health (system-level), though it never names a sibling explicitly. The fragmentary phrasing 'Status of a handoff' lacks a verb but 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?
There is no when-to-use guidance, no condition selecting this over dhp_last_checkpoint, dhp_health, or dhp_approval_status, and no stated prerequisites (e.g. the handoff must exist). Usage is only implied by the tool name and the returned-fields list.
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.
18 tool updates
v0.1.0- First observed
dhp_approval_status - First observed
dhp_approve - First observed
dhp_checkpoint - First observed
dhp_claim - First observed
dhp_complete - First observed
dhp_deny - First observed
dhp_dispatch - First observed
dhp_effect_done - First observed
dhp_health - First observed
dhp_heartbeat - First observed
dhp_last_checkpoint - First observed
dhp_note_activity - First observed
dhp_note_spend - First observed
dhp_record_effect - First observed
dhp_recover - First observed
dhp_request_approval - First observed
dhp_require_capability - First observed
dhp_status
TDQS
Scored across 18 tools
Most tools target distinct protocol actions (claim, checkpoint, complete, recover, approve/deny), but several read/write or lifecycle pairs (claim vs recover, checkpoint vs last_checkpoint, record_effect vs effect_done, status vs approval_status) require careful reading. Descriptions clarify the boundaries, and no true duplicates exist.
All names use a consistent dhp_ prefix and snake_case, which is easy to parse. The verb_noun pattern is not universal (heartbeat, status, health, approve, deny, dispatch, last_checkpoint), so it is mostly rather than perfectly consistent.
18 tools is on the heavy side for a single protocol server, but each maps to a distinct lifecycle, safety, or observability concern (lease, checkpoint, effects, approvals, budget, capabilities). The surface is defensible, though it could likely be consolidated slightly.
Core durable handoff lifecycle (dispatch, claim, recover, checkpoint, complete), approvals, side-effect deduplication, budget tracking, and capability checks are all covered. Minor gaps remain, such as no explicit cancel/abandon handoff or list-handoffs operation, but agents can largely work around these via status and recover.
Maintenance
Related MCP Connectors
Durable background job execution, async task scheduling, and state persistence for AI agents.
Checkpoint and resume for AI agent runs, so crashed runs pick up where they left off.
Dead-man switch for AI agents & cron jobs: heartbeat with state capsule, alerts + resume links
Durable self for AI agents: one-call resume, memory, real browser, free chat + hire real humans.
Related MCP Servers
AlicenseNot gradedqualityBmaintenanceEnables AI agents to run model-checked workflows durably, receiving one work order at a time with guarantees on admission.5 npmApache 2.0- AlicenseAqualityCmaintenanceIt enables AI agents to recover from failures by diagnosing issues, refocusing broad tasks, restoring session context, and managing retries safely with bounded memory and credential redaction.61MIT
- AlicenseNot gradedqualityAmaintenanceUniversal verifiable recovery for long-running AI agents with semantic checkpoints, idempotent action ledger and hash chained log as a deny by default MCP server. Framework agnostic with adapters for LangGraph, LangChain and OpenAI plus gateway and OTel.24Apache 2.0
- AlicenseNot gradedqualityBmaintenanceProvides durable mission state for AI agents, enabling crash-safe recovery, verified completion, and explicit reconciliation of uncertain side effects without duplicate or blind retries.4Apache 2.0