MCP/Tool reference

Tool reference

Every tool the NursePal MCP server exposes — parameters, return shape, and a worked example. Six tools live today; the surface expands as new Stat capabilities ship.

Endpoint
https://nursepal.com/mcp/
Transport
Streamable HTTP
Auth
Bearer token (Max plan)

Authentication

The MCP server requires an active Max-plan Stat subscription and a bearer token on every request. Mint a token at /stat/settings/api-keys and pass it as a header in your client config:

Authorization: Bearer npmcp_YOUR_KEY_HERE

Unauth requests return 401 missing_bearer. Lower-tier subscribers get 403 plan_required. Want to try the tools without a key? Use the public sandbox — five free calls per email, no auth required.

get_bill_rate_percentileLive

Returns where the proposed rate falls in the recent distribution (percentile rank), the p25/p50/p75/p90 breakdown, and a fill-probability estimate with expected days-to-fill.

Parameters

NameTypeRequiredDescription
specialtystringrequiredJob specialty. Common forms all resolve to the same canonical specialty: "RN - ICU", "ICU", "ICU Registered Nurse", "Critical Care RN" — fuzzy-matched server-side.
example: RN - ICU
bill_ratenumberrequiredHourly bill rate in USD to evaluate against the market. Pass 0 if you only want the percentile breakdown.
example: 90
statestringoptional2-letter US state code. Strongly recommended — without it, the tool returns a slower national comparison.
example: PA
citystringoptionalCity name. Pairs with `state`; combined into a radius-based search.
example: Pittsburgh
lookback_weeksintegeroptionalWeeks of postings to include. Default 4, max 12. Use 4 for "right now" snapshots; 12 for smoother markets.
example: 4

Returns

FieldTypeDescription
percentile_ranknumberWhere the proposed rate falls in the market distribution (0–100).
market_ratenumberMarket median (p50) in USD/hr.
min_ratenumberFloor (p25 or observed min) in USD/hr.
max_ratenumberCeiling (p90 or observed max) in USD/hr.
fill_probabilityintegerEstimated fill probability at the proposed rate (0–100).
fill_speedstring"very_fast" | "fast" | "moderate" | "slow" | "very_slow".
expected_fill_days_minintegerLower bound on days to fill.
expected_fill_days_maxintegerUpper bound on days to fill.
rate_vs_market_percentnumberSigned % delta vs market median (+ = above, − = below).
recommendationstringOne-sentence plain-English interpretation.
location_scopestring"radius" (city+state) | "state" | "national".
job_countintegerSample size in the comparison window.

Example transcript

Claude Desktop
You:    Is $90/hr competitive for ICU travel nurses in Pittsburgh?

Claude: Let me check the live market.
        → get_bill_rate_percentile(
            specialty: "RN - ICU",
            bill_rate: 90,
            state: "PA",
            city: "Pittsburgh"
          )

        $90/hr lands at the 38th percentile of recent ICU postings
        within ~50 miles of Pittsburgh — about 6.5% below the
        market median of $96.25/hr. Fill probability is ~54%, with
        an expected window of 7-14 days. Bumping to ~$96/hr would
        put you at median and meaningfully shorten the fill time.

Example response (JSON)

application/json
{
  "specialty": "RN - ICU",
  "state": "PA",
  "city": "Pittsburgh",
  "location_scope": "radius",
  "radius_miles": 50,
  "market_rate": 96.25,
  "min_rate": 84.0,
  "max_rate": 112.5,
  "percentile_rank": 38,
  "rate_vs_market_percent": -6.5,
  "fill_probability": 54,
  "fill_speed": "moderate",
  "expected_fill_days_min": 7,
  "expected_fill_days_max": 14,
  "recommendation": "Slightly below market — expect a moderate fill window. Bumping to ~$96/hr would land you at the median.",
  "job_count": 142
}
Note

When no market data is found for the requested specialty/location, the tool returns `{ "error": "No market data found...", "specialty": "...", "state": "...", "city": "...", "hint": "Try broadening the search..." }`.

get_market_demandLive

Returns month-over-month change in posting count (capped at ±20% — outliers above that are scrape noise), a 12-week shape for a sparkline, the top hiring health systems in the window, and a coarse trend label.

Parameters

