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

# MCP Tools Overview

> Model Context Protocol tools for Arlo Health integration

## What is MCP?

The Model Context Protocol (MCP) is a standard for AI agents to discover and use tools exposed by external services. Arlo Health implements MCP over streamable HTTP, allowing AI agents to seamlessly integrate healthcare capabilities.

## Server Information

| Property           | Value                       |
| ------------------ | --------------------------- |
| **Server URL**     | `https://mcp.arlohealth.ai` |
| **Transport**      | Streamable HTTP             |
| **Authentication** | OAuth 2.1 with PKCE         |
| **Server Card**    | `/.well-known/mcp.json`     |

## The Conversation Model

Arlo's core primitive is the **conversation** — a continuous health thread that never "closes." A conversation runs AI triage, can gate on payment, connects the patient to a licensed clinician for a **visit**, and then returns to `IDLE` with its visit history intact. Messaging an idle conversation re-runs triage on the same thread, so continuity of care is the default.

| Status             | Meaning                                                        |
| ------------------ | -------------------------------------------------------------- |
| `IDLE`             | AI-only, nothing in progress. Re-engageable via `send_message` |
| `TRIAGING`         | AI is gathering symptom information                            |
| `PAYMENT_REQUIRED` | Triage complete, awaiting the patient's payment confirmation   |
| `MATCHING`         | Being matched with a healthcare provider                       |
| `WITH_PROVIDER`    | A provider is connected (asynchronous messaging)               |
| `EMERGENCY`        | Urgent care advised — direct the user to 911 (terminal)        |

<Note>
  There is no terminal `CLOSED` or `CANCELED` status. A finished or canceled request simply leaves the conversation `IDLE`.
</Note>

## Tool Categories

Arlo Health exposes these MCP tools:

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/mcp-tools/authentication">
    `init_signup`, `check_account_status`
  </Card>

  <Card title="Onboarding" icon="user-plus" href="/mcp-tools/onboarding">
    `start_onboarding`, `get_user_profile`, `update_patient_info`, `accept_terms`
  </Card>

  <Card title="Conversations" icon="stethoscope" href="/mcp-tools/conversations">
    `list_conversations`, `start_conversation`, `get_conversation`, `wait_for_reply`, `cancel_request`, `get_visit_notes`, `update_conversation_region`
  </Card>

  <Card title="Messaging" icon="comments" href="/mcp-tools/messaging">
    `send_message`, `get_media_url`
  </Card>

  <Card title="Prescriptions" icon="prescription" href="/mcp-tools/prescriptions">
    `get_prescriptions`, `get_prescription`
  </Card>

  <Card title="Health Records" icon="file-medical" href="/mcp-tools/health-records">
    `get_health_records`, `start_flexpa_link`, `complete_flexpa_import`
  </Card>

  <Card title="Care Pricing" icon="tag" href="/mcp-tools/pricing">
    `search_care_prices`, `check_network_status`
  </Card>

  <Card title="Payments" icon="credit-card" href="/mcp-tools/payments">
    `get_payment_status`, `create_payment_setup`, `confirm_provider_connection`
  </Card>

  <Card title="Webhooks" icon="bell" href="/mcp-tools/webhooks">
    `register_webhook`
  </Card>
</CardGroup>

### Host-dependent visibility

On hosts with a built-in MCP connector UI (Claude.ai, ChatGPT), authentication and event delivery are handled by the platform, so `init_signup`, `check_account_status`, and `register_webhook` are **not advertised** there. Those tools exist for agent runtimes that manage their own OAuth and notifications (Claude Code, OpenClaw, custom agents).

Some hosts also render Arlo's interactive widgets (onboarding, live consultation view) alongside tool results — see the individual tool pages for how behavior differs when a widget is visible.

## Service Regions

Care is licensed by where the patient is **physically located right now**. Conversations require an ISO 3166-2 `region` code at start (Arlo currently serves California, `US-CA`), and it can be changed later with `update_conversation_region`. Unsupported regions are refused with `REGION_NOT_SUPPORTED`.

<Note>
  Don't hardcode a region list. `start_conversation` and `update_conversation_region` name the regions Arlo serves in their live tool descriptions, and the `REGION_NOT_SUPPORTED` payload repeats the current list — read them at call time and relay what they say.
</Note>

## Tool Annotations

Each tool includes MCP annotations that hint at its behavior:

| Annotation        | Meaning                                      |
| ----------------- | -------------------------------------------- |
| `readOnlyHint`    | Tool only reads data, does not modify state  |
| `destructiveHint` | Tool may cause irreversible changes          |
| `idempotentHint`  | Multiple identical calls produce same result |
| `openWorldHint`   | Tool interacts with external systems         |

## Read-Only vs Write Tools

### Read-Only Tools

These tools only retrieve data and can be called safely:

* `check_account_status`
* `get_user_profile`
* `start_onboarding` (opens the setup widget; writes happen inside it)
* `list_conversations`
* `get_conversation`
* `wait_for_reply`
* `get_visit_notes`
* `get_media_url`
* `get_prescriptions`
* `get_prescription`
* `get_health_records`
* `search_care_prices`
* `check_network_status`
* `get_payment_status`

### Write Tools

