Skip to main content

CodeRifts · MCP server · for agents

Get authority before you mutate a contract.

CodeRifts is a hosted MCP server, and an agent uses it in three steps, in this order. ANALYZE returns information about a change and issues nothing. Analyze does not need a key: POST /api/v1/preflight with preflight_mode: analyze answers without one. Authorize needs a key. AUTHORIZE issues the authority: a grant bound to that change set, which is the thing an execution needs before it proceeds. VERIFY lets anyone check that authority independently — offline, against a public key, with no account and no call to us.

Branch on execution_action: CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, or STOP (unrecognised values fail closed). decision (ALLOW / WARN / REQUIRE_APPROVAL / BLOCK) is explanation, not the branch key. The risk score, the break pattern and the cost estimate belong to the analysis: they describe the change, and none of them authorizes it. MCP tools report; they do not prevent a call by themselves — see what each path does.

When not to use this

Three cases where a grant from this server is the wrong tool, taken from the published does_not_prove list on /.well-known/coderifts.json (read 2026-09-23), not written for this page.

  • You need proof that what ran is what was authorized. The grant does not bind the canonical tool-call bytes, so what-was-called is not proven equal to what-was-authorized. Planned, not available.
  • You are delegating to a sub-agent and need its authority narrowed. A downstream agent is not given a strictly narrower grant than its caller held — delegation attenuation is not available. Hand a receipt down and you have handed down the whole grant.
  • You need a signed supply-chain envelope. No DSSE or in-toto envelope is emitted by any published artifact, and there is no single cross-domain bundle over grant, measurement and supply chain. Planned / on request, not available.

Endpoint

URL
https://app.coderifts.com/mcp
Transport
Streamable HTTP (protocol 2025-06-18)
Auth
Bearer API key — Authorization: Bearer <key> (from coderifts.com)
Manifest
coderifts.com/mcp.json
Registry
io.github.coderifts/api-governance

Connect

{
  "mcpServers": {
    "coderifts": {
      "url": "https://app.coderifts.com/mcp",
      "headers": {
        "Authorization": "Bearer <YOUR_CODERIFTS_API_KEY>"
      }
    }
  }
}
Add to Cursor Add to VS Code

Cursor and VS Code are one-click install URLs (auth is still a Bearer key after connect). Claude Desktop has no official one-click URL — paste the config above into claude_desktop_config.json and restart. Copilot cloud is Settings-paste (mcpServers) or coderifts copilot-setup for the developer surface. Claude Code: claude mcp add --transport http coderifts https://app.coderifts.com/mcp. Per-host table: app docs/mcp-one-click.md.

MCP Tools

ToolCall it when…
preflight_change_setBefore modifying contract artifacts in one change set. Requires preflight_mode: analyze (risk only — not permission) or authorize (needs context.operation; may mint a receipt). Mode-less requests return 400.
verify_receiptTo confirm a CodeRifts chain receipt you hold is authentic and unaltered. Verifies its signature and integrity. Not for authorizing a change — run preflight_change_set in authorize mode for that.
get_decision_detailsTo look up a past decision by decision_id or fingerprint. Returns the stored decision_result envelope and receipt. Read-only — not for making new safety decisions.

Only the three tools above are exposed through MCP. The REST rows below mirror that calling path (plus readiness) for agents that hit HTTP without MCP — the agent-relevant surface, not the full product API.

Agent-relevant REST endpoints

HTTP equivalents of the governance operations an agent actually calls. Not an exhaustive product API index.

EndpointDescription
POST /api/v1/preflightSame job as preflight_change_set. Pass preflight_mode (analyze | authorize). Authorize may return a signed receipt; analyze never does.
POST /api/v1/verify-receiptVerify a CodeRifts receipt (same job as verify_receipt).
POST /api/v1/decisions/lookup · GET /api/v1/decisions/:idRetrieve a previously issued decision (same job as get_decision_details).
POST /api/v1/agent-readiness-scoreStatic 0–100 readiness score for one OpenAPI/MCP document (advanced; not a change-set preflight).

Verify (connectivity)

MCP initialize proves the transport speaks MCP. GET /health is liveness. Neither is enforcement.

