Labsco
MCP SERVER

Taiwan-Health-MCP

by healthymind-tech

49 tools over Taiwan's medical data and the international terminologies beside it — ICD-10, LOINC, SNOMED CT, TFDA drugs, and FHIR R4 profile authoring with validation.

Biomedical: Genomics & Clinical Data
Summary
An availability signal that means something.

Tools here appear and disappear with their source data, so a visible tool is one whose dataset actually loaded — a far better signal than a tool that exists and returns empty results. The project is careful about the boundary too: it warns that availability does not mean embeddings are complete, and that search will quietly fall back to keyword matching until they are. The single write tool is fenced three ways — administrator-registered server, allow-list, and an explicit confirmation flag.

What it is

A Node.js MCP server covering Taiwanese health data — TFDA drugs with their leaflets and appearance, health supplements, food nutrition, TWCore IG — alongside the international terminologies clinical work depends on: ICD-10-CM/PCS 2025, SNOMED CT International, LOINC 2.80 and FHIR R4. It exposes 49 tools across 11 groups, and mirrors them as an OpenAPI surface for clients that cannot speak MCP.

What you get
  • Diagnosis coding work: search codes, infer complications, list nearby codes, check for conflicts, and browse a category — `search_medical_codes`, `infer_complications`, `get_nearby_codes`, `check_medical_conflict`, `browse_icd_category`
  • TFDA drug data including identifying an unknown pill from its appearance — `search_drug`, `identify_unknown_pill`, `get_drug_details`, `get_drug_asset_links`
  • Lab results interpreted against LOINC, one at a time or in a batch — `search_loinc`, `query_loinc`, `interpret_lab_result`, `batch_interpret_lab_results`
  • SNOMED CT concepts, their relationships and their mappings — `search_snomed_concept`, `query_snomed_concept`, `get_snomed_relationships`, `query_snomed_mapping`
  • A full FHIR IG authoring and validation surface: list and search artifacts across package-scoped IGs, rank and read profiles and their elements, expand ValueSets, look up and validate codes, resolve references, build and validate bundles, and generate a resource skeleton to fill — `fhir_list_igs`, `fhir_search_artifacts`, `fhir_rank_resource_profiles`, `fhir_get_profile_elements`, `fhir_expand_valueset`, `fhir_validate_code`, `fhir_build_bundle`, `fhir_validate_bundle`, `fhir_get_resource_skeleton`, `fhir_finalize_resource`
  • Condition and Medication resources queried and validated directly — `query_fhir_condition`, `validate_fhir_condition`, `query_fhir_medication`, `validate_fhir_medication`
  • Nutrition data: a food's profile, a single ingredient, foods ranked by a nutrient, and a whole meal analysed — `query_food_nutrition`, `query_food_ingredient`, `search_foods_by_nutrient`, `analyze_meal_nutrition`
  • Registered external FHIR servers, their status, and read/write access to them — `list_fhir_servers`, `get_fhir_server_status`, `crud_fhir_server`
  • Semantic or hybrid search backed by an embedding model, falling back to keyword search when embeddings are not yet built
  • Tools that register and deregister themselves as each module's data finishes loading, so an available tool means its source data is present
Requirements

This is a deployment, not an install: clone, copy `.env.example`, set `POSTGRES_PASSWORD` and the admin variables, and `docker compose up -d`. That brings up nginx as the single entry point on port 8080, the Node MCP server and admin REST API, a background worker, PostgreSQL 16 with pgvector, pgBouncer, Redis and MinIO. The app container deliberately does not publish port 8000 to the host — all traffic goes through nginx. Clients connect over streamable-http at `http://<host>:8080/mcp`, or through the OpenAPI bridge at `/openapi.json`, where each tool is a POST endpoint under `/tools/`. Data is loaded from the Admin Console, which is off until you set `ADMIN_ENABLED=true` with a username, a password hash and a session secret. Every tool is read-only except `crud_fhir_server`, which can write only to servers an administrator registered, only if that server's allow-list permits it, and only when the caller passes `confirm_write=true`. Both interfaces ship without enforced authentication — put a reverse proxy or a token in front before exposing them. Licensed MIT.

Setup effort

One command — docker compose up -d