Install
openclaw skills install @chrischall/rxlocal-mcpRead an RxLocal pharmacy patient portal (patient.rxlocal.com, PioneerRx/RedSail) from a shell: your prescriptions (refills remaining, whether a refill can be requested), refill pickup/delivery options and pharmacy hours, messages with the pharmacy, notifications, the account profile and the age gate, through your signed-in portal tab with the fpx CLI. Read-only: it never requests a refill or sends a message. Use when asked about an RxLocal / PioneerRx pharmacy portal account, prescriptions, refills or pharmacy messages.
openclaw skills install @chrischall/rxlocal-mcpRxLocal Patient (PioneerRx / RedSail Technologies) is a single-page app at
https://patient.rxlocal.com. There is no public API. Its own /api/* backend
is a Keycloak-protected Bearer API: the SPA holds a short-lived access token and
sends it as Authorization: Bearer …, a constant portalid header (the web
portal's public patientPortalID) and, where it has one, an rxlocaluserid
header. So every call here reads the live token from the signed-in tab and sends
the same headers through that tab with fpx. Read-only.
profile, age) and patient-data reads (refills,
refill-options, messages, notifications) all work, as long as the
portalid header is sent. The helper always sends it.portalid header: with the same fresh bearer, leaving it out gives
401 and sending it gives 200 (verified live, read-only, 2026-10-29).session-id cookie. Calls through the tab
(fpx get/post-json) carry it automatically, which is why the helper
uses them. The same bearer and header from plain curl answer 401 unless
that cookie is sent too. Never call PUT auth/session to get a fresh one:
the portal keeps one session per user, and a new one signs the browser out.messages never marks anything read. Read-marking is a separate endpoint the
helper does not call.Keep the signed-in patient.rxlocal.com tab open so the account token stays
fresh. reCAPTCHA v3 guards login only, not the API.
npm install -g @fetchproxy/cli # provides `fpx`
fpx profile add rxlocal --domain rxlocal.com
# declare ALL scopes BEFORE the first pairing (a later declare forces a re-pair):
fpx profile declare rxlocal \
--local-storage kc_authRes \
--capture-header authorization@patient.rxlocal.com \
--capture-header rxlocaluserid@patient.rxlocal.com
Needs ContextMint Bridge in the browser that holds the portal session, with a
patient.rxlocal.com tab open and signed in. The first call prints a pair code
on stderr; approve it in the bridge popup of that browser. If the bridge also
runs in a second browser, every call prints refusing an extension whose identity is not the one this MCP paired with and a fresh pair code — that is the other
browser being turned away, the call still succeeds, and those codes should NOT be
approved. Wrong browser pinned? fpx trust clear fpx-rxlocal, then pair again.
R=~/.claude/skills/rxlocal-fpx/scripts/rxlocal
$R profile # name, email, phone, account type, patient + user IDs
$R age # account-holder age gate
$R patient # demographics for the active patient (shape not re-verified)
$R refills # prescriptions on file: name, Rx number, refills left, canRequestRefill
$R refill-options [DEI] # pickup/delivery/mail, pickup times, calendar, pharmacy hours, disclaimers
$R messages # recent messages with the pharmacy, newest first (does not mark read)
$R notifications # most-relevant notification banner
$R raw GET <path> # any /api GET, unprojected
$R raw POST <path> '<json>' # read POSTs only (Messaging/SyncPatientMessages, Messaging/EmployeeInfo)
<path> is everything after /api/ (e.g. account/getuserinfo). stdout is
JSON ready for jq; stderr carries pair codes and status.
0 ok · 2 bridge down (open/reload the signed-in tab) · 3 bot wall ·
4 upstream HTTP error (often a 401 — the 5-minute token aged; reload the tab).
When the rxlocal-mcp server is hosted on mcp-host, its tools join the
health group (_meta.mint.domain: "health"). The group's canonical reads,
each answered with view: "brief" (one line per item,
title — <ISO date | no date> — <status>, ≤ 120 chars, inside the
untrusted-data envelope's data because drug and sender names are
pharmacy-written; a line starting -- is a note — -- none when empty,
-- N of M shown when limit cut the messages short):
rxlocal_list_prescriptions (the drug, the day the last
fill runs out — fill date + days supply — and its refill status: can request
a refill, needs a prescriber renewal, no refills left, …; soonest first).rxlocal_list_messages (pharmacy messages, newest first:
the sender, the day, and whether it came from the pharmacy or from you; the
pharmacy-written body is never in a brief line).Nothing here answers what's on, and neither read takes a subject or a
range: one signed-in account holder, nothing to fan out over. A compound ask —
"anything due at the pharmacy, and any new messages from my doctors?" — is one
whats-due call plus one whats-new call, merged with the other health-group
sources. The server reads the portal through the signed-in tab over the
ContextMint Bridge; with no signed-in patient.rxlocal.com tab open, the group
answers that RxLocal needs your browser open rather than reading nothing.
raw POST is limited to the read
endpoints. The portal can send messages and request refills; this skill does
not. The rxlocal-mcp server does both, behind a confirm gate.references/endpoints.md. jq recipes:
references/recipes.md.