Pierre MCP Server

A fitness data platform that aggregates data from providers like Strava and Fitbit, offering secure B2B API access.

Pierre MCP Server

CI Frontend Tests

Development Status: This project is under active development. APIs and features may change.

A Model Context Protocol (MCP) server that connects AI assistants to fitness data from providers like Strava. Built in Rust, it provides secure access to activity data, athlete profiles, and basic fitness analytics through the MCP protocol.

Key Features

  • Multi-Protocol Support: MCP, A2A (Agent-to-Agent), OAuth 2.0 Authorization Server, REST API
  • Enterprise Multi-Tenancy: Isolated data and configuration per organization
  • Real-Time Notifications: Server-Sent Events for OAuth status and system updates
  • Compile-Time Plugin System: Zero-overhead extensible fitness analysis tools
  • High Performance: Rust-based implementation with memory safety and fearless concurrency
  • Standards Compliance: RFC 7591 OAuth 2.0 dynamic client registration, MCP 1.0 specification

Use Cases

  • Fitness Data Analysis: Access and analyze activities from Strava, Fitbit, and other providers
  • Performance Intelligence: Generate insights from training data with weather and location context
  • AI Assistant Integration: Enable Claude, ChatGPT, and other AI assistants to work with fitness data
  • Autonomous Agent Systems: Build fitness-focused AI agents with A2A communication capabilities
  • Multi-tenant SaaS Applications: Support multiple organizations with isolated data and billing
  • OAuth 2.0 Provider: Act as authorization server for fitness applications using mcp-remote
  • Real-time Dashboards: Stream live notifications for OAuth flows and system events

AI Generated Code

  • This project uses a comprehensive TOML-based validation system (scripts/validation-patterns.toml) to maintain code quality standards and prevent AI assistants (including Claude Code) from introducing placeholder implementations or anti-patterns. The validation script (scripts/lint-and-test.sh) automatically checks for common AI-generated issues like "Implementation would...", mock implementations, error handling shortcuts, and architectural violations using patterns defined in the TOML configuration. Before committing changes, developers should run ./scripts/lint-and-test.sh to ensure all validation checks pass. The TOML approach allows easy maintenance and extension of validation rules without modifying the underlying bash scripts.

Quick Start

Prerequisites

  • Rust 1.70+
  • SQLite (default) or PostgreSQL (production)

Installation

git clone https://github.com/Async-IO/pierre_mcp_server.git
cd pierre_mcp_server
cargo build --release

Basic Setup

  1. Set required environment variables:
export DATABASE_URL="sqlite:./data/pierre.db"
export PIERRE_MASTER_ENCRYPTION_KEY="$(openssl rand -base64 32)"
  1. Start the server:
cargo run --bin pierre-mcp-server
  1. Create admin user:
curl -X POST http://localhost:8081/admin/setup \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@example.com",
    "password": "SecurePass123!",
    "display_name": "System Administrator"
  }'

Automated Development Setup

For development and testing:

# Clean database and start fresh server
./scripts/fresh-start.sh
RUST_LOG=debug cargo run --bin pierre-mcp-server &

# Run complete setup (admin + user + tenant + login + MCP test)
./scripts/complete-user-workflow.sh

# Use saved environment variables
source .workflow_test_env
echo "JWT Token: ${JWT_TOKEN:0:50}..."

Docker Installation

# Build and run with Docker
docker build -t pierre-mcp-server .
docker run -p 8080:8080 pierre-mcp-server

MCP Client Configuration

MCP Client Support

Pierre MCP Server supports any MCP-compliant client. However, mcp-remote is the recommended client for OAuth 2.0 authentication.

Using mcp-remote

Pierre MCP Server is designed to work with mcp-remote, which handles the OAuth 2.0 flow automatically.

Installation

mcp-remote can be used directly via npx (recommended) or installed globally:

# Option 1: Use via npx (recommended - no installation required)
npx mcp-remote http://localhost:8081/mcp --allow-http --debug --transport http-first --auth-timeout 120 --timeout 120

