Skip to main content
Glama
bobbynoble

MCP Server Healthcare

by bobbynoble
README.md
# MCP Server Healthcare

A Model Context Protocol (MCP) server for an NHS clinical coding workflow —
suggesting ICD-10-CM/OPCS-4/HCC codes for a clinical note, tracking SAR/FOI
information-governance requests, running DSAR mapping-repository requests
through classification and clinical review, batch coding, and reading/
writing patient data via a Cerner FHIR R4 sandbox.

Any MCP client (Claude Desktop, Claude Code, Copilot Studio's MCP connector,
etc.) can call these tools directly — no REST API layer required.

Originally built as part of [bobbynoble/clinical-coding-bot](https://github.com/bobbynoble/clinical-coding-bot);
this repo is the standalone MCP server, with its own copy of the business
logic it wraps so it has no dependency on that repo.

## Tools

| Area | Tools |
|---|---|
| Clinical coding | `suggest_clinical_codes` |
| SAR/FOI tracker | `list_sar_foi_requests`, `create_sar_foi_request`, `update_sar_foi_request`, `list_overdue_sar_foi_requests`, `list_sar_foi_requests_due_soon`, `get_sar_foi_stats`, `get_sar_foi_cerner_bundle` |
| DSAR mapping repository | `list_dsar_types`, `classify_dsar_type`, `list_dsar_requests`, `create_dsar_request`, `get_dsar_request`, `review_dsar_element`, `deliver_dsar_request` |
| Batch coding | `list_coding_batches`, `get_batch_episodes`, `get_batch_episode`, `get_batch_coding_stats`, `get_revenue_at_risk` |
| Cerner FHIR sandbox | `cerner_status`, `cerner_search_patients`, `cerner_get_patient`, `cerner_get_encounters`, `cerner_get_discharge_note`, `cerner_get_documents`, `cerner_post_condition`, `cerner_post_procedure`, `cerner_import_encounters_to_batch`, `cerner_writeback_episode` |

`cerner_post_condition`, `cerner_post_procedure` and `cerner_writeback_episode`
perform real writes against whatever Cerner environment is configured
(a non-production sandbox by default — see `app/fhir_cerner.py`).

## Setup

```bash
pip install -r requirements.txt
cp .env.example .env   # fill in Azure OpenAI / Search / Cerner credentials as needed
```

Every tool loads regardless of which credentials are set, but `suggest_clinical_codes`
needs Azure OpenAI + Azure AI Search configured, and the `cerner_*` tools need
`CERNER_CLIENT_ID`/`CERNER_CLIENT_SECRET` — calling one without the matching
credentials fails with a clear error rather than crashing the server.

## Running

**Stdio (Claude Desktop, Claude Code, most local MCP clients):**

```bash
python -m MCP_Server_Healthcare
```

Example Claude Desktop config (`claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "clinical-coding-bot": {
      "command": "python",
      "args": ["-m", "MCP_Server_Healthcare"],
      "cwd": "/absolute/path/to/mcp_server_healthcare"
    }
  }
}
```

**Streamable HTTP (remote access, e.g. from Copilot Studio or a hosted MCP
client):**

```bash
python -m MCP_Server_Healthcare --transport http --port 8010
```

The HTTP transport requires `CODING_API_KEY` to be set in `.env` — every
request must carry a matching `X-API-Key` header, or it's rejected with 401
(fails closed). It listens on `127.0.0.1` by default; set `MCP_HOST=0.0.0.0`
(and put it behind TLS/a reverse proxy) to expose it beyond localhost.

## Repository layout

```
MCP_Server_Healthcare/   the MCP server itself (server.py has the tool
                         definitions; __main__.py the stdio/http entry point;
                         auth.py the HTTP transport's API-key gate)
app/                     business logic each tool wraps — coder.py (RAG
                         coding), sar_foi.py, dsar.py, batch.py,
                         fhir_cerner.py. Each stores its state in a SQLite
                         file created alongside it on first run.
```

## Notes

- Blocking network calls (Azure OpenAI/Search, Cerner FHIR) are offloaded
  with `asyncio.to_thread` so one slow call doesn't stall other tool calls
  on the same server.
- SQLite files (`app/sar_foi.db`, `app/batch.db`, `app/dsar.db`) are created
  automatically on first run and are gitignored.