NameTypeRequiredDescription
specialtystringrequiredJob specialty (e.g. "RN - ICU", "Med Surg"). Fuzzy-matched server-side.
example: RN - ICU
statestringrequired2-letter US state code. Required — momentum needs a defined market window.
example: TX
citystringoptionalOptional city name. Without it, the answer is statewide.
example: Houston
professionstringoptional"Nursing" | "Allied" | "Locum/Tenens". Useful when a specialty name appears in multiple professions.
example: Nursing

Returns

FieldTypeDescription
mom_change_pctnumberMonth-over-month posting-count change, capped at ±20% server-side.
cappedstring | null"up" | "down" | null. When set, MoM hit the cap — phrase as "more than 20%", not a precise number.
trend_labelstring"accelerating" | "rising" | "steady" | "softening" | "contracting" | "low_signal".
top_hiring_systemsarrayTop 5 health systems in the window. Each row: { name, hospital_count }.
weekly_shapearray<int>12-week posting-count series for a sparkline. Chart-only — do not surface numbers verbatim.
low_signalbooleanTrue when the prior 4-week bucket had < 20 deduped postings; treat MoM as directional only.
state / specialty / city / professionstringEchoed back from the request.

Example transcript

Claude Desktop
You:    Is ICU travel demand up or down in Texas this month?

Claude: → get_market_demand(specialty: "RN - ICU", state: "TX")

        ICU travel demand in Texas is rising — postings are up
        ~13% month-over-month, building on a steady 12-week base.
        The top hiring health systems right now are HCA Houston,
        Methodist, and Memorial Hermann.

Example response (JSON)

application/json
{
  "state": "TX",
  "specialty": "RN - ICU",
  "city": null,
  "profession": null,
  "mom_change_pct": 12.5,
  "capped": null,
  "trend_label": "rising",
  "top_hiring_systems": [
    { "name": "HCA Houston", "hospital_count": 7 },
    { "name": "Methodist", "hospital_count": 5 },
    { "name": "Memorial Hermann", "hospital_count": 4 }
  ],
  "weekly_shape": [5, 8, 7, 6, 12, 10, 8, 9, 11, 14, 13, 15],
  "low_signal": false
}
get_msp_attributionLive

Returns the agencies (parent_org rollup) covering the most hospitals in a state or city, with each agency's share of attributed hospitals and a minimum-confidence score from the derivation pipeline.

Parameters

NameTypeRequiredDescription
statestringrequired2-letter US state code.
example: OH
top_nintegeroptionalNumber of agencies to return. Default 5, range 1–25.
example: 5
citystringoptionalOptional city name — narrows the footprint to a single city.
example: Cleveland
focus_parent_orgstringoptionalOptional agency name. When provided, the response includes a `focus` field with the queried org's rank, hospital count, and share — even if outside the top_n.
example: Aya Healthcare

Returns

FieldTypeDescription
mspsarrayTop-N agencies. Each row: { parent_org, systems, hospitals, share_of_footprint (0–1), min_confidence (0–1) }.
total_hospitalsintegerAll hospitals in the scope (state or city).
attributed_hospitalsintegerHospitals with a derived or confirmed msp_parent_org.
top_n_coveragenumberCombined market share (0–1) of the top-N agencies.
scopestring"city" | "state".
focusobject | nullPresent only when `focus_parent_org` was supplied. Includes rank, out_of, hospitals, share, and a no_match flag if the org wasn't found.
no_databoolean | nullSet when there is no MSP coverage at the requested scope.

Example transcript

Claude Desktop
You:    Which Agency/VMS has the most market share in Ohio?

Claude: → get_msp_attribution(state: "OH", top_n: 5)

        Based on publicly observed job postings and reporting, Aya
        Healthcare appears to be the largest staffing footprint in
        Ohio — covering ~20% of attributed hospitals (28 of 98),
        followed by AMN and Cross Country. Verify directly with
        each system.

Example response (JSON)

application/json
{
  "state": "OH",
  "scope": "state",
  "total_hospitals": 142,
  "attributed_hospitals": 98,
  "top_n_coverage": 0.42,
  "msps": [
    { "parent_org": "Aya Healthcare", "systems": 2, "hospitals": 28, "share_of_footprint": 0.205, "min_confidence": 0.95 },
    { "parent_org": "AMN", "systems": 3, "hospitals": 14, "share_of_footprint": 0.143, "min_confidence": 0.88 }
  ]
}
Note

When `msp_source` (a sibling field on derived rows) is "derived" — the common case — hedge the framing ("appear to be coming from X and Y"). Reserve a confident assertion ("the MSP is X") for `msp_source` = "manual".

