Skip to main content
Glama

af-unofficial-mcp-server

An unofficial MCP server for Anytime Fitness. Ask your assistant how busy the gym is, when it will be quieter, which nearby clubs are less crowded, or how often you have visited.

It uses the same private API as version 4.5.0 of the Anytime Fitness app. The API may change without warning. This project is not affiliated with Anytime Fitness.

Tools

Tool

What it returns

occupancy

Live headcount, how it compares with the usual crowd, and a go-now verdict

forecast

Typical hourly attendance for a chosen day

nearby_clubs

Nearby clubs, distance, opening status, and live headcount

visits

Visit history and common visit times

auth_status

Login status without exposing tokens

Attendance comparisons use the club's 100-day hourly averages. The server finds the home club and its timezone from your account.

Related MCP server: hevy-mcp

Setup

You need Python 3.11 or later, uv, and an MCP-compatible client.

git clone https://github.com/Sajush00/af-unofficial-mcp-server.git
cd af-unofficial-mcp-server
uv sync
uv run af-gym login --phone +61400000000

The login command sends an SMS code to the phone number registered with your Anytime Fitness account and prompts you to enter it.

Claude Desktop

Add this to claude_desktop_config.json:

{
  "mcpServers": {
    "af-gym": {
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/af-unofficial-mcp-server", "af-mcp"]
    }
  }
}

Claude Code

claude mcp add af-gym -- uv run --directory /absolute/path/to/af-unofficial-mcp-server af-mcp

Hermes Agent

Add this to ~/.hermes/config.yaml:

mcp_servers:
  af-gym:
    command: uv
    args: ["run", "--directory", "/absolute/path/to/af-unofficial-mcp-server", "af-mcp"]

Then ask your assistant: "How busy is the gym right now?"

Authentication and privacy

uv run af-gym status
uv run af-gym logout

Tokens are stored in ~/.af_token.json. Pending login details use ~/.af_session.json. Both files are private to your user account, and the CLI and MCP tools never print their contents.

Set AF_CLUB_TZ to an IANA timezone such as Australia/Sydney if you need to override automatic timezone detection.

Development

make check

This runs Ruff, mypy, project-specific static checks, and the offline test suite. Implementation notes are in docs/adr.

License

MIT © 2026 Sajush Arukat

Available Tools

5 tools
auth_statusAuth StatusA

Report whether a saved Anytime Fitness session exists and still refreshes.

Returns only metadata; token values are never returned. When this or any other call reports no usable session, ask the user to run af-gym login --phone <number> in their terminal.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full disclosure burden and does so well: it states that only metadata is returned, token values are never exposed, and it defines the agent's expected action when no usable session exists. This covers safety, output scope, and failure handling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: the first sentence states the core purpose, and the following sentences add only high-value behavioral and remediation details. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter status-check tool with an output schema available, the description fully covers what the agent needs: purpose, return scope, token safety, and user-facing recovery instructions. No critical context is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so parameter documentation is unnecessary. Baseline 4 applies because there is nothing for the description to add beyond the already-complete empty schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with a specific verb and resource: 'Report whether a saved Anytime Fitness session exists and still refreshes.' This clearly differentiates it from data-query siblings like occupancy, forecast, nearby_clubs, and visits, which return domain data rather than session state.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear operational context: when this tool or any other call reports no usable session, the agent should direct the user to run `af-gym login --phone <number>`. It does not explicitly list when-not-to-use alternatives, but the zero-parameter auth-check role is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

forecastForecastA

Typical hourly busy pattern for a day (100-day rolling averages, club-local time).

ParametersJSON Schema
NameRequiredDescriptionDefault
dayNo"today", "tomorrow", or a weekday name like "saturday". Defaults to "tomorrow".tomorrow
clubNoAF club number like "AU-0000". Defaults to the home gym.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It adds meaningful context by stating the data is a 100-day rolling average and expressed in club-local time, which clarifies computation method and timezone handling. It does not mention output structure, but an output schema exists, so that gap is covered elsewhere.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that communicates the core purpose and the two most important behavioral nuances: rolling averages and club-local time. There is no wasted text or redundant restating of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with two optional parameters and an output schema, the description provides enough context to understand what the tool returns and how the parameters affect the result. The main missing piece is explicit guidance on when to choose this tool over the sibling occupancy tool, but that is a usage-guideline gap rather than a completeness gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value beyond the schema by clarifying that the busy pattern is in club-local time, which affects how the 'day' and 'club' parameters should be interpreted. This is a useful semantic addition, though most parameter details are already fully documented in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool provides a typical hourly busy pattern for a day, based on 100-day rolling averages and club-local time. This is distinct from the sibling tools, especially occupancy, because it describes a historical/typical pattern rather than a current state, though it does not explicitly name the sibling it differs from.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for planning or understanding expected busyness rather than real-time occupancy, but it does not explicitly state when to use this tool versus alternatives like occupancy. There is no exclusion or alternative routing, leaving the agent to infer context from the word 'typical' and the sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

nearby_clubsNearby ClubsA

