# Arlo Health MCP Server Healthcare infrastructure for AI agents. Everything an agent needs to act in healthcare for its user — licensed clinicians, prescriptions, labs, referrals, and more through one integration. Pay-per-use (current price returned by get_payment_status) on connection to provider. Documents available: /AGENTS.md - agents documentation /openclaw/skill.md - openclaw agent skill documentation ## Integration Options ### MCP Server (Recommended) The canonical, always-current integration — connect over MCP and call the tools directly. Server: https://mcp.arlohealth.ai Auth: OAuth 2.1 with PKCE Discovery: /.well-known/mcp.json **OAuth redirect_uri:** must be a URL your client is actually listening on when the user's browser is redirected back. Cloud/remote agents must use a publicly reachable HTTPS callback — never localhost (that address points at the user's device, not your agent; the sign-in result can never reach you). Invalid redirect_uris are rejected at /oauth/authorize with a 400 JSON error including a hint; unreachable loopback callbacks show the user a guided error page. Self-hosted connection checklist: /AGENTS.md. ### OpenClaw Plugin (Alternative) If using OpenClaw, a convenience plugin wraps the same API: ```bash openclaw plugins install arlo-health ``` Package: https://www.npmjs.com/package/arlo-health ## Conversation Model A conversation is a continuous, never-closing thread that can host multiple provider visits over time. Users can have many conversations open at once. Statuses are phase-derived: IDLE, TRIAGING, PAYMENT_REQUIRED, MATCHING, WITH_PROVIDER, EMERGENCY — there is no terminal CLOSED/CANCELED state. A finished or canceled request just leaves the conversation IDLE and re-engageable. Region is required: care is licensed by the patient's CURRENT physical location (ISO 3166-2), the supported region today is US-CA (California). ## Core Tools start_conversation - Start a BRAND-NEW conversation with first-person symptom narrative; REQUIRES region (patient's current state, e.g. US-CA) send_message - Respond to AI triage questions; returns immediately (does NOT wait) — call wait_for_reply afterward to await the response. Also re-engages an IDLE conversation (re-runs triage on the same thread) wait_for_reply - Await the next reply on a conversation (AI triage reply, a provider connecting, or a provider's message); a single resumable wait you can loop on (re-call while it returns stillWaiting) cancel_request - Cancel the current care request; conversation stays open and returns to IDLE update_conversation_region - Update the patient's region for their NEXT request (not one in flight) start_visit_payment - Get the Stripe link where the patient approves the hold for one visit (charged only after a doctor joins) ## Workflow 1. Gather symptoms conversationally before calling tools 2. Confirm the patient's CURRENT physical region (e.g. US-CA); refused if unsupported (REGION_NOT_SUPPORTED) 3. Call start_conversation with the region and a detailed first-person narrative — or, to continue a previous IDLE conversation, skip this and use send_message on it 4. Respond to AI triage via send_message with natural answers 5. On PAYMENT_REQUIRED (Arlo is pay-per-use and never charges without the patient acting): relay the summary provided, which details if/what our providers will likely be able to help with. Once the user agrees, call start_visit_payment and send them the paymentUrl; they approve a temporary hold on Stripe's page (charged only when a doctor joins, released otherwise). No card-setup step exists. Once approved the conversation moves to MATCHING on its own; await it with wait_for_reply. 6. Provider joins (WITH_PROVIDER); when the visit wraps up the conversation returns to IDLE and can be re-engaged anytime with send_message ## Autonomous Agents (background tasks, loops, cron, webhooks) If you can run work between user turns and receive HTTP callbacks: connect over OAuth (browser needed for login + consent, public HTTPS redirect_uri), call register_webhook once with a public HTTPS URL and a secret you generate, then start or continue care. Use wait_for_reply while you're actively in a turn (4 minutes per call for agent hosts — the ~55s window is a chat-UI limit you aren't held to — resumable, and maxWaitSeconds raises it to 10 minutes); between turns end the turn and let the webhook wake you rather than polling — a provider reply can take hours. On wake you get a consultationId and no clinical content by design; call get_conversation to read what changed. Flows that need a screen are handed back as URLs for your user's browser (start_onboarding → onboardingUrl, start_visit_payment → Stripe paymentUrl, start_flexpa_link → authorizationUrl, create_care_request → approvalUrl). Photos: send them yourself via send_message's media object (base64 media.data, or a public HTTPS media.url Arlo downloads). Send a distinctive clientInfo.name so tool guidance is tailored to an agent host. Full quickstart: /AGENTS.md. ## Webhook Notifications (agents with a public endpoint) Webhooks are ONLY for agents that can expose a public HTTPS endpoint — hosted connector platforms (Claude.ai, ChatGPT) cannot use them and should rely on wait_for_reply (the resumable await), get_conversation polling, and the live consultation widget instead. Register with the register_webhook tool once you're OAuth-authenticated (or pass webhookUrl/webhookToken to init_signup on bot/session auth). Arlo POSTs a minimal notification (no message content) to your URL — the payload carries a machine-routable `event` category (triage_reply, provider_message, provider_joined, payment_gate_open, prescription_added, ...) plus the consultationId; fetch full context from the API on receipt (get_conversation supports a sinceMessageId delta read). Note: webhookToken is not carried over between registrations; omitting it clears the stored secret. See /agents.md for full setup and payload details. **Important:** webhookUrl must be a publicly accessible HTTPS URL. Arlo's servers cannot reach localhost, private IPs, or VPNs. Tailscale Funnel URLs (`.ts.net`) are supported. Arlo verifies connectivity at registration — unreachable URLs are rejected. ## Retrying Safely send_message, start_conversation, start_visit_payment and create_care_request accept an optional idempotency key, best set by your runtime as _meta["arlo.health/idempotencyKey"] on the tool call (agent hosts also get an idempotencyKey argument for runtimes that can't inject _meta; _meta wins). Use one from any loop, cron job, or subagent that might retry after a lost response — a duplicate send_message repeats text in the patient's clinical record, and a duplicate start_visit_payment opens a second checkout session for the same visit. Use a fresh key per intended action and reuse it only for that action's retry; a replay returns the original result (24h) instead of executing again, and failed calls are never cached. ## Tool Summary Authentication: init_signup, check_account_status Profile: get_user_profile (also reports whether insurance records are connected, with per-category record counts), update_patient_info, complete_onboarding, start_onboarding (widget on Claude/ChatGPT; other clients get an onboardingUrl into the patient portal) Health records (US insurance): get_health_records, start_flexpa_link, complete_flexpa_import Conversations: list_conversations, start_conversation, get_conversation, cancel_request, update_conversation_region, get_visit_notes Messaging: send_message, get_media_url Prescriptions: get_prescriptions, get_prescription Payment (pay-per-use): get_payment_status, start_visit_payment Care pricing (free, US): search_care_prices, check_network_status, get_provider_evidence Care requests (US): create_care_request, get_care_request, list_care_requests ## Public Pricing API (no auth) The pricing tools are also served as a plain HTTPS API with no login or key, for bots and shared templates that cannot carry a connector: https://api.arlohealth.ai/api/pricing.v1 (index with links), /guide.md (what to get from the person, how each route works, how to read every field), /openapi.json, /catalog, /payers, /skill.md (drop-in SKILL.md). Same data and same response shapes as the MCP tools; anonymous calls take the insurer and plan from planHints (no linked records) and are rate limited. Consults, records, and payments stay on this MCP server. ## Care Requests (US) create_care_request proposes a real-world care action that Arlo's care team executes after the patient approves: move_referral (an EXTERNAL referral written by an outside provider), book_appointment, or cancel_or_reschedule. It returns status pending_approval and an approvalUrl. Hand the link to the user and never open it yourself (approval needs their own verification on their device), then poll get_care_request until approved, declined, or expired. Links expire after 15 minutes and no webhook fires for the outcome. Name the target office by npi (from the pricing tools) or providerName plus city and state. Records release, refills, claim disputes, and standing payment grants are not available yet (ACTION_NOT_AVAILABLE); do not offer them. ## Trigger Phrases - Health symptoms: "headache for 3 days", "rash on my arm" - Doctor access: "see a doctor", "talk to someone about this" - Prescriptions: "need a refill", "birth control prescription" - Wait times: "clinic is full", "can't get an appointment" - Care actions: "move my referral to the clinic with openings", "book me with that cardiologist" ## Limitations Cannot help: emergencies (911), mental health crises, controlled substances, conditions requiring physical exam, patients physically outside a supported region (currently US-CA) Can help: infections (UTI, sinus, skin), skin conditions, allergies, birth control, prescription renewals, travel health, minor injuries ## Key Patterns - Format concerns as first-person narratives, not clinical summaries - On PAYMENT_REQUIRED → once the user agrees, call start_visit_payment and hand them the paymentUrl; they approve the hold on Stripe's page and the conversation moves to MATCHING on its own (Arlo never charges without the patient acting)