Skip to main content
Glama
nitinchakravarthy

Workout Tracker MCP Server

README.md
# Workout Tracker MCP Server

A comprehensive Model Context Protocol (MCP) server for workout tracking with DynamoDB persistence and Exercise Database integration. Built with FastMCP.

## Features

- **12 MCP Tools**: Workout logging, volume calculation, DynamoDB operations, Exercise DB integration
- **2 MCP Prompts**: AI-powered workout plan generation and formatting
- **1 MCP Resource**: Exercise list
- **DynamoDB Integration**: Persistent storage for workout plans with single-table design
- **Exercise Database**: 1500+ exercises with search, filtering, and detailed information
- **Dual Transport**: stdio (local) and HTTP/SSE (production) modes

---

## Prerequisites

Before you begin, ensure you have:

- **Python 3.12+** (Python 3.14 recommended)
- **AWS Account** with IAM credentials (Access Key ID and Secret Access Key)
- **AWS CDK** (for infrastructure deployment) - Install with: `npm install -g aws-cdk`
- **Terminal/Command Line**

---

## Infrastructure Setup (One-Time)

**⚠️ IMPORTANT:** You must deploy the DynamoDB infrastructure to your AWS account before using this MCP server.

### Option 1: Using AWS CDK (Recommended)

```bash
# Navigate to infrastructure directory
cd infrastructure

# Install CDK dependencies
npm install

# Bootstrap CDK in your AWS account (first time only)
cdk bootstrap

# Deploy the DynamoDB table
cdk deploy
```

This will create:
- DynamoDB table: `WorkoutPlans`
- Global Secondary Indexes: GSI1 (Status), GSI2 (Exercise History)
- Point-in-time recovery enabled
- Billing mode: Pay-per-request

### Option 2: Using the Bash Script

```bash
./scripts/create_dynamodb_table.sh
```

### Verify Table Creation

```bash
aws dynamodb describe-table --table-name WorkoutPlans --region us-west-2
```

---

## Quick Start (2 Minutes)

### 1. Install & Setup

Run the automated setup script:

```bash
./setup.sh
```

**During setup, you will be prompted to enter:**
- Your AWS Access Key ID
- Your AWS Secret Access Key
- AWS Region (default: us-west-2)

The script will:
- ✅ Install uv package manager (if needed)
- ✅ Detect Python 3.12+
- ✅ Create virtual environment
- ✅ Install all dependencies
- ✅ Prompt for AWS credentials and save them to ~/.bashrc or ~/.zshrc
- ✅ Verify DynamoDB access

**Note:** After setup, restart your terminal or run `source ~/.bashrc` (or `~/.zshrc`) for AWS credentials to be available system-wide.

### 3. Start the Server

**Local mode (stdio - for Claude Desktop, Claude Code):**
```bash
uv run main.py
```

**Production mode (HTTP/SSE):**
```bash
uv run main.py --http
```

Server will be available at `http://localhost:8000/sse`

---

## Connect to MCP Clients

### Option 1: Claude Desktop

**Config file location:**
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`

**Add to config:**
```json
{
  "mcpServers": {
    "workout-tracker": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/absolute/path/to/workout_tracker_mcp",
        "main.py"
      ]
    }
  }
}
```

**Important:**
- Replace `/absolute/path/to/workout_tracker_mcp` with your actual path
- AWS credentials are automatically configured by setup.sh
- Restart Claude Desktop after saving

### Option 2: Claude Code

The MCP server is already configured in `.mcp.json`. AWS credentials are automatically configured after running `./setup.sh`.

### Option 3: MCP Inspector (Testing)

```bash
npx @modelcontextprotocol/inspector uv run main.py
```

Opens interactive web UI at `http://localhost:5173`

---

## Test Queries for MCP Clients

Once connected to Claude Desktop or Claude Code, try these queries:

### 1. Basic Workout Logging

```
Log a workout: Bench Press, 3 sets of 8 reps
```

```
Calculate volume for: 185 lbs, 4 sets, 10 reps
```

### 2. Exercise Database Search

```
Search for push exercises
```

```
Find all chest exercises using a barbell
```

```
List exercises that target the quadriceps
```

```
Show me all bodyweight exercises for legs
```

```
What body parts can I train?
```

### 3. Workout Plan Generation

```
Create a 12-week strength training program for an intermediate lifter who trains 4 days per week
```

```
Generate a 6-week beginner workout plan focused on hypertrophy with 3 training days per week,
using only dumbbells, for a 28-year-old male
```

### 4. DynamoDB Operations

**Save a generated plan:**
```
Save the workout plan you just generated for user_123
```

