Using tokempic
Run the tokempic CLI to turn one patient's FHIR record into a compact, token-lean Markdown summary for an LLM. Use this whenever you need to fetch, summarize, or condense a patient's clinical record from a FHIR server (especially Google Cloud Healthcare API) — e.g. "summarize patient <id>", "pull this patient's chart", "make an LLM-ready summary of their conditions and meds", or any task that hands a FHIR patient id + server to an LLM. Prefer this over hand-writing curl calls to `$everything`, because tokempic already handles pagination, auth headers, caching, and the SQL-on-FHIR → Markdown rendering. Also use it when wiring patient context into a prompt or agent.From its SKILL.md
npx -y skills add recodelabs/tokempic --skill using-tokempicAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
6.4 KB, as published. Nobody here has run it
Using tokempic
tokempic fetches a single patient's record via the FHIR Patient/$everything
operation and renders a small Markdown summary. The content is defined by
SQL-on-FHIR ViewDefinitions; the layout by an eta template. The win is size:
a full $everything bundle (~70 KB / ~18k tokens for a typical patient) collapses
to ~5 KB / ~1.3k tokens — roughly 14× smaller — while keeping the clinically
relevant facts. Reach for it any time you'd otherwise paste a raw FHIR bundle
into a prompt.
Prerequisites
- The
tokempiccommand. Either a built standalone binary or run from source:- Binary: from the repo,
bun run buildproduces./tokempic(self-contained; move onto yourPATHto call from anywhere). It embeds the default views and template, so it works from any directory. - From source (dev):
bun run src/cli.ts …with the same flags.
- Binary: from the repo,
- A FHIR server URL (
--server). For Google Cloud Healthcare it looks likehttps://healthcare.googleapis.com/v1/projects/<proj>/locations/<loc>/datasets/<ds>/fhirStores/<store>/fhir. - A bearer token (
--tokenor theTOKEMPIC_TOKENenv var). For Google Healthcare, mint a short-lived one withgcloud auth print-access-token [--account=<service-account>]. It expires fast — generate a fresh one per run. The caller needsroles/healthcare.fhirResourceReaderon the dataset or store.
The canonical invocation
tokempic \
--patient <patient-id> \
--server "<fhir-base-url>" \
--token "$(gcloud auth print-access-token)" \
--out summary.md
--patient and --server are required. --out defaults to stdout (-), so omit
it to capture the markdown directly (e.g. to feed straight into a prompt).
Convenience: .env + run.sh (in this repo)
tokempic itself does not read .env — --server/--token are flags, and
$BASE/$SA in examples are ordinary shell variables. The single most common
failure is running with an empty $BASE or $SA because the shell never had them
set. This repo ships two helpers:
- A git-ignored
.envholdingSA=(gcloud service account) andBASE=(FHIR URL). Load it withset -a; source .env; set +abefore invoking the binary directly. run.sh <patient-id> [out-file] [extra flags…]— sources.env, fetches a fresh token for$SA, and runs tokempic. Extra flags are forwarded, e.g../run.sh <id> out.md --max-age 1h.
If a run produces an empty/garbage result or a connection error, first check that
$BASE and $SA are actually populated (echo "$BASE"), then that the token is
fresh.
Flags
| Flag | Purpose |
|---|---|
--patient <id> | Required. FHIR Patient logical id. |
--server <url> | Required. FHIR base URL (ends in …/fhir). |
--token <jwt> | Bearer token. Falls back to TOKEMPIC_TOKEN. |
--out <file> | Output path. Default - (stdout). |
--views <dir> | Directory of ViewDefinition JSON files. Default: built-in set. |
--template <file> | Custom eta template. Default: built-in layout. |
--since <ts> | Only include resources updated after this instant (first fetch). |
--max-age <dur> | Skip the network if the cache is younger than this (30s,10m,2h,1d). |
--refresh | Ignore the cache; do a full fetch (also the way to reconcile deletions). |
--no-cache | Bypass the cache entirely (read nothing, write nothing). |
--cache-dir <dir> | Override cache location (default ~/.cache/tokempic/). |
The fetched resource types are derived automatically from the resource field of
the active ViewDefinitions, so changing --views changes what is pulled.
Caching (default behavior — important for repeated runs)
By default tokempic caches results under ~/.cache/tokempic/, keyed by
(server, patient, viewset), and runs incrementally: it remembers the highest
meta.lastUpdated it has seen and asks the server only for what changed since
($everything?_since=…). If nothing changed, the delta is empty and the cached data
is reused — one tiny request instead of a full paginated pull.
Practical guidance:
- For a one-off, just run normally; the first run is a full fetch.
- For repeated/scripted runs where slightly-stale data is fine, add
--max-age(e.g.--max-age 10m) to skip the network entirely while fresh. - When you suspect a resource was deleted server-side, run
--refresh—_sincedeltas don't carry deletion tombstones, so a deleted resource lingers in the cache until a full refresh. - In tests or when you must not touch a shared cache dir, pass
--no-cache(or a throwaway--cache-dir).
Customizing the output
- To change what is included, point
--viewsat a directory of your own ViewDefinition JSON files (one per section). Each defines aname, aresourcetype, andselect/whereclauses using FHIRPath. The built-in set covers demographics, conditions, medications, allergies, labs, vitals, procedures, immunizations, encounters, and relatedpersons. - To change how it's laid out, pass
--templateanetatemplate. The render context exposesit.patient(the first demographics row) andit.views(a map of view name → array of rows).
Quick troubleshooting
- Empty output / "request failed" → almost always an unset
$BASE/$SAor an expired token. Verify the shell vars and regenerate the token. 401/403→ wrong account or missinghealthcare.fhirResourceReader. Checkgcloud auth listand that--accountmatches a credentialed service account.Both --patient and --server are required→ a flag is missing or its value expanded to empty.- Stale data after a server-side delete → re-run with
--refresh.