Skip to main content
Glama
cyanheads

cdc-health-mcp-server

by cyanheads

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

Public Hosted Server: https://cdc.caseyjhand.com/mcp


Overview

CDC public health data from the CDC Open Data portal and CDC WONDER. Search 1,000+ datasets on vaccination, surveillance, and behavioral risk, inspect their schemas and query them with SoQL, or pull national mortality statistics by year, age, sex, and race.

Tools

Tool

Description

cdc_discover_datasets

Search the CDC dataset catalog by keyword, category, or tag

cdc_get_dataset_schema

Fetch column schema, row count, and metadata for a dataset

cdc_list_catalog_vocabulary

List the catalog's category and tag values with their entry counts

cdc_query_dataset

Execute SoQL queries — filter, aggregate, sort, full-text search, select fields

cdc_query_wonder

Query CDC WONDER for national mortality, population, and death rates across five databases

Resources

Resource

Description

cdc://datasets

Top 50 most-viewed catalog entries, for orientation

cdc://datasets/{datasetId}

Dataset metadata and the first 100 columns for a specific dataset

Both resources mirror data also reachable via cdc_discover_datasets and cdc_get_dataset_schema, for clients that surface resources but not tools.

Prompts

Prompt

Description

analyze_health_trend

Guided workflow for investigating a public health question across CDC data

Related MCP server: mcp-data-orlando

Capability reference

cdc_discover_datasets tool

  • Filters: query, category, and tags. Up to 100 results per page (default 10); offset + limit is capped at 10,000 (page_out_of_range past it). order is dataset_id (default, stable paging) or relevance

  • Results carry assetType, columnCount (0 marks a chart, map, or other non-tabular asset), an 8-name columnSample, and a description cut to 300 characters, plus totalCount and appliedFilters

  • When a category or tags value matches nothing, the notice names the closest catalog values with their entry counts, e.g. Vaccination → "Vaccinations" (89 datasets)


cdc_get_dataset_schema tool

  • Takes a four-by-four datasetId (e.g. bi63-dtpu). column_limit (default 100) and column_offset page wide schemas, reporting totalCount, truncated, and nextOffset

  • The dataset description is capped at 4,000 characters by default (descriptionTruncated and descriptionLength are set when cut); full_description: true returns the whole text

  • Columns carry fieldName, dataType, and description. rowCountSource says whether rowCount is live or Socrata's cached figure. A non-tabular asset fails with not_queryable


cdc_list_catalog_vocabulary tool

  • Every category comes back whole; the ~1,600 tags are ranked by entry count and paged with tag_limit (default 50) and tag_offset. filter (3+ characters) narrows both by word match, not fuzzy matching

  • Each value carries datasetCount; the response also reports vocabularySize, categoryCount, tagCount, truncated, nextOffset, and truncationCeiling (an upper bound on the counts of the tags after the page)


cdc_query_dataset tool

  • Clauses: select, where, group, having, order, and full-text search. Up to 5,000 rows per call (default 100), offset up to 1,000,000

  • For stable offset paging, set an order ending in a unique tie-breaker (:id on ungrouped rows, the grouped columns on a grouped query); the notice says so when it is missing

  • effectiveQuery echoes the SoQL clauses as sent; truncated and nextOffset report paging, with no totalCount. A chart or map ID fails with not_queryable


cdc_query_wonder tool

database

CDC database

Years

Race groups

mcd_icd10

underlying_1999_2020 (default)

D76 — Underlying Cause of Death

1999–2020

4 bridged

—

provisional

D176 — Provisional Mortality Statistics

2018 → current year

6 single-race

yes

underlying_2018_2024

D158 — Underlying Cause of Death, Single Race

2018–2024

6 single-race

—

multiple_1999_2020

D77 — Multiple Cause of Death

1999–2020

4 bridged

yes

multiple_2018_2024

D157 — Multiple Cause of Death, Single Race

2018–2024

6 single-race

yes

  • group_by takes 1–4 of year, age_group, sex, race (national only). cause_icd10 and mcd_icd10 take an ICD-10 code, a range (X40-X49), or a list of up to 50. age_groups takes NS (age not stated) alone or with all eleven known groups. limit and offset (max 10,000) page the table

  • Rows carry deaths, population, crude_rate, and age_adjusted_rate where age can be standardized. Cells CDC returns as Suppressed, Unreliable, or Not Applicable read null and are listed in cellNotes; messages reports rows CDC hid, and totalCount is exact

  • CDC rejects requests less than 15 seconds apart, so calls are queued one at a time and spaced 16 seconds apart


cdc://datasets resource

  • Top 50 catalog entries by popularity, each with id, name, assetType, category, columnCount, and updatedAt, plus the catalog totalCount

  • columnCount: 0 marks a non-tabular entry; cdc_discover_datasets searches and pages the full catalog


cdc://datasets/{datasetId} resource

  • Dataset metadata plus the first 100 columns as application/json, with columnCount and truncated; the description is capped at 4,000 characters

  • For more columns or the full description, use cdc_get_dataset_schema with column_offset or full_description: true


analyze_health_trend prompt

  • Arguments: topic required; timeRange and geography optional

  • Returns one user message that routes the question to cdc_query_wonder (national mortality) or the Socrata tools (everything else), then walks discover → inspect → baseline → compare → synthesize

Features

Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.

