Skip to main content
Glama
nibu147
by nibu147

fitdays-mcp (Cloudflare Worker)

Remote MCP server for the unofficial FitDays / iComon API, hosted on your own Cloudflare Worker, with OAuth 2.1 login (no static API key to paste into the Worker: every connecting user logs in with their own FitDays email/password via an /authorize page).

Based on roquerodrigo/fitdays-mcp-server (which only runs in stdio/local) and adapted for Cloudflare Workers following the same pattern used by chrisdoc/hevy-mcp.

How it works

  • src/index.ts — composes @cloudflare/workers-oauth-provider (handles PKCE, dynamic client registration, tokens, OAuth discovery) with:

    • src/authorize.ts — the /authorize page: shows an email/password/region form, verifies the credentials with a real login on FitDays, then saves { fitdaysEmail, fitdaysPassword, fitdaysRegion } as grant props (encrypted at rest by Cloudflare's library).

    • src/mcp-handler.ts — the /mcp handler: automatically protected by the provider (requires a valid OAuth bearer token), reads the credentials from the grant and serves the MCP protocol via WebStandardStreamableHTTPServerTransport (from the same version of @modelcontextprotocol/sdk used by the original repo).

  • src/server.ts — the same 5 tools as the original: list_users, list_devices, get_weight_history, get_latest_weight, refresh_sync.

  • src/fitdays-session.ts — FitDays client with per-isolate in-memory cache (5 minutes), to avoid login + full resync on every call when the Worker isolate is "warm".

No credentials ever travel through a third-party server: the login happens in your Worker, and FitDays data stays between the Worker and the FitDays API.

Related MCP server: Garmin MCP Server

Deploy

Requires Node.js ≥ 22 and a free Cloudflare account.

npm ci
npx wrangler login

# Crea il namespace KV che l'OAuth provider usa per grant e token
npx wrangler kv namespace create OAUTH_KV
# copia l'"id" restituito in wrangler.jsonc -> kv_namespaces[0].id

npm run worker:dry-run   # opzionale: verifica il bundle localmente
npm run worker:deploy    # pubblica su https://fitdays-mcp.<tuo-subdomain>.workers.dev

Connecting Claude (or another MCP client)

  1. Claude.ai → Settings → Connectors → Add custom connector

  2. URL: https://fitdays-mcp.<your-subdomain>.workers.dev/mcp

  3. Click "Connect": your Worker's /authorize page opens → enter email, password, and FitDays region → authorize

From that point on, Claude can call the 5 FitDays tools without ever seeing your password (it stays in the encrypted OAuth grant inside your KV namespace).

Local development

npm run dev

wrangler dev starts the Worker locally with a simulated local KV namespace — useful for testing the login form and the tools without deploying.

Notes

  • Always use npm ci, never npm install. npm ci installs exactly the versions from package-lock.json and verifies each package against its SHA-512 hash: if the content published on npm changes, the installation fails with EINTEGRITY instead of silently installing different code. npm install can instead update dependencies. Always commit the package-lock.json.

  • All runtime dependencies are pinned to exact versions (no ^), so there's no drift even if you re-run the install months later.

  • The deployed Worker is self-contained: wrangler deploy bundles all the code at deploy time. At runtime it downloads nothing from npm or GitHub, and later changes made by upstream authors don't touch the already-published Worker.

  • nodejs_compat is required in wrangler.jsonc because fitdays-api uses node:crypto (MD5 for login) and randomUUID().

  • FitDays credentials are email+password (not a single API key like Hevy): that's why the /authorize form performs a real login attempt before completing authorization, so wrong credentials are rejected immediately instead of failing silently on the first tool call.

Where the password ends up

Only two destinations:

  1. The FitDays servers (online-{us,eu}.fitdays.cn) — unavoidable, it's the only way to authenticate. Sent as MD5(MD5(password+salt)), but the salt is a public constant, so it should be considered equivalent to a plaintext password: don't reuse your FitDays password elsewhere.

  2. Your KV namespace on Cloudflare, inside the grant props (encrypted at rest by Cloudflare's OAuth library).

No other third party. fitdays-api has zero runtime dependencies and only one network endpoint in the entire codebase; there's no telemetry, analytics, or error reporting in either upstream repo or in this Worker.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Connects to Garmin Connect and exposes fitness and health data (activities, steps, heart rate, sleep, body composition) to MCP-compatible clients like Claude.
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that connects Claude to Withings health data using OAuth 2.0. Provides 11 read-only tools to access body measurements, activity, sleep, heart rate, and device information from Withings devices.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A personal MCP server on Cloudflare Workers that connects Claude to Google Health API v4, enabling reading of health data like activity, sleep, heart rate, SpO₂, HRV, and nutrition.
    MIT