dhis2-mcp
# dhis2-mcp
A read-only MCP server for DHIS2 health data. It runs on stdio.
The server is built for small local models. Each tool returns compact JSON, not the raw
DHIS2 response. A small context window is a budget — the tools spend as little of it as
possible.
## Tools
| Tool | What it does |
|---|---|
| `search_indicators` | Search DHIS2 indicators by name. Returns id, name, and description. |
| `query_analytics` | Get aggregated values for one indicator, split by period, for one organisation unit. |
Run `search_indicators` first to get an indicator id. Then pass the id to `query_analytics`.
## Requirements
- Node.js 20 or later.
- A DHIS2 instance. The default is the public play demo, so you can start with no setup.
## Install and build
```bash
git clone https://github.com/brianmituka/dhis2-mcp.git
cd dhis2-mcp
npm install
npm run build
```
## Configuration
Set these environment variables. All three are optional.
| Variable | Default | Meaning |
|---|---|---|
| `DHIS2_BASE_URL` | `https://play.im.dhis2.org/stable-2-43-1` | Base URL of the DHIS2 instance |
| `DHIS2_USERNAME` | `admin` | Basic auth username |
| `DHIS2_PASSWORD` | `district` | Basic auth password |
The play demo resets every night. Use the host `play.im.dhis2.org`, not `play.dhis2.org` —
the old host redirects to an HTML page.
## Use with LM Studio
LM Studio 0.3.17 or later supports MCP. Open the **Program** tab, then edit `mcp.json`.
Add this entry:
```json
{
"mcpServers": {
"dhis2": {
"command": "node",
"args": ["/absolute/path/to/dhis2-mcp/dist/index.js"],
"env": {
"DHIS2_BASE_URL": "https://play.im.dhis2.org/stable-2-43-1",
"DHIS2_USERNAME": "admin",
"DHIS2_PASSWORD": "district"
}
}
}
}
```
Replace the path with your clone location. Restart the model chat after you edit the file.
## Use with other MCP clients
Any stdio MCP client works. For Claude Code:
```bash
claude mcp add dhis2 -- node /absolute/path/to/dhis2-mcp/dist/index.js
```
## Test with MCP Inspector
```bash
npx @modelcontextprotocol/inspector node dist/index.js
```
The Inspector does not reload the server after a rebuild. Click **Restart** in the
Inspector after every `npm run build`.
## License
MIT. See [LICENSE](LICENSE).
TDQS
Scored across 2 tools
The two tools are clearly distinct: search_indicators handles metadata discovery while query_analytics retrieves aggregated data. The explicit dependency between them removes any ambiguity.
Both tools follow the same verb_noun pattern with snake_case naming (search_indicators, query_analytics), making the naming perfectly consistent and predictable.
Two tools feels very thin for a DHIS2 server, which typically covers a broad health information system domain. The server only exposes a small analytics niche, so the count does not match the implied scope.
The core workflow of searching for indicators then querying analytics is present, but there is no way to discover organization units, periods, or other metadata within the server. This forces agents to obtain those identifiers from outside the tool surface.