Skip to main content
Glama
alliso

fitbot-mcp

by alliso

fitbot-mcp

Servidor MCP para AimHarder: reserva clases, consulta el horario y cancela reservas desde cualquier cliente MCP (Claude Desktop, Claude Code, etc.).

API no oficial, obtenida por ingeniería inversa de la web. Puede dejar de funcionar si AimHarder cambia sus endpoints. Úsalo solo con tu propia cuenta.

Herramientas

Herramienta

Qué hace

list_classes

Lista las clases de un día: hora, nombre, coach, plazas y si estás apuntado.

book_class

Reserva una clase por hora ("18:15") o por classId. insist=true → lista de espera.

cancel_class

Cancela tu reserva en una clase.

class_attendees

Lista los apuntados a una clase. Solo para cuentas coach/admin (ver nota abajo).

list_boxes

Muestra los boxes de tu cuenta y su boid.

Todas aceptan date (YYYY-MM-DD, por defecto hoy) y, si perteneces a varios boxes, boxId.

Related MCP server: nexudus-mcp

Configuración

Credenciales por variables de entorno: AIMHARDER_EMAIL y AIMHARDER_PASSWORD.

No hace falta clonar el repo: puedes ejecutarlo directamente con npx.

Opción 1 — directo desde GitHub (sin publicar en npm)

npx clona y compila el paquete la primera vez (script prepare). Añade a tu claude_desktop_config.json (Claude Desktop) o .mcp.json (Claude Code):

{
  "mcpServers": {
    "fitbot": {
      "command": "npx",
      "args": ["-y", "github:alliso/fitbot-mcp"],
      "env": {
        "AIMHARDER_EMAIL": "tu@email.com",
        "AIMHARDER_PASSWORD": "tu_contraseña"
      }
    }
  }
}

Opción 2 — desde npm (si lo publicas)

Tras npm publish --access public, la config es aún más corta:

{
  "mcpServers": {
    "fitbot": {
      "command": "npx",
      "args": ["-y", "fitbot-mcp"],
      "env": {
        "AIMHARDER_EMAIL": "tu@email.com",
        "AIMHARDER_PASSWORD": "tu_contraseña"
      }
    }
  }
}

Opción 3 — instalación local (desarrollo)

git clone https://github.com/alliso/fitbot-mcp.git
cd fitbot-mcp && npm install && npm run build

y usa "command": "node", "args": ["/ruta/a/fitbot-mcp/dist/index.js"].

Reinicia el cliente y pídele, por ejemplo: "reserva la clase de CrossFit de mañana a las 18:15".

Tests

npm test          # suite completa (vitest)
npm run test:watch
npm run coverage  # informe + umbrales (text, html en coverage/, lcov)

Los tests no tocan la red ni AimHarder: el fetch global va mockeado y se inyecta un cliente de mentira en el server MCP. El transporte HTTP sí se prueba de verdad, levantando el servidor en un puerto libre y hablándole con el cliente del MCP SDK.

Fichero

Qué cubre

tests/aimharder.test.ts

Login, fingerprint, cookies, mapeo de clases, reserva/cancelación, re-login tras {logout:1}.

tests/server.test.ts

Las cinco herramientas MCP vía transporte en memoria, y el formato de salida.

tests/server-http.test.ts

Rutas, Bearer token, ciclo de sesión Streamable HTTP y casos límite del handler.

tests/server-stdio.test.ts

Modo stdio y elección de transporte en main().

tests/logger.test.ts

Niveles, formato JSON, serialización de errores, correlación con trazas.

tests/tracing*.test.ts

Instrumentación de herramientas con OTel activado y desactivado.

tests/index.test.ts

Arranque y validación de credenciales.

Tests de mutación

El coverage dice qué líneas se ejecutan, no si alguien comprueba el resultado. StrykerJS introduce cambios pequeños en src/ (invertir un if, cambiar un + por -, vaciar un string) y da por buena la suite solo si algún test se pone en rojo.

npm run test:mutation   # informe HTML en reports/mutation/index.html

