Skip to content

WiseMatch MCP

Search WiseMatch providers from an AI agent using the Model Context Protocol.

Updated View as Markdown
For humans

WiseMatch exposes a Model Context Protocol (MCP) server so an AI agent on your platform can search WiseMatch providers as a tool call. The search_providers tool finds providers that match a patient’s state, insurance, care type, and preferences, and returns ranked provider records with availability summaries.

The intended workflow: the agent searches for a provider and a slot that fit the patient, then booking happens in the WiseMatch UI — every slot in the results carries a bookingUrl that opens WiseMatch with that provider and slot preselected. From there the booking is completed directly, either by the agent driving a browser or by handing the link to a human.

Endpoint

https://pluto.wisematch.com/mcp

The MCP endpoint is at /mcp on the API host, not under /api/v1.

Transport

The server speaks JSON-RPC 2.0 over stateless Streamable HTTP.

  • Send every message as an HTTP POST to the MCP endpoint.

  • Set both headers on every request:

    Content-Type: application/json
    Accept: application/json, text/event-stream
  • The server is stateless. It does not issue or require an Mcp-Session-Id, so you can call tools/list or tools/call directly, without an initialize handshake first. Clients that send initialize still work.

Any MCP client that supports the Streamable HTTP transport can connect. Point it at the endpoint URL above.

search_providers

Only state and timezone are required, and insurance is highly recommended for an accurate match. Everything else narrows or re-ranks the results. For anything the structured filters don’t capture — “a warm therapist who works with new parents” — put it in freeText, which refines the ranking semantically.

curl -X POST https://pluto.wisematch.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "search_providers",
      "arguments": {
        "state": "CA",
        "timezone": "America/Los_Angeles",
        "insurance": "aetna",
        "careType": "THERAPY",
        "clinicalNeeds": [{ "id": "ANXIETY", "required": true }],
        "genderPreferences": ["FEMALE"],
        "daysOfWeek": ["MON", "TUE"],
        "hourRanges": [{ "startHour": 8, "endHour": 12 }],
        "pagination": { "pageSize": 5 }
      }
    }
  }'

Arguments

Field Type Required Description
state enum Yes Two-letter US state the patient will receive care in.
timezone enum Yes IANA zone used to interpret hourRanges and the weekly availability windows: America/New_York, America/Chicago, America/Denver, or America/Los_Angeles.
insurance enum No Highly recommended for an accurate match. Canonical payor code (e.g. aetna) — the same insurancePayer codes returned by GET /insurance-payers.
careType enum No THERAPY (default) or MED_MANAGEMENT.
therapyType enum No COUPLES. INDIVIDUAL is accepted but treated as no filter — every provider offers individual therapy. The field is also ignored for MED_MANAGEMENT, and COUPLES is ignored when patientPopulations includes a minor band; stale combinations are dropped rather than rejected.
patientPopulations array<enum> No Age groups the provider must see: CHILDREN, PRETEENS, TEENAGERS, ADULTS, SENIORS — the same age bands as the roster’s specialty patient populations, uppercase. Empty means the default adult pool.
clinicalNeeds array<filter> No What the patient needs help with, e.g. ANXIETY, DEPRESSION, TRAUMA. Filter objects.
modalities array<filter> No Treatment approaches, e.g. CBT, EMDR, DBT. Filter objects.
genderPreferences array<enum> No MALE, FEMALE, NO_PREFERENCE.
languages array<filter> No Languages the provider speaks, as full words — ENGLISH, SPANISH, MANDARIN_CHINESE. Filter objects.
siteOfCare enum No VIRTUAL or IN_PERSON.
daysOfWeek array<enum> No Only count availability on these days: MON, TUE, WED, THU, FRI, SAT, SUN.
hourRanges array<object> No Preferred time-of-day windows in timezone, e.g. { "startHour": 8, "endHour": 12 }. startHour is 0–23; endHour is a half-open bound from 1–24 (24 means end of day) and must be greater than startHour.
pagination object No { "pageSize": ..., "pageToken": ... }. pageSize is 1–100, default 20. To fetch the next page, pass the previous result’s nextPageToken as pageToken.
freeText string No Semantic free-text query used for ranking, e.g. a sentence describing what the patient is looking for.

Filter objects

clinicalNeeds, modalities, and languages each take a list of { "id": <code>, "required": <bool> } objects. required defaults to false:

  • "required": true — hard filter; providers without the attribute are excluded.
  • "required": false — preference; matching providers rank higher but non-matching ones still appear.

When you send exactly one clinical need or exactly one language, it is treated as required — a lone filter has nothing to be preferred over.

Example response

The result arrives as JSON text in the tool result’s content; parsed, it’s a results array of ranked providers plus a pagination object:

{
  "results": [
    {
      "providerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "displayName": "Jane Sample, LMFT",
      "states": ["CA"],
      "languages": ["ENGLISH", "SPANISH"],
      "specialties": [{ "id": "ANXIETY", "label": "Anxiety" }],
      "modalities": ["CBT", "EMDR"],
      "siteOfCare": ["VIRTUAL"],
      "genders": ["FEMALE"],
      "insurances": ["aetna", "cigna"],
      "availabilitySummary": {
        "nextSlotAt": "2026-10-05T16:00:00Z",
        "slotCount": 12,
        "slotsThisWeek": 4,
        "matchesPreferredWindow": true,
        "weeklySlots": [
          {
            "weekStart": "2026-10-02",
            "weekEnd": "2026-10-08",
            "slots": [
              {
                "startTime": "2026-10-05T16:00:00Z",
                "mode": "VIRTUAL",
                "bookingUrl": "https://app.wisematch.com/wisematch/start?pid=3fa85f64-5717-4562-b3fc-2c963f66afa6&i=2026-10-05T16%3A00%3A00Z&mode=VIRTUAL",
                "matchesFilter": true
              }
            ]
          }
        ]
      },
      "matchScore": 0.92
    }
  ],
  "pagination": { "pageSize": 5, "nextPageToken": "5" }
}

The parts that matter most:

  • Results are ranked — matchScore runs 0.0 to 1.0 and the first result is the best match.
  • providerId is the same identifier used by /slots and /appointments.
  • insurances carries payor codes; map them to display names with GET /insurance-payers. states uses the usual US state codes.
  • To page through results, pass pagination.nextPageToken back as pagination.pageToken on the next call; it’s null on the last page.

Availability summary

availabilitySummary is where to look for whether the patient can actually get in:

  • nextSlotAt — the next open slot; null when there are none.
  • slotCount and slotsThisWeek — total upcoming slots, and slots in the rolling 7-day window starting today (request timezone).
  • matchesPreferredWindow — true when the provider has slots inside the requested daysOfWeek / hourRanges.
  • weeklySlots — the individual slots, grouped into rolling 7-day windows (weekStart / weekEnd in YYYY-MM-DD, request timezone). Each slot carries startTime (ISO 8601 UTC), mode (VIRTUAL / IN_PERSON), bookingUrl, and matchesFilter (true when it falls inside the requested time windows).
Navigation

Type to search…

↑↓ navigate↵ selectEsc close