Likenttt/garmin-connect-plugin-for-dsh

garmin-connect-plugin-for-dsh

A TypeScript-based Garmin Connect plugin and MCP server with secure browser-based MFA, built for DeepSeek Harness and designed to work with other AI agents.

Uncategorizedclaudeclaude-codeclaude-code-plugin

dsh-plugin-garmin-connect

A TypeScript-based Garmin Connect plugin and MCP server with official Personal API and secure browser-based MFA, built for DeepSeek Harness and designed to work with other AI agents.

English | 简体中文 | Test Report | Changelog

Developed by Li Erniu (李二牛), connecting Garmin training to your AI assistant.

This open-source DeepSeek Harness plugin and MCP connector support Garmin China and International accounts. Explore full activities and splits, sleep, heart rate and HRV with AI, then create, schedule or delete workouts or cancel calendar entries after your confirmation.

You control your account. Your password is not shared with AI. With the recommended Garmin browser sign-in, passwords and verification codes are entered only on Garmin’s official page, not given to AI or the developer. Session credentials are stored locally with restricted file permissions. Authorized fitness and health queries return data to your chosen AI client for analysis.

Works with mainstream coding agents and AI workspaces DeepSeek Harness · WorkBuddy · Qwen Work · ZCode · Claude Code · Codex · Cursor · Windsurf Connect through MCP or a SKILL.md workflow, depending on the client.

[!NOTE]
MFA support in 0.1.6: local dsh Web, the
garmin-connect-auth serve system-browser flow, and MCP URL elicitation can
bootstrap the same owner-only session for China and International accounts.
Real-account MFA completed in both regions on 2026-08-29, including a full
China-region browser-to-session-and-read chain and an International-region
system-browser DI exchange with owner-only session persistence. Browser policy
may still block an individual flow.
The older login --browser command is retained only as a diagnostic.

More Apps

Icon · App · What it does · WristTale · Read TXT and Markdown on your Garmin, Apple, and Android watch · JiaKe.app · Turn Garmin screenshots into polished assets · GameraSnap · Control your phone camera from your Garmin watch · WristAlbum · Keep a private photo album on your Garmin · WristPass · Keep cards and tickets ready on your wrist · 2FA4G · Keep offline 2FA codes on your Garmin

What It Does

This plugin connects DeepSeek Harness or any MCP-compatible AI agent to Garmin Connect, exposing your wearable data as AI-callable tools. Once installed, the agent can automatically query your activities, sleep, steps, and heart rate to provide personalized fitness insights — all through natural language.

Registered Tools

Version 0.1.20 provides 29 tools for Connect web-session accounts. Twenty-four provide queries or local advice without writing; download_garmin_activity_fit writes one local file on the MCP/dsh host. Creating, scheduling or deleting a workout and cancelling a calendar entry change Garmin data after explicit confirmation. Personal-only DSH connections and Personal MCP servers expose 15 compatible tools for Garmin reads, local FIT downloads and local coaching knowledge. Mixed DSH accounts keep the combined tool set and route each call by the selected account’s capabilities. The 13 recovery and training tools introduced in 0.1.14 depend on the published maintained SDK through an exact npm alias; see Maintained SDK dependency.

Tool · Description · Example Args get_garmin_activities · Fetch recent activities (runs, rides, swims…) with full detail by default; compact is optional · {"limit": 5} get_garmin_sleep · Sleep score, duration, and stage breakdown for a date or range · {"startDate": "2023-10-01", "endDate": "2023-10-02"} get_garmin_steps · Step totals for a date or range; goal/distance appear only when Garmin supplies them · {"startDate": "2023-10-01"} get_garmin_heart_rate · Resting, max, and min heart rate for a date or range · {"startDate": "2023-10-01", "endDate": "2023-10-02"} get_garmin_weight · Body composition (weight, BMI, body fat %, muscle mass, etc.) for a date or range · {"startDate": "2023-10-01"} get_garmin_workouts · Workout templates from your Garmin workout library (not calendar scheduling) · {"limit": 10, "offset": 0} get_garmin_profile · User profile summary · {} or omit get_running_skill_advice · Explain 8 workout types and 4 training philosophies, or collect the mandatory intake for personalized coaching · {"mode": "explain", "query": "Daniels", "language": "en"} download_garmin_activity_fit · Download an activity's original archive and safely extract its single FIT file to the account directory under the configured host parent · {"activityId": 123456789} create_garmin_workout · Preview and confirm a structured workout; optionally schedule it on scheduleDate · {"name": "Threshold 3×8min", "steps": [...], "scheduleDate": "2026-10-24"} schedule_garmin_workout · Preview and confirm a calendar date for an existing workout · {"workoutId": "123456", "date": "2026-10-24"}

Recovery and training tools (introduced in 0.1.14)

These tools are shared by DSH and MCP and map directly to the maintained SDK:

Tool · SDK method · Data and example arguments get_garmin_hrv · getHrvData · Daily HRV status, baseline and overnight readings; {"date":"2026-10-15"} get_garmin_hrv_summaries · getHrvSummaries · Daily HRV summaries; {"startDate":"2026-10-09","endDate":"2026-10-15"} get_garmin_stress · getStressData · Daily stress and available Body Battery time series; {"date":"2026-10-15"} get_garmin_stress_summaries · getStressSummaries · Daily stress summaries; {"startDate":"2026-10-09","endDate":"2026-10-15"} get_garmin_body_battery · getBodyBattery · Daily Body Battery reports and time series; {"startDate":"2026-10-09","endDate":"2026-10-15"} get_garmin_training_readiness · getTrainingReadiness · Every readiness snapshot and recovery factor; {"date":"2026-10-15"} get_garmin_daily_training_status · getDailyTrainingStatus · Daily status and acute/chronic load across returned devices; {"date":"2026-10-15"} get_garmin_training_status · getTrainingStatus · Aggregated training status, VO2 max and load; {"date":"2026-10-15"} get_garmin_training_load_balance · getTrainingLoadBalance · Four-week load balance ending on a date; {"date":"2026-10-15"} get_garmin_max_metrics · getMaxMetrics · Daily max metrics, including available VO2 max; {"date":"2026-10-15"} get_garmin_max_metrics_range · getMaxMetricsRange · Max metrics through a native range request; {"startDate":"2026-10-09","endDate":"2026-10-15"} get_garmin_race_predictions · getRacePredictions · Latest predictions for the authenticated account; {} get_garmin_race_predictions_range · getRacePredictionsRange · Prediction history; {"startDate":"2026-10-09","endDate":"2026-10-15","aggregation":"daily"}

Blood oxygen and respiration (introduced in 0.1.18)

These read-only tools are shared by DSH and MCP and use the maintained SDK's authenticated HTTP transport. They preserve the complete service response, including available summary fields, descriptors and time series:

Tool · Client method · Data and example arguments get_garmin_spo2 · getSpO2Data · Daily blood oxygen (SpO₂) data; {"date":"2026-10-20"} get_garmin_respiration · getRespirationData · Daily respiration data; {"date":"2026-10-20"}

Ask, for example: “Show my blood oxygen and respiration records for October 20, 2026.” Both tools take a single date; no range parameter is accepted. Availability depends on the selected account, date and recorded device data. Missing fields, null and empty arrays stay missing; they are not converted to zero. Update the plugin/MCP server and reconnect before using these tools, then check the actual tool schemas.

On 2026-10-21, existing China and International sessions passed the shared DSH/MCP read checks, and all four new-tool calls succeeded in a real Harness desktop conversation using the local release candidate. The International account returned blood oxygen and respiration records; the China account returned successful responses with no measurements on the tested dates. See the verification record.

Daily tools use date, defaulting to the host's current local date. Range tools use inclusive startDate and endDate; the start defaults to today and the end defaults to the start. Race prediction history accepts aggregation: "daily" (default) or "monthly", with a maximum calendar span of 366 days. Inputs must be real calendar dates in YYYY-MM-DD format. The service response fields, device maps, unknown fields and complete time series are retained. null and empty arrays are valid no-data results, not authentication failures.

When multiple Harness accounts are configured, add the stable account ID shown in settings as the tool's account argument. With only one configured account, the parameter can be omitted. Display aliases and regions help identify accounts but do not change their IDs. This also applies to all recovery tools, for example {"account":"personal","date":"2026-10-15"}. Standalone MCP uses the account configured for its process; select the corresponding MCP server instead of adding an account argument.

Workout creation is a two-call flow. The preview response includes a one-time confirmationId; after the user approves the unchanged preview, call the tool again with the same definition, confirmed: true, and that confirmationId. An ID expires after 10 minutes and cannot be reused.

Schedule a workout (0.1.20)

With a Connect web-session account, you can ask: “Create this workout and arrange it for 2026-10-24” or “Schedule workout 123456 for 2026-10-24.” Personal API accounts remain read-only. This capability is available in 0.1.20.

  • New workout: add optional scheduleDate: "2026-10-24" to

create_garmin_workout. One preview covers both the workout and its date; after explicit approval, repeat the unchanged inputs with confirmed: true and the returned confirmationId. Without scheduleDate, creation saves only to the library.

  • Existing workout: preview schedule_garmin_workout with workoutId and date,

then confirm the same account, workout and date with confirmed: true and the one-use confirmationId. Changing any of them requires a fresh preview and approval.

  • Result: a successful calendar write is “scheduled, waiting for Garmin Connect

sync.” The plugin does not trigger watch synchronization or confirm delivery to the watch. Scheduling adds a new calendar entry; moving or cancelling an existing entry is a separate, explicitly requested operation.

If the workout is created but scheduling fails, retain the returned workoutId. Read the target date with get_garmin_scheduled_workouts; if scheduling is still needed, preview and confirm only schedule_garmin_workout. Do not repeat creation. Read back any uncertain write outcome before another attempt.