Tarda alrededor de un minuto. El umbral de corte está en un 85% de mutation score; por debajo, el comando falla.

Lo que no se mutila, marcado con // Stryker disable en el propio código: las descripciones de las herramientas MCP (prosa dirigida al LLM: afirmar sobre ella en un test solo estorba al reescribirla), las líneas de logger.* y algún mutante equivalente suelto. Sin esos, el score mezclaba huecos reales con texto y no servía como señal.

Modo HTTP (para n8n y otros clientes remotos)

Además de stdio, el server puede arrancar como servicio HTTP con URL propia (transporte Streamable HTTP del MCP SDK), sin necesidad de gateways.

# desde el repo (o npx -y github:alliso/fitbot-mcp --http)
AIMHARDER_EMAIL=tu@email.com AIMHARDER_PASSWORD=tu_contraseña \
  PORT=8000 HOST=0.0.0.0 \
  node dist/index.js --http

Endpoint MCP: http://<host>:8000/mcp — y GET /health para healthcheck.

Variables de entorno:

Var

Por defecto

Descripción

PORT

8000

Puerto de escucha.

HOST

127.0.0.1

Interfaz. Usa 0.0.0.0 en Docker/contenedores.

MCP_HTTP_PATH

/mcp

Ruta del endpoint.

MCP_HTTP_TOKEN

Si se define, exige Authorization: Bearer <token>. Recomendado si el puerto es accesible por la red.

También puedes activarlo con MCP_TRANSPORT=http en vez del flag --http.

Logs

El server escribe logs estructurados (una línea JSON por evento) siempre a stderr — nunca a stdout, que en modo stdio es el canal del protocolo MCP.

{"ts":"2026-08-13T10:22:31.004Z","level":"info","msg":"tool ok","tool":"book_class","args":{"time":"18:15"},"duration_ms":412,"trace_id":"4bf92f…","span_id":"00f067…"}

Var

Por defecto

Descripción

LOG_LEVEL

info

debug, info, warn, error o silent (apaga los logs).

Qué se registra:

  • Ciclo de vida: arranque (server started, con transporte, puerto y si exige token), parada, apertura y cierre de sesiones HTTP.

  • Herramientas: una línea por invocación con el nombre, los argumentos y la duración — tool ok, tool error (la herramienta devuelve isError) o tool failed (excepción, con el stack).

  • Errores: peticiones HTTP fallidas, 401 por token inválido, sesión ausente o caducada y errores fatales.

  • Con LOG_LEVEL=debug se añaden tool start y los 404/405 del endpoint HTTP.

No se registran nunca credenciales, cookies de sesión ni el token de MCP_HTTP_TOKEN.

Si el tracing está activo (ver abajo), cada línea lleva trace_id/span_id del span en curso, así se salta desde un log (Loki) a su traza (Tempo). En Docker/k8s basta con recoger la salida del contenedor: no hay ficheros de log.

Trazas (OpenTelemetry)

Opcional y desactivado por defecto: si defines OTEL_EXPORTER_OTLP_ENDPOINT, el server exporta trazas por OTLP HTTP a ese colector (Tempo, Jaeger, el OTel Collector…). Sin esa variable no se arranca el SDK, que es lo que interesa en modo stdio.

Var

Descripción

OTEL_EXPORTER_OTLP_ENDPOINT

Colector OTLP HTTP, p.ej. http://tempo:4318. El exporter le añade /v1/traces.

OTEL_SERVICE_NAME

Nombre del servicio en el backend de trazas.

OTEL_RESOURCE_ATTRIBUTES

Atributos extra, p.ej. service.namespace=home-utils.

Cada petición produce un span de servidor, un span mcp.tool <nombre> por herramienta invocada y un span de cliente por cada llamada a AimHarder:

POST /mcp
└── mcp.tool list_classes
    └── POST login.aimharder.com/api/login

Las probes a /health se ignoran. Un fallo de herramienta marca el span como error y adjunta la excepción.