Clubs near the home gym, nearest first, each with distance and a live headcount.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of clubs to return.
radius_kmNoSearch radius in kilometres around the home gym.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It discloses ordering ('nearest first'), scope ('near the home gym'), and a notable live-data trait ('live headcount'). It does not mention authentication, data freshness limits, or behavior when no clubs are found, but for a simple read-style tool this is reasonably transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no filler. It front-loads the core scope ('Clubs near the home gym') and then packs in ordering, distance, and live headcount efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the low complexity, fully documented parameters, and presence of an output schema, the description covers the essential context: what is returned, from where, and in what order. It could add a note on authentication or data freshness, but nothing critical is missing for a basic nearby-clubs lookup.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already fully documents limit and radius_km. The description adds no parameter-level meaning beyond what the schema provides, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the resource (clubs near the home gym), the ordering (nearest first), and the returned fields (distance, live headcount). It lacks an explicit verb like 'list' or 'get', and it does not directly contrast with sibling tools, but its meaning is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: an agent would use this when it needs nearby clubs with distance and headcount. However, there is no explicit guidance about when to choose this over siblings like occupancy or visits, and no exclusions or prerequisites are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

occupancyOccupancyB

Live headcount right now, a go-now verdict, and typical counts for the rest of today.

The verdict compares the live count to the typical count for this hour: go-now, good-time, normal, wait or skip (see verdictMessage). restOfDay lists the typical count for each remaining hour of today.

ParametersJSON Schema
NameRequiredDescriptionDefault
clubNoAF club number like "AU-0000". Defaults to the home gym.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral burden. It explains the verdict logic and the restOfDay output, which adds meaningful behavioral context. However, it does not explicitly label the operation as read-only or disclose any latency, privacy, or edge-case behaviors.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: the first sentence captures the core purpose, and the second adds necessary detail about verdict values and restOfDay. Every sentence contributes value with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists and the parameter schema is complete, the description sufficiently explains the tool's primary outputs and verdict logic. It could be slightly more complete by clarifying when to use it relative to forecast, but the core information an agent needs to invoke it is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single optional parameter 'club' is 100% documented in the schema, including its format and default behavior, so the description does not need to add much. It adds no extra parameter insight, but the schema already covers it fully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states what the tool returns: live headcount, a go-now verdict, and typical counts for the rest of today. It distinguishes itself from sibling tools like forecast by focusing on current occupancy and today's remaining hours, though it does not explicitly name any sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies use when current occupancy or a go-now recommendation is needed, but it gives no explicit guidance on when to prefer this tool over forecast or other siblings. There are no usage conditions, prerequisites, or exclusions stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

visitsVisitsA

Gym check-ins in a date range, newest first, with totals and habits.

Defaults to the last 90 days. Prefer a range over pulling all history: "visits in August" is start "2026-08-01", end "2026-08-31" (count 1 when only the total matters). When the range reaches today it also reports days since the last visit and, when the window is wide enough, 7/30-day counts; it always reports the most common day and hour in the range. Dates are club-local and inclusive.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoRange end, inclusive; a bare date covers the whole day. Default: now.
countNoMax visits to list, newest first (default 20, max 200).
startNoRange start, inclusive. Default: 90 days before end.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and discharges it exceptionally well: discloses sort order (newest first), default range, conditional metrics (7/30-day counts only when the range reaches today and is wide enough), always-on aggregates (most common day/hour), and date semantics (club-local, inclusive). This goes well beyond what the schema or structured fields reveal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than average but every sentence earns its place — purpose is front-loaded, followed by defaults, usage guidance, conditional behavior, and date semantics in logical order. It is slightly dense as one block and the "count 1" hint is compressed, but there is virtually no waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists to explain return values and all three parameters have full schema descriptions, the description is complete for correct invocation: it covers defaults, conditional output behavior, date semantics, and query-framing strategy. Nothing an agent needs to call this tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the baseline is 3, but the description adds real meaning: it clarifies that dates are inclusive and club-local, provides a concrete mapping from a natural query to start/end values, and explains that count=1 retrieves the total efficiently. This is meaningful value beyond the schema's own field descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource statement — "Gym check-ins in a date range, newest first, with totals and habits" — that immediately distinguishes it from siblings (occupancy, forecast, nearby_clubs, auth_status are all clearly different domains). An agent can identify what this tool returns without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear usage context: defaults to 90 days, advises preferring a bounded range over pulling all history, and gives a concrete natural-language-to-parameters example ("visits in August" → start/end). It stops short of explicit when-not-to-use guidance or alternative routing to siblings, though those tools are distinct enough that confusion is unlikely.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.2.0
    • First observedauth_status
    • First observedforecast
    • First observednearby_clubs
    • First observedoccupancy
    • First observedvisits

TDQS

A4/5.0

Scored across 5 tools

Disambiguation4/5

Occupancy and forecast both deal with busyness and could be confused, but their live-vs-typical distinction is clear from the descriptions. The remaining tools are each tied to a distinct concern: nearby alternatives, visit history, and auth status.

Naming Consistency5/5

All tool names are lowercase noun-style names, forming a consistent and predictable query-oriented pattern. Single-word names like occupancy and multi-word names like nearby_clubs both follow snake_case, so there is no convention mixing.

Tool Count5/5

Five tools is well-scoped for a gym assistant: live busyness, typical trends, nearby options, visit history, and session status. Each tool earns its place and none feels redundant or missing enough to enlarge the set.

Completeness4/5

The core member workflows are covered: deciding when to go, checking nearby alternatives, and reviewing past visits. Minor gaps exist around club details like hours or address and membership info, but the surface seems intentionally focused and auth is explicitly handled via CLI.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers