Skip to main content

Sport Alliance MCP

Run your Magicline or PerfectGym Next studio with natural language. Ask questions or give instructions like "Book Jonas Weber into tonight's Spin class", "Pause Anna Schmidt's contract for August", or "When can Anna cancel her contract at the latest?" — and get instant answers without opening dashboards or writing code.

One install serves every Sport Alliance platform: setup asks which platform your studio is on — Magicline or PerfectGym Next — and configures the rest. Multi-brand operators can connect a Magicline studio and a PerfectGym Next club side by side in the same assistant, each with its own API key and its own permissions.

Built on the Sport Alliance Open API (Magicline docs · PerfectGym Next docs), with optional SQL analytics over the enterprise data warehouse (Magicline · PerfectGym Next, Amazon Redshift).

Not for legacy PerfectGym. This package connects to PerfectGym Next, Sport Alliance's current Open API platform. The classic PerfectGym product (perfectgym.pl, "Perfect Gym Manager") uses a different API with different authentication and is not supported here.

Supported AI clients:

What is MCP?

Model Context Protocol (MCP) is an open standard that lets AI assistants securely connect to external tools and APIs. This server acts as a bridge between your AI client and your studio platform, translating natural language requests into safe, scoped API calls. There is no server to run or keep alive — your AI client starts it on demand and shuts it down when finished.

Installation

