> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.truvo.com/llms.txt.

# MCP tools

The Truvo MCP server at `https://api.truvo.com/v1/mcp` lists these tools. [Agent setup](/guides/agent-setup) shows how to connect a client.

The tools a caller sees depend on how it connects:

* **Partner key:** your server key. It reads its quote requests by ID.
* **Platform key:** a key that Truvo issues to an AI platform. Each quote request it starts returns a `read_handle`, and only that handle reads the request. See [Read handles](/guides/agent-setup#read-handles).
* **Keyless:** an assistant that calls without a key. It reads by handle too, and sends the person's agreement to Truvo's quote disclosure in place of the consent receipts. See [Calls without a key](/guides/agent-setup#calls-without-a-key).

Each description below is the one that a partner key reads. A platform key and a keyless caller read a version with their own steps for read handles and the quote disclosure.

A tool returns its answer in `structuredContent`, with the same fields as the answer of its HTTP route unless the tool says otherwise. The text content holds a short summary for the model, then the same JSON. A refused call returns `isError: true` and the error envelope that HTTP returns. [Errors](/guides/errors) lists the codes.

## get\_capabilities

Shows what this key can quote for one line: the states, the facts a quote request needs, and the actions a quote can offer. Its required\_facts\_schema is the JSON Schema of the application for start\_quote\_request. Call it before you ask the person for facts. It only reads and starts no quote.

* **Title:** Get insurance capabilities
* **Callers:** partner key, platform key, and keyless
* **Hints:** `readOnlyHint: true`, `destructiveHint: false`
* **Result:** `capabilities`, with the line when the key can quote it: its states, its required facts and their JSON Schema, and the actions a quote can offer. A keyless caller also gets Truvo's quote disclosure in `quote_disclosure`.
* **HTTP:** [`GET /v1/capabilities`](/api-reference/get-capabilities)

| Field  | Type   | Required | Description                                                      |
| ------ | ------ | -------- | ---------------------------------------------------------------- |
| `line` | string | Yes      | The insurance line. One of `personal_auto`, `renters`, or `pet`. |

## start\_quote\_request

Starts one quote request for one person and one line. It returns at once with the request in\_progress, and carriers answer in the background. Follow the request with get\_quote\_request. Send only facts the person gave you. Put them in application, in the shape of the required\_facts\_schema that get\_capabilities gives for the line. If a required fact is missing, the answer is a needs\_information error that lists each missing field. Ask the person, then send the request again. consent\_receipt\_id is required: the ID of the person's consent for Truvo to get quotes for them. It covers quoting only. For auto only, send credit\_disclosure\_receipt\_id when the person agreed to a credit check. Renters and pet requests do not use it. Set a contact channel to true only when contact\_consent, the person's own record of consent to be contacted, lists that channel in its channels. Each receipt covers one consent. Never send one receipt ID in two fields, and never make a receipt up. request\_key is your own ID for this request. The same key with the same input returns the same request, so a retry never starts a second one. A key that already started a request cannot take different input, so use a new key for a new request. Leave out scenario unless the person or developer asks to test a named sandbox outcome, and never send it on a first quote. The line's default scenario prices whatever pets, drivers, or vehicles you send.

* **Title:** Request insurance quotes
* **Callers:** partner key, platform key, and keyless
* **Hints:** `readOnlyHint: false`, `destructiveHint: false`
* **Result:** The quote request, with the status `in_progress`. With a platform key or keyless, it also holds `read_handle` and `read_handle_expires_at`. Keyless, it also holds `quote_consent`, the receipt that Truvo recorded.
* **HTTP:** [`POST /v1/quote-requests`](/api-reference/start-quote-request)

| Field                          | Type    | Required | Description                                                                                                                                                      |
| ------------------------------ | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `line`                         | string  | Yes      | The insurance line. One of `personal_auto`, `renters`, or `pet`.                                                                                                 |
| `consent_receipt_id`           | string  | Yes      | Partner key and platform key only. The ID of the person's consent for Truvo to get quotes for them.                                                              |
| `credit_disclosure_receipt_id` | string  | No       | Partner key and platform key only. For auto, the ID of the person's agreement to a credit check.                                                                 |
| `contact_consent`              | object  | No       | Partner key and platform key only. The person's record of consent to be contacted: its `receipt_id` and the `channels` it covers.                                |
| `contact_channels`             | object  | No       | Partner key and platform key only. The `email`, `sms`, and `phone` channels, each `true` or `false`. Set a channel to `true` only if `contact_consent` lists it. |
| `scenario`                     | string  | No       | Sandbox only. The scenario that decides the outcome. Leave it out unless you test a named outcome.                                                               |
| `request_key`                  | string  | Yes      | Your own ID for this request. Send a new random UUID for each new request, and the same value to retry it.                                                       |
| `application`                  | object  | Yes      | The person's facts, in the shape of the line's `required_facts_schema` from `get_capabilities`.                                                                  |
| `quote_disclosure_version`     | string  | Yes      | Keyless only. The version of the quote disclosure from `get_capabilities` that the person agreed to.                                                             |
| `quote_disclosure_accepted`    | boolean | Yes      | Keyless only. `true` once the person agrees to the quote disclosure.                                                                                             |

## get\_quote\_request

Reads a quote request: its status, the terms and next actions of each quote, and the result from each carrier. It starts no new quote. While the request is in\_progress, the answer waits for the request to change: a new quote or a new status. wait\_seconds, from 0 to 20, is the longest it waits, and 20 when you leave it out. Send since\_version with the version from your last answer, so a change since then answers at once. The status is in\_progress, action\_required, completed, or failed: branch on it. status\_details.message says why, in words you can show the person. New status\_details.reason values can arrive, so don't rely on the reason alone. A failed request says what to do next. A completed request can hold no quotes, and a carrier can decline or give no answer. Report each result as it is. Each quote's price.premium is in US cents (amount\_minor) and is the price for the whole term in term\_months. The billing cycle does not change that: a quote billed monthly still gives the premium for the whole term. On a renters quote, the premium already includes every fee in price.fees. On other lines, the quote doesn't say whether it does.

* **Title:** Get a quote request
* **Callers:** partner key, platform key, and keyless
* **Hints:** `readOnlyHint: true`, `destructiveHint: false`
* **Result:** `quote_request`, the quote request as HTTP returns it, and `quotes`, each of its quotes in full.
* **HTTP:** [`GET /v1/quote-requests/{id}`](/api-reference/get-quote-request)

| Field           | Type             | Required | Description                                                                                           |
| --------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `id`            | string           | Yes      | The quote request ID, which starts with `qreq_`.                                                      |
| `wait_seconds`  | integer, 0 to 20 | No       | The longest the read waits for a change, in seconds. 20 when you leave it out.                        |
| `since_version` | integer          | No       | The `version` from your last answer, so a newer version answers at once.                              |
| `read_handle`   | string           | Yes      | Platform key and keyless only. The `read_handle` that `start_quote_request` returned for the request. |

## list\_quote\_requests

Lists the quote requests of this key, newest first, one page at a time. It starts no new quote. Filter by status, line, created\_after, created\_before, or updated\_since. A time is RFC 3339 with an offset. limit is from 1 to 100, and 10 when you leave it out. For the next page, send the same filters with the next\_cursor of the page before. updated\_since returns each request that changed at or after that time.

* **Title:** List quote requests
* **Callers:** partner key
* **Hints:** `readOnlyHint: true`, `destructiveHint: false`
* **Result:** One page of quote requests, newest first, and the `next_cursor` of the next page.
* **HTTP:** [`GET /v1/quote-requests`](/api-reference/list-quote-requests)

| Field            | Type              | Required | Description                                                                                            |
| ---------------- | ----------------- | -------- | ------------------------------------------------------------------------------------------------------ |
| `limit`          | integer, 1 to 100 | No       | The most quote requests on one page. 10 when you leave it out.                                         |
| `cursor`         | string            | No       | The `next_cursor` of the page before. Send the same filters with it.                                   |
| `status`         | string            | No       | Only quote requests in this status. One of `in_progress`, `action_required`, `completed`, or `failed`. |
| `line`           | string            | No       | Only quote requests for this line. One of `personal_auto`, `renters`, or `pet`.                        |
| `created_after`  | string            | No       | Only quote requests created after this time. An RFC 3339 time with an offset.                          |
| `created_before` | string            | No       | Only quote requests created before this time. An RFC 3339 time with an offset.                         |
| `updated_since`  | string            | No       | Only quote requests that changed at or after this time. An RFC 3339 time with an offset.               |

## get\_quote

Reads one quote: its status, the carrier, the price, the coverage, how long the quote stays available, the assumptions it used, and the next actions it supports. The status is active or inactive, and status\_details.message says why. Leave out version to read the latest version. It starts no new quote. Each quote's price.premium is in US cents (amount\_minor) and is the price for the whole term in term\_months. The billing cycle does not change that: a quote billed monthly still gives the premium for the whole term. On a renters quote, the premium already includes every fee in price.fees. On other lines, the quote doesn't say whether it does.

* **Title:** Get quote details
* **Callers:** partner key, platform key, and keyless
* **Hints:** `readOnlyHint: true`, `destructiveHint: false`
* **Result:** The quote version: its status, carrier, price, coverage, availability, assumptions, and next actions.
* **HTTP:** [`GET /v1/quotes/{id}`](/api-reference/get-quote)

| Field         | Type    | Required | Description                                                                                           |
| ------------- | ------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `id`          | string  | Yes      | The quote ID, which starts with `qt_`.                                                                |
| `version`     | integer | No       | The quote version. Leave it out to read the latest.                                                   |
| `read_handle` | string  | Yes      | Platform key and keyless only. The `read_handle` that `start_quote_request` returned for the request. |

## send\_feedback

Tells Truvo about a problem with this API or its tools: a missing feature, a bug, an unclear error, or unclear docs. Say what you expected and what happened instead. If you have them, name the tool you called and the request\_id of each error. Leave out personal data: a report that looks like it holds a Social Security, driver's license, or card number is refused. A report changes no quote.

* **Title:** Send feedback about this API
* **Callers:** partner key, platform key, and keyless
* **Listed:** only while Truvo accepts feedback
* **Hints:** `readOnlyHint: false`, `destructiveHint: false`
* **Result:** The report, with its `feedback_id` and the status `received`.
* **HTTP:** [`POST /v1/feedback`](/api-reference/send-feedback)

| Field      | Type                           | Required | Description                                                                                             |
| ---------- | ------------------------------ | -------- | ------------------------------------------------------------------------------------------------------- |
| `kind`     | string                         | Yes      | What the report is about. One of `missing_feature`, `bug`, `unclear_error`, `unclear_docs`, or `other`. |
| `summary`  | string, up to 200 characters   | Yes      | One line that says what went wrong or what's missing.                                                   |
| `expected` | string, up to 2,000 characters | Yes      | What you expected to happen.                                                                            |
| `actual`   | string, up to 2,000 characters | Yes      | What happened instead.                                                                                  |
| `tried`    | object                         | No       | The `operation` or tool you called, and the `request_ids` of up to 20 calls that show the problem.      |
| `agent`    | object                         | No       | Your agent's `name` and `version`.                                                                      |

## list\_api\_requests

Lists the recent requests of this key's organization, newest first: the time, the operation, the status, the error code, the request ID, the quote request ID, and the agent that sent it. Filter by status, error\_code, operation, or since, and pass next\_cursor as cursor to read the next page. Truvo keeps each request for 30 days and never keeps its body. It only reads.

* **Title:** List recent requests
* **Callers:** partner key
* **Listed:** only while Truvo has the request log turned on
* **Hints:** `readOnlyHint: true`, `destructiveHint: false`
* **Result:** One page of requests, newest first, and the `next_cursor` of the next page.
* **HTTP:** [`GET /v1/requests`](/api-reference/list-api-requests)

| Field        | Type                | Required | Description                                                                |
| ------------ | ------------------- | -------- | -------------------------------------------------------------------------- |
| `limit`      | integer, 1 to 100   | No       | The most requests on one page. 10 when you leave it out.                   |
| `cursor`     | string              | No       | The `next_cursor` of the page before. Send the same filters with it.       |
| `status`     | integer, 100 to 599 | No       | Only requests that got this HTTP status, such as `422`.                    |
| `operation`  | string              | No       | Only requests for this operation, such as `start_quote_request`.           |
| `error_code` | string              | No       | Only requests that answered this error code, such as `needs_information`.  |
| `since`      | string              | No       | Only requests made at or after this time. An RFC 3339 time with an offset. |

## send\_test\_event

Queues a test event for one of your webhook subscriptions, to check that your endpoint gets it and verifies its signature. Then call get\_event\_delivery to see whether the delivery succeeded. A test can take up to 35 seconds to answer, so set your timeout to 40 seconds or more. The test event has the type webhook.test, names the subscription, and carries no applicant data. It changes no quote. A subscription takes 10 test events a minute. request\_key is your own ID for this test. To retry after an error, send the same key: it queues the same test event.

* **Title:** Send a test event
* **Callers:** partner key
* **Listed:** only while Truvo has webhooks turned on
* **Hints:** `readOnlyHint: false`, `destructiveHint: false`
* **Result:** The subscription ID and the test event that Truvo queued.
* **HTTP:** `POST /v1/event-subscriptions/{id}/test`

| Field             | Type   | Required | Description                                                             |
| ----------------- | ------ | -------- | ----------------------------------------------------------------------- |
| `subscription_id` | string | Yes      | The webhook subscription ID, which starts with `sub_`.                  |
| `request_key`     | string | Yes      | Your own ID for this test. Send the same value to retry after an error. |

## list\_event\_deliveries

Lists the deliveries of one webhook subscription from the last 30 days, newest first: the event ID and type, the status, and the time of the next retry. Call get\_event\_delivery with an event\_id to see its attempts and the HTTP status your endpoint answered. limit is from 1 to 100, and 10 when you leave it out. Pass next\_cursor as cursor to read the next page. It only reads.

* **Title:** List webhook deliveries
* **Callers:** partner key
* **Listed:** only while Truvo has webhooks turned on
* **Hints:** `readOnlyHint: true`, `destructiveHint: false`
* **Result:** One page of deliveries, newest first, and the `next_cursor` of the next page.
* **HTTP:** `GET /v1/event-subscriptions/{id}/deliveries`

| Field             | Type              | Required | Description                                                |
| ----------------- | ----------------- | -------- | ---------------------------------------------------------- |
| `subscription_id` | string            | Yes      | The webhook subscription ID, which starts with `sub_`.     |
| `cursor`          | string            | No       | The `next_cursor` of the page before.                      |
| `limit`           | integer, 1 to 100 | No       | The most deliveries on one page. 10 when you leave it out. |

## get\_event\_delivery

Reads one delivery from a webhook subscription's delivery log: its status, the time of the next retry, and up to 20 attempts, newest first, with the HTTP status your endpoint answered. It only reads.

* **Title:** Get a webhook delivery
* **Callers:** partner key
* **Listed:** only while Truvo has webhooks turned on
* **Hints:** `readOnlyHint: true`, `destructiveHint: false`
* **Result:** The delivery's status, the time of its next retry, and up to 20 attempts with the HTTP status that your endpoint answered.
* **HTTP:** `GET /v1/event-subscriptions/{id}/deliveries/{event_id}`

| Field             | Type   | Required | Description                                            |
| ----------------- | ------ | -------- | ------------------------------------------------------ |
| `subscription_id` | string | Yes      | The webhook subscription ID, which starts with `sub_`. |
| `event_id`        | string | Yes      | The event ID, which starts with `evt_`.                |

## replay\_event\_delivery

Sends one event from a subscription's delivery log again, with the same event ID, so your endpoint can process it after a failure. event\_id must be in the subscription's delivery log from the last 30 days. Each event can be replayed 5 times a day. A replay changes no quote. request\_key is your own ID for this replay. Use a new key for each replay, and the same key to retry after an error.

* **Title:** Replay a webhook delivery
* **Callers:** partner key
* **Listed:** only while Truvo has webhooks turned on
* **Hints:** `readOnlyHint: false`, `destructiveHint: false`
* **Result:** The subscription ID and the ID of the event that Truvo queued again.
* **HTTP:** `POST /v1/event-subscriptions/{id}/replay`

| Field             | Type   | Required | Description                                                                                                |
| ----------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------- |
| `subscription_id` | string | Yes      | The webhook subscription ID, which starts with `sub_`.                                                     |
| `event_id`        | string | Yes      | An event from the subscription's delivery log of the last 30 days.                                         |
| `request_key`     | string | Yes      | Your own ID for this replay. Send a new value for each replay, and the same value to retry after an error. |

## get\_event\_subscription\_health

Shows whether delivery to one webhook subscription works: no\_endpoint, healthy, failing, or disabled, with the newest attempt. failing means the newest attempt failed. disabled means delivery is off: if the subscription reads active, delivery turned off after 5 days of failures, and an update of the subscription turns it back on. A subscription that you disabled stays off; create a new one. no\_endpoint means Truvo has nowhere to deliver the subscription's events; create a new subscription. It only reads.

* **Title:** Get webhook health
* **Callers:** partner key
* **Listed:** only while Truvo has webhooks turned on
* **Hints:** `readOnlyHint: true`, `destructiveHint: false`
* **Result:** The delivery state of the subscription, such as `healthy` or `failing`, and its newest attempt.
* **HTTP:** `GET /v1/event-subscriptions/{id}/health`

| Field             | Type   | Required | Description                                            |
| ----------------- | ------ | -------- | ------------------------------------------------------ |
| `subscription_id` | string | Yes      | The webhook subscription ID, which starts with `sub_`. |