{
  "name": "ActuallyCare MCP tools",
  "description": "Machine-readable index of every tool exposed by the ActuallyCare MCP server. Generated from the canonical platform tool registry. Note: to keep token costs low, the server advertises a small hot-list by default; all tools listed here are callable. \"categories\" are documentation groupings (one per registry bucket, matching docs URLs); each tool also carries its coarser registryCategory from the platform registry.",
  "server": "https://mcp.actuallycare.com/mcp",
  "docs": "https://docs.actuallycare.com/tools",
  "count": 232,
  "categories": [
    {
      "slug": "agent-brokerage-history",
      "title": "Agent brokerage history",
      "description": "Look up which brokerage an agent was at on a given date, from California DRE public records.",
      "docs": "https://docs.actuallycare.com/tools/agent-brokerage-history",
      "count": 2,
      "tools": [
        "agent_brokerage_at_date",
        "agent_brokerage_history_list"
      ]
    },
    {
      "slug": "appointments",
      "title": "Appointments",
      "description": "Create, search, update, and cancel appointments — including today's schedule and appointment stats.",
      "docs": "https://docs.actuallycare.com/tools/appointments",
      "count": 10,
      "tools": [
        "appointments_create",
        "appointments_list",
        "appointments_get",
        "appointments_update",
        "appointments_cancel",
        "appointments_today",
        "appointments_archive",
        "appointments_restore",
        "appointments_delete",
        "appointments_stats"
      ]
    },
    {
      "slug": "bulk-operations",
      "title": "Bulk operations",
      "description": "Bulk archive, restore, and delete across core entities, plus bulk lead status updates.",
      "docs": "https://docs.actuallycare.com/tools/bulk-operations",
      "count": 19,
      "tools": [
        "bulk_update_lead_status",
        "contacts_batch_archive",
        "contacts_batch_restore",
        "contacts_batch_delete",
        "leads_batch_archive",
        "leads_batch_restore",
        "leads_batch_delete",
        "clients_batch_archive",
        "clients_batch_restore",
        "clients_batch_delete",
        "escrows_batch_archive",
        "escrows_batch_restore",
        "escrows_batch_delete",
        "appointments_batch_archive",
        "appointments_batch_restore",
        "appointments_batch_delete",
        "listings_batch_archive",
        "listings_batch_restore",
        "listings_batch_delete"
      ]
    },
    {
      "slug": "clients",
      "title": "Clients",
      "description": "Manage the people you represent — create, update, search, archive, and sync client records.",
      "docs": "https://docs.actuallycare.com/tools/clients",
      "count": 11,
      "tools": [
        "clients_list",
        "clients_get",
        "clients_create",
        "clients_update",
        "clients_bulk_update",
        "clients_stats",
        "clients_archive",
        "clients_restore",
        "clients_find_or_create",
        "clients_sync_statuses",
        "clients_delete"
      ]
    },
    {
      "slug": "commission-ledger",
      "title": "Commission ledger",
      "description": "Track agent commission payouts per escrow — list, inspect, and update ledger entries from pending through paid.",
      "docs": "https://docs.actuallycare.com/tools/commission-ledger",
      "count": 4,
      "tools": [
        "commission_ledger_create",
        "commission_ledger_list",
        "commission_ledger_get",
        "commission_ledger_update"
      ]
    },
    {
      "slug": "communication",
      "title": "Communication drafts",
      "description": "Draft emails, text messages, and call scripts for your review — nothing is sent until you approve it.",
      "docs": "https://docs.actuallycare.com/tools/communication",
      "count": 3,
      "tools": [
        "draft_email",
        "draft_sms",
        "draft_call_script"
      ]
    },
    {
      "slug": "composite",
      "title": "Composite workflows",
      "description": "One-call shortcuts that combine several steps, like creating an escrow together with its client records.",
      "docs": "https://docs.actuallycare.com/tools/composite",
      "count": 3,
      "tools": [
        "create_escrow_with_clients",
        "log_showing_with_feedback",
        "create_listing_from_escrow"
      ]
    },
    {
      "slug": "contacts",
      "title": "Contacts",
      "description": "Your wider address book — everyone you know, whether or not they are a client yet.",
      "docs": "https://docs.actuallycare.com/tools/contacts",
      "count": 8,
      "tools": [
        "contacts_create",
        "contacts_list",
        "contacts_update",
        "contacts_get",
        "contacts_archive",
        "contacts_restore",
        "contacts_delete",
        "contacts_stats"
      ]
    },
    {
      "slug": "deadline",
      "title": "Deadlines & transaction tracking",
      "description": "Contingency deadlines, alerts, escrow checklists, call logging, follow-up reminders, and open-house logging.",
      "docs": "https://docs.actuallycare.com/tools/deadline",
      "count": 7,
      "tools": [
        "get_contingency_deadlines",
        "get_deadline_alerts",
        "get_escrow_checklist",
        "log_call",
        "get_follow_up_reminders",
        "create_open_house",
        "log_open_house_visitor"
      ]
    },
    {
      "slug": "deals",
      "title": "Deals (vendor pipeline)",
      "description": "Track vendor deals through the vendor sales pipeline — create, update, stats, and lifecycle operations.",
      "docs": "https://docs.actuallycare.com/tools/deals",
      "count": 8,
      "tools": [
        "deals_list",
        "deals_get",
        "deals_create",
        "deals_update",
        "deals_stats",
        "deals_archive",
        "deals_restore",
        "deals_delete"
      ]
    },
    {
      "slug": "documents",
      "title": "Documents",
      "description": "Read AI risk-analysis results for documents uploaded to a transaction.",
      "docs": "https://docs.actuallycare.com/tools/documents",
      "count": 2,
      "tools": [
        "documents_get_risks",
        "documents_list"
      ]
    },
    {
      "slug": "dre-license",
      "title": "DRE license lookup",
      "description": "Look up a California DRE real-estate license via the official DRE API.",
      "docs": "https://docs.actuallycare.com/tools/dre-license",
      "count": 1,
      "tools": [
        "lookup_dre_license"
      ]
    },
    {
      "slug": "engagements",
      "title": "Engagements (vendor pipeline)",
      "description": "Track vendor engagements and interactions — create, update, stats, and lifecycle operations.",
      "docs": "https://docs.actuallycare.com/tools/engagements",
      "count": 8,
      "tools": [
        "engagements_list",
        "engagements_get",
        "engagements_create",
        "engagements_update",
        "engagements_stats",
        "engagements_archive",
        "engagements_restore",
        "engagements_delete"
      ]
    },
    {
      "slug": "entity-links",
      "title": "Entity links",
      "description": "Create, list, and remove relationships between any two records — link contacts to escrows, leads to listings, and more.",
      "docs": "https://docs.actuallycare.com/tools/entity-links",
      "count": 3,
      "tools": [
        "entity_links_list",
        "entity_links_create",
        "entity_links_delete"
      ]
    },
    {
      "slug": "escrows",
      "title": "Escrows",
      "description": "Your transactions from contract to close — create, search, update, and manage escrows.",
      "docs": "https://docs.actuallycare.com/tools/escrows",
      "count": 9,
      "tools": [
        "escrows_list",
        "escrows_get",
        "escrows_create",
        "escrows_update",
        "escrows_stats",
        "escrow_parties_sync",
        "escrows_archive",
        "escrows_restore",
        "escrows_delete"
      ]
    },
    {
      "slug": "financial",
      "title": "Financial calculators",
      "description": "Pure calculators: seller net sheet, buyer closing costs, mortgage payment, and commission split.",
      "docs": "https://docs.actuallycare.com/tools/financial",
      "count": 4,
      "tools": [
        "calculate_seller_net_sheet",
        "calculate_buyer_closing_costs",
        "calculate_mortgage_payment",
        "calculate_commission_split"
      ]
    },
    {
      "slug": "geo-boundaries",
      "title": "Geographic boundaries",
      "description": "Search regional, neighborhood, and subdivision boundaries by place name.",
      "docs": "https://docs.actuallycare.com/tools/geo-boundaries",
      "count": 1,
      "tools": [
        "geo_boundary_search"
      ]
    },
    {
      "slug": "habits",
      "title": "Habits",
      "description": "Personal habit trackers — create daily, weekly, or monthly habits, log completions, and review streaks.",
      "docs": "https://docs.actuallycare.com/tools/habits",
      "count": 5,
      "tools": [
        "habits_list",
        "habits_get",
        "habits_create",
        "habits_update",
        "habits_log"
      ]
    },
    {
      "slug": "landing-pages",
      "title": "Landing pages",
      "description": "Manage open-house sign-in pages and marketing landing pages, with guardrails enforced server-side.",
      "docs": "https://docs.actuallycare.com/tools/landing-pages",
      "count": 7,
      "tools": [
        "landing_page_create",
        "landing_page_edit",
        "landing_page_get",
        "landing_page_publish",
        "landing_page_revert",
        "landing_page_submissions",
        "generate_open_house_flyer"
      ]
    },
    {
      "slug": "leads",
      "title": "Leads",
      "description": "Capture, qualify, update, and convert leads into clients.",
      "docs": "https://docs.actuallycare.com/tools/leads",
      "count": 9,
      "tools": [
        "leads_create",
        "leads_list",
        "leads_update",
        "leads_get",
        "leads_convert",
        "leads_archive",
        "leads_restore",
        "leads_delete",
        "leads_stats"
      ]
    },
    {
      "slug": "leases",
      "title": "Leases",
      "description": "Lease record management for the property-management vertical.",
      "docs": "https://docs.actuallycare.com/tools/leases",
      "count": 5,
      "tools": [
        "leases_list",
        "leases_get",
        "leases_create",
        "leases_expiring",
        "leases_stats"
      ]
    },
    {
      "slug": "listings",
      "title": "Listings",
      "description": "Your property inventory — create, search, update, and manage listings.",
      "docs": "https://docs.actuallycare.com/tools/listings",
      "count": 9,
      "tools": [
        "listings_list",
        "listings_get",
        "listings_create",
        "listings_update",
        "listings_stats",
        "listings_expiring",
        "listings_archive",
        "listings_restore",
        "listings_delete"
      ]
    },
    {
      "slug": "open-houses",
      "title": "Open houses",
      "description": "Schedule and manage open-house events and their visitor records.",
      "docs": "https://docs.actuallycare.com/tools/open-houses",
      "count": 8,
      "tools": [
        "open_houses_list",
        "open_houses_get",
        "open_houses_create",
        "open_houses_update",
        "open_houses_stats",
        "open_houses_archive",
        "open_houses_restore",
        "open_houses_delete"
      ]
    },
    {
      "slug": "partners",
      "title": "Partners (vendor pipeline)",
      "description": "Manage vendor-partner relationships — create, update, stats, and lifecycle operations.",
      "docs": "https://docs.actuallycare.com/tools/partners",
      "count": 8,
      "tools": [
        "partners_list",
        "partners_get",
        "partners_create",
        "partners_update",
        "partners_stats",
        "partners_archive",
        "partners_restore",
        "partners_delete"
      ]
    },
    {
      "slug": "pipelines",
      "title": "Pipelines",
      "description": "Config-driven pipeline engine: overview, record management, stage moves, and batch stage operations.",
      "docs": "https://docs.actuallycare.com/tools/pipelines",
      "count": 15,
      "tools": [
        "pipeline_overview",
        "pipeline_types_list",
        "pipeline_stages_list",
        "pipeline_records_create",
        "pipeline_records_list",
        "pipeline_records_get",
        "pipeline_records_update",
        "pipeline_records_move_stage",
        "pipeline_records_delete",
        "pipeline_records_archive",
        "pipeline_records_restore",
        "pipeline_records_stats",
        "pipeline_record_activities",
        "pipeline_record_log_activity",
        "pipeline_records_batch_stage"
      ]
    },
    {
      "slug": "pl-statements",
      "title": "P&L statements",
      "description": "Analyze an uploaded profit-and-loss statement and predict expense categories.",
      "docs": "https://docs.actuallycare.com/tools/pl-statements",
      "count": 2,
      "tools": [
        "analyze_pl_statement",
        "categorize_expense"
      ]
    },
    {
      "slug": "pm-consultations",
      "title": "PM consultations",
      "description": "Manage property-management consultation requests from prospective landlord clients.",
      "docs": "https://docs.actuallycare.com/tools/pm-consultations",
      "count": 4,
      "tools": [
        "pm_consultations_list",
        "pm_consultations_get",
        "pm_consultations_create",
        "pm_consultations_convert_to_tenancy"
      ]
    },
    {
      "slug": "prospects",
      "title": "Prospects (vendor pipeline)",
      "description": "Top-of-funnel vendor prospecting — create, update, stats, and lifecycle operations.",
      "docs": "https://docs.actuallycare.com/tools/prospects",
      "count": 8,
      "tools": [
        "prospects_list",
        "prospects_get",
        "prospects_create",
        "prospects_update",
        "prospects_stats",
        "prospects_archive",
        "prospects_restore",
        "prospects_delete"
      ]
    },
    {
      "slug": "referrals",
      "title": "Referrals",
      "description": "Agent-to-agent referrals — create, update, stats, and lifecycle operations.",
      "docs": "https://docs.actuallycare.com/tools/referrals",
      "count": 8,
      "tools": [
        "referrals_list",
        "referrals_get",
        "referrals_create",
        "referrals_update",
        "referrals_stats",
        "referrals_archive",
        "referrals_restore",
        "referrals_delete"
      ]
    },
    {
      "slug": "rental-applications",
      "title": "Rental applications",
      "description": "Receive and process rental applications for the property-management vertical.",
      "docs": "https://docs.actuallycare.com/tools/rental-applications",
      "count": 4,
      "tools": [
        "rental_applications_list",
        "rental_applications_get",
        "rental_applications_approve",
        "rental_applications_convert_to_lease"
      ]
    },
    {
      "slug": "reporting",
      "title": "Reporting & insights",
      "description": "Production reports, lead-source ROI, anniversaries, hot-lead lists, buyer matching, and close-probability estimates.",
      "docs": "https://docs.actuallycare.com/tools/reporting",
      "count": 7,
      "tools": [
        "get_production_report",
        "get_lead_source_roi",
        "get_client_anniversaries",
        "get_hot_leads",
        "suggest_next_action",
        "match_buyers_to_listings",
        "predict_close_probability"
      ]
    },
    {
      "slug": "review-requests",
      "title": "Review requests",
      "description": "Find clients from recently closed escrows, draft a review request email, and send it after your explicit confirmation.",
      "docs": "https://docs.actuallycare.com/tools/review-requests",
      "count": 3,
      "tools": [
        "list_clients_pending_review_request",
        "draft_review_request_email",
        "send_review_request"
      ]
    },
    {
      "slug": "showings",
      "title": "Showings",
      "description": "Schedule, track, and log property showings, including buyer feedback.",
      "docs": "https://docs.actuallycare.com/tools/showings",
      "count": 8,
      "tools": [
        "showings_list",
        "showings_get",
        "showings_create",
        "showings_update",
        "showings_stats",
        "showings_archive",
        "showings_restore",
        "showings_delete"
      ]
    },
    {
      "slug": "stats",
      "title": "Dashboard & stats",
      "description": "At-a-glance counters for your CRM — answers to \"how many X do I have?\" questions.",
      "docs": "https://docs.actuallycare.com/tools/stats",
      "count": 2,
      "tools": [
        "get_dashboard_stats",
        "get_contact_stats"
      ]
    },
    {
      "slug": "tenancies",
      "title": "Tenancies",
      "description": "Manage tenancy records, including delinquency lookups, for the property-management vertical.",
      "docs": "https://docs.actuallycare.com/tools/tenancies",
      "count": 7,
      "tools": [
        "tenancies_list",
        "tenancies_get",
        "tenancies_create",
        "tenancies_mark_rent_collected",
        "tenancies_record_inspection",
        "tenancies_delinquent",
        "tenancies_stats"
      ]
    },
    {
      "slug": "utility",
      "title": "Utilities",
      "description": "Helper lookups used before other operations: verified address lookup and parcel/APN lookup.",
      "docs": "https://docs.actuallycare.com/tools/utility",
      "count": 2,
      "tools": [
        "lookup_parcel",
        "lookup_address"
      ]
    },
    {
      "slug": "verticals",
      "title": "Verticals & roles",
      "description": "Read-only discovery of platform verticals and role definitions.",
      "docs": "https://docs.actuallycare.com/tools/verticals",
      "count": 4,
      "tools": [
        "vertical_schema_get",
        "verticals_list",
        "roles_list",
        "role_lookup"
      ]
    },
    {
      "slug": "websites",
      "title": "Websites",
      "description": "Agent personal website edit-publish-revert cycle, with Fair Housing, DRE, and IDX guardrails enforced server-side.",
      "docs": "https://docs.actuallycare.com/tools/websites",
      "count": 4,
      "tools": [
        "website_get",
        "website_edit",
        "website_publish",
        "website_revert"
      ]
    }
  ],
  "tools": [
    {
      "name": "agent_brokerage_at_date",
      "category": "agent-brokerage-history",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Resolve which brokerage an agent was at on a specific date. Returns the brokerage name, DRE license number, and date range of the matching responsible-broker relationship from CA DRE public records. Use this when a user asks \"which brokerage was X at on Y date\" or for historical escrow attribution. Returns null when the date predates the agent's recorded history (DRE typically goes back ~5–10 years).",
      "keywords": [
        "brokerage",
        "history",
        "agent",
        "dre",
        "date",
        "attribution",
        "former broker"
      ],
      "docs": "https://docs.actuallycare.com/tools/agent-brokerage-history/agent_brokerage_at_date",
      "inputSchema": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "description": "Platform user UUID. Defaults to the calling user when omitted."
          },
          "dre_license_id": {
            "type": "string",
            "pattern": "^[0-9]{8}$",
            "description": "CA DRE 8-digit license number (alternative to user_id, useful for non-platform agents on a listing)."
          },
          "on_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Date to resolve, in YYYY-MM-DD format. Both period start_date and end_date are inclusive bounds."
          }
        },
        "required": [
          "on_date"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "agent_brokerage_history_list",
      "category": "agent-brokerage-history",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "List the full brokerage career timeline for an agent. Use to answer where an agent has worked and for how long — for a point-in-time lookup, use agent_brokerage_at_date instead. Returns one entry per (brokerage, period) tuple, oldest first, including current responsible broker (end_date is null for current). Each entry includes brokerage name, DRE license, start/end dates, and a human-readable tenure label like \"1 year, 7 months\". Sourced from CA DRE public records.",
      "keywords": [
        "brokerage",
        "history",
        "timeline",
        "tenure",
        "career",
        "agent",
        "former broker"
      ],
      "docs": "https://docs.actuallycare.com/tools/agent-brokerage-history/agent_brokerage_history_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "description": "Platform user UUID. Defaults to the calling user when omitted."
          },
          "dre_license_id": {
            "type": "string",
            "pattern": "^[0-9]{8}$",
            "description": "CA DRE 8-digit license number (alternative to user_id, useful for non-platform agents on a listing)."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "appointments_create",
      "aliasOf": "create_appointment",
      "category": "appointments",
      "registryCategory": "core",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new appointment, showing, meeting, or follow-up. Use whenever the user wants something on their calendar. Call immediately with whatever data the user provides. Do NOT ask for missing fields — the system shows an editable draft card where the user can fill in remaining details. Returns the created appointment record.",
      "keywords": [
        "appointment",
        "meeting",
        "showing",
        "schedule",
        "create",
        "calendar"
      ],
      "docs": "https://docs.actuallycare.com/tools/appointments/appointments_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "Title or subject of the appointment"
          },
          "appointment_type": {
            "type": "string",
            "enum": [
              "buyer_consultation",
              "lender_prequalification",
              "listing_appointment",
              "showing",
              "property_tour",
              "client_meeting",
              "inspection",
              "appraisal",
              "signing",
              "final_walkthrough",
              "call",
              "other",
              "open_house",
              "escrow_deadline",
              "owner_blackout",
              "escrow_service"
            ],
            "description": "Type of appointment"
          },
          "start_time": {
            "type": "string",
            "description": "Start date and time (ISO 8601 format, e.g., 2025-01-15T14:00:00)"
          },
          "end_time": {
            "type": "string",
            "description": "End date and time (ISO 8601 format)"
          },
          "location": {
            "type": "string",
            "description": "Location or address of the appointment"
          },
          "notes": {
            "type": "string",
            "description": "Notes or description"
          },
          "contact_id": {
            "type": "string",
            "description": "UUID of the contact this appointment is with"
          },
          "listing_id": {
            "type": "string",
            "description": "UUID of the listing this appointment is for (if applicable)"
          }
        },
        "required": [
          "title",
          "start_time"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "appointments_list",
      "aliasOf": "list_appointments",
      "category": "appointments",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search for appointments by date range, status, or text. Use to answer calendar questions or to find an appointment's ID before updating or cancelling it (for today's schedule, appointments_today is faster). Returns IDs only by default for efficiency; use the fields parameter to include additional data. Response includes relatedIds.contactIds for chainable operations.",
      "keywords": [
        "appointment",
        "meeting",
        "schedule",
        "list",
        "search",
        "calendar"
      ],
      "docs": "https://docs.actuallycare.com/tools/appointments/appointments_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term — matches against title and location (case-insensitive partial match)"
          },
          "start_date": {
            "type": "string",
            "description": "Start date to filter from (YYYY-MM-DD)"
          },
          "end_date": {
            "type": "string",
            "description": "End date to filter to (YYYY-MM-DD)"
          },
          "appointment_type": {
            "type": "string",
            "enum": [
              "buyer_consultation",
              "lender_prequalification",
              "listing_appointment",
              "showing",
              "property_tour",
              "client_meeting",
              "inspection",
              "appraisal",
              "signing",
              "final_walkthrough",
              "call",
              "other",
              "open_house",
              "escrow_deadline",
              "owner_blackout",
              "escrow_service"
            ],
            "description": "Filter by appointment type"
          },
          "status": {
            "type": "string",
            "enum": [
              "scheduled",
              "completed",
              "cancelled",
              "no_show"
            ],
            "description": "Filter by appointment status"
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "basic",
                "schedule",
                "contacts",
                "full"
              ]
            },
            "description": "Field groups to include. Empty/omitted = IDs only. Options: basic (id, title, type, status), schedule (times, location), contacts (contact name), full (all fields)."
          },
          "limit": {
            "type": "string",
            "description": "Max results. Use a number (e.g. \"25\") or \"all\". Default: 10. \"all\" and any value above 200 are capped at 200 server-side."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "appointments_get",
      "aliasOf": "get_appointment",
      "category": "appointments",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of a specific appointment by its ID — time, location, type, status, and notes. Use after appointments_list when you need every field for one appointment. For multiple appointments, pass appointment_ids instead. Returns the complete appointment record.",
      "keywords": [
        "appointment",
        "meeting",
        "get",
        "fetch",
        "details"
      ],
      "docs": "https://docs.actuallycare.com/tools/appointments/appointments_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "appointment_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of a single appointment to retrieve"
          },
          "appointment_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "maxItems": 100,
            "description": "Array of appointment UUIDs for batch retrieval (max 100). Use either appointment_id OR appointment_ids, not both."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "appointments_update",
      "aliasOf": "update_appointment",
      "category": "appointments",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing appointment's details or reschedule it. Only provided fields are updated — omitted fields remain unchanged. Common uses: move the start/end time, change the location, or fix the title. Returns the updated appointment record.",
      "keywords": [
        "appointment",
        "meeting",
        "update",
        "edit",
        "reschedule",
        "modify"
      ],
      "docs": "https://docs.actuallycare.com/tools/appointments/appointments_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "appointment_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the appointment to update"
          },
          "title": {
            "type": "string",
            "description": "Updated title"
          },
          "start_time": {
            "type": "string",
            "description": "Updated start time (ISO 8601)"
          },
          "end_time": {
            "type": "string",
            "description": "Updated end time (ISO 8601)"
          },
          "location": {
            "type": "string",
            "description": "Updated location"
          },
          "notes": {
            "type": "string",
            "description": "Updated notes"
          },
          "status": {
            "type": "string",
            "enum": [
              "scheduled",
              "completed",
              "cancelled",
              "no_show"
            ],
            "description": "Updated status"
          }
        },
        "required": [
          "appointment_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "appointments_cancel",
      "aliasOf": "cancel_appointment",
      "category": "appointments",
      "registryCategory": "core",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Cancel an appointment while keeping its record for history. Use when a showing, meeting, or follow-up is called off; to move it to a new time instead, use appointments_update. Returns the cancelled appointment record.",
      "keywords": [
        "appointment",
        "meeting",
        "cancel",
        "abort"
      ],
      "docs": "https://docs.actuallycare.com/tools/appointments/appointments_cancel",
      "inputSchema": {
        "type": "object",
        "properties": {
          "appointment_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the appointment to cancel"
          },
          "reason": {
            "type": "string",
            "description": "Reason for cancellation"
          }
        },
        "required": [
          "appointment_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "appointments_today",
      "aliasOf": "get_today_schedule",
      "category": "appointments",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get all appointments scheduled for today. Use when user asks about today's schedule or calendar.",
      "keywords": [
        "appointment",
        "today",
        "schedule",
        "calendar",
        "daily"
      ],
      "docs": "https://docs.actuallycare.com/tools/appointments/appointments_today",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "appointments_archive",
      "category": "appointments",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive an appointment to hide it from active views without deleting it. Archived appointments can be restored later with appointments_restore. Use this for past appointments you want to declutter from your schedule view. Returns the archived appointment record.",
      "keywords": [
        "appointment",
        "archive",
        "hide"
      ],
      "docs": "https://docs.actuallycare.com/tools/appointments/appointments_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "appointment_id": {
            "type": "string",
            "description": "UUID of the appointment to archive. Use appointments_list to find the ID if unknown."
          }
        },
        "required": [
          "appointment_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "appointments_restore",
      "category": "appointments",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore a previously archived appointment back to active views. Reverses the effect of appointments_archive. Use this when an appointment was archived by mistake. Returns the restored appointment record.",
      "keywords": [
        "appointment",
        "restore",
        "unarchive"
      ],
      "docs": "https://docs.actuallycare.com/tools/appointments/appointments_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "appointment_id": {
            "type": "string",
            "description": "UUID of the appointment to restore. Must be currently archived."
          }
        },
        "required": [
          "appointment_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "appointments_delete",
      "category": "appointments",
      "registryCategory": "core",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete an appointment. This is IRREVERSIBLE - the appointment will be hidden from all views including archived. Only use for test data or duplicate records. For normal cleanup, use appointments_archive instead which is reversible. Returns confirmation of the deletion.",
      "keywords": [
        "appointment",
        "delete",
        "remove",
        "destructive"
      ],
      "docs": "https://docs.actuallycare.com/tools/appointments/appointments_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "appointment_id": {
            "type": "string",
            "description": "UUID of the appointment to delete. Use appointments_get first to verify."
          }
        },
        "required": [
          "appointment_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "appointments_stats",
      "category": "appointments",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get aggregate statistics for all appointments: counts by status (scheduled/completed/cancelled), upcoming appointments within 7 days, and total counts by type. Use this for dashboard metrics and scheduling overview. Does NOT return individual appointment records - use appointments_list for that.",
      "keywords": [
        "appointment",
        "stats",
        "metrics",
        "dashboard"
      ],
      "docs": "https://docs.actuallycare.com/tools/appointments/appointments_stats",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "bulk_update_lead_status",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Update multiple leads' status at once for bulk lead management. WARNING: This affects multiple records permanently. Common use cases: marking old leads as \"lost\" after cleanup review, updating all contacted leads to \"qualified\" after qualification calls, batch setting leads to \"unqualified\" after failed contact attempts. Returns: count of successfully updated leads, any failures with reasons. Always verify the lead_ids list before calling — consider using leads_list first to confirm you have the right records. Status transitions: new→contacted→qualified→converted (success path) or →unqualified/lost (failure path).",
      "keywords": [
        "bulk",
        "batch",
        "lead",
        "status",
        "update"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/bulk_update_lead_status",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lead_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 500,
            "description": "Array of lead UUIDs to update. Max 500 per call. Use leads_list to get IDs."
          },
          "new_status": {
            "type": "string",
            "enum": [
              "new",
              "contacted",
              "qualified",
              "unqualified",
              "converted",
              "lost"
            ],
            "description": "New status to set for ALL specified leads. converted should only be used via leads_convert for proper client creation."
          },
          "notes": {
            "type": "string",
            "maxLength": 1000,
            "description": "Notes to append to all updated leads. Example: \"Bulk marked lost - no response after 6 months\"."
          }
        },
        "required": [
          "lead_ids",
          "new_status"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "contacts_batch_archive",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Archive multiple contacts at once. Contacts must be active (not already archived). Returns success and failure counts with IDs. Use contacts_list first to verify the correct contact IDs.",
      "keywords": [
        "bulk",
        "batch",
        "contact",
        "archive"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/contacts_batch_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Contact UUIDs to archive. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "contacts_batch_restore",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Restore multiple archived contacts at once. Contacts must be currently archived. Returns success and failure counts with IDs. Restored contacts become active again.",
      "keywords": [
        "bulk",
        "batch",
        "contact",
        "restore"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/contacts_batch_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Contact UUIDs to restore. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "contacts_batch_delete",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete multiple contacts that have been archived. Contacts must be archived before deletion. This action is irreversible. Returns success and failure counts with IDs.",
      "keywords": [
        "bulk",
        "batch",
        "contact",
        "delete",
        "permanent"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/contacts_batch_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Contact UUIDs to permanently delete. Must be archived. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "leads_batch_archive",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Archive multiple leads at once. Sets lead status to \"archived\" and marks them as soft-deleted. Returns success and failure counts with IDs. Use leads_list first to verify the correct lead IDs.",
      "keywords": [
        "bulk",
        "batch",
        "lead",
        "archive"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/leads_batch_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Lead UUIDs to archive. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "leads_batch_restore",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Restore multiple archived leads at once. Resets lead status back to \"new\" and clears the soft-delete timestamp. Returns success and failure counts with IDs. Restored leads become active again.",
      "keywords": [
        "bulk",
        "batch",
        "lead",
        "restore"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/leads_batch_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Lead UUIDs to restore. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "leads_batch_delete",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete multiple leads that have been archived. Leads must be archived before deletion. This action is irreversible. Returns success and failure counts with IDs.",
      "keywords": [
        "bulk",
        "batch",
        "lead",
        "delete",
        "permanent"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/leads_batch_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Lead UUIDs to permanently delete. Must be archived. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "clients_batch_archive",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Archive multiple clients at once. Clients must be active (not already archived). Returns success and failure counts with IDs. Use clients_list first to verify the correct client IDs.",
      "keywords": [
        "bulk",
        "batch",
        "client",
        "archive"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/clients_batch_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Client UUIDs to archive. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "clients_batch_restore",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Restore multiple archived clients at once. Clients must be currently archived. Returns success and failure counts with IDs. Restored clients become active again.",
      "keywords": [
        "bulk",
        "batch",
        "client",
        "restore"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/clients_batch_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Client UUIDs to restore. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "clients_batch_delete",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete multiple clients that have been archived. Clients must be archived before deletion. This action is irreversible. Returns success and failure counts with IDs.",
      "keywords": [
        "bulk",
        "batch",
        "client",
        "delete",
        "permanent"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/clients_batch_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Client UUIDs to permanently delete. Must be archived. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "escrows_batch_archive",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Archive multiple escrows at once. Escrows must be active (not already archived). Returns success and failure counts with IDs. Use escrows_list first to verify the correct escrow IDs.",
      "keywords": [
        "bulk",
        "batch",
        "escrow",
        "archive"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/escrows_batch_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Escrow UUIDs to archive. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "escrows_batch_restore",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Restore multiple archived escrows at once. Escrows must be currently archived. Returns success and failure counts with IDs. Restored escrows become active again.",
      "keywords": [
        "bulk",
        "batch",
        "escrow",
        "restore"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/escrows_batch_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Escrow UUIDs to restore. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "escrows_batch_delete",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete multiple escrows that have been archived. Escrows must be archived before deletion. This action is irreversible. Returns success and failure counts with IDs.",
      "keywords": [
        "bulk",
        "batch",
        "escrow",
        "delete",
        "permanent"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/escrows_batch_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Escrow UUIDs to permanently delete. Must be archived. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "appointments_batch_archive",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Archive multiple appointments at once. Sets appointment status to \"cancelled\" and marks them as soft-deleted. Returns success and failure counts with IDs. Use appointments_list first to verify the correct appointment IDs.",
      "keywords": [
        "bulk",
        "batch",
        "appointment",
        "archive"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/appointments_batch_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Appointment UUIDs to archive. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "appointments_batch_restore",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Restore multiple archived appointments at once. Resets appointment status back to \"scheduled\" and clears the soft-delete timestamp. Returns success and failure counts with IDs. Restored appointments become active again.",
      "keywords": [
        "bulk",
        "batch",
        "appointment",
        "restore"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/appointments_batch_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Appointment UUIDs to restore. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "appointments_batch_delete",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete multiple appointments that have been archived. Appointments must be archived before deletion. This action is irreversible. Returns success and failure counts with IDs.",
      "keywords": [
        "bulk",
        "batch",
        "appointment",
        "delete",
        "permanent"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/appointments_batch_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Appointment UUIDs to permanently delete. Must be archived. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "listings_batch_archive",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Archive multiple listings at once. Sets listing status to \"cancelled\" and marks them as archived. Returns success and failure counts with IDs. Use listings_list first to verify the correct listing IDs.",
      "keywords": [
        "bulk",
        "batch",
        "listing",
        "archive"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/listings_batch_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Listing UUIDs to archive. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "listings_batch_restore",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Restore multiple archived listings at once. Resets listing status back to \"active\" and clears the archived flag. Returns success and failure counts with IDs. Restored listings become active again.",
      "keywords": [
        "bulk",
        "batch",
        "listing",
        "restore"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/listings_batch_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Listing UUIDs to restore. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "listings_batch_delete",
      "category": "bulk-operations",
      "registryCategory": "operations",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete multiple listings that have been archived. Listings must be archived before deletion. This action is irreversible. Returns success and failure counts with IDs.",
      "keywords": [
        "bulk",
        "batch",
        "listing",
        "delete",
        "permanent"
      ],
      "docs": "https://docs.actuallycare.com/tools/bulk-operations/listings_batch_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Listing UUIDs to permanently delete. Must be archived. Max 100."
          }
        },
        "required": [
          "ids"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "clients_list",
      "aliasOf": "search_clients",
      "category": "clients",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search for clients. Returns IDs only by default for efficiency. Use fields parameter to include additional data. Response includes relatedIds.contactIds for chainable operations.\n\nNOTE: When working with escrows, use relatedIds.clientIds directly with clients_bulk_update.\nThe contact_ids parameter is for finding clients by their linked contact - only needed for special cases.",
      "keywords": [
        "client",
        "search",
        "list",
        "find",
        "buyer",
        "seller"
      ],
      "docs": "https://docs.actuallycare.com/tools/clients/clients_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term (searches name, email, phone)"
          },
          "client_type": {
            "type": "string",
            "enum": [
              "buyer",
              "seller",
              "both"
            ],
            "description": "Filter by client type"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "closed",
              "expired",
              "cancelled"
            ],
            "description": "Filter by client status (active = working with, closed = deal completed, expired = agreement expired, cancelled = client cancelled)"
          },
          "contact_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Filter to clients linked to these contact IDs. CRITICAL for finding clients from escrow contacts - use escrow relatedIds.contactIds here."
          },
          "is_archived": {
            "type": [
              "boolean",
              "string"
            ],
            "description": "Filter by archived state. Default: false (active clients only). Pass true to find ARCHIVED clients (e.g. for a restore workflow). Pass \"any\" to include both."
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "basic",
                "contact",
                "financial",
                "activity",
                "full"
              ]
            },
            "description": "Field groups to include. Empty/omitted = IDs only. Options: basic (id, type, status), contact (name, email, phone), financial (budget range), activity (dates), full (all fields)."
          },
          "limit": {
            "type": "string",
            "description": "Max results. Use a number (e.g. \"25\") or \"all\". \"all\" and any value above 200 are capped at 200 server-side."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "clients_get",
      "aliasOf": "get_client",
      "category": "clients",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of a specific client by ID — contact info, client type, status, representation dates, and tags. Use after clients_list when you need every field for one client. For multiple clients, pass client_ids instead. Returns the complete client record.",
      "keywords": [
        "client",
        "get",
        "detail",
        "fetch"
      ],
      "docs": "https://docs.actuallycare.com/tools/clients/clients_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "client_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of a single client to retrieve"
          },
          "client_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "maxItems": 100,
            "description": "Array of client UUIDs for batch retrieval (max 100). Use either client_id OR client_ids, not both."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "clients_create",
      "aliasOf": "create_client",
      "category": "clients",
      "registryCategory": "core",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new client (buyer or seller). Use when someone signs with you or the user asks to add a client directly — to promote an existing lead, use leads_convert instead. Call immediately with whatever data the user provides. Do NOT ask for missing fields — the system shows an editable draft card where the user can fill in remaining details. Returns the created client record.",
      "keywords": [
        "client",
        "create",
        "add",
        "buyer",
        "seller"
      ],
      "docs": "https://docs.actuallycare.com/tools/clients/clients_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "first_name": {
            "type": "string",
            "description": "First name"
          },
          "last_name": {
            "type": "string",
            "description": "Last name"
          },
          "email": {
            "type": "string",
            "description": "Email address"
          },
          "phone": {
            "type": "string",
            "description": "Phone number"
          },
          "client_type": {
            "type": "string",
            "enum": [
              "buyer",
              "seller",
              "both"
            ],
            "description": "Type of client"
          },
          "budget_min": {
            "type": "number",
            "description": "Minimum budget (for buyers)"
          },
          "budget_max": {
            "type": "number",
            "description": "Maximum budget (for buyers)"
          },
          "notes": {
            "type": "string",
            "description": "Notes about this client"
          }
        },
        "required": [
          "first_name",
          "last_name",
          "client_type"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "clients_update",
      "aliasOf": "update_client",
      "category": "clients",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing client's information. Only provided fields are updated — omitted fields remain unchanged. Common uses: change status or client type, fix contact details, adjust representation dates. Returns the updated client record.",
      "keywords": [
        "client",
        "update",
        "edit",
        "modify"
      ],
      "docs": "https://docs.actuallycare.com/tools/clients/clients_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "client_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the client to update"
          },
          "first_name": {
            "type": "string",
            "description": "Updated first name"
          },
          "last_name": {
            "type": "string",
            "description": "Updated last name"
          },
          "email": {
            "type": "string",
            "description": "Updated email"
          },
          "phone": {
            "type": "string",
            "description": "Updated phone"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "closed",
              "expired",
              "cancelled",
              "inactive"
            ],
            "description": "Updated status (active = working with, closed = deal completed, expired = agreement expired, cancelled = client cancelled, inactive = paused)"
          },
          "notes": {
            "type": "string",
            "description": "Notes to add"
          }
        },
        "required": [
          "client_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "clients_bulk_update",
      "aliasOf": "batch_update_clients",
      "category": "clients",
      "registryCategory": "core",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Update multiple clients at once. Requires CLIENT IDs. Use for batch changes like marking every client on a closed escrow as closed. Returns a summary of the clients updated plus any IDs that were not found.\n\nWORKFLOW for updating clients from escrows (DIRECT - no intermediate steps):\n1. escrows_list → get relatedIds.clientIds (these ARE client IDs!)\n2. clients_bulk_update({ client_ids: relatedIds.clientIds, updates: {...} })\n\nNOTE: escrows_list now returns BOTH:\n- relatedIds.clientIds → use directly with this tool\n- relatedIds.contactIds → use with contacts_get (contact_ids) (different entity)",
      "keywords": [
        "client",
        "bulk",
        "batch",
        "update",
        "mass"
      ],
      "docs": "https://docs.actuallycare.com/tools/clients/clients_bulk_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "client_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Array of CLIENT UUIDs (from clients_list response.ids). NOT contact IDs from escrows!"
          },
          "updates": {
            "type": "object",
            "description": "Fields to update on all clients",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "active",
                  "closed",
                  "expired",
                  "cancelled"
                ],
                "description": "New status for all clients (active = working with, closed = deal completed, expired = agreement expired, cancelled = client cancelled)"
              },
              "client_type": {
                "type": "string",
                "enum": [
                  "buyer",
                  "seller",
                  "both"
                ],
                "description": "New client type"
              }
            }
          },
          "skip_if_already": {
            "type": "boolean",
            "description": "If true, skip clients already in target state (default: true).",
            "default": true
          }
        },
        "required": [
          "client_ids",
          "updates"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "clients_stats",
      "aliasOf": "get_clients_summary",
      "category": "clients",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get a summary of all clients including counts by type and status. Use for overview questions.",
      "keywords": [
        "client",
        "stats",
        "summary",
        "counts",
        "overview"
      ],
      "docs": "https://docs.actuallycare.com/tools/clients/clients_stats",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "clients_archive",
      "aliasOf": "archive_client",
      "category": "clients",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive a client to hide them from active views without deleting their record. Use for past clients you are no longer working with but whose history you want to keep — the client can be restored later with clients_restore. Returns the archived client record.",
      "keywords": [
        "client",
        "archive",
        "hide",
        "soft-delete"
      ],
      "docs": "https://docs.actuallycare.com/tools/clients/clients_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "client_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the client to archive"
          }
        },
        "required": [
          "client_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "clients_restore",
      "aliasOf": "restore_client",
      "category": "clients",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore a previously archived client back to active views. Use when you resume working with a client you had archived. Returns the restored client record.",
      "keywords": [
        "client",
        "restore",
        "unarchive"
      ],
      "docs": "https://docs.actuallycare.com/tools/clients/clients_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "client_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the archived client to restore"
          }
        },
        "required": [
          "client_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "clients_find_or_create",
      "aliasOf": "find_or_create_client",
      "category": "clients",
      "registryCategory": "core",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Look up a client by contact identifier; create one if none exists. Single-call idempotent path for \"promote this contact to a client\" intents — prefer this over clients_list → clients_create chains. Accepts either contact_id (preferred) or a name/email to resolve against the contact directory first. Returns the client record plus a `created: true|false` flag so the caller can tell whether a new record was inserted. New clients go through the same editable draft flow as clients_create.",
      "keywords": [
        "client",
        "find",
        "create",
        "upsert",
        "promote-contact"
      ],
      "docs": "https://docs.actuallycare.com/tools/clients/clients_find_or_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "description": "Existing contact UUID (preferred)."
          },
          "first_name": {
            "type": "string",
            "description": "Given name when resolving by name."
          },
          "last_name": {
            "type": "string",
            "description": "Family name when resolving by name."
          },
          "email": {
            "type": "string",
            "description": "Contact email for lookup/creation."
          },
          "phone": {
            "type": "string",
            "description": "Contact phone for lookup/creation."
          },
          "client_type": {
            "type": "string",
            "enum": [
              "buyer",
              "seller",
              "both"
            ],
            "description": "Client type to set when creating (default: buyer)."
          }
        },
        "required": [],
        "additionalProperties": false
      }
    },
    {
      "name": "clients_sync_statuses",
      "category": "clients",
      "registryCategory": "core",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Sync client statuses based on their linked escrow statuses. When escrows close, the clients linked to them should be marked as 'closed'. This tool handles the ENTIRE workflow in ONE call: finds all clients linked to escrows with the specified status who are still marked active, then updates them. ALWAYS use dry_run=true FIRST to preview what would be updated before making actual changes. Returns the list of clients that would be (or were) updated.",
      "keywords": [
        "client",
        "sync",
        "status",
        "workflow",
        "escrow",
        "automation"
      ],
      "docs": "https://docs.actuallycare.com/tools/clients/clients_sync_statuses",
      "inputSchema": {
        "type": "object",
        "properties": {
          "dry_run": {
            "type": "boolean",
            "description": "REQUIRED FIRST STEP: Set true to preview changes without making them. Set false to execute the sync."
          },
          "escrow_status": {
            "type": "string",
            "enum": [
              "closed",
              "cancelled",
              "fell_through"
            ],
            "description": "Which escrow status to sync from. closed=successful transactions, cancelled/fell_through=unsuccessful (default: closed)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "clients_delete",
      "category": "clients",
      "registryCategory": "core",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete a client. This is IRREVERSIBLE - the client will be hidden from all views including archived. Only use for test data or duplicate records. For normal cleanup, use clients_archive instead which is reversible. Returns confirmation of the deletion.",
      "keywords": [
        "client",
        "delete",
        "remove",
        "destructive"
      ],
      "docs": "https://docs.actuallycare.com/tools/clients/clients_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "client_id": {
            "type": "string",
            "description": "UUID of the client to delete. Use clients_get first to verify."
          }
        },
        "required": [
          "client_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "commission_ledger_create",
      "category": "commission-ledger",
      "registryCategory": "financial",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Record a commission ledger entry — the payment-tracking record for a deal commission (status, projected/actual payout dates, check number). Use this AFTER calculate_commission_split to persist the result so it appears on the agent commission ledger. Requires escrow_id, agent_id, and side. All amounts are optional dollar figures; status defaults to pending. This records a payment to be tracked; it does not move money.",
      "keywords": [
        "commission",
        "ledger",
        "record",
        "payment",
        "payout",
        "create",
        "track"
      ],
      "docs": "https://docs.actuallycare.com/tools/commission-ledger/commission_ledger_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "escrow_id": {
            "type": "string",
            "description": "Escrow/transaction ID this commission belongs to (escrow IDs are human-readable strings, e.g. \"ESC-2026-0142\", not UUIDs)"
          },
          "agent_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the agent (users.id) who earns this commission"
          },
          "side": {
            "type": "string",
            "enum": [
              "listing",
              "buyer",
              "both"
            ],
            "description": "Which side of the deal this commission is for"
          },
          "escrow_number": {
            "type": "string",
            "description": "Denormalized escrow/file number for list views"
          },
          "property_address": {
            "type": "string",
            "description": "Denormalized property address for list views"
          },
          "transaction_type": {
            "type": "string",
            "enum": [
              "Sale",
              "Lease"
            ],
            "description": "Transaction type"
          },
          "agent_name": {
            "type": "string",
            "description": "Denormalized agent display name"
          },
          "sale_price": {
            "type": "number",
            "minimum": 0,
            "description": "Sale price in dollars"
          },
          "commission_rate": {
            "type": "number",
            "minimum": 0,
            "description": "Commission rate (percent, e.g. 2.5)"
          },
          "gross_commission": {
            "type": "number",
            "minimum": 0,
            "description": "Gross commission in dollars"
          },
          "brokerage_split": {
            "type": "number",
            "minimum": 0,
            "description": "Brokerage split percentage"
          },
          "agent_commission": {
            "type": "number",
            "minimum": 0,
            "description": "Agent share of the commission in dollars"
          },
          "brokerage_commission": {
            "type": "number",
            "minimum": 0,
            "description": "Brokerage share of the commission in dollars"
          },
          "referral_fee": {
            "type": "number",
            "minimum": 0,
            "description": "Referral fee owed in dollars (default 0)"
          },
          "referral_agent": {
            "type": "string",
            "description": "Name of the referring agent/company"
          },
          "transaction_fee": {
            "type": "number",
            "minimum": 0,
            "description": "Flat brokerage transaction/admin fee in dollars (default 0)"
          },
          "net_commission": {
            "type": "number",
            "minimum": 0,
            "description": "Net commission to the agent in dollars"
          },
          "tax_withheld": {
            "type": "boolean",
            "description": "Whether tax is withheld on this payout (default false)"
          },
          "tax_rate": {
            "type": "number",
            "minimum": 0,
            "description": "Tax withholding rate percentage (default 0)"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "paid",
              "cancelled"
            ],
            "description": "Payment status (default \"pending\")"
          },
          "projected_payout_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Projected payout date (YYYY-MM-DD)"
          },
          "notes": {
            "type": "string",
            "description": "Free-text notes about this commission"
          }
        },
        "required": [
          "escrow_id",
          "agent_id",
          "side"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "commission_ledger_list",
      "category": "commission-ledger",
      "registryCategory": "financial",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "List commission ledger entries visible to the caller, newest first. Standard agents see only their own entries; brokers/team leads see their brokerage/team. Use to review upcoming or past commission payouts, or to find an entry's ID before updating it. Filter by status, agent, side, and payout-date range. Returns a paginated summary (id, escrow_number, property_address, side, agent_name, amounts, status, payout dates).",
      "keywords": [
        "commission",
        "ledger",
        "list",
        "search",
        "payout",
        "pending",
        "paid"
      ],
      "docs": "https://docs.actuallycare.com/tools/commission-ledger/commission_ledger_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Free-text search across escrow number, property address, and agent name"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "paid",
              "cancelled"
            ],
            "description": "Filter by payment status"
          },
          "agent_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Filter by agent UUID (users.id)"
          },
          "side": {
            "type": "string",
            "enum": [
              "listing",
              "buyer",
              "both"
            ],
            "description": "Filter by deal side"
          },
          "start_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Only entries with a payout date on/after this date (YYYY-MM-DD)"
          },
          "end_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Only entries with a payout date on/before this date (YYYY-MM-DD)"
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 100,
            "description": "Max results (default 25, cap 100)"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N records for pagination (default 0)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "commission_ledger_get",
      "category": "commission-ledger",
      "registryCategory": "financial",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get the full details of a single commission ledger entry by its ID — amounts, splits, status, payout dates, and the linked escrow. Use after commission_ledger_list when you need every field for one entry. Scoped to the caller — returns not-found if the entry belongs to another agent outside the caller scope. Returns the complete ledger entry.",
      "keywords": [
        "commission",
        "ledger",
        "get",
        "fetch",
        "details"
      ],
      "docs": "https://docs.actuallycare.com/tools/commission-ledger/commission_ledger_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the commission ledger entry"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "commission_ledger_update",
      "category": "commission-ledger",
      "registryCategory": "financial",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update mutable fields of a commission ledger entry — typically advancing status (pending → processing → paid), recording the actual payout date / check number, or correcting amounts. Use as payouts move through processing. Setting status to paid without an actual_payout_date stamps the current date automatically. Only entries the caller can see may be updated. Returns the updated ledger entry.",
      "keywords": [
        "commission",
        "ledger",
        "update",
        "paid",
        "status",
        "payout",
        "check"
      ],
      "docs": "https://docs.actuallycare.com/tools/commission-ledger/commission_ledger_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the commission ledger entry to update"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "paid",
              "cancelled"
            ],
            "description": "New payment status"
          },
          "sale_price": {
            "type": "number",
            "minimum": 0,
            "description": "Corrected sale price in dollars"
          },
          "commission_rate": {
            "type": "number",
            "minimum": 0,
            "description": "Corrected commission rate (percent)"
          },
          "brokerage_split": {
            "type": "number",
            "minimum": 0,
            "description": "Corrected brokerage split percentage"
          },
          "gross_commission": {
            "type": "number",
            "minimum": 0,
            "description": "Corrected gross commission in dollars"
          },
          "agent_commission": {
            "type": "number",
            "minimum": 0,
            "description": "Corrected agent commission in dollars"
          },
          "net_commission": {
            "type": "number",
            "minimum": 0,
            "description": "Corrected net commission in dollars"
          },
          "referral_fee": {
            "type": "number",
            "minimum": 0,
            "description": "Corrected referral fee in dollars"
          },
          "transaction_fee": {
            "type": "number",
            "minimum": 0,
            "description": "Corrected transaction fee in dollars"
          },
          "projected_payout_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Projected payout date (YYYY-MM-DD)"
          },
          "actual_payout_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Actual payout date (YYYY-MM-DD)"
          },
          "check_number": {
            "type": "string",
            "description": "Check number for the payout"
          },
          "deposit_account": {
            "type": "string",
            "description": "Deposit account the payout went to"
          },
          "notes": {
            "type": "string",
            "description": "Free-text notes about this commission"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "draft_email",
      "category": "communication",
      "registryCategory": "communication",
      "annotation": "Draft only",
      "readOnly": true,
      "destructive": false,
      "description": "Draft an email for the user to review and send. Use this when the user asks you to compose, write, or draft an email to a contact, lead, client, or any person. The email will appear as an interactive card in the chat where the user can review, edit, and send it via their connected Gmail account. IMPORTANT: Always look up the recipient's email address first using contacts_list or leads_list before drafting. Include context from the conversation (property addresses, dates, amounts) to make the email specific and useful.",
      "keywords": [
        "communication",
        "message",
        "draft",
        "email"
      ],
      "docs": "https://docs.actuallycare.com/tools/communication/draft_email",
      "inputSchema": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
            "description": "Recipient email address. Look up via contacts_list or leads_list first."
          },
          "cc": {
            "type": "string",
            "description": "CC email address(es), comma-separated if multiple."
          },
          "bcc": {
            "type": "string",
            "description": "BCC email address(es), comma-separated if multiple."
          },
          "subject": {
            "type": "string",
            "maxLength": 500,
            "description": "Email subject line. Be specific and professional."
          },
          "body": {
            "type": "string",
            "maxLength": 50000,
            "description": "Email body text. Use professional real estate tone. Can include markdown formatting."
          },
          "html_body": {
            "type": "string",
            "description": "Optional HTML version of the email body for rich formatting."
          },
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the contact being emailed. Helps link the communication for CRM tracking."
          },
          "related_entity_type": {
            "type": "string",
            "enum": [
              "escrow",
              "listing",
              "appointment",
              "deal"
            ],
            "description": "Type of related entity if this email is about a specific transaction or listing."
          },
          "related_entity_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the related entity (escrow, listing, etc.)."
          }
        },
        "required": [
          "to",
          "subject",
          "body"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "draft_sms",
      "category": "communication",
      "registryCategory": "communication",
      "annotation": "Draft only",
      "readOnly": true,
      "destructive": false,
      "description": "Draft an SMS text message for the user to review and send. Use this when the user asks you to text, message, or send an SMS to a contact or lead. The message will appear as an interactive card in the chat where the user can review, edit, and send it via Twilio. IMPORTANT: SMS messages should be concise (under 160 characters for a single segment). Always look up the recipient's phone number first using contacts_list or leads_list. The recipient must have active SMS consent on file before sending.",
      "keywords": [
        "communication",
        "message",
        "draft",
        "sms"
      ],
      "docs": "https://docs.actuallycare.com/tools/communication/draft_sms",
      "inputSchema": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "pattern": "^\\+?1?[-.]?\\(?\\d{3}\\)?[-.]?\\d{3}[-.]?\\d{4}$",
            "description": "Recipient phone number. Look up via contacts_list or leads_list first. Format: (555) 123-4567 or 5551234567."
          },
          "body": {
            "type": "string",
            "maxLength": 1600,
            "description": "SMS message body. Keep concise — 160 chars = 1 segment. Over 160 splits into multiple segments which cost more."
          },
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the contact being texted. Required for consent verification and CRM tracking."
          },
          "related_entity_type": {
            "type": "string",
            "enum": [
              "escrow",
              "listing",
              "appointment",
              "deal"
            ],
            "description": "Type of related entity if this text is about a specific transaction or listing."
          },
          "related_entity_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the related entity (escrow, listing, etc.)."
          }
        },
        "required": [
          "to",
          "body"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "draft_call_script",
      "category": "communication",
      "registryCategory": "communication",
      "annotation": "Draft only",
      "readOnly": true,
      "destructive": false,
      "description": "Draft a phone call script for the user to reference during a call. Use this when the user asks you to prepare talking points, a call script, or help them plan a phone conversation. The script will appear as an interactive card in the chat with a Copy button and a Log Call button. Include a clear opening, key talking points, and suggested close. Tailor the script to real estate contexts: listing presentations, offer discussions, follow-ups, check-ins, etc.",
      "keywords": [
        "communication",
        "message",
        "draft",
        "call",
        "script"
      ],
      "docs": "https://docs.actuallycare.com/tools/communication/draft_call_script",
      "inputSchema": {
        "type": "object",
        "properties": {
          "contact_name": {
            "type": "string",
            "maxLength": 200,
            "description": "Full name of the person being called."
          },
          "phone": {
            "type": "string",
            "pattern": "^\\+?1?[-.]?\\(?\\d{3}\\)?[-.]?\\d{3}[-.]?\\d{4}$",
            "description": "Phone number to call. Format: (555) 123-4567 or 5551234567."
          },
          "purpose": {
            "type": "string",
            "maxLength": 500,
            "description": "Brief purpose of the call. E.g., \"Follow up on offer\", \"Listing presentation\", \"Check-in after closing\"."
          },
          "script": {
            "type": "string",
            "maxLength": 10000,
            "description": "The full call script. Include greeting, key discussion points, objection handling, and closing."
          },
          "talking_points": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 500
            },
            "maxItems": 20,
            "description": "Key talking points as a bulleted list. Quick-reference items the agent can glance at during the call."
          },
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the contact being called. Used to link the call log after the conversation."
          }
        },
        "required": [
          "contact_name",
          "purpose",
          "script"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "create_escrow_with_clients",
      "category": "composite",
      "registryCategory": "workflow",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create an escrow AND create/link buyers and sellers in ONE atomic transaction. Use this when opening a new transaction where clients don't exist yet — it's equivalent to calling lookup_address → clients_create (×N) → escrows_create, but in a single operation that rolls back completely if any step fails. CRITICAL: representation_type determines which parties are YOUR CLIENTS — only add the party you represent. If representation_type='buyer', only add buyers (sellers are just contacts). If 'seller', only add sellers. If 'dual', add both. Returns the created escrow with all linked client IDs. After creation, use get_contingency_deadlines to calculate key dates.",
      "keywords": [
        "escrow",
        "create",
        "open transaction",
        "atomic",
        "buyer",
        "seller",
        "representation"
      ],
      "docs": "https://docs.actuallycare.com/tools/composite/create_escrow_with_clients",
      "inputSchema": {
        "type": "object",
        "properties": {
          "property_address": {
            "type": "string",
            "description": "Street address (required). Use lookup_address first for verified data."
          },
          "display_address": {
            "type": "string",
            "description": "Display address if different (e.g., with unit number)"
          },
          "city": {
            "type": "string",
            "description": "City name (from lookup_address)"
          },
          "state": {
            "type": "string",
            "pattern": "^[A-Z]{2}$",
            "description": "State abbreviation (e.g., \"CA\")"
          },
          "zip_code": {
            "type": "string",
            "pattern": "^\\d{5}(-\\d{4})?$",
            "description": "ZIP code"
          },
          "county": {
            "type": "string",
            "description": "County name — important for transfer tax calculations"
          },
          "latitude": {
            "type": "number",
            "description": "Latitude coordinate (from lookup_address)"
          },
          "longitude": {
            "type": "number",
            "description": "Longitude coordinate (from lookup_address)"
          },
          "purchase_price": {
            "type": "number",
            "minimum": 0,
            "description": "Purchase price in dollars (required)"
          },
          "buyer_commission": {
            "type": "number",
            "minimum": 0,
            "description": "Buyer agent commission in dollars"
          },
          "buyer_commission_percentage": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Buyer agent commission as percentage (e.g., 2.5)"
          },
          "seller_commission": {
            "type": "number",
            "minimum": 0,
            "description": "Seller agent commission in dollars"
          },
          "seller_commission_percentage": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Seller agent commission as percentage"
          },
          "representation_type": {
            "type": "string",
            "enum": [
              "buyer",
              "seller",
              "dual"
            ],
            "description": "Who YOU represent. CRITICAL: buyer=only add buyers as clients, seller=only add sellers, dual=add both (required)"
          },
          "acceptance_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Contract acceptance date. Used to calculate contingency deadlines. (Format: YYYY-MM-DD)"
          },
          "closing_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Expected closing date. Typically 30-45 days from acceptance. (Format: YYYY-MM-DD)"
          },
          "buyers": {
            "type": "array",
            "description": "Array of buyer info. ONLY add if representation_type is \"buyer\" or \"dual\". These become YOUR CLIENT records.",
            "items": {
              "type": "object",
              "properties": {
                "first_name": {
                  "type": "string",
                  "description": "Buyer first name (required)"
                },
                "last_name": {
                  "type": "string",
                  "description": "Buyer last name (required)"
                },
                "email": {
                  "type": "string",
                  "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
                  "description": "Buyer email"
                },
                "phone": {
                  "type": "string",
                  "description": "Buyer phone"
                }
              },
              "required": [
                "first_name",
                "last_name"
              ],
              "additionalProperties": false
            }
          },
          "sellers": {
            "type": "array",
            "description": "Array of seller info. ONLY add if representation_type is \"seller\" or \"dual\". These become YOUR CLIENT records.",
            "items": {
              "type": "object",
              "properties": {
                "first_name": {
                  "type": "string",
                  "description": "Seller first name (required)"
                },
                "last_name": {
                  "type": "string",
                  "description": "Seller last name (required)"
                },
                "email": {
                  "type": "string",
                  "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
                  "description": "Seller email"
                },
                "phone": {
                  "type": "string",
                  "description": "Seller phone"
                }
              },
              "required": [
                "first_name",
                "last_name"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "property_address",
          "purchase_price",
          "representation_type"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "log_showing_with_feedback",
      "category": "composite",
      "registryCategory": "workflow",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Log a property showing AND capture client feedback in ONE call. Use after showing a property to a buyer client. Creates a completed appointment record, logs the showing activity, and records feedback (interest level, pros, cons, notes). Equivalent to: appointments_create → appointments_update (status=completed) → log_call (with feedback notes). Returns the showing record with feedback. Use listings_list first to get listing_id if unknown.",
      "keywords": [
        "showing",
        "feedback",
        "tour",
        "pros",
        "cons",
        "interest level"
      ],
      "docs": "https://docs.actuallycare.com/tools/composite/log_showing_with_feedback",
      "inputSchema": {
        "type": "object",
        "properties": {
          "client_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the buyer client being shown the property. Use clients_list to find."
          },
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the listing being shown. Use listings_list to find by address."
          },
          "property_address": {
            "type": "string",
            "description": "Property address (required if no listing_id — for unlisted properties)"
          },
          "showing_time": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2})?$",
            "description": "When the showing occurred (defaults to now). ISO 8601 format, e.g., 2025-01-22T14:30:00Z."
          },
          "duration_minutes": {
            "type": "number",
            "minimum": 5,
            "maximum": 480,
            "description": "Duration in minutes (default: 30)"
          },
          "interest_level": {
            "type": "string",
            "enum": [
              "very_interested",
              "interested",
              "neutral",
              "not_interested",
              "rejected"
            ],
            "description": "Client interest level after viewing (required)"
          },
          "would_offer": {
            "type": "boolean",
            "description": "Would the client consider making an offer on this property?"
          },
          "pros": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "What the client liked (e.g., [\"big backyard\", \"updated kitchen\", \"quiet street\"])"
          },
          "cons": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "What the client disliked (e.g., [\"small bedrooms\", \"needs roof work\", \"busy road\"])"
          },
          "feedback_notes": {
            "type": "string",
            "description": "Detailed feedback or notes from the showing"
          },
          "schedule_follow_up": {
            "type": "boolean",
            "description": "If true, schedules a follow-up call for next business day"
          }
        },
        "required": [
          "client_id",
          "interest_level"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "create_listing_from_escrow",
      "category": "composite",
      "registryCategory": "workflow",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new listing pre-populated with data from a closed escrow. Use when a past client is selling their home (the one they bought through you). Copies property address, coordinates, and links to the seller client automatically. WORKFLOW: For seller representation on a property you previously helped buy, this saves data entry by pulling from the closed escrow. You still need to set listing_price, bedrooms, bathrooms, and other listing-specific fields. Returns the created listing with seller client linked.",
      "keywords": [
        "listing",
        "create",
        "from escrow",
        "past client",
        "seller",
        "repeat business"
      ],
      "docs": "https://docs.actuallycare.com/tools/composite/create_listing_from_escrow",
      "inputSchema": {
        "type": "object",
        "properties": {
          "escrow_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the closed escrow to copy address from. Use escrows_list status=closed to find."
          },
          "seller_client_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the seller client. Often the buyer from the original escrow."
          },
          "listing_price": {
            "type": "number",
            "minimum": 0,
            "description": "Listing price in dollars (required)"
          },
          "mls_number": {
            "type": "string",
            "description": "MLS number if already listed"
          },
          "bedrooms": {
            "type": "number",
            "minimum": 0,
            "description": "Number of bedrooms"
          },
          "bathrooms": {
            "type": "number",
            "minimum": 0,
            "description": "Number of bathrooms"
          },
          "square_feet": {
            "type": "number",
            "minimum": 0,
            "description": "Square footage"
          },
          "property_type": {
            "type": "string",
            "enum": [
              "single_family",
              "condo",
              "townhouse",
              "multi_family",
              "land",
              "commercial"
            ],
            "description": "Type of property"
          },
          "description": {
            "type": "string",
            "description": "Property description for MLS"
          },
          "listing_status": {
            "type": "string",
            "enum": [
              "coming_soon",
              "active"
            ],
            "description": "Initial listing status (default: coming_soon)"
          },
          "listing_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Date listing goes live (Format: YYYY-MM-DD)"
          },
          "expiration_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Listing expiration date (Format: YYYY-MM-DD)"
          }
        },
        "required": [
          "escrow_id",
          "listing_price"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "contacts_create",
      "aliasOf": "create_contact",
      "category": "contacts",
      "registryCategory": "data",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new contact in the CRM. Call immediately with whatever data the user provides. Do NOT ask for missing fields — the system shows an editable draft card where the user can fill in remaining details. NOTE: For clients with signed representation agreements, use clients_find_or_create instead.",
      "keywords": [
        "contact",
        "create",
        "add",
        "new",
        "directory"
      ],
      "docs": "https://docs.actuallycare.com/tools/contacts/contacts_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "first_name": {
            "type": "string",
            "description": "First name of the contact"
          },
          "last_name": {
            "type": "string",
            "description": "Last name of the contact"
          },
          "email": {
            "type": "string",
            "description": "Email address"
          },
          "phone": {
            "type": "string",
            "description": "Phone number"
          },
          "company": {
            "type": "string",
            "description": "Company or organization name"
          },
          "notes": {
            "type": "string",
            "description": "Notes about this contact"
          }
        },
        "required": [
          "first_name",
          "last_name"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "contacts_list",
      "aliasOf": "search_contacts",
      "category": "contacts",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search for contacts by name, email, phone, or other criteria. Use to find existing contacts in the CRM before creating a new one, or to look up a contact's ID for other tools. Returns matching contacts with their IDs and core contact fields.",
      "keywords": [
        "contact",
        "search",
        "list",
        "find",
        "directory"
      ],
      "docs": "https://docs.actuallycare.com/tools/contacts/contacts_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term (searches name, email, phone)"
          },
          "limit": {
            "type": "number",
            "description": "Maximum number of results to return (default 10)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "contacts_update",
      "aliasOf": "update_contact",
      "category": "contacts",
      "registryCategory": "data",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing contact's information. Only provided fields are updated — omitted fields remain unchanged. Common uses: fix a phone number or email, update the address, adjust tags. Returns the updated contact record.",
      "keywords": [
        "contact",
        "update",
        "edit",
        "modify"
      ],
      "docs": "https://docs.actuallycare.com/tools/contacts/contacts_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the contact to update"
          },
          "first_name": {
            "type": "string",
            "description": "New first name"
          },
          "last_name": {
            "type": "string",
            "description": "New last name"
          },
          "email": {
            "type": "string",
            "description": "New email address"
          },
          "phone": {
            "type": "string",
            "description": "New phone number"
          },
          "company": {
            "type": "string",
            "description": "New company name"
          },
          "notes": {
            "type": "string",
            "description": "Notes to add or update"
          }
        },
        "required": [
          "contact_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "contacts_get",
      "aliasOf": "get_contact",
      "category": "contacts",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of a specific contact by their ID — names, phones, emails, address, tags, and linked records. Use after contacts_list when you need every field for one contact. For multiple contacts, pass contact_ids instead. Returns the complete contact record.",
      "keywords": [
        "contact",
        "get",
        "details",
        "fetch"
      ],
      "docs": "https://docs.actuallycare.com/tools/contacts/contacts_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of a single contact to retrieve"
          },
          "contact_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "maxItems": 100,
            "description": "Array of contact UUIDs for batch retrieval (max 100). Use either contact_id OR contact_ids, not both."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "contacts_archive",
      "category": "contacts",
      "registryCategory": "data",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive a contact to hide them from active views without deleting their record. Archived contacts can be restored later with contacts_restore. Use this for contacts you no longer work with but want to keep their history. Returns the archived contact record.",
      "keywords": [
        "contact",
        "archive",
        "hide"
      ],
      "docs": "https://docs.actuallycare.com/tools/contacts/contacts_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "description": "UUID of the contact to archive. Use contacts_list to find the ID if unknown."
          }
        },
        "required": [
          "contact_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "contacts_restore",
      "category": "contacts",
      "registryCategory": "data",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore a previously archived contact back to active views. Reverses the effect of contacts_archive. Use this when a contact re-engages or was archived by mistake. Returns the restored contact record.",
      "keywords": [
        "contact",
        "restore",
        "unarchive"
      ],
      "docs": "https://docs.actuallycare.com/tools/contacts/contacts_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "description": "UUID of the contact to restore. Must be currently archived."
          }
        },
        "required": [
          "contact_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "contacts_delete",
      "category": "contacts",
      "registryCategory": "data",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete a contact. This is IRREVERSIBLE - the contact will be hidden from all views including archived. Only use for test data or duplicate records. For normal cleanup, use contacts_archive instead which is reversible. Returns confirmation of the deletion.",
      "keywords": [
        "contact",
        "delete",
        "remove",
        "destructive"
      ],
      "docs": "https://docs.actuallycare.com/tools/contacts/contacts_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "description": "UUID of the contact to delete. Use contacts_get first to verify."
          }
        },
        "required": [
          "contact_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "contacts_stats",
      "category": "contacts",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get aggregate statistics for all contacts: counts by status (homeowner/non_homeowner), counts by role (sphere/lead/client), and total portfolio value. Use this for dashboard metrics and network analysis. Does NOT return individual contact records - use contacts_list for that.",
      "keywords": [
        "contact",
        "stats",
        "metrics",
        "dashboard"
      ],
      "docs": "https://docs.actuallycare.com/tools/contacts/contacts_stats",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "get_contingency_deadlines",
      "category": "deadline",
      "registryCategory": "analytics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Calculate contingency dates (inspection, appraisal, loan, closing) for an escrow. ALL ARGUMENTS ARE OPTIONAL. With NO arguments, defaults to the user's most-recent active escrow — call this directly when the user asks \"what are my deadlines\" or \"show me contingency dates\" without specifying an escrow. Pass escrow_id to target a specific escrow, OR acceptance_date to compute hypothetically. Day counts default to CAR standards (inspection 17, appraisal 17, loan 21, closing 30); override only if non-standard periods were negotiated. Returns calculated dates only — not legal advice.",
      "keywords": [
        "contingency",
        "deadline",
        "inspection",
        "appraisal",
        "loan",
        "closing",
        "car",
        "rpa"
      ],
      "docs": "https://docs.actuallycare.com/tools/deadline/get_contingency_deadlines",
      "inputSchema": {
        "type": "object",
        "properties": {
          "acceptance_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "OPTIONAL. Contract acceptance date. If omitted, uses most-recent active escrow's acceptance date. (Format: YYYY-MM-DD)"
          },
          "escrow_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "OPTIONAL. Escrow UUID. If omitted, defaults to most-recent active escrow. Pass to target a specific escrow."
          },
          "inspection_days": {
            "type": "number",
            "minimum": 0,
            "maximum": 60,
            "description": "Inspection contingency days. CAR default: 17 days. Common alternatives: 10, 14, or waived (0)."
          },
          "appraisal_days": {
            "type": "number",
            "minimum": 0,
            "maximum": 60,
            "description": "Appraisal contingency days. CAR default: 17 days. Often shortened in competitive markets."
          },
          "loan_days": {
            "type": "number",
            "minimum": 0,
            "maximum": 60,
            "description": "Loan contingency days. CAR default: 21 days. Cash deals typically 0."
          },
          "closing_days": {
            "type": "number",
            "minimum": 0,
            "maximum": 120,
            "description": "Days from acceptance to close. CAR default: 30 days. Range: 21 (fast) to 60 (complex)."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "get_deadline_alerts",
      "category": "deadline",
      "registryCategory": "analytics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get upcoming deadlines across ALL active escrows. ALL ARGUMENTS ARE OPTIONAL — call with NO args for the standard daily/weekly review (default: 14 days ahead, includes past due). Use this directly when the user asks \"what's due\", \"deadline alerts\", \"what's coming up\", or \"what's past due\". Pass escrow_id only to filter to one escrow. Returns contingencies + closing dates with days until due (negative = past due) and urgency.",
      "keywords": [
        "deadline",
        "alert",
        "past due",
        "upcoming",
        "urgent",
        "review"
      ],
      "docs": "https://docs.actuallycare.com/tools/deadline/get_deadline_alerts",
      "inputSchema": {
        "type": "object",
        "properties": {
          "days_ahead": {
            "type": "number",
            "minimum": 1,
            "maximum": 90,
            "description": "How many days ahead to look for upcoming deadlines. Default: 14 days. Use 7 for weekly review, 30 for monthly planning."
          },
          "include_past_due": {
            "type": "boolean",
            "description": "Include past due deadlines in results. Default: true. Critical for catching missed deadlines."
          },
          "escrow_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Filter to a specific escrow. If not provided, returns deadlines from ALL active escrows."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "get_escrow_checklist",
      "category": "deadline",
      "registryCategory": "analytics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get a transaction checklist tailored to your representation type (buyer, seller, or dual agency). Use at contract acceptance to see what's ahead, or mid-transaction to check what's still open. Returns common transaction tasks with suggested due dates calculated from acceptance and closing dates based on standard CAR contract timelines. This is a general reference checklist — not a comprehensive legal compliance tool. Your broker or transaction coordinator can advise on the specific tasks and disclosures required for each transaction.",
      "keywords": [
        "checklist",
        "transaction",
        "buyer",
        "seller",
        "dual",
        "task list"
      ],
      "docs": "https://docs.actuallycare.com/tools/deadline/get_escrow_checklist",
      "inputSchema": {
        "type": "object",
        "properties": {
          "representation_type": {
            "type": "string",
            "enum": [
              "buyer",
              "seller",
              "dual"
            ],
            "description": "Who you represent determines the checklist. buyer=BRBC tasks, seller=listing/disclosure tasks, dual=both sets. Default: buyer."
          },
          "escrow_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Escrow UUID to get dates from. If provided, acceptance_date and closing_date are read from the escrow record."
          },
          "acceptance_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Contract acceptance date for calculating task due dates. Required if escrow_id not provided. (Format: YYYY-MM-DD)"
          },
          "closing_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Expected closing date. Required if escrow_id not provided. (Format: YYYY-MM-DD)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "log_call",
      "category": "deadline",
      "registryCategory": "analytics",
      "annotation": "Logs activity",
      "readOnly": false,
      "destructive": false,
      "description": "Log a phone call with a contact, lead, or escrow party for CRM tracking. IMPORTANT: This creates a permanent call log record — use this to track ALL phone communications for follow-up history and compliance. Provide EITHER contact_id, lead_id, OR phone_number to identify who was called. Outcomes track the call result for follow-up automation. If outcome is 'callback_requested' or 'scheduled_appointment', the follow_up_date and follow_up_notes are especially important. Call logs appear in the contact/lead activity timeline and can be used for prospecting reports.",
      "keywords": [
        "call",
        "log",
        "phone",
        "voicemail",
        "follow-up",
        "activity"
      ],
      "docs": "https://docs.actuallycare.com/tools/deadline/log_call",
      "inputSchema": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the contact called. Use contacts_list to find ID if unknown."
          },
          "lead_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the lead called. Use leads_list to find ID if unknown."
          },
          "escrow_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of related escrow if this call was about a specific transaction."
          },
          "phone_number": {
            "type": "string",
            "pattern": "^\\+?1?[-.]?\\(?\\d{3}\\)?[-.]?\\d{3}[-.]?\\d{4}$",
            "description": "Phone number called. Use if you do not have a contact_id or lead_id. Format: (555) 123-4567 or 5551234567."
          },
          "direction": {
            "type": "string",
            "enum": [
              "inbound",
              "outbound"
            ],
            "description": "Call direction. outbound=you called them, inbound=they called you. Default: outbound."
          },
          "outcome": {
            "type": "string",
            "enum": [
              "connected",
              "voicemail",
              "no_answer",
              "busy",
              "wrong_number",
              "callback_requested",
              "not_interested",
              "scheduled_appointment",
              "other"
            ],
            "description": "Result of the call. Required for proper follow-up tracking. Use connected for live conversations, voicemail for messages left."
          },
          "duration_minutes": {
            "type": "number",
            "minimum": 0,
            "maximum": 480,
            "description": "Call duration in minutes. Helps track engagement time for reporting."
          },
          "subject": {
            "type": "string",
            "maxLength": 200,
            "description": "Brief subject/reason for call. Examples: \"Listing follow-up\", \"Offer update\", \"Market check-in\"."
          },
          "notes": {
            "type": "string",
            "maxLength": 5000,
            "description": "Detailed notes from the call. What was discussed, action items, client concerns, etc."
          },
          "follow_up_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Date to follow up with this person. Especially important for callback_requested or voicemail outcomes. (Format: YYYY-MM-DD)"
          },
          "follow_up_notes": {
            "type": "string",
            "maxLength": 1000,
            "description": "Specific notes for the follow-up. What to discuss, preparation needed, etc."
          }
        },
        "required": [
          "outcome"
        ],
        "anyOf": [
          {
            "required": [
              "contact_id"
            ]
          },
          {
            "required": [
              "lead_id"
            ]
          },
          {
            "required": [
              "phone_number"
            ]
          }
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "get_follow_up_reminders",
      "category": "deadline",
      "registryCategory": "analytics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get contacts and leads that need follow-up for daily prospecting and client management. Returns people who: (1) have scheduled follow-ups due today or past due, (2) haven't been contacted in X days (configurable). Essential for maintaining relationships and not letting leads go cold. Results are sorted by urgency — past due first, then scheduled follow-ups, then stale contacts. Use this every morning to build your call list. For leads, you can filter by status to focus on new/contacted leads vs qualified ones.",
      "keywords": [
        "follow-up",
        "reminder",
        "stale",
        "morning",
        "call list",
        "prospecting"
      ],
      "docs": "https://docs.actuallycare.com/tools/deadline/get_follow_up_reminders",
      "inputSchema": {
        "type": "object",
        "properties": {
          "days_since_contact": {
            "type": "number",
            "minimum": 1,
            "maximum": 365,
            "description": "Show contacts/leads not contacted in X days. Default: 7 days. Use 14 for less aggressive follow-up."
          },
          "include_scheduled": {
            "type": "boolean",
            "description": "Include people with scheduled follow-ups due. Default: true. Set false to only see stale contacts."
          },
          "lead_status": {
            "type": "string",
            "enum": [
              "new",
              "contacted",
              "qualified",
              "all"
            ],
            "description": "Filter leads by status. new=fresh leads, contacted=in touch, qualified=ready to transact, all=all active leads. Default: all."
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 100,
            "description": "Maximum results to return. Default: 20. Use higher for comprehensive review."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "create_open_house",
      "category": "deadline",
      "registryCategory": "analytics",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Schedule an open house event for a listing. Creates a special appointment of type \"open_house\" linked to the listing for marketing and visitor tracking. Provide EITHER listing_id to link to an existing listing OR property_address for a one-off event. Types: public (general public), broker (agents only), twilight (evening showing), mega (large event with multiple agents). After creating, use log_open_house_visitor during the event to capture attendee information and automatically create leads.",
      "keywords": [
        "open house",
        "event",
        "broker preview",
        "twilight",
        "mega",
        "schedule"
      ],
      "docs": "https://docs.actuallycare.com/tools/deadline/create_open_house",
      "inputSchema": {
        "type": "object",
        "properties": {
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the listing this open house is for. Use listings_list to find ID."
          },
          "property_address": {
            "type": "string",
            "description": "Property address if no listing record exists. One of listing_id or property_address required."
          },
          "start_time": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2})?$",
            "description": "Start date and time. Examples: \"2025-01-25T13:00:00\" for 1 PM, \"2025-01-25T10:00:00\" for 10 AM. (ISO 8601 format, e.g., 2025-01-22T14:30:00Z)"
          },
          "end_time": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2})?$",
            "description": "End date and time. Typical duration: 2-4 hours for public, 1-2 hours for broker open. (ISO 8601 format, e.g., 2025-01-22T14:30:00Z)"
          },
          "open_house_type": {
            "type": "string",
            "enum": [
              "public",
              "broker",
              "twilight",
              "mega"
            ],
            "description": "Type of open house. public=general public (most common), broker=agent preview, twilight=evening showing, mega=large event."
          },
          "notes": {
            "type": "string",
            "maxLength": 2000,
            "description": "Notes or special instructions. Examples: \"Parking in rear\", \"No shoes inside\", \"Refreshments provided\"."
          }
        },
        "required": [
          "start_time"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "log_open_house_visitor",
      "category": "deadline",
      "registryCategory": "analytics",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Log a visitor at an open house to capture their information. AUTOMATICALLY creates a LEAD record with the open house as the source — this is your primary lead generation tool at open houses. Capture as much information as possible: buyer_status helps prioritize follow-up, working_with_agent indicates if they're represented, price_range helps match them to listings. Link to open_house_id (appointment) or listing_id. After the open house, use get_hot_leads to see which visitors should be contacted first based on their engagement score.",
      "keywords": [
        "open house",
        "visitor",
        "sign-in",
        "lead capture",
        "walk-in"
      ],
      "docs": "https://docs.actuallycare.com/tools/deadline/log_open_house_visitor",
      "inputSchema": {
        "type": "object",
        "properties": {
          "open_house_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the open house appointment. Links visitor to specific event for tracking."
          },
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the listing. Alternative if no open_house_id — useful for walk-in visitors."
          },
          "first_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "Visitor first name. Required for lead creation."
          },
          "last_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "Visitor last name. Required for lead creation."
          },
          "email": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
            "description": "Visitor email. Critical for follow-up — try to get this!"
          },
          "phone": {
            "type": "string",
            "pattern": "^\\+?1?[-.]?\\(?\\d{3}\\)?[-.]?\\d{3}[-.]?\\d{4}$",
            "description": "Visitor phone. Important for quick follow-up calls."
          },
          "buyer_status": {
            "type": "string",
            "enum": [
              "just_looking",
              "starting_search",
              "actively_searching",
              "ready_to_buy",
              "pre_approved"
            ],
            "description": "Buyer readiness. pre_approved and ready_to_buy are highest priority. just_looking may be long-term nurture."
          },
          "working_with_agent": {
            "type": "boolean",
            "description": "Already working with another agent? If true, be mindful of ethics rules."
          },
          "interested_in_property": {
            "type": "boolean",
            "description": "Interested in THIS specific property? Helps gauge if they are a buyer lead or just curious."
          },
          "price_range_min": {
            "type": "number",
            "minimum": 0,
            "description": "Minimum price range. Helps match to other listings."
          },
          "price_range_max": {
            "type": "number",
            "minimum": 0,
            "description": "Maximum price range. Helps match to other listings."
          },
          "interest_level": {
            "type": "string",
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "description": "Overall interest level in the property. Helps prioritize follow-up after the open house."
          },
          "notes": {
            "type": "string",
            "maxLength": 2000,
            "description": "Additional notes. Feedback on property, what they are looking for, timeline, etc."
          }
        },
        "required": [
          "first_name",
          "last_name"
        ],
        "anyOf": [
          {
            "required": [
              "email"
            ]
          },
          {
            "required": [
              "phone"
            ]
          }
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "deals_list",
      "category": "deals",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search for vendor deals by title, status, vendor type, or deal type. Returns pagination info (total_count, has_more, offset, limit). Results include: id, display_id, title, vendor_type, deal_type, status, payment_status, amount, fee, commission_amount, property_address, contact info, created_at. Filter by status (pending/in_progress/completed/invoiced/paid/cancelled/disputed), payment_status (unpaid/invoiced/paid/refunded), vendor_type, or deal_type. For a specific deal by ID, use deals_get instead. For aggregate stats, use deals_stats.",
      "keywords": [
        "deal",
        "deals",
        "vendor",
        "transaction",
        "payment",
        "list",
        "search",
        "pipeline"
      ],
      "docs": "https://docs.actuallycare.com/tools/deals/deals_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term - matches against title, property_address, notes (case-insensitive partial match)"
          },
          "status": {
            "type": "string",
            "enum": [
              "all",
              "pending",
              "in_progress",
              "completed",
              "invoiced",
              "paid",
              "cancelled",
              "disputed"
            ],
            "description": "Filter by status. pending=awaiting start, in_progress=work underway, completed=work done, invoiced=invoice sent, paid=payment received, cancelled=deal off, disputed=payment issue (default: all)"
          },
          "payment_status": {
            "type": "string",
            "enum": [
              "all",
              "unpaid",
              "invoiced",
              "paid",
              "refunded"
            ],
            "description": "Filter by payment status (default: all)"
          },
          "vendor_type": {
            "type": "string",
            "description": "Filter by vendor type (e.g. lender, inspector, escrow_officer, title_rep, appraiser, contractor, photographer)"
          },
          "deal_type": {
            "type": "string",
            "description": "Filter by deal type (e.g. inspection, appraisal, escrow_service, title_service, photography, staging, repair)"
          },
          "vertical": {
            "type": "string",
            "description": "Filter by industry vertical (e.g., lending, insurance, inspection)"
          },
          "date_from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show deals created on or after this date (Format: YYYY-MM-DD)"
          },
          "date_to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show deals created on or before this date (Format: YYYY-MM-DD)"
          },
          "archived": {
            "type": "boolean",
            "description": "Include archived deals (default: false)"
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 500,
            "description": "Maximum results (default: 50, max: 500)"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N results for pagination (default: 0)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "deals_get",
      "category": "deals",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of a vendor deal by UUID, including contact info, vendor type, deal type, financial details (amount, fee, commission), linked partner, linked escrow, property address, notes, and tags. Returns all fields. If you don't have the UUID, use deals_list first.",
      "keywords": [
        "deal",
        "detail",
        "get",
        "view",
        "vendor",
        "transaction"
      ],
      "docs": "https://docs.actuallycare.com/tools/deals/deals_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "deal_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the deal. Use deals_list to find IDs."
          }
        },
        "required": [
          "deal_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "deals_create",
      "category": "deals",
      "registryCategory": "generics",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new vendor deal to track a transaction or payment with a vendor partner. WORKFLOW: 1) Optionally use contacts_list to find the contact, partners_list to find the partner, and escrows_list to find the escrow 2) Create the deal with vendor_type, deal details, and financial info. Returns the created deal with ID and display_id.",
      "keywords": [
        "deal",
        "create",
        "new",
        "add",
        "vendor",
        "transaction",
        "payment"
      ],
      "docs": "https://docs.actuallycare.com/tools/deals/deals_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of an existing contact for this deal. Use contacts_list to find."
          },
          "vendor_type": {
            "type": "string",
            "description": "Type of vendor (e.g. lender, inspector, escrow_officer, title_rep, appraiser, contractor, photographer)"
          },
          "partner_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the linked partner. Use partners_list to find."
          },
          "escrow_service_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the linked escrow service record."
          },
          "escrow_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the linked escrow. Use escrows_list to find."
          },
          "title": {
            "type": "string",
            "description": "Title or description for this deal (e.g. \"Home Inspection - 123 Main St\")"
          },
          "deal_type": {
            "type": "string",
            "description": "Type of deal (e.g. inspection, appraisal, escrow_service, title_service, photography, staging, repair)"
          },
          "amount": {
            "type": "number",
            "minimum": 0,
            "description": "Total deal amount in dollars"
          },
          "fee": {
            "type": "number",
            "minimum": 0,
            "description": "Service fee amount in dollars"
          },
          "commission_amount": {
            "type": "number",
            "minimum": 0,
            "description": "Commission or referral amount in dollars"
          },
          "property_address": {
            "type": "string",
            "description": "Property address associated with this deal"
          },
          "notes": {
            "type": "string",
            "description": "Additional notes about the deal"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tags for categorization (e.g. [\"rush\", \"repeat-client\", \"discounted\"])"
          }
        },
        "required": [
          "vendor_type"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "deals_update",
      "category": "deals",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing vendor deal's information or status. Only provided fields are updated - omitted fields remain unchanged. Common uses: status change (pending->in_progress->completed->invoiced->paid), update financial details, link to escrow. Returns the updated deal record.",
      "keywords": [
        "deal",
        "update",
        "edit",
        "modify",
        "status",
        "vendor"
      ],
      "docs": "https://docs.actuallycare.com/tools/deals/deals_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "deal_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the deal to update (required). Use deals_list to find."
          },
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated contact ID. Use contacts_list to find."
          },
          "vendor_type": {
            "type": "string",
            "description": "Updated vendor type"
          },
          "partner_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated partner ID. Use partners_list to find."
          },
          "escrow_service_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated escrow service record ID."
          },
          "escrow_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated escrow ID. Use escrows_list to find."
          },
          "title": {
            "type": "string",
            "description": "Updated title"
          },
          "deal_type": {
            "type": "string",
            "description": "Updated deal type"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "in_progress",
              "completed",
              "invoiced",
              "paid",
              "cancelled",
              "disputed"
            ],
            "description": "Updated status"
          },
          "payment_status": {
            "type": "string",
            "enum": [
              "unpaid",
              "invoiced",
              "paid",
              "refunded"
            ],
            "description": "Updated payment status"
          },
          "amount": {
            "type": "number",
            "minimum": 0,
            "description": "Updated deal amount"
          },
          "fee": {
            "type": "number",
            "minimum": 0,
            "description": "Updated service fee"
          },
          "commission_amount": {
            "type": "number",
            "minimum": 0,
            "description": "Updated commission amount"
          },
          "property_address": {
            "type": "string",
            "description": "Updated property address"
          },
          "notes": {
            "type": "string",
            "description": "Updated notes"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Updated tags array (replaces existing tags)"
          },
          "care_status": {
            "type": "string",
            "enum": [
              "no_status",
              "cared",
              "needs_care",
              "didnt_care"
            ],
            "description": "Care status for tracking. Setting this also updates care_status_updated_at and care_status_updated_by audit columns."
          },
          "care_status_note": {
            "type": "string",
            "description": "Note explaining the care status change (audit trail)."
          },
          "started_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2})?$",
            "description": "Timestamp the deal work started. Usually set alongside status=in_progress. (ISO 8601 format, e.g., 2025-01-22T14:30:00Z)"
          },
          "completed_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2})?$",
            "description": "Timestamp the deal was completed. Usually set alongside status=completed. (ISO 8601 format, e.g., 2025-01-22T14:30:00Z)"
          },
          "paid_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Date the deal was paid out. Usually set alongside payment_status=paid. (Format: YYYY-MM-DD)"
          },
          "record_data": {
            "type": "object",
            "additionalProperties": true,
            "description": "Pipeline-specific vertical data as a JSON object. Replaces (does not merge with) the existing record_data."
          }
        },
        "required": [
          "deal_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "deals_stats",
      "category": "deals",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get aggregate statistics for vendor deals: total count, counts by status, counts by payment status, total revenue, total fees, total commissions, counts by vendor type. Use this for dashboard metrics and financial summaries. Does NOT return individual records - use deals_list for that.",
      "keywords": [
        "deal",
        "stats",
        "metrics",
        "dashboard",
        "aggregate",
        "revenue",
        "summary"
      ],
      "docs": "https://docs.actuallycare.com/tools/deals/deals_stats",
      "inputSchema": {
        "type": "object",
        "properties": {
          "period": {
            "type": "string",
            "enum": [
              "1_day",
              "1_week",
              "1_month",
              "3_months",
              "1_year",
              "ytd",
              "all"
            ],
            "description": "Time period for stats (default: 1_month)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "deals_archive",
      "category": "deals",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive a vendor deal to hide it from active views without deleting it. Archived deals can be restored later with deals_restore. Use this for completed or cancelled deals you want to declutter from your dashboard. Returns the archived record.",
      "keywords": [
        "deal",
        "archive",
        "hide",
        "declutter"
      ],
      "docs": "https://docs.actuallycare.com/tools/deals/deals_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "deal_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the deal to archive. Use deals_list to find."
          }
        },
        "required": [
          "deal_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "deals_restore",
      "category": "deals",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore a previously archived vendor deal back to active views. Reverses the effect of deals_archive. Returns the restored record.",
      "keywords": [
        "deal",
        "restore",
        "unarchive",
        "recover"
      ],
      "docs": "https://docs.actuallycare.com/tools/deals/deals_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "deal_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the deal to restore. Must be currently archived."
          }
        },
        "required": [
          "deal_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "deals_delete",
      "category": "deals",
      "registryCategory": "generics",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete a vendor deal. This is IRREVERSIBLE - the deal will be hidden from all views including archived. The deal must be archived first. For normal cleanup, use deals_archive instead, which is reversible.",
      "keywords": [
        "deal",
        "delete",
        "remove",
        "destroy",
        "permanent"
      ],
      "docs": "https://docs.actuallycare.com/tools/deals/deals_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "deal_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the deal to delete. Must be archived first. Use deals_get to verify."
          }
        },
        "required": [
          "deal_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "documents_get_risks",
      "category": "documents",
      "registryCategory": "operations",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get the latest AI risk analysis for a document the agent owns. Returns findings (each with id, severity P0/P1/P2, title, description, citation, recommendation), summary counts (p0_count, p1_count, p2_count, overall_severity, headline), and the analysis state (pending / in_review / acknowledged / escalated / resolved). Returns null if no analysis has been run on this document yet — the agent must trigger analysis from the web app first (Risk Analysis modal on the document detail page). The findings are AI-generated risk signals, not legal advice; always defer to the agent's broker or attorney for actual decisions.",
      "keywords": [
        "document",
        "risk",
        "analysis",
        "findings",
        "review",
        "compliance",
        "rpa",
        "tds"
      ],
      "docs": "https://docs.actuallycare.com/tools/documents/documents_get_risks",
      "inputSchema": {
        "type": "object",
        "properties": {
          "document_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50,
            "description": "The document_id (e.g. \"doc_7022796200ff\"). Get this from the documents tool or from an escrow's document list."
          }
        },
        "required": [
          "document_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "documents_list",
      "category": "documents",
      "registryCategory": "operations",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "List the documents attached to a specific entity (escrow, listing, client, lead, or appointment). Returns each document id (pass it to documents_get_risks), filename, original_name, document_type, category, mime_type, file_size, requires_signature, signed_at, is_primary_contract, and created_at, newest first. Use this to see what is on file for a transaction (the RPA, TDS, NHD, pre-approval on an escrow). Read-only; returns only documents the agent can access under their tenant scope.",
      "keywords": [
        "document",
        "documents",
        "list",
        "files",
        "attachments",
        "escrow",
        "rpa",
        "tds",
        "nhd",
        "disclosure"
      ],
      "docs": "https://docs.actuallycare.com/tools/documents/documents_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "entity_type": {
            "type": "string",
            "enum": [
              "escrow",
              "listing",
              "client",
              "lead",
              "appointment"
            ],
            "description": "The kind of record the documents are attached to."
          },
          "entity_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50,
            "description": "The id of the escrow, listing, client, lead, or appointment."
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 200,
            "description": "Max documents to return (default 50)."
          }
        },
        "required": [
          "entity_type",
          "entity_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "lookup_dre_license",
      "category": "dre-license",
      "registryCategory": "integration",
      "annotation": "External lookup",
      "readOnly": true,
      "destructive": false,
      "description": "Look up a California DRE (Department of Real Estate) license by ID. Returns comprehensive license information: license type (salesperson/broker/corporation), licensee name, license status (active/inactive/expired/cancelled), expiration date, business and mailing addresses, and for salespersons: their responsible broker information. Works for all license types: salesperson (starts with 01 or 02), broker (01 or 02), corporation (01). Use this to verify agents you are working with or to look up cooperating brokers. Note: This makes an external API call to the DRE — expect a 1-3 second response time.",
      "keywords": [
        "dre",
        "license",
        "california",
        "lookup",
        "verify",
        "agent",
        "broker"
      ],
      "docs": "https://docs.actuallycare.com/tools/dre-license/lookup_dre_license",
      "inputSchema": {
        "type": "object",
        "properties": {
          "license_id": {
            "type": "string",
            "pattern": "^[0-9]{8}$",
            "description": "The 8-digit DRE license ID. Examples: \"02203217\" (salesperson), \"01910265\" (corporation), \"00123456\" (broker). Leading zeros required."
          }
        },
        "required": [
          "license_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "engagements_list",
      "category": "engagements",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search for vendor engagements by title, status, vendor type, or engagement type. Returns pagination info (total_count, has_more, offset, limit). Results include: id, display_id, title, vendor_type, engagement_type, status, scheduled_date, scheduled_time, duration_minutes, location, contact info, created_at. Filter by status (proposed/scheduled/in_progress/follow_up/completed/cancelled), vendor_type, or engagement_type. For a specific engagement by ID, use engagements_get instead. For aggregate stats, use engagements_stats.",
      "keywords": [
        "engagement",
        "engagements",
        "meeting",
        "call",
        "event",
        "vendor",
        "list",
        "search"
      ],
      "docs": "https://docs.actuallycare.com/tools/engagements/engagements_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term - matches against title, notes (case-insensitive partial match)"
          },
          "status": {
            "type": "string",
            "enum": [
              "all",
              "proposed",
              "scheduled",
              "in_progress",
              "follow_up",
              "completed",
              "cancelled"
            ],
            "description": "Filter by status. proposed=suggested, scheduled=confirmed, in_progress=happening now, follow_up=needs follow-up, completed=done, cancelled=not happening (default: all)"
          },
          "vendor_type": {
            "type": "string",
            "description": "Filter by vendor type (e.g. lender, inspector, escrow_officer, title_rep, appraiser, contractor, photographer)"
          },
          "engagement_type": {
            "type": "string",
            "description": "Filter by engagement type (e.g. coffee_meeting, lunch, phone_call, office_visit, networking_event, training, co_marketing)"
          },
          "date_from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show engagements scheduled on or after this date (Format: YYYY-MM-DD)"
          },
          "date_to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show engagements scheduled on or before this date (Format: YYYY-MM-DD)"
          },
          "archived": {
            "type": "boolean",
            "description": "Include archived engagements (default: false)"
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 500,
            "description": "Maximum results (default: 50, max: 500)"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N results for pagination (default: 0)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "engagements_get",
      "category": "engagements",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of a vendor engagement by UUID, including contact info, vendor type, engagement type, schedule, location, meeting URL, notes, tags, and linked prospect. Returns all fields. If you don't have the UUID, use engagements_list first.",
      "keywords": [
        "engagement",
        "detail",
        "get",
        "view",
        "meeting",
        "vendor"
      ],
      "docs": "https://docs.actuallycare.com/tools/engagements/engagements_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "engagement_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the engagement. Use engagements_list to find IDs."
          }
        },
        "required": [
          "engagement_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "engagements_create",
      "category": "engagements",
      "registryCategory": "generics",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new vendor engagement to track a meeting, call, or event with a vendor. WORKFLOW: 1) Optionally use contacts_list to find the contact and prospects_list to find the prospect 2) Create the engagement with vendor_type, type, and schedule details. Returns the created engagement with ID and display_id.",
      "keywords": [
        "engagement",
        "create",
        "new",
        "add",
        "meeting",
        "call",
        "schedule",
        "vendor"
      ],
      "docs": "https://docs.actuallycare.com/tools/engagements/engagements_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of an existing contact for this engagement. Use contacts_list to find."
          },
          "vendor_type": {
            "type": "string",
            "description": "Type of vendor (e.g. lender, inspector, escrow_officer, title_rep, appraiser, contractor, photographer)"
          },
          "prospect_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the linked prospect. Use prospects_list to find."
          },
          "title": {
            "type": "string",
            "description": "Title or description for this engagement (e.g. \"Coffee with John - Title Rep\")"
          },
          "engagement_type": {
            "type": "string",
            "description": "Type of engagement (e.g. coffee_meeting, lunch, phone_call, office_visit, networking_event, training, co_marketing)"
          },
          "scheduled_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Date of the engagement (Format: YYYY-MM-DD)"
          },
          "scheduled_time": {
            "type": "string",
            "description": "Time of the engagement (e.g. \"14:30\", \"2:30 PM\")"
          },
          "duration_minutes": {
            "type": "number",
            "minimum": 1,
            "description": "Expected duration in minutes (e.g. 30, 60, 90)"
          },
          "location": {
            "type": "string",
            "description": "Physical location or address for the engagement"
          },
          "meeting_url": {
            "type": "string",
            "description": "Virtual meeting URL (Zoom, Google Meet, etc.)"
          },
          "notes": {
            "type": "string",
            "description": "Additional notes or agenda items for the engagement"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tags for categorization (e.g. [\"first-meeting\", \"follow-up\", \"co-marketing\"])"
          }
        },
        "required": [
          "vendor_type"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "engagements_update",
      "category": "engagements",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing vendor engagement's information or status. Only provided fields are updated - omitted fields remain unchanged. Common uses: status change (proposed->scheduled->in_progress->completed), reschedule, add follow-up notes. Returns the updated engagement record.",
      "keywords": [
        "engagement",
        "update",
        "edit",
        "modify",
        "reschedule",
        "status",
        "meeting",
        "vendor"
      ],
      "docs": "https://docs.actuallycare.com/tools/engagements/engagements_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "engagement_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the engagement to update (required). Use engagements_list to find."
          },
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated contact ID. Use contacts_list to find."
          },
          "vendor_type": {
            "type": "string",
            "description": "Updated vendor type"
          },
          "prospect_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated prospect ID. Use prospects_list to find."
          },
          "title": {
            "type": "string",
            "description": "Updated title"
          },
          "engagement_type": {
            "type": "string",
            "description": "Updated engagement type"
          },
          "status": {
            "type": "string",
            "enum": [
              "proposed",
              "scheduled",
              "in_progress",
              "follow_up",
              "completed",
              "cancelled"
            ],
            "description": "Updated status"
          },
          "scheduled_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Updated scheduled date (Format: YYYY-MM-DD)"
          },
          "scheduled_time": {
            "type": "string",
            "description": "Updated scheduled time"
          },
          "duration_minutes": {
            "type": "number",
            "minimum": 1,
            "description": "Updated duration in minutes"
          },
          "location": {
            "type": "string",
            "description": "Updated location"
          },
          "meeting_url": {
            "type": "string",
            "description": "Updated meeting URL"
          },
          "notes": {
            "type": "string",
            "description": "Updated notes"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Updated tags array (replaces existing tags)"
          },
          "care_status": {
            "type": "string",
            "enum": [
              "no_status",
              "cared",
              "needs_care",
              "didnt_care"
            ],
            "description": "Care status for tracking. Setting this also updates care_status_updated_at and care_status_updated_by audit columns."
          },
          "care_status_note": {
            "type": "string",
            "description": "Note explaining the care status change (audit trail)."
          },
          "completed_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2})?$",
            "description": "Timestamp the engagement was completed. Usually set alongside status=completed. (ISO 8601 format, e.g., 2025-01-22T14:30:00Z)"
          },
          "record_data": {
            "type": "object",
            "additionalProperties": true,
            "description": "Pipeline-specific vertical data as a JSON object. Replaces (does not merge with) the existing record_data."
          }
        },
        "required": [
          "engagement_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "engagements_stats",
      "category": "engagements",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get aggregate statistics for vendor engagements: total count, counts by status, counts by vendor type, counts by engagement type, upcoming engagements count. Use this for dashboard metrics. Does NOT return individual records - use engagements_list for that.",
      "keywords": [
        "engagement",
        "stats",
        "metrics",
        "dashboard",
        "aggregate",
        "meetings"
      ],
      "docs": "https://docs.actuallycare.com/tools/engagements/engagements_stats",
      "inputSchema": {
        "type": "object",
        "properties": {
          "period": {
            "type": "string",
            "enum": [
              "1_day",
              "1_week",
              "1_month",
              "3_months",
              "1_year",
              "ytd",
              "all"
            ],
            "description": "Time period for stats (default: 1_month)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "engagements_archive",
      "category": "engagements",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive a vendor engagement to hide it from active views without deleting it. Archived engagements can be restored later with engagements_restore. Use this for completed or cancelled engagements you want to declutter from your dashboard. Returns the archived record.",
      "keywords": [
        "engagement",
        "archive",
        "hide",
        "declutter"
      ],
      "docs": "https://docs.actuallycare.com/tools/engagements/engagements_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "engagement_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the engagement to archive. Use engagements_list to find."
          }
        },
        "required": [
          "engagement_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "engagements_restore",
      "category": "engagements",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore a previously archived vendor engagement back to active views. Reverses the effect of engagements_archive. Returns the restored record.",
      "keywords": [
        "engagement",
        "restore",
        "unarchive",
        "recover"
      ],
      "docs": "https://docs.actuallycare.com/tools/engagements/engagements_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "engagement_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the engagement to restore. Must be currently archived."
          }
        },
        "required": [
          "engagement_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "engagements_delete",
      "category": "engagements",
      "registryCategory": "generics",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete a vendor engagement. This is IRREVERSIBLE - the engagement will be hidden from all views including archived. The engagement must be archived first. For normal cleanup, use engagements_archive instead, which is reversible.",
      "keywords": [
        "engagement",
        "delete",
        "remove",
        "destroy",
        "permanent"
      ],
      "docs": "https://docs.actuallycare.com/tools/engagements/engagements_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "engagement_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the engagement to delete. Must be archived first. Use engagements_get to verify."
          }
        },
        "required": [
          "engagement_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "entity_links_list",
      "category": "entity-links",
      "registryCategory": "operations",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "List entity links for a specific entity. Query by entity_type + entity_id to find all related entities across verticals — for example all deals linked to an escrow, or all escrows linked to a deal. Use before creating a link (to avoid duplicates) or to navigate between related records. Returns the matching links with both endpoints and each link's ID.",
      "keywords": [
        "entity",
        "link",
        "related",
        "cross-vertical",
        "relationship",
        "list"
      ],
      "docs": "https://docs.actuallycare.com/tools/entity-links/entity_links_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term (not used for entity links — use entity_type + entity_id instead)"
          },
          "entity_type": {
            "type": "string",
            "enum": [
              "escrow",
              "deal",
              "lead",
              "client",
              "appointment",
              "listing"
            ],
            "description": "Type of entity to find links for"
          },
          "entity_id": {
            "type": "string",
            "description": "ID of the entity to find links for"
          },
          "source_type": {
            "type": "string",
            "description": "Filter by source entity type"
          },
          "source_id": {
            "type": "string",
            "description": "Filter by source entity ID"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "entity_links_create",
      "category": "entity-links",
      "registryCategory": "operations",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a cross-vertical link between two entities (e.g., link a lending deal to a real estate escrow). Both entities must exist. The link is queryable from either side.",
      "keywords": [
        "entity",
        "link",
        "create",
        "related",
        "cross-vertical",
        "connect"
      ],
      "docs": "https://docs.actuallycare.com/tools/entity-links/entity_links_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "source_type": {
            "type": "string",
            "enum": [
              "escrow",
              "deal",
              "lead",
              "client",
              "appointment",
              "listing"
            ],
            "description": "Source entity type"
          },
          "source_id": {
            "type": "string",
            "description": "Source entity ID"
          },
          "source_vertical": {
            "type": "string",
            "description": "Source entity vertical (e.g., real_estate, lending)"
          },
          "target_type": {
            "type": "string",
            "enum": [
              "escrow",
              "deal",
              "lead",
              "client",
              "appointment",
              "listing"
            ],
            "description": "Target entity type"
          },
          "target_id": {
            "type": "string",
            "description": "Target entity ID"
          },
          "target_vertical": {
            "type": "string",
            "description": "Target entity vertical"
          },
          "link_type": {
            "type": "string",
            "enum": [
              "related",
              "converted_from",
              "depends_on",
              "parent_of",
              "assigned_to"
            ],
            "description": "Type of relationship (default: related)"
          },
          "notes": {
            "type": "string",
            "description": "Optional notes about the relationship"
          }
        },
        "required": [
          "source_type",
          "source_id",
          "source_vertical",
          "target_type",
          "target_id",
          "target_vertical"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "entity_links_delete",
      "category": "entity-links",
      "registryCategory": "operations",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Remove a cross-vertical entity link by its ID. Use when two records were linked by mistake or the relationship no longer applies — the linked records themselves are not touched. Find the link ID with entity_links_list first. Returns confirmation of the deletion.",
      "keywords": [
        "entity",
        "link",
        "delete",
        "remove",
        "unlink"
      ],
      "docs": "https://docs.actuallycare.com/tools/entity-links/entity_links_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the entity link to remove"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "escrows_list",
      "aliasOf": "search_escrows",
      "category": "escrows",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search for escrows. Returns IDs only by default for efficiency.\n\nResponse includes relatedIds with BOTH clientIds and contactIds:\n- relatedIds.clientIds: CLIENT table IDs → use with clients_bulk_update\n- relatedIds.contactIds: CONTACT table IDs → use with contacts_get (contact_ids)\n\nWORKFLOW: To mark clients as closed when escrow closes:\n1. escrows_list({ status: 'closed' }) → get relatedIds.clientIds\n2. clients_bulk_update({ client_ids: relatedIds.clientIds, updates: { status: 'closed' } })\n\nDirect workflow - no intermediate clients_list step needed!",
      "keywords": [
        "escrow",
        "transaction",
        "search",
        "list",
        "find",
        "deal"
      ],
      "docs": "https://docs.actuallycare.com/tools/escrows/escrows_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term (searches property address, escrow number)"
          },
          "status": {
            "type": "string",
            "enum": [
              "all",
              "active",
              "pending",
              "closed",
              "cancelled",
              "fell_through"
            ],
            "description": "Filter by escrow status (default: all)"
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "basic",
                "dates",
                "financial",
                "clients",
                "location",
                "property",
                "full"
              ]
            },
            "description": "Field groups to include. Empty/omitted = IDs only (most efficient). Options: basic (id, display_id, address, status), dates (closing_date, etc), financial (price, commission), clients (buyers/sellers), location (city, state), property (beds, baths), full (all fields)."
          },
          "limit": {
            "type": [
              "string",
              "number"
            ],
            "maximum": 200,
            "description": "Max results. Use a number (e.g. \"25\") or \"all\". \"all\" and any value above 200 are capped at 200 server-side."
          },
          "offset": {
            "type": "number",
            "description": "Skip N records for pagination. Use pagination.nextOffset from previous response."
          },
          "slim": {
            "type": "boolean",
            "description": "DEPRECATED: Use fields parameter instead. slim=true maps to fields=[] (IDs only)."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "escrows_get",
      "aliasOf": "get_escrow",
      "category": "escrows",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of a specific escrow by ID — property, parties, key dates, price, commission, and status. Use after escrows_list when you need every field for one transaction. For multiple escrows, pass escrow_ids instead. Returns the complete escrow record.",
      "keywords": [
        "escrow",
        "transaction",
        "get",
        "fetch",
        "details"
      ],
      "docs": "https://docs.actuallycare.com/tools/escrows/escrows_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "escrow_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of a single escrow to retrieve"
          },
          "escrow_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "maxItems": 100,
            "description": "Array of escrow UUIDs for batch retrieval (max 100). Use either escrow_id OR escrow_ids, not both."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "escrows_create",
      "aliasOf": "create_escrow",
      "category": "escrows",
      "registryCategory": "core",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new escrow/transaction record. Use when an offer is accepted and a transaction opens — to also create buyer/seller client records in one call, use create_escrow_with_clients instead. Call immediately with whatever data the user provides. Do NOT ask for missing fields — the system shows an editable draft card where the user can fill in remaining details. Returns the created escrow record.",
      "keywords": [
        "escrow",
        "transaction",
        "create",
        "add",
        "contract",
        "new-deal"
      ],
      "docs": "https://docs.actuallycare.com/tools/escrows/escrows_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "property_address": {
            "type": "string",
            "description": "Full property address (street line)"
          },
          "city": {
            "type": "string",
            "description": "City name"
          },
          "state": {
            "type": "string",
            "description": "State abbreviation (e.g. \"CA\")"
          },
          "zip_code": {
            "type": "string",
            "description": "ZIP code (5 or 9 digit)"
          },
          "purchase_price": {
            "type": "number",
            "description": "Purchase price in dollars"
          },
          "escrow_number": {
            "type": "string",
            "description": "Escrow or file number"
          },
          "closing_date": {
            "type": "string",
            "description": "Expected closing date (YYYY-MM-DD format)"
          },
          "escrow_status": {
            "type": "string",
            "enum": [
              "active",
              "pending",
              "closed",
              "cancelled"
            ],
            "description": "Status of the escrow"
          },
          "representation_type": {
            "type": "string",
            "enum": [
              "buyer",
              "seller",
              "dual"
            ],
            "description": "Who the agent represents in this transaction"
          },
          "notes": {
            "type": "string",
            "description": "Notes about this transaction"
          }
        },
        "required": [
          "property_address"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "escrows_update",
      "aliasOf": "update_escrow",
      "category": "escrows",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing escrow/transaction record. Only provided fields are updated — omitted fields remain unchanged. Common uses: move key dates, update the price, or change status as the transaction progresses. Returns the updated escrow record.",
      "keywords": [
        "escrow",
        "transaction",
        "update",
        "edit",
        "modify",
        "status"
      ],
      "docs": "https://docs.actuallycare.com/tools/escrows/escrows_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "escrow_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the escrow to update"
          },
          "property_address": {
            "type": "string",
            "description": "Updated property address"
          },
          "purchase_price": {
            "type": "number",
            "description": "Updated purchase price"
          },
          "escrow_number": {
            "type": "string",
            "description": "Updated escrow number"
          },
          "closing_date": {
            "type": "string",
            "description": "Updated closing date (YYYY-MM-DD)"
          },
          "escrow_status": {
            "type": "string",
            "enum": [
              "active",
              "pending",
              "closed",
              "cancelled",
              "fell_through"
            ],
            "description": "Updated status"
          },
          "notes": {
            "type": "string",
            "description": "Updated notes"
          }
        },
        "required": [
          "escrow_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "escrows_stats",
      "aliasOf": "get_escrow_summary",
      "category": "escrows",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get a summary of all escrows including counts by status and upcoming closings. Use for overview questions.",
      "keywords": [
        "escrow",
        "stats",
        "summary",
        "metrics",
        "dashboard",
        "pipeline-volume"
      ],
      "docs": "https://docs.actuallycare.com/tools/escrows/escrows_stats",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "escrow_parties_sync",
      "category": "escrows",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Synchronize the buyer and/or seller client rosters for an escrow. Pass the full desired roster for each side; the tool compares it against the escrow's current parties and adds/removes as needed. Provide only the sides you want to change — omit a side to leave it unchanged, pass an empty array to remove all parties on that side. Each client_id must already exist (use clients_create or clients_find_or_create first). Returns { added, removed, buyers, sellers } summarizing the change and the resulting rosters.",
      "keywords": [
        "escrow",
        "parties",
        "sync",
        "buyers",
        "sellers",
        "roster",
        "link"
      ],
      "docs": "https://docs.actuallycare.com/tools/escrows/escrow_parties_sync",
      "inputSchema": {
        "type": "object",
        "properties": {
          "escrow_id": {
            "type": "string",
            "description": "UUID of the escrow whose roster you want to sync."
          },
          "buyers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Desired buyer client UUIDs (full set — compared against the current roster). Omit to leave buyers unchanged; pass [] to clear."
          },
          "sellers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Desired seller client UUIDs (full set — compared against the current roster). Omit to leave sellers unchanged; pass [] to clear."
          }
        },
        "required": [
          "escrow_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "escrows_archive",
      "category": "escrows",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive an escrow to hide it from active views without deleting it. Archived escrows can be restored later with escrows_restore. Use this for completed or abandoned transactions you want to declutter from your dashboard. Returns the archived escrow record.",
      "keywords": [
        "escrow",
        "archive",
        "hide"
      ],
      "docs": "https://docs.actuallycare.com/tools/escrows/escrows_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "escrow_id": {
            "type": "string",
            "description": "UUID of the escrow to archive. Use escrows_list to find the ID if unknown."
          }
        },
        "required": [
          "escrow_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "escrows_restore",
      "category": "escrows",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore a previously archived escrow back to active views. Reverses the effect of escrows_archive. Use this when a transaction needs to be revisited or was archived by mistake. Returns the restored escrow record.",
      "keywords": [
        "escrow",
        "restore",
        "unarchive"
      ],
      "docs": "https://docs.actuallycare.com/tools/escrows/escrows_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "escrow_id": {
            "type": "string",
            "description": "UUID of the escrow to restore. Must be currently archived."
          }
        },
        "required": [
          "escrow_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "escrows_delete",
      "category": "escrows",
      "registryCategory": "core",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete an escrow. This is IRREVERSIBLE - the escrow will be hidden from all views including archived. Only use for test data or duplicate records. For normal cleanup, use escrows_archive instead which is reversible. Returns confirmation of the deletion.",
      "keywords": [
        "escrow",
        "delete",
        "remove",
        "destructive"
      ],
      "docs": "https://docs.actuallycare.com/tools/escrows/escrows_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "escrow_id": {
            "type": "string",
            "description": "UUID of the escrow to delete. Use escrows_get first to verify."
          }
        },
        "required": [
          "escrow_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "calculate_seller_net_sheet",
      "category": "financial",
      "registryCategory": "financial",
      "annotation": "Calculator",
      "readOnly": true,
      "destructive": false,
      "description": "Calculate estimated seller proceeds after all closing costs. Shows sellers what they will NET from their sale. Includes: listing commission, buyer agent commission, title insurance, escrow fees, county/city transfer taxes, loan payoff, HOA fees, repairs/credits, and other costs. CALIFORNIA-SPECIFIC: Uses CA default transfer tax rates (0.11% county). For accurate city transfer tax, provide county name. Returns itemized breakdown of all costs plus estimated net proceeds. NOTE: These are estimates — actual amounts may vary based on negotiation and specific circumstances.",
      "keywords": [
        "seller",
        "net",
        "proceeds",
        "closing",
        "costs",
        "commission",
        "transfer tax"
      ],
      "docs": "https://docs.actuallycare.com/tools/financial/calculate_seller_net_sheet",
      "inputSchema": {
        "type": "object",
        "properties": {
          "sale_price": {
            "type": "number",
            "minimum": 0,
            "description": "The sale price of the property (required)"
          },
          "mortgage_balance": {
            "type": "number",
            "minimum": 0,
            "description": "Remaining mortgage balance to pay off (default: 0)"
          },
          "listing_commission_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 10,
            "description": "Listing agent commission percentage (e.g., 2.5 for 2.5%)"
          },
          "buyer_agent_commission_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 10,
            "description": "Buyer agent commission percentage (e.g., 2.5 for 2.5%)"
          },
          "title_insurance_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 2,
            "description": "Title insurance as percentage of sale price (default: 0.5)"
          },
          "escrow_fee": {
            "type": "number",
            "minimum": 0,
            "description": "Escrow fee in dollars. If not provided, estimated as $2 per $1,000 of sale price"
          },
          "transfer_tax_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 2,
            "description": "County transfer tax percentage (default: 0.11 for CA, $1.10 per $1,000)"
          },
          "city_transfer_tax_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 3,
            "description": "City transfer tax percentage if applicable. Some CA cities have additional taxes (e.g., Oakland, Berkeley)"
          },
          "hoa_fees": {
            "type": "number",
            "minimum": 0,
            "description": "HOA transfer fees or outstanding dues owed (default: 0)"
          },
          "repairs_credits": {
            "type": "number",
            "minimum": 0,
            "description": "Repairs or credits to buyer negotiated in contract (default: 0)"
          },
          "other_costs": {
            "type": "number",
            "minimum": 0,
            "description": "Any other closing costs not listed above (default: 0)"
          },
          "county": {
            "type": "string",
            "description": "County name for accurate transfer tax lookup (optional, uses CA default if not provided)"
          }
        },
        "required": [
          "sale_price"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "calculate_buyer_closing_costs",
      "category": "financial",
      "registryCategory": "financial",
      "annotation": "Calculator",
      "readOnly": true,
      "destructive": false,
      "description": "Calculate estimated buyer closing costs. Shows buyers their TOTAL CASH needed to close including down payment. Includes: down payment, loan origination fees, appraisal, inspection, title insurance, escrow fees, prepaid insurance, prepaid taxes, and other costs. Loan type affects costs: FHA has mortgage insurance premiums, VA has funding fee, jumbo may have higher fees. Returns itemized breakdown plus total cash needed. NOTE: These are estimates — actual lender costs may vary.",
      "keywords": [
        "buyer",
        "closing",
        "costs",
        "cash to close",
        "down payment",
        "fha",
        "va",
        "jumbo"
      ],
      "docs": "https://docs.actuallycare.com/tools/financial/calculate_buyer_closing_costs",
      "inputSchema": {
        "type": "object",
        "properties": {
          "purchase_price": {
            "type": "number",
            "minimum": 0,
            "description": "The purchase price of the property (required)"
          },
          "down_payment_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Down payment as percentage (e.g., 20 for 20%). Affects PMI requirement."
          },
          "loan_type": {
            "type": "string",
            "enum": [
              "conventional",
              "fha",
              "va",
              "jumbo"
            ],
            "description": "Type of loan. Affects costs: FHA=MIP, VA=funding fee, jumbo=higher fees (default: conventional)"
          },
          "interest_rate": {
            "type": "number",
            "minimum": 0,
            "maximum": 20,
            "description": "Annual interest rate as percentage (e.g., 6.5 for 6.5%). Used for prepaid interest calculation."
          },
          "lender_fees": {
            "type": "number",
            "minimum": 0,
            "description": "Lender origination/processing fees. If not provided, estimated as 1% of loan amount."
          },
          "appraisal_fee": {
            "type": "number",
            "minimum": 0,
            "description": "Appraisal fee (default: $600)"
          },
          "inspection_fee": {
            "type": "number",
            "minimum": 0,
            "description": "Home inspection fee (default: $500)"
          },
          "title_insurance_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 2,
            "description": "Title insurance as percentage of purchase price (default: 0.5)"
          },
          "escrow_fee": {
            "type": "number",
            "minimum": 0,
            "description": "Escrow fee. If not provided, estimated as $2 per $1,000 of purchase price."
          },
          "prepaid_insurance": {
            "type": "number",
            "minimum": 0,
            "description": "Prepaid homeowners insurance (typically 1 year). If not provided, estimated."
          },
          "prepaid_taxes_months": {
            "type": "number",
            "minimum": 0,
            "maximum": 12,
            "description": "Months of property taxes to prepay into escrow (default: 3)"
          },
          "property_tax_rate": {
            "type": "number",
            "minimum": 0,
            "maximum": 5,
            "description": "Annual property tax rate as percentage (default: 1.1 for CA)"
          },
          "hoa_monthly": {
            "type": "number",
            "minimum": 0,
            "description": "Monthly HOA dues — affects prepaid HOA fees (default: 0)"
          }
        },
        "required": [
          "purchase_price"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "calculate_mortgage_payment",
      "category": "financial",
      "registryCategory": "financial",
      "annotation": "Calculator",
      "readOnly": true,
      "destructive": false,
      "description": "Calculate estimated monthly mortgage payment with PITI breakdown (Principal, Interest, Taxes, Insurance). Use when a buyer asks what their monthly payment would be for a given price or loan. Includes: P&I, property taxes, homeowners insurance, HOA dues, and PMI if applicable (down payment < 20%). Can calculate from loan_amount OR from purchase_price with down_payment_pct. Returns itemized estimate of each component. NOTE: These are estimates — actual payments depend on lender terms. This is not financial advice.",
      "keywords": [
        "mortgage",
        "payment",
        "piti",
        "principal",
        "interest",
        "pmi",
        "monthly"
      ],
      "docs": "https://docs.actuallycare.com/tools/financial/calculate_mortgage_payment",
      "inputSchema": {
        "type": "object",
        "properties": {
          "loan_amount": {
            "type": "number",
            "minimum": 0,
            "description": "Total loan amount in dollars. Provide this OR purchase_price+down_payment_pct."
          },
          "purchase_price": {
            "type": "number",
            "minimum": 0,
            "description": "Purchase price (used with down_payment_pct to calculate loan)"
          },
          "down_payment_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Down payment as percentage (e.g., 20 for 20%)"
          },
          "interest_rate": {
            "type": "number",
            "minimum": 0,
            "maximum": 20,
            "description": "Annual interest rate as percentage (required, e.g., 6.5 for 6.5%)"
          },
          "loan_term_years": {
            "type": "number",
            "minimum": 1,
            "maximum": 40,
            "description": "Loan term in years (default: 30)"
          },
          "property_tax_rate": {
            "type": "number",
            "minimum": 0,
            "maximum": 5,
            "description": "Annual property tax rate as percentage (default: 1.1 for CA)"
          },
          "homeowners_insurance": {
            "type": "number",
            "minimum": 0,
            "description": "Annual homeowners insurance. If not provided, estimated as 0.35% of purchase price."
          },
          "hoa_monthly": {
            "type": "number",
            "minimum": 0,
            "description": "Monthly HOA dues (default: 0)"
          },
          "pmi_rate": {
            "type": "number",
            "minimum": 0,
            "maximum": 3,
            "description": "PMI rate as percentage of loan if down payment < 20% (default: 0.5)"
          },
          "include_pmi": {
            "type": "boolean",
            "description": "Include PMI in calculation. Auto-included if down payment < 20% (default: true if applicable)"
          }
        },
        "required": [
          "interest_rate"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "calculate_commission_split",
      "category": "financial",
      "registryCategory": "financial",
      "annotation": "Calculator",
      "readOnly": true,
      "destructive": false,
      "description": "Calculate estimated agent net commission after broker split, franchise fees, and transaction fees. Use when the user asks what they will actually take home from a sale. Provide gross_commission directly OR calculate from sale_price+commission_pct. Returns itemized estimate of deductions plus net-to-agent amount. NOTE: This is a simplified estimate — verify all commission calculations with your brokerage accounting. Does not account for referral fees, team splits, E&O, or brokerage caps.",
      "keywords": [
        "commission",
        "split",
        "broker",
        "franchise",
        "referral fee",
        "net to agent"
      ],
      "docs": "https://docs.actuallycare.com/tools/financial/calculate_commission_split",
      "inputSchema": {
        "type": "object",
        "properties": {
          "gross_commission": {
            "type": "number",
            "minimum": 0,
            "description": "Total gross commission in dollars. Provide this OR sale_price+commission_pct."
          },
          "commission_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 10,
            "description": "Commission percentage (used with sale_price to calculate gross_commission)"
          },
          "sale_price": {
            "type": "number",
            "minimum": 0,
            "description": "Sale price (used with commission_pct)"
          },
          "broker_split_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Percentage you KEEP after broker split (required, e.g., 80 for 80/20 split means you keep 80%)"
          },
          "referral_fee_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Referral fee percentage owed to referring agent/company (default: 0)"
          },
          "team_split_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Team lead split percentage if on a team (default: 0)"
          },
          "transaction_fee": {
            "type": "number",
            "minimum": 0,
            "description": "Flat transaction/admin fee charged by brokerage (default: 0)"
          },
          "errors_omissions_fee": {
            "type": "number",
            "minimum": 0,
            "description": "E&O insurance fee per transaction (default: 0)"
          },
          "franchise_fee_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 10,
            "description": "Franchise fee percentage if applicable (e.g., Keller Williams, RE/MAX)"
          }
        },
        "required": [
          "broker_split_pct"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "geo_boundary_search",
      "category": "geo-boundaries",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search geographic boundaries (regional neighborhoods, neighborhoods, subdivisions) by name. Returns id, kind, name, centroid, and bbox for each match. Useful when the user asks about a named place (\"show me The Northwest\", \"what neighborhood is this in\"). Pass the returned id to listings_list as boundary_id to filter listings to the polygon. Results are ordered by kind priority (regional > neighborhood > subdivision) then text-search relevance — so a search for \"northwest\" surfaces \"The Northwest\" (regional) above any subdivision with that word in its name.",
      "keywords": [
        "neighborhood",
        "subdivision",
        "place",
        "geography",
        "boundary",
        "area",
        "location"
      ],
      "docs": "https://docs.actuallycare.com/tools/geo-boundaries/geo_boundary_search",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "description": "Search term — matches against boundary name (case-insensitive, full-text-search)."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 25,
            "default": 10,
            "description": "Max results (1–25). Defaults to 10."
          }
        },
        "required": [
          "query"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "habits_list",
      "category": "habits",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search the authenticated user's habits (daily/weekly/monthly trackers like \"Read My Bible\", \"Go to the Gym\"). Returns pagination info (total_count, has_more, offset, limit). Each result includes: id, display_id, name, habit_type, cadence, status, started_on, best_streak, created_at. Filter by status (active/paused/archived) or habit_type. For a single habit's full detail + checklist + trackers, use habits_get. To mark a habit done for a day, use habits_log.",
      "keywords": [
        "habit",
        "habits",
        "streak",
        "tracker",
        "routine",
        "list",
        "search"
      ],
      "docs": "https://docs.actuallycare.com/tools/habits/habits_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term — matches against habit name and tagline (case-insensitive partial match)"
          },
          "status": {
            "type": "string",
            "enum": [
              "all",
              "active",
              "paused",
              "archived"
            ],
            "description": "Filter by status (default: all)"
          },
          "habit_type": {
            "type": "string",
            "description": "Filter by habit type (e.g. bible, gym, throwing, reading, custom)"
          },
          "archived": {
            "type": "boolean",
            "description": "Include archived habits (default: false)"
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 500,
            "description": "Maximum results (default: 50, max: 500)"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N results for pagination (default: 0)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "habits_get",
      "category": "habits",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of one habit by UUID, including its per-habit checklist (step_template), tracker schema (tracker_schema), cadence, status, started_on, and best_streak. If you don't have the UUID, use habits_list first.",
      "keywords": [
        "habit",
        "detail",
        "get",
        "view",
        "streak"
      ],
      "docs": "https://docs.actuallycare.com/tools/habits/habits_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "habit_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the habit. Use habits_list to find IDs."
          }
        },
        "required": [
          "habit_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "habits_create",
      "category": "habits",
      "registryCategory": "generics",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new habit to track. The checklist and trackers are seeded automatically from the habit_type (bible/gym/throwing/reading/custom). Returns the created habit with its id and display_id (H-####). Cadence defaults to 'daily'. After creating, use habits_log to mark progress for a day.",
      "keywords": [
        "habit",
        "create",
        "new",
        "add",
        "track",
        "routine"
      ],
      "docs": "https://docs.actuallycare.com/tools/habits/habits_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the habit (e.g. \"Read My Bible\", \"Go to the Gym\")"
          },
          "habit_type": {
            "type": "string",
            "enum": [
              "bible",
              "gym",
              "throwing",
              "reading",
              "custom"
            ],
            "description": "Habit type — seeds the default checklist + trackers (default: custom)"
          },
          "cadence": {
            "type": "string",
            "enum": [
              "daily",
              "weekly",
              "monthly"
            ],
            "description": "How often the habit recurs (default: daily)"
          },
          "weekly_target": {
            "type": "number",
            "minimum": 1,
            "maximum": 7,
            "description": "For weekly cadence — target sessions per week (e.g. 4 for a gym habit)"
          },
          "tagline": {
            "type": "string",
            "description": "A short reminder of the \"why\" behind the habit"
          },
          "started_on": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "The date the habit started (YYYY-MM-DD). Defaults to unset. (Format: YYYY-MM-DD)"
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "habits_update",
      "category": "habits",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing habit's name, cadence, status, tagline, or weekly target. Only provided fields are updated — omitted fields stay unchanged. Use status='paused' to pause a habit or status='active' to resume. Returns the updated habit.",
      "keywords": [
        "habit",
        "update",
        "edit",
        "modify",
        "pause",
        "resume",
        "status"
      ],
      "docs": "https://docs.actuallycare.com/tools/habits/habits_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "habit_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the habit to update (required). Use habits_list to find."
          },
          "name": {
            "type": "string",
            "description": "Updated habit name"
          },
          "cadence": {
            "type": "string",
            "enum": [
              "daily",
              "weekly",
              "monthly"
            ],
            "description": "Updated cadence"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "archived"
            ],
            "description": "Updated status"
          },
          "weekly_target": {
            "type": "number",
            "minimum": 1,
            "maximum": 7,
            "description": "Updated weekly target"
          },
          "tagline": {
            "type": "string",
            "description": "Updated tagline"
          }
        },
        "required": [
          "habit_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "habits_log",
      "category": "habits",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Mark a habit's progress for a day (the headline action — \"mark my Bible reading done today\"). Upserts the per-day log: pass done=true to mark the day complete, plus optional checklist steps and tracker metrics. Defaults log_date to today. Idempotent — calling again for the same day updates that day's log. Returns the saved log row.",
      "keywords": [
        "habit",
        "log",
        "mark",
        "done",
        "complete",
        "check",
        "track",
        "streak"
      ],
      "docs": "https://docs.actuallycare.com/tools/habits/habits_log",
      "inputSchema": {
        "type": "object",
        "properties": {
          "habit_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the habit to log (required). Use habits_list to find."
          },
          "log_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "The day to log (YYYY-MM-DD). Defaults to today. (Format: YYYY-MM-DD)"
          },
          "done": {
            "type": "boolean",
            "description": "Whether the habit was completed for the day (default: true)"
          },
          "steps": {
            "type": "object",
            "additionalProperties": true,
            "description": "Checklist completion as { stepId: boolean } — keys match the habit's step_template ids."
          },
          "metrics": {
            "type": "object",
            "additionalProperties": true,
            "description": "Tracker values as { trackerKey: value } — keys match the habit's tracker_schema keys."
          },
          "note": {
            "type": "string",
            "description": "An optional note for the day"
          }
        },
        "required": [
          "habit_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "landing_page_create",
      "category": "landing-pages",
      "registryCategory": "growth",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a landing page for an open house sign-in or marketing purpose. Optionally link it to an open house by ID to create a visitor sign-in page with a QR code. The page is created as a draft — use landing_page_publish to make it live. Returns: id, shortcode, publicUrl, status, title.",
      "keywords": [
        "landing",
        "page",
        "marketing",
        "create"
      ],
      "docs": "https://docs.actuallycare.com/tools/landing-pages/landing_page_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "Page title (e.g. \"Sign In — 123 Main St\"). Required."
          },
          "open_house_id": {
            "type": "string",
            "description": "UUID of the open house to link this sign-in page to. Optional — omit for standalone landing pages."
          },
          "template_id": {
            "type": "string",
            "enum": [
              "open-house-default",
              "open-house-luxury",
              "open-house-minimal"
            ],
            "description": "Template to use. open-house-default includes qualifying questions, open-house-minimal is name/email/phone only. Default: open-house-default."
          }
        },
        "required": [
          "title"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "landing_page_edit",
      "category": "landing-pages",
      "registryCategory": "growth",
      "annotation": "Creates data + external action",
      "readOnly": false,
      "destructive": false,
      "description": "Edit a landing page using natural language. Describe what you want to change (colors, text, layout, questions) and the AI will update the HTML/CSS. Same compliance guardrails as website_edit — Fair Housing, DRE, and XSS rules are enforced automatically. The edit is applied to the draft — use landing_page_publish to make it live. Examples: \"Change the background to navy blue\", \"Add a question about school district preferences\", \"Make the welcome text larger\".",
      "keywords": [
        "landing",
        "page",
        "marketing",
        "edit"
      ],
      "docs": "https://docs.actuallycare.com/tools/landing-pages/landing_page_edit",
      "inputSchema": {
        "type": "object",
        "properties": {
          "landing_page_id": {
            "type": "string",
            "description": "UUID of the landing page to edit. Use landing_page_get to find."
          },
          "prompt": {
            "type": "string",
            "description": "Natural language description of the edit. Be specific.",
            "maxLength": 2000
          }
        },
        "required": [
          "landing_page_id",
          "prompt"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "landing_page_get",
      "category": "landing-pages",
      "registryCategory": "growth",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get details of a landing page including status, shortcode URL, view count, submission count, and configuration. Use this to check the current state before editing or publishing.",
      "keywords": [
        "landing",
        "page",
        "marketing"
      ],
      "docs": "https://docs.actuallycare.com/tools/landing-pages/landing_page_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "landing_page_id": {
            "type": "string",
            "description": "UUID of the landing page."
          }
        },
        "required": [
          "landing_page_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "landing_page_publish",
      "category": "landing-pages",
      "registryCategory": "growth",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Publish the current draft of a landing page to make it live. The page will be accessible at its public URL. Only works if there is draft content to publish.",
      "keywords": [
        "landing",
        "page",
        "marketing",
        "publish"
      ],
      "docs": "https://docs.actuallycare.com/tools/landing-pages/landing_page_publish",
      "inputSchema": {
        "type": "object",
        "properties": {
          "landing_page_id": {
            "type": "string",
            "description": "UUID of the landing page to publish."
          }
        },
        "required": [
          "landing_page_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "landing_page_revert",
      "category": "landing-pages",
      "registryCategory": "growth",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Revert a landing page draft to the last published version. Discards all unpublished changes. Only works if there is a published version to revert to.",
      "keywords": [
        "landing",
        "page",
        "marketing",
        "revert"
      ],
      "docs": "https://docs.actuallycare.com/tools/landing-pages/landing_page_revert",
      "inputSchema": {
        "type": "object",
        "properties": {
          "landing_page_id": {
            "type": "string",
            "description": "UUID of the landing page to revert."
          }
        },
        "required": [
          "landing_page_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "landing_page_submissions",
      "category": "landing-pages",
      "registryCategory": "growth",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get visitor sign-in submissions for a landing page. Returns contact info (name, email, phone), qualifying answers, and whether each visitor completed step 1 only or both steps. Use this to review who visited an open house.",
      "keywords": [
        "landing",
        "page",
        "marketing",
        "submissions"
      ],
      "docs": "https://docs.actuallycare.com/tools/landing-pages/landing_page_submissions",
      "inputSchema": {
        "type": "object",
        "properties": {
          "landing_page_id": {
            "type": "string",
            "description": "UUID of the landing page."
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 100,
            "description": "Max results (default: 25)."
          },
          "page": {
            "type": "number",
            "minimum": 1,
            "description": "Page number (default: 1)."
          }
        },
        "required": [
          "landing_page_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "generate_open_house_flyer",
      "category": "landing-pages",
      "registryCategory": "growth",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Generate a professional PDF flyer for an open house. Use when preparing marketing for an upcoming open house. Auto-populates from MLS listing data (photos, beds/baths/sqft, price, description), agent profile (headshot, contact info, DRE#), and brokerage brand (logo, colors, disclaimer). Returns a download URL for the PDF. The flyer is print-ready at 8.5\" × 11\" letter size.",
      "keywords": [
        "landing",
        "page",
        "marketing",
        "generate",
        "open",
        "house",
        "flyer"
      ],
      "docs": "https://docs.actuallycare.com/tools/landing-pages/generate_open_house_flyer",
      "inputSchema": {
        "type": "object",
        "properties": {
          "open_house_id": {
            "type": "string",
            "description": "UUID of the open house to generate a flyer for."
          }
        },
        "required": [
          "open_house_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "leads_create",
      "aliasOf": "create_lead",
      "category": "leads",
      "registryCategory": "core",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new lead in the CRM. Use when a new prospective buyer or seller comes in from any source. Call immediately with whatever data the user provides. Do NOT ask for missing fields — the system shows an editable draft card where the user can fill in remaining details. Returns the created lead record.",
      "keywords": [
        "lead",
        "create",
        "add",
        "prospect",
        "inquiry"
      ],
      "docs": "https://docs.actuallycare.com/tools/leads/leads_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "first_name": {
            "type": "string",
            "description": "First name of the lead"
          },
          "last_name": {
            "type": "string",
            "description": "Last name of the lead"
          },
          "email": {
            "type": "string",
            "description": "Email address"
          },
          "phone": {
            "type": "string",
            "description": "Phone number"
          },
          "source": {
            "type": "string",
            "description": "Lead source (e.g., referral, zillow, open_house, website, cold_call)"
          },
          "notes": {
            "type": "string",
            "description": "Notes about this lead"
          },
          "lead_type": {
            "type": "string",
            "enum": [
              "buyer",
              "seller",
              "both",
              "investor",
              "renter"
            ],
            "description": "Type of lead"
          }
        },
        "required": [
          "first_name",
          "last_name"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "leads_list",
      "aliasOf": "search_leads",
      "category": "leads",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search for leads by status, source, or text. Use to find lead IDs before updating or converting, or to answer questions about the lead pipeline. Returns IDs only by default for efficiency; use the fields parameter to include additional data. Response includes relatedIds.contactIds for chainable operations.",
      "keywords": [
        "lead",
        "search",
        "list",
        "find",
        "pipeline"
      ],
      "docs": "https://docs.actuallycare.com/tools/leads/leads_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term (searches name, email, phone)"
          },
          "status": {
            "type": "string",
            "enum": [
              "new",
              "contacted",
              "qualified",
              "unqualified",
              "converted",
              "lost"
            ],
            "description": "Filter by lead status"
          },
          "source": {
            "type": "string",
            "description": "Filter by lead source"
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "basic",
                "contact",
                "source",
                "timeline",
                "full"
              ]
            },
            "description": "Field groups to include. Empty/omitted = IDs only. Options: basic (id, type, status), contact (name, email, phone), source (source, score), timeline (dates), full (all fields)."
          },
          "limit": {
            "type": "string",
            "description": "Max results. Use a number (e.g. \"25\") or \"all\". \"all\" and any value above 200 are capped at 200 server-side."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "leads_update",
      "aliasOf": "update_lead",
      "category": "leads",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing lead's information or status. Only provided fields are updated — omitted fields remain unchanged. Common uses: advance status as the lead warms up, correct contact details, or record the source. Returns the updated lead record.",
      "keywords": [
        "lead",
        "update",
        "edit",
        "modify",
        "status"
      ],
      "docs": "https://docs.actuallycare.com/tools/leads/leads_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lead_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the lead to update"
          },
          "first_name": {
            "type": "string",
            "description": "Updated first name"
          },
          "last_name": {
            "type": "string",
            "description": "Updated last name"
          },
          "email": {
            "type": "string",
            "description": "Updated email"
          },
          "phone": {
            "type": "string",
            "description": "Updated phone"
          },
          "status": {
            "type": "string",
            "enum": [
              "new",
              "contacted",
              "qualified",
              "unqualified",
              "converted",
              "lost"
            ],
            "description": "Updated status"
          },
          "notes": {
            "type": "string",
            "description": "Notes to add"
          }
        },
        "required": [
          "lead_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "leads_get",
      "aliasOf": "get_lead",
      "category": "leads",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of a specific lead by ID — contact info, source, status, and timeline fields. Use after leads_list when you need every field for one lead. For multiple leads, pass lead_ids instead. Returns the complete lead record.",
      "keywords": [
        "lead",
        "get",
        "detail",
        "fetch"
      ],
      "docs": "https://docs.actuallycare.com/tools/leads/leads_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lead_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of a single lead to retrieve"
          },
          "lead_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "maxItems": 100,
            "description": "Array of lead UUIDs for batch retrieval (max 100). Use either lead_id OR lead_ids, not both."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "leads_convert",
      "aliasOf": "convert_lead_to_client",
      "category": "leads",
      "registryCategory": "core",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Convert a lead to a client when they become an active buyer or seller. Use at the moment a representation agreement is signed or the lead commits to working with you. Returns the new client record linked to the original lead. WARNING: This is IRREVERSIBLE — once a lead is marked converted, the source/timeline data freezes for analytics.",
      "keywords": [
        "lead",
        "convert",
        "client",
        "sign",
        "representation"
      ],
      "docs": "https://docs.actuallycare.com/tools/leads/leads_convert",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lead_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the lead to convert"
          },
          "client_type": {
            "type": "string",
            "enum": [
              "buyer",
              "seller",
              "both"
            ],
            "description": "Type of client they are becoming"
          }
        },
        "required": [
          "lead_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "leads_archive",
      "category": "leads",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive a lead to hide them from active views without deleting their record. Archived leads can be restored later with leads_restore. Use this for leads that have gone cold or been disqualified but you want to keep their history. Returns the archived lead record.",
      "keywords": [
        "lead",
        "archive",
        "hide",
        "cold"
      ],
      "docs": "https://docs.actuallycare.com/tools/leads/leads_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lead_id": {
            "type": "string",
            "description": "UUID of the lead to archive. Use leads_list to find the ID if unknown."
          }
        },
        "required": [
          "lead_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "leads_restore",
      "category": "leads",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore a previously archived lead back to active views. Reverses the effect of leads_archive. Use this when a cold lead re-engages or was archived by mistake. Returns the restored lead record.",
      "keywords": [
        "lead",
        "restore",
        "unarchive"
      ],
      "docs": "https://docs.actuallycare.com/tools/leads/leads_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lead_id": {
            "type": "string",
            "description": "UUID of the lead to restore. Must be currently archived."
          }
        },
        "required": [
          "lead_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "leads_delete",
      "category": "leads",
      "registryCategory": "core",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete a lead. This is IRREVERSIBLE - the lead will be hidden from all views including archived. Only use for test data or duplicate records. For normal cleanup, use leads_archive instead which is reversible. Returns confirmation of the deletion.",
      "keywords": [
        "lead",
        "delete",
        "remove",
        "destructive"
      ],
      "docs": "https://docs.actuallycare.com/tools/leads/leads_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lead_id": {
            "type": "string",
            "description": "UUID of the lead to delete. Use leads_get first to verify."
          }
        },
        "required": [
          "lead_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "leads_stats",
      "category": "leads",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get aggregate statistics for all leads: counts by status (new/contacted/qualified/converted/lost), conversion rate, and counts by source. Use this for dashboard metrics and pipeline analysis. Does NOT return individual lead records - use leads_list for that.",
      "keywords": [
        "lead",
        "stats",
        "metrics",
        "conversion",
        "pipeline"
      ],
      "docs": "https://docs.actuallycare.com/tools/leads/leads_stats",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "leases_list",
      "category": "leases",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search the user's leases by status, lease_type, party, or free-text query. Returns id, lease_start, lease_end, monthly_rent, status, lease_type, renter_client_id, landlord_contact_id, listing_id. Use status='expiring' or the dedicated leases_expiring tool to find leases ending soon — the dedicated view is more useful when looking for renewal opportunities. Pagination: total_count + has_more + offset + limit.",
      "keywords": [
        "lease",
        "leases",
        "rental agreement",
        "tenant",
        "landlord",
        "monthly rent",
        "active leases"
      ],
      "docs": "https://docs.actuallycare.com/tools/leases/leases_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Free-text search (reserved — not currently indexed; use specific filters instead)"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "active",
              "expiring",
              "renewed",
              "terminated",
              "expired"
            ],
            "description": "Filter by lease status. active=currently occupied, expiring=within renewal window, renewed=has successor lease, terminated=ended early, expired=passed lease_end with no renewal"
          },
          "lease_type": {
            "type": "string",
            "enum": [
              "residential",
              "commercial",
              "short_term"
            ],
            "description": "Filter by lease type"
          },
          "renter_client_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Filter to leases for a specific renter (client). Use clients_list with client_type=tenant to find tenants first."
          },
          "landlord_contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Filter to leases for a specific landlord (contact). Use contacts_list with leasing_role=landlord to find landlords first."
          },
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Filter to leases for a specific listing"
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 500,
            "description": "Maximum results (default: 25)"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N results for pagination (default: 0)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "leases_get",
      "category": "leases",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of one lease by UUID. Returns all lease fields including renter/landlord references, commission, renewal chain (previous_lease_id), and the rental_application_id that led to the lease. Use leases_list first if you don't have the UUID.",
      "keywords": [
        "lease details",
        "get lease",
        "lease terms",
        "renewal chain"
      ],
      "docs": "https://docs.actuallycare.com/tools/leases/leases_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lease_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the lease"
          }
        },
        "required": [
          "lease_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "leases_create",
      "category": "leases",
      "registryCategory": "core",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new lease agreement. Use when a new lease is being drafted or activated outside the normal application→lease flow. For the common case of approving an application and executing the lease, use rental_applications_convert_to_lease instead — that atomically approves + creates + links. Required: lease_start, lease_end (ISO dates), monthly_rent. Defaults: status='draft', lease_type='residential'. Returns the created lease record.",
      "keywords": [
        "new lease",
        "create lease",
        "draft lease",
        "rental agreement create"
      ],
      "docs": "https://docs.actuallycare.com/tools/leases/leases_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the listing being leased"
          },
          "landlord_contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the landlord contact"
          },
          "renter_client_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the renter client (typically client_type=tenant)"
          },
          "rental_application_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the approved application (if converted from one)"
          },
          "previous_lease_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the prior lease (for renewals — links the chain)"
          },
          "lease_start": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Lease start date (ISO format, YYYY-MM-DD) (Format: YYYY-MM-DD)"
          },
          "lease_end": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Lease end date (ISO format, YYYY-MM-DD). Must be after lease_start. (Format: YYYY-MM-DD)"
          },
          "monthly_rent": {
            "type": "number",
            "minimum": 0,
            "description": "Monthly rent amount"
          },
          "security_deposit": {
            "type": "number",
            "minimum": 0,
            "description": "Security deposit amount"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "active",
              "expiring",
              "renewed",
              "terminated",
              "expired"
            ],
            "description": "Initial status (default: draft)"
          },
          "lease_type": {
            "type": "string",
            "enum": [
              "residential",
              "commercial",
              "short_term"
            ],
            "description": "Lease type (default: residential)"
          },
          "commission_amount": {
            "type": "number",
            "minimum": 0,
            "description": "Agent commission for this lease"
          },
          "notes": {
            "type": "string",
            "maxLength": 10000,
            "description": "Free-text notes"
          }
        },
        "required": [
          "lease_start",
          "lease_end",
          "monthly_rent"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "leases_expiring",
      "category": "leases",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "List leases expiring within the next N days (default 60, max 365). Returns active + expiring leases ordered by lease_end ascending — closest expiration first. Use this to surface renewal opportunities, proactive outreach, or renewal-vs-sale pitches. This is the primary tool for the \"who needs attention this quarter\" question.",
      "keywords": [
        "expiring leases",
        "renewal opportunities",
        "lease end",
        "upcoming renewals"
      ],
      "docs": "https://docs.actuallycare.com/tools/leases/leases_expiring",
      "inputSchema": {
        "type": "object",
        "properties": {
          "days": {
            "type": "number",
            "minimum": 0,
            "maximum": 365,
            "description": "Lookahead window in days (default: 60)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "leases_stats",
      "category": "leases",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get aggregate stats for the user's leases: total count, breakdown by_status, active_monthly_rent_roll (sum of monthly_rent for active leases — useful for \"how much recurring rental income am I managing\"), and expiring_in_60_days count.",
      "keywords": [
        "lease stats",
        "rent roll",
        "leasing dashboard",
        "lease counts"
      ],
      "docs": "https://docs.actuallycare.com/tools/leases/leases_stats",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "listings_list",
      "aliasOf": "search_listings",
      "category": "listings",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search for property listings by address, MLS number, status, or price range. Returns pagination info (total_count, has_more, offset, limit) for batch operations. Results include: id, property_address, city, state, zip_code, list_price, listing_status, property_type, bedrooms, bathrooms, square_feet, created_at. Filter by status to find active listings vs sold/expired. Use min_price/max_price to match buyer budgets. For a specific listing by ID, use listings_get instead. For aggregate stats, use listings_stats. Default limit is 20 when not provided; if the default is used and more results exist, the response includes truncated: true and total: N so you can rerun with a higher limit.",
      "keywords": [
        "listing",
        "listings",
        "property",
        "properties",
        "mls",
        "for sale",
        "active listings",
        "search",
        "price range"
      ],
      "docs": "https://docs.actuallycare.com/tools/listings/listings_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term — matches against property_address, city, and mls_number (case-insensitive partial match)."
          },
          "status": {
            "type": "string",
            "enum": [
              "all",
              "active",
              "pending",
              "sold",
              "expired",
              "cancelled",
              "coming_soon"
            ],
            "description": "Filter by listing status. active=on market, pending=under contract, sold=closed, expired=listing ended, coming_soon=pre-market (default: all)."
          },
          "min_price": {
            "type": "number",
            "minimum": 0,
            "description": "Minimum listing price in dollars. Use with max_price for buyer matching."
          },
          "max_price": {
            "type": "number",
            "minimum": 0,
            "description": "Maximum listing price in dollars. Use with min_price for buyer matching."
          },
          "property_type": {
            "type": "string",
            "enum": [
              "single_family",
              "condo",
              "townhouse",
              "multi_family",
              "land",
              "commercial"
            ],
            "description": "Filter by property type."
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 500,
            "description": "Maximum results (default: 20, max: 500). When omitted and more results exist, response includes truncated: true + total: N."
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N results for pagination (default: 0)."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "listings_get",
      "aliasOf": "get_listing",
      "category": "listings",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of one or more listings by UUID. Supports BOTH single and batch modes: pass listing_id for one listing, or listing_ids array for efficient multi-fetch (up to 100 IDs). Single mode returns all listing fields including full description and MLS data. Batch mode returns array of listings with count and not_found list. If you don't have the UUID, use listings_list first. For matching listings to buyers, use match_buyers_to_listings.",
      "keywords": [
        "listing",
        "get",
        "details",
        "fetch",
        "property",
        "batch listings",
        "mls data"
      ],
      "docs": "https://docs.actuallycare.com/tools/listings/listings_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of a single listing. Use listings_list to find IDs."
          },
          "listing_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "maxItems": 100,
            "description": "Array of listing UUIDs for batch retrieval (max 100). More efficient than multiple single calls."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "listings_create",
      "aliasOf": "create_listing",
      "category": "listings",
      "registryCategory": "data",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new property listing. Call immediately with whatever data the user provides. Do NOT ask for missing fields — the system shows an editable draft card where the user can fill in remaining details. WORKFLOW: 1) Use lookup_address first to get verified address data with coordinates 2) Create the listing with property details 3) Optionally schedule open houses with create_open_house. Returns the created listing with ID. Required fields: property_address and list_price. May trigger notifications if integrations are configured.",
      "keywords": [
        "listing",
        "create",
        "new",
        "property",
        "add",
        "list property",
        "seller"
      ],
      "docs": "https://docs.actuallycare.com/tools/listings/listings_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "property_address": {
            "type": "string",
            "description": "Full property address (required). Use lookup_address first for verified data."
          },
          "display_address": {
            "type": "string",
            "description": "Display address if different (e.g., \"123 Main St, Unit 4B\")."
          },
          "city": {
            "type": "string",
            "description": "City."
          },
          "state": {
            "type": "string",
            "description": "State abbreviation (e.g., CA)."
          },
          "zip_code": {
            "type": "string",
            "description": "ZIP code."
          },
          "county": {
            "type": "string",
            "description": "County name."
          },
          "latitude": {
            "type": "number",
            "description": "Latitude coordinate (from lookup_address)."
          },
          "longitude": {
            "type": "number",
            "description": "Longitude coordinate (from lookup_address)."
          },
          "list_price": {
            "type": "number",
            "minimum": 0,
            "description": "Listing price in dollars (required)."
          },
          "mls_number": {
            "type": "string",
            "description": "MLS number (RESO ListingId)."
          },
          "bedrooms": {
            "type": "number",
            "minimum": 0,
            "description": "Number of bedrooms."
          },
          "bathrooms": {
            "type": "number",
            "minimum": 0,
            "description": "Number of bathrooms (can be decimal for half baths)."
          },
          "square_feet": {
            "type": "number",
            "minimum": 0,
            "description": "Square footage (RESO LivingArea)."
          },
          "lot_size": {
            "type": "number",
            "description": "Lot size in square feet."
          },
          "year_built": {
            "type": "number",
            "description": "Year built."
          },
          "garage_spaces": {
            "type": "number",
            "description": "Number of garage spaces."
          },
          "stories": {
            "type": "number",
            "description": "Number of stories."
          },
          "property_type": {
            "type": "string",
            "enum": [
              "single_family",
              "condo",
              "townhouse",
              "multi_family",
              "land",
              "commercial"
            ],
            "description": "Type of property (RESO PropertyType)."
          },
          "property_sub_type": {
            "type": "string",
            "description": "RESO PropertySubType (e.g., Attached, Detached)."
          },
          "listing_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Date listing goes active on MLS. (Format: YYYY-MM-DD)"
          },
          "expiration_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Listing agreement expiration date — important for tracking. (Format: YYYY-MM-DD)"
          },
          "listing_status": {
            "type": "string",
            "enum": [
              "active",
              "pending",
              "coming_soon"
            ],
            "description": "Initial listing status."
          },
          "description": {
            "type": "string",
            "description": "Property description (also sets public_remarks)."
          },
          "public_remarks": {
            "type": "string",
            "description": "RESO PublicRemarks (MLS description)."
          },
          "showing_instructions": {
            "type": "string",
            "description": "RESO ShowingInstructions."
          },
          "virtual_tour_link": {
            "type": "string",
            "description": "Virtual tour URL (branded)."
          },
          "list_agent_mls_id": {
            "type": "string",
            "description": "RESO ListAgentMlsId."
          },
          "list_agent_full_name": {
            "type": "string",
            "description": "RESO ListAgentFullName."
          },
          "list_office_name": {
            "type": "string",
            "description": "RESO ListOfficeName."
          }
        },
        "required": [
          "property_address",
          "list_price"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "listings_update",
      "aliasOf": "update_listing",
      "category": "listings",
      "registryCategory": "data",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing listing's information or status. Only provided fields are updated — omitted fields remain unchanged. Common uses: price reduction (update list_price), status change (active→pending→sold), address correction, extend expiration date. Status transitions: active → pending (offer accepted) → sold (closed) or expired/cancelled (listing ended). Returns the updated listing record. If the listing_id is not found, the error suggests using listings_list.",
      "keywords": [
        "listing",
        "update",
        "edit",
        "status",
        "price",
        "price reduction"
      ],
      "docs": "https://docs.actuallycare.com/tools/listings/listings_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the listing to update (required). Use listings_list to find the ID if unknown."
          },
          "property_address": {
            "type": "string",
            "description": "Updated street address."
          },
          "display_address": {
            "type": "string",
            "description": "Updated display address (e.g., with unit number)."
          },
          "city": {
            "type": "string",
            "description": "Updated city name."
          },
          "state": {
            "type": "string",
            "description": "Updated state abbreviation."
          },
          "zip_code": {
            "type": "string",
            "description": "Updated ZIP code."
          },
          "county": {
            "type": "string",
            "description": "Updated county name."
          },
          "latitude": {
            "type": "number",
            "description": "Updated latitude coordinate."
          },
          "longitude": {
            "type": "number",
            "description": "Updated longitude coordinate."
          },
          "list_price": {
            "type": "number",
            "minimum": 0,
            "description": "Updated listing price (price reduction or increase)."
          },
          "mls_number": {
            "type": "string",
            "description": "Updated MLS listing number."
          },
          "bedrooms": {
            "type": "number",
            "minimum": 0,
            "description": "Updated bedroom count."
          },
          "bathrooms": {
            "type": "number",
            "minimum": 0,
            "description": "Updated bathroom count (can be decimal for half baths)."
          },
          "square_feet": {
            "type": "number",
            "minimum": 0,
            "description": "Updated square footage."
          },
          "property_type": {
            "type": "string",
            "enum": [
              "single_family",
              "condo",
              "townhouse",
              "multi_family",
              "land",
              "commercial"
            ],
            "description": "Updated property type (rare — usually fixed at creation)."
          },
          "close_price": {
            "type": "number",
            "description": "Close/sale price (RESO ClosePrice)."
          },
          "close_date": {
            "type": "string",
            "description": "Close date (ISO 8601, RESO CloseDate)."
          },
          "listing_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Updated date listing went active on MLS. (Format: YYYY-MM-DD)"
          },
          "expiration_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Updated expiration date (for extensions). (Format: YYYY-MM-DD)"
          },
          "listing_status": {
            "type": "string",
            "enum": [
              "active",
              "pending",
              "sold",
              "expired",
              "cancelled"
            ],
            "description": "Updated status. active→pending→sold is the typical flow."
          },
          "description": {
            "type": "string",
            "description": "Updated description."
          },
          "public_remarks": {
            "type": "string",
            "description": "RESO PublicRemarks."
          },
          "private_remarks": {
            "type": "string",
            "description": "RESO PrivateRemarks (agent-only notes)."
          },
          "buyer_agent_mls_id": {
            "type": "string",
            "description": "RESO BuyerAgentMlsId."
          },
          "buyer_agent_full_name": {
            "type": "string",
            "description": "RESO BuyerAgentFullName."
          }
        },
        "required": [
          "listing_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "listings_stats",
      "aliasOf": "get_listings_summary",
      "category": "listings",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get aggregate statistics for all listings: counts by status (active/pending/sold/expired), total active listings value, and average days on market. Use this for dashboard metrics and pipeline overview. Does NOT return individual listing records — use listings_list for that. Returns statusCounts array and activeListingsValue total. For specific listings, use listings_list with filters.",
      "keywords": [
        "listing",
        "stats",
        "summary",
        "dashboard",
        "counts",
        "active listings value",
        "days on market"
      ],
      "docs": "https://docs.actuallycare.com/tools/listings/listings_stats",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "listings_expiring",
      "category": "listings",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get listings approaching or past their expiration date. PROSPECTING TOOL: Expiring listings are opportunities to acquire new business — contact sellers whose listings are about to expire. Returns listings sorted by expiration date. Use days_until_expiration to set the lookback window. include_expired=true also shows recently expired listings (within expired_within_days). Default shows active listings expiring in next 30 days plus expired within 14 days.",
      "keywords": [
        "expiring listings",
        "expired listings",
        "prospecting",
        "relist opportunities",
        "seller outreach"
      ],
      "docs": "https://docs.actuallycare.com/tools/listings/listings_expiring",
      "inputSchema": {
        "type": "object",
        "properties": {
          "days_until_expiration": {
            "type": "number",
            "minimum": 1,
            "description": "Show listings expiring within X days (default: 30)."
          },
          "include_expired": {
            "type": "boolean",
            "description": "Include recently expired listings (default: true)."
          },
          "expired_within_days": {
            "type": "number",
            "minimum": 1,
            "description": "If including expired, how many days back to look (default: 14)."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "listings_archive",
      "category": "listings",
      "registryCategory": "data",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive a listing to hide it from active views without deleting it. Archived listings can be restored later with listings_restore. Use this for expired or sold listings you want to declutter from your dashboard. Returns the archived listing record.",
      "keywords": [
        "archive listing",
        "hide listing",
        "declutter"
      ],
      "docs": "https://docs.actuallycare.com/tools/listings/listings_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the listing to archive. Use listings_list to find the ID if unknown."
          }
        },
        "required": [
          "listing_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "listings_restore",
      "category": "listings",
      "registryCategory": "data",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore a previously archived listing back to active views. Reverses the effect of listings_archive. Use this when a listing needs to be reactivated or was archived by mistake. Returns the restored listing record.",
      "keywords": [
        "restore listing",
        "unarchive listing",
        "reactivate listing"
      ],
      "docs": "https://docs.actuallycare.com/tools/listings/listings_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the listing to restore. Must be currently archived."
          }
        },
        "required": [
          "listing_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "listings_delete",
      "category": "listings",
      "registryCategory": "data",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete a listing. This is IRREVERSIBLE — the listing will be hidden from all views, including archived. Only use for test data or duplicate records. For normal cleanup, use listings_archive instead which is reversible. Returns confirmation of the deletion.",
      "keywords": [
        "delete listing",
        "remove listing",
        "destructive"
      ],
      "docs": "https://docs.actuallycare.com/tools/listings/listings_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the listing to delete. Use listings_get first to verify."
          }
        },
        "required": [
          "listing_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "open_houses_list",
      "category": "open-houses",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search for open house events by address, status, or date range. Returns pagination info (total_count, has_more, offset, limit). Results include: id, address, list_price, date, start_time, end_time, status, visitor_count, notes, created_at. Filter by status (scheduled/in_progress/completed/cancelled) or date range. For a specific open house by ID, use open_houses_get instead. For aggregate stats, use open_houses_stats.",
      "keywords": [
        "open house",
        "open houses",
        "events",
        "sunday showings",
        "visitor sign-in",
        "upcoming open houses"
      ],
      "docs": "https://docs.actuallycare.com/tools/open-houses/open_houses_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term - matches against address (case-insensitive partial match)"
          },
          "status": {
            "type": "string",
            "enum": [
              "all",
              "scheduled",
              "in_progress",
              "completed",
              "cancelled"
            ],
            "description": "Filter by status. scheduled=upcoming, in_progress=happening now, completed=past, cancelled=cancelled (default: all)"
          },
          "date_from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show open houses on or after this date (Format: YYYY-MM-DD)"
          },
          "date_to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show open houses on or before this date (Format: YYYY-MM-DD)"
          },
          "archived": {
            "type": "boolean",
            "description": "Include archived open houses (default: false)"
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 500,
            "description": "Maximum results (default: 50, max: 500)"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N results for pagination (default: 0)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "open_houses_get",
      "category": "open-houses",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of an open house by UUID, including all visitors. Returns address, date/time, status, notes, visitor_count, and full visitor list with contact info and interest level. If you don't have the UUID, use open_houses_list first.",
      "keywords": [
        "open house details",
        "get open house",
        "visitors",
        "sign-in list"
      ],
      "docs": "https://docs.actuallycare.com/tools/open-houses/open_houses_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "open_house_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the open house. Use open_houses_list to find IDs."
          }
        },
        "required": [
          "open_house_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "open_houses_create",
      "category": "open-houses",
      "registryCategory": "data",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Schedule a new open house event. WORKFLOW: 1) Optionally use listings_list to find the listing 2) Create the open house with address, date, and time 3) Use log_open_house_visitor to log visitors during the event. Returns the created open house with ID. Required fields: address, date, start_time, end_time.",
      "keywords": [
        "schedule open house",
        "new open house",
        "create event"
      ],
      "docs": "https://docs.actuallycare.com/tools/open-houses/open_houses_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "description": "Property address for the open house (required)"
          },
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the associated listing (optional). Use listings_list to find."
          },
          "list_price": {
            "type": "number",
            "minimum": 0,
            "description": "Property list price in dollars"
          },
          "date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Date of the open house (required) (Format: YYYY-MM-DD)"
          },
          "start_time": {
            "type": "string",
            "description": "Start time in HH:MM format (required), e.g. \"13:00\""
          },
          "end_time": {
            "type": "string",
            "description": "End time in HH:MM format (required), e.g. \"16:00\""
          },
          "status": {
            "type": "string",
            "enum": [
              "scheduled",
              "in_progress",
              "completed",
              "cancelled"
            ],
            "description": "Initial status (default: scheduled)"
          },
          "notes": {
            "type": "string",
            "description": "Notes or special instructions for the open house"
          }
        },
        "required": [
          "address",
          "date",
          "start_time",
          "end_time"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "open_houses_update",
      "category": "open-houses",
      "registryCategory": "data",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing open house's information or status. Only provided fields are updated - omitted fields remain unchanged. Common uses: reschedule (update date/times), status change (scheduled→in_progress→completed), add notes. Returns the updated open house record.",
      "keywords": [
        "reschedule open house",
        "update open house",
        "change time"
      ],
      "docs": "https://docs.actuallycare.com/tools/open-houses/open_houses_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "open_house_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the open house to update (required). Use open_houses_list to find."
          },
          "address": {
            "type": "string",
            "description": "Updated property address"
          },
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated listing ID"
          },
          "list_price": {
            "type": "number",
            "minimum": 0,
            "description": "Updated list price"
          },
          "date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Updated date (Format: YYYY-MM-DD)"
          },
          "start_time": {
            "type": "string",
            "description": "Updated start time in HH:MM format"
          },
          "end_time": {
            "type": "string",
            "description": "Updated end time in HH:MM format"
          },
          "status": {
            "type": "string",
            "enum": [
              "scheduled",
              "in_progress",
              "completed",
              "cancelled"
            ],
            "description": "Updated status"
          },
          "notes": {
            "type": "string",
            "description": "Updated notes"
          }
        },
        "required": [
          "open_house_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "open_houses_stats",
      "category": "open-houses",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get aggregate statistics for open houses: total count, upcoming count, completed count, total visitors, average visitors per event, and next 5 upcoming events. Use this for dashboard metrics. Does NOT return individual records - use open_houses_list for that.",
      "keywords": [
        "open house stats",
        "visitor totals",
        "event metrics"
      ],
      "docs": "https://docs.actuallycare.com/tools/open-houses/open_houses_stats",
      "inputSchema": {
        "type": "object",
        "properties": {
          "period": {
            "type": "string",
            "enum": [
              "1_day",
              "1_week",
              "1_month",
              "3_months",
              "1_year",
              "ytd",
              "all"
            ],
            "description": "Time period for stats (default: 1_month)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "open_houses_archive",
      "category": "open-houses",
      "registryCategory": "data",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive an open house to hide it from active views without deleting it. Archived open houses can be restored later with open_houses_restore. Use this for past events you want to declutter from your dashboard. Returns the archived record.",
      "keywords": [
        "archive open house",
        "hide open house"
      ],
      "docs": "https://docs.actuallycare.com/tools/open-houses/open_houses_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "open_house_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the open house to archive. Use open_houses_list to find."
          }
        },
        "required": [
          "open_house_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "open_houses_restore",
      "category": "open-houses",
      "registryCategory": "data",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore a previously archived open house back to active views. Reverses the effect of open_houses_archive. Returns the restored record.",
      "keywords": [
        "restore open house",
        "unarchive open house"
      ],
      "docs": "https://docs.actuallycare.com/tools/open-houses/open_houses_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "open_house_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the open house to restore. Must be currently archived."
          }
        },
        "required": [
          "open_house_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "open_houses_delete",
      "category": "open-houses",
      "registryCategory": "data",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete an open house. This is IRREVERSIBLE - the open house will be hidden from all views, including archived. The open house must be archived first. For normal cleanup, use open_houses_archive instead which is reversible.",
      "keywords": [
        "delete open house",
        "remove open house",
        "destructive"
      ],
      "docs": "https://docs.actuallycare.com/tools/open-houses/open_houses_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "open_house_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the open house to delete. Must be archived first. Use open_houses_get to verify."
          }
        },
        "required": [
          "open_house_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "partners_list",
      "category": "partners",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search for vendor partners by name, status, vendor type, or tier. Returns pagination info (total_count, has_more, offset, limit). Results include: id, display_id, title, vendor_type, status, tier, partner_since, care_status, contact info, created_at. Filter by status (onboarding/active/preferred/paused/churned), tier (standard/preferred/vip), vendor_type, or care_status. For a specific partner by ID, use partners_get instead. For aggregate stats, use partners_stats.",
      "keywords": [
        "partner",
        "partners",
        "vendor",
        "relationship",
        "list",
        "search",
        "tier"
      ],
      "docs": "https://docs.actuallycare.com/tools/partners/partners_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term - matches against title, notes (case-insensitive partial match)"
          },
          "status": {
            "type": "string",
            "enum": [
              "all",
              "onboarding",
              "active",
              "preferred",
              "paused",
              "churned"
            ],
            "description": "Filter by status. onboarding=setting up, active=regular partner, preferred=top partner, paused=temporarily inactive, churned=relationship ended (default: all)"
          },
          "tier": {
            "type": "string",
            "enum": [
              "all",
              "standard",
              "preferred",
              "vip"
            ],
            "description": "Filter by partner tier (default: all)"
          },
          "vendor_type": {
            "type": "string",
            "description": "Filter by vendor type (e.g. lender, inspector, escrow_officer, title_rep, appraiser, contractor, photographer)"
          },
          "care_status": {
            "type": "string",
            "enum": [
              "all",
              "no_status",
              "cared",
              "needs_care",
              "didnt_care"
            ],
            "description": "Filter by care status (default: all)"
          },
          "date_from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show partners created on or after this date (Format: YYYY-MM-DD)"
          },
          "date_to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show partners created on or before this date (Format: YYYY-MM-DD)"
          },
          "archived": {
            "type": "boolean",
            "description": "Include archived partners (default: false)"
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 500,
            "description": "Maximum results (default: 50, max: 500)"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N results for pagination (default: 0)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "partners_get",
      "category": "partners",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of a vendor partner by UUID, including contact info, vendor type, tier, partner_since date, notes, tags, and relationship history. Returns all fields. If you don't have the UUID, use partners_list first.",
      "keywords": [
        "partner",
        "detail",
        "get",
        "view",
        "vendor",
        "relationship"
      ],
      "docs": "https://docs.actuallycare.com/tools/partners/partners_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "partner_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the partner. Use partners_list to find IDs."
          }
        },
        "required": [
          "partner_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "partners_create",
      "category": "partners",
      "registryCategory": "generics",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new vendor partner to track an established vendor relationship. WORKFLOW: 1) Optionally use contacts_list to find the contact 2) Create the partner with vendor_type and relationship details. Returns the created partner with ID and display_id. Tier defaults to 'standard' if not specified.",
      "keywords": [
        "partner",
        "create",
        "new",
        "add",
        "vendor",
        "relationship"
      ],
      "docs": "https://docs.actuallycare.com/tools/partners/partners_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of an existing contact for this partner. Use contacts_list to find."
          },
          "vendor_type": {
            "type": "string",
            "description": "Type of vendor (e.g. lender, inspector, escrow_officer, title_rep, appraiser, contractor, photographer)"
          },
          "title": {
            "type": "string",
            "description": "Title or name for this partner record"
          },
          "tier": {
            "type": "string",
            "enum": [
              "standard",
              "preferred",
              "vip"
            ],
            "description": "Partner tier level (default: standard)"
          },
          "partner_since": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Date the partnership began (Format: YYYY-MM-DD)"
          },
          "notes": {
            "type": "string",
            "description": "Additional notes about the partner relationship"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tags for categorization (e.g. [\"reliable\", \"fast-turnaround\", \"bilingual\"])"
          }
        },
        "required": [
          "vendor_type"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "partners_update",
      "category": "partners",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing vendor partner's information or status. Only provided fields are updated - omitted fields remain unchanged. Common uses: status change (onboarding->active->preferred), tier upgrade, update notes. Returns the updated partner record.",
      "keywords": [
        "partner",
        "update",
        "edit",
        "modify",
        "tier",
        "status",
        "vendor"
      ],
      "docs": "https://docs.actuallycare.com/tools/partners/partners_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "partner_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the partner to update (required). Use partners_list to find."
          },
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated contact ID. Use contacts_list to find."
          },
          "vendor_type": {
            "type": "string",
            "description": "Updated vendor type"
          },
          "title": {
            "type": "string",
            "description": "Updated title"
          },
          "status": {
            "type": "string",
            "enum": [
              "onboarding",
              "active",
              "preferred",
              "paused",
              "churned"
            ],
            "description": "Updated status"
          },
          "tier": {
            "type": "string",
            "enum": [
              "standard",
              "preferred",
              "vip"
            ],
            "description": "Updated partner tier"
          },
          "partner_since": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Updated partnership start date (Format: YYYY-MM-DD)"
          },
          "notes": {
            "type": "string",
            "description": "Updated notes"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Updated tags array (replaces existing tags)"
          },
          "care_status": {
            "type": "string",
            "enum": [
              "no_status",
              "cared",
              "needs_care",
              "didnt_care"
            ],
            "description": "Care status for tracking. Setting this also updates the audit columns."
          },
          "care_status_note": {
            "type": "string",
            "description": "Note explaining the care status change."
          },
          "record_data": {
            "type": "object",
            "additionalProperties": true,
            "description": "Pipeline-specific vertical data as a JSON object. Replaces (does not merge with) the existing record_data."
          }
        },
        "required": [
          "partner_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "partners_stats",
      "category": "partners",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get aggregate statistics for vendor partners: total count, counts by status, counts by tier, counts by vendor type, active vs churned ratio. Use this for dashboard metrics. Does NOT return individual records - use partners_list for that.",
      "keywords": [
        "partner",
        "stats",
        "metrics",
        "dashboard",
        "aggregate",
        "churn"
      ],
      "docs": "https://docs.actuallycare.com/tools/partners/partners_stats",
      "inputSchema": {
        "type": "object",
        "properties": {
          "period": {
            "type": "string",
            "enum": [
              "1_day",
              "1_week",
              "1_month",
              "3_months",
              "1_year",
              "ytd",
              "all"
            ],
            "description": "Time period for stats (default: 1_month)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "partners_archive",
      "category": "partners",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive a vendor partner to hide it from active views without deleting it. Archived partners can be restored later with partners_restore. Use this for churned or paused partners you want to declutter from your dashboard. Returns the archived record.",
      "keywords": [
        "partner",
        "archive",
        "hide",
        "declutter"
      ],
      "docs": "https://docs.actuallycare.com/tools/partners/partners_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "partner_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the partner to archive. Use partners_list to find."
          }
        },
        "required": [
          "partner_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "partners_restore",
      "category": "partners",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore a previously archived vendor partner back to active views. Reverses the effect of partners_archive. Returns the restored record.",
      "keywords": [
        "partner",
        "restore",
        "unarchive",
        "recover"
      ],
      "docs": "https://docs.actuallycare.com/tools/partners/partners_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "partner_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the partner to restore. Must be currently archived."
          }
        },
        "required": [
          "partner_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "partners_delete",
      "category": "partners",
      "registryCategory": "generics",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete a vendor partner. This is IRREVERSIBLE - the partner will be hidden from all views including archived. The partner must be archived first. For normal cleanup, use partners_archive instead, which is reversible.",
      "keywords": [
        "partner",
        "delete",
        "remove",
        "destroy",
        "permanent"
      ],
      "docs": "https://docs.actuallycare.com/tools/partners/partners_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "partner_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the partner to delete. Must be archived first. Use partners_get to verify."
          }
        },
        "required": [
          "partner_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_overview",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get pipeline counts grouped by industry vertical for the current user. Returns lead, appointment, client, and stage-4 counts per vertical. Useful for understanding pipeline volume across different business verticals.",
      "keywords": [
        "pipeline",
        "overview",
        "counts",
        "vertical",
        "dashboard"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_overview",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_types_list",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "List available pipeline types for the current user based on their role. System admins see the SaaS Growth Pipeline. Vendors and lenders see their industry-specific pipeline. Returns pipeline type IDs needed for other pipeline operations.",
      "keywords": [
        "pipeline",
        "types",
        "list",
        "config"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_types_list",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_stages_list",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get the ordered stages (funnel) for a specific pipeline type. Each stage has a key, label, color, probability, and whether it is a default/final/lost stage. Use pipeline_types_list first to get the pipeline_type_id.",
      "keywords": [
        "pipeline",
        "stages",
        "funnel",
        "config"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_stages_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "pipeline_type_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Pipeline type UUID from pipeline_types_list"
          }
        },
        "required": [
          "pipeline_type_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_records_create",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new pipeline record. Provide contact_id for an existing contact, OR first_name + last_name (+ optional email/phone) to auto-create a contact. The record starts at the default (first) stage. Returns the created record with ID for subsequent operations.",
      "keywords": [
        "pipeline",
        "record",
        "create",
        "new"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_records_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "pipeline_type_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Pipeline type UUID (use pipeline_types_list to find)"
          },
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Existing contact UUID (optional if providing name/email)"
          },
          "first_name": {
            "type": "string",
            "description": "First name for auto-creating a contact"
          },
          "last_name": {
            "type": "string",
            "description": "Last name for auto-creating a contact"
          },
          "email": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
            "description": "Email address"
          },
          "phone": {
            "type": "string",
            "description": "Phone number"
          },
          "company": {
            "type": "string",
            "description": "Company name"
          },
          "title": {
            "type": "string",
            "description": "Record title (e.g., \"Smith Brokerage — 15 seats\")"
          },
          "source": {
            "type": "string",
            "description": "Lead source (referral, website, ad, cold_call, etc.)"
          },
          "estimated_ltv": {
            "type": "number",
            "description": "Estimated lifetime value in dollars"
          },
          "expected_close_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Expected conversion date (Format: YYYY-MM-DD)"
          },
          "priority": {
            "type": "string",
            "enum": [
              "low",
              "medium",
              "high",
              "urgent"
            ],
            "description": "Priority level"
          },
          "notes": {
            "type": "string",
            "description": "Notes about this record"
          },
          "record_data": {
            "type": "object",
            "description": "Stage-specific fields as key-value pairs"
          }
        },
        "required": [
          "pipeline_type_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_records_list",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "List pipeline records with filtering. Use to browse a pipeline or find record IDs before get/update/move operations. Filter by stage, care status, priority, source, or search by name/email/title. Returns records with contact info and stage details.",
      "keywords": [
        "pipeline",
        "records",
        "list",
        "filter"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_records_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "pipeline_type_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Filter by pipeline type"
          },
          "stage_key": {
            "type": "string",
            "description": "Filter by stage key (e.g., \"lead\", \"demo\", \"trial\")"
          },
          "care_status": {
            "type": "string",
            "description": "Filter by care status",
            "enum": [
              "no_status",
              "cared",
              "needs_care",
              "didnt_care"
            ]
          },
          "priority": {
            "type": "string",
            "description": "Filter by priority level",
            "enum": [
              "low",
              "medium",
              "high",
              "urgent"
            ]
          },
          "source": {
            "type": "string",
            "description": "Filter by source"
          },
          "search": {
            "type": "string",
            "description": "Search by contact name, email, or record title"
          },
          "is_archived": {
            "type": "boolean",
            "description": "Include archived records (default: false)"
          },
          "page": {
            "type": "integer",
            "minimum": 1,
            "description": "Page number (default: 1)"
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "Results per page (default: 25)"
          },
          "sort_by": {
            "type": "string",
            "description": "Sort field",
            "enum": [
              "created_at",
              "updated_at",
              "estimated_ltv",
              "expected_close_date",
              "priority"
            ]
          },
          "sort_order": {
            "type": "string",
            "description": "Sort direction",
            "enum": [
              "asc",
              "desc"
            ]
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_records_get",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get a single pipeline record by ID with full details including contact info, current stage, pipeline type, and stage-specific fields. Use after pipeline_records_list when you need everything about one record. Returns the complete record.",
      "keywords": [
        "pipeline",
        "record",
        "get",
        "detail"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_records_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Pipeline record UUID"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_records_update",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update a pipeline record's fields — title, source, estimated_ltv, priority, notes, tags, record_data, and more. Only provided fields are updated. To change stage, use pipeline_records_move_stage instead. Returns the updated record.",
      "keywords": [
        "pipeline",
        "record",
        "update",
        "edit"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_records_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Pipeline record UUID"
          },
          "title": {
            "type": "string",
            "description": "Record title"
          },
          "source": {
            "type": "string",
            "description": "Lead/record source"
          },
          "estimated_ltv": {
            "type": "number",
            "description": "Estimated lifetime value"
          },
          "current_revenue": {
            "type": "number",
            "description": "Current revenue amount"
          },
          "expected_close_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Expected conversion date (Format: YYYY-MM-DD)"
          },
          "expiration_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Expiration date (Format: YYYY-MM-DD)"
          },
          "priority": {
            "type": "string",
            "description": "Priority level",
            "enum": [
              "low",
              "medium",
              "high",
              "urgent"
            ]
          },
          "notes": {
            "type": "string",
            "description": "Free-text notes"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tags for categorization (replaces existing tags)"
          },
          "record_data": {
            "type": "object",
            "description": "Stage-specific fields (merged with existing)"
          },
          "probability": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "Close probability percentage (0-100)"
          },
          "care_status": {
            "type": "string",
            "description": "Care status",
            "enum": [
              "no_status",
              "cared",
              "needs_care",
              "didnt_care"
            ]
          },
          "care_status_note": {
            "type": "string",
            "description": "Note for care status change"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_records_move_stage",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Move a pipeline record to a new stage. Logs the stage transition in the activity history. Use pipeline_stages_list to see available stage keys.",
      "keywords": [
        "pipeline",
        "record",
        "stage",
        "move",
        "transition"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_records_move_stage",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Pipeline record UUID"
          },
          "stage_key": {
            "type": "string",
            "description": "Target stage key (e.g., \"demo\", \"trial\", \"paid\")"
          },
          "notes": {
            "type": "string",
            "description": "Notes about why this record moved stages"
          }
        },
        "required": [
          "id",
          "stage_key"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_records_delete",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Delete a pipeline record. Use for records created by mistake or test data — for records you may need again, prefer pipeline_records_archive. The record is marked as deleted and hidden from all views, but not permanently removed. Returns confirmation of the deletion.",
      "keywords": [
        "pipeline",
        "record",
        "delete",
        "remove"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_records_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Pipeline record UUID"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_records_archive",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive a pipeline record to hide it from default views without deleting it. Use for stale or inactive records you want out of the way — restore later with pipeline_records_restore. Returns the archived record.",
      "keywords": [
        "pipeline",
        "record",
        "archive"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_records_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Pipeline record UUID"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_records_restore",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore an archived pipeline record back to active status. Use when a previously archived record becomes relevant again. Returns the restored record.",
      "keywords": [
        "pipeline",
        "record",
        "restore"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_records_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Pipeline record UUID"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_records_stats",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get pipeline statistics: funnel counts per stage, total LTV, total revenue, conversion rate, records needing follow-up, and records expiring soon. Use to answer how a pipeline is doing or to decide where to focus follow-up. Returns the aggregate numbers only — use pipeline_records_list to see the underlying records.",
      "keywords": [
        "pipeline",
        "stats",
        "funnel",
        "conversion",
        "ltv"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_records_stats",
      "inputSchema": {
        "type": "object",
        "properties": {
          "pipeline_type_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Filter stats by pipeline type"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_record_activities",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get the activity history for a pipeline record — stage changes, notes, calls, meetings, and other logged activities in reverse chronological order. Use to review what has happened on a record before the next touch. Returns the activity list.",
      "keywords": [
        "pipeline",
        "record",
        "activity",
        "history",
        "timeline"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_record_activities",
      "inputSchema": {
        "type": "object",
        "properties": {
          "record_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Pipeline record UUID"
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "Max activities to return (default: 20)"
          }
        },
        "required": [
          "record_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_record_log_activity",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Logs activity",
      "readOnly": false,
      "destructive": false,
      "description": "Log an activity on a pipeline record. Use for notes, calls, emails, meetings, demos, or tasks. Creates a timestamped entry in the record's activity history.",
      "keywords": [
        "pipeline",
        "record",
        "log",
        "activity",
        "note",
        "call"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_record_log_activity",
      "inputSchema": {
        "type": "object",
        "properties": {
          "record_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Pipeline record UUID"
          },
          "activity_type": {
            "type": "string",
            "enum": [
              "note",
              "call",
              "email",
              "meeting",
              "demo",
              "task",
              "other"
            ],
            "description": "Type of activity"
          },
          "subject": {
            "type": "string",
            "description": "Activity subject/title"
          },
          "body": {
            "type": "string",
            "description": "Activity details/notes"
          },
          "details": {
            "type": "object",
            "description": "Structured activity data"
          }
        },
        "required": [
          "record_id",
          "activity_type"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "pipeline_records_batch_stage",
      "category": "pipelines",
      "registryCategory": "pipelines",
      "annotation": "Bulk changes",
      "readOnly": false,
      "destructive": true,
      "description": "Move multiple pipeline records to the same stage. All records must belong to the same pipeline type. Logs individual stage transitions for each record.",
      "keywords": [
        "pipeline",
        "record",
        "batch",
        "bulk",
        "stage"
      ],
      "docs": "https://docs.actuallycare.com/tools/pipelines/pipeline_records_batch_stage",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "maxItems": 100,
            "description": "Array of pipeline record UUIDs"
          },
          "stage_key": {
            "type": "string",
            "description": "Target stage key"
          },
          "notes": {
            "type": "string",
            "description": "Notes about the batch stage change"
          }
        },
        "required": [
          "ids",
          "stage_key"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "analyze_pl_statement",
      "category": "pl-statements",
      "registryCategory": "financial",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Analyze an uploaded Profit & Loss statement the caller owns. Returns the parsed summary (period, totals, line-item count, top categories), prior-period totals when available, and the AI-generated recommendations attached to the statement. The caller MUST own the statement — requests for statements belonging to another account return an error. Use when the user asks \"what does my P&L tell me\", \"analyze my Q1 numbers\", or similar.",
      "keywords": [
        "pl",
        "profit",
        "loss",
        "analyze",
        "statement",
        "recommendations",
        "summary"
      ],
      "docs": "https://docs.actuallycare.com/tools/pl-statements/analyze_pl_statement",
      "inputSchema": {
        "type": "object",
        "properties": {
          "pl_statement_id": {
            "type": "string",
            "description": "UUID of the P&L statement to analyze. Must be owned by the caller."
          }
        },
        "required": [
          "pl_statement_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "categorize_expense",
      "category": "pl-statements",
      "registryCategory": "financial",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Predict the expense category for a single ad-hoc expense input (description + optional vendor + optional amount). Returns category, subcategory, confidence (0–1), and the source of the prediction (per-user vendor map, platform-wide vendor map, keyword rules, or none). NOT a write — does not record the expense.",
      "keywords": [
        "categorize",
        "expense",
        "category",
        "vendor",
        "classify"
      ],
      "docs": "https://docs.actuallycare.com/tools/pl-statements/categorize_expense",
      "inputSchema": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "description": "Free-text description of the expense (required if vendor not given)."
          },
          "vendor": {
            "type": "string",
            "description": "Vendor or payee name. Strongest signal for the categorizer."
          },
          "amount_cents": {
            "type": "integer",
            "minimum": 0,
            "description": "Amount in cents. Optional — used as a tie-breaker but not required."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "pm_consultations_list",
      "category": "pm-consultations",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search property-management (PM) consultations — the funnel for turning landlord contacts into management clients. Returns id, landlord_contact_id, stage, proposed_management_fee_pct, estimated_monthly_revenue, close_probability, next_meeting_at. Filter by stage to find consultations at a specific funnel step (e.g. stage='proposal_sent' for \"who am I waiting on?\").",
      "keywords": [
        "pm consultation",
        "property management sales",
        "landlord funnel",
        "management proposal",
        "pm pipeline"
      ],
      "docs": "https://docs.actuallycare.com/tools/pm-consultations/pm_consultations_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Free-text search (reserved)"
          },
          "stage": {
            "type": "string",
            "enum": [
              "initial_inquiry",
              "property_walkthrough",
              "proposal_sent",
              "contract_negotiation",
              "signed",
              "declined",
              "stalled"
            ],
            "description": "Filter by funnel stage"
          },
          "landlord_contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Filter to consultations with a specific landlord"
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 500,
            "description": "Maximum results (default: 25, max: 500)"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N results for pagination (default: 0)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "pm_consultations_get",
      "category": "pm-consultations",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of one consultation by UUID. Includes sensitive proposal terms (proposed_management_fee_pct, proposed_leasing_fee_months, estimated_monthly_revenue, close_probability) — caller must sanitize before any public AI summary.",
      "keywords": [
        "pm consultation details",
        "get consultation",
        "proposal terms",
        "management fee"
      ],
      "docs": "https://docs.actuallycare.com/tools/pm-consultations/pm_consultations_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "consultation_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the consultation"
          }
        },
        "required": [
          "consultation_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "pm_consultations_create",
      "category": "pm-consultations",
      "registryCategory": "core",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Start a PM consultation — a new conversation with a landlord about potentially handing over property management. Defaults stage='initial_inquiry'. Add property_listing_ids if the landlord has specific properties under discussion. Set estimated_monthly_revenue + close_probability to surface weighted pipeline value in stats.",
      "keywords": [
        "new pm consultation",
        "start pm discussion",
        "landlord intake",
        "pm inquiry"
      ],
      "docs": "https://docs.actuallycare.com/tools/pm-consultations/pm_consultations_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "landlord_contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the landlord contact (required)"
          },
          "property_listing_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUIDs of listings the landlord is considering for PM"
          },
          "stage": {
            "type": "string",
            "enum": [
              "initial_inquiry",
              "property_walkthrough",
              "proposal_sent",
              "contract_negotiation",
              "signed",
              "declined",
              "stalled"
            ],
            "description": "Initial stage (default: initial_inquiry)"
          },
          "proposed_management_fee_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Proposed monthly management fee percentage (0-100)"
          },
          "proposed_leasing_fee_months": {
            "type": "number",
            "minimum": 0,
            "description": "Months of rent charged as leasing fee when placing a new tenant"
          },
          "estimated_monthly_revenue": {
            "type": "number",
            "minimum": 0,
            "description": "Estimated recurring monthly revenue if signed"
          },
          "close_probability": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Probability of closing (0-100, used for weighted pipeline stats)"
          },
          "stage_notes": {
            "type": "string",
            "maxLength": 10000,
            "description": "Notes about the current stage (discussion points, next steps, objections)"
          }
        },
        "required": [
          "landlord_contact_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "pm_consultations_convert_to_tenancy",
      "category": "pm-consultations",
      "registryCategory": "core",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Atomically mark a consultation as signed and create a linked tenancy. Requires lease_id (the lease that now gets managed) and typically owner_client_id (the landlord as a client). The new tenancy automatically inherits the consultation's brokerage/team assignment. This is the canonical \"we've signed this landlord, start managing the lease\" action. Cannot convert a declined consultation.",
      "keywords": [
        "sign pm consultation",
        "convert to tenancy",
        "start managing",
        "pm close"
      ],
      "docs": "https://docs.actuallycare.com/tools/pm-consultations/pm_consultations_convert_to_tenancy",
      "inputSchema": {
        "type": "object",
        "properties": {
          "consultation_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the consultation to convert"
          },
          "lease_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the lease that will now be PM-managed (required)"
          },
          "owner_client_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the landlord as a client (typically client_type=landlord)"
          },
          "management_fee_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Actual fee on signing (default: proposed_management_fee_pct from consultation, or 10.00)"
          },
          "rent_collection_day": {
            "type": "number",
            "minimum": 1,
            "maximum": 31,
            "description": "Day of month for rent collection (default: 1)"
          },
          "notes": {
            "type": "string",
            "maxLength": 10000,
            "description": "Initial notes on the new tenancy"
          }
        },
        "required": [
          "consultation_id",
          "lease_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "prospects_list",
      "category": "prospects",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search for vendor prospects by name, status, vendor type, or interest level. Returns pagination info (total_count, has_more, offset, limit). Results include: id, display_id, title, vendor_type, status, interest_level, priority, estimated_ltv, care_status, contact info, created_at. Filter by status (identified/researching/outreach/responded/nurturing/converted/disqualified/lost), interest_level (cold/warm/hot), priority (low/medium/high/urgent), or vendor_type. For a specific prospect by ID, use prospects_get instead. For aggregate stats, use prospects_stats.",
      "keywords": [
        "prospect",
        "prospects",
        "vendor",
        "pipeline",
        "list",
        "search",
        "lead",
        "outreach"
      ],
      "docs": "https://docs.actuallycare.com/tools/prospects/prospects_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term - matches against title, notes (case-insensitive partial match)"
          },
          "status": {
            "type": "string",
            "enum": [
              "all",
              "identified",
              "researching",
              "outreach",
              "responded",
              "nurturing",
              "converted",
              "disqualified",
              "lost"
            ],
            "description": "Filter by status. identified=new prospect, researching=gathering info, outreach=initial contact, responded=they replied, nurturing=building relationship, converted=became partner, disqualified=not a fit, lost=went cold (default: all)"
          },
          "vendor_type": {
            "type": "string",
            "description": "Filter by vendor type (e.g. lender, inspector, escrow_officer, title_rep, appraiser, contractor, photographer)"
          },
          "interest_level": {
            "type": "string",
            "enum": [
              "all",
              "cold",
              "warm",
              "hot"
            ],
            "description": "Filter by interest level (default: all)"
          },
          "priority": {
            "type": "string",
            "enum": [
              "all",
              "low",
              "medium",
              "high",
              "urgent"
            ],
            "description": "Filter by priority (default: all)"
          },
          "care_status": {
            "type": "string",
            "enum": [
              "all",
              "no_status",
              "cared",
              "needs_care",
              "didnt_care"
            ],
            "description": "Filter by care status (default: all)"
          },
          "date_from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show prospects created on or after this date (Format: YYYY-MM-DD)"
          },
          "date_to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show prospects created on or before this date (Format: YYYY-MM-DD)"
          },
          "archived": {
            "type": "boolean",
            "description": "Include archived prospects (default: false)"
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 500,
            "description": "Maximum results (default: 50, max: 500)"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N results for pagination (default: 0)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "prospects_get",
      "category": "prospects",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of a vendor prospect by UUID, including contact info, vendor type, interest level, priority, estimated lifetime value, notes, tags, and status history. Returns all fields. If you don't have the UUID, use prospects_list first.",
      "keywords": [
        "prospect",
        "detail",
        "get",
        "view",
        "vendor"
      ],
      "docs": "https://docs.actuallycare.com/tools/prospects/prospects_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "prospect_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the prospect. Use prospects_list to find IDs."
          }
        },
        "required": [
          "prospect_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "prospects_create",
      "category": "prospects",
      "registryCategory": "generics",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new vendor prospect to track a potential partner. WORKFLOW: 1) Optionally use contacts_list to find the contact 2) Create the prospect with vendor_type and details. Returns the created prospect with ID and display_id. Interest level defaults to 'warm' and priority to 'medium' if not specified.",
      "keywords": [
        "prospect",
        "create",
        "new",
        "add",
        "vendor",
        "pipeline"
      ],
      "docs": "https://docs.actuallycare.com/tools/prospects/prospects_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of an existing contact for this prospect. Use contacts_list to find."
          },
          "vendor_type": {
            "type": "string",
            "description": "Type of vendor (e.g. lender, inspector, escrow_officer, title_rep, appraiser, contractor, photographer)"
          },
          "title": {
            "type": "string",
            "description": "Title or name for this prospect record"
          },
          "source": {
            "type": "string",
            "description": "How you discovered this prospect (e.g. \"referral\", \"networking event\", \"online search\")"
          },
          "interest_level": {
            "type": "string",
            "enum": [
              "cold",
              "warm",
              "hot"
            ],
            "description": "Interest level of the prospect (default: warm)"
          },
          "priority": {
            "type": "string",
            "enum": [
              "low",
              "medium",
              "high",
              "urgent"
            ],
            "description": "Priority for outreach (default: medium)"
          },
          "estimated_ltv": {
            "type": "number",
            "minimum": 0,
            "description": "Estimated lifetime value of this vendor relationship in dollars"
          },
          "notes": {
            "type": "string",
            "description": "Additional notes about the prospect"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tags for categorization (e.g. [\"local\", \"high-volume\", \"spanish-speaking\"])"
          }
        },
        "required": [
          "vendor_type"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "prospects_update",
      "category": "prospects",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing vendor prospect's information or status. Only provided fields are updated - omitted fields remain unchanged. Common uses: status change (identified->researching->outreach->responded->nurturing->converted), update interest level, add notes. Returns the updated prospect record.",
      "keywords": [
        "prospect",
        "update",
        "edit",
        "modify",
        "status",
        "vendor"
      ],
      "docs": "https://docs.actuallycare.com/tools/prospects/prospects_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "prospect_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the prospect to update (required). Use prospects_list to find."
          },
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated contact ID. Use contacts_list to find."
          },
          "vendor_type": {
            "type": "string",
            "description": "Updated vendor type"
          },
          "title": {
            "type": "string",
            "description": "Updated title"
          },
          "source": {
            "type": "string",
            "description": "Updated source"
          },
          "status": {
            "type": "string",
            "enum": [
              "identified",
              "researching",
              "outreach",
              "responded",
              "nurturing",
              "converted",
              "disqualified",
              "lost"
            ],
            "description": "Updated status"
          },
          "interest_level": {
            "type": "string",
            "enum": [
              "cold",
              "warm",
              "hot"
            ],
            "description": "Updated interest level"
          },
          "priority": {
            "type": "string",
            "enum": [
              "low",
              "medium",
              "high",
              "urgent"
            ],
            "description": "Updated priority"
          },
          "estimated_ltv": {
            "type": "number",
            "minimum": 0,
            "description": "Updated estimated lifetime value"
          },
          "notes": {
            "type": "string",
            "description": "Updated notes"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Updated tags array (replaces existing tags)"
          },
          "care_status": {
            "type": "string",
            "enum": [
              "no_status",
              "cared",
              "needs_care",
              "didnt_care"
            ],
            "description": "Care status for tracking. Setting this also updates the audit columns."
          },
          "care_status_note": {
            "type": "string",
            "description": "Note explaining the care status change."
          },
          "record_data": {
            "type": "object",
            "additionalProperties": true,
            "description": "Pipeline-specific vertical data as a JSON object. Replaces (does not merge with) the existing record_data."
          }
        },
        "required": [
          "prospect_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "prospects_stats",
      "category": "prospects",
      "registryCategory": "generics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get aggregate statistics for vendor prospects: total count, counts by status, counts by vendor type, counts by interest level, average estimated LTV. Use this for dashboard metrics. Does NOT return individual records - use prospects_list for that.",
      "keywords": [
        "prospect",
        "stats",
        "metrics",
        "dashboard",
        "aggregate",
        "pipeline"
      ],
      "docs": "https://docs.actuallycare.com/tools/prospects/prospects_stats",
      "inputSchema": {
        "type": "object",
        "properties": {
          "period": {
            "type": "string",
            "enum": [
              "1_day",
              "1_week",
              "1_month",
              "3_months",
              "1_year",
              "ytd",
              "all"
            ],
            "description": "Time period for stats (default: 1_month)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "prospects_archive",
      "category": "prospects",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive a vendor prospect to hide it from active views without deleting it. Archived prospects can be restored later with prospects_restore. Use this for disqualified or lost prospects you want to declutter from your dashboard. Returns the archived record.",
      "keywords": [
        "prospect",
        "archive",
        "hide",
        "declutter"
      ],
      "docs": "https://docs.actuallycare.com/tools/prospects/prospects_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "prospect_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the prospect to archive. Use prospects_list to find."
          }
        },
        "required": [
          "prospect_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "prospects_restore",
      "category": "prospects",
      "registryCategory": "generics",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore a previously archived vendor prospect back to active views. Reverses the effect of prospects_archive. Returns the restored record.",
      "keywords": [
        "prospect",
        "restore",
        "unarchive",
        "recover"
      ],
      "docs": "https://docs.actuallycare.com/tools/prospects/prospects_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "prospect_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the prospect to restore. Must be currently archived."
          }
        },
        "required": [
          "prospect_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "prospects_delete",
      "category": "prospects",
      "registryCategory": "generics",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete a vendor prospect. This is IRREVERSIBLE - the prospect will be hidden from all views including archived. The prospect must be archived first. For normal cleanup, use prospects_archive instead, which is reversible.",
      "keywords": [
        "prospect",
        "delete",
        "remove",
        "destroy",
        "permanent"
      ],
      "docs": "https://docs.actuallycare.com/tools/prospects/prospects_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "prospect_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the prospect to delete. Must be archived first. Use prospects_get to verify."
          }
        },
        "required": [
          "prospect_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "referrals_list",
      "category": "referrals",
      "registryCategory": "growth",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search for referrals by name, status, type, or date range. Returns pagination info (total_count, has_more, offset, limit). Results include: id, display_id, referred_name, referred_email, referring_agent_name, receiving_agent_name, referral_type, status, referral_fee_percentage, created_at. Filter by status (submitted/accepted/active/closed/paid/declined/expired), type (buyer/seller/both), or date range. For a specific referral by ID, use referrals_get instead. For aggregate stats, use referrals_stats.",
      "keywords": [
        "referral",
        "referrals",
        "agent",
        "list",
        "search",
        "fee",
        "broker"
      ],
      "docs": "https://docs.actuallycare.com/tools/referrals/referrals_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term - matches against referred_name, referred_email, referring_agent_name, receiving_agent_name (case-insensitive partial match)"
          },
          "status": {
            "type": "string",
            "enum": [
              "all",
              "submitted",
              "accepted",
              "active",
              "closed",
              "paid",
              "declined",
              "expired"
            ],
            "description": "Filter by status. submitted=new, accepted=agreed, active=in progress, closed=transaction closed, paid=fee collected, declined=rejected, expired=timed out (default: all)"
          },
          "referral_type": {
            "type": "string",
            "enum": [
              "all",
              "buyer",
              "seller",
              "both"
            ],
            "description": "Filter by referral type (default: all)"
          },
          "date_from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show referrals submitted on or after this date (Format: YYYY-MM-DD)"
          },
          "date_to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show referrals submitted on or before this date (Format: YYYY-MM-DD)"
          },
          "archived": {
            "type": "boolean",
            "description": "Include archived referrals (default: false)"
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 500,
            "description": "Maximum results (default: 50, max: 500)"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N results for pagination (default: 0)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "referrals_get",
      "category": "referrals",
      "registryCategory": "growth",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of a referral by UUID, including referred person info, referring agent, receiving agent, financial details, and linked escrow. Returns all fields including status history timestamps. If you don't have the UUID, use referrals_list first.",
      "keywords": [
        "referral",
        "detail",
        "get",
        "view",
        "agent"
      ],
      "docs": "https://docs.actuallycare.com/tools/referrals/referrals_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "referral_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the referral. Use referrals_list to find IDs."
          }
        },
        "required": [
          "referral_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "referrals_create",
      "category": "referrals",
      "registryCategory": "growth",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Create a new referral to track an agent-to-agent referral. WORKFLOW: 1) Optionally use leads_list or contacts_list to find the referred person 2) Create the referral with referred person info and receiving agent details. Returns the created referral with ID and display_id. If referral_fee_percentage is not specified, it defaults to your brokerage's configured rate, or 25%.",
      "keywords": [
        "referral",
        "create",
        "new",
        "add",
        "agent",
        "fee",
        "broker"
      ],
      "docs": "https://docs.actuallycare.com/tools/referrals/referrals_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "referred_name": {
            "type": "string",
            "description": "Name of the referred person"
          },
          "referred_email": {
            "type": "string",
            "description": "Email of the referred person"
          },
          "referred_phone": {
            "type": "string",
            "description": "Phone number of the referred person"
          },
          "referred_lead_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of an existing lead being referred. Use leads_list to find."
          },
          "referred_contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of an existing contact being referred. Use contacts_list to find."
          },
          "receiving_agent_name": {
            "type": "string",
            "description": "Name of the agent receiving the referral"
          },
          "receiving_agent_email": {
            "type": "string",
            "description": "Email of the receiving agent"
          },
          "receiving_agent_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the receiving agent if they are on the platform"
          },
          "referring_agent_name": {
            "type": "string",
            "description": "Name of the referring agent (auto-filled from current user if omitted)"
          },
          "referring_agent_email": {
            "type": "string",
            "description": "Email of the referring agent"
          },
          "referral_type": {
            "type": "string",
            "enum": [
              "buyer",
              "seller",
              "both"
            ],
            "description": "Type of referral (default: buyer)"
          },
          "referral_fee_percentage": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Referral fee percentage (default: your brokerage's configured rate, or 25%)"
          },
          "referral_source": {
            "type": "string",
            "description": "How the referral originated (e.g. \"sphere of influence\", \"past client\", \"open house\")"
          },
          "notes": {
            "type": "string",
            "description": "Additional notes about the referral"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "referrals_update",
      "category": "referrals",
      "registryCategory": "growth",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing referral's information or status. Only provided fields are updated - omitted fields remain unchanged. Common uses: status change (submitted->accepted->active->closed->paid), add financial details, link escrow. Returns the updated referral record.",
      "keywords": [
        "referral",
        "update",
        "edit",
        "modify",
        "status",
        "fee"
      ],
      "docs": "https://docs.actuallycare.com/tools/referrals/referrals_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "referral_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the referral to update (required). Use referrals_list to find."
          },
          "referred_name": {
            "type": "string",
            "description": "Updated referred person name"
          },
          "referred_email": {
            "type": "string",
            "description": "Updated referred person email"
          },
          "referred_phone": {
            "type": "string",
            "description": "Updated referred person phone"
          },
          "referred_lead_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated lead ID"
          },
          "referred_contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated contact ID"
          },
          "referring_agent_name": {
            "type": "string",
            "description": "Updated referring agent name"
          },
          "referring_agent_email": {
            "type": "string",
            "description": "Updated referring agent email"
          },
          "receiving_agent_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated receiving agent ID"
          },
          "receiving_agent_name": {
            "type": "string",
            "description": "Updated receiving agent name"
          },
          "receiving_agent_email": {
            "type": "string",
            "description": "Updated receiving agent email"
          },
          "referral_type": {
            "type": "string",
            "enum": [
              "buyer",
              "seller",
              "both"
            ],
            "description": "Updated referral type"
          },
          "referral_source": {
            "type": "string",
            "description": "Updated referral source"
          },
          "notes": {
            "type": "string",
            "description": "Updated notes"
          },
          "status": {
            "type": "string",
            "enum": [
              "submitted",
              "accepted",
              "active",
              "closed",
              "paid",
              "declined",
              "expired"
            ],
            "description": "Updated status"
          },
          "referral_fee_percentage": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Updated fee percentage"
          },
          "transaction_amount": {
            "type": "number",
            "minimum": 0,
            "description": "Transaction amount when closed"
          },
          "referral_fee_amount": {
            "type": "number",
            "minimum": 0,
            "description": "Actual referral fee amount"
          },
          "escrow_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Link to an escrow when the referral leads to a transaction"
          },
          "care_status": {
            "type": "string",
            "enum": [
              "no_status",
              "cared",
              "needs_care",
              "didnt_care"
            ],
            "description": "Care status for tracking"
          }
        },
        "required": [
          "referral_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "referrals_stats",
      "category": "referrals",
      "registryCategory": "growth",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get aggregate statistics for referrals: total count, counts by status, total fees earned, total fees pending. Use this for dashboard metrics. Does NOT return individual records - use referrals_list for that.",
      "keywords": [
        "referral",
        "stats",
        "metrics",
        "dashboard",
        "aggregate",
        "fees"
      ],
      "docs": "https://docs.actuallycare.com/tools/referrals/referrals_stats",
      "inputSchema": {
        "type": "object",
        "properties": {
          "period": {
            "type": "string",
            "enum": [
              "1_day",
              "1_week",
              "1_month",
              "3_months",
              "1_year",
              "ytd",
              "all"
            ],
            "description": "Time period for stats (default: 1_month)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "referrals_archive",
      "category": "referrals",
      "registryCategory": "growth",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive a referral to hide it from active views without deleting it. Archived referrals can be restored later with referrals_restore. Use this for old or inactive referrals you want to declutter from your dashboard. Returns the archived record.",
      "keywords": [
        "referral",
        "archive",
        "hide",
        "declutter"
      ],
      "docs": "https://docs.actuallycare.com/tools/referrals/referrals_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "referral_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the referral to archive. Use referrals_list to find."
          }
        },
        "required": [
          "referral_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "referrals_restore",
      "category": "referrals",
      "registryCategory": "growth",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore a previously archived referral back to active views. Reverses the effect of referrals_archive. Returns the restored record.",
      "keywords": [
        "referral",
        "restore",
        "unarchive",
        "recover"
      ],
      "docs": "https://docs.actuallycare.com/tools/referrals/referrals_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "referral_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the referral to restore. Must be currently archived."
          }
        },
        "required": [
          "referral_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "referrals_delete",
      "category": "referrals",
      "registryCategory": "growth",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete a referral. This is IRREVERSIBLE - the referral will be hidden from all views including archived. The referral must be archived first. For normal cleanup, use referrals_archive instead, which is reversible.",
      "keywords": [
        "referral",
        "delete",
        "remove",
        "destroy",
        "permanent"
      ],
      "docs": "https://docs.actuallycare.com/tools/referrals/referrals_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "referral_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the referral to delete. Must be archived first. Use referrals_get to verify."
          }
        },
        "required": [
          "referral_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "rental_applications_list",
      "category": "rental-applications",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search rental applications by decision, applicant, listing, or free-text query. Returns id, listing_id, applicant_contact_id, decision, submitted_at, reviewed_at. Use decision='pending' or 'reviewing' to find applications needing a decision. Sensitive financial fields (credit_score, monthly_income) are NOT returned in list mode — fetch with rental_applications_get when needed for decision context.",
      "keywords": [
        "rental application",
        "applications",
        "applicant",
        "tenant screening",
        "pending applications"
      ],
      "docs": "https://docs.actuallycare.com/tools/rental-applications/rental_applications_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Free-text search (reserved — use decision/applicant/listing filters for now)"
          },
          "decision": {
            "type": "string",
            "enum": [
              "pending",
              "reviewing",
              "approved",
              "denied",
              "withdrawn"
            ],
            "description": "Filter by decision status. pending=not yet reviewed, reviewing=in progress, approved/denied=decided, withdrawn=applicant pulled out"
          },
          "applicant_contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Filter to applications by a specific applicant"
          },
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Filter to applications for a specific listing"
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 500,
            "description": "Maximum results (default: 25)"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N results for pagination"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "rental_applications_get",
      "category": "rental-applications",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of one rental application by UUID. Returns all application fields including credit_score, monthly_income, employment_status, background_check_status, eviction_history (sensitive — caller must sanitize before AI use). Returns decision, decision_reason, reviewed_at for audit trail.",
      "keywords": [
        "application details",
        "get application",
        "credit score",
        "background check",
        "applicant financials"
      ],
      "docs": "https://docs.actuallycare.com/tools/rental-applications/rental_applications_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "application_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the rental application"
          }
        },
        "required": [
          "application_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "rental_applications_approve",
      "category": "rental-applications",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Mark a rental application as approved. Stamps reviewed_at=NOW. Idempotent — calling on an already-approved application is a no-op. Cannot approve a withdrawn application (will error). Does NOT create a lease — call rental_applications_convert_to_lease for that atomic flow.",
      "keywords": [
        "approve application",
        "approve tenant",
        "application decision"
      ],
      "docs": "https://docs.actuallycare.com/tools/rental-applications/rental_applications_approve",
      "inputSchema": {
        "type": "object",
        "properties": {
          "application_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the application to approve"
          },
          "reason": {
            "type": "string",
            "maxLength": 2000,
            "description": "Optional approval note for audit trail (e.g., \"Strong credit and income verified\")"
          }
        },
        "required": [
          "application_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "rental_applications_convert_to_lease",
      "category": "rental-applications",
      "registryCategory": "core",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Atomically approve (if pending) and create a lease from an approved application. Links the new lease to the application via rental_application_id. The new lease automatically inherits the application's listing and brokerage/team assignment. Cannot convert denied or withdrawn applications. Returns the new lease record. This is the canonical \"I've decided to sign this tenant\" action.",
      "keywords": [
        "sign tenant",
        "convert to lease",
        "execute lease",
        "application to lease"
      ],
      "docs": "https://docs.actuallycare.com/tools/rental-applications/rental_applications_convert_to_lease",
      "inputSchema": {
        "type": "object",
        "properties": {
          "application_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the application to convert"
          },
          "lease_start": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Lease start date (ISO format, YYYY-MM-DD) (Format: YYYY-MM-DD)"
          },
          "lease_end": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Lease end date (ISO format, YYYY-MM-DD) (Format: YYYY-MM-DD)"
          },
          "monthly_rent": {
            "type": "number",
            "minimum": 0,
            "description": "Monthly rent amount"
          },
          "security_deposit": {
            "type": "number",
            "minimum": 0,
            "description": "Security deposit amount"
          },
          "lease_type": {
            "type": "string",
            "enum": [
              "residential",
              "commercial",
              "short_term"
            ],
            "description": "Lease type (default: residential)"
          },
          "landlord_contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the landlord contact"
          },
          "renter_client_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the renter client. If not provided, the agent should create a client with client_type=tenant first via clients_create and link it here."
          },
          "commission_amount": {
            "type": "number",
            "minimum": 0,
            "description": "Agent commission for this lease"
          },
          "notes": {
            "type": "string",
            "maxLength": 10000,
            "description": "Lease notes"
          }
        },
        "required": [
          "application_id",
          "lease_start",
          "lease_end",
          "monthly_rent"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "get_production_report",
      "category": "reporting",
      "registryCategory": "analytics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get a production report showing volume, units closed, and commission earned for a time period. Essential for tracking business performance and setting goals. Returns: total closed volume, units closed, gross commission, average deal size, and comparison to prior period. Use period parameter for standard ranges (ytd, mtd, qtd) or custom for specific date ranges. group_by allows breakdown by month/quarter to see trends. include_pending adds pipeline value for forecasting.",
      "keywords": [
        "production",
        "report",
        "volume",
        "commission",
        "gci",
        "ytd",
        "pipeline"
      ],
      "docs": "https://docs.actuallycare.com/tools/reporting/get_production_report",
      "inputSchema": {
        "type": "object",
        "properties": {
          "period": {
            "type": "string",
            "enum": [
              "ytd",
              "mtd",
              "qtd",
              "last_month",
              "last_quarter",
              "last_year",
              "all_time",
              "custom"
            ],
            "description": "Time period for the report. ytd=year to date (most common), mtd=month to date, qtd=quarter to date, custom=use start_date/end_date. Default: ytd."
          },
          "start_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Start date for custom period. Required when period=\"custom\". (Format: YYYY-MM-DD)"
          },
          "end_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "End date for custom period. Required when period=\"custom\". (Format: YYYY-MM-DD)"
          },
          "include_pending": {
            "type": "boolean",
            "description": "Include pending escrows in pipeline forecast. Default: true. Set false for closed-only report."
          },
          "group_by": {
            "type": "string",
            "enum": [
              "month",
              "quarter",
              "year",
              "none"
            ],
            "description": "Group results by time period for trend analysis. none=single total, month=monthly breakdown. Default: none."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "get_lead_source_roi",
      "category": "reporting",
      "registryCategory": "analytics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get lead conversion data grouped by source. Returns for each source: total leads, converted count, and conversion rate. Sources include: referral, zillow, realtor.com, open_house, sign_call, website, social_media, etc. Note: cost per lead and ROI are not tracked — only conversion rates from existing data.",
      "keywords": [
        "lead source",
        "roi",
        "conversion",
        "channel",
        "attribution"
      ],
      "docs": "https://docs.actuallycare.com/tools/reporting/get_lead_source_roi",
      "inputSchema": {
        "type": "object",
        "properties": {
          "period": {
            "type": "string",
            "enum": [
              "ytd",
              "last_6_months",
              "last_year",
              "all_time"
            ],
            "description": "Time period to analyze. Longer periods give more reliable conversion data. Default: ytd."
          },
          "min_leads": {
            "type": "number",
            "minimum": 1,
            "maximum": 100,
            "description": "Minimum leads to include a source in results. Use 5-10 for meaningful averages. Default: 1."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "get_client_anniversaries",
      "category": "reporting",
      "registryCategory": "analytics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get clients with upcoming home purchase anniversaries for sphere marketing. A proven touchpoint for staying in contact with past clients and generating referrals. Returns: client name, property address, purchase date, anniversary date, years since purchase. Send an anniversary card or call to maintain the relationship. Also useful for triggering annual home value updates or refinance discussions. Results sorted by anniversary date.",
      "keywords": [
        "anniversary",
        "sphere",
        "past clients",
        "touchpoint",
        "referral"
      ],
      "docs": "https://docs.actuallycare.com/tools/reporting/get_client_anniversaries",
      "inputSchema": {
        "type": "object",
        "properties": {
          "days_ahead": {
            "type": "number",
            "minimum": 1,
            "maximum": 90,
            "description": "Look ahead this many days for upcoming anniversaries. Default: 30 days gives time to prepare cards."
          },
          "include_past": {
            "type": "number",
            "minimum": 0,
            "maximum": 30,
            "description": "Include anniversaries from past N days for recently missed ones. Default: 7 days."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "get_hot_leads",
      "category": "reporting",
      "registryCategory": "analytics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get active leads sorted by status priority and recency for prospecting. Returns leads in priority order: qualified first, then contacted, then new — with most recent first within each group. Use this to build a daily call list. Note: this is a simple sort by status and date, not a predictive scoring model.",
      "keywords": [
        "hot leads",
        "prospecting",
        "call list",
        "priority",
        "qualified"
      ],
      "docs": "https://docs.actuallycare.com/tools/reporting/get_hot_leads",
      "inputSchema": {
        "type": "object",
        "properties": {
          "min_score": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Minimum score 0-100 to include. Default: 50. Use 70+ for hot leads only, 0 for all leads ranked."
          },
          "lead_type": {
            "type": "string",
            "enum": [
              "buyer",
              "seller",
              "both",
              "all"
            ],
            "description": "Filter by lead type. buyer=buying clients, seller=listing prospects, both=investor/dual leads, all=no filter. Default: all."
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 100,
            "description": "Maximum results. Default: 10. Your daily call list should be 10-20 leads."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "suggest_next_action",
      "category": "reporting",
      "registryCategory": "analytics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get data-driven suggestions for next steps. Two modes: (1) HOLISTIC — call with NO args to get the top highest-impact next moves across hot leads, closing escrows, and stale clients (use this for prompts like \"what's my next move?\" or \"what should I do next?\"). (2) PER-ENTITY — pass entity_type ('lead' | 'client' | 'escrow') AND entity_id to get suggestions scoped to one specific record. Returns suggestions with priority levels and reasons. These are suggestions for internal planning — the licensed agent must exercise independent professional judgment on all actions.",
      "keywords": [
        "next action",
        "suggestion",
        "priority",
        "follow-up",
        "planning"
      ],
      "docs": "https://docs.actuallycare.com/tools/reporting/suggest_next_action",
      "inputSchema": {
        "type": "object",
        "properties": {
          "entity_type": {
            "type": "string",
            "enum": [
              "lead",
              "client",
              "escrow"
            ],
            "description": "OPTIONAL. Type of entity to analyze. Omit for holistic mode."
          },
          "entity_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "OPTIONAL. UUID of the entity to analyze. Omit for holistic mode. If provided, entity_type is also required."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "match_buyers_to_listings",
      "category": "reporting",
      "registryCategory": "analytics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Find buyer clients whose saved price range overlaps with a listing's price (within 10%). Returns the listing details and a list of potential buyer clients filtered by price criteria. Results are filtered by data, not recommended — the agent should independently evaluate suitability for each buyer.",
      "keywords": [
        "match",
        "buyer",
        "listing",
        "price range",
        "showing"
      ],
      "docs": "https://docs.actuallycare.com/tools/reporting/match_buyers_to_listings",
      "inputSchema": {
        "type": "object",
        "properties": {
          "client_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the buyer client to match. Their saved preferences (budget, beds, baths, areas) are used for matching."
          },
          "min_price": {
            "type": "number",
            "minimum": 0,
            "description": "Override client minimum price. Useful for expanding search if few matches."
          },
          "max_price": {
            "type": "number",
            "minimum": 0,
            "description": "Override client maximum price. Useful for stretching budget for right property."
          },
          "min_beds": {
            "type": "number",
            "minimum": 0,
            "maximum": 10,
            "description": "Minimum bedrooms filter."
          },
          "min_baths": {
            "type": "number",
            "minimum": 0,
            "maximum": 10,
            "description": "Minimum bathrooms filter."
          },
          "property_types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "single_family",
                "condo",
                "townhouse",
                "multi_family",
                "land",
                "commercial"
              ]
            },
            "description": "Property types to search. Default: all types client is interested in."
          },
          "cities": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Cities to search in. Default: cities from client preferences."
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 50,
            "description": "Maximum results. Default: 10. Use 20-30 for comprehensive showing tour."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "predict_close_probability",
      "category": "reporting",
      "registryCategory": "analytics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Estimate close likelihood for an escrow based on simple heuristics: contingency removal status and days to closing date. Returns a rough percentage (not a statistical model) and the factors used. This is an internal planning heuristic only — do not share the percentage with clients or present it as a factual prediction. The agent should apply their own experience and judgment.",
      "keywords": [
        "close probability",
        "escrow",
        "forecast",
        "heuristic"
      ],
      "docs": "https://docs.actuallycare.com/tools/reporting/predict_close_probability",
      "inputSchema": {
        "type": "object",
        "properties": {
          "escrow_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the escrow to analyze. Use escrows_list to find ID."
          }
        },
        "required": [
          "escrow_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "list_clients_pending_review_request",
      "category": "review-requests",
      "registryCategory": "growth",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "List the agent's closed escrows that are eligible for a Google review request but haven't been asked yet. A closing is eligible when it has a recorded close date within the days_since_close window AND no review request has been sent to the same client for that escrow in the last 60 days. Use when the user asks \"who should I ask for a review?\", \"any closings I forgot to follow up on?\", or similar. Returns one entry per pending closing with the data needed to draft a request: escrow_id, client_name, property_address, close_date, days_since_close.",
      "keywords": [
        "review",
        "google",
        "reputation",
        "closed",
        "escrow",
        "pending",
        "follow-up"
      ],
      "docs": "https://docs.actuallycare.com/tools/review-requests/list_clients_pending_review_request",
      "inputSchema": {
        "type": "object",
        "properties": {
          "days_since_close": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "description": "Window of closings to consider, measured from the actual close-of-escrow date (or the scheduled closing date when no actual date is recorded) up to today. Default 7 — matches the typical post-close cooling-off period used by the auto-send scheduler."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "draft_review_request_email",
      "category": "review-requests",
      "registryCategory": "growth",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Generate the personalized subject, plain-text body, HTML body, and Google write-review URL for a review request email tied to a specific closed escrow. Read-only — does NOT send. Use this BEFORE `send_review_request` so the user can preview and edit the draft in chat. The tool also reports `suppressed: true` (with a reason) if the recipient is on the email suppression list — the assistant should surface that to the user instead of proceeding to send. Any reviewer comment fields present in related data are sanitized to strip protected-characteristic and personal information before any AI processing.",
      "keywords": [
        "review",
        "google",
        "draft",
        "email",
        "preview",
        "personalize"
      ],
      "docs": "https://docs.actuallycare.com/tools/review-requests/draft_review_request_email",
      "inputSchema": {
        "type": "object",
        "properties": {
          "escrow_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "Identifier of the closed escrow. NOTE: escrow IDs are text identifiers (e.g. \"ESC-2026-0042\"), not UUIDs. Use list_clients_pending_review_request or escrows_list to discover it."
          },
          "tone": {
            "type": "string",
            "enum": [
              "warm",
              "professional",
              "casual"
            ],
            "description": "Tone variant for the email copy. \"warm\" is the default in the personalization service; choose explicitly if the user asks for a different feel."
          }
        },
        "required": [
          "escrow_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "send_review_request",
      "category": "review-requests",
      "registryCategory": "growth",
      "annotation": "Creates data + external action",
      "readOnly": false,
      "destructive": false,
      "description": "Send a review request email NOW for a specific closed escrow. **REQUIRES EXPLICIT USER CONFIRMATION IN CHAT BEFORE EXECUTION.** The assistant MUST first call `draft_review_request_email` to show the user the proposed subject + body, and MUST receive an unambiguous \"yes, send it\" (or equivalent confirmation) from the user before invoking this tool. This is a write tool that sends a real email. The service enforces the email suppression list, blocks repeat sends to the same client for the same escrow within 60 days, and applies the per-user limit of 50 sends per day — the same safeguards enforced by the REST endpoint. Returns `{ message_id, sent_at, status }` on success or a structured `skipped_*` / `error` outcome that explains why the send did not happen.",
      "keywords": [
        "review",
        "google",
        "send",
        "email",
        "reputation",
        "request"
      ],
      "docs": "https://docs.actuallycare.com/tools/review-requests/send_review_request",
      "inputSchema": {
        "type": "object",
        "properties": {
          "escrow_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "Identifier of the closed escrow. A text identifier (e.g. \"ESC-2026-0042\"), not a UUID."
          },
          "template_variant": {
            "type": "string",
            "enum": [
              "warm",
              "professional",
              "casual"
            ],
            "description": "Tone variant to send. Defaults to the user's saved review-request tone preference (typically \"warm\"). Pick explicitly when the user asked for a specific tone in their confirmation."
          },
          "custom_body": {
            "type": "string",
            "maxLength": 5000,
            "description": "Optional custom body override. The current template does NOT include this text in the sent email — it is recorded on the audit trail only. Pass it when the user dictates exact words, but be aware the recipient still receives the standard template body for now."
          }
        },
        "required": [
          "escrow_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "showings_list",
      "category": "showings",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search for property showings by address, status, type, or date range. Returns pagination info (total_count, has_more, offset, limit). Results include: id, address, showing_date, showing_time, showing_status, showing_type, access_type, listing address/photo, contact name, agent_notes, created_at. Filter by status (pending/confirmed/completed/cancelled/no_show), type (first_showing/follow_up/final_walkthrough/inspection/appraisal), or date range. For a specific showing by ID, use showings_get instead. For aggregate stats, use showings_stats.",
      "keywords": [
        "showing",
        "showings",
        "viewing",
        "walkthrough",
        "buyer tour",
        "property visit"
      ],
      "docs": "https://docs.actuallycare.com/tools/showings/showings_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search term - matches against address (case-insensitive partial match)"
          },
          "status": {
            "type": "string",
            "enum": [
              "all",
              "pending",
              "confirmed",
              "completed",
              "cancelled",
              "no_show"
            ],
            "description": "Filter by status. pending=awaiting confirmation, confirmed=scheduled, completed=done, cancelled=cancelled, no_show=missed (default: all)"
          },
          "showing_type": {
            "type": "string",
            "enum": [
              "all",
              "first_showing",
              "follow_up",
              "final_walkthrough",
              "inspection",
              "appraisal"
            ],
            "description": "Filter by showing type (default: all)"
          },
          "date_from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show showings on or after this date (Format: YYYY-MM-DD)"
          },
          "date_to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Show showings on or before this date (Format: YYYY-MM-DD)"
          },
          "archived": {
            "type": "boolean",
            "description": "Include archived showings (default: false)"
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 500,
            "description": "Maximum results (default: 50, max: 500)"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N results for pagination (default: 0)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "showings_get",
      "category": "showings",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of a showing by UUID, including listing and contact information. Returns address, date/time, status, type, access info, feedback, notes, and joined listing + contact details. If you don't have the UUID, use showings_list first.",
      "keywords": [
        "showing details",
        "get showing",
        "showing feedback",
        "access notes"
      ],
      "docs": "https://docs.actuallycare.com/tools/showings/showings_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "showing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the showing. Use showings_list to find IDs."
          }
        },
        "required": [
          "showing_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "showings_create",
      "category": "showings",
      "registryCategory": "data",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Schedule a new property showing. WORKFLOW: 1) Optionally use listings_list to find the listing 2) Optionally use contacts_list to find the contact 3) Create the showing with address, date, and time. Returns the created showing with ID. Required fields: address, showing_date, showing_time.",
      "keywords": [
        "schedule showing",
        "new showing",
        "book viewing"
      ],
      "docs": "https://docs.actuallycare.com/tools/showings/showings_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "description": "Property address for the showing (required)"
          },
          "showing_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Date of the showing (required) (Format: YYYY-MM-DD)"
          },
          "showing_time": {
            "type": "string",
            "description": "Time of the showing in HH:MM format (required), e.g. \"14:00\""
          },
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the associated listing (optional). Use listings_list to find."
          },
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the associated contact (optional). Use contacts_list to find."
          },
          "appointment_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the associated appointment (optional). Use appointments_list to find."
          },
          "showing_type": {
            "type": "string",
            "enum": [
              "first_showing",
              "follow_up",
              "final_walkthrough",
              "inspection",
              "appraisal"
            ],
            "description": "Type of showing (default: first_showing)"
          },
          "access_type": {
            "type": "string",
            "description": "Access type, e.g. \"lockbox\", \"agent_present\", \"owner_present\""
          },
          "lockbox_code": {
            "type": "string",
            "description": "Lockbox code for property access"
          },
          "access_notes": {
            "type": "string",
            "description": "Notes about property access instructions"
          },
          "showing_status": {
            "type": "string",
            "enum": [
              "pending",
              "confirmed",
              "completed",
              "cancelled",
              "no_show"
            ],
            "description": "Initial status (default: pending)"
          }
        },
        "required": [
          "address",
          "showing_date",
          "showing_time"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "showings_update",
      "category": "showings",
      "registryCategory": "data",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Update an existing showing's information or status. Only provided fields are updated - omitted fields remain unchanged. Common uses: reschedule (update date/time), status change (pending→confirmed→completed), add feedback/notes. Returns the updated showing record.",
      "keywords": [
        "reschedule showing",
        "update showing",
        "showing feedback",
        "confirm showing"
      ],
      "docs": "https://docs.actuallycare.com/tools/showings/showings_update",
      "inputSchema": {
        "type": "object",
        "properties": {
          "showing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the showing to update (required). Use showings_list to find."
          },
          "address": {
            "type": "string",
            "description": "Updated property address"
          },
          "showing_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Updated showing date (Format: YYYY-MM-DD)"
          },
          "showing_time": {
            "type": "string",
            "description": "Updated showing time in HH:MM format"
          },
          "listing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated listing ID"
          },
          "contact_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated contact ID"
          },
          "appointment_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Updated appointment ID"
          },
          "showing_type": {
            "type": "string",
            "enum": [
              "first_showing",
              "follow_up",
              "final_walkthrough",
              "inspection",
              "appraisal"
            ],
            "description": "Updated showing type"
          },
          "access_type": {
            "type": "string",
            "description": "Updated access type"
          },
          "lockbox_code": {
            "type": "string",
            "description": "Updated lockbox code"
          },
          "access_notes": {
            "type": "string",
            "description": "Updated access notes"
          },
          "showing_status": {
            "type": "string",
            "enum": [
              "pending",
              "confirmed",
              "completed",
              "cancelled",
              "no_show"
            ],
            "description": "Updated status"
          },
          "client_interest_level": {
            "type": "number",
            "minimum": 1,
            "maximum": 10,
            "description": "Client interest level (1-10)"
          },
          "agent_notes": {
            "type": "string",
            "description": "Agent notes about the showing"
          },
          "client_feedback": {
            "type": "string",
            "description": "Client feedback about the property"
          },
          "confirmation_number": {
            "type": "string",
            "description": "Showing confirmation number"
          }
        },
        "required": [
          "showing_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "showings_stats",
      "category": "showings",
      "registryCategory": "data",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get aggregate statistics for showings: total count, upcoming count, counts by status, counts by type. Use this for dashboard metrics. Does NOT return individual records - use showings_list for that.",
      "keywords": [
        "showing stats",
        "showings dashboard",
        "showing metrics"
      ],
      "docs": "https://docs.actuallycare.com/tools/showings/showings_stats",
      "inputSchema": {
        "type": "object",
        "properties": {
          "period": {
            "type": "string",
            "enum": [
              "1_day",
              "1_week",
              "1_month",
              "3_months",
              "1_year",
              "ytd",
              "all"
            ],
            "description": "Time period for stats (default: 1_month)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "showings_archive",
      "category": "showings",
      "registryCategory": "data",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Archive a showing to hide it from active views without deleting it. Archived showings can be restored later with showings_restore. Use this for past showings you want to declutter from your dashboard. Returns the archived record.",
      "keywords": [
        "archive showing",
        "hide showing"
      ],
      "docs": "https://docs.actuallycare.com/tools/showings/showings_archive",
      "inputSchema": {
        "type": "object",
        "properties": {
          "showing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the showing to archive. Use showings_list to find."
          }
        },
        "required": [
          "showing_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "showings_restore",
      "category": "showings",
      "registryCategory": "data",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Restore a previously archived showing back to active views. Reverses the effect of showings_archive. Returns the restored record.",
      "keywords": [
        "restore showing",
        "unarchive showing"
      ],
      "docs": "https://docs.actuallycare.com/tools/showings/showings_restore",
      "inputSchema": {
        "type": "object",
        "properties": {
          "showing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the showing to restore. Must be currently archived."
          }
        },
        "required": [
          "showing_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "showings_delete",
      "category": "showings",
      "registryCategory": "data",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Permanently delete a showing. This is IRREVERSIBLE - the showing will be hidden from all views, including archived. The showing must be archived first. For normal cleanup, use showings_archive instead which is reversible.",
      "keywords": [
        "delete showing",
        "remove showing",
        "destructive"
      ],
      "docs": "https://docs.actuallycare.com/tools/showings/showings_delete",
      "inputSchema": {
        "type": "object",
        "properties": {
          "showing_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the showing to delete. Must be archived first. Use showings_get to verify."
          }
        },
        "required": [
          "showing_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "get_dashboard_stats",
      "category": "stats",
      "registryCategory": "analytics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get comprehensive statistics for all CRM entities in one call. Perfect for dashboard displays and health checks. Returns for each entity type: total count, active count, recent additions. Entities covered: contacts (total, new this month), escrows (by status: active/pending/closed/cancelled), clients (total, active, by type), leads (by status: new/contacted/qualified), listings (by status: active/pending/sold), appointments (today count, this week count). Use entity parameter to filter to specific type, or \"all\" for complete overview. This is a read-only aggregation — no individual records returned.",
      "keywords": [
        "dashboard",
        "stats",
        "counts",
        "overview",
        "summary",
        "aggregate"
      ],
      "docs": "https://docs.actuallycare.com/tools/stats/get_dashboard_stats",
      "inputSchema": {
        "type": "object",
        "properties": {
          "entity": {
            "type": "string",
            "enum": [
              "all",
              "contacts",
              "escrows",
              "clients",
              "leads",
              "listings",
              "appointments"
            ],
            "description": "Which entity to get stats for. \"all\" returns stats for every entity type. Default: all."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "get_contact_stats",
      "category": "stats",
      "registryCategory": "analytics",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get detailed statistics specifically for contacts including breakdown by contact type. Returns: total contacts, new contacts this month, counts by type (vendor, attorney, lender, inspector, escrow_officer, title_rep, etc.). Use this for contact directory health checks or to see distribution of your professional network. More detailed than get_dashboard_stats for contacts. For individual contact details, use contacts_list instead.",
      "keywords": [
        "contact",
        "stats",
        "directory",
        "distribution",
        "network",
        "breakdown"
      ],
      "docs": "https://docs.actuallycare.com/tools/stats/get_contact_stats",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "tenancies_list",
      "category": "tenancies",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Search the user's property-managed tenancies. Returns id, lease_id, status (active/vacating/vacant/terminated), rent_current, management_fee_pct, next_inspection_due_at. Use rent_current=false to find delinquent tenancies (or call tenancies_delinquent for a dedicated view). Pagination: total_count + offset + limit.",
      "keywords": [
        "tenancy",
        "tenancies",
        "property management",
        "managed leases",
        "rent collection",
        "pm portfolio"
      ],
      "docs": "https://docs.actuallycare.com/tools/tenancies/tenancies_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Free-text search (reserved)"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "vacating",
              "vacant",
              "terminated"
            ],
            "description": "Filter by tenancy lifecycle status"
          },
          "owner_client_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "Filter to tenancies owned by a specific client (landlord)"
          },
          "rent_current": {
            "type": "boolean",
            "description": "Filter by rent-current flag (false = delinquent)"
          },
          "limit": {
            "type": "number",
            "minimum": 1,
            "maximum": 500,
            "description": "Maximum results (default: 25, max: 500)"
          },
          "offset": {
            "type": "number",
            "minimum": 0,
            "description": "Skip N results for pagination (default: 0)"
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "tenancies_get",
      "category": "tenancies",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details of one tenancy by UUID — includes management fee, rent collection state, inspection cadence, linked lease_id and owner_client_id. Use tenancies_list first if you don't have the UUID. Returns the complete tenancy record.",
      "keywords": [
        "tenancy details",
        "get tenancy",
        "management details"
      ],
      "docs": "https://docs.actuallycare.com/tools/tenancies/tenancies_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tenancy_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the tenancy"
          }
        },
        "required": [
          "tenancy_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "tenancies_create",
      "category": "tenancies",
      "registryCategory": "core",
      "annotation": "Creates data",
      "readOnly": false,
      "destructive": false,
      "description": "Start managing a lease. Requires lease_id (the UUID of an existing lease). Use when taking over management of a signed lease outside the consultation flow — for the common case of converting a signed PM consultation into a tenancy, prefer pm_consultations_convert_to_tenancy, which atomically signs + creates. Defaults management_fee_pct=10.00, rent_collection_day=1, rent_current=TRUE, status='active'. Returns the created tenancy record.",
      "keywords": [
        "new tenancy",
        "start managing lease",
        "onboard lease"
      ],
      "docs": "https://docs.actuallycare.com/tools/tenancies/tenancies_create",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lease_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the lease to start managing (required)"
          },
          "owner_client_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the owner client (landlord) who hired the PM"
          },
          "pm_consultation_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the consultation that led to this tenancy (optional; for audit trail)"
          },
          "management_fee_pct": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Management fee percentage (default 10.00)"
          },
          "rent_collection_day": {
            "type": "number",
            "minimum": 1,
            "maximum": 31,
            "description": "Day of month rent is collected (default 1)"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "vacating",
              "vacant",
              "terminated"
            ],
            "description": "Initial status (default: active)"
          },
          "notes": {
            "type": "string",
            "maxLength": 10000,
            "description": "Free-text notes on the tenancy (operational details, landlord preferences, etc.)"
          }
        },
        "required": [
          "lease_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "tenancies_mark_rent_collected",
      "category": "tenancies",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Stamp rent as collected for a tenancy. Sets last_rent_collected_at (default: today) and flips rent_current to TRUE. Call this after confirming rent receipt (ACH settlement, check cleared, etc.).",
      "keywords": [
        "rent collected",
        "mark paid",
        "rent received",
        "rent current"
      ],
      "docs": "https://docs.actuallycare.com/tools/tenancies/tenancies_mark_rent_collected",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tenancy_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the tenancy"
          },
          "collected_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Date rent was collected (default: today) (Format: YYYY-MM-DD)"
          }
        },
        "required": [
          "tenancy_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "tenancies_record_inspection",
      "category": "tenancies",
      "registryCategory": "core",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Record a property inspection. Stamps last_inspection_at and (optionally) sets the next_inspection_due_at. Inspections are typically on a 6-month cadence for active tenancies.",
      "keywords": [
        "property inspection",
        "record inspection",
        "inspection done",
        "next inspection"
      ],
      "docs": "https://docs.actuallycare.com/tools/tenancies/tenancies_record_inspection",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tenancy_id": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "UUID of the tenancy"
          },
          "inspected_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Date of inspection (default: today) (Format: YYYY-MM-DD)"
          },
          "next_due_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "When the next inspection should occur (optional — typically +6 months) (Format: YYYY-MM-DD)"
          }
        },
        "required": [
          "tenancy_id"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "tenancies_delinquent",
      "category": "tenancies",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "List active and vacating tenancies where rent is currently late (rent_current=FALSE). Ordered by last_rent_collected_at ascending (longest-overdue first) with NULLs first (never-collected). This is the primary tool for the \"who do I need to chase on rent\" question.",
      "keywords": [
        "delinquent rent",
        "late rent",
        "overdue",
        "rent chase",
        "rent not collected"
      ],
      "docs": "https://docs.actuallycare.com/tools/tenancies/tenancies_delinquent",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "tenancies_stats",
      "category": "tenancies",
      "registryCategory": "core",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get aggregate property-management portfolio stats: total tenancies, by_status breakdown, assets_under_management_monthly (sum of monthly_rent from the linked leases of active tenancies — the recurring revenue you're managing), delinquent_count, inspections_due_in_30_days.",
      "keywords": [
        "pm stats",
        "tenancy stats",
        "assets under management",
        "aum",
        "pm dashboard",
        "recurring revenue"
      ],
      "docs": "https://docs.actuallycare.com/tools/tenancies/tenancies_stats",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "lookup_parcel",
      "category": "utility",
      "registryCategory": "integration",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Look up cached parcel/county-tax-assessor data by APN+county or property address. Returns assessed value, annual property tax, county, owner name (sanitized for AI use). Cache-only read — does not trigger a paid vendor lookup. Use BEFORE generating a net sheet to enrich seller proceeds estimates with verified tax basis. Returns null if the property has not been previously cached.",
      "keywords": [
        "parcel",
        "apn",
        "assessor",
        "tax",
        "property tax",
        "assessed value",
        "datatree"
      ],
      "docs": "https://docs.actuallycare.com/tools/utility/lookup_parcel",
      "inputSchema": {
        "type": "object",
        "properties": {
          "apn": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50,
            "description": "Assessor Parcel Number (e.g. \"123-456-789\"). Pair with `county` for the most precise lookup."
          },
          "county": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "County name (e.g. \"Riverside\"). Required when looking up by APN."
          },
          "address": {
            "type": "string",
            "minLength": 5,
            "maxLength": 250,
            "description": "Property address. Used when APN is unknown. Lowercased and whitespace-normalized before lookup."
          },
          "state": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2,
            "description": "2-letter US state code. Defaults to \"CA\" if omitted."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "lookup_address",
      "category": "utility",
      "registryCategory": "integration",
      "annotation": "External lookup",
      "readOnly": true,
      "destructive": false,
      "description": "Look up a property address using Google Places API to get structured, verified address data. IMPORTANT: Use this BEFORE creating escrows or listings to ensure accurate address data. Returns: formatted address, street number, street name, city, state, zip code, county (important for transfer tax calculations), latitude/longitude coordinates (for mapping), and place_id. If the address is ambiguous, returns multiple suggestions — pick the correct one. Common issues: apartment numbers may need manual addition, PO boxes are rejected, new construction may not be found.",
      "keywords": [
        "address",
        "lookup",
        "geocode",
        "google places",
        "verify",
        "county"
      ],
      "docs": "https://docs.actuallycare.com/tools/utility/lookup_address",
      "inputSchema": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "minLength": 5,
            "maxLength": 200,
            "description": "The property address to look up. Be as specific as possible. Examples: \"123 Main St, Bakersfield, CA\", \"456 Oak Ave Unit 12, Los Angeles 90001\". Include city and state for best results."
          }
        },
        "required": [
          "address"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "vertical_schema_get",
      "category": "verticals",
      "registryCategory": "system",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get the metadata schema for a specific vertical and entity type (deal, lead, client, appointment). Returns field definitions with types, labels, validation rules, and select options. Use this to understand what structured metadata fields are available for a vertical before creating or updating deals. Example: get lending deal schema to see loan_type, interest_rate, ltv_ratio fields.",
      "keywords": [
        "vertical",
        "schema",
        "metadata",
        "fields",
        "config"
      ],
      "docs": "https://docs.actuallycare.com/tools/verticals/vertical_schema_get",
      "inputSchema": {
        "type": "object",
        "properties": {
          "vertical_key": {
            "type": "string",
            "description": "Vertical key (e.g., lending, inspection, home_services)"
          },
          "entity_type": {
            "type": "string",
            "enum": [
              "deal",
              "lead",
              "client",
              "appointment"
            ],
            "description": "Entity type to get schema for"
          }
        },
        "required": [
          "vertical_key",
          "entity_type"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "verticals_list",
      "category": "verticals",
      "registryCategory": "system",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "List all industry verticals available in the ActuallyCare platform. Each vertical represents an industry segment (real_estate, lending, inspection, home_services, etc.) with its own pipeline labels. Returns vertical key, label, description, icon, pipeline_labels (entity naming by stage), and role_count. Use this to understand what industries the platform supports and how each pipeline stage is labeled per vertical.",
      "keywords": [
        "vertical",
        "industry",
        "list",
        "real_estate",
        "lending",
        "inspection"
      ],
      "docs": "https://docs.actuallycare.com/tools/verticals/verticals_list",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "roles_list",
      "category": "verticals",
      "registryCategory": "system",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "List all user roles in the platform role registry. Use to understand what a role can do before assigning it, or to enumerate the roles available in a vertical. Each role maps to exactly one vertical and has a scope_level (admin, brokerage, team, standard) that determines its authorization tier. Filterable by vertical key (e.g., \"inspection\" returns 16 roles) or scope_level (e.g., \"brokerage\" returns broker-level roles). Returns role key, vertical_key, vertical_label, label, description, scope_level, and is_loginable. There are roughly 80 active roles across 12 verticals.",
      "keywords": [
        "role",
        "list",
        "rbac",
        "permissions",
        "scope",
        "broker"
      ],
      "docs": "https://docs.actuallycare.com/tools/verticals/roles_list",
      "inputSchema": {
        "type": "object",
        "properties": {
          "vertical": {
            "type": "string",
            "description": "Filter by vertical key (e.g., \"real_estate\", \"inspection\", \"home_services\", \"lending\"). Leave empty for all roles."
          },
          "scope_level": {
            "type": "string",
            "enum": [
              "admin",
              "brokerage",
              "team",
              "standard"
            ],
            "description": "Filter by scope level. \"admin\" = full system access, \"brokerage\" = brokerage-wide, \"team\" = team-wide, \"standard\" = own data."
          }
        },
        "additionalProperties": false
      }
    },
    {
      "name": "role_lookup",
      "category": "verticals",
      "registryCategory": "system",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get full details about a specific user role by its key. Returns the role's vertical mapping, scope level, description, and whether it allows login. Use this to understand what a specific role key means and what vertical/authorization tier it belongs to. Works for both active and legacy (deprecated) roles.",
      "keywords": [
        "role",
        "lookup",
        "rbac",
        "permissions",
        "detail"
      ],
      "docs": "https://docs.actuallycare.com/tools/verticals/role_lookup",
      "inputSchema": {
        "type": "object",
        "properties": {
          "role_key": {
            "type": "string",
            "description": "The role key to look up (e.g., \"broker\", \"plumber\", \"home_inspector\", \"transaction_coordinator\")"
          }
        },
        "required": [
          "role_key"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "website_get",
      "category": "websites",
      "registryCategory": "growth",
      "annotation": "Read-only",
      "readOnly": true,
      "destructive": false,
      "description": "Get the current user's personal website status and settings. Returns: id, templateId, status (draft/published/suspended), subdomain, metaTitle, metaDescription, approvalRequired, approvalStatus, publishedAt, createdAt. Use this to check if the agent has a website and its current state before performing other website operations.",
      "keywords": [
        "website",
        "marketing"
      ],
      "docs": "https://docs.actuallycare.com/tools/websites/website_get",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "website_edit",
      "category": "websites",
      "registryCategory": "growth",
      "annotation": "Creates data + external action",
      "readOnly": false,
      "destructive": false,
      "description": "Edit the agent's personal website using natural language. Describe what you want to change (colors, layout, text, sections) and the AI will update the HTML/CSS in real time. Examples: \"Change the hero background to dark blue\", \"Add a section about my specialties\", \"Make the contact form more prominent\". The edit is applied to the draft — use website_publish to make it live. Guardrails enforce Fair Housing, DRE, and IDX compliance automatically. Returns the updated HTML, diff summary, and any guardrail flags.",
      "keywords": [
        "website",
        "marketing",
        "edit"
      ],
      "docs": "https://docs.actuallycare.com/tools/websites/website_edit",
      "inputSchema": {
        "type": "object",
        "properties": {
          "prompt": {
            "type": "string",
            "description": "Natural language description of the edit to make. Be specific about what to change and how.",
            "maxLength": 2000
          }
        },
        "required": [
          "prompt"
        ],
        "additionalProperties": false
      }
    },
    {
      "name": "website_publish",
      "category": "websites",
      "registryCategory": "growth",
      "annotation": "Updates data",
      "readOnly": false,
      "destructive": false,
      "description": "Publish the current draft of the agent's website to make it live. The website will be accessible at username.actuallycare.com. Only works if there is draft content to publish. If the brokerage requires approval, the website must be approved first before publishing.",
      "keywords": [
        "website",
        "marketing",
        "publish"
      ],
      "docs": "https://docs.actuallycare.com/tools/websites/website_publish",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    {
      "name": "website_revert",
      "category": "websites",
      "registryCategory": "growth",
      "annotation": "Irreversible",
      "readOnly": false,
      "destructive": true,
      "description": "Revert the agent's website draft to the last published version. Use this to undo all draft changes and restore the live version. Only works if there is a published version to revert to.",
      "keywords": [
        "website",
        "marketing",
        "revert"
      ],
      "docs": "https://docs.actuallycare.com/tools/websites/website_revert",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    }
  ]
}
