snowstorm-mcp-server

kaihempel/snowstorm-mcp-server

3.2

If you are the rightful owner of snowstorm-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

The Snowstorm MCP Server is a Model Context Protocol server designed to integrate seamlessly with SNOMED CT terminology services, enabling AI applications to perform various operations using standardized FHIR protocols.

Tools
4
Resources
0
Prompts
0

Snowstorm MCP Server

Node.js Version License: MIT

Model Context Protocol (MCP) server for the Snowstorm SNOMED CT Terminology Server FHIR API.

Provides seamless integration between MCP clients and SNOMED CT terminology services, enabling AI applications to perform concept lookups, validate codes, and expand value sets using standardized FHIR operations.

Features

šŸŽÆ Core Functionality

  • Concept Lookup: Look up SNOMED CT concepts by code with full property details
  • Code Validation: Validate codes exist in SNOMED CT or specific ValueSets
  • ValueSet Expansion: Expand ValueSets using ECL, ISA relationships, or reference sets
  • Language Support: Multi-language display names via displayLanguage parameter

šŸ—ļø Robust Infrastructure

  • Error Handling: Automatic HTTP → MCP error mapping with actionable messages
  • Retry Logic: Exponential backoff for transient errors (3 retries max)
  • Connection Pooling: HTTP keep-alive for optimal performance
  • 4-Level Logging: File-based logging (critical, warning, info, debug)
  • Comprehensive Tests: 130+ tests with 80% coverage target

⚔ Performance

  • 30-second timeout for simple operations
  • 60-second timeout for complex expansions
  • Connection pooling (max 50 sockets, 10 free sockets)
  • Async logging for high-volume operations

Quick Start

