BikeControl (SwiftControl)
Use Zwift Click, Zwift Play, Shimano Di2, or any Bluetooth controller with MyWhoosh, Rouvy, Zwift, and more. Free to try on iOS, Android, Windows, and macOS.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Interval running with an AI coach: ChatGPT reads and writes workouts over MCP + OAuth 2.1 (multi-user, Google sign-in, Next.js 16, Better Auth, Neon)
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Interval running with an AI coach. Your assistant (ChatGPT, Claude or any MCP client) plans the intervals over OAuth; the iPhone app plays them with beeps that keep going with the screen locked, and sends each run back.
The live site is open: sign in with any Google account.README 전문 보기 ↗Interval running with an AI coach. Your assistant (ChatGPT, Claude or any MCP client) plans the intervals over OAuth; the iPhone app plays them with beeps that keep going with the screen locked, and sends each run back.
pacebeep.vercel.app · Connect ChatGPT · Run your own
The live site is open: sign in with any Google account.
/mcp.The auth + MCP layer is also available on its own as a clean template: MCP OAuth Starter. Single-owner sibling project: English Coach.
With the screen locked, the run stays on the lock screen as a Live Activity, and in the Dynamic Island while you use other apps: orange to run, blue to rest.
On the web, the week your coach planned, what you ran and how it felt, and which apps can see your data.
APPLE_* variables are set), "Continue with Google" (when GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET are set) or email + password (Better Auth). With Apple or Google on, new accounts come only from them, whose emails are verified, so nobody can pre-register a password account on someone else's email; password sign-in keeps working for existing accounts. Set SIGNUP_ENABLED=false to close registration entirely. Every new account starts with three workouts, so the app has something to play before an assistant is connected./oauth/consent, and gets an access token bound to <BETTER_AUTH_URL>/mcp. /mcp also checks on every request that the user's approval still exists, so Disconnect on the dashboard cuts access at once (for that user only).workouts (plans: an interval run, or a full workout whose blocks list strength exercises and runs in the order the coach chose), runs (what happened: device = recorded by the phone, manual = entered/reported) and run_feedback (RPE and notes – self-reported, kept apart from measurements). Every write carries a request_id; replaying it returns the same row and never duplicates.| Tool | What it does |
|---|---|
get_summary | Runs and distance for 7/30 days, last run, upcoming workouts |
list_workouts / get_workout | Workout plans |
create_workout / plan_week | Create one / several scheduled workouts |
update_workout | Change a plan |
list_runs / get_run | Runs with planned vs. actual per interval, plus feedback |
record_run | Store a run (manual when the runner reports it in chat) |
add_run_feedback | RPE 1–10 and notes for a run |
The app is one more OAuth client of the same server: it registers itself as a native client (redirect app.vercel.pacebeep:/oauth/callback, PKCE, no secret), the user approves it like an assistant, and it calls two routes with the same kind of token:
| Route | What it does |
|---|---|
GET /api/workouts | Workouts scheduled for today or later, then unscheduled ones; done once a run was recorded for it. Full workouts (blocks) only with ?blocks=1, so app versions from before them keep working |
POST /api/runs | { request_id, run, feedback? }: stores the run as device, plus the RPE. Idempotent, so the app's offline outbox resends until it gets a 2xx |
Requires Node 22+ and Docker.
cd web
npm install
npm run db:up
cp .env.example .env.local # then fill BETTER_AUTH_SECRET (openssl rand -hex 32)
npm run db:migrate
npm run dev -- -p 3200
Open http://localhost:3200 and create an account.
Requires Xcode 26 and an Apple ID (a free one works; the app then expires after 7 days).
ios/Config.xcconfig. Building your own copy: cp ios/Local.xcconfig.example ios/Local.xcconfig and set your team id and a bundle id of your own there.ios/PaceBeep.xcodeproj and Run.The app talks to https://pacebeep.vercel.app (SERVER_URL in ios/Config.xcconfig). Sign in once, ask your assistant to plan your week, and the workouts show up under From your coach; pull to refresh. Workouts are cached and finished runs wait in an outbox, so a gym without signal is fine.
The whole workout is rendered into one audio track (silence with the beeps at their exact times) and played with the background audio mode, so iOS keeps the app alive with the screen locked and the beeps can't drift. After a run the app shows whether the audio played without gaps and how late the voice cues were.
A full workout (gym) plays the same way up to each part that waits for a tap: a set done by reps waits for Done, and a run after strength waits for Ready (getting on the treadmill). The tap renders and plays the next stretch (the rest, with its beeps); a silent loop keeps the app alive in between. Done, Skip (a rest before a set) and Ready are also buttons on the Live Activity, so the phone can stay locked; reps and weight are the plan unless changed with − and + in the app.
web.DATABASE (gives DATABASE_URL).BETTER_AUTH_SECRET (openssl rand -hex 32), BETTER_AUTH_URL (your production URL), optionally SIGNUP_ENABLED.https://<your-app>/api/auth/callback/google; set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET. While the app is in "Testing", only listed test users can sign in; to publish, fill the Branding page (home page, /privacy, /terms) and click Publish app – with only the basic openid email profile scopes and no logo, no Google verification is needed.<your-app> and return URL https://<your-app>/api/auth/callback/apple, and a Key with Sign in with Apple. Set APPLE_CLIENT_ID (the Services ID), APPLE_TEAM_ID, APPLE_KEY_ID and APPLE_PRIVATE_KEY (the whole .p8 file). The server signs Apple's client secret itself on every cold start, so there is no 6-month secret to renew.vercel-build) applies web/db/migrations/*.sql before next build. Only main deploys (web/vercel.json turns off deployments for other branches): the environment variables are production-only, and giving previews the production DATABASE_URL would let any branch migrate the production database.https://<your-app>/mcp, authentication OAuth.@ and pick the app..env* is ignored; only .env.example is committed./privacy and /terms (review them for your own deployment – they name the operator and contact).Disconnect is per user: it deletes that user's consent, refresh tokens and access tokens in one transaction, and never the shared client registration.
Retries are safe: a lost response followed by a retry with the same request_id returns the same run.
MIT – see LICENSE.