Prerequisites:

  • uv (installs its own Python — nothing else needed):

    # macOS / Linux
    curl -LsSf https://astral.sh/uv/install.sh | sh
    
    # Windows (PowerShell)
    powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
    
  • An Open API key (tenant name + key are in your integration activation email — the base URL looks like https://<tenant>.open-api.magicline.com for Magicline studios or https://<tenant>.open-api.perfectgym.com for PerfectGym Next)

Then run the setup wizard:

uvx sportalliance-mcp setup

The first question is your platform — Magicline or PerfectGym Next (with a built-in "help me tell them apart" if you're unsure: check the hostname in your activation email). Everything after that is painted in your platform's colours. Setup asks whether the studio is production or sandbox, shows the fully resolved API host right in the key prompt so a key can't land on the wrong platform unnoticed, validates the credentials against the live API and shows the studio name the key actually opens (it is stored and re-checked every time the server starts), stores the key in your OS secret store (macOS Keychain / Windows Credential Manager / Secret Service — never in a plain-text config file), then lets you pick which AI clients to configure from an interactive checklist — detected clients are pre-selected, and Claude Code is configured via claude mcp add --scope user automatically. Restart your AI client and you're done. Run setup again any time to configure your other platform alongside the first.

To always use the latest version (auto-update on each client restart), add --auto-update:

uvx sportalliance-mcp setup --auto-update

To skip the platform question (e.g. scripted installs):

uvx sportalliance-mcp setup --platform perfectgym-next

By default, setup configures the server in a safe, read-only mode (no member data, no writes). To selectively enable elevated capabilities during setup, pass --advanced:

uvx sportalliance-mcp setup --advanced

What you'll choose (optional):

  • Member data / PII (pii tier): access member profiles (including lookup by card/barcode/QR), contracts, check-in history, account balances, payment details, transactions, and membership switch/add previews.
  • Writes (write tier): book and cancel classes and appointments, check members in and out, create customers and leads, assign memberships (zero-due offers), cancel contracts, manage idle periods (contract freezes), and log communications.
  • Individual tools (optional): after picking tiers, setup offers the same per-category tool editor as sportalliance-mcp permissions — e.g. keep class bookings but disable cancel_membership entirely. Existing per-tool disables survive a re-run of setup either way.

IMPORTANT: Enabling writes allows the AI agent to take real, potentially irreversible actions in your studio — including cancelling real member contracts and creating real bookings. Enabling member data exposes personal data of real members, with everything that implies under data-protection law (GDPR, CCPA, and their local equivalents). If you are not in a position to review each tool call before approving it, keep these disabled — especially against a production studio. If you enable them, it is your responsibility to review every action before allowing the agent to proceed.

You can change permissions at any time without re-running setup:

uvx sportalliance-mcp permissions

When both platforms are configured, permissions asks which one you mean (or pass --platform). Besides switching tiers, this opens a per-category tool editor: pick a category (memberships, appointments, classes, ...), then check or uncheck individual tools. Disabled tools are never registered with the AI client — the agent doesn't see them at all. Selections are stored as a deny-list (SPORTALLIANCE_TOOLS_EXCLUDE), so tools added in future versions are enabled by default.

Skipping permission prompts (Claude Code)

Independently of the tiers above, Claude Code asks for approval before every tool call ("Claude wants to use List customers…"). When setup configures Claude Code, it offers to pre-approve tools so those prompts disappear:

  • Non-personal reads (recommended): schedules, offers and studio info run without prompting; anything touching member data, and every write action (bookings, cancelations, check-ins), still asks first.
  • Everything except destructive actions: no prompts for reads and routine writes; contract signups/cancellations (including withdrawing a cancellation) and financial exports always ask — they are never pre-approved, by design.
  • No: keep Claude's default ask-every-time behavior.

To skip the question and pre-approve everything (e.g. scripted installs):

uvx sportalliance-mcp setup --allow-all

This works by merging mcp__Magicline… / mcp__PerfectGymNext… rules into the permissions.allow list in ~/.claude/settings.json, which both the Claude Code CLI and its desktop app read. Your existing rules are preserved (the file is backed up before every rewrite); remove the entries from that file to get the prompts back. Rules are per platform — pre-approving your Magicline studio changes nothing for your PerfectGym Next club.

Claude Desktop has no pre-approval config file — use the "Always allow" option in its permission dialog, once per tool. Other clients (Cursor, Windsurf, Gemini CLI) have their own auto-approval settings in their UIs.

What you can do

Run uvx sportalliance-mcp tools to see every tool, grouped by permission tier. Tools are hand-curated over the Open API with pagination, rate limiting and retries handled internally, and are identical on both platforms — the two share one API surface. The warehouse tools only appear when the optional data warehouse connection is configured.

Try these prompts — a day at the front desk:

  • "Book Jonas Weber into tonight's Spin class"
  • "Check Anna Schmidt in"
  • "When can Anna cancel her contract at the latest?"
  • "What payment method does she have on file, and what's her balance?"
  • "Pause her contract for August — vacation"
  • "Extend that freeze by a month — what would it cost?"
  • "Create a lead for Max Mustermann, max@example.com, and book him a free trial session for tomorrow morning"
  • "Assign the 12 Month Fixed membership to customer 10023 from next month"
  • "Log that phone call on their record"

…and for the back office:

  • "What classes are running tomorrow, and which still have free spots?"
  • "How busy is the gym right now?"
  • "What membership offers do we sell, and what would Premium cost customer 10023?"
  • "Show the account balance and upcoming charges for customer 10023"

Every booking, contract and validate/preview result carries a studio field naming the platform, tenant and environment it executed against — with PRODUCTION spelled out — so the assistant (and you, reading the transcript) always know which studio a write went to.

Data warehouse (optional)

Operators with access to the enterprise data warehouse (Magicline · PerfectGym Next, Amazon Redshift) can enable extra SQL analytics tools. The setup wizard asks about this ("Configure a Redshift data warehouse connection?") — skip it and nothing changes: the warehouse tools are only registered when a connection is configured.

Tool Tier What it does
warehouse_docs read Topic lookup in the built-in glossary (business terms, join keys, KPI definitions, SQL rules)
warehouse_list_schemas read List queryable schemas
warehouse_list_tables read List tables/views in a schema (stale __old copies flagged deprecated)
warehouse_describe_table read Column names, types, nullability
warehouse_query read Read-only SQL with PII values masked
warehouse_query_pii pii Read-only SQL, unmasked rows

Queries run with guardrails: results are capped at 500 rows (with a truncated flag), a 60-second statement timeout is set, multi-statement SQL is rejected, and driver errors come back cleaned up with corrective hints for common Redshift-dialect mistakes.

At read tier, warehouse_query masks values in string/varchar columns and known personal-data columns such as date_of_birth as "<withheld>" — row counts and structure stay intact, and enum-like status/type columns plus period aliases (AS month, AS year, …) stay visible. This masking is best-effort hygiene, not a security boundary — it keys on result column names, so aliased queries can slip past it. If you must guarantee no PII at read tier, disable warehouse_query (via sportalliance-mcp permissions) or enforce masking in the warehouse itself.

IMPORTANT: connect with a warehouse user that has read-only grants. The server opens read-only transactions and rolls every query back, but arbitrary SQL could escape that — the database user's permissions are the real enforcement.

The password lives in the OS keyring (manage it with sportalliance-mcp warehouse set|status|delete); host, port, database and user go into the client config's env block as WAREHOUSE_* variables (see Environment variables). A group sharing one warehouse across both platforms stores the password once.

When a warehouse is configured, the server also teaches the AI how to query it: the key-tables cheat sheet is embedded in the server instructions, and the full business glossary (definitions, join keys, correct status filters for every erp_v2 table) is available on demand — by topic through the warehouse_docs tool, or wholesale as MCP resources (magicline://warehouse/glossary or perfectgym-next://warehouse/glossary, per platform).

API Key Management

Key storage: actual key values live in your OS secret store (macOS Keychain, Windows Credential Manager / DPAPI, Secret Service on Linux), keyed by platform:tenant — the same tenant name can exist on both platforms without collision. Only tenant names are kept in ~/.sportalliance-mcp/registry.json, along with each entry's environment and the verified studio name. On headless Linux without a keyring, fall back to the SPORTALLIANCE_API_KEY environment variable.

How key selection works: keys are stored per studio. The active tenant for each platform is whatever SPORTALLIANCE_TENANT is written in that platform's entry in your client configs — keys activate rewrites it everywhere in one command, touching only that platform's entries.

# List stored keys grouped by platform (masked), with the active tenant
uvx sportalliance-mcp keys list

# Add a key for another studio (validated against the live API)
uvx sportalliance-mcp keys add

# Switch a platform's configured clients to another studio
uvx sportalliance-mcp keys activate perfectgym-next/tribegym-us
uvx sportalliance-mcp keys activate acme        # unambiguous tenants work bare

# Delete a stored key (warns if it's the active one)
uvx sportalliance-mcp keys delete magicline/acme

Open API keys are per studio: multi-studio operators store one key per tenant and switch with keys activate. Each key remembers its environment (production, sandbox, or a custom URL — chosen when it was added), and keys activate switches the endpoint together with the tenant.

Checking your setup

uvx sportalliance-mcp status

status is a local doctor — no network, safe to run blind. It checks every configured client entry for the disagreements that actually break things: entry key vs declared platform, platform vs base-URL host, environment vs host, the same inline API key pasted under two different platforms, stale MAGICLINE_*/SPORTALLIANCE_* twins that disagree, launcher paths that no longer exist, missing keyring entries, and Claude Code allow rules that match no configured entry.

uvx sportalliance-mcp test goes one step further and verifies every configured entry against the live API, printing the studio name each key actually opens.

Upgrading from magicline-mcp

Run uvx sportalliance-mcp setup — it detects an existing magicline-mcp installation and offers to migrate before anything else. Migration copies every discoverable key into the new keyring service (verified by read-back, deleting nothing), writes the new registry (leaving the old one in place), backs up each client config, and rewrites the existing Magicline entry with both env prefixes — so the config keeps working under a cached old binary, under the new package, and can simply be restored from the backup if you ever want to roll back. The MCP server key stays exactly Magicline: existing Claude Code allow rules keep working untouched, and your AI client shows the same server name as before.

Staying on magicline-mcp 0.1.2 is also fine — it keeps working and nothing breaks. Configs carried over by hand (just the MAGICLINE_* env block) work with zero action: the server recognises the legacy prefix and serves the Magicline platform, printing a one-line deprecation note.

Claude Code

setup --claude-code configures Claude Code automatically by running claude mcp add --scope user for you (user scope, so the server is available in every directory, not just the one setup ran in), and then offers to pre-approve tools (see Skipping permission prompts). Or do it manually:

claude mcp add PerfectGymNext --scope user \
  -e SPORTALLIANCE_PLATFORM=perfectgym-next \
  -e SPORTALLIANCE_TENANT=<tenant> \
  -e SPORTALLIANCE_ENVIRONMENT=production \
  -e SPORTALLIANCE_TOOLS=read -- uvx sportalliance-mcp

# Verify it was added
claude mcp list

Manual configuration

The setup wizard edits these files for you, but you can also edit them by hand:

  • Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json (Windows: %APPDATA%\Claude\claude_desktop_config.json)
  • Cursor: ~/.cursor/mcp.json
  • Windsurf: ~/.codeium/windsurf/mcp_config.json
  • Gemini CLI: ~/.gemini/settings.json
  • Antigravity: ~/.gemini/antigravity/mcp_config.json

All use the same format (for Gemini CLI, the mcpServers block lives inside its existing settings.json — the wizard merges without touching your other settings). Two platforms from one install look like this (keys come from the OS keyring, stored by setup or keys add):

{
  "mcpServers": {
    "Magicline": {
      "command": "uvx",
      "args": ["sportalliance-mcp"],
      "env": {
        "SPORTALLIANCE_PLATFORM": "magicline",
        "SPORTALLIANCE_TENANT": "acme-fitness",
        "SPORTALLIANCE_ENVIRONMENT": "production",
        "SPORTALLIANCE_TOOLS": "read"
      }
    },
    "PerfectGymNext": {
      "command": "uvx",
      "args": ["sportalliance-mcp"],
      "env": {
        "SPORTALLIANCE_PLATFORM": "perfectgym-next",
        "SPORTALLIANCE_TENANT": "tribegym-us",
        "SPORTALLIANCE_ENVIRONMENT": "sandbox",
        "SPORTALLIANCE_TOOLS": "read"
      }
    }
  }
}

Alternative — environment variable instead of the keyring (CI, Docker, headless Linux): add "SPORTALLIANCE_API_KEY": "your-api-key-here" to the env block. Never paste the same key into two different platforms' entries — keys are per studio, and status flags exactly that mistake.

On Windows, prefer the full path to uvx.exe as command — GUI apps don't always inherit your shell's PATH. The setup wizard does this automatically.

CLI reference

Command What it does
sportalliance-mcp setup One-time interactive setup (platform question first; safe read-only mode)
sportalliance-mcp setup --platform <id> Skip the platform question (magicline, perfectgym-next)
sportalliance-mcp setup --advanced Setup with elevated capabilities (member data, writes, per-tool fine-tuning)
sportalliance-mcp setup --auto-update Clients always launch the latest published version
sportalliance-mcp setup --claude-code Also configures Claude Code via claude mcp add --scope user
sportalliance-mcp setup --allow-all Pre-approve tools in Claude Code — writes included, but destructive contract/payment actions still ask
sportalliance-mcp test Verify every configured entry against the live API
sportalliance-mcp status Local config doctor — spot misconfigurations without any network
sportalliance-mcp tools List every tool, grouped by permission tier
sportalliance-mcp permissions [--platform p] Change tiers or enable/disable individual tools
sportalliance-mcp keys list Show stored keys grouped by platform (masked), environments, active tenants
sportalliance-mcp keys add Store a key for another studio
sportalliance-mcp keys activate <p/tenant> Switch a platform's clients to another studio (and its environment)
sportalliance-mcp keys delete <p/tenant> Remove a stored key
sportalliance-mcp warehouse set|status|delete Manage the data-warehouse password in the OS keyring
sportalliance-mcp Run the MCP server on stdio — your AI client does this for you

(Prefix with uvx, or uv run inside the repo.)

Environment variables

Variables marked managed are written by the setup wizard; you only set them yourself in non-interactive environments. MAGICLINE_* equivalents of the serve-time variables remain supported for existing Magicline configs (deprecated; if both prefixes are set they must agree).

Variable Managed Description
SPORTALLIANCE_PLATFORM Which platform this entry serves: magicline or perfectgym-next (aliases perfectgym, pgnext). Required — the server refuses to guess.
SPORTALLIANCE_TENANT Your tenant/studio name (the <tenant> in the base URL). Required.
SPORTALLIANCE_ENVIRONMENT production (default) or sandbox. Explicit — never inferred from other settings.
SPORTALLIANCE_TOOLS Enabled tiers, comma-separated: read (default), pii, write. read is always included.
SPORTALLIANCE_TOOLS_EXCLUDE Individual tools to disable, comma-separated (e.g. cancel_contract,create_tax_advisor_export). Applied after tier filtering; unknown names are ignored with a warning. Managed by sportalliance-mcp permissions.
SPORTALLIANCE_API_KEY API key. Overrides the OS keyring — for CI, Docker, or headless machines.
SPORTALLIANCE_BASE_URL Custom API base URL. Written by the wizard for sandbox/custom environments. HTTPS required (plain http only for localhost). Refused if the host belongs to a different platform than SPORTALLIANCE_PLATFORM.
SPORTALLIANCE_MAX_RPS Client-side request ceiling in requests/second (default 3). Keeps the MCP to a small slice of the API key's rate allowance, which your other integrations share. 0 disables the throttle.
WAREHOUSE_HOST Redshift endpoint of the enterprise data warehouse. Warehouse tools register only when host, database and user are all set.
WAREHOUSE_PORT Warehouse port (default 5439).
WAREHOUSE_DATABASE Warehouse database name.
WAREHOUSE_USER Warehouse user — use one with read-only grants.
WAREHOUSE_PASSWORD Warehouse password. Overrides the OS keyring — only needed where no keyring exists.

Troubleshooting

  • "SPORTALLIANCE_PLATFORM is not set" — add it to the entry's env block (magicline or perfectgym-next), or re-run uvx sportalliance-mcp setup.
  • "No API key found for tenant" — run uvx sportalliance-mcp setup, or set SPORTALLIANCE_API_KEY. Verify with uvx sportalliance-mcp test.
  • "tenant does not exist" (404) — sandbox and production are separate tenant namespaces: a sandbox studio only resolves on <tenant>.open-api.sandbox.<platform-domain>. Setup offers the switch with one keystroke.
  • 401 Unauthorized — tenant and key don't match, or the integration was deactivated. Both come from the same activation email. Also check the key isn't from your other platform — uvx sportalliance-mcp status flags a key pasted under two platforms.
  • 403 Permission denied — three possible causes: your API key lacks the scope for that operation, the entity belongs to a different studio, or the member has opted out of third-party data access (their right — the error message says which).
  • The server refuses to start with a "STOPPING" identity message — the API key opens a different studio than the one this entry was configured for. Re-run setup for that platform, or inspect with uvx sportalliance-mcp status.
  • Tools missing in your client — member data and write tools only appear when their tier is enabled, and individual tools may have been disabled: check uvx sportalliance-mcp permissions. Restart the client after any config change.
  • claude CLI not found (with --claude-code) — install Claude Code first, then re-run uvx sportalliance-mcp setup --claude-code.
  • "Server disconnected" in Claude Desktop — check the server log at ~/Library/Logs/Claude/mcp-server-Magicline.log or mcp-server-PerfectGymNext.log (macOS); the last Python traceback usually names the cause.
  • Keyring issues on Linux — headless machines often have no Secret Service; use the SPORTALLIANCE_API_KEY env var in the client config instead.

Development

uv sync
uv run sportalliance-mcp tools
uv run pytest

Project layout:

src/sportalliance_mcp/
├── cli.py            # entry point + subcommands
├── platforms.py      # the platform registry: Magicline, PerfectGym Next, ...
├── config.py         # platform/tenant/key/tier resolution (env > keyring)
├── registry.py       # ~/.sportalliance-mcp/registry.json, keyed (platform, tenant)
├── client.py         # httpx wrapper: auth, retries, backoff, pagination
├── server.py         # FastMCP assembly, identity check, studio stamps
├── setup_wizard.py   # the one-time setup experience (platform picker first)
├── manage.py         # keys + permissions + the `status` doctor
├── migrate.py        # copy-forward migration from magicline-mcp
├── warehouse.py      # read-only Redshift client (optional warehouse tools)
├── branding.py       # terminal UI (per-platform palettes and banners)
└── tools/            # one module per API domain

Note (macOS + iCloud): if this repo lives in an iCloud-synced folder (e.g. ~/Documents), iCloud recursively stamps the macOS hidden flag on dot-directories — and Python ≥ 3.13.4 refuses to load hidden .pth files, which silently breaks the venv. Do not work around it with a .venv symlink — iCloud materializes symlinks into broken directory copies. Instead, keep the venv in a *.nosync directory (iCloud ignores those) by setting, e.g. in ~/.zshenv:

export UV_PROJECT_ENVIRONMENT=".venv.nosync"

The simplest alternative: keep code outside iCloud-synced folders entirely.

License

This project is licensed under the MIT License — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sportalliance_mcp-0.2.0.tar.gz (195.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sportalliance_mcp-0.2.0-py3-none-any.whl (102.0 kB view details)

Uploaded Python 3

File details

Details for the file sportalliance_mcp-0.2.0.tar.gz.

File metadata

  • Download URL: sportalliance_mcp-0.2.0.tar.gz
  • Upload date:
  • Size: 195.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for sportalliance_mcp-0.2.0.tar.gz
Algorithm Hash digest
SHA256 007f17aedf479080ccee23e7e2190703b9be82d59142abddcbcd3bff0a415b45
MD5 a8e3985de0763afb36386f41231febfb
BLAKE2b-256 7ba61590a8d0a429d3172c8a145261efb16e4df8913fdd899a4fc0add51905fe

See more details on using hashes here.

File details

Details for the file sportalliance_mcp-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: sportalliance_mcp-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 102.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for sportalliance_mcp-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d5258a82cf6b7f20a4a1f2536d03ebe82285de1d2010bfbc2b6cfc1a065dc0b4
MD5 83bcaf22d96502def32ff980c80c8f0e
BLAKE2b-256 2f149246ce7b691e86651ff3f92964fc723472426b4ddc491a26ae480ad8f5f4

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page