Look up elevation worldwide, profile route ascent/descent, grid areas, check terrain line of sight via MCP. STDIO or Streamable HTTP.
- ✓Open-source license (Apache-2.0)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
git clone https://github.com/cyanheads/elevation-mcp-server{
"mcpServers": {
"elevation": {
"command": "node",
"args": ["/path/to/elevation-mcp-server/dist/index.js"]
}
}
}MCP Servers overview
<div align="center">
<h1>@cyanheads/elevation-mcp-server</h1>
<p><b>Look up elevation worldwide, profile route ascent/descent, grid areas, check terrain line of sight via MCP. STDIO or Streamable HTTP.</b>
<div>4 Tools</div>
</p>
</div>
<div align="center">
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/elevation-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/elevation-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
</div>
<div align="center">
[](https://github.com/cyanheads/elevation-mcp-server/releases/latest/download/elevation-mcp-server.mcpb) [](https://cursor.com/en/install-mcp?name=elevation-mcp-server&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjeWFuaGVhZHMvZWxldmF0aW9uLW1jcC1zZXJ2ZXIiXX0=) [](https://vscode.dev/redirect?url=vscode:mcp/install?%7B%22name%22%3A%22elevation-mcp-server%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40cyanheads%2Felevation-mcp-server%22%5D%7D)
[](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
</div>
<div align="center">
**Public Hosted Server:** [https://elevation.caseyjhand.com/mcp](https://elevation.caseyjhand.com/mcp)
</div>
---
## Overview
Ground elevation and terrain analysis from two keyless sources: USGS 3DEP across the US and its territories (plus much of Canada and Mexico), and Open Topo Data everywhere else, which answers from SRTM GL1 v3 and, where SRTM has no tile, Mapzen terrain tiles. Look up spot heights, measure a route's ascent, descent, and grades, find an area's high and low points, and check whether terrain blocks a sightline. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
### Tools
| Tool | Description |
|:---|:---|
| `elevation_get_points` | Ground elevation at 1–100 coordinates, in meters and feet, with the dataset and resolution behind each value |
| `elevation_get_profile` | Sample a route at evenly spaced points and summarize distance, ascent, descent, elevation range, and steepest grades |
| `elevation_get_grid` | Sample a node grid over a bounding box and report its highest and lowest points, mean elevation, and relief |
| `elevation_check_line_of_sight` | Decide whether terrain blocks the sightline between two points, with earth curvature and refraction, and check first Fresnel zone clearance for radio links |
## Capability reference
### `elevation_get_points` <sub>tool</sub>
- `points`: 1–100 `{lat, lon}` objects in decimal degrees (WGS84)
- Each point comes back `ok` or `no_data` (a miss never fails the call), with `elevation_m` / `elevation_ft`, `dataset`, and `resolution_m` (omitted for `mapzen`); 3DEP answers add `raster_id` and `acquisition_date`. `points_with_data` counts the hits
---
### `elevation_get_profile` <sub>tool</sub>
- `path`: 2–1,000 vertices in travel order (consecutive duplicates dropped); `samples`: 2–250 evenly spaced points along it, endpoints included (default 100)
- `summary` carries `total_distance_m`, `ascent_m` / `descent_m` (and feet), start, end, min, and max elevation, `highest_point` / `lowest_point`, and `max_grade_pct` / `min_grade_pct` with where each occurs; ascent depends on the reported `sample_interval_m`. Fails as `degenerate_path` (under 1 m of route) or `no_coverage` (no sample has data)
- `include_samples` (default `true`) returns `samples[]` (distance, position, elevation, grade, dataset, and resolution per sample); `false` omits it and the sample table, and the rest of the result is unchanged
---
### `elevation_get_grid` <sub>tool</sub>
- `south`, `west`, `north`, `east` edges in decimal degrees (a box can't cross longitude 180); `rows` and `cols` 2–25 each (default 10), with `rows × cols` at most 250
- `elevations_m` and `cell_datasets` matrices indexed `[row][col]` (row 0 north, column 0 west, `null` without data), plus `summary.highest`, `summary.lowest`, `mean_elevation_m`, and `relief_m`. Fails as `invalid_bbox`, `too_many_cells`, or `no_coverage`
- Nodes are point samples with the edges included, not cell averages
---
### `elevation_check_line_of_sight` <sub>tool</sub>
- `observer` and `target` points, at most 1,000 km apart; `observer_height_m` (default 1.7) and `target_height_m` (default 0), each 0–10,000 m above ground; `earth_model` `flat`, `geometric`, `optical` (default, κ 0.13), or `radio` (κ 0.25); `samples` 3–250 (default 100); optional `water_surface_m` (-500 to 9,000) and `frequency_mhz` (30–300,000)
- `verdict` is `clear`, `blocked`, or `indeterminate` (samples without data leave the line unconfirmed), with `min_clearance_m` / `min_clearance_ft`, the `limiting_point`, and the `first_obstruction` when blocked. Fails as `same_endpoints` (under 1 m apart), `sightline_too_long` (over 1,000 km apart), or `endpoint_no_data`
- `frequency_mhz` adds `fresnel`: a `sufficient`, `insufficient`, or `indeterminate` verdict against the 60% free-space bar of the first Fresnel zone, `min_clearance_ratio` (clearance over zone radius), and the sample that limits it, which is often not `limiting_point`
- Terrain only: buildings and vegetation count only as far as the elevation source captures them. Where Mapzen reports sea-floor depth, clearance is measured to the sea surface; USGS 3DEP values below 0 m (bay floor in some bays, or dry land) count as received unless `water_surface_m` sets a water level, which then applies to every sample
---
### Failures shared by every tool
| Reason | Code | When |
|:---|:---|:---|
| `usgs_unavailable` | `ServiceUnavailable` | USGS 3DEP did not answer or rejected the request; `data.retryable` says whether retrying can help |
| `opentopodata_unavailable` | `ServiceUnavailable` | Open Topo Data did not answer, rejected the request, or sent an unusable response; `data.retryable` as above |
| `opentopodata_rate_limited` | `RateLimited` | Open Topo Data kept answering HTTP 429, or asked for a wait over 8 s; `data.retryAfter` in seconds when it sent one of at most a day |
| `opentopodata_daily_limit` | `RateLimited` | Public instance only: this server already sent 1,000 requests in the trailing 24 hours, so none was sent; `data.retryAfter` is the seconds until a slot frees |
| `opentopodata_config_rejected` | `ConfigurationError` | The instance at `OPENTOPODATA_BASE_URL` answered 401, 403, or 404, redirected (self-hosted only; never followed), lacks `srtm30m` or `mapzen`, caps locations below 100, or answered from a dataset this server didn't request; the operator must fix it |
| `sampling_deadline_exceeded` | `Timeout` | The 45 s sampling budget ran out (`data.provider` names the provider it was waiting on), or other calls' queued USGS 3DEP lookups left no time for this call's, so it sent none and `data.retryAfter` is the seconds until they drain |
A coverage miss is never an error: that point has no data. Any provider failure fails the whole call with no partial result.
## Features
Built on [`@cyanheads/mcp-ts-core`](https://github.com/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.
Elevation-specific:
- `source` on every tool: `auto` (default) queries USGS 3DEP inside its coverage and sends 3DEP misses and everything outside it to Open Topo Data; `usgs_3dep` and `opentopodata` pin one provider. Only a coverage miss falls back, never an outage
- Open Topo Data answers from SRTM GL1 v3 (about 30 m, land between 60°N and 56°S), then Mapzen terrain tiles where SRTM has no tile: high latitudes, Antarctica, and ocean bathymetry
- Per-call caps of 100 points or 250 samples or grid cells, inside a 45 s sampling budget; each 3DEP point is its own request (6 concurrent, 10 per second), while Open Topo Data takes 100 points per request
- The public Open Topo Data instance is paced under its published limits: one request at a time, starts at least 1.1 s apart, at most 1,000 in any trailing 24 hours per server process
- Profiles, grids, and sightlines are computed locally from point samples, with great-circle distances and resampling and earth curvature with standard refraction
Agent-friendly output:
- Provenance on every value: each point, profile sample, grid cell, and sightline point names its `dataset` (`usgs_3dep`, `srtm30m`, `mapzen`) and, except for Mapzen, its `resolution_m` (`resolution_m_range` on profiles and grids); computed results add `datasets_used` counts, and a `Sources:` line credits every dataset that answered
- Absent stays absent: a point or sample without data omits its elevation and a grid cell is `null`, never 0; summaries report how many values had data
- Notices flag what changes interpretation: results mixing 3DEP and Open Topo Data, Mapzen values below 0What people ask about elevation-mcp-server
What is cyanheads/elevation-mcp-server?
+
cyanheads/elevation-mcp-server is mcp servers for the Claude AI ecosystem. Look up elevation worldwide, profile route ascent/descent, grid areas, check terrain line of sight via MCP. STDIO or Streamable HTTP. It has 1 GitHub stars and its last recorded update is dated 2026-10-02.
How do I install elevation-mcp-server?
+
You can install elevation-mcp-server by cloning the repository (https://github.com/cyanheads/elevation-mcp-server) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is cyanheads/elevation-mcp-server safe to use?
+
Our security agent has analyzed cyanheads/elevation-mcp-server and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.
Who maintains cyanheads/elevation-mcp-server?
+
cyanheads/elevation-mcp-server is maintained by cyanheads. The last recorded GitHub activity is dated 2026-10-02, with 0 open issues.
Are there alternatives to elevation-mcp-server?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy elevation-mcp-server to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/cyanheads-elevation-mcp-server)<a href="https://claudewave.com/repo/cyanheads-elevation-mcp-server"><img src="https://claudewave.com/api/badge/cyanheads-elevation-mcp-server" alt="Featured on ClaudeWave: cyanheads/elevation-mcp-server" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
The fastest path to AI-powered full stack observability, even for lean teams.