**Retrieve a saved plan:**
```
Get the workout plan for user_123 with plan_id abc-123-def
```

**Format for client:**
```
Format this workout plan in a clean, printable format for my client
```

### 5. Exercise Details

```
Get detailed information about exercise ID "VPPtusI"
```

```
Show me exercise instructions for barbell squats
```

---

## Available MCP Components

### Tools (12)

**Workout Tracking (2):**
- `log_workout(exercise, sets, reps)` - Log a workout session
- `calculate_volume(weight, sets, reps)` - Calculate total volume

**DynamoDB Operations (3):**
- `save_workout_plan_to_dynamodb(workout_plan_json, user_id, ...)` - Save workout plan
- `get_workout_plan_from_dynamodb(user_id, plan_id, ...)` - Retrieve workout plan
- `log_workout_session_to_dynamodb(workout_log_json, user_id, ...)` - Log workout execution

**Exercise Database (7):**
- `get_all_exercises(limit, offset)` - List all exercises (paginated)
- `search_exercises(query, limit, offset, threshold)` - Search exercises by name
- `get_exercise_by_id(exercise_id)` - Get exercise details
- `get_exercises_by_body_part(body_part, limit, offset)` - Filter by body part
- `get_exercises_by_target_muscle(target, limit, offset)` - Filter by muscle
- `get_exercises_by_equipment(equipment, limit, offset)` - Filter by equipment
- `list_body_parts()` - List all body parts
- `list_target_muscles()` - List all target muscles
- `list_equipment()` - List all equipment types

### Prompts (2)

- `workout_plan_prompt()` - Generate comprehensive workout plans with 10 parameters
  - Parameters: goal, experience_level, training_frequency, session_duration_min, equipment_available, age, gender, current_maxes, injuries_limitations, program_duration_weeks
  - Returns: Structured JSON for DynamoDB storage

- `format_workout_plan()` - Transform DynamoDB JSON to client-friendly format
  - Parameters: workout_plan_json
  - Returns: Beautiful markdown document

### Resources (1)

- `workout://exercises/list` - Static list of 8 basic exercises

---

## Running Tests

### End-to-End DynamoDB Test

```bash
uv run python tests/test_dynamodb_fetch.py
```

**What it tests:**
- ✅ Saves workout plan to DynamoDB
- ✅ Fetches plan from DynamoDB
- ✅ Verifies data integrity
- ✅ Cleans up test data

**Expected output:**
```
✅ SUCCESS - All verifications passed!
  ✓ Saved 27 entities to DynamoDB
  ✓ Fetched complete workout plan
  ✓ Verified 6 weeks
```

### Exercise DB API Test

```bash
uv run python examples/test_api_slow.py
```

**What it tests:**
- ✅ Exercise listing
- ✅ Exercise search
- ✅ Exercise details
- ✅ Body part listing

---

## Project Structure

```
workout_tracker_mcp/
├── main.py                          # MCP server (12 tools, 2 prompts, 1 resource)
├── setup.sh                         # Automated setup script
├── .mcp.json                        # MCP client configuration
├── ARCHITECTURE.md                  # System architecture documentation
│
├── src/                             # Source modules
│   ├── db/
│   │   └── dynamodb_client.py      # DynamoDB integration
│   └── client/
│       ├── mcp_client.py           # MCP client wrapper
│       └── mcp_client_tools.py     # MCP client helpers
│
├── src/prompts/                         # Prompt templates
│   ├── workout_plan_prompt_template.py    # Plan generation
│   └── format_workout_plan_prompt.py      # Plan formatting
│
├── docs/                            # Documentation
│   ├── DYNAMODB_DATA_MODEL.md      # Schema reference
│   ├── DYNAMODB_INTEGRATION.md     # Integration guide
│   ├── DYNAMODB_SETUP.md           # Table setup
│   └── ...
│
├── infrastructure/                  # Infrastructure as Code
│   └── dynamodb_stack.py           # AWS CDK stack
│
├── scripts/                         # Utility scripts
│   ├── create_dynamodb_table.sh    # DynamoDB table creation
│   └── ...
│
├── tests/                           # Test suite
│   ├── test_dynamodb_fetch.py      # DynamoDB integration test
│   └── ...
│
└── examples/                        # Usage examples
    ├── save_workout_plan_example.py    # DynamoDB save
    ├── test_api_slow.py                # Exercise DB test
    └── mcp_client_usage.py             # MCP client example
```

---

## Configuration

### Environment Variables

**AWS Configuration:**
Automatically configured by `./setup.sh` (saved to ~/.bashrc or ~/.zshrc).

