Skip to main content
Glama
Slipstream Extended

Slipstream Extended

Slipstream Extended

CI License: MIT

A private, self-hosted MCP server for exploring your Garmin history with an AI assistant.

Slipstream Extended imports data from Garmin Connect, stores it in your own private Cloudflare R2 bucket, and exposes safe, analysis-oriented tools through a Cloudflare Worker. Cloudflare Access Managed OAuth controls who may connect. There is no shared Slipstream service: every user installs and pays for their own infrastructure.

Use it to discuss your latest workout, last night's recovery, training trends and weight history in ChatGPT or another compatible assistant. Fresh-data requests check what is already stored, import only the needed recent scope when necessary, and report whether the requested data is ready. Your historical data and prepared analyses remain available between refreshes.

What it includes

  • Activity and daily-health summaries

  • Minute-level overnight HRV curves

  • Stored weekly and monthly sleep heart-rate/HRV reference curves, updated incrementally as imported nights are added or corrected

  • Sleep stages, sleep score components, respiration, SpO2 and stress

  • Bounded HRV and sleep history with automatic weekly summaries for long ranges

  • Weight and body-composition measurements, plus bounded morning-weight history

  • Optional revision-verified monthly weight indexes retaining all weighings and clocks

  • Strength exercises, sets, reps, weight, work time and rest time

  • Endurance laps, kilometre splits, heart-rate distribution and drift

  • Optional aerobic/anaerobic Training Effect from verified stored FIT sessions in activity detail reads

  • Optional recorded running measurements: average power, step length, ground contact time, vertical oscillation and vertical ratio, plus recorded ground-contact balance with unknown side semantics; new Coach Input includes FIT laps and source-covered distance segments

  • Versioned coach profiles, append-only RPE/context and prepared coach-input JSON

  • Current user context for every indexed activity type, including strength and cycling, composed separately from immutable analysis; context-save receipts include the current view even without a running analysis or regeneration

  • Stored pre-activity Coach context from the workout's local-night sleep/HRV and optional already-collected Readiness/Recovery, with separate observation and source-check clocks

  • Optional encrypted local backup and isolated recovery testing of user-owned profile/context history and immutable coach inputs; see the backup quick start for a separate local installation

  • Resumable historical backfills that avoid repeated source fetching once complete; pending reference curves continue within the existing storage budgets

  • Detection and replacement of changed Garmin activity files

  • Optional chat-triggered refresh with completion polling

  • R2-first fresh workout and sleep/HRV requests with bounded targeted imports

Raw FIT/TCX files remain private in R2. MCP tools never return GPS coordinates, routes, arbitrary R2 objects or Garmin credentials.

Related MCP server: garmin-mcp

Architecture

Garmin Connect
      │ saved session + application read guard
      ▼
GitHub Actions ── restore / merge / upload ──► private Cloudflare R2
                                                      │ private binding
                                                      ▼
AI client ◄── MCP + Managed OAuth ── Cloudflare Access ── Worker
  • GitHub Actions supplies scheduled compute; generated fitness data is not committed to Git.

  • Chat dispatch, schedules and local refresh share one bounded Python pipeline, with per-stage timing and provider/storage call counts for troubleshooting.

  • Refresh stages reuse one R2 client and lazy bucket inventory per run, retaining separate stage write limits and conservative storage accounting across stages. Pipeline writers share one queue; each new run checks current storage again.

  • R2 is the source of truth for summaries, detailed exports and backfill state.

  • The Worker validates Cloudflare Access assertions before reading R2.

  • Its shared storage reader bounds payloads and checks summary revisions before reusing parsed data, so warm chats see updated imports.

  • Sleep/HRV and activity/coach tools live in focused modules with shared storage and unchanged tool contracts, making the connector easier to maintain.

  • A rate limiter, payload bounds and a Durable Object refresh lease protect the installation from abuse and duplicate dispatches.

The Garmin session is not a provider-issued read-only token and may have write privileges. The pipeline's fail-closed method/endpoint guard permits only the reviewed fitness reads; separate authentication/token renewal may use POST. See Security for the boundary and its limits.

See Architecture for the complete flow.

A matching stored revision permits parsed-summary reuse; it is not a new Garmin source check. Cache reuse, object upload time, job completion and completeness of the requested workout/night must be distinguished from source freshness.

See refresh diagnostics for bounded activity discovery, old dispatch reservations and a connection check without a data sync.

Install

