An MCP (Model Context Protocol) server written in Go that enables LLMs like Claude to discover and learn about recreation opportunities by integrating three public REST APIs:
- National Park Service API - Information about national parks, activities, alerts, and campgrounds
- Recreation.gov API - Recreation areas, facilities, and campsites across federal lands
- OpenWeatherMap API - Current weather and forecasts for outdoor locations
- Features
- MCP Tools
- Prerequisites
- Quick Start
- Example Queries
- Project Structure
- Configuration
- Development
- Architecture
- Performance
- Security
- Troubleshooting
- Contributing
- Roadmap
- Support
- License
- Acknowledgments
- Search and explore national parks across the United States
- Find campgrounds and recreation facilities
- Get weather information for planning outdoor activities
- Query parks by state, activity, or keyword
- Check park alerts and closures
- Discover recreation areas and detailed facility information
- Easy deployment via Docker and docker-compose
- Seamless integration with Claude Desktop
This server provides 9 tools for exploring recreation opportunities:
Search for national parks by name, state, or activity.
Inputs:
query(optional): Search textstate(optional): Two-letter state code (e.g., "CA", "CO")activity(optional): Activity name (e.g., "Hiking", "Camping")limit(optional): Maximum results (default: 10)
Example: "Search for parks in California"
Get detailed information about a specific park including hours, fees, activities, and directions.
Inputs:
park_code(required): Four-letter park code (e.g., "yose" for Yosemite)
Example: "Tell me about Yosemite National Park"
Get current alerts, closures, and important notices for a park.
Inputs:
park_code(required): Four-letter park code
Example: "Are there any alerts for Grand Canyon?"
Search for campgrounds in national parks or recreation areas.
Inputs:
park_code(optional): NPS park codestate(optional): State codequery(optional): Search textlimit(optional): Maximum results (default: 10)
Example: "Find campgrounds near Yellowstone"
Search recreation areas on Recreation.gov across federal lands.
Inputs:
query(optional): Search textstate(optional): State codeactivity(optional): Activity namelimit(optional): Maximum results (default: 10)
Example: "Show me recreation areas in Utah with hiking"
Get detailed information about a specific facility (campground, day-use area, etc.).
Inputs:
facility_id(required): Recreation.gov facility ID
Example: "Tell me about facility 234567"
Get current weather conditions for a location.
Inputs:
latitude(required): Latitude coordinatelongitude(required): Longitude coordinateunits(optional): "metric" or "imperial" (default: "imperial")
Example: "What's the weather at 44.4280, -110.5885?" (Yellowstone coordinates)
Get 5-day weather forecast for a location.
Inputs:
latitude(required): Latitude coordinatelongitude(required): Longitude coordinateunits(optional): "metric" or "imperial" (default: "imperial")
Example: "What's the weather forecast for Rocky Mountain National Park?"
List all available activities across NPS and Recreation.gov.
Inputs:
source(optional): "nps", "recreation_gov", or "all" (default: "all")limit(optional): Maximum results (default: 50)
Example: "What activities are available in national parks?"
- API Keys - Free API keys from:
- National Park Service - Get an NPS API key
- Recreation.gov (RIDB) - Register for RIDB API access
- OpenWeatherMap - Sign up for a free API key
You can run this MCP server in two ways:
- Docker and Docker Compose (Install Docker)
- No Go installation required
- Easiest setup and most portable
- Isolated environment
- Go 1.24+ installed on your system
- Direct execution without containerization
- Faster startup time
- Better for development
- Visit https://www.nps.gov/subjects/developer/get-started.htm
- Click "Get An API Key"
- Fill out the form with your email
- You'll receive your API key immediately via email
- Visit https://ridb.recreation.gov/
- Click "Obtain an API Key"
- Register with your email address
- Your API key will be sent to your email
- Visit https://openweathermap.org/api
- Click "Sign Up" and create a free account
- Go to API Keys section in your account
- Copy your default API key (or create a new one)
git clone https://github.com/adhocteam/recreation-mcp-server.git
cd recreation-mcp-serverCopy the example environment file and add your API keys:
cp .env.example .env
# Edit .env and add your API keysBuild and run:
docker-compose build
docker-compose upConfigure Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"recreation": {
"command": "docker",
"args": [
"compose",
"-f",
"/path/to/recreation-mcp-server/docker-compose.yml",
"run",
"--rm",
"mcp-recreation-server"
]
}
}
}Replace /path/to/recreation-mcp-server with the actual path to this repository.
Build and run:
go build -o recreation-mcp-server
./recreation-mcp-serverConfigure Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"recreation": {
"command": "/path/to/recreation-mcp-server/recreation-mcp-server",
"env": {
"NPS_API_KEY": "your-nps-api-key",
"RIDB_API_KEY": "your-ridb-api-key",
"OPENWEATHER_API_KEY": "your-openweather-api-key"
}
}
}
}Replace /path/to/recreation-mcp-server with the actual path to this repository and add your API keys.
-
Install Go 1.24+
go version # Verify installation -
Clone and setup
git clone https://github.com/adhocteam/recreation-mcp-server.git cd recreation-mcp-server go mod download -
Set up environment
cp .env.example .env # Edit .env and add your API keys
# Build the binary
go build -o mcp-server ./cmd/server
# Build for specific OS/architecture
GOOS=linux GOARCH=amd64 go build -o mcp-server-linux ./cmd/server
GOOS=darwin GOARCH=arm64 go build -o mcp-server-darwin ./cmd/server# Run all unit tests
make test
# or
go test -v -race ./...
# Run with coverage
make test-coverage
# or
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
# Check coverage percentage
go tool cover -func=coverage.out | grep total
# Run specific package tests
go test -v ./internal/api/...
# Run with verbose output
go test -v -run TestSearchParks ./internal/api/Coverage Requirements:
- Minimum threshold: 25% (enforced in CI to prevent regression)
- Target coverage: 70% (see Contributing section for roadmap)
- CI will fail if coverage drops below the minimum threshold
- Always check coverage locally before pushing:
make test-coverage
# Make sure .env file exists with your API keys
go run ./cmd/server
# With debug logging
LOG_LEVEL=debug go run ./cmd/server# Format code
make fmt
# or
go fmt ./...
# Run linter
make lint
# or
golangci-lint run
# Run all pre-commit checks
make pre-commitThe project includes a Makefile with common development tasks:
make help # Show all available commands
make build # Build the binary
make test # Run tests
make test-coverage # Generate coverage report
make lint # Run linter
make clean # Clean build artifacts
make run # Run the server locally
make docker-build # Build Docker image
make pre-commit # Run all pre-commit checks
make ci-check # Simulate CI environment locally- Create feature branch:
git checkout -b feature/my-feature - Write tests first (TDD approach recommended)
- Implement feature
- Run tests and linter:
make pre-commit - Update documentation as needed
- Submit pull request
For local development testing with Claude Desktop, you can run the server directly without Docker:
- Build the binary:
make build - Update Claude Desktop config to use the binary directly:
{ "mcpServers": { "recreation": { "command": "/absolute/path/to/recreation-mcp-server/mcp-server" } } } - Restart Claude Desktop
Enable debug logging to see detailed API requests and responses:
LOG_LEVEL=debug go run ./cmd/serverDebug output includes:
- API request URLs and parameters
- Response status codes and timing
- Cache hit/miss information
- Error stack traces
Once integrated with Claude Desktop, you can ask questions like:
- "What national parks are in Colorado?"
- "Tell me about Yosemite National Park"
- "What are the operating hours and entrance fees for Grand Canyon?"
- "Which parks offer rock climbing activities?"
- "Show me parks in California with camping"
- "Are there any alerts or closures for Grand Canyon?"
- "What should I know before visiting Yellowstone?"
- "Are there any fire restrictions at Yosemite?"
- "Find campgrounds near Yellowstone"
- "What campgrounds are available in Acadia National Park?"
- "Show me recreation areas in Utah with hiking"
- "Find facilities with RV hookups in Colorado"
- "What's the current weather at Rocky Mountain National Park?"
- "What's the 5-day forecast for Yosemite?"
- "Should I expect rain at Grand Canyon this week?"
- "What activities are available in national parks?"
- "Which parks are best for photography?"
- "Where can I go kayaking in federal recreation areas?"
Claude can combine multiple tools to answer complex questions:
- "Find me a campground in a California national park with good weather this weekend"
- "Which Colorado parks are open now and what's the weather like?"
- "I want to go hiking in Utah - what are my options and should I be aware of any alerts?"
recreation-mcp-server/
├── cmd/
│ └── server/ # Main application entry point
├── internal/
│ ├── mcp/ # MCP server implementation
│ ├── api/ # API clients (NPS, Recreation.gov, Weather)
│ ├── models/ # Data models
│ ├── cache/ # Response caching
│ └── config/ # Configuration management
├── pkg/
│ └── util/ # Utility functions
├── test/
│ ├── fixtures/ # Test data
│ └── integration/ # Integration tests
├── spec/ # Project specification
├── Dockerfile # Container definition
├── docker-compose.yml # Container orchestration
└── README.md # This file
The server can be configured through environment variables or an optional config.yaml file. See .env.example for available options.
- NPS_API_KEY - National Park Service API key (required)
- RECREATION_GOV_API_KEY - Recreation.gov API key (required)
- OPENWEATHER_API_KEY - OpenWeatherMap API key (required)
- LOG_LEVEL - Logging level: debug, info, warn, error (default: info)
- CACHE_ENABLED - Enable response caching (default: true)
- CACHE_TTL_SECONDS - Cache time-to-live in seconds (default: 3600)
- MAX_REQUESTS_PER_MINUTE - Rate limiting (default: 60)
Problem: Container exits immediately or fails to start
Solutions:
- Verify API keys are set in
.envfile:cat .env - Check Docker logs:
docker-compose logs -f - Ensure .env file is in the correct location (project root)
- Verify Go version matches requirement:
docker build --no-cache .
Problem: Claude doesn't see the MCP server or can't connect
Solutions:
- Verify the absolute path in
claude_desktop_config.jsonis correct - Restart Claude Desktop completely after configuration changes
- Check that docker-compose runs successfully:
docker-compose run --rm mcp-recreation-server - Look for errors in Claude Desktop Developer Tools (Help → Show Logs)
- Ensure Docker daemon is running
Config file locations:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
Problem: Tools return errors or no data
Solutions:
- Verify your API keys are valid and active
- Check API rate limits haven't been exceeded (common with free tiers)
- Test API keys manually:
# Test NPS API curl "https://developer.nps.gov/api/v1/parks?limit=1&api_key=YOUR_KEY" # Test Recreation.gov API curl -H "apikey: YOUR_KEY" "https://ridb.recreation.gov/api/v1/recareas?limit=1" # Test OpenWeather API curl "https://api.openweathermap.org/data/2.5/weather?lat=35&lon=-106&appid=YOUR_KEY"
- Ensure network connectivity to external APIs (check firewall/proxy)
- Review server logs for specific error messages:
docker-compose logs
Problem: Queries return empty results
Solutions:
- Check if search parameters are too restrictive
- Verify state codes are two-letter abbreviations (e.g., "CA" not "California")
- Some activities might not have associated data
- Check API responses in debug logs:
LOG_LEVEL=debug docker-compose up
Problem: Slow responses or timeouts
Solutions:
- Check cache is enabled:
CACHE_ENABLED=truein .env - Verify network connectivity and latency to external APIs
- Review cache TTL settings (default: 1 hour)
- Check system resources:
docker stats
Problem: Docker build fails
Solutions:
- Clear Docker cache:
docker-compose build --no-cache - Verify Go version in Dockerfile matches go.mod requirement
- Check internet connectivity for downloading dependencies
- Ensure sufficient disk space
- Enable debug logging:
LOG_LEVEL=debugin your .env file - Check the logs:
docker-compose logs -f - Review Docker documentation: See DOCKER.md
- Open an issue on GitHub with:
- Error messages from logs
- Steps to reproduce
- Environment details (OS, Docker version)
┌─────────────────┐
│ Claude Desktop │ User interacts with Claude
│ (MCP Client) │
└────────┬────────┘
│ MCP Protocol (stdio)
▼
┌─────────────────────────────────┐
│ Recreation MCP Server (Go) │
│ ┌─────────────────────────┐ │
│ │ MCP Protocol Handler │ │ Handles tool calls
│ └──────────┬──────────────┘ │
│ │ │
│ ┌──────────▼──────────────┐ │
│ │ Tool Implementations │ │ 9 recreation tools
│ │ ┌──────────────────┐ │ │
│ │ │ Cache Layer │ │ │ LRU cache with TTL
│ │ └──────────────────┘ │ │
│ │ ┌──────────────────┐ │ │
│ │ │ API Clients │ │ │ HTTP clients
│ │ │ - NPS │ │ │ with retry logic
│ │ │ - Recreation.gov│ │ │
│ │ │ - OpenWeather │ │ │
│ │ └──────────────────┘ │ │
│ └─────────────────────────┘ │
└─────────────────────────────────┘
│ HTTPS
▼
┌─────────────────────────────────┐
│ External REST APIs │
│ - api.nps.gov │
│ - ridb.recreation.gov │
│ - api.openweathermap.org │
└─────────────────────────────────┘
- MCP Server (
internal/mcp/): Handles MCP protocol communication - API Clients (
internal/api/): HTTP clients for external APIs with retry logic - Cache Layer (
internal/cache/): LRU cache with configurable TTL - Configuration (
internal/config/): Environment-based configuration - Models (
internal/models/): Shared data structures - Utilities (
pkg/util/): HTTP client, logging, and helper functions
- Go Language: Fast, compiled, excellent concurrency support, small binary size
- MCP Protocol: Enables direct integration with Claude and other AI assistants
- Docker Deployment: Portable, consistent environment, easy to deploy
- Caching Strategy: Reduces API calls, improves response times, respects rate limits
- Security First: Non-root container, read-only filesystem, no privilege escalation
- Response Time: Typically < 2 seconds for cached requests, < 5 seconds for API calls
- Caching: 1-hour TTL reduces redundant API calls by ~80%
- Concurrency: Handles multiple concurrent requests efficiently
- Binary Size: ~20MB optimized binary
- Container Size: ~30MB runtime container
- Memory Usage: ~50MB baseline, scales with cache size
- Runs as non-root user (UID 1000)
- Read-only root filesystem
- No new privileges allowed
- Minimal attack surface (Alpine-based)
- Stored in environment variables (never in code)
- Not logged or exposed in responses
- Loaded from .env file (excluded from git)
- Should use secrets management in production
- HTTPS only for external API calls
- Certificate validation enabled
- Configurable timeouts prevent hanging
Contributions are welcome! Here's how you can help:
- Check existing issues first
- Provide detailed description
- Include error messages and logs
- Specify environment details
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Ensure all tests pass (
make test) - Run linter (
make lint) - Commit your changes (
git commit -m 'Add amazing feature') - Push to your branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow Go best practices and idioms
- Maintain test coverage above minimum threshold (see coverage requirements below)
- Document exported functions and packages
- Update README for user-facing changes
- Keep commits atomic and well-described
- Review
AGENTS.mdfor project conventions and patterns
Current Status:
- Overall coverage: ~25%
- Minimum threshold: 25% (enforced in CI)
- Target coverage: 70%
Coverage by Package:
internal/config: 94.3% ✅internal/cache: 45.7%internal/api: 27.2%internal/mcp: 0.0%⚠️ pkg/util: 0.0%⚠️
Roadmap to 70% Coverage:
- Phase 1 (Target: ~50-60%): Add comprehensive handler tests for
internal/mcp - Phase 2 (Target: ~60-70%): Add utility package tests for
pkg/util - Phase 3 (Target: 70%+): Add integration tests and improve API client coverage
Before Submitting PRs:
- Check coverage locally:
make test-coverage - Ensure your changes don't decrease overall coverage
- Add tests for new features and bug fixes
- Aim for 70%+ coverage on new code
- All PRs require review before merging
- CI checks must pass (automated via GitHub Actions)
- Branches must be up to date with
mainbefore merging - Maintain backward compatibility
- Consider performance implications
The main branch is protected with the following requirements:
- ✅ All status checks must pass:
- Test - Full test suite (34 tests)
- Lint - golangci-lint with zero issues
- Build - Successful compilation
- ✅ Branches must be up to date before merging
- ✅ Pull request reviews required
These protections ensure code quality and prevent broken code from reaching production.
Future enhancements being considered:
- Real-time campsite availability checking
- Trail information and difficulty ratings
- Photo gallery integration
- Distance calculations between locations
- Multi-language support
- Webhook notifications for alerts
- GraphQL API option
- Prometheus metrics exporter
- Advanced caching strategies (Redis option)
- Documentation: See DOCKER.md for Docker-specific help
- Issues: Report bugs on GitHub Issues
- Discussions: Ask questions in GitHub Discussions
- Updates: Watch the repository for updates
MIT License - see LICENSE file for details.
- Inspired by nps-explorer-mcp-server by Kyle-Ski
- Built with the Model Context Protocol (MCP)
- Uses Go MCP SDK
- Powered by Go, Docker, and open data APIs
- National Park Service: Data provided by the NPS API
- Recreation.gov: Recreation Information Database (RIDB) from Recreation.gov
- OpenWeatherMap: Weather data from OpenWeatherMap