generate_rate_cardLive

Returns p50 / p65 / p90 weekly pay and bill rates for each requested specialty in a state or city. Each row cascades 20mi → 50mi → state and accepts the smallest scope with enough data; the `scope` field tells you which one was used.

Parameters

NameTypeRequiredDescription
specialtiesarray<string>required1–50 specialty names. Order is preserved in the response rows. In the sandbox: enter as a comma-separated list.
example: RN - ICU, RN - ER, RN - L&D, RN - Med Surg
statestringrequired2-letter US state code.
example: TX
citystringoptionalOptional city name. Auto-geocoded when the hospitals table has a matching city; falls back to state scope otherwise.
example: Houston
lookback_weeksintegeroptionalWeeks of postings to include. Default 16, range 1–26.
example: 16

Returns

FieldTypeDescription
rowsarrayOne row per requested specialty (input order). See per-row fields below.
rows[].specialtystringSpecialty name (echoed).
rows[].jobCountintegerPosting count in the lookback window after IQR dedup.
rows[].scopestring | null"radius_20" | "radius_50" | "state". Smallest scope that hit the data-quality bar.
rows[].lowVariancebooleanTrue when IQR filtering removed >30% of the raw sample (treat row as directional).
rows[].weeklyobject{ p50, p65, p90 } weekly pay in USD. P65 is the recommended-rate anchor.
rows[].billRateobject{ p50, p65, p90 } bill rate in USD/hr.
state / city / lookbackWeeksstring / intEchoed from the request.

Example transcript

Claude Desktop
You:    Build me a 4-specialty rate card for Houston.

Claude: → generate_rate_card(
            specialties: ["RN - ICU", "RN - ER", "RN - L&D", "RN - Med Surg"],
            state: "TX",
            city: "Houston"
          )

        Houston rate card (recommended P65, 16-week window):
          ICU      ~$3,200/wk  ($98/hr bill)
          ER       ~$3,050/wk  ($94/hr bill)
          L&D      ~$3,150/wk  ($96/hr bill)
          Med Surg ~$2,700/wk  ($83/hr bill)
        All four rows hit the 20-mile radius — good local data.

Example response (JSON)

application/json
{
  "state": "TX",
  "city": "Houston",
  "lookbackWeeks": 16,
  "rows": [
    {
      "specialty": "RN - ICU",
      "jobCount": 152,
      "scope": "radius_20",
      "lowVariance": false,
      "weekly": { "p50": 2800.0, "p65": 3200.0, "p90": 3850.0 },
      "billRate": { "p50": 85.50, "p65": 98.00, "p90": 115.25 }
    }
  ]
}
Note

Anchor recommendations to P65, not P50. P50 means competitive with half the market; P65 means materially attractive to candidates.

get_system_rate_cardLive

Resolves a free-form health system name, pools competitor postings across every hospital in the system, and returns one row per qualifying specialty with the system's median bill rate alongside the market's recommended (P65) and premium (P85) tiers. Each row includes a signed % delta. **Max-plan only** — requires a `Bearer npmcp_…` API key.

Parameters

NameTypeRequiredDescription
system_namestringrequiredHealth system name. Fuzzy-matched against `health_systems.name` (canonical) and `hospitals.system` (legacy fallback). Examples: "Catholic Health", "CHS Buffalo", "HCA Houston", "Cleveland Clinic".
example: Catholic Health
lookback_monthsintegeroptionalWindow for the system's own postings. Default 6, range 1–24.
example: 6

Returns

FieldTypeDescription
system_namestringCanonical name of the resolved system (may differ from `system_name` input).
system_idintegerhealth_systems.id. 0 when resolved via the legacy `hospitals.system` column.
hospital_countintegerNumber of hospitals pooled in the system.
primary_statestring | nullModal state across the system's hospitals. Used to anchor the market percentile lookup.
lookback_monthsintegerWindow used for the system's postings.
market_anchorstringAlways "estimated observed median, public postings" — framing for the LLM.
specialtiesarrayOne row per qualifying specialty (≥3 postings). See per-row fields below.
specialties[].specialtystringSpecialty name as observed in postings.
specialties[].system_bill_ratenumberSystem's median bill rate (USD/hr) for this specialty.
specialties[].market_recommendationnumber | nullMarket P65 (the sweet spot) for the primary state.
specialties[].market_premiumnumber | nullMarket P85 (top-quartile) for the primary state.
specialties[].delta_vs_market_pctnumber | nullSigned % delta: system_bill_rate vs market_recommendation. +X% = paying above recommended.
specialties[].posting_countintegerPostings in the lookback window for this specialty.