Each installation needs its own Garmin, GitHub and Cloudflare accounts, plus an OAuth-capable MCP client. The documented and tested client flow uses ChatGPT.

Start with the complete installation guide. It covers R2, GitHub secrets, Garmin login, Worker deployment, Cloudflare Access, Managed OAuth, redirect URIs, testing and cost checks.

bash setup.sh is a safe bootstrap helper for macOS/Linux, and setup-windows.ps1 provides the equivalent native PowerShell flow on Windows. Both check prerequisites and install local dependencies, but deliberately leave account-specific R2 credentials and Access policy decisions to the documented dashboard steps.

Both also run a read-only installation check that points to the next unfinished step. Rerun python scripts/check_installation.py to resume; optional --online checks verify your own cloud setup without changing credentials or data. Recent data is sufficient to finish setup; full historical backfill remains optional.

Normal night-data ingestion also maintains closed ISO-week and calendar-month sleep HR/HRV references from stored R2 data. Improved coverage and corrected values update affected periods; open periods wait until closed, and older reference versions remain available. Configure the ingestion calendar timezone as described in installation. See reference refresh for pending work, bounds and integration of existing local archive publishers.

Connect and use

The canonical server URL is:

https://<worker-name>.<workers-subdomain>.workers.dev/mcp

It is protected by Cloudflare Access Managed OAuth. There is no secret URL and no unauthenticated fallback. See Connecting an MCP client.

Example questions:

  • “How has my running volume changed over the last eight weeks?”

  • “Show last night's HRV curve and compare it with my recent baseline.”

  • “Summarize my latest strength session by exercise and category.”

  • “Analyze the latest run for splits, heart-rate drift and time at each BPM.”

  • “Save my confirmed running zones, then prepare coach input for my latest run.”

  • “Refresh today's Garmin data, wait until it is ready, then summarize it.”

More examples are in Prompt ideas. Start with the copyable AI workflows for the six common tasks and consult the generated MCP tool catalog for actual registrations, input limits and conditional permissions. For an explicitly requested update, sync_latest_activity and sync_latest_night check canonical R2 data and a recent successful source check before starting a targeted import. They report source age, missing components and readiness, and share compatible jobs. Historical read tools stay read-only. An acknowledged targeted job can wait for its startup receipt and queue within its existing three status windows; clients must honor the returned polling delay. After those are spent, at most one later, expressly requested inspection of the same request ID is available. Unknown/error results consume it; it starts no new import and does not establish data readiness. It must never become automatic polling. See Fresh data on request for local workout/wake-date rules, polling limits and R2-only Coach Input repair. Coach context is a versioned, retrospective snapshot, not a live recovery check or coaching recommendation. Reading an existing analysis never adds later health data or starts a sync. See context semantics and immutable versioning before requesting regeneration of a particular activity. See HRV and sleep history for date-range behavior, local night_of versus wake-date semantics, monthly R2 indexes and the one-time index build. Garmin's recorded local times handle travel nights; set HEALTH_TIMEZONE during installation as a DST-correct fallback for older data.

Keeping data fresh

The summary workflow runs every six hours. Detailed health and activity jobs are staggered and serialized so Garmin is never queried concurrently. Historical backfills skip existing objects, persist progress, pause repeated item failures, and quiesce automatically when complete.

Historical activity discovery resumes bounded metadata pages and pending imports from the existing range progress. It preserves accumulated failure counts and the three-failure automatic retry threshold. Checkpoint wire version 2 reads older state, but rolling back to an older reader needs preserved compatible progress. See activity backfill for limits, reconciliation, compatibility and measured resource tradeoffs.

Each six-hour summary refresh also refreshes the three most recent HRV and detailed-sleep dates. A chat-triggered refresh performs the same recent-health steps, checks recent activity artifacts and prepares coach input for selected new/recent running activities. Unchanged activity files and ready analyses are reused; unchanged summaries and same-day snapshots skip uploads. Recent source data is still checked so late changes can be reconciled.

Summary publication now seals immutable activity/health pairs before committing a conditional manifest. Cold Python refreshes can recover that committed pair after an interrupted upload; existing current-CSV consumers retain their compatibility interface. See summary recovery for legacy fallback, retry limits, storage cost and rollout boundaries.

