TEMPO

Connect your coach — BYOK, credits & MCP

The AI coach needs a model to think with. You choose how it gets one in Settings (the gear icon) → AI connection — four cards, pick one (a fifth, Local CLI, appears only when you self-host — see the end):

Your own key (BYOK)

Pick a recipient — a provider + model + endpoint TEMPO's operator has already verified — paste your key for it, and hit Connect key. The key is only ever sent to that exact, pre-verified endpoint (never a freeform host you typed), encrypted at rest, and you can Disconnect it at any time. You pay your provider directly; TEMPO never meters BYOK turns. If no recipient is listed yet, the card says so — the operator hasn't provisioned one on your server.

TEMPO credits

Zero setup: the coach runs on TEMPO's own models and draws from your monthly balance, shown right on the card. While this mode is on, any key you stored is deliberately ignored — you're never billed twice for the same turn. If the balance runs out, the coach falls back to its deterministic engine until the next month. Top-ups are coming soon.

Monthly plan

A flat €14.99/mo for unlimited coaching. Coming soon — the card is visible but locked until it ships.

Your agent (MCP)

Drive the whole coach from Claude Code, Codex, or any MCP client — same tools, same safety gates, your automation. Two steps:

  1. Generate a token. On the MCP card, hit Generate — you get a token (tempo_pat_…) shown exactly once. Copy it now; TEMPO only ever stores its hash, so it can't be shown again (Rotate if you lose it — that invalidates the old one instantly, or Revoke to disconnect the agent entirely).
  2. Paste one snippet. The card gives you copy-paste-ready snippets with your token already dropped in:
    • a claude mcp add --transport http one-liner and a .mcp.json block for Claude Code,
    • a config.toml block for Codex,
    • and a routines bootstrap prompt (your athlete id is already filled in, and the server double-checks it against your token): paste it into your agent and it walks itself through wiring the MCP connection and standing up recurring routines — a morning readiness check, post-sync analysis, and a weekly review. If your agent ever needs to re-discover its id, it can call tempo_whoami.

That's it — no repo checkout, no database URL, nothing to self-host. The agent talks to the same hosted coach over HTTPS, authenticated by your token. The card shows when the agent last connected ("Agent last seen …") so you can tell it's actually wired up.

What your agent can do

Everything the in-app coach can read: your season, plan, today's workout, activity history, zones, races, readiness, profile, pending changes, and usage — the same data the dashboard shows you, nothing extra. Writes go through the same consent gate as the in-app coach: propose and (with your consent) commit plan changes. Your autonomy setting (Settings → Coach: safe / auto / greedy) decides how much an agent can do without asking (an outside agent's call carries no confidence, so greedy treats it exactly like auto) — anything it doesn't auto-commit is never silently dropped, it lands as a pending change you can Accept or Decline right on your plan, exactly like an in-app coach suggestion. Your keys and data never pass through a third party.

Prefer to self-host?

An advanced, self-hosted option still exists if you'd rather run your own single-athlete MCP server next to your own Postgres (stdio transport, full database access for the driving agent). It's collapsed under "Advanced / self-host" on the MCP card — most people won't need it; the hosted HTTP door above is the default for a reason.

Local CLI (self-hosted only)

If you run your own copy of TEMPO on your own machine, you can power the coach with the Claude or Codex command-line app you're already subscribed to — no API key, no per-message billing. The coach hands its prompt to the claude or codex CLI on that machine and reads the answer back; your subscription pays for it, the same way it does when you use the CLI yourself.

Turn it on in three steps:

  1. Install and log in to the Claude or Codex CLI on the server that runs TEMPO — TEMPO uses its own, separate login (isolated from any personal Claude Code session on that machine), so the one-time login command looks like CLAUDE_CONFIG_DIR=~/.tempo/claude-config claude login (the Local CLI card on Settings → AI connection shows the exact command for your server once the door is enabled).
  2. Enable the door — set COACH_CLI_DOOR=1 in your .env, or flip it on live in the creator admin panel. It's off by default, and it never appears on the hosted tempo.zepoch.io app. If you'd rather the coach's CLI ignore everything you've set up for your own Claude Code — your CLAUDE.md, skills, plugins, hooks and MCP servers — also set COACH_CLI_SAFE_MODE=1. It's off by default; TEMPO already uses its own login directory, so this is only for the extra-careful.
  3. Pick the card — open Settings → AI connection and choose Local CLI. The card only shows up once the server can see a working CLI; select Claude or Codex and a model right there and save.