Prerequisites

  • Node.js >= 18.0.0
  • Running Snowstorm server (default: http://localhost:8080)
  • Snowstorm loaded with SNOMED CT data

Installation

# Clone the repository
git clone <repository-url>
cd snowstorm-mcp-server

# Install dependencies
npm install

# Run tests to verify setup
npm test

# Validate MVP
node validate-mvp.js

Running the Server

# Start the MCP server
npm start

# With custom Snowstorm URL
SNOWSTORM_URL=https://snowstorm.example.com npm start

# With custom log directory
LOG_DIR=/var/log/snowstorm-mcp npm start

Available Tools

CodeSystem Operations

codesystem_lookup

Look up a SNOMED CT concept by code to retrieve its display name, properties, and designations.

Parameters:

  • code (required): SNOMED CT concept code (e.g., "404684003")
  • system (optional): Code system URI (default: http://snomed.info/sct)
  • version (optional): System version
  • displayLanguage (optional): Language for display (e.g., "en", "es", "de")
  • property (optional): Array of properties to include (e.g., ["parent", "child"])

Example:

{
  "code": "404684003"
}

Returns: FHIR Parameters resource with concept details

codesystem_validate_code

Validate that a code exists in SNOMED CT and retrieve its display name.

Parameters:

  • code (required): SNOMED CT concept code
  • system (optional): Code system URI
  • version (optional): System version
  • displayLanguage (optional): Language preference

Example:

{
  "code": "73211009",
  "displayLanguage": "en"
}

Returns: FHIR Parameters resource with validation result (boolean) and display name

ValueSet Operations

valueset_expand

Expand a SNOMED CT ValueSet using ECL (Expression Constraint Language), ISA relationships, or reference sets.

Parameters:

  • url (required): ValueSet URL (canonical or implicit with ECL/ISA/refset)
  • valueSetVersion (optional): ValueSet version
  • filter (optional): Text filter for searching concepts
  • count (optional): Maximum number of concepts to return (default: 100, max: 1000)
  • offset (optional): Offset for pagination (default: 0)
  • displayLanguage (optional): Language preference

Examples:

ECL expression (all descendants of Body structure):

{
  "url": "http://snomed.info/sct?fhir_vs=ecl/<<27624003",
  "count": 50
}

ISA relationship (Kidney structure and children):

{
  "url": "http://snomed.info/sct?fhir_vs=isa/64033007"
}

Reference set:

{
  "url": "http://snomed.info/sct?fhir_vs=refset/447562003"
}

Returns: FHIR ValueSet resource with expansion.contains[] array

valueset_validate_code

Check if a code is a member of a ValueSet.

Parameters:

  • url (required): ValueSet URL
  • code (required): SNOMED CT concept code to validate
  • system (optional): Code system URI
  • version (optional): System version
  • displayLanguage (optional): Language preference

Example:

{
  "url": "http://snomed.info/sct?fhir_vs=ecl/<<27624003",
  "code": "27624003"
}

Returns: FHIR Parameters resource with validation result

Configuration

Environment Variables

VariableDescriptionDefault
SNOWSTORM_URLSnowstorm server URLhttp://localhost:8080
LOG_DIRLog file directory./logs

Log Files

Logs are written to the configured LOG_DIR directory:

  • critical.log: Server startup failures, unhandled exceptions (sync write)
  • warning.log: Retried requests, rate limits, slow operations (sync write)
  • info.log: Tool calls, request/response summaries, metrics (async write)
  • debug.log: Detailed request/response bodies, parameters (async write)

All log entries are JSON-formatted with ISO 8601 timestamps.

Development

Project Structure

snowstorm-mcp-server/
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ server.js                       # MCP server entry point
│   ā”œā”€ā”€ lib/                            # Foundational infrastructure
│   │   ā”œā”€ā”€ constants.js                # Configuration constants
│   │   ā”œā”€ā”€ logger.js                   # 4-level file logging
│   │   ā”œā”€ā”€ error-handler.js            # Error mapping
│   │   ā”œā”€ā”€ snowstorm-client.js         # HTTP client
│   │   └── tool-schemas.js             # JSON Schema definitions
│   └── tools/                          # MCP tool implementations
│       ā”œā”€ā”€ codesystem-lookup.js
│       ā”œā”€ā”€ codesystem-validate-code.js
│       ā”œā”€ā”€ valueset-expand.js
│       └── valueset-validate-code.js
ā”œā”€ā”€ tests/
│   ā”œā”€ā”€ unit/                           # Unit tests (mocked)
│   └── integration/                    # Integration tests (MSW)
ā”œā”€ā”€ docs/                               # Snowstorm API documentation
ā”œā”€ā”€ logs/                               # Log files (gitignored)
└── validate-mvp.js                     # MVP validation script

Testing

# Run tests in watch mode
npm test

# Run tests once
npm run test:run

# Run tests with UI
npm run test:ui

# Run tests with coverage report
npm run test:coverage

Test Statistics:

  • 130+ tests across 9 test files
  • Unit tests for all foundational modules
  • Integration tests with MSW for HTTP mocking
  • Error scenario coverage for network errors, invalid inputs, server errors

Adding New Tools

  1. Create a new tool file in src/tools/
  2. Define the tool schema in src/lib/tool-schemas.js
  3. Implement the tool handler function
  4. Register the tool in src/server.js
  5. Write comprehensive tests following TDD workflow
  6. Update documentation

Example tool structure:

import { createMyToolSchema } from '../lib/tool-schemas.js';

export async function myToolHandler(args, client) {
  // Build request parameters
  // Execute Snowstorm API call
  // Return FHIR resource
}

export function register(registerTool) {
  const schema = createMyToolSchema();
  registerTool(schema, myToolHandler);
}

SNOMED CT Concepts

ECL (Expression Constraint Language)

ECL is a formal language for defining sets of SNOMED CT concepts based on their relationships and attributes.

Common ECL patterns:

  • <<27624003 - All descendants of Body structure
  • <64033007 - Direct children of Kidney structure
  • >>138875005 - All ancestors of SNOMED CT Concept
  • * - All active concepts

ISA Relationships

ISA relationships define hierarchical "is-a" relationships between concepts.

Example: "Diabetes mellitus (73211009) is-a Disease (64572001)"

Reference Sets

Reference sets group related concepts for specific purposes (e.g., clinical findings, procedures).

Error Handling

The server automatically handles and maps errors:

HTTP StatusMCP Error CodeDescription
400-32602Invalid parameters
404-32001Resource not found
429-32000Rate limit exceeded (retryable)
500-32603Internal server error
503-32000Server unavailable (retryable)

Network errors (ECONNREFUSED, ETIMEDOUT, ENOTFOUND) are automatically retried with exponential backoff.

Performance Considerations

  • Keep-Alive Connections: Reduces latency by reusing TCP connections
  • Connection Pooling: Maintains up to 50 concurrent connections
  • Exponential Backoff: 1s → 2s → 4s delays for retries
  • Timeout Configuration: 30s for simple operations, 60s for expansions
  • Async Logging: Non-blocking writes for INFO/DEBUG levels

Troubleshooting

Server won't start

  1. Check Snowstorm is running: curl http://localhost:8080/fhir/metadata
  2. Verify Node.js version: node --version (should be >= 18.0.0)
  3. Check logs in ./logs/critical.log

Tests failing

  1. Run npm install to ensure dependencies are up-to-date
  2. Check for conflicting ports
  3. Review test logs for specific failures

Connection errors

  1. Verify SNOWSTORM_URL is correct
  2. Check network connectivity to Snowstorm server
  3. Review retry logs in ./logs/warning.log

Contributing

  1. Follow the existing code structure and patterns
  2. Write tests BEFORE implementation (TDD workflow)
  3. Maintain 80% test coverage
  4. Use ESLint for code quality
  5. Update documentation for new features

License

MIT License - see LICENSE file for details

Resources

Support

For issues, questions, or contributions, please refer to the project repository.