Sherpa MCP Server
A remote Model Context Protocol (MCP) server with Auth0 OAuth authentication, designed to act as your personal assistant. The server manages calendar events, tasks, notes, health data, and more.
Features
- 🔐 Secure Authentication: Auth0 OAuth 2.1 + OIDC with PKCE support
- 📅 Google Calendar: Full calendar management (list, create, update, delete events)
- ✅ TickTick: Task management (projects, tasks, completion tracking)
- 🍽️ Meal Logger: Track meals and nutrition with persistent storage
- 🏋️ Workout Tracker: Log and track a 50-day structured workout plan
- 💧 Water Tracker: Log daily water intake with goal progress
- 🛠️ MCP Tools: Test connection, echo messages, get server time, and more
- 🏥 Health Monitoring: Built-in health check and info endpoints
- 🌐 Remote Access: HTTP-based transport for remote connectivity
- 📦 Modular Design: Easy to extend with new tools and integrations
Current Status
✅ Phase 1 Complete: Basic MCP server with Auth0 OAuth authentication
- Remote MCP server with streamable-http transport
- Test connection tool for connectivity verification
- Health check and info custom endpoints
- Auth0 OAuth authentication (optional)
- Production-ready with secure defaults
✅ Phase 1.5 Complete: Docker & Railway deployment
- Docker containerization with health checks
- Railway one-click deployment support
- Production-ready deployment guides
✅ Phase 2 Complete: Google Calendar integration
- Full calendar CRUD operations
- Natural language event creation (quick add)
- Multi-calendar support
- See GOOGLE_CALENDAR_SETUP.md for setup
✅ Phase 3 Complete: TickTick integration
- Project (task list) management
- Task CRUD operations with priorities and due dates
- Task completion tracking
- See TICKTICK_SETUP.md for setup
✅ Phase 4 Complete: Meal Logger
- Log meals with description, type, time, and macros
- Daily nutrition summaries with macro totals
- Persistent storage using Railway volumes
- Configurable timezone support
✅ Phase 5 Complete: Workout Tracker
- Pure session log — no external plan dependency
- Structured session logging:
session_type, exercises with sets/reps/weight, free-formtags - Supports strength, cardio, HIIT, bodyweight, mobility, and rest sessions
- Progress summary with days trained, rest days logged, and average feel score
✅ Phase 6 Complete: Water Tracker
- Log water intake entries with amount (ml), optional timestamp, and notes
- Daily summary with total ml, entry count, goal progress percentage, and goal-met flag
- Configurable daily goal via
WATER_DAILY_GOAL_MLenv var (default: 1920ml) - Persistent storage using Railway volumes
🚧 Planned Integrations:
- Obsidian notes (filesystem synced with SyncThing)
- Health data management
Quick Start
Prerequisites
- Python 3.8 or higher
- Auth0 account (optional, for authentication)
- pip or uv for package management
Installation
- Clone the repository:
git clone <repository-url>
cd sherpa-mcp-server
- Create a virtual environment:
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
- Install dependencies:
pip install -r requirements.txt
- Configure environment variables:
cp .env.example .env
# Edit .env with your configuration
- Run the server:
python server.py
The server will start on http://localhost:8000 by default.
Configuration
Without Authentication (Development)
For local development without authentication:
# .env file - leave Auth0 variables commented out
SERVER_HOST=0.0.0.0
SERVER_PORT=8000
SERVER_BASE_URL=http://localhost:8000
Run the server: ``bash python server.py ``
With Auth0 Authentication (Production)
For production with Auth0:
- Set up Auth0 (see AUTH0_SETUP.md for detailed instructions)
- Configure environment variables in
.env:
AUTH0_CONFIG_URL=https://YOUR_DOMAIN.auth0.com/.well-known/openid-configuration
AUTH0_CLIENT_ID=your-client-id
AUTH0_CLIENT_SECRET=your-client-secret
AUTH0_AUDIENCE=https://api.your-app.com
SERVER_BASE_URL=https://your-server.com
- Run the server:
python server.py
Available Endpoints
MCP Protocol Endpoint
- POST
/mcp- Main MCP protocol endpoint (streamable-http transport)
Custom HTTP Endpoints
- GET
/- Root endpoint with server information - GET
/health- Health check for monitoring - GET
/info- Detailed server information
OAuth Endpoints (when Auth0 is enabled)
- GET
/.well-known/oauth-authorization-server- OAuth metadata - GET
/.well-known/oauth-protected-resource- Protected resource metadata - GET
/auth/callback- OAuth callback endpoint
Available Tools
The MCP server exposes the following tools to clients:
Core Tools
test_connection
Test the connection to the MCP server and get server status.
Returns: Connection status with timestamp and authentication info
echo
Echo back a message with optional formatting.
Parameters:
message(string, required): The message to echouppercase(boolean, optional): Convert to uppercaseprefix(string, optional): Prefix to add to the message
Returns: Formatted message
get_server_time
Get the current server time in ISO format.
Returns: Dictionary with local and UTC timestamps
Google Calendar Tools
Note: These tools require Google Calendar setup. See GOOGLE_CALENDAR_SETUP.md
calendar_list_calendars
List all Google Calendars accessible to the user.
Returns: List of calendars with ID, name, and access role
calendar_list_events
List upcoming events from Google Calendar.
Parameters:
calendar_id(string, optional): Calendar ID (default: "primary")max_results(int, optional): Maximum events to return (default: 10)days_ahead(int, optional): Days to look ahead (default: 7)query(string, optional): Search filter
Returns: List of events with details
calendar_get_event
Get details of a specific calendar event.
Parameters:
event_id(string, required): The event IDcalendar_id(string, optional): Calendar ID (default: "primary")
Returns: Full event details
calendar_create_event
Create a new event in Google Calendar.
Parameters:
summary(string, required): Event titlestart_time(string, required): Start time in ISO formatend_time(string, required): End time in ISO formatcalendar_id(string, optional): Calendar ID (default: "primary")description(string, optional): Event descriptionlocation(string, optional): Event locationattendees(string, optional): Comma-separated emailstime_zone(string, optional): Time zone (default: "UTC")all_day(boolean, optional): All-day event flag
Returns: Created event details
calendar_quick_add
Create an event using natural language description.
Parameters:
text(string, required): Natural language description (e.g., "Meeting with John tomorrow at 3pm")calendar_id(string, optional): Calendar ID (default: "primary")
Returns: Created event details
calendar_update_event
Update an existing calendar event.
Parameters:
event_id(string, required): Event ID to updatecalendar_id(string, optional): Calendar ID (default: "primary")summary(string, optional): New titlestart_time(string, optional): New start timeend_time(string, optional): New end timedescription(string, optional): New descriptionlocation(string, optional): New location
Returns: Updated event details
calendar_delete_event
Delete a calendar event.
Parameters:
event_id(string, required): Event ID to deletecalendar_id(string, optional): Calendar ID (default: "primary")
Returns: Deletion confirmation
TickTick Tools
Note: These tools require TickTick setup. See TICKTICK_SETUP.md
ticktick_list_projects
List all TickTick projects (task lists).
Returns: List of projects with ID, name, color, and view mode
ticktick_get_project
Get a specific project with all its tasks.
Parameters:
project_id(string, required): The project IDinclude_tasks(boolean, optional): Include tasks (default: true)
Returns: Project details and tasks
ticktick_create_project
Create a new project (task list).
Parameters:
name(string, required): Project namecolor(string, optional): Color in hex format (e.g., "#F18181")view_mode(string, optional): "list", "kanban", or "timeline" (default: "list")
Returns: Created project details
ticktick_delete_project
Delete a project.
Parameters:
project_id(string, required): Project ID to delete
Returns: Deletion confirmation
ticktick_get_task
Get a specific task.
Parameters:
project_id(string, required): The project ID containing the tasktask_id(string, required): The task ID
Returns: Task details
ticktick_create_task
Create a new task.
Parameters:
title(string, required): Task titleproject_id(string, required): Project ID to add the task tocontent(string, optional): Task content/notesdesc(string, optional): Description for checkliststart_date(string, optional): Start date in ISO formatdue_date(string, optional): Due date in ISO formattime_zone(string, optional): Time zone (default: "America/Los_Angeles")is_all_day(boolean, optional): All-day task flag (default: false)priority(int, optional): 0 (None), 1 (Low), 3 (Medium), 5 (High)
Returns: Created task details
ticktick_update_task
Update an existing task.
Parameters:
task_id(string, required): Task ID to updateproject_id(string, required): Project ID containing the tasktitle(string, optional): New titlecontent(string, optional): New contentstart_date(string, optional): New start datedue_date(string, optional): New due datepriority(int, optional): New priority
Returns: Updated task details
ticktick_complete_task
Mark a task as complete.
Parameters:
project_id(string, required): Project ID containing the tasktask_id(string, required): Task ID to complete
Returns: Completion confirmation
ticktick_delete_task
Delete a task.
Parameters:
project_id(string, required): Project ID containing the tasktask_id(string, required): Task ID to delete
Returns: Deletion confirmation
Workout Tracker Tools
Note: These tools require Railway volume setup. See RAILWAY_DEPLOYMENT.md
workout_log
Log a workout session with structured exercises.
Parameters:
session_type(string, required): One ofstrength,cardio,hiit,bodyweight,mobility,restdate(string, optional): Date in YYYY-MM-DD format (defaults to today)exercises(string, optional): JSON array of exercise objects (see examples below)tags(string, optional): Comma-separated grouping tags, e.g."phase-1,lower,gym"how_felt(int, optional): Energy/effort rating 1-5 (1=exhausted, 5=great)notes(string, optional): Free-text notes (e.g. modifications made, baby sleep quality)logged_at(string, optional): ISO datetime when workout occurred (defaults to now)
Exercise examples: ```json // Strength [{"exercise_type":"strength","name":"Back Squat","equipment":"barbell", "sets":[{"reps":8,"weight_lbs":125},{"reps":8,"weight_lbs":125}]}]
// Bodyweight / timed sets [{"exercise_type":"bodyweight","name":"Plank", "sets":[{"duration_seconds":60},{"duration_seconds":45}]}]
// Cardio [{"exercise_type":"cardio","name":"HIIT Circuit","duration_seconds":1500}]
// HIIT intervals [{"exercise_type":"hiit","name":"Tabata","rounds":4,"work_seconds":20,"rest_seconds":10}] ```
Returns: Created workout log entry with ID
workout_get_log
Get all logged workout entries for a date.
Parameters:
date(string, optional): Date in YYYY-MM-DD format (defaults to today)
Returns: All logged workout entries for that date
workout_list
List logged workout sessions with optional filters.
Parameters:
start_date(string, optional): Filter on or after this date (YYYY-MM-DD)end_date(string, optional): Filter on or before this date (YYYY-MM-DD)session_type(string, optional): Filter by type —strength,cardio,hiit,bodyweight,mobility,resttag(string, optional): Filter by a single tag value (e.g."phase-1","gym")limit(int, optional): Maximum results to return (default: 50)
Returns: List of logged workout entries
workout_update
Update an existing workout log entry. Pass the full updated exercises array to replace exercises.
Parameters:
workout_id(string, required): ID of the entry to updatesession_type(string, optional): New session typeexercises(string, optional): Full replacement JSON exercise arraytags(string, optional): New comma-separated tags (replaces existing)how_felt(int, optional): Updated feel rating 1-5notes(string, optional): Updated notes
Returns: Updated workout entry
workout_delete
Delete a workout log entry.
Parameters:
workout_id(string, required): ID of the entry to delete
Returns: Deletion confirmation
workout_progress
Get a summary of all logged sessions.
Returns: Summary including:
days_trained— non-rest sessions loggedrest_days_logged— rest/recovery days loggedavg_feel_score,first_session_date,last_session_date
Water Tracker Tools
Note: These tools require Railway volume setup. See RAILWAY_DEPLOYMENT.md
water_log
Log a water intake entry.
Parameters:
amount_ml(float, required): Amount consumed in millilitres (e.g. 250 for a glass, 500 for a bottle)logged_at(string, optional): ISO datetime when water was consumed (defaults to now)notes(string, optional): Optional label, e.g. "morning", "post-run", "with supplements"
Returns: Created entry with ID
water_get
Get a specific water intake entry by ID.
Parameters:
entry_id(string, required): The entry ID
Returns: Entry details
water_update
Update an existing water intake entry.
Parameters:
entry_id(string, required): ID of the entry to updateamount_ml(float, optional): New amount in millilitreslogged_at(string, optional): Updated ISO datetimenotes(string, optional): Updated notes
Returns: Updated entry details
water_delete
Delete a water intake entry.
Parameters:
entry_id(string, required): Entry ID to delete
Returns: Deletion confirmation
water_list
List water intake entries with optional date range filter.
Parameters:
start_date(string, optional): Filter on or after this date (YYYY-MM-DD)end_date(string, optional): Filter on or before this date (YYYY-MM-DD)limit(int, optional): Maximum results to return (default: 50)
Returns: List of entries sorted by time descending
water_daily_summary
Get water intake summary for a day.
Parameters:
date(string, optional): Date in YYYY-MM-DD format (defaults to today)
Returns: Daily summary including:
total_ml— total water consumedentry_count— number of entries loggedgoal_ml— daily goal (configurable viaWATER_DAILY_GOAL_ML, default 1920ml)goal_pct— percentage of goal reachedgoal_met— boolean whether goal was reachedentries— all entries for that day sorted chronologically
Meal Logger Tools
Note: These tools require Railway volume setup. See RAILWAY_DEPLOYMENT.md
meal_log
Log a new meal with description, type, time, and optional macros.
Parameters:
description(string, required): What you ate (e.g., "Grilled chicken salad with avocado")meal_type(string, required): Type of meal -breakfast,lunch,dinner, orsnacklogged_at(string, optional): ISO datetime when meal was eaten (defaults to now)calories(float, optional): Total caloriesprotein(float, optional): Protein in gramscarbs(float, optional): Carbohydrates in gramsfat(float, optional): Fat in gramsfiber(float, optional): Fiber in grams
Returns: Created meal details with ID
meal_list
List logged meals with optional filters.
Parameters:
meal_type(string, optional): Filter by type -breakfast,lunch,dinner, orsnackstart_date(string, optional): Filter meals on or after this ISO date (YYYY-MM-DD)end_date(string, optional): Filter meals on or before this ISO date (YYYY-MM-DD)limit(int, optional): Maximum number of meals to return (default: 50)
Returns: List of meals with details
meal_get
Get a specific meal by ID.
Parameters:
meal_id(string, required): The meal ID
Returns: Meal details
meal_update
Update an existing meal.
Parameters:
meal_id(string, required): ID of the meal to updatedescription(string, optional): New descriptionmeal_type(string, optional): New meal typelogged_at(string, optional): New ISO datetimecalories(float, optional): Updated caloriesprotein(float, optional): Updated protein in gramscarbs(float, optional): Updated carbohydrates in gramsfat(float, optional): Updated fat in gramsfiber(float, optional): Updated fiber in grams
Returns: Updated meal details
meal_delete
Delete a meal.
Parameters:
meal_id(string, required): Meal ID to delete
Returns: Deletion confirmation
meal_daily_summary
Get nutrition summary for a specific day.
Parameters:
date(string, optional): ISO date (YYYY-MM-DD) to summarize. Defaults to today.
Returns: Daily summary including:
- Total meal count
- Macro totals (calories, protein, carbs, fat, fiber)
- Meals grouped by type (breakfast, lunch, dinner, snack)
Connecting to Claude Desktop
To use this server with Claude Desktop:
- Without Auth0 (Local Development):
{
"mcpServers": {
"sherpa": {
"url": "http://localhost:8000/mcp",
"transport": "streamable-http"
}
}
}
- With Auth0 (Production):
{
"mcpServers": {
"sherpa": {
"url": "https://your-server.com/mcp",
"transport": "streamable-http",
"oauth": {
"client_id": "your-mcp-client-id"
}
}
}
}
See AUTH0_SETUP.md for complete Auth0 configuration.
Testing the Server
Test Health Endpoint
curl http://localhost:8000/health
Expected response: ``json { "status": "healthy", "timestamp": "2026-01-04T...", "service": "sherpa-mcp-server", "version": "1.0.0", "auth_enabled": false, "google_calendar_enabled": true, "ticktick_enabled": true, "meal_logger_enabled": true, "water_tracker_enabled": true } ``
Test Info Endpoint
curl http://localhost:8000/info
Test MCP Tool (requires MCP client)
Use Claude Desktop or the FastMCP CLI to test MCP tools: ```bash
Using FastMCP CLI (if available)
fastmcp client http://localhost:8000/mcp --tool test_connection ```
Development
Project Structure
sherpa-mcp-server/
├── server.py # Main composed server
├── config.py # Shared configuration (timezone, etc.)
├── servers/ # Modular MCP servers
│ ├── __init__.py
│ ├── core.py # Core utility tools
│ ├── calendar.py # Google Calendar tools
│ ├── ticktick.py # TickTick tools
│ ├── meal_logger.py # Meal logging tools
│ ├── workout_tracker.py # Workout tracking tools
│ └── water_tracker.py # Water tracking tools
├── google_calendar.py # Google Calendar API client
├── ticktick.py # TickTick API client
├── meal_logger.py # Meal logger with persistent storage
├── workout_tracker.py # Workout tracker with embedded 50-day plan
├── water_tracker.py # Water tracker with persistent storage
├── requirements.txt # Python dependencies
├── Dockerfile # Docker container configuration
├── .dockerignore # Docker build exclusions
├── railway.toml # Railway deployment configuration
├── .env.example # Example environment configuration
├── .env # Your local configuration (not in git)
├── README.md # This file
├── AUTH0_SETUP.md # Auth0 setup guide
├── GOOGLE_CALENDAR_SETUP.md # Google Calendar setup guide
├── TICKTICK_SETUP.md # TickTick setup guide
├── RAILWAY_DEPLOYMENT.md # Railway deployment guide
└── scripts/
├── google_calendar_auth.py # Google Calendar auth script
└── ticktick_auth.py # TickTick auth script
Adding New Tools
Add new tools using the @server.tool decorator:
@server.tool(
name="my_tool",
description="Description of what this tool does"
)
async def my_tool(param1: str, param2: int = 0) -> dict:
"""Tool implementation."""
return {"result": f"{param1}-{param2}"}
Adding Custom Endpoints
Add custom HTTP endpoints using @server.custom_route:
@server.custom_route("/my-endpoint", methods=["GET"])
async def my_endpoint(request: Request) -> JSONResponse:
return JSONResponse({"data": "value"})
Security
Authentication
- Development: Server runs without authentication by default
- Production: Enable Auth0 OAuth for secure remote access
- PKCE: Full OAuth 2.1 PKCE support for enhanced security
- Token Encryption: Upstream OAuth tokens encrypted at rest
Best Practices
- Always use HTTPS in production (set
SERVER_BASE_URLto https://) - Keep
REQUIRE_CONSENT=truein production - Use strong
JWT_SIGNING_KEY(minimum 12 characters) - Restrict
ALLOWED_CLIENT_REDIRECT_URISappropriately - Store secrets in environment variables, never in code
- Rotate credentials regularly in Auth0
See AUTH0_SETUP.md for complete security guidelines.
Deployment
Local Development
python server.py
Production - Railway (Recommended)
This project is ready for deployment on Railway with Docker support.
Quick Deploy:
- Push your code to GitHub
- Connect your repository to Railway
- Railway automatically detects
Dockerfileandrailway.toml - Configure environment variables in Railway dashboard
- Deploy automatically on every push
Required Environment Variables for Railway: ``bash AUTH0_CONFIG_URL=https://YOUR_DOMAIN.auth0.com/.well-known/openid-configuration AUTH0_CLIENT_ID=your-production-client-id AUTH0_CLIENT_SECRET=your-production-client-secret AUTH0_AUDIENCE=https://api.sherpa-mcp.com SERVER_BASE_URL=https://your-app.up.railway.app REQUIRE_CONSENT=true ``
Railway automatically provides:
PORT- Assigned port (server.py handles this)RAILWAY_STATIC_URL- Your app's public URL- SSL certificate (automatic with custom domains)
See RAILWAY_DEPLOYMENT.md for complete deployment guide including:
- Step-by-step Railway setup
- Auth0 production configuration
- Custom domain setup
- Monitoring and logs
- Troubleshooting
Docker Deployment (Other Platforms)
Build and run with Docker:
# Build the image
docker build -t sherpa-mcp-server .
# Run the container
docker run -p 8000:8000 \
-e AUTH0_CONFIG_URL="https://YOUR_DOMAIN.auth0.com/.well-known/openid-configuration" \
-e AUTH0_CLIENT_ID="your-client-id" \
-e AUTH0_CLIENT_SECRET="your-client-secret" \
-e AUTH0_AUDIENCE="https://api.sherpa-mcp.com" \
-e SERVER_BASE_URL="https://your-domain.com" \
sherpa-mcp-server
Or use docker-compose (create docker-compose.yml): ```yaml version: '3.8' services: mcp-server: build: . ports:
- "8000:8000"
env_file:
- .env
restart: unless-stopped ```
Troubleshooting
Server won't start
- Check Python version:
python --version(requires 3.8+) - Verify dependencies:
pip install -r requirements.txt - Check port availability:
lsof -i :8000(macOS/Linux)
Auth0 errors
- Verify environment variables are set correctly
- Check Auth0 dashboard for application configuration
- Ensure callback URLs are whitelisted in Auth0
- See AUTH0_SETUP.md for detailed troubleshooting
Connection errors
- Verify server is running:
curl http://localhost:8000/health - Check firewall settings
- Verify MCP client configuration
Contributing
This is a personal project, but suggestions and improvements are welcome!
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
License
This project is licensed under the MIT License - see LICENSE file for details.
Resources
- FastMCP Documentation
- MCP Protocol Specification
- Auth0 Documentation
- Google Calendar API Documentation
- TickTick Open API Documentation
- Railway Documentation
- Claude Desktop Documentation
Support
For issues and questions:
- Check AUTH0_SETUP.md for Auth0-related questions
- Check GOOGLE_CALENDAR_SETUP.md for Google Calendar setup
- Check TICKTICK_SETUP.md for TickTick setup
- Check RAILWAY_DEPLOYMENT.md for Railway deployment help
- Review FastMCP documentation at https://gofastmcp.com
- Open an issue in this repository
Roadmap
- ✅ Phase 1: Basic MCP server with Auth0 OAuth
- ✅ Phase 1.5: Docker containerization and Railway deployment
- ✅ Phase 2: Google Calendar integration
- ✅ Phase 3: TickTick task management
- ✅ Phase 4: Meal logger with persistent storage
- ✅ Phase 5: Workout tracker with 50-day plan
- ✅ Phase 6: Water tracker with daily goal tracking
- 🚧 Phase 7: Obsidian notes integration
- 🚧 Phase 8: Health data management
- 🚧 Phase 9: Advanced AI-powered features
---
Made with ❤️ using FastMCP