The development candidate passed a real Harness desktop check with the China main account: both creation with a date and scheduling an existing template succeeded. The test template and both calendar entries were removed afterward; the original 42 library entries were preserved. See the verification record.

Workout deletion and calendar cancellation (0.1.17)

Version 0.1.17 introduced these three workout management tools (26 tools in that release):

Both write operations passed a live Harness desktop check with the China account; see the workout management verification record (Chinese).

Tool · Purpose · Preview arguments get_garmin_scheduled_workouts · Read an inclusive range of up to 31 calendar days and discover actual schedule IDs · {"startDate":"2026-10-18","endDate":"2026-10-24"} delete_garmin_workout · Delete a template from the workout library · {"workoutId":"123456"} unschedule_garmin_workout · Cancel one calendar entry while retaining its library template · {"scheduleId":"654321"}

workoutId and scheduleId identify different resources. Positive decimal ID strings are accepted; numeric IDs must be JavaScript safe integers. Both destructive tools first read the target and return a preview. After user approval, submit the same target, confirmed: true and its confirmationId. Confirmations bind the account, operation and target details, expire after ten minutes and work once; a changed target requires a new preview. Read back uncertain outcomes before another attempt; writes are not automatically replayed.

Personalized running coaching

get_running_skill_advice deliberately separates explanation from planning:

  • mode: "explain" explains a workout type or training philosophy. It does not

invent an athlete-specific schedule.

  • mode: "personalized" is required for any recommendation or plan. Before it

returns planning material, the tool requires answers for all six intake areas below. Missing answers are returned as focused questions; Garmin activity data is not fetched and a schedule must not be generated yet.

Intake field · What the assistant must ask goal · Target distance/event, future ISO YYYY-MM-DD date, and completion or ideal/minimum time goal currentPerformance + performanceBasis · A representative race/time trial from the past two years, result, non-future date, effort/conditions, or an explicit no_recent_benchmark trainingBackground · Running history and recent 4–8 week volume, frequency, long run, quality work, and interruptions availability · Available days/time, fixed rest and long-run days, terrain/facility limits, strength-training time, and whether double days are possible healthConstraints + hasWarningSymptoms · Current/past-year injury, pain, relevant disease/medication, sleep and recovery, plus an explicit warning-symptom boolean trainingPreference + preference details · steady, hard_easy, or mixed, plus maxQualitySessionsPerWeek (0–7) and intensityGuidancePreference (pace, heart_rate, rpe, or mixed)

If hasWarningSymptoms is true—for example current chest discomfort, unusual breathlessness with mild activity, fainting/dizziness, or abnormal palpitations—the tool returns a safety stop without workout material or Garmin activity access. It advises medical clearance and does not diagnose. If performanceBasis is no_recent_benchmark, planning material instructs the assistant to begin with easy base work or a low-risk benchmark instead of inventing precise threshold or interval paces.

The compact philosophy layer contains:

  • Hansons — frequent, more evenly distributed mileage, pace discipline, and

cumulative fatigue; its 16-mile long run is not a standalone prescription.

  • Jack Daniels — derive VDOT and E/M/T/I/R intensity from current, recent

performance, never from the goal time.

  • Norwegian threshold — borrow controlled, non-exhaustive threshold work and

hard/easy separation; double-threshold days are not prescribed by default.

  • Polarized training — keep most work genuinely easy and a small amount

clearly hard; 80/20 is a direction rather than an exact quota.

Recent Garmin runs may supplement this intake but never replace the athlete's answers. The method notes and evidence boundaries are summarized in the training-method research note. Each philosophy and workout-card output labels its statements as system_principle, research_evidence, or application_inference so a method definition or coaching inference is not misrepresented as comparative proof.

Quick Start

1. Install this plugin — from the npm registry (recommended)

npx @deepseek-ai/dsh plugin --profile web add dsh-plugin-garmin-connect

This single command installs the dependency and activates the plugin layer — the first run automatically initializes the web profile. You only need pnpm on your PATH:

npm install -g pnpm

Verify the plugin layer is composed without booting:

npx @deepseek-ai/dsh --profile web --dump-config | grep -A 2 garmin-connect

Other install sources:

# Local checkout (development)
cd garmin-connect-plugin-for-dsh && npm install
npx @deepseek-ai/dsh plugin --profile web add .

# GitHub source install
npx @deepseek-ai/dsh plugin --profile web add github:<owner>/<repo>

2. Install the Harness CLI (if you haven't already)

npx @deepseek-ai/dsh web

The web UI starts at http://127.0.0.1:3080 by default. If you launch Harness via npx, keep using the same prefix for the commands below (npx @deepseek-ai/dsh …); if you have dsh installed globally, you can drop the npx @deepseek-ai/ prefix.

3. Configure the Garmin account when you are ready to sign in