Skip to main content
Glama
README.md
# medprice

medprice is a small local bridge to FineRx's hosted MCP
server, a prescription-price service for the US: it knows
what a medicine costs with a free discount card at the
major pharmacy chains, which stores sit near a ZIP code,
and what a medicine sold under a foreign brand name is
called in the US.

The bridge keeps no drug or price data of its own. It
serves the upstream server's tool list locally, exactly
as captured from the live endpoint, and forwards each
tool call upstream, returning the result untouched.

## Labelled subset: 18 of 19 tools

The live capture held 19 tools. This rebuild serves 18
of them. One tool is deliberately omitted:

- `email_savings_card` — **omitted**. It sends email to
  an arbitrary address supplied by the caller, an
  external-sending action outside this server's
  price-read core, so it is excluded under the program's
  safety rule. It is not registered, not forwarded, and
  the test suite asserts its absence from both the local
  registry and the served MCP tools/list.

One nearby tool is kept on purpose:

- `get_savings_card` — **kept**. It returns the FineRx
  program's own free discount card: the shared program
  codes printed on every card the service distributes
  publicly, with usage steps. That is published program
  data, not a user's payment-card data, and it creates
  no payment instrument — a read like the price reads
  around it.

## Tools

- `compare_prices` — one medicine's card price at US
  pharmacy chains, near a place. Optional: `drug`,
  `strength`, `form`, `quantity`, `zip`, `ndc`, `locale`,
  `channel`, `compare_to`.
- `ui_prices` — the same price answer for a package and
  place picked inside the FineRx card. Required: `slug`.
- `find_nearby_pharmacies` — pharmacy stores within
  30 miles, per chain, with the card price when a drug
  is given. All arguments optional.
- `ui_nearby` — nearby pharmacies for the package on
  screen, called by the card itself. All optional.
- `get_transfer_steps` — how to move a prescription to
  another chain. All arguments optional.
- `compare_basket` — card prices for several medicines
  at once, and which chain was seen pricing the whole
  list. Required: `drugs`.
- `ui_basket` — the same basket for another place,
  called by the card itself. Required: `slugs`.
- `open_price_finder` — open the FineRx search inside
  the card. Optional: `query`, `locale`.
- `ui_suggest` — medicines matching what is being typed
  in the FineRx search. Required: `q`.
- `get_savings_card` — the free FineRx discount card:
  its codes, how to use it, how to keep it. See the
  subset note above. All arguments optional.
- `search_drugs` — find a medicine by name (brand,
  generic, misspelled or in another script) and get its
  slug. Required: `query`.
- `get_drug` — strengths, forms and pack sizes of one
  medicine that have a card price. Required: `slug`.
- `get_dataset_info` — what FineRx covers: chains,
  freshness, store counts, terms. No arguments.
- `get_prescription_options` — routes to filling a
  prescription, including having none yet. All optional.
- `find_us_equivalent` — what a medicine from another
  country is in the US, and its card price here.
  Required: `brand`.
- `find_us_equivalents` — the same for several foreign
  medicines at once. Required: `brands`.
- `ui_equivalent` — one foreign brand picked in the
  FineRx search, called by the card itself. Required:
  `brand_slug`.
- `foreign_brands_for_drug` — what a US drug is called
  abroad. Required: `slug`.

## Configuration

- `FINERX_MCP_URL` (optional) — override the upstream
  endpoint. Defaults to `https://www.finerxfinder.com/mcp`.
  (The override hook is this rebuild's own labelled
  reconstruction.)
- `FINERX_API_KEY` (optional) — when set, every
  upstream request carries an
  `Authorization: Bearer <key>` header. When it is not
  set, no auth header is sent. (This forwarding is also
  a labelled reconstruction; the original surface was
  captured keyless.)

### Forwarding mechanics

On the first tool call the client opens a streamable
HTTP session with the upstream: a JSON-RPC `initialize`
request (protocolVersion `2025-03-26`, clientInfo name
`medprice`), then a `notifications/initialized`
notification, then the `tools/call` request carrying
the caller's arguments unchanged. When the upstream
answers `initialize` with an `Mcp-Session-Id` header,
that value rides on every later request of the session,
which is reused for the life of the process. Replies
may arrive as plain JSON or as server-sent events;
both are read.

Successful upstream results pass through verbatim,
including any `isError` flag the upstream sets.
Failures — a JSON-RPC error, a non-2xx status, an
unreadable response, or a request that cannot be
completed — come back as an `isError` result whose
text starts with `medprice error:` (this rendering
is this rebuild's own labelled reconstruction).

## CLI

Each tool is also a subcommand taking one JSON argument
string (omit it for tools that take none):

```bash
npx @reneturcios/medprice search_drugs '{"query":"lisinopril"}'
npx @reneturcios/medprice compare_prices '{"drug":"lisinopril","zip":"94110"}'
npx @reneturcios/medprice compare_basket '{"drugs":["lisinopril","metformin"]}'
npx @reneturcios/medprice find_us_equivalent '{"brand":"No-Spa"}'
npx @reneturcios/medprice get_dataset_info
npx @reneturcios/medprice --version
```

Exit codes: `0` on success, `1` on an `isError`
result, `2` on a usage error.

## MCP server

```bash
npx -y @reneturcios/medprice mcp
```

MCP client config:

```json
{
  "mcpServers": {
    "medprice": {
      "command": "npx",
      "args": ["-y", "@reneturcios/medprice", "mcp"]
    }
  }
}
```

## Docker

```bash
docker run -i ghcr.io/cloudcorprecords/medprice
docker run --rm ghcr.io/cloudcorprecords/medprice --version
```

The container's default command is `mcp`, so the first
form is a stdio MCP server; any other arguments reach
the CLI normally.

## Development

```bash
npm install
npm run build
npm test
npm run dev
```

The test suite runs entirely against a stubbed
JSON-RPC upstream — no live network calls.

## License

MIT — see `LICENSE`.