dsh-coros-mcp
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
dsh-coros-mcp
Bridges the official COROS (高驰) MCP server into DeepSeek Harness. One install exposes the full mcp__coros__* tool set: sleep, HRV, resting heart rate, recovery, training load, activities and FIT files, plus workout / training-plan CRUD and scheduling (34 tools on the current endpoint; may change with the server).
Self-contained: the stdio bridge, the OAuth login flow and token refresh all live in this package. No external CLI, no absolute paths in your profile, no local callback port.
Highlights
Zero runtime dependencies — plain Node.js built-ins (
fetch,crypto,fs,http); nothing tonpm install.Self-contained OAuth — dynamic client registration + PKCE(S256) + COROS CLI login-session flow;
login-start/login-finishare separate processes and open no local port.Survives DSH upgrades —
engines.dshis a bottomless minimum (>=0.2.1-rc.1), and if a future DSH changes the MCP-client JS API the plugin falls back to mounting the same row through the core Cordis Loader. It is not silently gated off by a version bump.Tokens stay local —
~/.dsh/coros-mcp/<region>/token.json(0600), outside the profile config, never printed in logs, no telemetry, no third-party server in the data path.Bridge fixes real MCP schema issues — COROS serves
tools/listschemas with top-level$defs/$ref; the bridge inlines them so providers do not rejectcreateScheduledWorkoutwithPointer '/$defs/Section' does not exist.Rotation-safe refresh — COROS rotates the refresh token on every refresh; bridge and login CLI serialise refreshes with one cross-process file lock.
Works Outside DSH too —
lib/proxy.mjsis a standard MCP stdio server usable from any MCP client.
Related MCP server: coros-training-mcp
Architecture
DeepSeek Harness
└─ dsh-coros-mcp (host plugin, this package)
└─ registers the DSH MCP client (serverName=coros)
│ JSON-RPC / stdio
▼
lib/proxy.mjs bridge: token cache, refresh with a file lock, tools/list $ref inlining
│ HTTPS POST + Authorization: Bearer <access_token>
▼
https://mcpcn.coros.com/mcp (official COROS MCP, CN region)The bridge exists because DSH's MCP client speaks stdio / static headers while the COROS endpoint requires expiring OAuth 2.0 bearer tokens.
Login (lib/login.mjs) uses COROS' gateway CLI login session: dynamic client registration + PKCE(S256) + browser authorization + polling for the one-time loginTicket + server-side code exchange. No local listener is started, so login-start and login-finish are independent processes and Windows has no port conflicts.
Does a DSH upgrade disable it?
No longer because of a version mismatch. How it works:
At profile start DSH evaluates
engines.dsh(app-boot→evaluatePluginCompatibility) withsemver.satisfies(..., { includePrerelease: true }). Earlier builds declared a finite range (the 0.2.1 line plus a single 0.2.2 RC); when DSH auto-updated to a newer RC the range no longer matched, so the plugin was skipped silently — that is why the COROS tools disappeared after a DSH update.Since 1.0.2
engines.dshis a bottomless minimum:>=0.2.1-rc.1. WithincludePrerelease: truethat covers 0.2.1, 0.2.2, future 0.2.x RCs, 0.3.x, 1.x — normal DSH upgrades will not gate it out again.Belt and braces: if a future DSH release changes the
@deepseek-ai/dsh-mcp-clientJS exports, the plugin falls back to mounting the same MCP-client row through the core Cordis Loader (ctx.loader.create, the same path profile patches use). Only when both registration paths fail does it log an explicit[coros-mcp] could not attach the DSH MCP clientwarning.The one case not guaranteed: a breaking DSH API change where both registration paths are gone. Install a freshly built plugin for that DSH version; tokens and login state are unaffected.
A GitHub/tarball install does not auto-upgrade the plugin itself; re-run
dsh plugin add <new tgz>when a new build is available.
Install
Requires DeepSeek Harness ≥ 0.2.1-rc.1 (engines.dsh is a bottomless range, so future versions are not blocked) and Node.js ≥ 20 (the DSH runtime provides one).
# tarball (recommended for sharing)
& '<DSH>\resources\runtime\cli\bin\dsh.cmd' plugin --profile desktop add 'github:xsnnnnnn/dsh-coros'
# linked directory (development)
& '<DSH>\resources\runtime\cli\bin\dsh.cmd' plugin --profile desktop add 'D:\path\to\dsh-coros-mcp'No local build needed: download
dsh-coros-mcp-<version>.tgzfrom GitHub Releases, or install straight from the repository:dsh plugin --profile desktop add 'github:xsnnnnnn/dsh-coros'.
Then enable dsh-coros-mcp in Settings → Plugins and restart DSH if needed.
Migrating from a hand-wired setup: back up the profile
cordis.patch.ymland delete the manualid: mcp-coros@deepseek-ai/dsh-mcp-clientrow. Keeping both registers the samemcp__coros__*tool names twice and the tool registration fails.
Login
node '<package>\lib\login.mjs' login-start # prints/opens the authorization URL
node '<package>\lib\login.mjs' login-finish # completes the session, caches the token
node '<package>\lib\login.mjs' login-status # offline status
node '<package>\lib\login.mjs' refresh # refresh now
node '<package>\lib\login.mjs' logout # delete local token/pending filesTokens live in
~/.dsh/coros-mcp/<region>/token.json(0600, atomic writes). That is outside the profile directory, so profile-config backups never capture them.Existing
~/.coros-mcp-skill-gateway-ts/<region>/token.json(the official COROS CLI cache) is read as a fallback, so an existing login keeps working with zero migration. A new login writes to the plugin-owned path, which wins afterwards.Access tokens last 30 days. The refresh token rotates on every refresh and the old value dies immediately, so the bridge and the login CLI serialise refreshes with one file lock (
token.json.lock).Region: inferred from the cache; override with
--region cn|eu|usor configuration.
Configuration
Optional config: fields on the bundle row (defaults are built in):
Field | Default | Meaning |
|
| Tool prefix ( |
|
| Token cache root |
| inferred |
|
| per region | Override the OAuth issuer |
|
| Override the MCP endpoint |
| auto-detected | Node executable used to spawn the bridge |
|
| Per-request timeout towards COROS |
|
| Per-tool-call timeout (DSH side) |
|
| Fail profile startup when the bridge cannot start |
|
| Keep installed but disconnected when |
Environment fallbacks (lower priority): COROS_MCP_CACHE_ROOT, COROS_MCP_REGION, COROS_MCP_ISSUER, COROS_MCP_URL, COROS_MCP_TIMEOUT_MS.
Standalone use
lib/proxy.mjs is a plain MCP stdio server and works with any MCP client:
{
"mcpServers": {
"coros": { "command": "node", "args": ["D:\\path\\to\\dsh-coros-mcp\\lib\\proxy.mjs"] }
}
}Diagnostics:
node lib\proxy.mjs --status # region / cache / expiry, offline
node lib\proxy.mjs --selftest # real initialize + tools/list against COROSTroubleshooting
Symptom | Fix |
No |
|
| run |
| refresh token rotated/revoked — log in again |
| delete |
Tools disappear after a DSH upgrade | 1.0.2+ is no longer gated by the version check; if it still happens, search the DSH log for |
Privacy
Tokens never leave the machine, are stored 0600 outside the profile, and are never printed; logs contain only region, endpoint and expiry metadata. The plugin makes no network request at startup — only tool calls, --selftest and explicit login/refresh commands reach COROS.
Development
npm test # 39 unit + mock-issuer end-to-end tests (no network)
npm run status # offline status
npm run selftest # real endpoint: initialize + tools/list
npm pack # prepack runs scripts/prepack-check.mjsRepository layout
Path | Purpose |
| Host half: registers the DSH MCP client (direct import + Loader fallback) |
| stdio↔HTTP bridge ( |
| Self-contained OAuth: |
| Token cache, region resolution, refresh with a cross-process file lock |
| Bundle manifest and plugin metadata |
| Plugin icon (DSH plugin page / marketplace card) |
| 42 offline tests, including the full mock-issuer login/refresh flow |
| Pre-publish static checks (manifest/icon/secret leakage) |
Compatibility & license
engines.dsh:>=0.2.1-rc.1(no upper bound, covers future releases; DSH evaluates withincludePrerelease: true);dsh.compatibility.dshReleases:0.2.1-rc.5,0.2.2-rc.1= compatible.Node.js ≥ 20, no third-party runtime dependencies.
MIT. COROS and 高驰 are trademarks of their owner; this project is unofficial.
Protocol details were derived from the public COROS gateway endpoints and the official CLI's observable behaviour; no code from the UNLICENSED official npm packages is copied or bundled.
See README.zh.md for the full Chinese documentation.
This server cannot be deployed
Maintenance
Related MCP Connectors
Access COROS activity, training and health data, and manage training plans and workouts.
Pace is a remote MCP server that exposes wearable and fitness data to Claude via the Model Context Protocol. It connects to Garmin, Oura, Whoop, Polar, Fitbit and 20+ devices and provides 15 tools for querying sleep, activity, recovery, and training data. Hosted on Google Cloud Run, OAuth 2.1 authentication, Streamable HTTP transport. Instructions: First you need to create an account at: https://pacetraining.co and connect your wearables. After that you can connect the remote Server via Custom Connector in Claude and OAuth 2.1 Flow startet.
Multi-tenant hosted MCP server for Oura Ring — 21 read-only tools, OAuth per user.
Hosted MCP server with managed OAuth for 15+ toolkits: Google Workspace, Fitbit, Oura, Kalshi, etc.
Related MCP Servers
- AlicenseAqualityAmaintenanceA Model Context Protocol (MCP) server that fetches sleep, HRV, and training data from the unofficial Coros API and exposes them to AI assistants like Claude, enabling natural language queries about fitness metrics and workout management.26125MIT
- AlicenseBqualityCmaintenanceRunning-first MCP server for COROS that allows authoring, editing, and scheduling running workouts, plus accessing sleep, HRV, training load, and activity exports.2926 PyPIMIT
- FlicenseNot gradedqualityDmaintenanceExposes Garmin Connect health data (steps, sleep, HR, HRV, stress, activities, etc.) as tools for MCP-compatible clients like Claude.-
- AlicenseBqualityCmaintenanceA read-only MCP server that lets AI agents query a user's own Garmin Connect data via Garmin's official Personal API. It exposes activities, daily wellness metrics, sleep and recovery, and body/profile data as tools for natural-language analysis.21Apache 2.0