Skip to main content
Glama

AllTrails MCP Client

A Model Context Protocol (MCP) server and Python package for searching hiking trails from AllTrails.com. Includes smart caching to avoid rate limiting.

āš ļø Important: Rate Limiting

AllTrails.com implements CAPTCHA and rate limiting. This package includes a caching system to minimize requests:

  • āœ… Cache-first: Stores up to 15 trails per park for 7 days

  • šŸ”„ Automatic refresh: Updates cache after expiration

  • šŸ’¾ SQLite storage: Local database (trails_cache.db)

  • 🚫 Use sparingly: Best for personal, low-volume usage

Features

  • 🄾 Search trails by US National Park (all 63 parks supported)

  • šŸ“ Get detailed trail information

  • šŸ’¾ Smart caching system (7-day cache)

  • šŸ¤– MCP server for Claude Desktop integration

  • šŸ› ļø CLI tools for quick searches

  • šŸ Python API for programmatic access

Installation

From PyPI (when published)

pip install alltrails-mcp

Development Install

git clone https://github.com/dbrown540/alltrails-mcp-client.git
cd alltrails-mcp-client
pip install -e .

Quick Start

Python API

from alltrails_mcp import NationalPark, search_trails_with_cache

# Search with automatic caching
trails = search_trails_with_cache(NationalPark.YOSEMITE.value)

for trail in trails[:5]:
    print(f"{trail['name']} - {trail['difficulty']} - {trail['length']}")

CLI

# Search trails
alltrails-search search us/california/yosemite-national-park --limit 5

# Get trail details
alltrails-search details us/california/half-dome-trail

# Show cache info and location
alltrails-search cache

# Clear the cache
alltrails-search cache --clear

# View current configuration
alltrails-search config

# Set cache expiration to 14 days
alltrails-search config --set-cache-days 14

MCP Server (Claude Desktop)

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "alltrails": {
      "command": "/path/to/.venv/bin/python",
      "args": ["/path/to/alltrails-mcp-client/src/alltrails_mcp/server.py"],
      "env": {
        "ALLTRAILS_CACHE_DAYS": "14"
      }
    }
  }
}

Optional environment variables:

  • ALLTRAILS_CACHE_DAYS: Cache expiration in days (default: 7)

Then ask Claude: "Find trails in Yosemite National Park"

National Parks

All 63 US National Parks are available via the NationalPark enum:

from alltrails_mcp import NationalPark, get_park_slug, list_parks

# Use enum
park = NationalPark.YOSEMITE
slug = park.value  # 'us/california/yosemite-national-park'

# Look up by name
slug = get_park_slug("Yellowstone")

# List all parks
all_parks = list_parks()

See PARKS_SUMMARY.md for complete list.

Cache Management

from alltrails_mcp import TrailCache

cache = TrailCache()

# Get cache info
info = cache.get_cache_info()
print(f"Parks cached: {info['total_parks']}")

# Clear specific park
cache.clear_cache("us/california/yosemite-national-park")

# Clear entire cache
cache.clear_cache()

# Force refresh (bypass cache)
from alltrails_mcp import search_trails_with_cache
trails = search_trails_with_cache(park_slug, force_refresh=True)

# Use custom cache location
from pathlib import Path
custom_cache = TrailCache(db_path=Path("/custom/path/cache.db"))

# Use custom cache expiration (e.g., 14 days)
custom_cache = TrailCache(cache_days=14)

Cache Location:

  • Linux/macOS: ~/.cache/alltrails-mcp/trails_cache.db

  • Fallback: ~/.alltrails_mcp/trails_cache.db

  • Custom: Pass db_path to TrailCache()

Cache Expiration Configuration:

Cache expiration can be configured in multiple ways with the following priority:

  1. Programmatic (highest priority): Pass cache_days=14 to TrailCache()

  2. Environment variable: Set ALLTRAILS_CACHE_DAYS=14

  3. Saved configuration: Use CLI command alltrails-search config --set-cache-days 14

  4. Default: 7 days

# Set cache expiration persistently via CLI
alltrails-search config --set-cache-days 14

# View current configuration
alltrails-search config

# Override via environment variable
export ALLTRAILS_CACHE_DAYS=30

Configuration is saved to ~/.cache/alltrails-mcp/config.json and persists across sessions.

The cache is automatically managed - users don't need to interact with it directly unless they want to clear it or customize the location/expiration.

Examples

See the examples/ directory:

  • demo.py - Simple demonstration of key features

Run with:

python examples/demo.py --park ZION
python examples/demo.py --stats
python examples/demo.py --clear-cache

Project Structure

alltrails-mcp-client/
ā”œā”€ā”€ src/alltrails_mcp/      # Main package
│   ā”œā”€ā”€ __init__.py          # Package exports
│   ā”œā”€ā”€ scraper.py           # AllTrails scraping logic
│   ā”œā”€ā”€ cache.py             # SQLite caching system
│   ā”œā”€ā”€ parks.py             # National Park enums
│   ā”œā”€ā”€ server.py            # MCP server
│   └── cli.py               # Command-line interface
ā”œā”€ā”€ examples/                # Example scripts
ā”œā”€ā”€ pyproject.toml          # Package configuration
└── README.md               # This file

API Reference

Core Functions

search_trails_in_park(park_slug: str) -> List[Dict]

  • Search for trails (no caching)

  • Returns: List of trail dictionaries

search_trails_with_cache(park_slug: str, cache=None, force_refresh=False, limit=15) -> List[Dict]

  • Search with automatic caching

  • Returns cached data if valid (<7 days old)

get_trail_by_slug(slug: str) -> Dict

  • Get detailed trail information

  • Example slug: us/tennessee/alum-cave-trail

Trail Dictionary Format

{
    "name": "Half Dome Trail",
    "url": "https://www.alltrails.com/trail/...",
    "summary": "Experience this 14.2-mile...",
    "difficulty": "Hard",
    "length": "14.2 mi",
    "rating": "4.8"
}

Publishing to PyPI

See PUBLISHING.md for detailed instructions.

Quick steps:

# Build
python -m build

# Upload
twine upload dist/*

License

MIT License - See LICENSE.md

Acknowledgments

Disclaimer

This tool scrapes publicly available data from AllTrails. Use responsibly and respect AllTrails' terms of service. The caching system helps minimize requests.