Skip to main content
Glama
remoprinz

Swiss Health MCP Server

by remoprinz
README.md
# Swiss Health MCP Server

[![npm version](https://badge.fury.io/js/%40prinz_esox%2Fswiss-health-mcp.svg)](https://www.npmjs.com/package/@prinz_esox/swiss-health-mcp)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

An MCP server that gives AI assistants structured access to **1.6 million Swiss health insurance premium records** -- 55 insurers, 26 cantons, 11 years of official government data.

Built on the [Model Context Protocol](https://modelcontextprotocol.io). Data sourced from [BAG Priminfo](https://priminfo.admin.ch) (Swiss Federal Office of Public Health, 2016--2026). This is the MCP companion to the [KrankenkassenGPT](https://github.com/remoprinz/KrankenkassenGPT) REST API.

## Quick Start

Add this to your Claude Desktop config (`claude_desktop_config.json`) or Cursor settings (`.cursor/mcp.json`):

```json
{
  "mcpServers": {
    "swiss-health": {
      "command": "npx",
      "args": ["-y", "@prinz_esox/swiss-health-mcp"],
      "env": {
        "SUPABASE_URL": "https://your-project.supabase.co",
        "SUPABASE_SERVICE_ROLE_KEY": "your-service-role-key"
      }
    }
  }
}
```

Or install globally:

```bash
npm install -g @prinz_esox/swiss-health-mcp
```

The server is also available on the [Smithery](https://smithery.ai) registry and the [MCP Registry](https://registry.modelcontextprotocol.io/?q=swiss-health).

## Tools

### `get_cheapest_insurers`

Find the top 5 cheapest health insurers for a given profile.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `canton` | string | yes | Canton code (e.g. `ZH`, `BE`, `GE`) |
| `year` | number | yes | Year (2016--2026) |
| `age_band` | string | yes | `child` (0--18), `young_adult` (19--25), `adult` (26+) |
| `franchise_chf` | number | yes | Deductible: 0, 100, 200, 300, 400, 500, 600, 1000, 1500, 2000, 2500 |
| `model_type` | string | no | `standard` (default), `hmo`, `telmed`, `family_doctor`, `diverse` |
| `accident_covered` | boolean | no | Include accident coverage (default: `true`) |

### `compare_insurers`

Side-by-side comparison of specific insurers for the same profile.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `insurer_names` | string[] | yes | Insurer names (e.g. `["CSS", "Helsana", "Swica"]`) |
| `canton` | string | yes | Canton code |
| `year` | number | yes | Year (2016--2026) |
| `age_band` | string | yes | Age group |
| `franchise_chf` | number | yes | Deductible in CHF |

### `get_price_history`

10-year price development for a single insurer with year-over-year percentage change.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `insurer_name` | string | yes | Insurer name (e.g. `CSS`, `Helsana`) |
| `canton` | string | yes | Canton code |
| `age_band` | string | yes | Age group |
| `franchise_chf` | number | yes | Deductible in CHF |
| `start_year` | number | no | Start year (default: 2016) |
| `end_year` | number | no | End year (default: 2026) |

### `get_database_stats`

Returns coverage statistics and metadata. No parameters.

## Data

| Dimension | Coverage |
|-----------|----------|
| Records | 1,611,386+ |
| Insurers | 55 (CSS, Helsana, Swica, Assura, KPT, Groupe Mutuel, Sanitas, ...) |
| Cantons | 26 (all Swiss cantons) |
| Years | 11 (2016--2026) |
| Franchise levels | 11 (CHF 0--2,500) |
| Insurance models | 5 (standard, HMO, telmed, family doctor, diverse) |
| Age bands | 3 (child, young adult, adult) |

All data comes from BAG Priminfo, the official database of the Swiss Federal Office of Public Health.

## Features

- **Intelligent insurer name resolution** -- fuzzy matching across 55+ insurers and their sub-brands. Ask for "Helsana" and the server resolves all associated insurer IDs automatically.
- **Automatic disclaimer** -- every response includes BAG Priminfo attribution and a notice that premiums are informational only.
- **Read-only access** -- no write operations, no personal data.
- **Percentage change calculations** -- price history includes year-over-year trends.

## Example Prompts

```
"What are the cheapest health insurers in Zurich for 2026?"

"Compare CSS, Helsana and Swica in Bern for an adult with CHF 300 deductible"

"How did Assura premiums develop from 2016 to 2026?"

"Which insurer had the smallest price increase over the last 10 years in Basel?"
```

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `SUPABASE_URL` | yes | Supabase project URL |
| `SUPABASE_SERVICE_ROLE_KEY` | yes | Supabase service role key for database access |

## Tech Stack

- **Protocol:** MCP SDK v1.0.0 (stdio transport)
- **Language:** TypeScript
- **Database:** Supabase (PostgreSQL)
- **Runtime:** Node.js 18+
- **Package:** [@prinz_esox/swiss-health-mcp](https://www.npmjs.com/package/@prinz_esox/swiss-health-mcp)
- **Registry ID:** `io.github.remoprinz/swiss-health-mcp`

## Development

```bash
git clone https://github.com/remoprinz/swiss-health-mcp.git
cd swiss-health-mcp
npm install
npm run dev     # Start with tsx
npm run build   # Compile TypeScript
```

## Project Structure

```
src/index.ts       # Complete server implementation (~530 lines)
server.json        # MCP registry manifest
smithery.yaml      # Smithery registry config
llms.txt           # LLM-readable project description
CITATION.cff       # Citation metadata
```

## License

MIT -- [Remo Prinz](https://github.com/remoprinz)

## Links

- [npm package](https://www.npmjs.com/package/@prinz_esox/swiss-health-mcp)
- [MCP Registry](https://registry.modelcontextprotocol.io/?q=swiss-health)
- [BAG Priminfo (data source)](https://priminfo.admin.ch)
- [Model Context Protocol](https://modelcontextprotocol.io)
- [KrankenkassenGPT REST API (companion project)](https://github.com/remoprinz/KrankenkassenGPT)

TDQS

B3.2/5.0

Scored across 4 tools

Disambiguation4/5

The tools have mostly distinct purposes: compare_insurers compares multiple insurers, get_cheapest_insurers finds the cheapest ones, get_database_stats shows database statistics, and get_price_history shows price trends. However, compare_insurers and get_cheapest_insurers could potentially overlap in function if comparing insurers includes price considerations, but their descriptions clarify distinct focuses (comparison vs. cheapest selection).

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case: compare_insurers, get_cheapest_insurers, get_database_stats, and get_price_history. This uniformity makes the set predictable and easy to understand, with no deviations in naming conventions.

Tool Count3/5

With 4 tools, the count is borderline for a health insurance domain. It feels slightly thin as it covers comparison, cheapest selection, stats, and price history, but lacks tools for detailed insurer information, plan specifics, or user profile management, which might be expected in a comprehensive health insurance server.

Completeness3/5

The tool set covers key aspects like comparison, cost analysis, stats, and history, but has notable gaps. For a health insurance domain, missing operations include creating or updating profiles, retrieving detailed insurer data, or managing user preferences, which could limit agent effectiveness in broader workflows.

Maintenance

ActivityInactive
ResponsivenessNo issues