curl -sS https://app.coderifts.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'

Enforcement health-check

There is no MCP tool named health. After one-click + Bearer key, run this sequence (scaffold: app docs/mcp-health-check.json). Hidden alias governance_health is POST /api/v1/diff — not this check.

  1. GET https://app.coderifts.com/health — process up.
  2. MCP initialize (above) — transport up.
  3. MCP tools/list — exact set: preflight_change_set, verify_receipt, get_decision_details.
  4. First authorized action: preflight_change_set with preflight_mode: "authorize", context.operation, and at least one artifacts[] (authorize without a change set is 400). Branch on execution_action: CONTINUE | CONTINUE_WITH_MONITORING | REQUEST_APPROVAL | STOP. Unrecognised values fail closed.

Conformance END_TO_END, 2 vectors, RECORDED

@coderifts/conformance@0.8.11 reports END_TO_END COVERED / RECORDED — 2 vector(s) via TARGET_STATE_TRANSITION_PROVEN: a governed ref moved to the authorized commit under a signed grant, observed afterwards by a separate read-only process. Boundary, exactly as the profile records it: proof_scope TRUSTED_EXECUTOR, provider_witness NOT_APPLICABLE, externally_witnessed false. CodeRifts did not witness or sign the provider state. This is trusted-executor-integrity, not PATH B, and not the GitHub provider-loop. Honesty table: What each proof proves. What is a gate today versus planned / on-request (never available): claim table.

Response contract (Decision Spec v2)

preflight_change_set is a mode-discriminated union on preflight_mode. Analyze is not permission. verify_receipt and get_decision_details return different shapes. Schema: preflight-response.v2.consumer.json.

ANALYZE (informational — branch on may_execute / analysis_outcome; no execution_action / decision / safe_for_agent):

{
  "preflight_mode": "analyze",
  "analysis_outcome": "NO_BREAK_DETECTED",
  "authorization_effect": "NONE",
  "may_execute": false,
  "receipt_kind": "NONE",
  "analysis_control": {
    "next_call": {
      "tool": "preflight_change_set",
      "is_permission": false,
      "reason": "still_not_permission",
      "arguments": { "preflight_mode": "authorize" }
    }
  }
}

AUTHORIZE (operation-bound — requires context.operation; branch on execution_action: CONTINUE | CONTINUE_WITH_MONITORING | REQUEST_APPROVAL | STOP; gates verify receipt conjunctively):

{
  "preflight_mode": "authorize",
  "decision_spec_version": "2.0",
  "receipt_kind": "operation_authorization",
  "decision": "BLOCK",
  "execution_action": "STOP",
  "safe_for_agent": false,
  "risk_score": 57,
  "chain_receipt": "...",
  "breaking_changes": 1,
  "patterns": [ ... ]
}

Mode-less request → 400. Default is Decision Spec 2.0. A request that pins decision_spec_version: "1.0" is refused, not downgraded. The announced sunset was 2026-09-07T00:00:00Z, and the pin is gone: the server answers 400 INVALID_INPUT and names the retirement — decision_spec_version ‘1.0’ retired at 2026-09-07T00:00:00Z; Decision Spec 2.0 is required. There is no pre-v2 shape to fall back to and no deprecation header to read; the request does not complete. Measured 2026-09-20 against /api/v1/preflight: the identical body pinned to "2.0" answers 200. Do not pin 1.0. Permission still requires authorize + verified receipt (receipt AND currently_authorized AND operation AND fingerprint AND execution_action) — never analyze alone.

Handing a receipt to another agent

