Thirty years of test results, discharge summaries, ultrasound reports — printed by clinics that no longer exist, in countries you no longer live in, in languages your current doctor does not read.
Epicrisis Companion turns that box into an archive on your own computer. Every value exactly as it was printed, in the language it was printed in, next to the reference range printed beside it, one click from the original page.
You run it for yourself, then for your father, then for your grandmother — one instance, one archive per person, and the archives never touch.
The same program, three different reasons to open it.
The appointment is in an hour and the doctor asks how long your haemoglobin has been at that level. Three years — and here are the eleven measurements, in the units each of the three laboratories used.
Fifteen years of glycated haemoglobin in one line: before it was found, the two years it was bad, the year treatment started, and every year since. The picture no single form contains, and the one every endocrinologist asks for.
Her archive is small, on paper, in the language of another decade, and nobody but the family will ever type it up. Twenty documents are still twenty documents you can hand over as a chart instead of a plastic bag.
All of it is the built-in demo: three archives of people who do not exist, drawn as scanned forms in five languages and then transcribed, checked and indexed for real — without a single model call and without anything leaving the machine. Drag the strip, or use the buttons. Click a picture to open it whole.
Most of the work in this program is refusing to be helpful.
Models misread pages. So the archive does not trust its own reading.
Read and in daily use in Russian, Ukrainian, English, Spanish and Greek — including Greek capitals that lose their accents, headings spaced o u t like this, and tables printed sideways.
For one page, yes — and it will read it better than any rule. For an archive it is a different job, and the difference is structural rather than a matter of prompting.
| A model reading your files | Epicrisis | |
|---|---|---|
| Scale | Thousands of pages do not fit in a context window | Read once, stored, indexed; the whole archive answers in milliseconds |
| Repeatability | Ask twice, get two answers | The reading is a file on your disk; tomorrow's answer is today's |
| Provenance | A number in a chat | Every value carries its file, page and date, and links to the scan |
| Your corrections | Die with the conversation | Stored apart from the model's output, keyed to the printed line, reapplied after every re-read |
| Catching mistakes | You have to notice | Deterministic checks find them; a second, different model reads again and disagreements are shown |
| Units and specimens | Quietly converted, quietly merged | Never converted silently; split by unit and by specimen, and where one test printed at two scales is drawn as one history, every moved point says so |
| Vocabulary | Regrouped differently every time | One vocabulary, approved once, in five languages |
| Several people | One pile | One archive per person, one index file each, by construction |
| With no model at all | Nothing works | Search, charts, index, checks and the whole dashboard |
Real medical records of real people, and whose they are is nobody's business.
Nothing from them appears here: every picture on this page comes from
epicrisis demo, which invents its own people. Every count of what those archives
hold is a floor and only ever goes up; the size of the test suite is exact, because this
repository can prove it.
The whole design assumes the machine is yours and the network is not.
127.0.0.1 only. From anywhere else, through an SSH tunnel.data/. Most of it is made again by code alone: the index and the checks in seconds, the walk of the folder in minutes. The readings — what each page is and what was printed on it — only by paying a model to read the documents again, and it will read them a little differently.data/ are your own work, and nothing rebuilds them: your corrections, your verdicts on findings, the indicators you approved, the doctors and clinics you said were one, the earlier readings kept when a later one displaced them, your conversations, and the rules you wrote for your own laboratory's forms. epicrisis backup <folder> copies exactly those, and nothing else, in one place. Do not delete data/ without them.unlock returns a pass good for four hours by default, and that window is a setting on the same page; every tool refuses without it, unless the owner has let that one link off the code (connector code off) or opened it from the machine itself (mcp-lock open) — both are the owner's own deliberate acts, and the links page says of each link which it is; lock_archive ends it early. The secret behind that code is generated on your server, read once into your phone, and never travels through a conversation.
Two licences — free for a person and their family, commercial for an organisation — and which one you fall under is written into the licence itself, not promised on a page that can be edited later.
Keeping and reading medical records — your own, your household's, and those of relatives or friends you help without being paid — costs nothing and always will. So does reading the code, changing it, publishing your changes and running it to see what it does.
You run it yourself, and you use it at your own risk. It is provided as is, with no warranty of any kind: it is not a medical device, it does not say whether a value is normal, and a transcription from a scan can be wrong — which is why every value is one click from the page it came from. The page, not the program, is the authority.
Business Source License 1.1 · free production use for a person keeping records of their own, their household's, or of relatives and friends they help without being paid · every version becomes Apache 2.0 four years after it is published
An insurer, a reinsurer, an assistance company — and any other organisation running this program, or offering what it does to other people as a product or a service — needs a commercial licence. It carries:
The first teams this is built for are medical underwriting and claims: a full case history before the decision instead of a stack of PDFs, and the scan behind every number. Self-hosted, inside your own perimeter. It extracts and cites; it does not score, price or decide.
Three modes, and the strictest is the default. As printed: the archive is shown as the forms wrote it and the application compares nothing. May also read the values: a model may say what a value means and how it moved, and the application still computes nothing. No limits set here: the model answers under no rule of ours, and this is the one mode in which the application itself compares a number with the range printed beside it on its own form and counts what fell outside — so this is where a question such as when a value first left its printed range is answered. The mode is chosen on the Settings page of your own instance, by you, and nothing here changes who is responsible for a decision.
Write to artem.berman@gmail.com and say what your organisation does and how many people would use it.
Business Source License 1.1 · running it in production by or for an organisation is not covered by the free grant and needs a commercial licence · reading the code, changing it and evaluating it are free for everyone · every version becomes Apache 2.0 four years after it is published
A clinic, a hospital, a laboratory, a practice — any organisation running this program for its own clinicians and its own patients — needs a commercial licence. It carries the same things: the right to run it in production, a data processing agreement under Article 28 GDPR and answers to a security review, releases, a named person to write to, and terms of liability an organisation can sign.
What it is for here is the paper a patient brings from somewhere else: other clinics' discharge letters, other laboratories' forms, often in several languages and spanning decades. It becomes one archive your clinician can read before the visit ends — one timeline per test across laboratories, the range printed on each form kept as that form printed it, and every value one click from the scan it came from. It reads and cites; it does not diagnose, triage or decide, and the page, not the program, is the authority. It holds what the patient brought and what could be read from it: a test missing from this archive is not a test that was never taken, and the program says as much wherever it answers with nothing.
Three modes, and the strictest is the default. As printed: the archive is shown as the forms wrote it and the application compares nothing. May also read the values: a model may say what a value means and how it moved, and the application still computes nothing. No limits set here: the model answers under no rule of ours, and this is the one mode in which the application itself compares a number with the range printed beside it on its own form. The last two were written for a person reading their own records — the model is told that the person asking is the person the records are about — so the mode that fits a clinic reading somebody else's file is the first. The mode is chosen on the Settings page of your own instance, by you, and nothing here changes who is responsible for a clinical decision.
One archive per patient, isolated by construction, and every page carries the name of the one whose records are open. Self-hosted, inside your own perimeter: no vendor cloud and no telemetry, and model calls go out with your own key or not at all.
Write to artem.berman@gmail.com and say what your organisation does and how many people would use it.
Business Source License 1.1 · running it in production by or for an organisation is not covered by the free grant and needs a commercial licence · reading the code, changing it and evaluating it are free for everyone · every version becomes Apache 2.0 four years after it is published
The same four commands whichever of the two you are: a person about to type up a parent's folder, or a team looking at this before it goes anywhere near a real case.
Python 3.14 and uv. This project asks uv to use a
Python already on the machine rather than fetching one, so install 3.14 the way your system
installs Pythons — brew install python@3.14 on macOS — rather than with
uv python install. One system library too: libmagic, which tells a file's
kind from its first bytes — brew install libmagic on macOS,
apt install libmagic1 on Debian or Ubuntu, python-magic-bin on
Windows.
git clone https://github.com/bermana-net/epicrisis && cd epicrisis
uv sync
uv run epicrisis demo --into /tmp/demo # three invented archives, no model called
uv run epicrisis serve --data-dir /tmp/demo/data
That demo is everything on this page: three lives that never happened — Vera, her father Anders, her grandmother Zoya — drawn as scanned forms in five languages, transcribed, checked and indexed for real, with not one call leaving your machine.
Then, when you are ready — in this order:
uv run epicrisis sources add ~/scans --owner "Your name"
uv run epicrisis serve # open /consent and read what would be sent
uv run epicrisis update # inventory → classify → extract → validate → index
The steps that read documents need a model: either the claude command signed in
with your own Claude subscription, or ANTHROPIC_API_KEY in a .env
file with the engine changed on the Settings page. Without one the other steps still work and
the dashboard says which is missing. Nothing is sent before you read, once, what would go
— which is why serve comes before update here: run them the
other way round and the two steps in the middle are skipped, and you are left with an archive
that has been listed and not read.