# Option 2: Install globally first, then use
npm install -g mcp-remote
mcp-remote http://localhost:8081/mcp --allow-http --debug --transport http-first --auth-timeout 120 --timeout 120

Claude Desktop Configuration

Add this to your Claude Desktop configuration file (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

Option 1: Using npx (recommended)

{
  "mcpServers": {
    "pierre-fitness": {
      "command": "npx",
      "args": ["mcp-remote", "http://localhost:8081/mcp", "--allow-http", "--debug", "--transport", "http-first", "--auth-timeout", "120", "--timeout", "120"],
      "env": {}
    }
  }
}

Option 2: Using globally installed mcp-remote

{
  "mcpServers": {
    "pierre-fitness": {
      "command": "mcp-remote",
      "args": ["http://localhost:8081/mcp", "--allow-http", "--debug", "--transport", "http-first", "--auth-timeout", "120", "--timeout", "120"],
      "env": {}
    }
  }
}

This will:

  1. Register a new OAuth client automatically
  2. Open browser for user login and authorization
  3. Exchange authorization code for JWT token
  4. Use JWT for subsequent MCP requests

Claude Desktop Integration

Note: Direct Claude Desktop integration has not been reliably tested. The recommended approach is to use mcp-remote as your MCP client, which provides a stable interface to Pierre MCP Server's OAuth 2.0 authentication system.

For Claude Desktop users, use mcp-remote as an intermediary client to access Pierre's fitness tools through the command line.

Available Tools

Core Fitness Data Tools

ToolDescriptionRequired Parameters
get_activitiesGet activities from fitness providersprovider (optional), limit (optional)
get_athleteGet athlete informationNone
get_statsGet athlete statisticsNone
get_activity_intelligenceGet AI intelligence for activityactivity_id
get_connection_statusCheck provider connection statusNone
disconnect_providerDisconnect and remove stored tokens for a specific fitness providerprovider

Notification Management Tools

ToolDescriptionRequired Parameters
get_notificationsGet user notificationsNone
mark_notifications_readMark notifications as readNone
announce_oauth_successAnnounce OAuth flow completionNone
check_oauth_notificationsCheck for OAuth notificationsNone

Analytics & Performance Tools

ToolDescriptionRequired Parameters
analyze_activityAnalyze an activityactivity_id
calculate_metricsCalculate advanced fitness metrics for an activityactivity_id
analyze_performance_trendsAnalyze performance trends over timeNone
compare_activitiesCompare an activity against similar activities or personal bestsactivity_ids
detect_patternsDetect patterns in training dataNone
predict_performancePredict future performance capabilitiesNone
calculate_fitness_scoreCalculate comprehensive fitness scoreNone
analyze_training_loadAnalyze training load balance and recovery needsNone
generate_recommendationsGenerate personalized training recommendationsNone

Goal & Training Tools

ToolDescriptionRequired Parameters
set_goalSet a fitness goalgoal_type, target_value
track_progressTrack progress toward a specific goalgoal_id
suggest_goalsGenerate AI-powered goal suggestionsNone
analyze_goal_feasibilityAssess whether a goal is realistic and achievablegoal_data

Configuration Tools

ToolDescriptionRequired Parameters
get_configuration_catalogGet the complete configuration catalog with all available parametersNone
get_configuration_profilesGet available configuration profiles (Research, Elite, Recreational, etc.)None
get_user_configurationGet current user's configuration settings and overridesNone
update_user_configurationUpdate user's configuration parameters and session overridesprofile or parameters
calculate_personalized_zonesCalculate personalized training zones based on user's VO2 max and configurationNone
validate_configurationValidate configuration parameters against safety rules and constraintsparameters

Fitness Configuration Tools

ToolDescriptionRequired Parameters
get_fitness_configGet current fitness configurationNone
set_fitness_configSet fitness configuration parametersconfig
list_fitness_configsList available fitness configurationsNone
delete_fitness_configDelete a fitness configurationconfig_id

A2A (Agent-to-Agent) Protocol

Pierre supports Agent-to-Agent communication for building autonomous fitness agent networks:

A2A Protocol Features:

  • Agent Cards: Self-describing agent capabilities and identity
  • Secure Communication: Cryptographic authentication between agents
  • Async Messaging: Non-blocking inter-agent communication
  • Protocol Versioning: Forward-compatible A2A message format

A2A Endpoints:

  • GET /a2a/status - Get A2A protocol status
  • GET /a2a/tools - Get available A2A tools
  • POST /a2a/execute - Execute A2A tool
  • GET /a2a/monitoring - Get A2A monitoring information
  • GET /a2a/client/tools - Get client-specific A2A tools
  • POST /a2a/client/execute - Execute client A2A tool

Example A2A Integration:

use pierre_mcp_server::a2a::A2AClient;

#[tokio::main]
async fn main() -> Result<()> {
    let client = A2AClient::new("https://pierre-server.com/a2a").await?;

    let response = client.send_message(
        "fitness-analyzer-agent",
        serde_json::json!({
            "action": "analyze_performance",
            "user_id": "user-123",
            "timeframe": "last_30_days"
        })
    ).await?;

    println!("Analysis result: {}", response);
    Ok(())
}

Real-Time Notifications

Pierre provides Server-Sent Events (SSE) for real-time updates:

Notification Endpoints:

  • GET /notifications/sse?user_id={user_id} - Subscribe to user notifications

Notification Types:

  • OAuth authorization completion
  • OAuth errors and failures
  • System status updates
  • A2A message notifications

Example SSE Integration:

const eventSource = new EventSource('/notifications/sse?user_id=user-123');

eventSource.onmessage = function(event) {
    const notification = JSON.parse(event.data);
    console.log('Received:', notification);

    if (notification.type === 'oauth_complete') {
        // Handle OAuth completion
        window.location.reload();
    }
};

Authentication & Security

Pierre MCP Server implements dual authentication modes for maximum compatibility:

OAuth 2.0 Authorization Server (RFC-Compliant)

Pierre acts as a standards-compliant OAuth 2.0 Authorization Server for mcp-remote compatibility:

Available OAuth 2.0 Endpoints:

  • GET /.well-known/oauth-authorization-server - Server metadata discovery (RFC 8414)
  • POST /oauth2/register - Dynamic client registration (RFC 7591)
  • GET /oauth2/authorize - Authorization endpoint
  • POST /oauth2/token - Token endpoint (issues JWT access tokens)
  • GET /oauth2/jwks - JSON Web Key Set

OAuth 2.0 Flow Example:

# 1. Client registration (automatic via mcp-remote)
curl -X POST http://localhost:8080/oauth2/register \
  -H "Content-Type: application/json" \
  -d '{
    "redirect_uris": ["http://localhost:35535/oauth/callback"],
    "client_name": "mcp-remote",
    "grant_types": ["authorization_code"]
  }'

