Sherpa MCP Server
Remote MCP server acting as a personal assistant with secure OAuth authentication, integrating Google Calendar, TickTick tasks, meal logging, workout tracking, and water intake logging.
README
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:
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:
// 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:
{
"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:
# 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:
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):
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
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.