Revisions and ETags
Resources you can edit return an ETag header. An edit sends that value back in If-Match:
When an edit is refused as stale: read the resource again, apply your change to the new state, and retry with the new ETag. Never resend an old body with a fresh ETag: that would overwrite the change you did not see.
Which ETag each edit uses
Rollback does not take If-Match. It takes expected_live_version_id in the body instead, and a
live version that moved answers 409 conflict with details.reason: live_version_changed.
The draft ETag is the publication token
The draft ETag covers everything a publish would freeze: the draft revision, the revision of each
bound tool, the revision of each MCP server the tools use, every pinned secret version, the direct agent
library membership and source state/revision and the default-tool policy. A change to any of them gives
a new ETag. Editing a shared MCP server therefore changes the draft ETag of every agent that uses
it. The body’s revision field equals the ETag.
POST /agents/{agent_id}/publish requires this token in If-Match. The server recomputes it inside
the publish, and a mismatch answers 409 draft_conflict: the version you reviewed is the version
that goes live, or nothing does. Two publishes sent with the same token make one version.
Adding or removing a source in the direct agent library changes the token. A source state or revision change also changes it. An MCP server rediscovered with the same tool set does not move it.
GET /agents/{agent_id}/draft/diff returns the same token, so you can review the changes a publish
would make and publish exactly that.
Replays and revisions
An idempotent replay returns its stored answer before the current revision is checked, and uses the
original If-Match. See Idempotency and replay.