> ## Documentation Index
> Fetch the complete documentation index at: https://docs.waniwani.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Insurance quote

> Build an insurance quote MCP: collect pet/vehicle/home details, validate, call your pricing API, return a quote with widget cards.

This page shows you how to **build an insurance quote MCP** with `@waniwani/sdk`. The funnel collects what you need, validates it server-side, calls your pricing API, and shows the user a quote, all as one MCP tool inside ChatGPT, Claude, or any MCP client.

## Production example

The most complete example in the docs is the **[Pet Insurance Quote flow](/sdk/guides/pet-insurance)**. It demonstrates every pattern an insurance quote funnel needs:

* **Open-ended extraction.** One question pulls 5+ fields out of free-form text.
* **Conversational follow-ups.** Ask the rest 1-2 at a time, not as a form.
* **Async validation.** Breed and location validated against your API before quoting.
* **Conditional branching.** Different paths for mixed breeds, indoor cats, etc.
* **Confirmation widget.** Show a summary card, let the user correct anything.
* **Correction loop.** Corrections re-validate and re-display until the user confirms.
* **Pricing widget.** Call the pricing API, render a grid of plan cards.
* **Adjustment loop.** User tweaks deductible/copay, recalculate, re-render.
* **Compliance rules in the description.** Embedded "no recommendation" guardrails.

Open [the Pet Insurance Quote example](/sdk/guides/pet-insurance) for the full \~250-line code.

## Why an MCP funnel beats a quote form

* **The AI asks naturally.** Users say "I have a 2-year-old Golden Retriever named Max, he's neutered" and the flow extracts 5 fields in one turn. A form would ask each separately.
* **No leaving the conversation.** Users get quotes inside ChatGPT or Claude. No tab switch, no friction.
* **Compliance lives in the tool description.** Insurance, finance, and healthcare can encode "no recommendation" rules where the model always reads them.
* **Branching is trivial.** Mixed breed? Indoor cat? Conditional edges, not nested form fields.

## Skeleton for any quote vertical

The pet insurance flow's shape works for **vehicle insurance**, **home insurance**, **business insurance**, and any vertical with the same shape: collect details, validate, quote, adjust.

```ts theme={null}
import { createFlow, START, END } from "@waniwani/sdk/mcp";
import { z } from "zod";

export const quoteFunnel = createFlow({
  id: "vehicle_insurance_quote",
  title: "Vehicle Insurance Quote",
  description: "Use when a user wants a price quote for vehicle insurance.",
  state: {
    // Fields the user provides
    make: z.string().describe("Vehicle make"),
    model: z.string().describe("Vehicle model"),
    year: z.number().describe("Vehicle year"),
    postcode: z.string().describe("Owner postcode"),
    // Resolved by validation
    vehicleId: z.string().describe("Resolved vehicle ID from your DB"),
    // Confirmation state
    confirmed: z.boolean().describe("User confirmed the details"),
    // Quote state
    quoteId: z.string().describe("Quote ID returned by pricing API"),
    deductible: z.number().optional().describe("Chosen deductible"),
    pricingAction: z.enum(["adjust", "done"]).describe("Adjust loop control"),
  },
})
  .addNode({
    id: "ask_vehicle",
    label: "Ask about vehicle",
    run: ({ interrupt }) =>
      interrupt({
        make: {
          question: "Tell me about your vehicle: make, model, year, and your postcode.",
          context: "Extract make, model, year, and postcode from the user's response.",
        },
      }),
  })
  .addNode({
    id: "validate",
    label: "Validate vehicle + postcode",
    hideFromFunnel: true,
    run: async ({ state }) => {
      // your validation API call
      return { vehicleId: "..." };
    },
  })
  .addNode({
    id: "show_confirmation",
    label: "Confirm details",
    run: ({ state, showWidget }) => {
      // see Pet Insurance Quote example for the showWidget pattern
      return showWidget(/* ... */);
    },
  })
  .addNode({
    id: "show_pricing",
    label: "Show pricing",
    run: async ({ state, showWidget }) => {
      // call pricing API, render widget
      return { quoteId: "...", /* ... */ };
    },
  })
  // ... edges and adjustment loop
  .compile();
```

See the [full Pet Insurance Quote code](/sdk/guides/pet-insurance) for working versions of `show_confirmation`, `show_pricing`, the correction loop, and the adjustment loop.

## Add funnel analytics

Set `WANIWANI_API_KEY` to track step-by-step drop-off across your quote funnel: `ask_vehicle → validate → show_confirmation → show_pricing`. The dashboard shows you where users abandon, typically at confirmation or at the price reveal. See [Tracking / Overview](/sdk/tracking/overview).

## Next

<CardGroup cols={2}>
  <Card title="Pet Insurance Quote (full example)" icon="shield" href="/sdk/guides/pet-insurance" />

  <Card title="Widgets in flows" icon="window-maximize" href="/sdk/guides/pet-insurance" />

  <Card title="Build a booking MCP app" icon="calendar" href="/sdk/guides/booking" />

  <Card title="Build a sales funnel MCP" icon="filter" href="/sdk/guides/sales-funnel" />
</CardGroup>
