Skip to main content
Glama
matrix-workouts-mcp

matrix-workouts-mcp

by bestimmaa

matrix-workouts-mcp

npm CI license

An MCP server for your Matrix / Johnson Fitness ride history, so an AI agent can answer questions about it.

The dashboard at matrixworkouts.jfit.co shows six numbers per ride. The record behind it carries a sample every 10 seconds with power (watts), console resistance level and cadence (rpm) — none of which appears anywhere in the site's UI, and none of which its own list page can reach for anything older than about a week. This server hands all of it to an agent, with the cross-ride views the platform has never had: power curve, training volume by week or month, one ride against another.

> what was my best 5-minute power this month, and which ride was it?
> compare my last two Sprint 8 sessions
> has my average power at resistance 8 moved since August?

Install

claude mcp add matrix-workouts -- npx -y matrix-workouts-mcp

Or, in a client that takes JSON:

{
  "mcpServers": {
    "matrix-workouts": {
      "command": "npx",
      "args": ["-y", "matrix-workouts-mcp"],
      "env": {
        "MATRIX_XID": "your-member-number",
        "MATRIX_PIN": "your-passcode"
      }
    }
  }
}

Node 20 or newer.

You can also run it without credentials. Download your history once with npx matrix-workouts-history, point MATRIX_CACHE_DIR at the result, and every tool except refresh_history works against it. No passcode in a config file, no sign-in from the server at all.

Related MCP server: Intervals.icu MCP Server

Configuration

Variable

Default

What it does

MATRIX_XID

—

Member number from the gym tag. Without it the server is read-only over the cache.

MATRIX_PIN

—

Numeric passcode. Used for one sign-in request, never stored or logged.

MATRIX_CACHE_DIR

$XDG_CACHE_HOME/matrix-workouts-mcp, else ~/.cache/matrix-workouts-mcp

Where the downloaded history is kept, written 0600.

MATRIX_CACHE_TTL_MINUTES

60

How long a cached history is served before a refetch.

MCP_TRANSPORT

stdio

Set to http to serve over HTTP instead.

MATRIX_HTTP_PORT

3000

HTTP transport only. Falls back to PORT when unset.

MATRIX_HTTP_HOST

127.0.0.1

HTTP transport only. Loopback on purpose — see Privacy.

MATRIX_MCP_TOKEN

—

Bearer token. Required for the HTTP transport; the server refuses to start without it.

Tools

Tool

Returns

list_workouts

Rides newest first, one compact row each. Filter by date, machine or program mode. No sample series.

get_workout

One ride in full: work, power, cadence and resistance (average and peak), heart rate's average, minimum and maximum both as reported and as filtered, and what the console was holding constant.

get_samples

The 10-second interval series as CSV, over a window and a stride you choose. Downsampled to fit the row limit, never cut short.

summarize_history

Volume by week or month, plus the power curve over the matched rides. Same date, machine and mode filters as list_workouts.

compare_workouts

Two to eight rides side by side on every derived number.

export_workout

Writes a lossless JSON export document and returns the path.

refresh_history

Re-downloads from the API. Needs credentials.

Tools answer from one cached history rather than fetching per call — the API returns every ride on the account in a single response, so anything else would re-download your entire history a dozen times a conversation.

Two heart-rate averages, always. The platform's own figure is not derived from the sample series and does not always agree with it: the console averages in real time, ahead of the dropouts the series preserves. On a glitching strap the reported figure is the better one — on one ride with independent Apple Watch ground truth, the console's 153 bpm was exactly right and the filtered series gave 151. Reporting only ours would be quietly misleading, so both go out, labelled.

Privacy

This is your heart rate at ten-second resolution, and handing it to a language model is a real decision rather than a formality. What the server does about that:

  • The HTTP transport refuses to start without MATRIX_MCP_TOKEN, and binds 127.0.0.1 unless you deliberately change it. Over stdio nothing is listening at all, which is the mode to prefer.

  • Credentials are used for one sign-in request. The passcode is never stored, logged or returned; the bearer token is never persisted. Errors from the API client are redacted before they can carry a token into a message.

  • Cached and exported files are written 0600, outside any repository.

  • export_workout returns a path, never the contents — partly for your context budget, mostly because a document is a thing you keep rather than a thing you paste.

  • Nothing is sent anywhere but apollo.jfit.co, the API the data came from.

Running with no credentials at all, over a cache you downloaded yourself, is the tightest configuration and everything except refresh_history still works.