Recent sleep and HRV also reuse unchanged canonical files and monthly indexes, updating only affected months. Successful source-check times are recorded separately; empty or incomplete Garmin responses preserve earlier usable data. Targeted night refresh shares this import logic. General manual refresh leaves sleep/HRV historical plans untouched, while scheduled index reconciliation and explicit backfills remain available. See fresh-data behavior for the retained overlap and request-volume measurements.

General manual and scheduled refresh also recheck the three latest populated weight dates and reuse unchanged individual weigh-in files. Every actual sample, timestamp and composition field is retained; successful source checks advance separately. Sparse weigh-ins retain an overlap of measured dates. Historical body backfill plans remain untouched, and incomplete dayviews preserve earlier data.

General summary refresh normally checks the past week of activities, with an inclusive overlap day, and three health dates. A successful wider check permits these shorter repeats for 24 hours; the next refresh then rechecks the existing 30-day activity and 14-day health windows. Missing or failed wider checks remain due. Older summary rows are retained, and edits within the wider windows are picked up by this daily reconciliation. Detailed health checks and explicit historical imports keep their own scopes. See fresh-data behavior for the coverage limits and measured request/storage tradeoffs.

Scheduled sleep/HRV index maintenance checks recent calendar months rather than scanning all history every six hours. It performs a full R2 repair at startup and when the last successful full check is at least seven days old. Missing or failed checks remain due, and immediate manual full repair remains available. This repairs indexes from stored data; it does not re-download Garmin history. See health-history maintenance for recovery and reproducible operation counts.

Legacy general/run-only data_ready reports workflow success. Targeted sync tools require a complete, source-fresh canonical package for readiness; inspect sync_status, its source-check time and missing components. A successful job alone does not establish TCX/Coach readiness. A configured coach profile and usable endurance artifacts are still required for an analysis.

For a new installation with years of history, an optional local overnight bootstrap can advance the same R2 plans in consecutive bounded cycles. It is resumable, retains all free-tier guards, and requires the scheduled cloud jobs to be paused while it runs. The same local tooling can seed canonical HRV and sleep objects from existing raw Garmin JSON exports, skipping anything already present in R2.

Historical coach generation runs as a separate R2-only consumer after scheduled refresh and other activity-producing workflows. Manual refresh prepares its selected analyses directly and skips the automatic historical follow-up. The historical consumer keeps a per-activity source index, so unchanged FIT/TCX artifacts are not reread on every backfill cycle.

Manual refresh:

gh workflow run refresh.yml --repo "<owner>/<repo>" -f include_granular=true

This is a broad source refresh that may contact Garmin and write private R2; it is not a workaround for an exhausted targeted job or a held duplicate guard. Stored-data/index repair and source refresh are different operations; see the installation index-repair command and R2-only Coach Input repair.

Optional chat-triggered refresh requires a fine-grained, single-repository GitHub token with Actions: read and write. Store both values as Worker secrets, never in wrangler.jsonc:

cd worker
npx wrangler secret put GITHUB_REPOSITORY
npx wrangler secret put GITHUB_ACTIONS_TOKEN
npm run deploy -- --no-upload-source-maps

Use owner/repository for GITHUB_REPOSITORY. Without these optional secrets, all read tools still work and only on-demand refresh is disabled.

Free-tier design

The workflows use R2 Standard storage and fail closed before projected usage exceeds conservative project limits: 5 GiB stored, 100,000 objects, 250 writes per run and 512 MiB uploaded per run. Authenticated MCP calls are limited to 30 per minute per identity. These application limits are not an account-wide or monthly spending cap: stored history, retries, overlapping work and combined R2, Workers and Actions usage still count. Per-job guards and synthetic request reductions do not guarantee free operation or a total performance improvement.

The public template exposes only read tools by default. Installers may opt in to immutable coach-profile and append-only activity-context writes; accepted writes then have an exact 60-per-identity UTC-day ceiling in addition to short cooldowns.

Coach analysis is deliberately outside the Worker CPU path. The scheduled job uses existing R2 artifacts only, processes 50 activities per run, and is limited to 60 writes and 64 MiB per run. Historical sleep and body-composition jobs use up to 100 dates per stream while retaining the shared 250-write ceiling. The activity scheduler keeps its 50-activity Garmin limit but carries unused capacity across year boundaries. Once complete these jobs perform no further writes until a relevant source, profile or user context changes.

Check the installer's actual account plan, accumulated usage and current terms before changing budgets or schedules:

