national-parks-mcp-server

v0.3.0 pre-1.0

Plan US National Park Service trips — find parks, check alerts and closures, find campgrounds, browse things to do and events via the NPS Data API. STDIO or Streamable HTTP.

national-parks.caseyjhand.com/mcp
claude mcp add --transport http national-parks-mcp-server https://national-parks.caseyjhand.com/mcp
codex mcp add national-parks-mcp-server --url https://national-parks.caseyjhand.com/mcp
{
  "mcpServers": {
    "national-parks-mcp-server": {
      "url": "https://national-parks.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http national-parks-mcp-server https://national-parks.caseyjhand.com/mcp
{
  "mcpServers": {
    "national-parks-mcp-server": {
      "command": "bunx",
      "args": [
        "mcp-remote",
        "https://national-parks.caseyjhand.com/mcp"
      ]
    }
  }
}
{
  "mcpServers": {
    "national-parks-mcp-server": {
      "type": "http",
      "url": "https://national-parks.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://national-parks.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

6

nps_find_parks

open-world

Resolve a place name, US state, or free-text query to National Park Service parks — the required first step before the detail tools. Returns each park's parkCode (the key nps_get_park, nps_get_alerts, nps_find_campgrounds, nps_get_activities, and nps_find_events all use) plus a compact trip-planning summary (designation, states, description, coordinates, headline activities, entrance fee, NPS page). Coverage is US NPS sites only — national parks, monuments, historic sites, seashores — not state parks and not Forest Service or BLM land.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "nps_find_parks",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "description": "Free-text search across park names and descriptions (e.g. \"yosemite\", \"civil war\", \"redwood\"). Exact parkCode or name matches lead, then other name matches, then parks that only mention the term in their description — ranked across every match before start/limit apply. Omit to browse by state. At least one of query or stateCode is recommended; with neither, returns the first page of all ~470 NPS sites.",
      "type": "string"
    },
    "stateCode": {
      "description": "Two-letter US state/territory code, or comma-separated list (e.g. \"CA\", \"WY,MT,ID\"). Filters to parks located in those states. Combine with query to narrow.",
      "type": "string"
    },
    "activity": {
      "description": "Filter to parks offering an activity, matched against each park's activities list (e.g. \"hiking\", \"camping\", \"stargazing\"). Case-insensitive substring match, combined with query/stateCode and applied before start/limit, so totalCount counts every matching park, not one page. Use nps_get_park to see a park's full activity list.",
      "type": "string"
    },
    "limit": {
      "default": 10,
      "description": "Maximum parks to return (1–50). The full set is ~470 sites; narrow with query/stateCode rather than paging through everything.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    },
    "start": {
      "default": 0,
      "description": "Zero-based offset for pagination within the matched set. Use with limit to page through results.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "limit",
    "start"
  ],
  "additionalProperties": false
}
view source ↗

nps_get_park

open-world

Full trip-planning detail for one or more parks by parkCode: description, activities and topics, entrance fees and passes, operating hours by area/season, contacts, directions, a free-text weather overview, representative images, and the NPS page for everything else. Get codes from nps_find_parks. Accepts up to ten codes per call. Use the fields parameter to return only the sections you need.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "nps_get_park",
    "arguments": {
      "parkCode": "<parkCode>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "parkCode": {
      "minItems": 1,
      "maxItems": 10,
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "One to ten park codes per call, each a 4-letter lowercase code (e.g. \"yose\", \"grca\", \"zion\"). Get codes from nps_find_parks."
    },
    "fields": {
      "description": "Optional detail sections to include beyond the always-present core (name, designation, states, description, coordinates, weather, url). Omit for all sections. Narrow to reduce payload when you only need, say, hours and fees.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "activities",
          "topics",
          "fees",
          "hours",
          "contacts",
          "directions",
          "images"
        ]
      }
    }
  },
  "required": [
    "parkCode"
  ],
  "additionalProperties": false
}
view source ↗

nps_get_alerts

open-world

Current alerts for a park or a whole state — closures, hazards, caution notices, and information — with category and recency surfaced first so "is anything closed at Glacier right now?" is answered at a glance. Get park codes from nps_find_parks, or pass a stateCode for a statewide "what's closed" sweep. Returns most-recent-first. An empty result with totalCount 0 means no active alerts match the request (with category or query set, alerts outside that filter may still be active); an empty page with a non-zero totalCount means start ran past the end of the matches. Closures and road conditions change daily.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "nps_get_alerts",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "parkCode": {
      "description": "Park code, or comma-separated list (e.g. \"glac\", \"yose,zion\") — 4-letter lowercase codes. Get codes from nps_find_parks. Provide parkCode or stateCode; with neither, returns recent alerts service-wide.",
      "type": "string"
    },
    "stateCode": {
      "description": "Two-letter state code, or comma-separated list (e.g. \"MT\", \"WY,MT,ID\"). Returns alerts for all NPS sites in those states — use for a statewide sweep rather than one park.",
      "type": "string"
    },
    "category": {
      "description": "Filter to one alert category. \"Danger\" and \"Park Closure\" are trip-affecting. Combined with parkCode/stateCode/query and applied before start/limit, so totalCount counts every matching alert, not one page. Omit to see all categories.",
      "type": "string",
      "enum": [
        "Danger",
        "Caution",
        "Information",
        "Park Closure"
      ]
    },
    "query": {
      "description": "Free-text search within alert titles/descriptions (e.g. \"road\", \"wildfire\", \"trail\").",
      "type": "string"
    },
    "limit": {
      "default": 20,
      "description": "Maximum alerts to return (1–50), most-recent first.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    },
    "start": {
      "default": 0,
      "description": "Zero-based offset for pagination within the matched set. Use with limit to page through results — when totalCount exceeds what was returned, re-request with start advanced by limit.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "limit",
    "start"
  ],
  "additionalProperties": false
}
view source ↗

nps_find_campgrounds

open-world

Campgrounds at a park or across a state: amenities (potable water, showers, RV dump station, toilets, trash collection, RV access), reservable vs. first-come-first-served site counts, reservation guidance and booking URL, accessibility, and fees. Check the linked campground page for RV hookups and date-specific availability. Get park codes from nps_find_parks. Some parks list lodging or backcountry permits instead of NPS-managed campgrounds; an empty result is not an error.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "nps_find_campgrounds",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "parkCode": {
      "description": "Park code, or comma-separated list (e.g. \"zion\") — 4-letter lowercase codes. Get codes from nps_find_parks. Provide parkCode or stateCode.",
      "type": "string"
    },
    "stateCode": {
      "description": "Two-letter state code, or comma-separated list. Returns campgrounds across all NPS sites in those states.",
      "type": "string"
    },
    "query": {
      "description": "Free-text search across campground names/descriptions (e.g. \"river\", \"group\", \"rv\").",
      "type": "string"
    },
    "limit": {
      "default": 15,
      "description": "Maximum campgrounds to return (1–50).",
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    },
    "start": {
      "default": 0,
      "description": "Zero-based pagination offset.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "limit",
    "start"
  ],
  "additionalProperties": false
}
view source ↗

