Skip to main content
MCP Gateway Spec · v0.1 · draft

MCP Gateway Spec — Formal Specification, v0.1

A governed surface for insurance agents acting across one or more carrier-core systems. Defines eight primary operations, five IR primitives, an audit-trail record, and a multi-carrier composition protocol. The gateway is the control plane; inference advises.

1. Status

v0.1 — draft. Spec text is CC-BY-4.0. Reference code is Apache-2.0.

v1.0 ships when at least one carrier-core adapter and one MGA-side client implement five of the eight primary operations against pinned IR with signed audit and pass the conformance fixtures.

2. Conformance

A gateway is conformant with v0.1 if and only if it satisfies all of the following:

  • Implements at least five of the eight primary operations in §3.
  • Emits a signed audit-trail record (§5) for every operation, with joules populated for every model call.
  • Supports IR pinning at session start; refuses operations whose pinned IR has been rotated.
  • Implements decision.replay for any prior trace it issued.
  • Exposes prepare / commit / abort if it participates in multi-carrier composition (§6); otherwise declares saga_only.
  • Treats inference as advisory: no operation's outcome is determined by a model call alone.

3. Operations — formal signatures

carrier.compose.atomic

(steps: Step[]) → ComposedTrace

All-or-nothing across N carrier gateways. 2PC where every target declares it; saga otherwise with compensation functions. The trace contains per-carrier sub-traces.

ir.pin

(contract_id: URI, version: semver) → SessionPin

Binds a session to a specific IR version. Pins recorded in audit-trail ir_pins[]. Drift on either side terminates the session.

decision.replay

(trace_id: UUID) → ReplayedDecision

Re-runs the prior decision against the pinned IR. Output: byte-identical decision + drift report if any pinned IR has changed.

appetite.match

(risk_ir: SubmissionIR) → MatchResult[]

Queries the appetite-IR registry. Each result carries { carrier, program, confidence, basis }. Inference fallback only when explicitly authorized by the session.

form.assemble

(coverage_form_ir: URI, schedule: Schedule) → PolicyForm

Deterministically assembles a policy form from coverage-form-IR + schedule. Free-generation is not permitted.

rate.diff

(plan_v1: URI, plan_v2: URI) → FilingDelta

Filing-grade structural diff: factor changes, territory updates, ILF deltas, base-rate moves, with per-state regulatory-impact flags.

claim_event.append

(claim_id: UUID, event_ir: ClaimEventIR) → AppendReceipt

Append-only Merkle ledger. Receipt includes prev-event hash, ledger position, signature.

hitl.require

(op: OperationRef, threshold_policy_id: URI) → HITLAttachment

Attaches a human-approval gate to an operation. Threshold policies are versioned; approvals are signed and replayable.

4. IR primitive schemas

All five IR primitives are semver-versioned and content-addressed. Pinned at session start.

rate-plan-IR

rate-plan-IR:
  id: string
  version: semver
  content_hash: blake3
  effective_dates_by_state: { state: { from, to? } }
  filing_ids: [ string ]
  prior_version: ref?
  base_rates: { lob, territory_code, value }
  factors:        [ { name, classes, values } ]
  territory_tables: { state: { code → name } }
  ilfs:           [ { layer, factor } ]
  min_premium:    by_state_lob
  max_premium:    by_state_lob

coverage-form-IR

coverage-form-IR:
  id: string
  version: semver
  content_hash: blake3
  iso_aais_ref: { source: enum[ISO|AAIS|carrier], code, edition }
  coverage_parts:    [ { id, name, limits[], deductibles[] } ]
  exclusions:        [ { id, text, scope } ]
  conditions:        [ { id, text } ]
  definitions:       [ { term, text } ]
  endorsements:      [ { id, name, modifies[], schedule_binding } ]
  schedule_binding_rules: [ rule ]

claim-event-IR

claim-event-IR:
  claim_id: string
  event_id: string
  event_type: enum[fnol|reserve_change|payment|subro_open|subro_recovery|close|reopen]
  ts: timestamp
  actor: { principal_id, role }
  monetary_delta: { amount, currency, ledger_account }
  reserve_delta:  { amount, line, period }
  document_refs:  [ doc_hash ]
  prev_event_hash: bytes32     # Merkle chain
  signature:       bytes

appetite-IR

appetite-IR:
  id: string
  version: semver
  class_codes:    { naics?, sic?, iso_gl? }
  states_in:      [ state ]
  states_out:     [ state ]
  hazard_limits:  { hazard_code → cap }
  premium_bounds: { min, max }
  expiring_carrier_rules: [ predicate ]
  exception_predicates:   [ { predicate, reason_code } ]

submission-IR

submission-IR:
  acord_form_ref: { form_id, edition }
  fields: { name: { value, source, confidence, provenance_uri } }
  required_field_table: by_carrier
  attachments: [ { kind, ref, doc_hash } ]
  signature: bytes

5. Audit trail — JSON Schema

One signed record per operation. Records are append-only; prev_event_hash chains the log into a Merkle structure.

{
  "trace_id": "uuid",
  "parent_trace_id": "uuid?",
  "ts_start": "rfc3339",
  "ts_end":   "rfc3339",
  "actor": {
    "principal_id": "did|opaque",
    "role": "string",
    "on_behalf_of": "principal_id?"
  },
  "operation": { "name": "string", "version": "semver" },
  "ir_pins": [
    { "kind": "rate-plan-IR|coverage-form-IR|claim-event-IR|appetite-IR|submission-IR",
      "id": "uri", "version": "semver", "hash": "bytes32" }
  ],
  "inputs": {
    "schema_version": "semver",
    "hash": "bytes32",
    "redacted_payload_ref": "uri"
  },
  "rule_evaluations": [
    { "rule_id": "string", "version": "semver",
      "result": "passed|failed|n/a", "basis": "string" }
  ],
  "model_calls": [
    { "provider": "string", "model_id": "string",
      "prompt_hash": "bytes32", "response_hash": "bytes32",
      "tokens": "int", "joules": "float" }
  ],
  "decision": {
    "outcome": "string",
    "confidence": "float",
    "basis": "deterministic | inference | hybrid"
  },
  "hitl": {
    "required": "bool",
    "approver": "principal_id?",
    "approval_ts": "rfc3339?",
    "policy_id": "string",
    "policy_version": "semver"
  },
  "outputs": {
    "schema_version": "semver",
    "hash": "bytes32",
    "artifact_refs": [ "uri" ]
  },
  "prev_event_hash": "bytes32",
  "signature": "bytes"
}

6. Multi-carrier composition

The composition session is server-side state: pinned IR set, target carrier-gateway list, 2PC coordinator, compensation registry.

Each participating carrier MCP gateway implements:

  • prepare(op: Operation) → reservation_id — validates and holds resources without committing.
  • commit(reservation_id) — finalizes.
  • abort(reservation_id) — releases.

Gateways that cannot implement 2PC declare saga_only; the coordinator falls back to a saga with the compensation function declared per operation. Idempotency keys per step are required.

Output: one ComposedTrace with per-carrier sub-traces and (if applicable) an applied-compensations log.

7. Joule metering

Every model_calls[] entry in the audit trail carries a joules field measured by the gateway's runtime. Composed traces aggregate per-operation joules. This is the unit of cost.

8. Versioning

The gateway spec is semver-versioned. IR primitives are independently semver-versioned and content-addressed. Audit-trail records carry both the operation version and the IR pin versions, so future readers can resolve every artifact deterministically.

9. Security

The gateway composes proven primitives. mTLS between agent and gateway. Capability tokens for operation scope. DID-based signing on audit records. Merkle-chained audit log. Content-addressed IR.

Detailed engineering reference: implementation notes ship in the reference repository under SECURITY.md.