**Server Configuration (optional):**
```bash
export MCP_HOST="0.0.0.0"           # Default: 0.0.0.0
export MCP_PORT="8000"              # Default: 8000
export MCP_TRANSPORT="stdio"        # Default: stdio (or "http")
```

### DynamoDB Table Setup

**Option 1: Using the script (Quick)**
```bash
./scripts/create_dynamodb_table.sh
```

**Option 2: Using AWS CDK**
```bash
cd infrastructure
cdk deploy
```

**Table Details:**
- Name: `WorkoutPlans`
- Region: `us-west-2`
- Billing: On-demand
- Indexes: 2 GSIs (status, exercise history)

---

## Deployment

### Docker

```bash
# Build image
docker build -t workout-tracker-mcp .

# Run with environment variables
docker run -p 8000:8000 \
  -e AWS_ACCESS_KEY_ID="your_key" \
  -e AWS_SECRET_ACCESS_KEY="your_secret" \
  -e AWS_DEFAULT_REGION="us-west-2" \
  workout-tracker-mcp
```

### Google Cloud Run

```bash
# Deploy (will prompt for region)
gcloud run deploy workout-tracker \
  --source . \
  --platform managed \
  --allow-unauthenticated \
  --set-env-vars AWS_ACCESS_KEY_ID=your_key,AWS_SECRET_ACCESS_KEY=your_secret
```

---

## Troubleshooting

### Server Won't Start

**Check Python version:**
```bash
python --version  # Should be 3.12+
```

**Reinstall dependencies:**
```bash
uv sync --reinstall
```

### AWS Credentials Issues

If AWS credentials are missing or not working:

1. **Re-run setup:**
   ```bash
   ./setup.sh
   ```

2. **Restart terminal:**
   ```bash
   source ~/.bashrc  # or ~/.zshrc
   ```

3. **Verify credentials:**
   ```bash
   aws sts get-caller-identity
   ```

### Claude Desktop Can't Connect

1. **Use absolute paths** in config (not relative `~` or `./`)
2. **Restart Claude Desktop** after config changes
3. **Check logs:** Help > View Logs in Claude Desktop
4. **Test server manually:** `uv run main.py` should start without errors

### DynamoDB Table Not Found

```bash
# Check if table exists
aws dynamodb describe-table --table-name WorkoutPlans --region us-west-2

# Create table if missing
./scripts/create_dynamodb_table.sh
```

---

## Example Workflows

### Complete Workout Plan Creation

```
1. "Search for compound leg exercises"
2. "Create a 12-week strength program for intermediate lifter, 4 days/week"
3. "Save this plan for user_john_doe"
4. "Format the plan for my client to print"
```

### Exercise Discovery

```
1. "What body parts can I train?"
2. "Show me all chest exercises"
3. "Filter chest exercises that use dumbbells"
4. "Get detailed instructions for dumbbell bench press"
```

---

## Resources

- [MCP Specification](https://modelcontextprotocol.io)
- [FastMCP Documentation](https://github.com/jlowin/fastmcp)
- [Claude Desktop MCP Guide](https://docs.anthropic.com/claude/docs/mcp)
- [Exercise DB API](https://www.exercisedb.dev)
- [Architecture Documentation](ARCHITECTURE.md)

---

## License

MIT License

## Support

- Documentation: [docs/](docs/)
- Architecture: [ARCHITECTURE.md](ARCHITECTURE.md)

TDQS

A3.5/5.0

Scored across 14 tools

Disambiguation2/5

log_workout and log_workout_session_to_dynamodb both log workouts but at different levels of detail and persistence, creating real ambiguity for an agent. The multiple get_exercises_by_* filters are largely distinct but could be confused with search_exercises, especially since they all return exercise lists.

Naming Consistency4/5

Tool names consistently use snake_case with a verb_noun pattern, such as list_*, get_*, log_*, and save_*. Minor deviations like calculate_volume (no resource object) and the long 'to_dynamodb'/'from_dynamodb' suffixes are still readable and predictable.

Tool Count4/5

With 14 tools, the count is on the higher end but still within a reasonable scope for an exercise database combined with workout plan and session logging. A few tools, especially the redundant log_workout, could be consolidated, but the overall count is not excessive.

Completeness2/5

The server provides save/get for workout plans and a session logger, but lacks list, update, and delete operations for plans or logs. There is also no way to retrieve a user's workout history, leaving significant lifecycle gaps that would cause agent failures in common tracking workflows.

Maintenance

ActivityInactive
ResponsivenessNo issues