Skip to main content
Glama
BrianVia

tonal-mcp-cloudflare-workers

tonal-mcp-cloudflare-workers

A remote Model Context Protocol server for one Tonal account, hosted on Cloudflare Workers. It reads workout history (including per-set weights), muscle readiness, strength scores, and lifetime stats through Tonal’s unofficial Auth0 + REST APIs.

One Worker serves a bearer-protected, stateless /mcp endpoint. A Durable Object owns Auth0 tokens (password grant + refresh), the user id, and a cached movement catalog.

Setup

npm install
npx wrangler login
cp wrangler.jsonc wrangler.local.jsonc

In wrangler.local.jsonc, replace tonal.example.com with a hostname on a Cloudflare zone you manage. Deploy using that local config:

WRANGLER_CONFIG=wrangler.local.jsonc npm run deploy
npx wrangler secret put TONAL_USERNAME --config wrangler.local.jsonc
npx wrangler secret put TONAL_PASSWORD --config wrangler.local.jsonc
openssl rand -hex 32 | tee /dev/stderr | npx wrangler secret put MCP_BEARER --config wrangler.local.jsonc

The custom-domain route creates its DNS record on first deploy.

Related MCP server: garmin-coach-mcp

Tools

Tool

Description

get_recent_workouts

Recent completed workouts (name, volume, reps, duration, target area)

list_workout_activities

Paginated workout activities (API oldest-first; page re-sorted newest-first)

get_workout_activity_details

One workout with every set: movement name, reps, avg weight (lbs), 1RM, volume

get_workout_summary

Tonal formatted summary (coach, target area, per-movement volume)

get_user_stats

Lifetime statistics + current streak

get_muscle_readiness

Current muscle-group readiness percentages

get_strength_scores

Current strength scores by body region

search_movements

Search the movement catalog by name / muscle / region

Read-only. Volumes are pounds.

Raw HTTP

The endpoint uses stateless Streamable HTTP and returns SSE-framed MCP responses.

curl -s https://tonal.example.com/mcp -X POST \
  -H 'Authorization: Bearer <MCP_BEARER>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

GET / identifies the MCP endpoint. GET /health is public and reports whether the Durable Object has tokens without making a network request.

Local development

cp .dev.vars.example .dev.vars
npm run check
npx wrangler dev

Notes

  • Authentication uses Tonal’s public Auth0 client and password grant. The API expects the Auth0 id_token as Authorization: Bearer. This is unofficial and may break if Tonal changes that flow.

  • No browser authorization is needed.

  • Credentials are Worker secrets and are sent only to Tonal’s Auth0 token endpoint and api.tonal.com.

  • /mcp requires MCP_BEARER; / and /health are public.

  • The Node @dlwiest/ts-tonal-client package is intentionally not used (it depends on fs/os/path/Buffer); the Worker ports the Auth0 + REST calls directly.

License

MIT. See LICENSE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Connects MCP clients to Garmin Connect data, enabling queries about activities, sleep, heart rate, body battery, and training status.
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    Provides read-only access to your Garmin Connect health data, including sleep, HRV, body battery, stress, training readiness, and activities, through an MCP server.
    14
    -
  • A
    license
    B
    quality
    C
    maintenance
    Enables access to Hevy strength-training data—workouts, routines, exercise history, and progression—via an MCP server with per-user credential encryption and optional write support.
    16
    Apache 2.0