Skip to main content

MCP Draft System

AI drafts your infrastructure. You approve it.

Overview

The Draft System lets MCP agents propose infrastructure changes without directly mutating production. Agents create drafts; humans review, approve, and apply them. This ensures AI-generated proposals go through a human governance gate before taking effect.

How It Works

  1. An agent creates a draft describing a proposed configuration change
  2. The draft is stored in a pending state — no production resources are modified
  3. A human reviews the draft via CLI or UI, inspecting the proposed spec and diff
  4. The human applies the draft (or discards it)
  5. Apply-time validation runs before the change takes effect

Creating Drafts

Agents create drafts through dedicated MCP tools. In V1, agents can create draft endpoints only.

V1 Draft Types

TypeAgent-Creatable in V1
endpointYes
routeNo (V1.1+)
policyNo (V1.1+)
targetNo (V1.1+)
sourceNo (V1.1+)

Draft Status Lifecycle

pending → applied

discarded

expired
  • pending: Awaiting human review
  • applied: Human-approved and applied to production
  • discarded: Rejected or cancelled by human
  • expired: TTL exceeded without action

Listing and Viewing Drafts

Agents and humans can list drafts to see what is awaiting review:

AttributeDescription
Draft IDUnique identifier
TypeResource type (endpoint, route, etc.)
Statuspending / applied / discarded / expired
CreatorAgent or human who created it
Created atTimestamp of creation
Expires atTimestamp of automatic expiry
Proposed specThe configuration the draft would create

Each draft stores the proposed specification so reviewers can inspect exactly what would change.

Discarding Drafts

Drafts can be discarded by either an agent or a human if the proposal is no longer needed. Discarded drafts are not deleted but marked for audit trail purposes.

No-Apply MCP Governance

MCP agents cannot apply drafts directly.

Apply is an explicit human-only action:

  • The apply API (POST /api/v1/drafts/{id}/apply) rejects MCP authentication with a 403 MCP_CANNOT_APPLY error
  • Apply requires a X-User-Id header identifying the human operator
  • Drafts do not mutate any production resource until a human applies them
  • The MCP surface has no apply tool, no apply route, and no write-to-production scope

This is a governance design — not a temporary limitation. Human-in-the-loop approval for infrastructure changes is intentional.

Draft Review and Apply Model

Review Surface

Drafts can be reviewed through two surfaces:

CLI (draft.py):

  • draft list — view all pending drafts with status and type
  • draft show <id> — inspect proposed spec with diff
  • draft apply <id> — apply a draft (human only, requires ZEN_USER_ID)
  • draft discard <id> — discard a pending draft

UI (web dashboard):

  • Pending count badge showing how many drafts await review
  • Draft list table showing status, type, creator, expiry, and diff availability
  • Draft review page with proposed spec visualization and diff view
  • Human-only Apply and Discard buttons (gated by session authentication)
  • Empty state and expired draft indicators

Apply-Time Validation

When a human applies a draft, these validations run and the apply is fail-closed:

  1. MCP auth rejectedMCP_CANNOT_APPLY (403)
  2. Pending status check — draft must be in pending state
  3. Expiry check — draft must not be expired
  4. Tenant ownership check — drafter and applier must belong to the same tenant
  5. Type check — only endpoint drafts can be applied in V1
  6. Proposed spec exists — draft must have a valid proposed spec
  7. Provider template enum check — provider must be a known, valid provider
  8. Target URL format check — endpoint target URL must be well-formed and non-empty
  9. Secret material check — proposed spec must not contain raw secrets (uses secret references)

Evidence Artifacts

Each draft lifecycle event produces separate evidence artifacts:

EventFields
draft_createddraft_id, type, created_by, created_at, proposed_spec_digest, merkle_position
draft_applieddraft_id, applied_by, applied_at, resource_created, merkle_position, previous_digest

Creation and apply evidence are generated by different endpoints and never share fields, maintaining separation of concerns.

Draft Expiry and Cleanup

Drafts have a configurable time-to-live. Expired drafts are automatically cleaned up by a garbage collection process:

  • Expired drafts cannot be applied (fail-closed at validation)
  • Cleanup respects tenant boundaries
  • Evidence artifacts are never deleted — only the draft record is cleaned
  • Maximum deletion rate is bounded to prevent resource spikes

V1 vs V1.1 Scope

V1 (Current)

FeatureAvailable
Agent-created endpoint draftsYes
Draft list / show / discardYes
Human-only apply (CLI + UI)Yes
Apply-time validation (9 checks, fail-closed)Yes
Draft evidence artifactsYes
Draft expiry and GCYes
MCP cannot apply (403 enforcement)Yes

V1.1+ (Planned)

FeatureTimeline
route, policy, target, source draft typesV1.1+
GitOps PR generation from draftsV1.1+
Inline draft editing before applyV1.1+
Draft comments and annotationsV1.1+
Full admission webhook frameworkV1.1+
Merkle chain integration for draft evidenceV1.1+

Relationship to Read-Only V1 Policy

The Draft System extends MCP beyond pure read-only while preserving the human-in-the-loop governance model. MCP remains read-only for production operations — drafts are proposals, not mutations. Apply is exclusively human. See the Read-Only V1 Policy for the base read-only contract.