nps_get_activities

open-world

Curated things to do and points of interest at a park — title, description, time commitment, location, accessibility, and fee/pet/reservation flags — answering "what should I do at Acadia?" Covers the NPS editorially-curated activity list (distinct from a park's raw activity tags in nps_get_park). Accepts a single 4-letter park code or a single two-letter state code, and at least one is required. Not every park has a curated list; an empty result is not an error.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "nps_get_activities",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "parkCode": {
      "description": "A single 4-letter lowercase park code (e.g. \"acad\"). Get it from nps_find_parks. Accepts one park code, not a list. Provide parkCode or stateCode.",
      "type": "string"
    },
    "stateCode": {
      "description": "A single two-letter state code (e.g. \"ME\"). Returns curated activities across NPS sites in that state.",
      "type": "string"
    },
    "query": {
      "description": "Free-text search across activity titles/descriptions (e.g. \"sunrise\", \"hike\", \"tour\").",
      "type": "string"
    },
    "limit": {
      "default": 15,
      "description": "Maximum activities to return (1–50).",
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    },
    "start": {
      "default": 0,
      "description": "Zero-based pagination offset.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "limit",
    "start"
  ],
  "additionalProperties": false
}
view source ↗

nps_find_events

open-world

Scheduled events at a park within a date range — ranger programs, festivals, tours, interpretive events — answering "what's happening at Yellowstone this weekend?" with title, dates and times, location, category, fee, and registration links. Get park codes from nps_find_parks. Paginates by page number, not offset. Many parks list few or no events; an empty result is not an error.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "nps_find_events",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "parkCode": {
      "description": "Park code, or comma-separated list (e.g. \"yell\") — 4-letter lowercase codes. Get codes from nps_find_parks. Provide parkCode or stateCode.",
      "type": "string"
    },
    "stateCode": {
      "description": "Two-letter state code, or comma-separated list (e.g. \"WY\", \"WY,MT,ID\"). Returns events across NPS sites in those states.",
      "type": "string"
    },
    "dateStart": {
      "description": "Start of the date window (YYYY-MM-DD). Combine with dateEnd to bound the search (e.g. a weekend). Omit for upcoming events from today.",
      "type": "string"
    },
    "dateEnd": {
      "description": "End of the date window (YYYY-MM-DD). Use with dateStart.",
      "type": "string"
    },
    "query": {
      "description": "Free-text search across event titles/descriptions (e.g. \"ranger\", \"astronomy\", \"guided\").",
      "type": "string"
    },
    "pageSize": {
      "default": 15,
      "description": "Maximum events to return per page (1–50). Paginates by page number, not offset — use with pageNumber to walk through results.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    },
    "pageNumber": {
      "default": 1,
      "description": "1-based page number. Increment to page through results beyond the first page.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "pageSize",
    "pageNumber"
  ],
  "additionalProperties": false
}
view source ↗

Extensions

1

io.modelcontextprotocol/skills

{
  "directoryRead": true
}