CDC-specific:

  • The Socrata SODA API v2.1 over the CDC Open Data portal (~1,080 datasets); no auth required, and an optional app token raises rate limits

  • CDC WONDER mortality data from five databases covering 1999 through the current year, reached over its XML request API

  • The three Socrata tools take a domain input, limited to data.cdc.gov (default) and chronicdata.cdc.gov; both serve the same catalog

  • category and tags must match the catalog's own values (categories case-sensitively, tags case-insensitively); cdc_list_catalog_vocabulary lists them

  • Socrata returns every value as a string, and a column like year is numeric in some datasets and text in others. Match WHERE literals to the column's dataType: numbers bare, strings single-quoted

Agent-friendly output:

  • Paging is reported explicitly: totalCount, truncated, nextOffset, and shown/cap. Both query tools cap each page at 200,000 characters, so a wide page can end short of limit

  • Typed errors with a recovery hint on every declared reason, such as not_queryable, page_out_of_range, and invalid_query

  • Upstream gaps stay visible: WONDER status tokens in cellNotes, hidden-row notices in messages, and rowCountSource on schema row counts

  • effectiveQuery echoes the SoQL clauses or a WONDER query summary, so a result can be reproduced

Getting started

Public Hosted Instance

A public instance is available at https://cdc.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:

{
  "mcpServers": {
    "cdc-health-mcp-server": {
      "type": "streamable-http",
      "url": "https://cdc.caseyjhand.com/mcp"
    }
  }
}

Self-Hosted / Local

Add the following to your MCP client configuration file.

{
  "mcpServers": {
    "cdc-health-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/cdc-health-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Or with npx (no Bun required):

{
  "mcpServers": {
    "cdc-health-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/cdc-health-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Or with Docker:

{
  "mcpServers": {
    "cdc-health-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/cdc-health-mcp-server:latest"]
    }
  }
}

For Streamable HTTP, set the transport and start the server:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp

Prerequisites

Installation

  1. Clone the repository:

git clone https://github.com/cyanheads/cdc-health-mcp-server.git
  1. Navigate into the directory:

cd cdc-health-mcp-server
  1. Install dependencies:

bun install
  1. Configure environment:

cp .env.example .env
# optionally set CDC_APP_TOKEN

Configuration

Variable

Description

Default

CDC_APP_TOKEN

Socrata app token; raises rate limits.

none

CDC_BASE_URL

SODA host for requests with no domain (the cdc://datasets/{datasetId} resource).

https://data.cdc.gov

CDC_CATALOG_URL

Socrata Discovery API base URL.

https://api.us.socrata.com/api/catalog/v1

MCP_TRANSPORT_TYPE

Transport: stdio or http.

stdio

MCP_HTTP_PORT

HTTP server port.

3010

MCP_SESSION_MODE

HTTP session mode: stateless, stateful, or auto.

stateless

MCP_AUTH_MODE

Authentication: none, jwt, or oauth.

none

MCP_LOG_LEVEL

Log level (debug, info, warning, error, etc.).

info

OTEL_ENABLED

Enable OpenTelemetry.

false

See .env.example for the full list of optional overrides.

Running the server

Local development

  • Build and run the production version:

    # One-time build
    bun run rebuild
    
    # Run the built server
    bun run start:http
    # or
    bun run start:stdio
  • Run checks and tests:

    bun run devcheck  # Lints, formats, type-checks, and more
    bun run test      # Runs the test suite

Docker

docker build -t cdc-health-mcp-server .
docker run --rm -p 3010:3010 cdc-health-mcp-server

The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/cdc-health-mcp-server. OpenTelemetry peer dependencies are installed by default; build with --build-arg OTEL_ENABLED=false to omit them.

Project structure

Directory

Purpose

src/index.ts

createApp() entry point — registers tools/resources/prompts and inits services.

src/config

Server-specific environment variable parsing and validation with Zod.

src/mcp-server/tools

Tool definitions (*.tool.ts). Four Socrata tools and one WONDER tool.

src/mcp-server/resources

Resource definitions. Catalog overview and dataset detail.

src/mcp-server/prompts

Prompt definitions. Health trend analysis workflow.

src/services/socrata

Socrata service — catalog search, vocabularies, metadata, SoQL queries.

src/services/wonder

CDC WONDER service — XML request builder, response parser, request spacing.

src/utils

Shared helpers — HTML-to-text, table-cell escaping, vocabulary matching, response budget.

tests/

Unit and integration tests mirroring src/.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic

  • Use ctx.log for logging, ctx.state for storage

  • Register new tools and resources in the createApp() arrays in src/index.ts

  • Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields

Contributing

Issues are welcome. Run checks and tests before submitting:

bun run devcheck
bun run test

License

Apache-2.0 — see LICENSE for details.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides access to 73 CDC public health datasets covering disease surveillance, vaccination tracking, behavioral risk factors, environmental health, and outbreak detection across 18 surveillance systems through the Socrata Open Data API.
    2
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables searching and querying Orlando Open Data datasets via Socrata SoQL, providing access to metadata and data rows through natural language or direct tool calls.
    23 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to query U.S. public-health datasets such as disease surveillance, mortality, behavioral risk factors, and flu activity through the Socrata API, using natural language or direct tool calls.
    14 npm
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI clients to search and read over 2,400 New York City public datasets through the Socrata SODA API, with ready-made tools for restaurant health inspections and 311 service requests plus general dataset discovery and querying.
    4
    MIT