Conectarlo desde n8n (self-hosted)

  1. Arranca el server en modo HTTP en una máquina accesible desde n8n (mismo host, otra máquina de la red, o un contenedor en el mismo docker-compose).

  2. En n8n, dentro de tu AI Agent, añade el nodo MCP Client Tool.

  3. Transporte HTTP Streamable (o SSE, según versión) y Endpoint: http://<host>:8000/mcp

    • Si defines MCP_HTTP_TOKEN, añade en el nodo la cabecera Authorization: Bearer <token>.

  4. Si n8n corre en Docker y el server en el host, usa http://host.docker.internal:8000/mcp.

Alternativa sin modo HTTP: el community node n8n-nodes-mcp permite conexión STDIO con command: npx, args: -y github:alliso/fitbot-mcp y las variables de entorno de credenciales (requiere Node/npx dentro del contenedor de n8n).

Ejemplos de uso (lenguaje natural)

  • "¿Qué clases hay hoy?" → list_classes

  • "Apúntame al WOD de las 18:15" → book_class { time: "18:15" }

  • "Cancela mi reserva de las 18:15" → cancel_class { time: "18:15" }

  • "¿Quién va a la clase de las 18:15?" → class_attendees (ver nota)

Notas

  • Apuntados a una clase: AimHarder solo expone la lista de asistentes a cuentas con rol coach/administrador en el box. Para cuentas de cliente el endpoint (/api/coachBookings) devuelve vacío, y class_attendees lo indica en su respuesta.

  • Fingerprint: en el primer arranque se genera un identificador de dispositivo estable y se guarda en ~/.fitbot-mcp/fingerprint (en tu carpeta de usuario, para que persista aunque se ejecute vía npx). Puedes fijarlo con la variable AIMHARDER_FINGERPRINT.

  • Sesión caducada: la cookie de login no dura para siempre. Si AimHarder responde {"logout":1} (pasa en servidores de larga vida), el cliente vuelve a autenticarse y repite la llamada una vez; solo si falla otra vez devuelve error.

  • Multi-box: si tu cuenta pertenece a varios boxes, usa list_boxes para ver los boid y pasa boxId a las demás herramientas.

API (referencia interna)

  • Login: POST https://login.aimharder.com/api/login — JSON { username, password, fingerprint, iniframe: 0 }. Devuelve data.userData.roles[].boid / centre_url y cookies de sesión (.aimharder.com).

  • Horario: GET https://{subdominio}/api/bookings?day=YYYYMMDD&box={boid}&familyId=

  • Reservar: POST https://{subdominio}/api/book — form { id, day, insist, familyId }. bookState: 1/0 ok · -1 llena · -2 sin tarifa · -4/-7 antelación · -5 pago pendiente.

  • Cancelar: POST https://{subdominio}/api/cancelBook — form { id: idres, late, familyId }. cancelState: 1 = ok.

  • Sesión caducada: cualquiera de los endpoints anteriores puede responder { logout: 1 } en lugar del estado esperado; significa que hay que rehacer el login.

Available Tools

5 tools
book_classReservar claseA

Reserva una clase. Identifícala por hora de inicio (p.ej. "18:15") o por classId. Si a esa hora hay varias clases, añade 'name' para desambiguar. Con insist=true entras en lista de espera si está llena.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoFecha en formato YYYY-MM-DD. Si se omite, se usa el día de hoy.
nameNoFiltro por nombre de clase, p.ej. "CROSSFIT".
timeNoHora de inicio, p.ej. "18:15".
boxIdNoid del box (boid). Solo necesario si tu cuenta pertenece a varios boxes.
insistNoEntrar en lista de espera si está llena.
classIdNoid de la clase (de list_classes).

TDQS

A4.2/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It discloses the waiting-list behavior via insist=true and the disambiguation logic, but doesn't mention important traits like idempotency, confirmation responses, or authorization requirements. Some transparency is present, but not comprehensive.

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?

