{"protocol":"mcp","version":"2025-06-18","name":"CodeRifts API Governance","description":"API governance and contract safety for AI agents. Preflight checks before tool calls.","tools":[{"name":"preflight_change_set","description":"Preflight a COMPLETE base→head change set of contract artifacts and return a\ngovernance decision (ALLOW / WARN / REQUIRE_APPROVAL / BLOCK), risk score,\nbreaking-change analysis, and a signed chain-receipt when applicable.\n\nUse this when:\n- You are about to merge, push to a protected branch, deploy, publish a package,\n  or register/expose agent tools, AND the change includes at least one contract\n  artifact: OpenAPI/Swagger, GraphQL SDL, gRPC/protobuf, AsyncAPI, MCP manifest,\n  or agent tool schemas (inputSchema/JSON Schema tools list).\n- You have (or can assemble) the FULL base and head (or before/after) content for\n  every changed contract artifact in this change set — not a single-file subset\n  when other contract files also change.\n- You need a NEW decision for the CURRENT change; you do not already hold a\n  currently-valid receipt for this exact target/operation.\n\nDo not use when:\n- The change is documentation-only (README, guides, comments) with no contract\n  artifact content change — do not call any CodeRifts tool.\n- You already hold a signed receipt and only need to check it is authentic and\n  currently valid — use coderifts.verify_receipt instead.\n- You need details of a PREVIOUS decision by decision_id — use\n  coderifts.get_decision_details instead.\n- You only want a static \"agent readiness\" score of a single unspec-diffed file\n  with no pending mutate — that is a specialized non-default alias, not this tool.\n- You cannot supply both before and after (or base and head) for the artifacts\n  that change — fix the change set first; do not invent empty before specs.\n\nInputs: list of artifacts, each with type, before, after (or equivalent), plus\noptional operation (merge|deploy|tool_call|publish), environment/stakes, and\ncontext. Returns decision, execution_action, risk fields, and chain_receipt when issued.","inputSchema":{"type":"object","properties":{"artifacts":{"type":"array","description":"Contract artifacts to analyze together (max 20). Each is { id, type, before, after }.","minItems":1,"maxItems":20,"items":{"type":"object","properties":{"id":{"type":"string","description":"Caller-chosen id, unique within the bundle"},"type":{"type":"string","enum":["openapi","graphql","grpc","asyncapi","mcp_manifest","agent_tools"]},"before":{"type":"string","description":"Prior artifact content (spec/schema/manifest) as a string"},"after":{"type":"string","description":"Updated artifact content as a string"}},"required":["id","type","before","after"]}},"context":{"type":"object","description":"Optional { operation, environment, repository, branch, pull_request, policy_profile }"},"previous_receipt":{"type":"string","description":"Optional prior chain receipt token to link"},"idempotency_key":{"type":"string","description":"Optional client key; a repeat with the same key + body replays the original decision (24h)"}},"required":["artifacts"]},"annotations":{"readOnlyHint":true,"openWorldHint":false},"outputSchema":{"type":"object","description":"Aggregated bundle verdict across contract artifacts (strictest-wins). required holds on every success path including idempotency replay (formatStoredDecision), which does not carry fresh-only fields such as bundle_fingerprint or artifacts.","properties":{"decision":{"type":"string","enum":["ALLOW","WARN","REQUIRE_APPROVAL","BLOCK"]},"safe_for_agent":{"type":"boolean"},"execution_action":{"type":"string","enum":["CONTINUE","CONTINUE_WITH_MONITORING","REQUEST_APPROVAL","STOP"]},"risk_score":{"type":"integer","minimum":0,"maximum":100},"breaking_changes":{"type":"integer","minimum":0},"patterns":{"type":"array","items":{"type":"string"}},"bundle_fingerprint":{"type":"string","pattern":"^sha256:[a-f0-9]{64}$"},"artifacts":{"type":"array","items":{"type":"object"}},"evidence":{"type":"array","items":{"type":"object"}},"decision_result":{"type":"object","description":"decision-result.v1 envelope (present when a chain receipt is available). Full schema: https://coderifts.com/schemas/decision-result.v1.consumer.json"},"meta":{"type":"object"},"control_envelope":{"type":"object","description":"Control envelope (control/1.0): decision, safe_for_agent, execution_action, required_action, receipt."},"required_action_core":{"type":"object","description":"Branchable required-action core { type, reason_code, recheck_required } when the stored/fresh envelope carries it."},"verdict_fingerprint":{"type":"string","description":"Verdict fingerprint (sha256:…); mirrors envelope.fingerprint on replay."},"chain_receipt":{"type":"string","description":"Signed chain receipt token when issued (fresh path with signer configured)."}},"required":["decision","execution_action","safe_for_agent"],"additionalProperties":true}},{"name":"verify_receipt","description":"Verify a CodeRifts signed chain-receipt you ALREADY HOLD: cryptographic\nauthenticity (signature + key id), body binding, and — when lifecycle indices\nare available — whether it is currently valid authorization (not expired,\nsuperseded, or revoked) for a stated operation/target.\n\nUse this when:\n- You already obtained a chain_receipt / receipt token from a prior preflight\n  (or CI artifact) and are about to act (merge/deploy) under that receipt.\n- A contract-gate or policy requires offline/online proof that the receipt is\n  authentic for this change before proceeding.\n- You must distinguish \"signature ok\" from \"currently authorized\" (stale or\n  superseded receipts must not be treated as live approval).\n\nDo not use when:\n- You do not have a receipt yet — call coderifts.preflight_change_set first.\n- You need a NEW decision for a changed base→head set — preflight again;\n  verify_receipt does not re-diff specs.\n- You only need human-readable history of an old decision_id without a receipt\n  token — use coderifts.get_decision_details.\n- The change set itself is unknown or incomplete — fix the change set and\n  preflight; do not \"verify\" a placeholder.\n\nInputs: receipt token (required); optional expected target_id, operation, and\nnow-skew policy hooks. Returns { valid, status, decision, execution_action,\nlifecycle_state, reasons[] }.","inputSchema":{"type":"object","properties":{"token":{"type":"string","description":"The chain receipt token (base64url(body).base64url(signature))"},"operation":{"type":"string","description":"Intended operation the receipt must authorize (merge|deploy|tool_call|publish)"},"target_id":{"type":"string","description":"Intended apply-site target the receipt must bind"},"environment":{"type":"string","description":"Intended environment (e.g. production) — must match the receipt"},"fingerprint":{"type":"string","description":"Intended change fingerprint — must equal the receipt fp"},"audience":{"type":"string","description":"Intended audience — must match the receipt"},"decision_result":{"type":"object","description":"The body_hash-bound decision envelope (carries operation/target/decision); required to evaluate authorization scope"}},"required":["token"]},"annotations":{"readOnlyHint":true,"openWorldHint":false},"outputSchema":{"type":"object","properties":{"valid":{"type":"boolean","description":"true iff status is VERIFIED_CURRENT or RETIRED_KEY_VALID_AT_ISSUE"},"status":{"type":"string","enum":["VERIFIED_CURRENT","VERIFIED_EXPIRED","VERIFIED_WRONG_AUDIENCE","VERIFIED_WRONG_ENVIRONMENT","VERIFIED_SUPERSEDED","VERIFIED_SCOPE_MISMATCH","UNKNOWN_KEY","RETIRED_KEY_VALID_AT_ISSUE","INVALID_SIGNATURE","MALFORMED","UNSUPPORTED_VERSION","REGISTRY_UNREACHABLE"]},"reason":{"type":["string","null"]},"payload":{"type":"object"},"currently_authorized":{"type":["boolean","null"],"description":"Whether the receipt currently authorizes the intended operation/target/fp (§106). null means authorization could not be evaluated (e.g. no intended context) — not unauthorized and not authorized."},"authz_reason":{"type":"string","description":"When currently_authorized=false: the deny reason (operation_mismatch, decision_not_allow, superseded, expired, target_mismatch, environment_mismatch, …)"},"authz_status":{"type":"string","description":"Authorization-level status (VERIFIED_WRONG_ENVIRONMENT / VERIFIED_SUPERSEDED / VERIFIED_SCOPE_MISMATCH / …)"},"authz_state":{"type":"string","description":"Lifecycle state from isCurrentlyAuthorized when authorization is evaluated (optional; omitted when currently_authorized is null)"},"authz_note":{"type":"string","description":"Present when no intended context supplied: status reflects signature+expiry only"}},"required":["valid","status","currently_authorized"],"additionalProperties":true}},{"name":"get_decision_details","description":"Retrieve a PAST CodeRifts decision by decision_id (or fingerprint): full\nreport payload, breaking changes list, scores, and linked receipt metadata\nif stored.\n\nUse this when:\n- You have a decision_id (or fingerprint) from a previous preflight, PR\n  comment, or CI log and need to inspect or explain that past decision.\n- You are auditing why a prior ALLOW/WARN/BLOCK was issued.\n- You are NOT requesting a new analysis of current before/after specs.\n\nDo not use when:\n- You need a decision for the CURRENT uncommitted or PR head change set —\n  call coderifts.preflight_change_set with the current artifacts.\n- You hold a receipt token and only need cryptographic/lifecycle verification —\n  use coderifts.verify_receipt.\n- You have no decision_id/fingerprint — run preflight first to create one.\n\nInputs: decision_id (preferred) and/or fingerprint. Returns the stored\ndecision document or not_found.","inputSchema":{"type":"object","properties":{"decision_id":{"type":"string","description":"The decision_id from a prior decision_result envelope"},"fingerprint":{"type":"string","description":"A verdict fingerprint (sha256:...); returns the latest matching decision"}}},"annotations":{"readOnlyHint":true,"openWorldHint":false},"outputSchema":{"type":"object","description":"A stored CodeRifts decision: the original decision_result.v1 envelope + lookup meta. Retrieval-path control fields (safe_for_agent/execution_action/verdict_fingerprint/control_envelope) mirror the fresh preflight response and are present only when the stored envelope carries their source field.","properties":{"decision":{"type":"string","enum":["ALLOW","WARN","REQUIRE_APPROVAL","BLOCK"]},"safe_for_agent":{"type":"boolean"},"execution_action":{"type":"string","enum":["CONTINUE","CONTINUE_WITH_MONITORING","REQUEST_APPROVAL","STOP"]},"verdict_fingerprint":{"type":"string"},"control_envelope":{"type":"object","description":"Control envelope (control/1.0) derived from the stored decision_result."},"required_action_core":{"type":"object","description":"Branchable required-action core { type, reason_code, recheck_required } when present on the envelope."},"risk_score":{"type":"integer","minimum":0,"maximum":100},"breaking_changes":{"type":"integer","minimum":0},"patterns":{"type":"array","items":{"type":"string"}},"decision_result":{"type":"object","description":"decision-result.v1 envelope (present when a chain receipt is available). Full schema: https://coderifts.com/schemas/decision-result.v1.consumer.json"},"meta":{"type":"object","properties":{"decision_id":{"type":"string"},"source":{"type":"string"},"created_at":{"type":"string"},"retrieval_mode":{"type":"string","enum":["stored"]}},"additionalProperties":true}},"required":["decision_result","meta"],"additionalProperties":true}}],"correlation_id":"7f8f9b42-b211-40dc-85b2-57e4161061e8"}