A receipt travels. Authority does not travel with it in the way most delegation designs assume, and the difference is one field. verify_receipt answers is this token authentic; it returns valid: true and status: VERIFIED_CURRENT for a token whose signature and expiry check out. It returns currently_authorized: null — not false, not true — because with a token alone the question cannot be answered, and an unanswered question is never a yes. The hosted verify_receipt route, given a token alone, answers currently_authorized null. The open offline verifier prints VERIFIED_CURRENT and has no currently_authorized field. Before acting under a held receipt: call verify_receipt with the SAME context the preflight was made under (operation, and only the environment, repository, branch and pull_request it had) for THIS attempt AND target_id set to decision_result.artifact_digest. A content-only receipt cannot be bound to a repository afterwards — do not add a repository, branch or pull_request the preflight did not have. Do not act on a receipt whose scope does not match. Without target_id the answer is currently_authorized: false with authz_reason target_not_stated — a missing input, not a refusal; authz_reasons lists every violation, not only the first. Valid is not currently_authorized. A sub-agent that treats a handed-down receipt as permission has skipped the only step that binds authority to its operation. And the grant it received is not narrowed: delegation attenuation is not available, so a receipt passed down carries the caller’s full scope, never a reduced one. If the sub-agent is doing something narrower, it should be calling preflight_change_set in authorize mode for its own change set, not reusing a parent’s.

Where to go next

Two pages this one deliberately does not duplicate. The onboarding ladder is the same three steps as a sequence you can walk from keyless to receipt-gated, one rung at a time, with what each rung does and does not give you. System prompts is the copy-paste text for an agent's own instructions — the rules that make it call preflight_change_set before it mutates a contract, rather than after.

Questions with exact commands

Every command below was run on 2026-09-23. Each REST call is POST-only unless the row says otherwise — a GET on these paths answers 404, which is correct routing and not an outage.

How do I run this in CI?

One step and one secret. Add CODERIFTS_API_KEY as a repository secret (app.coderifts.com/api/signup), then:

- uses: actions/checkout@v4
- uses: coderifts/action@v1
  with:
    api-key: ${{ secrets.CODERIFTS_API_KEY }}
    fail-on-breaking: true

This reports: it fails the CI job, and a failing job is not a merge gate until you make that check required on the branch. It trusts the API response and does not verify a signed receipt. For a required-check merge gate with offline receipt verification, use the GitHub App and the CLI gates — one path per goal.

How do I install this into Claude Code?

Two routes. The MCP server alone, which reports:

claude mcp add --transport http coderifts https://app.coderifts.com/mcp

Or the plugin, which adds the PreToolUse hook — the one surface on this list that refuses a tool call rather than describing it:

claude plugin marketplace add coderifts/api-governance
claude plugin install agent-hooks@coderifts
claude plugin list          # agent-hooks@coderifts 0.2.0, enabled

The hook fires only when the tool call’s target path matches a contract-file pattern. A call touching anything else never leaves your machine.

What happens if I act without a grant?

Nothing stops you from this server — that is the honest answer, and it is why the hook and the customer-hosted verifiers exist. What you get instead is a refusal to pretend. analyze mode returns authorization_effect: "NONE", may_execute: false and receipt_kind: "NONE"; there is no execution_action to branch on, because analysis is not permission. Calling authorize without an API key answers authorization_requires_issuer: no key, no issuer, no grant. Downstream, a verifier that is handed no receipt denies with receipt_missing — absence is a deny, not a pass.

How do I check a receipt offline?

No account, no call to us. Clone the verifier and run it against the token:

git clone -q --depth 1 https://github.com/coderifts/receipt-verifier
node receipt-verifier/cli.js "$(cat receipt.txt)"

It prints valid and a status. VERIFIED_CURRENT means the signature verifies against the verifier’s pinned key snapshot — it does not mean the receipt authorizes anything now. See a valid signature is not authorization.

What does this NOT gate?

MCP tools report; they do not prevent a call by themselves. This server issues a decision and a grant; it executes nothing and refuses nothing. Nothing here touches a Kubernetes admit, an API gateway request path, a tool registry, or a merge — those are target-side, and two of them ship as separate customer-hosted verifiers you run yourself. See when not to use this for the three cases the published does_not_prove list rules out entirely, and what each path does for the per-surface answer.

How do I remove it?

Delete the server entry from your MCP client config — there is no local agent and no background process, so nothing else remains. For the Claude Code plugin, claude plugin uninstall agent-hooks@coderifts (or remove the hook entry from .claude/settings.json if you wired it by hand). For CI, delete the step and the secret. Per-path detail, including what each one reads and what leaves your machine: per-path credentials. What we store and for how long: data retention.