One caveat if more than one athlete shares your server: everyone's coach then spends your personal subscription. It's meant for a single-user or trusted self-host, not a public multi-athlete deployment. And if the CLI ever becomes unavailable (you log out, or it's removed), the coach quietly falls back to your other configured option or its built-in engine — it won't break.

Creator MCP (admin only)

The Researcher — TEMPO's admin-tier research agent — can also be driven from your own desktop MCP client. In the admin panel open Researcher → Connect and mint a token: it's a short-lived admin credential, shown once and never stored, valid for up to 168 hours (7 days). Point your client at the same /mcp URL the athlete setup card uses and send the token as a bearer.

That connection exposes the ADMIN toolset — the workout library, the base-plan library, the global knowledge corpus and the research queue. It reaches no athlete's data: none of the personal tools (activities, memory, plan, settings) are offered on it. Revoking is immediate and total — clear the admin account's superuser flag and every outstanding token stops working at its next call.

Admin panel

Three more admin-only surfaces live behind the same creator sign-in as the runtime-config and coach-tool consoles:

Users (/admin/users) — every registered account in one table: email, display name, athlete id, roles, connected providers (Garmin, Strava…), live coaching contracts, whether the account is active and verified, and whether deletion has been requested. Search by email, name or athlete id and filter by role (athlete / coach / creator admin) or status; the filtered view's URL is shareable. Click a row to open the account: toggle Active and Verified, rename the athlete, and grant or remove creator access — that last one asks for confirmation first, because a creator reaches every account, setting and library. The same sheet grants or revokes coach access; revoking warns first, since it ends every contract that coach still holds. Coaching contracts and the credit balance are listed underneath. Roles are derived, not stored: creator admin is a flag, coach is a coach profile, everyone else is an athlete.

Workout library (/admin/workouts) — the catalog of workout templates the coach selects from and blends into a plan: TEMPO's own generated ladders, hand-authored sessions, and imported .FIT files. Filter by sport, ladder, rung, level, modality, source, license, visibility or status; click a row to edit every field, see a live preview of its steps, download the .FIT, retire/reactivate, or delete. Import .fit files as private/personal-use (the default) or, only if you hold distribution rights, as global/licensed — the panel reminds you before that choice takes effect. "Generate library" re-runs TEMPO's own ladder generators, with a dry-run preview before writing anything. The filter's Source list is whatever the catalog actually holds — TEMPO's own writers plus any catalogued third-party library (the 80/20 Endurance library, for instance, imports as 8020: 621 sessions catalogued by family, rung, sport and pool, private and personal-use until you hold the rights to open them).

Researcher (/admin/researcher) — queue a research job (nutrition, supplementation, plan, workout, FIT, library review, or a custom prompt) with optional source links; the job list updates live while anything is queued or running. Open a job to see its prompt, sources, summary, and what it wrote — a knowledge document, a draft workout template, or a FIT file — with a Cancel button while it's still running. "Run library review now" is a one-click shortcut for the weekly job. The MCP section here mints the same token described above.

Web access. Whether the coach can search the web, and where. WEB_SEARCH_PROVIDER is duckduckgo (default — free, no key or account, DuckDuckGo's results parsed server-side; nothing to set up), off (the search tool is not offered at all), brave (set WEB_SEARCH_API_KEY, a Brave Search subscription token; it is encrypted at rest, never returned by the panel, and never appears in a tool result) or searxng (set WEB_SEARCH_BASE_URL to your instance). WEB_SEARCH_ALLOW_PRIVATE_BASE lets that base point at a LAN/tailnet address, skipping the SSRF guard for that host only — turn it on solely for a SearXNG you host yourself; it never applies to Brave or to a URL the coach picks. COACH_WEB_FETCH_MAX_CHARS caps the page text the coach's page-read tool returns (default 12000, clamped 500..24000). None of this overrides the athlete's own "Let the coach look things up online" toggle, which gates every call.

Travel. How the race briefing works out the drive to a race. ROUTING_PROVIDER is osrm (default — the public OSRM demo at ROUTING_OSRM_BASE_URL, free and keyless, one request per race per briefing; it carries no traffic data, so the traffic minutes come from a time-of-day convention), tomtom (set TOMTOM_API_KEY — a free-tier key, 2 500 requests a day, buys the real historic traffic for the athlete's actual departure; encrypted at rest and never returned by the panel) or off. With no provider, or when one fails, the briefing falls back to straight-line distance at 70 km/h — the race-morning advice still appears, labelled as an estimate. Point ROUTING_OSRM_BASE_URL at your own OSRM instance if you outgrow the demo server's light-use policy.

Where did the chat connect form go?

Into Settings. The coach chat now shows a small provider · model chip — click it to jump straight to the AI connection section.