Example transcript

Claude Desktop
You:    What\'s Catholic Health paying for ICU travel?

Claude: → get_system_rate_card(system_name: "Catholic Health")

        Catholic Health is paying ~$92/hr for ICU travel across 4
        Buffalo hospitals — about 5% below the NY market
        recommendation of $97/hr. Their premium tier (P85) for the
        market is ~$112/hr, so they\'re competitive but not
        chasing the top of the market.

Example response (JSON)

application/json
{
  "system_name": "Catholic Health",
  "system_id": 656,
  "hospital_count": 4,
  "primary_state": "NY",
  "lookback_months": 6,
  "market_anchor": "estimated observed median, public postings",
  "specialties": [
    {
      "specialty": "RN - ICU",
      "system_bill_rate": 92.0,
      "market_recommendation": 97.0,
      "market_premium": 112.5,
      "delta_vs_market_pct": -5.2,
      "posting_count": 17
    }
  ]
}
Note

Requires `Authorization: Bearer npmcp_…` header (Max plan). Non-max requests return 403; missing-key returns 401.

get_parent_org_rankingLive

Ranks parent_orgs by median bill rate for the requested state, profession, and (optional) specialty. Returns the N cheapest, the N priciest, and each org's in-state hospital + city coverage plus adjacent-state coverage — useful when in-state data is thin.

Parameters

NameTypeRequiredDescription
statestringrequired2-letter US state code.
example: SD
professionstringrequired"Nursing" | "Allied" | "Locum/Tenens".
example: Nursing
specialtystringoptionalOptional specialty drill-down. Nursing buckets: "ICU", "PCU", "ER", "Operating Room". Allied buckets: "CT Tech", "MRI Tech", "X-Ray Tech", "Respiratory Therapist", "Surgical Tech", "CVOR Tech". Omit for the profession-level rollup.
example: ICU
limitintegeroptionalN per side (cheapest AND priciest). Default 5, range 1–25.
example: 5

Returns

FieldTypeDescription
state_median_bill_ratenumber | nullReference median across all parent_orgs in the bucket.
lowestarrayTop-N cheapest agencies. Sorted ASC by median bill rate.
highestarrayTop-N priciest agencies. Sorted DESC by median bill rate.
best_valuearrayAgencies closest to the state median across their specialty mix.
rows[].parent_orgstringMSP / staffing agency name.
rows[].median_bill_ratenumberMedian bill rate (or posting-weighted avg in `best_value`).
rows[].posting_countintegerPostings in the bucket over the prior 12 weeks.
rows[].own_stateobject{ hospitals, cities } in the queried state.
rows[].adjacentobject{ hospitals, cities, states[] } in contiguous neighbor states.
rows[].hospitalsarrayTop 10 in-state hospitals by posting count: { hospital_id, name, city, postings }.
state / profession / specialtystringEchoed from the request.

Example transcript

Claude Desktop
You:    Who's the cheapest ICU agency in South Dakota?

Claude: → get_parent_org_ranking(
            state: "SD",
            profession: "Nursing",
            specialty: "ICU"
          )

        Cheapest ICU parent orgs in SD by median bill rate (prior
        12 weeks): "Local Staff Only" at ~$48.50/hr across 4
        Rapid City hospitals, then [Agency B] at $50.10/hr. The
        state median for ICU sits at $52.75/hr, so the cheapest
        tier is running ~8% below the broader market.

Example response (JSON)

application/json
{
  "state": "SD",
  "profession": "Nursing",
  "specialty": "ICU",
  "state_median_bill_rate": 52.75,
  "lowest": [
    {
      "parent_org": "Local Staff Only",
      "median_bill_rate": 48.50,
      "posting_count": 23,
      "own_state": { "hospitals": 4, "cities": 2 },
      "adjacent": { "hospitals": 1, "cities": 1, "states": ["NE", "WY"] },
      "hospitals": [
        { "hospital_id": 101, "name": "Rapid City Regional", "city": "Rapid City", "postings": 5 }
      ]
    }
  ],
  "highest": [/* same row shape, DESC by median */],
  "best_value": [/* rows include specialties_covered + distance_to_median */]
}