Development

npm test         # vitest, against real ride fixtures — no network
npm run typecheck
npm run build
npm run dev      # tsx src/cli.ts

Tests use three real captured rides and a stubbed downloader, so the suite needs neither credentials nor a network. src/docs.test.ts fails the build if a tool or an environment variable is missing from the tables above — see AGENTS.md.

Cutting a release:

npm run release -- patch     # bumps, tags, packs; refuses without a CHANGELOG entry
git push origin main:main --follow-tags
npm publish --access public

Part of matrix-workouts

matrix-workouts-core

the parser, API client and export format this is built on

matrix-workouts-chrome

a Chrome extension that puts the same data on screen

matrix-workouts-mcp

this server

MIT licensed. Unaffiliated with Matrix Fitness or Johnson Health Tech.

Available Tools

7 tools
compare_workoutsB

Two or more rides side by side on every derived number. Use it for 'how did today compare to last Tuesday' rather than calling get_workout repeatedly.

Inputs: ids (required).

export_workoutA

Write one ride to disk as a lossless JSON export document — normalized telemetry plus the upstream record verbatim. Returns the path, not the contents, because the document is far too large to read into a conversation.

Inputs: id (required), path.

get_samplesA

The raw interval series for one ride as CSV — power, cadence, resistance, heart rate, speed, one row per 10 seconds. Ask for a window and a stride rather than a whole ride: a full ride is several hundred rows.

Inputs: id (required), fields, maxRows, everyNth, +2 more.

get_workoutA

Everything derived about one ride: duration, distance, work done, average and peak power, cadence, resistance, both heart-rate averages, and what the console was actually holding constant. Does not return the sample series — use get_samples for that.

Inputs: id (required).

list_workoutsA

List recorded rides, newest first, one compact row each: date, program mode, duration, distance, average power and heart rate. Use this first to find the id of a ride before asking for its detail. Returns no sample series.

Inputs: to, from, mode, limit, +1 more.

refresh_historyA

Re-download the whole history from the API, replacing the cache. Needs credentials. Everything else answers from the cache, so call this only when a ride is missing because it happened since the last fetch.

Inputs: no named parameters.

summarize_historyA

Training volume per week or month — rides, time, distance, work, average power and heart rate — plus the all-time power curve over the matched rides. This is the tool for questions about trends, totals and bests.

Inputs: to, from, bucket, windowsSeconds.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 7 tools

    Disambiguation5/5

    Each tool targets a distinct operation—listing, single-ride detail, raw samples, aggregates, comparison, export, and cache refresh—and the descriptions explicitly cross-reference the intended usage. No two tools overlap in function, and boundary cases like get_workout vs get_samples are clearly called out.

    Naming Consistency5/5

    All seven tools follow a consistent verb_noun snake_case pattern (list_, get_, summarize_, compare_, export_, refresh_). Singular and plural noun usage is logical and predictable, making tool selection straightforward.

    Tool Count5/5

    Seven tools is well-scoped for a workout-history MCP: the core read, analyze, and export paths are covered without redundancy. Each tool earns its place, and there is no sense of bloat or thinness.

    Completeness5/5

    The surface covers listing, detail, raw samples, aggregation, comparison, export, and cache refresh, so a user can go from finding a ride to analyzing or exporting it without dead ends. Create/update/delete are not needed because the server reads externally recorded rides and refresh_history handles new data.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      A
      quality
      D
      maintenance
      Enables AI assistants to access and analyze intervals.icu training data including activities, fitness metrics (CTL/ATL/TSB), wellness stats, and calendar events. Supports natural language querying of athletic performance for training insights and workout planning.
      6
      -
    • F
      license
      Not graded
      quality
      A
      maintenance
      Enables AI assistants to query and create workouts with structured intervals, manage calendars and events, analyze power PRs and CTL/ATL/TSB fitness trends, handle workout libraries, equipment and health metrics through natural language. Uses secure cookie-based authentication stored in the system keyring, so no API approval is required and any account can be set up in minutes.
      -
    • F
      license
      Not graded
      quality
      A
      maintenance
      Enables AI assistants like Claude to query and manage endurance-training data through natural language, including workouts, structured intervals, calendars, events, workout libraries, strength sessions, health metrics, equipment, and coach tools. Provides fitness trend analysis (CTL/ATL/TSB), power and running PRs, FTP and zone updates, and annual training plan targets without requiring API approval, using keyring-stored cookie authentication.
      -