A Model Context Protocol (MCP) server that exposes structured outdoor intelligence through typed tools. The server aggregates data from multiple external providers (parks, weather, air quality), validates inputs and outputs, and returns deterministic JSON responses suitable for automated and human evaluation.
The server acts as a controlled execution layer between language models and external environmental data providers, enforcing strict contracts, predictable behavior, and operational safeguards such as retries, rate limiting, and error normalization.
- Scope
- Data Providers
- Available MCP Tools
- Installation
- Configuration
- Development and Testing
- Error Model
- Project Structure
- Extending
- Contributing
- Acknowledgments
This MCP server provides a unified interface for:
- National park and location metadata
- Safety and operational alerts
- Environmental conditions (weather, air quality)
- Contextual summaries derived from multiple data sources
All functionality is exposed via MCP tools with strict input/output schemas.
- National Park Service (NPS)
The official national data source of the United States National Park Service, providing Authoritative park data including parks, alerts, visitor centers, campgrounds, and events.
Configured via
NPS_API_KEY.
- Open-Meteo (default; no API key required)
- OpenWeather (optional; API-key based)
Provider selection strategy:
If OPENWEATHER_API_KEY is configured, the server attempts OpenWeather first and falls back to Open-Meteo on provider failure.
Provides AQI and pollutant data. Requires AIRVISUAL_API_KEY.
If the key is not configured, air-quality requests return a structured configuration error.
Search parks by state, keywords, and activities.
Retrieve a full park profile.
Retrieve visitor center data for a park.
Retrieve campground data for a park.
Retrieve park-related events.
Retrieve active alerts and warnings.
Return a condensed context object combining park metadata, alerts, and safety information.
Retrieve live weather conditions.
Retrieve air-quality indices and pollutant data.
All tools:
- Validate inputs using Pydantic models
- Return structured JSON only
- Surface errors in a consistent machine-readable format
- Python 3.10+
- Poetry (recommended) or pip
git clone https://github.com/ester-bloch/Outdoor-Parks-Intelligence-MCP.git
cd Outdoor-Parks-Intelligence-MCP
poetry installgit clone https://github.com/ester-bloch/Outdoor-Parks-Intelligence-MCP.git
cd Outdoor-Parks-Intelligence-MCP
python -m venv .venv
pip install -e .- Generate API keys from:
NPS_API_KEY(required) — National Park ServiceOPENWEATHER_API_KEY(optional) — OpenWeatherAIRVISUAL_API_KEY(optional) — IQAir / AirVisual
-
Copy the example environment file:
cp .env.example .env
-
Edit
.envand set the configuration values:# Required NPS_API_KEY=your_nps_api_key_here # Optional (enable air quality) AIRVISUAL_API_KEY=your_airvisual_api_key_here # Optional (prefer OpenWeather; otherwise Open-Meteo is used) OPENWEATHER_API_KEY=your_openweather_api_key_here
poetry run python -m src.mainpython -m src.mainThe server runs over stdio, per MCP conventions.
poetry run pytest
poetry run pytest --cov=src --cov-report=html
poetry run pytest tests/unit/
poetry run pytest tests/integration/
poetry run pytest tests/property/poetry run black src tests
poetry run isort src tests
poetry run flake8 src tests
poetry run mypy srcpre-commit run --all-files
pre-commit run black
pre-commit run mypyAll errors are returned as structured JSON objects and categorized as:
- Input validation errors
- Missing or invalid configuration
- Upstream provider HTTP errors
- Network and timeout failures
No free-text or implicit error responses are produced.
developer 2/
├── docs/
│ └── claude_desktop_config.json
├── scripts/
│ └── demo.py
├── src/
│ ├── api/
│ │ ├── __init__.py
│ │ ├── air_quality.py
│ │ ├── client.py
│ │ ├── rate_limit.py
│ │ ├── retry.py
│ │ └── weather.py
│ ├── handlers/
│ │ ├── __init__.py
│ │ ├── find_parks.py
│ │ ├── get_air_quality.py
│ │ ├── get_alerts.py
│ │ ├── get_campgrounds.py
│ │ ├── get_events.py
│ │ ├── get_park_context.py
│ │ ├── get_park_details.py
│ │ ├── get_visitor_centers.py
│ │ └── get_weather.py
│ ├── models/
│ │ ├── __init__.py
│ │ ├── errors.py
│ │ ├── external.py
│ │ ├── requests.py
│ │ └── responses.py
│ ├── utils/
│ │ ├── __init__.py
│ │ ├── error_handler.py
│ │ ├── formatters.py
│ │ ├── geo.py
│ │ └── logging.py
│ ├── __init__.py
│ ├── config.py
│ ├── constants.py
│ ├── main.py
│ └── server.py
├── tests/
│ ├── integration/
│ │ ---
│ ├── property/
│ │ ---
│ ├── unit/
│ │ ---
│ ├── __init__.py
│ └── conftest.py
├── .env.example
├── .flake8
├── .gitignore
├── .pre-commit-config.yaml
├── poetry.lock
├── pyproject.toml
├── requirements-dev.txt
└── requirements.txt
Key conventions:
src/api/contains provider clients plus resilience primitives (retry / rate limit).src/handlers/contains the MCP tool implementations (one file per tool).src/models/defines request/response schemas and the normalized error model.tests/is split by test intent (unit / integration / property).- Generated artifacts (e.g.,
__pycache__/,*.pyc) are development by-products and should not be versioned.
- Implement the client in
src/api/ - Register configuration keys in
.env.example - Integrate via a handler without cross-provider coupling
- Implement logic in
src/handlers/ - Define schemas in
src/models/ - Register the tool in
server.py
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and ensure code quality
- Submit a pull request
- Built with FastMCP
- Data provided by: