Programmatically access and parse NOAA Electronic Navigational Charts (ENC) in S-57 format.
An MCP (Model Context Protocol) server for Electronic Navigational Charts (ENC) data, providing programmatic access to NOAA electronic navigational charts with S-57 format parsing capabilities.
This MCP server enables AI assistants to access and analyze electronic navigational charts from NOAA. It automatically downloads, caches, and parses S-57 format chart data, making it available through a standardized API. The server supports coordinate-based chart discovery, feature extraction, and navigation-focused queries.
Install the MCP server globally via npm:
npm install -g enc-charts-mcp
The server requires GDAL Python bindings for S-57 chart parsing:
macOS:
# Using Homebrew
brew install gdal
pip3 install gdal==$(gdal-config --version)
Ubuntu/Debian:
sudo apt-get update
sudo apt-get install gdal-bin libgdal-dev
pip3 install gdal==$(gdal-config --version)
Windows:
# Using conda (recommended)
conda install -c conda-forge gdal
# Check if the server is installed
enc-charts-mcp --version
# Test GDAL availability
python3 -c "from osgeo import ogr; print('GDAL installed successfully')"
The server supports the following environment variables:
Variable | Description | Default |
---|---|---|
ENC_CACHE_DIR | Directory for chart cache | ./cache/charts/ |
ENC_CACHE_MAX_SIZE_GB | Maximum cache size in GB | 10 |
ENC_CACHE_MAX_AGE_DAYS | Cache expiration in days | 7 |
Add the following to your Claude Desktop configuration file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"enc-charts": {
"command": "npx",
"args": ["enc-charts-mcp"],
"transport": {
"type": "stdio"
},
"env": {
"ENC_CACHE_DIR": "~/.enc-charts/cache",
"ENC_CACHE_MAX_SIZE_GB": "20",
"ENC_CACHE_MAX_AGE_DAYS": "14"
}
}
}
}
Note: Adjust the cache directory path based on your preferences. The server will automatically create the directory if it doesn't exist.
After installation and configuration, restart Claude Desktop. You can then use the ENC charts tools in your conversations:
Find charts for a location:
Use the get_chart tool with coordinates:
lat: 37.8, lon: -122.5 (San Francisco Bay)
Search for charts in an area:
Use search_charts with a bounding box to find all charts
between San Diego and Los Angeles
Get navigation features:
Get all lights and buoys from chart US5CA12M
Retrieve chart features for a specific area by chart ID or coordinates.
Parameters:
chartId
(string, optional): Chart identifier (e.g., "US5CA12M")coordinates
(object, optional): GPS coordinates
lat
(number): Latitude (-90 to 90)lon
(number): Longitude (-180 to 180)boundingBox
(object, optional): Geographic bounds filter
minLat
, maxLat
, minLon
, maxLon
(numbers)featureTypes
(array, optional): S-57 object classes to includedepthRange
(object, optional): Depth filter in meters
min
, max
(numbers)includeNearby
(boolean, optional): Include nearby featureslimit
(integer, optional): Maximum features to return (default: 100, max: 1000)offset
(integer, optional): Number of features to skip for pagination (default: 0)Example Request:
{
"coordinates": { "lat": 37.8, "lon": -122.5 },
"featureTypes": ["LIGHTS", "BOYLAT", "DEPARE"],
"depthRange": { "min": 0, "max": 20 }
}
Example Response:
{
"chartId": "US5CA12M",
"features": [
{
"id": "LIGHTS.123",
"type": "LIGHTS",
"geometry": {
"type": "Point",
"coordinates": [-122.5295, 37.8156]
},
"properties": {
"COLOUR": ["1"],
"LITCHR": 8,
"SIGPER": 4,
"VALNMR": 18
}
}
],
"featureCount": 42,
"totalFeatures": 150,
"hasMore": true,
"limit": 100,
"offset": 0,
"source": "NOAA ENC"
}
Search available charts by various criteria.
Parameters:
query
(string, optional): Search by name or areascale
(object, optional): Scale range filter
min
, max
(numbers)boundingBox
(object, optional): Geographic search areaformat
(string, optional): Chart format ("S-57" or "S-101")limit
(integer, optional): Maximum charts to return (default: 50, max: 100)offset
(integer, optional): Number of charts to skip for pagination (default: 0)Get detailed information about a specific chart.
Parameters:
chartId
(string, optional): Chart identifiercoordinates
(object, optional): GPS coordinates to find chartGet information about S-57 object classes and their representations.
Parameters:
category
(string, optional): Filter by category
search
(string, optional): Search by acronym or descriptionincludeAttributes
(boolean, optional): Include standard attributesThe server integrates with NOAA's Electronic Navigational Chart services:
https://www.charts.noaa.gov/ENCs/ENCProdCat.xml
https://www.charts.noaa.gov/ENCs/
Charts are automatically downloaded on-demand when queried by coordinates and cached locally for performance. The XML catalog is cached for 24 hours to reduce API calls.
The server supports all 172 standard S-57 object classes. Key categories include:
LIGHTS
- All lighted aids (lighthouses, beacons, lit buoys)BOYLAT
- Lateral buoys (port/starboard markers)BOYSAW
- Safe water buoysBCNLAT
- Lateral beaconsDAYMAR
- Day marksDEPARE
- Depth areas with rangesDEPCNT
- Depth contour linesSOUNDG
- Individual soundingsDRGARE
- Dredged areasFAIRWY
- Navigation channelsANCHRG
- Anchorage areasRESARE
- Restricted areasTSSLPT
- Traffic separation schemesOBSTRN
- Underwater obstructionsWRECKS
- ShipwrecksROCKS
- Rocks and reefsfeatureTypes
to reduce response sizelimit
and offset
for large datasetsLIGHTS
, BOYLAT
, BOYSAW
, BCNLAT
DEPARE
, DEPCNT
, SOUNDG
OBSTRN
, WRECKS
, ROCKS
FAIRWY
, ANCHRG
, RESARE
Find charts and extract navigation aids for route planning:
// Get charts for Golden Gate area
{
"coordinates": { "lat": 37.8199, "lon": -122.4783 },
"featureTypes": ["LIGHTS", "BOYLAT", "BOYSAW", "BCNLAT"],
"includeNearby": true
}
Find suitable anchoring spots with depth information:
// Search for anchorages with specific depth range
{
"chartId": "US5CA12M",
"featureTypes": ["DEPARE", "ANCHRG", "SOUNDG"],
"depthRange": { "min": 5, "max": 15 },
"boundingBox": {
"minLat": 37.8,
"maxLat": 37.82,
"minLon": -122.52,
"maxLon": -122.5
}
}
Identify navigation hazards in an area:
// Get all hazards near a route
{
"coordinates": { "lat": 32.7157, "lon": -117.1611 },
"featureTypes": ["OBSTRN", "WRECKS", "ROCKS", "UWTROC"],
"includeNearby": true
}
Find all available charts for a region:
// Search charts between San Diego and Los Angeles
{
"boundingBox": {
"minLat": 32.5,
"maxLat": 34.0,
"minLon": -118.5,
"maxLon": -117.0
},
"scale": { "max": 50000 } // Detailed charts only
}
"GDAL Python bindings not found"
pip install gdal==$(gdal-config --version)
brew install gdal
"Failed to parse S-57 chart data"
python3 -c "from osgeo import ogr"
python3
)npm run gdal:validate
to check your installationServer not appearing in Claude
npm list -g enc-charts-mcp
npx enc-charts-mcp --version
"No charts found for coordinates"
Clearing the cache
# Default cache location
rm -rf ~/.enc-charts/cache/*
# Or your custom cache directory
rm -rf $ENC_CACHE_DIR/*
Disk space issues
ENC_CACHE_MAX_SIZE_GB
in your config# Clone the repository
git clone https://github.com/tonybentley/enc-charts-mcp.git
cd enc-charts-mcp
# Install dependencies
npm install
# Build the project
npm run build
# Run in development mode (with hot reload)
npm run dev
# Run production build
npm start
npm run dev
- Run in development mode with hot reloadnpm run build
- Build TypeScript to JavaScriptnpm run test
- Run unit testsnpm run test:e2e
- Run end-to-end testsnpm run test:all
- Run all test suitesnpm run lint
- Run ESLintnpm run typecheck
- Run TypeScript type checkingnpm run format
- Format code with Prettiernpm run gdal:detect
- Check if GDAL is properly installednpm run gdal:validate
- Validate GDAL installation and environmentnpm run test:integration:check
- Verify GDAL before running integration testsTo prevent response size issues, the get_chart
and search_charts
tools implement pagination:
Use the limit
and offset
parameters to page through large result sets:
// First page
{ "chartId": "US5CA12M", "limit": 100, "offset": 0 }
// Next page
{ "chartId": "US5CA12M", "limit": 100, "offset": 100 }
The response includes pagination metadata:
totalFeatures
or totalCount
: Total number of available itemshasMore
: Boolean indicating if more results existlimit
: Number of items returnedoffset
: Number of items skippedISC
The source code is available on GitHub.
Contributions are welcome! Please open an issue or submit a pull request on GitHub.
Integrates with Language Server Protocol (LSP) to provide features like code completion, diagnostics, and hover information.
Up-to-date Docs For Any Cursor Prompt
A code observability MCP enabling dynamic code analysis based on OTEL/APM data to assist in code reviews, issues identification and fix, highlighting risky code etc.
Remote server (SSE/Streamable) for the latest Svelte and SvelteKit documentation
Set up MCP servers in Claude Desktop
Execute shell commands without permission prompts.
Generate high-quality images using Google's Imagen 3.0 model via the Gemini API.
Converts LaTeX mathematical expressions to MathML format using MathJax-node.
A server for Zero-Vector's hybrid vector-graph persona and memory management system, featuring advanced LangGraph workflow capabilities.
A collection of reference implementations for Model Context Protocol (MCP) servers in Typescript and Python, demonstrating MCP features and SDK usage.