{
  "contractVersion": "7.0.0",
  "product": {
    "name": "Company Cloudflare Publisher MCP",
    "release": "0.11.0"
  },
  "clientInstallation": {
    "explicitUrlFragment": "#install",
    "baseGuideUrlIsInstallTrigger": false,
    "scope": "Install or replace exactly company-cloudflare-validator and company-cloudflare-deployer in one detected supported MCP client; preserve unrelated configuration.",
    "credentials": "Require exactly one separately supplied one-time code matching ccpc_ plus 32 lowercase hexadecimal characters. Before code use, validate the same-origin manifest, its single endpoint pair, and the canonical HTTPS production pair id exactly production. Derive the claim URL only from the trusted Deployer origin plus /agent/claim and exchange the code once for a Validator credential matching ^ccpv_[a-f0-9]{48}$ and a Deployer credential matching ^ccpd_[a-f0-9]{48}$. The code expires after 30 minutes, is never a bearer, and must never enter the URL, Guide, command arguments, output, or logs. Persist only each returned 90-day role-scoped credential in its matching owner-private client entry. Never provide an Agent with operator break-glass credentials, never downgrade to a shared bearer, and require re-onboarding for migration.",
    "verificationCallsAllowed": [
      "get_site_requirements",
      "get_deployment_requirements"
    ],
    "neverAuthorizesPublish": true
  },
  "intent": {
    "id": "publish_static_site_to_company_cloudflare",
    "explicitTrigger": "cloudflare-publish",
    "confirmedTriggerForms": [
      "cloudflare-publish now",
      "cloudflare-publish 直接上線"
    ],
    "contextualConfirmationPhrases": [
      "直接上線"
    ]
  },
  "naturalTriggerPhrases": {
    "en": [
      "Publish this static website to the company Cloudflare domain",
      "Deploy this HTML proposal to our company Cloudflare domain"
    ],
    "zh-Hant": [
      "將這個靜態網站發佈到公司 Cloudflare domain",
      "把這個 HTML 提案發佈到公司網域"
    ],
    "yue-Hant": [
      "幫我將呢個 static website deploy 去公司 Cloudflare domain",
      "幫我上呢個 HTML proposal 去公司網域"
    ]
  },
  "nonTriggers": [
    {
      "category": "information_only",
      "examples": [
        "Explain the publishing architecture",
        "公司 Cloudflare 架構係點？"
      ]
    },
    {
      "category": "local_preview_only",
      "examples": [
        "Preview this site locally",
        "只係本機睇下，唔好 deploy"
      ]
    },
    {
      "category": "unsupported_runtime",
      "examples": [
        "Deploy this Next.js server",
        "發布 Cloudflare Worker 或後端 API"
      ]
    },
    {
      "category": "administration_or_removal",
      "examples": [
        "Delete the Cloudflare project",
        "移除 Worker deployment 或修改 Basic Auth credential"
      ]
    },
    {
      "category": "rollback_or_auth_verification",
      "examples": [
        "Rollback the proposal",
        "重新驗證 Basic Auth gate"
      ]
    }
  ],
  "requiredUserInputs": [
    "projectName",
    "source",
    "credentialInputCompletion"
  ],
  "projectAdmission": {
    "mode": "first-claim",
    "askOnEveryNewUpload": true,
    "neverGuessOrSuffix": true,
    "reservationExpiresWithUpload": true,
    "successfulValidationFinalizesName": true,
    "finalizedNamesReusable": false
  },
  "targetContract": {
    "canonicalPublicUrl": "https://<worker-script>.<account-subdomain>.workers.dev/<projectName>/",
    "canonicalTrailingSlash": true,
    "topologyEvidence": {
      "customDomainAbsenceVerifiedByRuntime": true,
      "workerRoutesEnumeratedByRuntime": false,
      "workerRouteAbsence": "administrator-controlled-assumption",
      "agentMustNotClaimWorkerRouteAbsenceWasVerified": true
    },
    "authentication": {
      "mode": "basic",
      "scope": "project-path",
      "credentialsAcceptedByMcp": false,
      "credentialReferenceAcceptedByMcp": true,
      "credentialInputMode": "url",
      "credentialSource": "user-supplied-out-of-band",
      "immutablePerProject": true,
      "planDisplays": ["username", "credentialState", "confirmationId"],
      "planNeverDisplays": ["password"],
      "activeResponseReturns": ["url", "username", "capturedStatus"]
    }
  },
  "credentialInput": {
    "create": {
      "tool": "create_credential_input",
      "arguments": ["projectName"]
    },
    "pageUrl": {
      "origin": "exact-configured-deployer-endpoint-origin",
      "path": "/credential-input/",
      "queryAllowed": false,
      "exactFragmentParameters": ["projectName", "credentialRef", "submissionToken"],
      "userEntersUsernameAndPasswordOnlyHere": true
    },
    "status": {
      "tool": "get_credential_input_status",
      "arguments": ["projectName", "credentialRef"],
      "requiredBeforeReadiness": "captured"
    },
    "mcpArguments": {
      "readiness": ["projectName", "receipt", "credentialRef"],
      "plan": ["projectName", "receipt", "credentialRef"],
      "deploy": ["projectName", "receipt", "credentialRef", "confirmationId"],
      "rawCredentialFieldsAllowed": false
    },
    "privacy": {
      "neverAskForCredentialsInChat": true,
      "neverReadOrLogSubmissionToken": true,
      "passwordReturnedByMcp": false
    }
  },
  "acceptedSourceKinds": [
    "pasted_html",
    "html_file",
    "static_directory",
    "root_layout_zip",
    "prebuilt_react_static_output"
  ],
  "semantics": {
    "plainTrigger": {
      "mode": "plan_then_confirm",
      "rule": "Validate the source and produce a deployment plan, then obtain explicit user confirmation before deploy_proposal."
    },
    "confirmedTrigger": {
      "mode": "plan_then_confirm",
      "rule": "Urgency words such as now or 直接上線 do not confirm a plan the user has not seen. Run discovery, upload, validation, trusted out-of-band credential capture, readiness, and planning with credentialRef; show the exact project, workers.dev URL, artifact, authMode, captured username, credential status, and confirmationId without the password, then obtain explicit confirmation before deploy_proposal."
    },
    "neverBypass": [
      "project_name_reservation_and_claim",
      "input_upload_and_readiness",
      "static_site_validation",
      "signed_receipt_verification",
      "out_of_band_credential_capture",
      "deployment_readiness",
      "read_only_deployment_plan",
      "canonical_public_path_derivation",
      "worker_basic_auth_gate_verification"
    ]
  },
  "validatorSequence": [
    {
      "operation": "mcp_tool",
      "name": "get_site_requirements"
    },
    {
      "operation": "mcp_tool_when_inputs_are_missing_or_need_checking",
      "name": "check_site_readiness"
    },
    {
      "operation": "mcp_tool",
      "name": "create_input_upload"
    },
    {
      "operation": "https_put_to_server_issued_url",
      "name": "upload_source_bytes"
    },
    {
      "operation": "mcp_tool",
      "name": "check_site_readiness"
    },
    {
      "operation": "mcp_tool_only_when_ready",
      "name": "validate_site"
    }
  ],
  "deployerSequence": [
    {
      "operation": "mcp_tool",
      "name": "get_deployment_requirements"
    },
    {
      "operation": "mcp_tool",
      "name": "create_credential_input"
    },
    {
      "operation": "user_browser_action",
      "name": "complete_trusted_deployer_credential_page"
    },
    {
      "operation": "mcp_tool_until_captured",
      "name": "get_credential_input_status"
    },
    {
      "operation": "mcp_tool",
      "name": "check_deployment_readiness"
    },
    {
      "operation": "mcp_tool_read_only",
      "name": "plan_deployment"
    },
    {
      "operation": "confirmation_gate",
      "name": "confirm_exact_project_path_url_and_artifact"
    },
    {
      "operation": "mcp_tool_mutating",
      "name": "deploy_proposal"
    },
    {
      "operation": "mcp_tool_when_status_is_not_terminal",
      "name": "get_deployment_status"
    }
  ],
  "confirmation": {
    "requiredForPlainTrigger": true,
    "coveredByConfirmedTrigger": false,
    "scope": [
      "projectName",
      "authMode",
      "derivedHostname",
      "derivedPublicPath",
      "derivedPublicUrl",
      "artifactId",
      "planNoOpState",
      "credentialRef",
      "credentialInputStatus",
      "capturedUsername",
      "confirmationId"
    ],
    "invalidatedBy": [
      "project_change",
      "source_change",
      "receipt_change",
      "derived_target_change",
      "credential_reference_change",
      "credential_input_status_change",
      "captured_username_change",
      "confirmation_id_change"
    ]
  },
  "recovery": {
    "statusProbe": {
      "tool": "get_deployment_status",
      "arguments": ["projectName"],
      "requiredBeforeValidatorRenewal": true,
      "purpose": "branch-selection-only",
      "receiptReturned": false,
      "outcomes": {
        "STATUS_NOT_FOUND": "allow-same-finalized-claim-and-artifact-receipt-renewal",
        "matchingNonterminalExactReceipt": "use-retained-original-accepted-receipt",
        "operatorRequired": "stop-and-escalate-to-operator",
        "missingOrInvalidRecoveryMode": "stop-and-escalate-to-operator",
        "SERVICE_UNAVAILABLE": "retry-status-later-or-escalate-no-renewal",
        "otherError": "retry-status-later-or-escalate-no-renewal",
        "stable": "stop-and-escalate-to-operator",
        "mismatched": "stop-and-escalate-to-operator",
        "malformed": "stop-and-escalate-to-operator"
      }
    },
    "beforeDeployerNonterminal": {
      "condition": "status-not-found-and-credential-page-or-receipt-expired",
      "retainExact": ["projectName", "inputRef", "finalizedClaim", "artifact"],
      "renewReceipt": {
        "tool": "validate_site",
        "arguments": ["projectName", "inputRef"],
        "sameFinalizedClaimOnly": true,
        "sameArtifactOnly": true
      },
      "newCredentialInput": {
        "tool": "create_credential_input",
        "arguments": ["projectName"]
      },
      "then": ["capture-new-credential-ref", "repeat-readiness", "repeat-plan", "display-changes", "obtain-new-explicit-confirmation"],
      "newUploadAllowed": false,
      "newProjectNameAllowed": false
    },
    "afterDeployerNonterminal": {
      "condition": "matching-project-and-artifact-nonterminal-with-recovery-mode-exact-receipt",
      "requiredRecoveryMode": "exact-receipt",
      "exactProjectMatchRequired": true,
      "exactArtifactMatchRequired": true,
      "ambiguousConfirmationResponseMayBeLost": true,
      "receiptSource": "retained-original-accepted-receipt",
      "receiptRetainedBy": "agent-workflow",
      "persistedReceiptRequired": true,
      "replaceReceiptAllowed": false,
      "validatorRenewalAllowed": false,
      "newCredentialRefOnlyIfNeeded": true,
      "then": ["repeat-readiness", "repeat-plan", "display-changes", "obtain-new-explicit-confirmation"],
      "newUploadAllowed": false,
      "newProjectNameAllowed": false
    },
    "unsafeStatus": {
      "states": ["stable", "mismatched", "malformed"],
      "action": "stop-and-escalate-to-operator"
    },
    "statusError": {
      "states": ["SERVICE_UNAVAILABLE", "otherError"],
      "renewalAllowed": false,
      "credentialInputAllowed": false,
      "action": "retry-status-later-or-escalate-to-operator"
    },
    "recoveryModeGate": {
      "receiptReuseMode": "exact-receipt",
      "exactProjectMatchRequired": true,
      "exactArtifactMatchRequired": true,
      "blockedValues": ["operator-required", "missing", "invalid"],
      "blockedAction": "stop-and-escalate-to-operator"
    }
  },
  "retryRules": {
    "pre_deployer_nonterminal_expiry": "First call get_deployment_status with the exact projectName. Only STATUS_NOT_FOUND permits retaining the exact original projectName and inputRef and calling validate_site again to renew only the same finalized claim and artifact receipt. Create a new credential input, then repeat readiness, plan display, and explicit confirmation. Never create a new upload or project name.",
    "auth_pending": "Only an exact project/artifact match with server-authoritative recoveryMode=exact-receipt permits using the original accepted signed receipt retained by the Agent workflow. Status selects the branch and never returns a receipt. recoveryMode=operator-required, missing, or invalid stops and escalates to the operator. Never call Validator to renew a matching nonterminal receipt.",
    "status_error": "SERVICE_UNAVAILABLE or any error other than explicit STATUS_NOT_FOUND forbids Validator renewal and credential-input creation. Stop and retry get_deployment_status later or escalate to the operator.",
    "stable_mismatched_or_malformed_status": "Stop and escalate to the operator. Do not renew a Validator receipt, create a credential input, allocate an upload, or infer deployment state.",
    "service_unavailable": "Retry the same operation and same inputRef or receipt when still valid; do not silently allocate a replacement.",
    "input_not_found_or_expired": "Only before any claim is finalized, create a new upload and upload the source again. Never apply this rule to credential-page or receipt expiry recovery for a finalized claim.",
    "project_name_taken": "Stop and ask the user for a different exact projectName; never rename it automatically or reveal another claimant.",
    "validation_failed": "Correct the source against get_site_requirements, then create a new upload.",
    "failed_or_non_retryable": "Stop and ask the operator to inspect state; do not delete or adopt Cloudflare resources automatically."
  },
  "securityRules": [
    "Never send a client-local path to a remote MCP tool.",
    "Never ask the user to invent an inputRef.",
    "Never accept a hostname, Cloudflare credential, bearer token, actor identity, artifact path, Basic Auth username, or Basic Auth password as a publishing MCP argument. Remote Deployer readiness, plan, and deploy accept only the opaque credentialRef.",
    "Accept only a credential-input URL returned by create_credential_input whose origin exactly equals the configured Deployer endpoint origin, whose path is exactly /credential-input/, whose query is empty, and whose fragment contains exactly projectName, credentialRef, and submissionToken.",
    "The user enters username and password only on that trusted page. Never ask for them in chat, inspect or log submissionToken, or continue until get_credential_input_status for the exact projectName and credentialRef reports captured.",
    "Ask the user for the exact projectName on every new upload; never guess, reuse, or silently suffix values.",
    "Treat PROJECT_NAME_TAKEN as a global first-claim conflict, not as permission to identify another user.",
    "Only after deploy_proposal returns active, return its access.url, access.basicAuth.username, and access.basicAuth.status=captured. Never request or return the password through MCP, status, logs, or local state.",
    "Keep the Validator receipt private key separate from all Deployer Cloudflare credentials.",
    "Never report success until the deployment state is active and the exact canonical trailing-slash public URL is returned.",
    "Never treat now or 直接上線 as permission to bypass the post-plan confirmation gate.",
    "Expiry recovery always starts with get_deployment_status for the exact projectName only to select a branch; status never returns a receipt. Only explicit STATUS_NOT_FOUND permits validate_site renewal. SERVICE_UNAVAILABLE or any other error forbids renewal and credential input. A nonterminal may reuse the Agent-retained original receipt only when project and artifact match exactly and server-authoritative recoveryMode is exact-receipt. operator-required, missing, or invalid recoveryMode stops and escalates. Stable, mismatched, or malformed state also stops. No branch allocates a new upload or project name.",
    "For rollback, call read-only plan_rollback with projectName, display the exact current artifact/deployment state and the exact user-selected recorded candidate, then obtain a separate explicit confirmation. Never omit, infer, default, or auto-select rollbackTargetId.",
    "Runtime proves that the only Worker Custom Domain attached to the script is the operator-declared publishing hostname, which Cloudflare must report as attached. It does not enumerate Worker routes because Deployer has no Zone permission; route absence is an administrator-controlled assumption and must never be described as runtime-verified.",
    "Explain that every project path has a distinct Basic Auth credential but all projects share one browser origin; this trial has path-level authentication but no identity-aware authorization or browser-origin isolation."
  ],
  "administrativeOperations": {
    "verify_basic_auth": "Require a separate explicit administrative request and confirmation; never accept or reveal the credential.",
    "rollback": {
      "plan": {
        "tool": "plan_rollback",
        "arguments": ["projectName"],
        "readOnly": true,
        "displayExactCurrentArtifactAndDeploymentState": true,
        "candidateRequiredFields": ["rollbackTargetId", "artifactId", "deployedAt", "confirmationId"]
      },
      "selection": {
        "userSelectsExactCandidate": true,
        "autoSelectAllowed": false,
        "omittedTargetAllowed": false
      },
      "confirmation": {
        "separateExplicitConfirmationRequired": true,
        "displayExactCurrentAndSelectedTargetBeforeConfirmation": true
      },
      "execute": {
        "tool": "rollback_proposal",
        "arguments": ["projectName", "rollbackTargetId", "confirmationId"]
      }
    }
  }
}