Privacy and security

  • Access is allow-listed by identity in the installer's own Zero Trust account.

  • The Worker verifies signature, issuer, audience, expiry and human identity.

  • The Worker accepts only the configured production hostname and is read-only unless the installer explicitly enables bounded append-only tools.

  • Garmin and R2 credentials stay in encrypted GitHub/Cloudflare secrets.

  • R2 is private and reached through a Worker binding.

  • Generated datasets and tokens are ignored by Git.

  • Responses use no-store; request and object sizes are bounded.

  • Refresh requests are rate-limited, cooldown-protected and atomically leased.

Read Security before making an installation available outside a personal account.

Maintenance

Shared synthetic sleep/HRV tests exercise the complete Python import, R2 objects and indexes, and authenticated MCP responses in the local Workers runtime. They cover changed data in warm chats, interrupted index updates, recovery and summary cache refresh. See health contract tests for coverage and local commands.

Dependabot proposes weekly Python, npm, Wrangler and GitHub Actions updates. Review and merge only after CI passes. A weekly upstream workflow opens or updates an issue when the original project changes. It never merges or pushes upstream code automatically; every change must be reviewed and adapted manually.

Useful documents:

Scope

Slipstream supports Garmin's official Personal API alongside the existing community garminconnect connection. Their data coverage differs; see the connection comparison. Both adapters may need maintenance as Garmin changes its interfaces. Slipstream is intentionally single-tenant. Ordinary ingestion and MCP are read-only with respect to Garmin fitness data; the optional local dated chart-reload command has its own explicit operator authorization and narrow guard.

The reviewed Garmin client is pinned to garminconnect 0.3.20. This is a compatibility update, not an expansion of exposed Garmin methods, collection or permissions. See SDK compatibility and safe upgrade order.

License and non-affiliation

MIT. Slipstream Extended is an independent derivative of the original Slipstream project by Yannique Hecht. The clean public history intentionally does not claim GitHub fork ancestry. Slipstream Extended is not affiliated with or endorsed by Garmin, Cloudflare, GitHub, Anthropic or OpenAI.

Stored overnight HR/HRV, Body Battery and stress curves are described in night signals. See explicit night context and personal reference curves for their separate provenance and bounded read contracts.

Training and subsequent nights compares recorded local activity summaries with stored UTC sleep windows using a bounded offline product; missing coverage and uncertain associations remain explicit.

Garmin connection choice

Slipstream supports the existing legacy connection (default) and the official Garmin Personal API (personal). Both feed the shared stored-data interface; Personal currently supports summaries and selected curves, with explicit limits for full activity details, sleep stages, stress and readiness. Compare coverage without network access using python -m pipeline.provider_setup --capabilities. See connection setup and same-account switching. Switching is explicit and reversible for the same Garmin account. It does not delete history, change activity identifiers or start a historical import.

Optional local HR/HRV archive history

For a new installation or later historical repair, the portable python -m pipeline.history_backfill commands provide an offline dated plan, progress and missing-date CSV, bounded local collection, persistent quota pause, explicit resume and separate verified R2 publication. Setup does not start this opt-in job. Personal archive reload is unsupported; the legacy dated reload requires its own explicit operator choice.

The optional history publisher uses the same conditional dirty-source/reference queue as ordinary ingestion. Its offline status separates delivered canonical curves from pending references. Repeating explicit R2-only publication can drain closed references without fetching Garmin again, within the same budgets.

Failure diagnostics

Application CLI/job failures include fixed categories, component/stage/operation and a bounded code-only site. Observed HTTP status appears only when retained by a typed boundary. Existing exit/partial/HOLD and retry policies stay unchanged. See failure diagnostics for fields and coverage.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    A
    maintenance
    Downloads all your Garmin health and fitness data into a local SQLite database and exposes 45 MCP tools for AI analysis, enabling assistants to query sleep, training load, HRV, and more.
    48
    107 PyPI
    166
    AGPL 3.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to query live Garmin Connect health and fitness data, including daily metrics, activities, sleep analysis, and trends via natural language.
    MIT
  • A
    license
    C
    quality
    A
    maintenance
    Garmin Connect for AI assistants: sleep, HRV, training readiness, activities, workouts and weight across 193 tools. Unofficial; run it locally or use the free hosted connector.
    198
    734 npm
    3
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Syncs your own Garmin Personal API data into a local SQLite archive and lets any MCP-capable AI assistant query sleep, HRV, stress, body battery, training and activity trends through natural language, with optional interactive charts. Everything runs locally with your own API key, so private health data stays on your machine.
    1
    Apache 2.0