Skip to main content
Glama
aranlucas

set-and-signal

by aranlucas

Set & Signal

CI License: AGPL-3.0-or-later

Set & Signal is a privacy-first, self-hostable workout planner and set-by-set training log. It keeps the next session obvious on a phone while giving the same data a durable home: a Go API, SQLite storage, a React web app, and an OAuth-protected MCP endpoint for coaching agents.

The product identity is new; the storage and protocol identifiers are deliberately stable. Existing opengym.db files, gym_state_v1 browser state, opengym_plan exports, and native app data continue to work after the visual rebrand.

What it does

  • Build weekly plans, edit routines, and start a workout in one tap.

  • Log sets, rest timers, notes, bodyweight, and measurements with offline-friendly browser or mobile storage.

  • See adherence, estimated 1RM progress, history, and muscle recovery.

  • Import/export plans and backups without sending data to a third party.

  • Connect Grok, Cursor, or another MCP client through the server's OAuth 2.1 + PKCE flow. Preview program changes before applying them.

Related MCP server: tally-workout-mcp

Run locally

Requirements: Go 1.27+, Node 24+, and pnpm 11+.

go run ./cmd/opengym-api

# In a second terminal, during frontend work:
pnpm install
pnpm --dir web dev

For a production-shaped build, the Dockerfile builds the SPA and embeds it in the single Go binary:

docker build -t set-and-signal .
docker run --rm -p 3000:3000 -v set-and-signal-data:/data set-and-signal

Copy .env.example to .env for local overrides. At minimum, set PUBLIC_URL to the public HTTPS origin when enabling OAuth or MCP clients. Configure one or more of GOOGLE_*, GITHUB_*, or APPLE_* credentials for sign-in.

Deploy on Railway

The production topology is declared in /.railway/railway.ts: a Dockerfile-built application, health and restart policy, environment contract, and a persistent 5 GB volume at /data. Railway secrets remain stored in Railway; the source declaration only preserves them.

pnpm install --frozen-lockfile
pnpm infra:check
railway link
railway environment production
pnpm infra:plan
pnpm infra:apply

Read .railway/README.md before changing resource names, the volume mount, domain, or relying-party settings. A plan is mandatory before every apply.

Architecture

  • cmd/opengym-api — HTTP server binary

  • cmd/opengym-import — one-shot migration from a legacy ./data directory

  • internal/config — environment parsing and runtime defaults

  • internal/store — SQLite connection, goose migrations, and typed queries

  • internal/auth — signed sessions, bearer tokens, and WebAuthn

  • internal/oauth — OAuth 2.1 authorization server with DCR + PKCE

  • internal/httpapi — chi handlers, static SPA delivery, and the HTTP-mounted MCP transport

  • internal/training — training state, persistence, analytics, prescriptions, and MCP data contracts

  • internal/exercises — embedded exercise catalogue and instruction shards

  • web/catalog — source exercise catalogue and translated instruction shards

  • web/src/app — React bootstrap, routing, global styles, and client store

  • web/src/domain — framework-light exercise and training rules

  • web/src/features — route and sheet modules grouped by user flow

  • web/src/shared — reusable components, hooks, utilities, and UI primitives

  • web/src/generated — checked-in generated exercise data consumed by the app

See the architecture guide for the complete dependency direction and where new code belongs.

The frontend routes are unchanged: /home, /plan, /plan/r/$id, /workout, /stats, /history, /library, /settings, and /admin, plus the existing home sheets. The identity and visual system changed; those flows did not.

Exercise media

The catalogue is embedded, but the large exercise image and animation files are not part of the public source snapshot. The web build resolves them from a pinned commit of hasaneyldrm/exercises-dataset through jsDelivr; deployments can set VITE_IMG_BASE and VITE_GIF_BASE to an approved media host. This keeps clones and container layers small and makes the media attribution boundary explicit. See NOTICE.md before mirroring or redistributing that media.

Clean public history

This public repository starts from a reviewed, source-only root commit. The private development history and its media-bearing legacy refs were deliberately not imported. Keep web/public/img, web/public/gif, generated builds, local training data, design-review artifacts, and credentials out of future commits.

Data and privacy

Guest and mobile state stays on the device. A self-hosted server stores each authenticated profile in its own SQLite-backed state record under DATA_DIR. /data, .env, OAuth credentials, VAPID keys, and OpenRouter keys are deployment secrets and must never be committed. The optional OpenRouter-powered suggestions feature sends the prompt you choose to that provider; leave OPENROUTER_API_KEY unset to disable it.

MCP

Point an MCP client at https://your-host.example/mcp. The server advertises its OAuth protected-resource metadata, registers clients dynamically, and uses Authorization Code + PKCE. Planning writes are revision-checked: call preview_program first, then pass its expectedRevision to set_program.

Development checks

go test ./...
go vet ./...
pnpm install --frozen-lockfile
pnpm infra:check
pnpm --dir web format
pnpm --dir web lint:tailwind
pnpm --dir web lint
pnpm --dir web test
pnpm --dir web build

Please read CONTRIBUTING.md before opening a pull request and see SECURITY.md for private vulnerability reports. Product, design, internationalization, and architecture references live under docs/.

License and attribution

Set & Signal is released under the GNU Affero General Public License, version 3 or later. See LICENSE and NOTICE.md for the upstream code, body-map, exercise catalogue, instruction, and media attributions that travel with the project.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    Connect Pelaris to any MCP-compatible AI assistant for personalised fitness coaching. Plan training programs, log workouts, track benchmarks, manage goals, and get data-driven coaching insights. Supports science-based methodologies including 5/3/1, Pfitzinger, polarised training, and more. OAuth 2.0 authentication with Streamable HTTP transport. Documentation: https://pelaris.io/integrations Web
  • A
    license
    Not graded
    quality
    C
    maintenance
    Strength-training app Claude can write to: reads real workout history (planned vs actual) and writes planned workouts back into the Tally iOS app. First-party hosted remote MCP server secured with OAuth 2.1 (PKCE + dynamic client registration).
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    MCP server for TrainingPeaks that reads workouts, fitness metrics (CTL/ATL/TSB), and health data, and creates/updates/deletes planned workouts. Enables AI-powered training plan management and automated adjustment based on performance, fatigue, and injury.
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables agents to track workouts, body metrics, and training stats for registered users through a JSON-RPC MCP endpoint, with scoped agent permissions and a web dashboard.

View all related MCP servers

Related MCP Connectors

  • Manage clients, plans, sessions, habits, and billing on Trainzilla via one-click OAuth.

  • Garmin data in Claude & ChatGPT via the Garmin Health API. OAuth sign-in, no password sharing.

  • Self-hosted federated MCP gateway: one OAuth 2.1 MCP server in front of N apps, user-level scopes.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aranlucas/set-and-signal'

If you have feedback or need assistance with the MCP directory API, please join our Discord server