Three sentences, each earning its place: action, identification method, disambiguation rule, and waiting-list option. No filler or 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 6 optional parameters and no output schema, the description covers the main booking flow and edge cases (multiple classes, full class). It omits return-value details and prerequisites, but for a booking tool the core behaviors are addressed.

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 by explaining how parameters relate: time or classId for identification, name for disambiguation, insist for waiting list. This clarifies semantics beyond the individual schema 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?

The description opens with 'Reserva una clase' (Book a class), a clear verb+resource statement. It distinguishes from siblings like cancel_class and list_classes by specifying the booking action and how to identify the class (time or classId).

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 concrete usage guidance: identify by start time or classId, add 'name' to disambiguate when multiple classes overlap, and use insist=true for waiting list. It doesn't explicitly exclude alternatives but gives clear context for when to use the tool and how to handle ambiguity.

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

cancel_classCancelar reservaA

Cancela tu reserva en una clase. Identifícala por hora de inicio o por classId. Usa late=true si cancelas fuera de plazo (puede penalizar según el box).

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoFecha en formato YYYY-MM-DD. Si se omite, se usa el día de hoy.
lateNoCancelación fuera de plazo.
nameNoFiltro por nombre de clase.
timeNoHora de inicio, p.ej. "18:15".
boxIdNoid del box (boid). Solo necesario si tu cuenta pertenece a varios boxes.
classIdNoid de la clase (de list_classes).

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations provided, the description carries the burden of behavioral disclosure. It mentions that late cancellation may incur a penalty depending on the box, which is a meaningful side effect. However, it does not describe other outcomes like confirmation or reversibility, but the primary effect (cancellation) is clear.

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 concise—two sentences that are front-loaded with the core action and followed by essential usage details. There is no redundancy or filler, and every word contributes to the agent's understanding.

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 tool has six optional parameters and no output schema, the description is reasonably complete. It covers the main usage scenario (identifying and canceling a reservation) and mentions the late penalty. However, it does not explicitly state that at least one of time or classId is required, and it does not hint at the response format. These minor gaps are partially mitigated by the schema's parameter descriptions.

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 input schema already provides full descriptions for all six parameters (100% coverage). The description adds value by linking parameters together: it explains that you can identify the reservation via 'time' or 'classId', and clarifies the purpose of 'late'. This goes beyond the schema's individual parameter definitions.

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 clearly states the action: 'Cancela tu reserva en una clase' (Cancel your reservation in a class). It also specifies how to identify the reservation (by start time or classId), making it distinct from sibling tools like book_class. The verb and resource are unambiguous.

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 gives practical usage instructions: identify the reservation by start time or classId, and use late=true for cancellations outside the deadline. It does not explicitly compare with alternatives, but the context of a cancellation tool alongside book_class makes the use case clear.

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

class_attendeesVer apuntados a una claseA

Lista quién se ha apuntado a una clase. NOTA: AimHarder solo expone esta lista a cuentas con rol de coach/administrador en el box; para cuentas de cliente devuelve una nota informativa.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoFecha en formato YYYY-MM-DD. Si se omite, se usa el día de hoy.
nameNoFiltro por nombre de clase.
timeNoHora de inicio, p.ej. "18:15".
boxIdNoid del box (boid). Solo necesario si tu cuenta pertenece a varios boxes.
classIdNoid de la clase (de list_classes).

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It transparently notes the role-based restriction and the distinct behavior for client accounts (returning an informative note). This goes beyond the basic purpose and adds useful behavioral context, though it does not detail other behaviors like error handling or output structure.

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 concise and well-structured: one sentence states the primary purpose, and a second sentence provides a critical usage note. Every word earns its place, and the important role restriction is highlighted clearly without unnecessary padding.

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 tool has five optional parameters and no output schema, the description delivers the essential context: what the tool does and who can use it. It does not explain how to specify which class (leaving that to the schema), but the role restriction is crucial and well covered. This is reasonably complete for a read-only listing tool.

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 input schema fully documents all five parameters with descriptions, so the baseline score is 3. The description itself adds no additional parameter semantics beyond what the schema already provides, leaving parameter interpretation to the structured 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 clearly states the tool's function with a specific verb and resource: 'Lista quién se ha apuntado a una clase' (lists who signed up for a class). This unambiguously distinguishes it from sibling tools like list_classes, book_class, cancel_class, and list_boxes, as it focuses specifically on attendees.

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 a clear when-not scenario: it notes that only coach/administrator accounts can view the list, while client accounts receive an informative note instead. This gives practical usage guidance, though it does not explicitly mention alternative tools or contrast with siblings.

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

