Medical Shield.
An offline medication interaction checker for doctors, nurses, and humanitarian
medical workers operating without internet access.
MEDICAL DISCLAIMER
This software is an offline informational aid. It does not replace professional medical judgement, clinical protocols, or qualified healthcare decisions. Always use professional clinical judgement.
mensung 'Acetylsalicylic acid' Warfarin!!! CONTRAINDICATED INTERACTION !!!
Acetylsalicylic acid + Warfarin
Severity:
CONTRAINDICATED
Risk:
DDInter classifies this as a major interaction. Treat with the same urgency
as a contraindication: verify management guidance before co-administering.
Evidence: Established (DDInter (http://ddinter.scbdd.com/))
This software is an offline informational assistant.
Always use professional clinical judgement.
No server, no cloud, no GPU, no database service. Runs on a 10-15 year old laptop with an Intel Core 2 Duo or early i3-class CPU, 2-4GB of RAM, and a slow HDD.
In war zones, refugee camps, rural clinics, and disaster areas, medical workers often have to make drug interaction decisions with no internet connection, on hardware that predates most currently-supported software. A missed contraindication in that setting is not an abstract bug: it is a patient at risk. MenSung exists to give those workers a fast, correct lookup tool that runs on whatever laptop happens to be available, and does not need connectivity for the lookups themselves.
Every actual drug lookup is fully offline: once the database is on the
machine, MenSung never touches the network to answer a query. Getting the
database onto the machine is the one exception. That happens once, either
by running mensung somewhere with connectivity and letting it install a
dataset, or by copying a pre-built medical_database.men file onto the
machine by hand (USB stick, local network, however it gets there). After
that one-time step, the binary and its database file can be copied
anywhere, including a machine that will never see a network connection
again. See Security model for exactly what the binary
does and does not do over the network.
Want the full story behind why this exists and how the data pipeline works? Read the deep-dive article on dev.to.
| Category | Feature |
|---|---|
| Core | Two-or-more-drug interaction lookup, ranked most severe first |
| Safety | Zero false negative policy -- an interaction in the data is always shown |
| Safety | No silent correction -- an inexact name shows ranked candidates and waits for confirmation, never guesses |
| Data | DDInter interactions enriched with RxNorm, WHO ATC, PubChem, and openFDA drug facts |
| Format | Custom .men binary format: zero-copy reads, shared string table, SHA-256 payload checksum verified on every open |
| Interfaces | Scriptable CLI (mensung <drug-1> <drug-2> ...) and a full interactive TUI |
| TUI | Colorized severity (red/yellow/green), text wrapping, Up/Down/PageUp/PageDown scroll, Alt+I for single-drug info |
| Install | Downloads the pre-built enriched database on first run, with an automatic fallback to a bare DDInter-only build if that fails |
| Platforms | Static musl binary on Linux, plus Windows and macOS builds |
| Performance | Startup under 100ms, lookup under 5ms, binary under 10MB |
Two rules shape every part of the design:
- Zero false negative policy. If an interaction exists in the data, it is shown. Recall matters more than precision: an extra warning costs a moment of attention, a missed interaction can cost a patient's life.
- No silent correction. If a typed drug name does not match an INN entry exactly, MenSung shows ranked candidates with similarity scores and asks for confirmation. It never substitutes a guess on its own.
See MEDICAL_DATA_POLICY.md for the full policy, data sources, and validation pipeline.
MenSung is a Cargo workspace following Clean/Hexagonal Architecture. The
dependency direction is one-way toward mensung-domain, which never depends
on anything else in the workspace, so it never knows about the filesystem,
the database format, the CLI, the TUI, or the network:
mensung-domain
^
|
mensung-db <-------- mensung-builder
^ ^
| |
mensung-core (offline tool,
^ not linked into
| the client)
mensung-client
| Crate | Responsibility |
|---|---|
mensung-domain |
Drug entities, interaction models, severity rules, validation logic. No I/O, no UI, no dependency on anything else in the workspace. |
mensung-db |
Binary .men database reader: zero-copy access, checksum validation. Depends on mensung-domain for shared value types. |
mensung-core |
Lookup engine, fuzzy matcher, business rules. Depends on mensung-domain and mensung-db, since a lookup has to read the one database format this project ships. |
mensung-builder |
DDInter importer and downloader, parser, and .men database compiler. Depends on mensung-domain and mensung-db. Linked into the mensung binary, since mensung-client calls it to install the database at runtime; it is the only source of network code in the workspace. |
mensung-client |
CLI and TUI (ratatui + crossterm), the deployed mensung binary. |
mensung-core talks to mensung-db's concrete reader directly rather than
through a trait-based port: there is exactly one .men implementation in
scope, and a lifetime-generic port over its zero-copy return types would add
real complexity for no adapter it would ever swap in. See
CONTRIBUTING.md for the reasoning.
A medical worker runs one statically linked binary plus one .men database
file sitting next to it; nothing else to install, no runtime services, no
required configuration. The database is not embedded inside the binary: see
Usage for how it gets installed and Security
model for the network implications of that.
| Target | Budget |
|---|---|
| Startup | < 100ms |
| Drug lookup | < 5ms |
| Memory | < 50MB RAM |
| Binary size | < 10MB |
The installed database is separate from the binary and is not held to the
10MB figure. A bare DDInter-only build compiles to about 9.3MB under the
.men format v2 shared string table (down from format v1's roughly
28MB); the enriched database mensung installs by default (DDInter +
RxNorm + WHO ATC + PubChem + openFDA, see Usage) is larger,
about 27MB, since it also carries the openFDA drug facts text. See
ROADMAP.md Phase 5's known tradeoff note and Phase 8b.
Download the binary for your platform from the
latest release.
Running it looks for medical_database.men next to itself; if that file is
not there yet, it offers to install a dataset, which needs a network
connection for that one step. See Usage.
The first time mensung runs and finds no medical_database.men next to
itself, it says so and, in an interactive terminal, asks whether to install
a dataset now:
No medication database found at /path/to/medical_database.men.
You can place a compiled medical_database.men there yourself, or let mensung install a dataset now.
Would you like to install the dataset now? [y/N]
Answering yes downloads MenSung's pre-built, enriched database (DDInter +
RxNorm + WHO ATC + PubChem + openFDA, see MEDICAL_DATA_POLICY.md) from this
project's medical-database GitHub Release over HTTPS (TLS certificate
validation is never disabled) and saves it directly; no per-drug API calls,
no local build step. If that download fails for any reason (no route to
GitHub, a corrupt transfer), mensung falls back to downloading DDInter's
own public CSV export and compiling a bare DDInter-only database locally
instead, so a field deployment with only partial connectivity still ends up
with a usable database. Either way, this is the only time mensung touches
the network, and only with this explicit confirmation. In a non-interactive
shell, set MENSUNG_DOWNLOAD_DATASET=1 to skip the prompt, or place a
pre-built medical_database.men next to the binary yourself (or point
MENSUNG_DATA_DIR at wherever you keep it) and mensung never needs to
ask. Once installed, every lookup is fully offline again; nothing about
answering questions touches the network.
Run mensung with no arguments for the interactive terminal interface: two
input fields, Tab to switch between them, Enter to check, Alt+I to show the
focused field's own drug information (RxCUI, WHO ATC classification,
chemical properties, and any contraindications, boxed warnings, or similar
facts known about it) instead of checking an interaction. Alt+I rather than
a bare i or F1: a bare letter would collide with typing a drug name, and
F1 is commonly intercepted by the terminal or OS for their own help screen
before the app sees it. A typed name with no exact match shows a ranked
candidate list with a similarity score and waits for confirmation, the same
for either Alt+I or Enter; it never guesses. Interactions and drug facts are
shown red for contraindicated or high risk, yellow for moderate, minor, or
unknown severity, green for no known interaction. Long text wraps inside its
box and scrolls with Up/Down/PageUp/PageDown. Esc or Ctrl-C quits.
mensung <drug-1> <drug-2> [<drug-3> ...]Run it with two or more drug names for the scriptable command-line mode
instead: every known pairwise interaction out, most severe first. Exit
codes: 0 no known interaction, 1 an interaction was found or a name
could not be resolved, 2 bad command-line usage, 70 an internal or
database error. A typed name with no exact match returns a ranked candidate
list instead of guessing, same as the interactive mode:
$ mensung Amoxilin Aspirin
Unknown drug:
Amoxilin
Did you mean:
Amoxicillin (92.0%)
Aspirin (69.0%)
Confirm your selection and try again with the exact name.
mensung info <drug-name>The command-line equivalent of the TUI's Alt+I key: one drug's own RxCUI, WHO
ATC classification, chemical properties, and any known contraindications,
boxed warnings, or similar facts, instead of an interaction between two
drugs. Exit codes: 0 the drug resolved (whether or not it has any facts
or cross-reference data), 1 the name could not be resolved, 2 bad
command-line usage, 70 an internal or database error. Nothing in the
DDInter-only dataset mensung falls back to populates this data yet; see
ROADMAP.md's Phase 8b and the builder CLI
(mensung-builder build --out <path>) for how a richer database gets
built.
mensung version
mensung check-updateversion prints the installed version and exits; it never touches the
network or the database. check-update is a manual, explicit request
against GitHub's release API for a version newer than the one running; it
never runs automatically (not at startup, not anywhere else), and it never
downloads or installs anything itself, only reports what it found and a
link to get it, the same "explicit confirmation, no silent network
activity" rule the dataset install follows. Both work with no database
installed and never trigger the dataset install prompt.
See MEDICAL_DATA_POLICY.md for why DDInter and not OpenFDA/RxNorm/WHO as originally planned, and for the data license that applies to the installed database (CC BY-NC-SA 4.0, separate from this project's own MIT/Apache-2.0 code license).
git clone https://github.com/Etoile-Bleu/MenSung.git
cd MenSung
cargo build --releaseThe mensung binary is produced by the mensung-client crate at
target/release/mensung. The build itself never touches the network or
needs a dataset; see Usage for how the binary installs its
database the first time it runs.
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
cargo fmt --check
cargo audit
cargo deny checkSupported build targets: x86_64-unknown-linux-musl (statically linked),
x86_64-pc-windows-msvc, x86_64-apple-darwin.
MenSung never sends telemetry, never collects patient data, and never stores patient information. It does contain network code, unlike earlier drafts of this project, in exactly two places, both explicit and neither automatic:
- Dataset install.
mensung-client'sdataset_download.rs, called when a database is not yet installed and the user explicitly agrees, either by answering the interactive prompt or by settingMENSUNG_DOWNLOAD_DATASET=1ahead of time, fetches the pre-built, enriched database from this project's ownmedical-databaseGitHub Release. If that fails,mensung-builder's downloader fetches DDInter's public CSV export over HTTPS instead, fromddinter.scbdd.comfirst and this project's own GitHub Releases second, as a fallback mirror of the exact same files, used when DDInter's own TLS certificate cannot be validated (true as of this writing; see MEDICAL_DATA_POLICY.md). Nothing else. mensung check-update. Fetches this project's latest release metadata fromapi.github.comwhen, and only when, the user runs that exact command. It never runs at startup or anywhere else, and it never downloads or installs a new binary itself; it only reports what it found and a link to get it. See Usage.
Both:
- Never run automatically or silently; each only runs on its own explicit
trigger (a missing database plus a yes, or the
check-updatecommand itself). - TLS certificate validation is never disabled on any source. An invalid or expired certificate is a hard failure, not a fallback to an unverified connection.
- Touch no other host than the ones named above.
Once a database is installed, every drug lookup is answered locally; the
lookup path itself makes no network calls, regardless of how the database
got there, and version never touches the network at all.
See SECURITY.md for the vulnerability reporting process and scope.
See CONTRIBUTING.md for build instructions, the Rust engineering rules this project follows, and PR guidelines. See MEDICAL_DATA_POLICY.md before touching any drug or interaction data. See CODE_OF_CONDUCT.md for community standards.
Dual-licensed under either of:
at your option.
See ROADMAP.md for completed phases and planned work.

