dhis2w¶
Python tooling for DHIS2. A uv workspace with an async client library, a Typer CLI, a code generator, and a shared plugin runtime. The FastMCP server (dhis2w-mcp), the FHIR Implementation Guide tooling (dhis2w-fhir), and the Playwright browser helper (dhis2w-browser) are plugin packs in repositories of their own.
Where to start¶
Everything here talks to DHIS2. Pick the surface you want to talk to it through — each has its own tab, its own tutorial, and its own reference:
- Python client — async library for ETL scripts, embedded DHIS2 calls inside another service, and tests that need typed access. Pairs with the Python library tutorial.
d2wCLI — terminal use, shell pipelines, CI / cron jobs, day-to-day admin. Pairs with the CLI tutorial.dhis2w-mcpMCP server — LLM-driven workflows (Claude Desktop, Claude Code, Cursor, Continue, Cline), from thedhis2w-mcpplugin pack with its own documentation site. Pairs with the MCP tutorial.d2w fhir— publish an instance's metadata as a FHIR Implementation Guide, serve it as a capture endpoint, and forward what it captures back into DHIS2, from thedhis2w-fhirplugin pack with its own documentation site. See FHIR support for installing it.
Whichever you pick:
- New to the repo? Skim the Walkthrough, set up a local DHIS2, then pick a surface above.
- Connecting to a remote DHIS2? Connecting to DHIS2 covers Basic / PAT / OAuth2 with profiles.
- Looking for the architecture? Start at Overview, then Typed schemas + Codegen.
- Browsing by symbol? The API reference auto-renders every
dhis2w-clientmodule's docstrings.
Packages¶
| Package | Role | PyPI |
|---|---|---|
dhis2w-client |
Async DHIS2 API client with pluggable auth and pydantic models | dhis2w-client |
dhis2w-core |
Profile discovery, plugin registry, first-party plugins | dhis2w-core |
dhis2w-cli |
Typer console script d2w (mounts plugins from dhis2w-core) |
dhis2w-cli |
dhis2w-codegen |
Version-aware client generator | workspace-only |
Plugin packs ship from their own repositories and mount their own commands on the same CLI: uv tool install 'dhis2w-cli[security]' brings the security posture scanner, 'dhis2w-cli[browser]' the Playwright-driven screenshots and PAT minting of dhis2w-browser, and 'dhis2w-cli[fhir]' the FHIR Implementation Guide tooling of dhis2w-fhir. The MCP surface is the dhis2w-mcp pack: the dhis2w-mcp server carrying the MCP tools of every built-in plugin (uvx dhis2w-mcp), the single-tool dhis2w-mcp-bridge for small local models, and the dhis2w-mcp-router search + dispatch router, documented at https://winterop-com.github.io/dhis2w-mcp/. The LLM benchmark harness lives in dhis2w-integration, the control center that assembles this workspace and every pack into one environment; see AI agent testing.
Plus infra/, a docker-compose stack for running a local DHIS2 instance with pre-seeded PATs and an OAuth2 client.
FHIR support¶
d2w fhir - generating a FHIR Implementation Guide from an instance, serving it as a capture endpoint, and forwarding captures back into DHIS2 - is the dhis2w-fhir plugin pack, documented at https://winterop-com.github.io/dhis2w-fhir/. Install it with the CLI:
uv tool install "dhis2w-cli[fhir]" # d2w fhir init / generate / validate / forward / doctor
uv tool install "dhis2w-cli[fhir,serve]" # plus the serving facade behind d2w fhir serve
In a project, uv add dhis2w-fhir (and dhis2w-fhir-serve, dhis2w-fhir-engine for the facade and the evaluation engine as libraries). Without the pack installed, d2w fhir prints the install command rather than failing as an unknown command; d2w browser and d2w security do the same for their packs.
Capability matrix¶
The generated MCP tool reference of the dhis2w-mcp pack currently reports around 315 tools across 14 plugin groups (the auto-regenerated count is the source of truth; the per-group numbers below age with each release). 19 top-level CLI domains, plus whatever a plugin pack mounts. Every MCP tool accepts an optional profile: str | None kwarg so an agent can target any configured profile per call. Most operational read/write commands ship as both a CLI command and a matching MCP tool sharing one typed service call. A few surfaces are intentionally CLI-only — they involve local-machine state, interactive prompts, or out-of-process subprocesses that don't fit the MCP stdio model:
d2w dev— codegen, sample-fixture generation, ad-hoc UID minting. Local developer workflow; not exposed via MCP.d2w browser— Playwright-driven PAT mint, OIDC login, dashboard / viz / map screenshots. Runs Chromium out-of-process; not exposed via MCP.d2w profile add / remove / rename / login / logout / bootstrap— profile mutations touch local TOML + the OAuth2 token store and gate on interactive prompts. Profile reads (list,verify,show) are exposed as MCP tools; the four MCP profile tools cover those read paths.d2w fhir— scaffolds project trees, shells out to a dockerized IG publisher, and runs its own HTTP facade. The plugin registers no MCP tool at all; the served facade is the network surface an agent talks to instead.
| Domain | CLI | MCP tools | Docs |
|---|---|---|---|
| Profile (list / verify / show / default / add / remove / rename, login / logout / bootstrap) | d2w profile |
4 | Profiles |
| System (whoami, info, server-info, calendar get/set) | d2w system |
5 | System module |
Metadata — core surface (list / get / patch / search / usage / export / import / diff / diff-profiles / merge) |
d2w metadata |
230 | Metadata plugin |
| Metadata — authoring triples (org-units, data-elements, indicators, program-indicators, category-options + legend-sets + options + attribute + program-rule + sql-view + viz + dashboard + map) | d2w metadata <sub-app> |
— (part of metadata count above) | Organisation units / Data elements / Indicators / Program indicators / Category options / Legend sets |
Data (aggregate dataValueSets + dataValues, tracker entities / enrollments / events / relationships / push) |
d2w data aggregate + d2w data tracker |
15 | Aggregate plugin / Tracker plugin |
| Analytics (aggregate / event / enrollment / outlier / tracked-entity queries) | d2w analytics |
5 | Analytics plugin |
Route (/api/routes integration proxies) |
d2w route |
7 | Auth schemes |
| Maintenance (tasks, cache, cleanup, data integrity, validation, predictors) | d2w maintenance |
15 | Maintenance plugin |
| Files (documents + file resources) | d2w files |
5 | Files plugin |
| Data store (namespaces, keys, get / set / delete, delete-namespace, the shared store and the per-user one) | d2w datastore |
5 | Data store |
Messaging (/api/messageConversations + ticket-workflow fields) |
d2w messaging |
11 | Messaging plugin |
| User admin (users, groups, roles, sharing) | d2w user + d2w user group + d2w user role |
16 | User plugin / User groups + roles |
| Customize (login page / logos / CSS / system settings) | d2w customize |
7 | Customize plugin |
Apps (/api/apps + /api/appHub + snapshot/restore) |
d2w apps |
13 | Apps API |
| Doctor (DHIS2_ISSUES.md tripwires + integrity checks + metadata health) | d2w doctor |
4 | Doctor plugin |
| Security posture (settings, authorities, audit, report) | d2w security (the dhis2w-security pack) |
3 | dhis2w-security |
| Dev (codegen, uid, pat, oauth2 client, sample fixtures) | d2w dev |
— (dev-only) | Codegen |
| Browser automation (Playwright-driven PAT mint, screenshots, OIDC login) | d2w browser |
— (runs out-of-process) | Browser automation |
| FHIR (init / validate / generate / serve / forward / withdraw / doctor) | d2w fhir (the dhis2w-fhir pack) |
— (CLI and its own HTTP facade) | dhis2w-fhir |
Day-to-day workflows (make install, make lint, make test, make docs-serve) are documented in the repo root README.md.