list_boxesListar mis boxesA

Muestra los boxes (gimnasios) asociados a tu cuenta y su id (boid).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

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

The verb 'muestra' (shows) implies a read-only operation, and the phrase 'asociados a tu cuenta' indicates data is scoped to the authenticated user. Since there are no annotations, this description provides the necessary behavioral context for a safe listing tool.

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, clear sentence in Spanish that directly states what the tool does and returns. No unnecessary information.

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 simplicity (0 parameters, no output schema), the description adequately covers the tool's purpose and output. It mentions the returned field (boid), making it complete.

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 takes no parameters, so the description has nothing to add. The baseline for zero parameters is 4.

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 states the tool lists the boxes (gyms) associated with the account and includes their boid. This is a specific verb+resource that clearly distinguishes it from the sibling class-related tools.

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 implies the use case of retrieving one's own gym boxes and their IDs. It does not explicitly mention alternatives or when-not-to-use, but the context is clear given the sibling tools are about classes.

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

list_classesListar clases del díaA

Lista las clases de un día concreto con su horario, coach, plazas ocupadas y si ya estás apuntado.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoFecha en formato YYYY-MM-DD. Si se omite, se usa el día de hoy.
boxIdNoid del box (boid). Solo necesario si tu cuenta pertenece a varios boxes.

TDQS

A3.6/5.0
Behavior3/5

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

There are no annotations, so the description carries the full burden of behavioral disclosure. It implicitly signals a read-only operation ('Lista') and adds useful context about returned fields, but it does not explicitly state that no changes are made, nor does it address dates, auth, or error behavior.

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 concise sentence that front-loads the purpose and lists the key returned data. Every word adds value and there is no redundant or vague filler.

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 list tool with a well-described schema and no output schema, the description manages to convey the return context (schedule, coach, occupancy, enrollment status). It lacks explicit sibling differentiation, but that gap is largely covered by the clear purpose statement.

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 coverage is 100%: the date parameter is described with format and default behavior, and boxId is described with its conditional need. The description adds no additional meaning beyond the schema, so a baseline score of 3 is appropriate.

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 uses the specific verb 'Lista' with resource 'clases de un día concreto' and enumerates useful output details (horario, coach, plazas ocupadas, inscripción). This clearly distinguishes it from sibling tools like book_class, cancel_class, and class_attendees.

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?

No guidance is provided about when to use this tool versus siblings. It does not mention that class_attendees is for viewing attendees of a specific class or that book_class/cancel_class are for actions. The only conditionality noted is the boxId parameter, not tool selection.

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. Dates show when Glama detected each change.

  1. 5 tool updatesv0.1.4
    • First observedbook_class
    • First observedcancel_class
    • First observedclass_attendees
    • First observedlist_boxes
    • First observedlist_classes

TDQS

A4.1/5.0
Disambiguation5/5

Each tool addresses a distinct operation: listing boxes, listing classes, booking, canceling, and viewing attendees. There is no overlap in purpose, and the role restriction on class_attendees does not create ambiguity.

Naming Consistency4/5

Most tools follow a verb_noun pattern (list_boxes, list_classes, book_class, cancel_class), but class_attendees is a noun phrase rather than an imperative verb, deviating slightly from the otherwise consistent style.

Tool Count5/5

Five tools is well-scoped for a fitness class booking domain. Each tool is necessary and covers the core user flow without redundancy.

Completeness4/5

Core operations (view schedule, book, cancel) are covered, but there is no direct way to list a user's own upcoming bookings across days, requiring agents to call list_classes repeatedly. This is a minor gap that can be worked around.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Connectors

Related MCP Servers

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/alliso/fitbot-mcp'

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