ICU Visor MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ICU Visor MCPshow me my five most recent activities"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Intervals.icu MCP · Cloudflare deployment template
A self-deployable Cloudflare template that connects ChatGPT to your Intervals.icu training data through MCP.
Deploy a private, single-owner gateway in your own Cloudflare account. GitHub sign-in restricts access to you; ICU Visor, the Go MCP server inside the container, provides 22 read-only tools with the default core toolset.
Your Cloudflare account · Your GitHub identity · Your Intervals.icu API key
Self-deploy · Architecture · Connect ChatGPT · Documentation
Architecture at a glance
flowchart LR
C[ChatGPT] -->|OAuth + MCP| W[Cloudflare Worker]
B[Owner browser] -->|Consent + sign-in| W
W <-->|Verify owner identity| G[GitHub OAuth App]
W <-->|Clients + grants| K[OAuth KV]
W -->|Authorized MCP requests| D[Owner Durable Object]
D --> V[ICU Visor / Go container]
V -->|API key / read-only tools| I[Intervals.icu API]Component | Role |
Worker + OAuth Provider | Public entry point; handles consent, OAuth tokens, owner checks, and MCP proxying. |
GitHub OAuth App | Verifies the configured owner's numeric GitHub identity. |
OAuth KV | Stores OAuth clients and authorization grants. |
SQLite Durable Object + Container | Routes to one named owner instance and manages the ICU Visor container lifecycle. |
Intervals.icu | Source of athlete and training data, accessed with a runtime API key. |
The Worker is the only public application ingress. It checks authorization before forwarding MCP requests; the container has no separate public endpoint. See architecture and trust boundaries for the full flow.
Related MCP server: intervals-mcp
Self-deploy on Cloudflare
This repository supplies the deployment template; you provision and operate your own instance. Workers Paid with Containers is required, and the deployment incurs Cloudflare usage charges. Single-owner routing and idle sleep are not a spending cap.
Before starting, have:
A Cloudflare account with Workers Paid/Containers.
A GitHub account and a GitHub OAuth App for owner sign-in.
An Intervals.icu account, athlete ID, and API key.
Set up with a coding agent
Fork this repository, then give your coding agent this instruction:
Inspect this repository and follow AGENTS.md's “End-to-end self-hosting setup” to deploy my own read-only intervals.icu MCP server to my Cloudflare account. Automate the implementation, checks, configuration, and deployment. Guide me through browser authorization, GitHub OAuth App creation, and secure secret entry. Confirm my account and paid provisioning before the first deployment.
The step-by-step agent runbook covers
setup through real ChatGPT acceptance. Keep your settings in ignored
deployment.local.json; keep the committed template generic. Existing deployments
should use the runbook's resume path. For manual setup, follow the
deployment guide.
Documentation
The deployment has been exercised with real GitHub OAuth, ChatGPT tool discovery, and a user-confirmed data query. This records validation of an existing instance; your deployment still needs its own acceptance checks. See validation and remaining checks.
Local checks
Use Node 24.22.0 from .node-version, npm, Docker with Linux amd64 support, and Chromium/Chrome for the browser tests. Dependencies, cf, the compatible beta Vite plugin, Go, and the upstream source commit are pinned.
npm ci
npm run check:public
npm run check
REQUIRE_BROWSER_TESTS=true npm test
npm run build
npx cf deploy --prebuilt --mode production --dry-run
docker build --platform linux/amd64 -t icuvisor-mcp:test .
npm run test:containerNormal builds and tests use no production credentials and make no intervals.icu API calls. cf build builds the image but does not deploy it. The public placeholder configuration is sufficient for CI build/dry-run checks; npm run preflight deliberately rejects it for production.
Configure privately
cp deployment.json deployment.local.json
chmod 600 deployment.local.json
# Edit deployment.local.json with your non-secret account/identity settings.
npm run preflightdeployment.local.json is ignored by Git and excluded from the Docker context. All commands use the same settings loader. ICUVISOR_DEPLOYMENT_FILE can select an explicit JSON file instead. The public deployment.json remains a placeholder template; never replace it with your personal deployment settings.
Create a GitHub OAuth App, whose callback is PUBLIC_ORIGIN/callback. It is distinct from a GitHub App installation and from ChatGPT's callback. Store GITHUB_CLIENT_SECRET and INTERVALS_ICU_API_KEY as Worker Secret entries or in an ignored mode-0600 .dev.vars file for first deployment. Never put them in chat, JSON settings, Docker arguments, logs, or source control.
Authenticate the official CLI with npx cf auth login --no-browser, verify the selected account and paid-plan requirements, and follow the deployment guide. Use cloudflare.config.ts; there is no maintained Wrangler configuration or separate Cloudflare Access gate.
Connect ChatGPT
Create a custom app/connector with the URL PUBLIC_ORIGIN/mcp and authentication OAuth. Leave predefined client ID/secret blank when optional, allowing dynamic client registration. Review consent and sign in to the configured owner's GitHub account. Only its numeric GitHub ID can authorize access.
Use Refresh tools, then Try in chat. Ask the app to fetch your athlete profile or list a few recent activities using its tools. Verify the visible tool call and compare its result with intervals.icu. Never use a correct-looking prose answer alone as evidence of a server call. Also complete the real non-owner denial check.
Security and design constraints
Standards-based OAuth discovery, dynamic registration, explicit consent, S256 PKCE, canonical audience validation, token refresh, and authorization-version invalidation.
deleteMode: noneis checked before deployment and at Worker runtime; the container also hard-codes read-only registration and disables coach mode.Current stateless Streamable HTTP with JSON responses supports protocol
2026-07-28and legacy initialization. A reviewed one-line patch exposes the option missing from the pinned upstream CLI; the binary version includes+stateless-http.One fixed owner Durable Object routes to a lite container with a ten-minute inactivity timeout. The account-required
durable_objectscheduling policy has no platformmax_instancessetting. Single-instance routing and idle sleep are not a spending cap.The gateway removes bearer tokens, cookies, and untrusted forwarding headers. It preserves standard MCP method/name/parameter headers required by current clients. No automatic tool-call retries occur.
Observability is disabled; temporary development diagnostics have been removed. There is no public diagnostics endpoint or container ingress URL.
CI checks PRs and
main; production deployment is manually triggered frommain. See CI setup.
License
Gateway code: Apache-2.0, with NOTICE. ICU Visor remains MIT-licensed; its notice accompanies the source patch and is also copied into the container. Other dependencies retain their own licenses.
This server cannot be deployed
Maintenance
Related MCP Connectors
- FlaMapOAuthapp.flamap
Your own cycling data for your AI assistant: rides, power, climbs and routes. Read-only.
Garmin data in Claude & ChatGPT via the Garmin Health API. OAuth sign-in, no password sharing.
Connect Claude to your Intervals.icu watch data for fitness, workout review, and plan writing.
Your swim, bike and run training: readiness, HRV, sleep, workouts and race predictions. Read-only.
Related MCP Servers
- FlicenseAqualityDmaintenanceEnables 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-
- AlicenseAqualityBmaintenanceProvides AI assistants with read-only access to an athlete's Intervals.icu training data, including activities, wellness metrics, zones, and planned events, for use with MCP clients like ChatGPT and Claude.15MIT
- AlicenseAqualityBmaintenanceEnables Claude and ChatGPT to access and manage Intervals.icu data, including activities, events, wellness metrics, power curves, and custom items through natural language.26GPL 3.0
- FlicenseAqualityCmaintenanceEnables chat to query cycling training data from Intervals, including athlete profiles, activities, wellness, and calendar events, via read-only tools.5-