Skip to content

Latest commit

 

History

739 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Physiquinator

.NET 11 .NET MAUI Blazor Hybrid License Platform Build GitHub Release Android APK Windows ZIP

A cross-platform workout tracking app built with .NET MAUI and Blazor Hybrid. Plan workouts, log sets against a rest timer that keeps running across apps, track progress and personal records, and ask an on-device AI assistant to analyze your training. All data lives in a local SQLite database and works offline.

It also ships a web client with a Model Context Protocol (MCP) server, so any AI agent (Claude, Cursor, Copilot) can query your workout history and manage your plans.

Live Demo — Try in browser

No install, no account. Data stays in your browser.

Download - Preview - Features - Agent API (MCP) - Architecture - Tech stack - Getting started - Testing and CI


Download

Android. Install the latest signed APK (~115 MB, Android 7.0+):

Download Physiquinator for Android

Windows. Download and extract the ZIP (~70 MB):

Download Physiquinator for Windows

Requires .NET 11 Desktop Runtime (one-time, free). Extract the ZIP and run Physiquinator.exe. No installation needed. See WINDOWS-INSTALL.md for troubleshooting.

Every v* tag builds a signed APK and a Windows package via .github/workflows/release.yml. On first Android install, allow Install unknown apps for your browser. Updates keep your local SQLite data. The app checks GitHub releases on start and shows an update prompt in Settings.

The app seeds sample plans and workouts on first launch so you can explore immediately.


Preview

Live workout - Plans home - AI assistant

Active workout with rest timer    Home dashboard and plan list    AI assistant chat


Activity history - Session summary - Exercise detail

Workout history with activity grid    Completed session summary    Per-exercise session history


Create plan - Edit plan - Settings

Create a new workout plan    Edit workout plan exercises    Settings with appearance and JSON backup


Features

AI assistant

  • In-app chat with streaming responses and 15 built-in tools: create and edit workout plans, log bodyweight, query training history and progression, and configure rest timer or application settings.
  • Provider presets for OpenAI, OpenRouter, OpenCode, local Ollama instances, or any custom OpenAI-compatible endpoint.
  • Clipboard bridge for closed models such as Gemini or ChatGPT that have no API access. Copy a generated prompt carrying your training context and the app's action schemas into the web chat, then paste the reply back. The app parses the actions, shows a summary of each, and applies them through the same tool registry. No API key required.
  • Full parity with external AI agents via MCP (see Agent API).

Workout plans and live tracking

  • Configurable plans with custom exercises, rest intervals, and target sets and reps.
  • Three logging types per exercise: weight and reps, bodyweight reps with an optional added-weight offset, or plain duration.
  • Bodyweight share for calisthenics: volume counts a configurable percentage of your logged bodyweight, pre-filled from a built-in catalog (push-ups 65%, pull-ups 100%). Weighted variations such as weighted pull-ups add their plate load on top.
  • Real-time set logging with weight and rep steppers, undo support, and completion summaries with total volume and newly achieved personal records.
  • Session-to-session carryover: each set's weight and reps pre-fill from the same set number in your most recent session of that plan, falling back to the plan defaults where no history exists.

Rest timer

  • Accurate interval countdown with quick-add increments, reset, and skip controls.
  • On Android, a draggable floating overlay runs inside a foreground service to maintain countdown visibility across apps, with optional audio, haptics, and exact alarms that survive Doze mode.

History and analytics

  • 53-week activity heatmap, per-exercise progression charts, automatic personal record tracking (weight, reps, volume, session duration), and schedule-aware streaks that account for rest days.
  • Bodyweight exercises compute their volume from your current logged bodyweight, so set volume reflects real load rather than zero.

Profiles and data management

  • Isolated user profiles with one-tap switching.
  • Offline-first local SQLite persistence with JSON backup and restore (plans, history, preferences).
  • Automated GitHub release update checks on Android and Windows.

Agent API (MCP)

The web client exposes all assistant tools over the Model Context Protocol (Streamable HTTP). MCP-compatible agents connect to https://<host>/mcp. With the default launch settings (dotnet run --project Physiquinator.Web), the local endpoint is http://localhost:5149/mcp.

All 15 tools, including get_workout_plans, create_workout_plan, log_bodyweight_entry, and get_workout_history_stats, publish standard JSON schemas. Destructive actions (delete_workout_plan, delete_bodyweight_entry) prompt for user confirmation using the protocol's input_required flow.

Configuration (appsettings.json or environment variables):

"Mcp": {
  "ApiKey": "",     // Required in production: /mcp rejects requests without a matching X-Api-Key or Authorization header
  "CorsOrigins": "" // Comma-separated allowed origins for browser-based clients
}

Web client

Physiquinator.Web is the same Blazor UI as a server-rendered web app, plus the MCP endpoint at /mcp. Every account gets its own SQLite database with cookie auth and PBKDF2 password hashes. While the page is open, the server mirrors databases to browser IndexedDB. The app ships security headers, rate limiting, and a /healthz readiness probe.

