national-parks-mcp-server

v0.1.1 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.

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 "MCP-Protocol-Version: 2025-11-25" \
  -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\"). 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",
      "pattern": "^[A-Za-z]{2}(,[A-Za-z]{2})*$"
    },
    "activity": {
      "description": "Filter to parks offering an activity, matched against each park's activities list (e.g. \"hiking\", \"camping\", \"stargazing\"). Case-insensitive substring match applied locally after fetch — it narrows the returned page, it does not search all ~470 sites by activity. 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. Up to ten codes are fetched in a single request. Use the fields parameter to trim the payload when you only need certain sections.

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",
        "pattern": "^[a-z]{4}$"
      },
      "description": "One to ten park codes (each a 4-letter lowercase code like \"yose\", \"grca\", \"zion\"). Get codes from nps_find_parks. Multiple codes are fetched in a single request."
    },
    "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 means the park reports nothing closed or hazardous, which is good news, not an error. Closures and road conditions change daily — re-check before departure.

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\"). Get codes from nps_find_parks. Provide parkCode or stateCode; with neither, returns recent alerts service-wide.",
      "type": "string",
      "pattern": "^[a-z]{4}(,[a-z]{4})*$"
    },
    "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",
      "pattern": "^[A-Za-z]{2}(,[A-Za-z]{2})*$"
    },
    "category": {
      "description": "Filter to one alert category. \"Danger\" and \"Park Closure\" are the high-priority ones for trip safety. Omit to see all categories (the default — closures and hazards should not be missed).",
      "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
    }
  },
  "required": [
    "limit"
  ],
  "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 — answering "where can I camp at Zion, and can I get an RV hookup?" 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\"). Get codes from nps_find_parks. Provide parkCode or stateCode.",
      "type": "string",
      "pattern": "^[a-z]{4}(,[a-z]{4})*$"
    },
    "stateCode": {
      "description": "Two-letter state code, or comma-separated list. Returns campgrounds across all NPS sites in those states.",
      "type": "string",
      "pattern": "^[A-Za-z]{2}(,[A-Za-z]{2})*$"
    },
    "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",
      "pattern": "^[a-z]{4}$"
    },
    "stateCode": {
      "description": "A single two-letter state code (e.g. \"ME\"). Returns curated activities across NPS sites in that state.",
      "type": "string",
      "pattern": "^[A-Za-z]{2}$"
    },
    "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. The events feed is sparser and less consistent than alerts or campgrounds; many parks list few or no events, and 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\"). Get codes from nps_find_parks. Provide parkCode or stateCode.",
      "type": "string",
      "pattern": "^[a-z]{4}(,[a-z]{4})*$"
    },
    "stateCode": {
      "description": "Two-letter state code, or comma-separated list. Returns events across NPS sites in those states.",
      "type": "string",
      "pattern": "^[A-Za-z]{2}(,[A-Za-z]{2})*$"
    },
    "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",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "dateEnd": {
      "description": "End of the date window (YYYY-MM-DD). Use with dateStart.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "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 ↗