AI-powered medical imaging analysis toolkit
Analyze MRI scans with local ML models and frontier Vision-LLMs (Claude, GPT, Gemini) and generate structured, radiology-style reports — from the CLI, a web UI, or Docker.
Quick Start · Usage · Configuration · Docs · Contributing · Report Bug
⚠️ MedCheck is a research and educational tool, NOT a medical device. Every output must be reviewed by a qualified radiologist before any clinical use. See the full disclaimer below.
- Plug & Play Docker — single
docker runcommand, no local setup required - Multiple data sources — local DICOM folders/ZIPs, easyRadiology portal links, and custom plugins
- Local ML analysis — on-device anomaly detection and feature extraction; no API key required
- Vision-LLM analysis — Claude Opus 4.8, GPT-5.5, and Gemini 3.5 Flash (opt-in, consent-gated)
- Privacy by default — nothing leaves your machine without explicit consent;
--deidentifypseudonymizes reports - Clinical context input — attach symptoms, trauma history, and suspected diagnosis to guide the analysis
- Professional reports — structured PDF/HTML/JSON with findings tables, impression, and limitations
- YAML workflow engine — compose and version-control custom analysis pipelines as code
- Web UI + CLI + REST API — 3-step browser wizard, scriptable CLI, and an HTTP API
docker run -p 8080:8080 \
-e ANTHROPIC_API_KEY=your_key_here \
-v $(pwd)/scans:/data/scans \
ghcr.io/liohtml/medcheck:latestOpen http://localhost:8080 and follow the 3-step wizard.
pip install medcheck
medcheck serve # web UI on http://localhost:8080git clone https://github.com/Liohtml/MedCheck.git
cd MedCheck
uv sync
uv run medcheck serve# Fully local, no API key needed (ML analysis + JSON report):
medcheck analyze ./my-dicom-folder --steps ingest,preprocess,ml_analysis,report
# Full analysis with a cloud Vision-LLM (requires a key + explicit consent):
medcheck analyze ./my-dicom-folder \
--model claude --allow-cloud-llm \
--symptoms "Medial knee pain after sports injury" \
--report pdf --lang en
# Not sure what to type? Let MedCheck ask you:
medcheck analyze ./my-dicom-folder --interactiveReports land in ./output/ (they contain patient data unless you pass --deidentify — see Privacy & Security).
┌─────────┐ ┌────────────┐ ┌────────────┐ ┌───────────┐ ┌────────┐
│ Ingest │───▶│ Preprocess │───▶│ ML Analyze │───▶│ Vision AI │───▶│ Report │
│ │ │ │ │ │ │ │ │ │
│ DICOM / │ │ Normalize │ │ LLaVA-Med │ │ Claude / │ │ PDF / │
│ easyRad │ │ Resize │ │ MONAI │ │ GPT / │ │ HTML │
│ Plugins │ │ Anonymize │ │ Anomaly │ │ Gemini │ │ + PNG │
└─────────┘ └────────────┘ └────────────┘ └───────────┘ └────────┘
- Ingest — load studies from local paths, the easyRadiology portal, or third-party plugins.
- Preprocess — normalize pixel values, detect anatomy/planes, build volumes.
- ML Analyze — run local anomaly-detection models to find suspicious slices (no API key required).
- Vision AI — send the top slices to a Vision-LLM for structured findings (only with your consent).
- Report — render a structured radiology-style report as PDF, HTML, or JSON.
medcheck analyze SOURCE [OPTIONS] # run an analysis pipeline
medcheck serve # start the web UI / REST API
medcheck providers # list data providers
medcheck models # list LLM providers and availabilityThe most useful analyze options:
| Option | Description |
|---|---|
--model, -m |
LLM provider: claude, openai, gemini, local |
--allow-cloud-llm |
Consent to send imaging data to an external cloud LLM |
--deidentify |
Replace patient name/ID/DOB with a pseudonym in reports |
--symptoms, --trauma, --diagnosis |
Clinical context to guide the analysis |
--report, -r |
Report format: pdf, html, json |
--lang, -l |
Report language: en, de, fr, es |
--steps |
Comma-separated pipeline steps (skip what you don't need) |
--workflow, -w |
Run a YAML-defined pipeline instead |
--interactive, -i |
Prompt for missing inputs |
Run medcheck analyze --help for the full list.
medcheck serve exposes:
| Endpoint | Description |
|---|---|
GET /health |
Liveness probe (always public) |
POST /api/analyze |
Run an analysis (JSON body: source, anatomy, report_format, language, allow_cloud_llm, …) |
When MEDCHECK_API_KEY is set, /api/* requires an X-API-Key header. Requests
are rate-limited per client IP (MEDCHECK_RATE_LIMIT, default 10/min).
| Model | Provider | Best For |
|---|---|---|
| Claude Opus 4.8 | Anthropic | Highest diagnostic quality and reasoning depth |
| GPT-5.5 | OpenAI | High-resolution image understanding |
| Gemini 3.5 Flash | Speed-optimized, cost-effective batch processing | |
| LLaVA-Med | Local | Fully offline, no API key required (coming soon — #18) |
Default model IDs are overridable via MEDCHECK_CLAUDE_MODEL, MEDCHECK_OPENAI_MODEL, and MEDCHECK_GEMINI_MODEL.
| Source | Type | Notes |
|---|---|---|
| Local DICOM | Folder / ZIP | Point to any directory or ZIP of DICOM files |
| easyRadiology | Portal link | Authenticates with the access code from your clinic (date of birth optional) |
| Custom providers | Plugin | See docs/providers.md |
Copy .env.example and fill in your API keys:
cp .env.example .env| Variable | Default | Description |
|---|---|---|
ANTHROPIC_API_KEY / OPENAI_API_KEY / GOOGLE_API_KEY |
— | LLM keys (at least one for cloud Vision analysis) |
MEDCHECK_LLM_PROVIDER |
claude |
Default LLM provider (claude | openai | gemini | local) |
MEDCHECK_ALLOW_EXTERNAL_LLM |
off | Consent to external LLM transmission (1 to enable) |
MEDCHECK_LANGUAGE |
en |
Default report language |
MEDCHECK_HOST |
127.0.0.1 |
Bind address; set 0.0.0.0 to expose on the network |
MEDCHECK_PORT |
8080 |
Bind port |
MEDCHECK_API_KEY |
— | When set, /api requires an X-API-Key header |
MEDCHECK_RATE_LIMIT |
10 |
POST /api/analyze requests per IP per minute (0 = off) |
MEDCHECK_MAX_VISION_IMAGES |
12 |
Max slice images sent to the LLM per analysis |
MEDCHECK_MAX_DOWNLOAD_BYTES |
2 GiB | Cap on portal exam-ZIP downloads |
MedCheck handles patient data (PHI), so the defaults are deliberately conservative:
- Nothing leaves your machine without consent. Cloud Vision analysis requires
--allow-cloud-llm,MEDCHECK_ALLOW_EXTERNAL_LLM=1, or the interactive prompt. If the requested LLM provider is unavailable, MedCheck never silently reroutes data to a different cloud provider. - Reports contain PHI by default. Pass
--deidentifyto replace patient name/ID/DOB with a stable pseudonym. Report files are written with owner-only permissions. - Localhost by default. The server binds to
127.0.0.1; network exposure requires an explicit opt-in and should always be combined withMEDCHECK_API_KEY. - Logs are pseudonymized, ZIP extraction is hardened, and the web UI ships a strict Content-Security-Policy.
Details: SECURITY.md · vulnerability reports via private advisory.
Define analysis pipelines as YAML and commit them alongside your code:
# workflows/full_analysis.yml
name: full_analysis
description: Complete MRI analysis with ML and Vision-LLM
steps:
- ingest:
- preprocess:
normalize: true
auto_detect_anatomy: true
- ml_analysis:
models: [anomaly_detection, feature_extraction]
- vision_analysis:
provider: claude
clinical_context:
symptoms: "Medial knee pain after sports injury"
trauma: "Valgus stress, 10 days ago"
- report:
format: pdf
language: enRun a workflow:
medcheck analyze --source ./dicoms --workflow workflows/default.yml| Topic | Link |
|---|---|
| Quickstart guide | docs/quickstart.md |
| Data providers & plugins | docs/providers.md |
| Workflow engine reference | docs/workflows.md |
| Supported models | docs/models.md |
| Intended use & positioning | docs/intended-use.md |
| Model card (limitations & risks) | docs/model-card.md |
Contributions of every size are welcome — from typo fixes to new data providers.
Where to start:
- 🟢
good first issue— small, well-scoped tasks with pointers - 🙋
help wanted— features we'd love help with (new providers, local LLaVA-Med, …) - 🗺️ Roadmap epic #51 — validation & enhancement pipeline stages
Dev setup:
git clone https://github.com/Liohtml/MedCheck.git
cd MedCheck
uv sync --all-extras
pre-commit install
# Quality gates (same as CI):
uv run pytest # tests (coverage floor: 80%)
uv run ruff check src tests && uv run ruff format --check src tests
uv run mypy src
uv run bandit -r src/medcheck -ll -qPlease read CONTRIBUTING.md before opening a PR. All pull requests require passing CI and at least one approving review.
MedCheck builds on the shoulders of excellent open-source work:
- Stanford MRNet — benchmark dataset for knee MRI analysis
- Project MONAI — PyTorch-based framework for medical image learning
- pydicom — pure-Python DICOM file I/O
MedCheck is NOT a medical device and has NOT been cleared or approved by any regulatory authority (FDA, CE/EU MDR, or otherwise). It is intended solely as a research and educational tool. It must NOT be used to diagnose, screen for, or rule out any condition. All outputs must be reviewed and verified by a qualified radiologist or licensed medical professional before use in any clinical decision-making context. Do not use MedCheck as a substitute for professional medical advice, diagnosis, or treatment.
See Intended Use & Positioning for the scope and the do/don't boundary, and the Model Card for limitations and known risks.
Distributed under the Apache License 2.0.