Run it locally with dotnet run --project Physiquinator.Web. The /mcp endpoint rejects requests without a matching API key, so set Mcp__ApiKey before hosting publicly. Optionally set AUTH_DEMO_USERNAME and AUTH_DEMO_PASSWORD for a demo login. Serve the app behind an HTTPS reverse proxy that sets X-Forwarded-* headers.


Browser client (static)

Physiquinator.Wasm compiles the same Blazor UI to WebAssembly so it runs entirely in the browser with zero server. There are no accounts and no cold starts. Data lives in real SQLite executing in WebAssembly, with e_sqlite3 linked via native dependencies, restored from browser Cache Storage on boot and written back by a 20-second autosave plus pagehide hooks. The browser is the source of truth. JSON backup and restore remain the cross-device bridge.

Run it locally with dotnet run --project Physiquinator.Wasm (requires the wasm-tools workload). Publish a static bundle with dotnet publish -c Release, then serve the wwwroot output from any static file server or deploy .github/workflows/deploy-web.yml, which uploads it to Cloudflare Pages via wrangler. Notes:

  • Data is per-browser. Clearing site data deletes your history, so use Settings export regularly.
  • AI providers must send CORS headers for direct browser calls. Ollama needs OLLAMA_ORIGINS configured.
  • The MCP endpoint is not part of this host. Use Physiquinator.Web for agent access.
  • tools/web-e2e/wasm-persist-e2e.mjs verifies persistence end to end.

Architecture

Five projects sharing a common domain model and service layer:

Project Purpose
Physiquinator.Core Domain model, SQLite repositories, and business logic (workouts, history, stats, AI assistant, backup, updates)
Physiquinator.UI Blazor Hybrid UI (Razor class library): pages, components, and theming
Physiquinator .NET MAUI host for Android, iOS, macOS, and Windows
Physiquinator.Web ASP.NET Core web host: browser-rendered UI and MCP endpoint
Physiquinator.Wasm Blazor WebAssembly host: fully local static build
Physiquinator.Tests xUnit test suite covering repositories, services, and the MCP surface

Key design points:

  • Shared Blazor Hybrid UI: The same Razor component tree renders natively via WebView2 in MAUI and on the web.
  • Platform abstractions: Notifications, vibration, file transfer, and update installation are abstracted behind interfaces with native, no-op, and test-double implementations.
  • Unified service registration: AddPhysiquinatorServices() registers core dependencies across both hosts (singletons on MAUI, scoped per Blazor circuit on Web).
  • Background rest timer: On Android, the rest timer runs within a foreground service with a draggable overlay and exact alarms.

Tech stack

  • .NET 11 with .NET MAUI (Android, iOS, macOS, Windows) and Blazor Hybrid
  • MudBlazor Material Design components and Markdig for AI response rendering
  • SQLite via sqlite-net-pcl - local, offline-first storage
  • OpenAI-compatible client with SSE streaming and tool-call loops and ModelContextProtocol.AspNetCore MCP server
  • Plugin.LocalNotification, MAUI Essentials, and Android foreground services
  • GitHub Actions workflows for CI, SonarCloud analysis, and signed releases, plus Playwright for E2E tests and screenshot generation

Getting started

git clone https://github.com/kadato/Physiquinator.git
cd Physiquinator
dotnet restore

# Run on Windows
dotnet build -t:Run -f net11.0-windows10.0.19041.0

# Run on Android (device/emulator)
dotnet build -t:Run -f net11.0-android

# Run the web client (includes the MCP server on /mcp)
dotnet run --project Physiquinator.Web

# Run the tests
dotnet test Physiquinator.Tests/Physiquinator.Tests.csproj

# Enable format checks and commit linting (one time)
./install-hooks.sh

Requires the .NET 11 SDK (pinned in global.json) and the MAUI workload.

To build the Android APK without installing an Android SDK, see DOCKER.md. To regenerate the screenshots in docs/ on any OS, build Physiquinator.Web once and run node tools/screenshot-generator/screenshot-web.js.


Testing and CI

  • xUnit tests covering repositories, workout, session, and history services, stats, formatting, the AI tool registry, and the MCP surface
  • CI on every push and PR: restore, build, test, and dotnet format verification (.github/workflows/ci.yml), including a Release publish of the WebAssembly host
  • SonarCloud analysis with coverage (.github/workflows/sonarcloud.yml)
  • Tag-based releases (v*): a signed Android APK and Windows package are published automatically (.github/workflows/release.yml)
  • Web deploy: v* tags and manual runs publish the WebAssembly build to Cloudflare Pages (.github/workflows/deploy-web.yml)
  • Web E2E: Playwright suite in tools/web-e2e covering registration, seeded plans, and the IndexedDB sync roundtrip. Start the web host on port 8080, then run the tests:
    dotnet run --project Physiquinator.Web --urls http://localhost:8080
    cd tools/web-e2e
    npm test
    To test a host on another port, set PLAYWRIGHT_BASE_URL.

About

Cross-platform workout tracker built with .NET MAUI and Blazor Hybrid. Rest timer with Android floating overlay, AI assistant, analytics, and MCP server.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages