agentlookups.ai / docs / CounterScript
CounterScript shows what US pharmacies pay to buy a drug, a fair cash-price range built from that cost, FDA generic equivalents and Medicare negotiated prices. Use it to see what a prescription costs the pharmacy before you pay for it, and to judge a cash price you have been quoted. It works on its website, through an AI assistant over MCP, and as a plain HTTPS API.
CMS publishes NADAC weekly: each file is dated a Wednesday and posted the day before. CounterScript checks daily and reindexes when a new file appears. It archives every file it uses, and each match names its as-of date and a fingerprint (hash) of the source file behind it. Every answer also carries freshness, which gives each source file's date and the day CounterScript last checked for a newer one (see How to read results). The methodology page explains each number.
CounterScript is in beta. Lookups are free during beta, with no account and no API key. Features, access and pricing may change. Rate limits apply.
Open Settings > Connectors > Add custom connector. Paste https://rx.agentlookups.ai/mcp as the URL. No authentication is needed, so leave any OAuth fields empty.
claude mcp add --transport http counterscript https://rx.agentlookups.ai/mcp
Add a remote MCP server with the URL https://rx.agentlookups.ai/mcp, transport Streamable HTTP, no authentication. In ChatGPT this is a custom connector; depending on your plan, adding one may require developer mode.
To test the endpoint by hand, list its tools:
curl -X POST https://rx.agentlookups.ai/mcp \
-H 'content-type: application/json' \
-H 'accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
The same lookup, as a GET request that returns JSON:
https://rx.agentlookups.ai/v1/price?q=atorvastatin+20+mg
GET https://rx.agentlookups.ai/v1/coverage reports the as-of date and counts worked out from the data being served: drugs in all, brand and generic, over-the-counter, by billing unit, drugs with a fair cash range, brands with linked generics, each generic_equivalence status and the Medicare negotiated prices. It also carries freshness. Agent-facing notes are in llms.txt.
drug_price (query; clients show it as "Look up a US drug's fair cash price"): takes a drug name with optional strength and form, such as "atorvastatin 20 mg", and returns a match, a list of candidates, or no match. Read-only.Generic (ingredient) names match best. A name alone, such as "eliquis", returns a list of strengths and forms to choose from. The list shows at most 12, and the result says how many matched. "metformin" alone matches 29, and the answer says the list was cut to 12. For a drug that comes in many strengths or forms, give the strength and form too. To pick from the list, call again with a description exactly as the list gives it, such as "METFORMIN HCL 500 MG TABLET".
Each prompt was run live on September 29, 2026, with the arguments an assistant would send. The figures come from the NADAC file dated September 23, 2026, and change weekly.
"What's a fair cash price for 30 tablets of atorvastatin 20 mg?"
Call: drug_price {"query": "atorvastatin 20 mg"}
Came back: a match for ATORVASTATIN 20 MG TABLET. Pharmacies paid $0.02792 per tablet on average; the fair cash estimate for 30 tablets is $9.84 to $13.84.
"Is there a cheaper generic for Lipitor 20 mg?"
Call: drug_price {"query": "lipitor 20 mg"}
Came back: a match for LIPITOR 20 MG TABLET at $19.07256 per tablet ($581.18 to $585.18 for 30), with one FDA generic equivalent: ATORVASTATIN 20 MG TABLET at $0.02792 per tablet ($9.84 to $13.84 for 30). Its cms_generic_price gives CMS's own figure for the generic version, $0.0279 per tablet, and names the same generic. The answer also says that only your prescriber can decide what you should take.
"What price did Medicare negotiate for Eliquis 5 mg?"
Call: drug_price {"query": "eliquis 5 mg tablet"}
Came back: a match with the Medicare Part D negotiated price, $231 for a 30-day supply, effective January 1, 2026, with a link to the CMS file. It lists the same price for Eliquis Sprinkle. It also gave the pharmacy cost, $5.52114 per tablet ($174.63 to $178.63 for 30). It named no priced generic. Its generic_equivalence note says the FDA Orange Book lists one (apixaban), but no NADAC price is linked to it.
"My pharmacy quoted $40 cash for 30 lisinopril 10 mg tablets. How does that compare?"
First call: drug_price {"query": "lisinopril 10 mg"} returned two candidates: LISINOPRIL 10 MG TABLET and LISINOPRIL-HYDROCHLOROTHIAZIDE 10-12.5 MG TAB.
Second call: drug_price {"query": "lisinopril 10 mg tablet"} returned a match: $0.01815 per tablet, and a fair cash estimate of $9.54 to $13.54 for 30. So the $40 quote sits above the estimate. The answer notes that pharmacies may lawfully charge more or less, and that an insurance copay may be lower than any cash price.
Every lookup result has a result_type:
match: one drug. nadac.per_unit_usd is the average price pharmacies paid per unit (for example EA, one tablet or capsule, or ML, one milliliter), with its effective_date. fair_cash_floor is the fair cash estimate for 30 units: acquisition cost plus a $9 to $13 dispensing fee. For another count, multiply the per-unit price by the count and add $9 to $13. Some results carry no fair cash range: liquids priced per milliliter, and some tablets and packs too. generic_alternatives and medicare_negotiated_prices appear when they apply. A brand-name match with no generic alternatives listed carries generic_equivalence: a status and a dated statement of what the FDA Orange Book file shows for it. A brand-name match can also carry cms_generic_price, CMS's NADAC figure for the corresponding generic, with its effective date, a fair cash estimate where one applies, and the generic's name when exactly one generic in the index has that price, strength and ingredient. Its statement says: "CMS pairs this figure with the brand; it is not an FDA equivalence rating." concept.nadac_classification is NADAC's own class for the drug: G (generic), B (brand), B-ANDA or B-BIO. concept.human_page is a page a person can open.candidates: several drugs fit the query. Each carries its per-unit price, its nadac_classification and, where available, a 30-unit range. The list holds at most 12, generics first, then alphabetical. candidates_total is how many drugs matched. When that is more than 12, message says so, for example: "The list was cut: 12 of 29 matching drugs are shown (generics first, then alphabetical). Adding a strength or form to the query narrows the list." Pick one and call again with its description.no_match: nothing in the index fits. The service says, in its own words: "This does NOT mean the drug does not exist or has no fair price: NADAC covers drugs with sufficient pharmacy survey data, and some brands, OTC products, and new drugs are absent."A match also carries provenance (the source, the source file's hash and its as-of date). Matches and candidates carry honesty notes that an assistant should pass on as written, and all three kinds of result carry a dispute_url.
All three kinds of result, and /v1/coverage, carry freshness: one entry per source, in the order nadac, orangebook, mfp (Medicare negotiated prices) and purplebook (the FDA Purple Book). Each entry gives as_of, the publisher's date on the file in use; checked, the date of CounterScript's newest successful fetch of that source; expected, how often the publisher usually updates it (weekly, monthly or irregular); and stale. A source not fetched yet has no as_of or checked; on September 29, 2026 that was true of purplebook. stale is true when the NADAC file is more than 10 days old, the Orange Book file more than 45 days old, or the month of the Purple Book file ended more than 60 days ago. A statement then says why in plain words, including when CounterScript's own fetch is behind. stale is always false for mfp, whose updates are irregular.
The service's honesty rules, quoted from its llms.txt:
NADAC is what pharmacies PAY to acquire a drug: a benchmark, not a price anyone owes.
Fair-cash figures are estimates (acquisition + $9-13 dispensing fee band).
Insurance copays may be lower; cash usually does not count toward deductibles.
Not medical advice; a no_match never means a drug lacks a fair price.
no_match, or a result with no generic listed, proves nothing./v1/coverage rather than relying on a copied list.candidates_total: when more drugs matched than the 12 shown, message says the list was cut. Add the strength and form to your query.freshness, stale true means that source's file is older than its publisher's usual schedule allows, and statement says whether the publisher has not posted a newer one or CounterScript has not fetched it yet. Figures from that file may be out of date.us-tx. Each service's docs page gives its rule./mcp and that no authentication is set, then run the curl test above.No account, no cookies, no trackers. Searches on the website (/search/) and lookups through /v1 and /mcp are logged without the drug name, except in the error line a failed or turned-away request leaves. A drug page's web address names the drug, so visiting one leaves that name in the page log. All logs are deleted after 14 days. Details are on the privacy page; use is covered by the terms. Both cover every agentlookups.ai service. CounterScript is run by TopHat Monkey Software LLC.
Last updated: September 29, 2026