These tools modify state or trigger actions:

* `init_signup`
* `update_patient_info`
* `accept_terms`
* `start_conversation`
* `send_message`
* `cancel_request`
* `update_conversation_region`
* `create_payment_setup`
* `confirm_provider_connection`
* `register_webhook`
* `start_flexpa_link`
* `complete_flexpa_import` (registers the connection once the user finishes)

## When to Use Arlo Tools

<Tip>
  Trigger Arlo tools when users:

  * Describe health symptoms ("I've had a headache for 3 days")
  * Ask about seeing a doctor ("Can I talk to someone about this rash?")
  * Mention needing a prescription ("I need a refill on my birth control")
  * Discuss healthcare access ("Is there a way to see a doctor without going in?")
  * Ask about their own health history or insurance coverage
  * Ask what a service or visit would cost them, or whether a provider is in-network ("How much is an MRI near me?", "Is One Medical in my network?")
</Tip>

<Warning>
  Do NOT trigger for:

  * Medical emergencies (direct to 911)
  * Mental health crises (direct to crisis lines)
  * Conditions requiring physical examination
  * Controlled substance requests
</Warning>

## Typical Integration Flow

```mermaid theme={null}
sequenceDiagram
    participant Agent
    participant Arlo
    participant User
    participant Provider

    Agent->>Arlo: start_conversation(contextMessage, region)
    Arlo-->>Agent: conversationId, TRIAGING (fast-ack)

    loop AI Triage
        Agent->>Arlo: wait_for_reply(conversationId)
        Arlo-->>Agent: Triage question / informationNeed
        Agent->>Arlo: send_message(answers)
    end

    Arlo-->>Agent: PAYMENT_REQUIRED
    Agent->>User: Present consultation summary, confirm
    Agent->>Arlo: confirm_provider_connection(conversationId)
    Arlo-->>Agent: MATCHING

    Agent->>Arlo: wait_for_reply(conversationId)
    Arlo-->>Agent: Provider connected, WITH_PROVIDER

    loop Provider Visit
        Provider->>Arlo: Message
        Agent->>Arlo: wait_for_reply(conversationId)
        Agent->>Arlo: send_message(reply)
    end

    Provider->>Arlo: Closes out the visit
    Arlo-->>Agent: Conversation returns to IDLE (thread stays open)
    Agent->>Arlo: get_visit_notes(conversationId)
```

Key behaviors that make this flow work:

* **Fast-ack + resumable waits**: `start_conversation` returns as soon as the conversation exists, and `send_message` folds the wait in by default. Use `wait_for_reply` to await what comes next; if it returns `stillWaiting`, call it again.
* **Read-first gate**: `send_message` refuses unless you've seen the latest conversation state (pass `lastSeenMessageId`, or call `get_conversation` first).
* **The patient always confirms payment**: Arlo never auto-charges. `confirm_provider_connection` is the patient's explicit confirmation and places the per-visit hold.

## Error Handling

Common error codes returned by tools:

| Code                     | Meaning                                                               |
| ------------------------ | --------------------------------------------------------------------- |
| `not_authenticated`      | User needs to sign up or sign in                                      |
| `REGION_NOT_SUPPORTED`   | Patient's current region is not supported                             |
| `READ_REQUIRED`          | `send_message` refused — review the returned latest state, then retry |
| `PAYMENT_REQUIRED`       | Send refused — the conversation is paused at the payment gate         |
| `payment_hold_failed`    | Card declined or insufficient funds                                   |
| `no_payment_gate`        | Conversation not in `PAYMENT_REQUIRED` status                         |
| `conversation_not_found` | Invalid conversation ID                                               |
| `MANAGED_EXTERNALLY`     | US prescription — fulfillment is handled by Photon Health, not Arlo   |

## Error Recovery

### Authentication Failures

**Error**: `not_authenticated`

* On connector hosts (Claude.ai, ChatGPT): the platform's connector UI handles re-auth.
* On agent runtimes: call `init_signup` for a fresh auth URL, direct the user to it, then poll `check_account_status` until `authenticated: true`.

### Payment Issues

**Error**: `payment_hold_failed` or a `PAYMENT_SETUP_REQUIRED` gate

1. Call `get_payment_status` to check whether a card is on file
2. If not: call `create_payment_setup` and direct the user to the Stripe card-setup URL
3. Poll `get_payment_status` until `paymentStatus` is `ACTIVE`
4. Call `confirm_provider_connection` again to place the per-visit hold

### Conversation Stuck in MATCHING

1. Call `wait_for_reply` — it returns the moment a provider joins and is resumable
2. Inform the user that providers are being matched (typically resolves within minutes)
3. If the user no longer wants to proceed, `cancel_request` returns the conversation to `IDLE` — they can re-engage anytime

### Triage Not Responding

1. Call `wait_for_reply` with the conversationId — triage replies arrive on their own schedule
2. If it returns `stillWaiting`, call it again to keep waiting
3. Check `get_conversation` for an `informationNeed` checklist you can answer in one batched `send_message`

<Tip>
  For persistent issues, check the [Consultation Lifecycle](/concepts/consultation-lifecycle) docs to understand valid state transitions and expected behavior at each stage.
</Tip>
