kaihempel/snowstorm-mcp-server
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.
Snowstorm MCP Server
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 versiondisplayLanguage
(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 codesystem
(optional): Code system URIversion
(optional): System versiondisplayLanguage
(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 versionfilter
(optional): Text filter for searching conceptscount
(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 URLcode
(required): SNOMED CT concept code to validatesystem
(optional): Code system URIversion
(optional): System versiondisplayLanguage
(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
Variable | Description | Default |
---|---|---|
SNOWSTORM_URL | Snowstorm server URL | http://localhost:8080 |
LOG_DIR | Log 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
- Create a new tool file in
src/tools/
- Define the tool schema in
src/lib/tool-schemas.js
- Implement the tool handler function
- Register the tool in
src/server.js
- Write comprehensive tests following TDD workflow
- 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 Status | MCP Error Code | Description |
---|---|---|
400 | -32602 | Invalid parameters |
404 | -32001 | Resource not found |
429 | -32000 | Rate limit exceeded (retryable) |
500 | -32603 | Internal server error |
503 | -32000 | Server 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
- Check Snowstorm is running:
curl http://localhost:8080/fhir/metadata
- Verify Node.js version:
node --version
(should be >= 18.0.0) - Check logs in
./logs/critical.log
Tests failing
- Run
npm install
to ensure dependencies are up-to-date - Check for conflicting ports
- Review test logs for specific failures
Connection errors
- Verify
SNOWSTORM_URL
is correct - Check network connectivity to Snowstorm server
- Review retry logs in
./logs/warning.log
Contributing
- Follow the existing code structure and patterns
- Write tests BEFORE implementation (TDD workflow)
- Maintain 80% test coverage
- Use ESLint for code quality
- 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.