# 2. Use mcp-remote for full OAuth 2.0 flow
mcp-remote http://localhost:8080/mcp --allow-http

JWT Token Authentication

  1. Create admin user (using admin-setup binary):
# Create admin user with admin-setup binary
cargo run --bin admin-setup -- create-admin-user \
  --email admin@example.com \
  --password SecurePass123!
  1. User registration and login:
# Register a new user
curl -X POST http://localhost:8080/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "password": "pass123", "display_name": "User"}'

# Get JWT token for MCP integration
JWT_TOKEN=$(curl -s -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "password": "pass123"}' | jq -r '.jwt_token')
  1. Alternative: OAuth 2.0 flow (recommended):
# Use mcp-remote for automatic OAuth 2.0 authentication
mcp-remote http://localhost:8080/mcp --allow-http

Configuration

OAuth Provider Integration

Pierre MCP Server supports multiple methods for providing OAuth credentials for fitness providers:

  1. Server-level credentials (default): Environment variables shared across all users
  2. Client-specific credentials (for full control): Environment variables in MCP client configuration
  3. Tenant-specific credentials: Isolated per organization via API

OAuth Credential Configuration

By default, Pierre MCP Server uses shared server-level OAuth credentials for all users.

Alternative: Client-Specific Credentials

If you need full control over your OAuth application (custom rate limits, branding, etc.), you can optionally provide your own credentials in the MCP client configuration:

{
  "mcpServers": {
    "pierre-fitness": {
      "url": "http://127.0.0.1:8080/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_JWT_TOKEN"
      },
      "initializationOptions": {
        "oauthCredentials": {
          "strava": {
            "clientId": "your_client_id",
            "clientSecret": "your_client_secret"
          },
          "fitbit": {
            "clientId": "your_fitbit_client_id",
            "clientSecret": "your_fitbit_client_secret"
          }
        }
      }
    }
  }
}

The server will use these client-specific credentials instead of the shared server-level credentials for OAuth flows.

Environment Variables

Required

# Core Configuration
DATABASE_URL=sqlite:./data/pierre.db
PIERRE_MASTER_ENCRYPTION_KEY=your_32_byte_base64_key  # Generate with: openssl rand -base64 32

Optional

# Server Configuration
HTTP_PORT=8081  # Default port for all protocols (MCP + OAuth 2.0 + REST API)
HOST=localhost

# Logging
RUST_LOG=info
LOG_FORMAT=json  # For structured logging

# Database (Production)
DATABASE_URL=postgresql://user:pass@localhost:5432/pierre

# OAuth Provider Configuration (for fitness data integration)
STRAVA_CLIENT_ID=your_strava_client_id
STRAVA_CLIENT_SECRET=your_strava_client_secret
STRAVA_REDIRECT_URI=http://localhost:8080/api/oauth/callback/strava

# JWT Configuration (Required for OAuth 2.0)
JWT_SECRET=your_jwt_secret_key  # Required for OAuth 2.0 authorization server
JWT_EXPIRY_HOURS=24

# OpenWeather API (for activity intelligence)
OPENWEATHER_API_KEY=your_openweather_api_key

Architecture

Pierre MCP Server implements a multi-protocol architecture:

  • HTTP Server: Single port (default 8081) for all protocols
  • MCP Protocol: JSON-RPC over HTTP with JWT authentication for tool execution
  • OAuth 2.0 Authorization Server: RFC-compliant server supporting dynamic client registration (RFC 7591)
  • REST API: User management and fitness provider OAuth endpoints
  • Plugin System: Compile-time plugin architecture for extensible fitness analysis
  • Multi-tenant Support: Isolated user data and configuration
  • JWT Authentication: Standard token-based authentication with configurable secrets

Testing

# Run all tests
cargo test

# Run with coverage
cargo test --release

# Lint and test (comprehensive validation)
./scripts/lint-and-test.sh

# MCP protocol compliance tests
cargo test --test mcp_protocol_comprehensive_test
cargo test --test mcp_protocol_compliance_test

# Multi-tenant integration tests
cargo test --test mcp_multitenant_complete_test

Management Dashboard

A web dashboard is available for monitoring and administration:

# Start the dashboard (requires server running)
cd frontend
npm install && npm run dev

Access at http://localhost:5173 for:

  • User management and approval
  • API key monitoring and rate limits
  • Usage analytics and system metrics
  • Real-time request monitoring

See frontend/README.md for detailed development information.

Documentation

Complete documentation is available in the docs/ directory:

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/new-feature)
  3. Run tests and linting (./scripts/lint-and-test.sh)
  4. Commit your changes (git commit -m 'feat: add new feature')
  5. Push to the branch (git push origin feature/new-feature)
  6. Open a Pull Request

License

This project is dual-licensed under:

You may choose either license for your use.

Related Servers