Hevy MCP
The Hevy MCP server enables AI assistants to interact with the Hevy fitness tracking app API for comprehensive fitness data management:
Workout Management: Fetch, create, update, and track workouts with detailed exercise data
Routine Management: Access, create, update, and organize workout routines
Exercise Templates: Browse and retrieve both standard and custom exercise templates
Folder Organization: Create and manage folders to categorize routines effectively
Utilized for code formatting and linting in the development process of the MCP server.
Used for environment variable configuration to store the Hevy API key.
Used for version control of the MCP server codebase.
Hosts the repository for the MCP server codebase.
Provides tools for accessing and managing workout data, routines, exercise templates, and folders through the Hevy fitness app API, enabling workout tracking and fitness management capabilities.
Required as a runtime environment (v20 or higher) for running the MCP server.
Used as a package manager for installing and managing dependencies of the MCP server.
Provides badge for license information in the README.
Supported as an alternative package manager for installing and managing dependencies.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Hevy MCPshow me my last 3 workouts"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Hevy MCP Server
Talk to your Hevy workout data from Claude, Cursor, Codex, and other MCP clients.
Connect to the hosted MCP · Use the Hevy CLI · Watch the 18-second demo · Explore all 22 tools
Hevy CLI
Prefer the terminal? The separate
@chrisdoc/hevy-cli
package reads workouts, routines, exercises, and body measurements directly
from the Hevy API, and can create or update those resources with explicit
confirmation. Deletion is not supported.
npm install -g @chrisdoc/hevy-cli
export HEVY_API_KEY=your-hevy-api-key
hevy workouts list --page-size 10
hevy summary --weeks 4Add --json to any command for scripts and pipelines. The CLI is a standalone
Hevy API client, not an MCP wrapper. See
packages/cli/README.md for the full command
reference, pagination behavior, and exit codes.
hevy-mcp is an open-source Model Context Protocol (MCP)
server for the Hevy fitness and workout tracking
app. It lets AI assistants read, analyze, create, and update your Hevy workouts,
routines, exercise templates, and body measurements through authenticated Hevy
API requests.
The repository is organized as a private workspace with explicit runtime
boundaries: @hevy-mcp/hevy-client owns the web-safe Hevy client,
@hevy-mcp/operations owns reusable Hevy domain operations,
@hevy-mcp/core owns MCP tools and server construction, hevy-mcp is the
published Node.js stdio adapter, @hevy-mcp/worker is the private Cloudflare
HTTP/OAuth adapter, and @chrisdoc/hevy-cli is the standalone CLI. Node and
CLI are the public packages.
The public HevyClient remains Promise-based, while
@hevy-mcp/operations provides Effect-first domain programs for reads,
mutations, and composite workflows. Effect is also the control structure for
the request runtime: @hevy-mcp/hevy-client owns retry schedules, per-attempt
timeouts, and interruption, rather than using Effect only as a delay
calculator. MCP tools and CLI commands collapse each invocation once at their
Promise adapter boundary. The MCP catalog remains 22 tools.
The runtime has three nested scopes:
Process Scope: the Node lifecycle owns telemetry, signal handlers, and transport shutdown.
Server Scope: core owns the MCP runtime and the exercise-template cache, including finalization when the server closes.
Request Scope: each tool or resource invocation carries its deadline and MCP request signal, so fiber interruption reaches the Hevy request.
These scopes do not change the supported Promise façades. Public
HevyClient methods, createHevyMcpServer, createNodeMcpServer,
runStdioServer / runServer, operation .execute(), and CLI
execute / runCli remain usable without requiring callers to construct
Effect programs.
The Worker adapter is not Effect-wide: its OAuth, bindings, and request
handling remain platform-specific Promise code; only the validation-cache
retry is Effect-controlled. Tool input and response contracts remain Zod
contracts, environment and CLI parsing remain throwing parsers, and generated
Kubb API functions and .kubb internals are not public API.
A Hevy API key, available with Hevy PRO, is required.
Related MCP server: hevy-mcp
See it in action

In the demo, the assistant retrieves real Hevy data and answers a multi-part training question with evidence from the user's workout history.
What can you do with it?
Analyze training progress: summarize 1-12 weeks of workouts and body measurements in one tool call.
Ask questions in plain language: find recent sessions, frequently trained exercises, consistency gaps, routine details, or exercise history.
Plan and log training: create or update workouts, routines, routine folders, custom exercises, and body measurements.
Search without huge responses: discover routines and exercise templates with compact, AI-friendly results.
Connect from your preferred MCP client: use the hosted Streamable HTTP endpoint or run locally with Codex, Claude Desktop, Cursor, and other clients.
Start without installing anything: connect directly to the production Cloudflare Worker—no Node.js, package download, or Docker container required.
Keep local control when you want it: run the same server with
npx,bunx, or the official Docker image.
Try asking:
Analyze my training over the last six weeks. Show workouts per week, my most frequently trained exercises, any obvious gaps or inconsistencies, and cite the workout evidence you used.
Find my push-day routine and show its exercises and sets.
Compare my recent body measurements with my training consistency.
Create a completed workout from my saved routine. Ask me for any missing set results before writing it to Hevy.
Claude integration
The repository includes a Claude plugin that connects to the hosted OAuth-enabled MCP endpoint without embedding a user's Hevy API key.
Claude.ai and Claude Desktop
In Claude, open Settings → Connectors → Add custom connector and enter:
https://mcp.hevy-mcp.dev/mcpComplete the OAuth flow and enter the Hevy API key when prompted. The same remote endpoint can be used by Claude Desktop and other clients that support remote MCP connectors.
Claude Code and Cowork
The Claude plugin is defined by .claude-plugin/plugin.json
and .mcp.json. Install it from this public repository or from
the Claude Plugin Directory after publication. It adds the hosted Hevy MCP
connector and the Hevy workout skill.
See the privacy policy for the hosted service's data handling details.
Quick start
1. Get your Hevy API key
Create an API key in Hevy's API settings, then keep it somewhere secure. API access currently requires a Hevy PRO subscription.
2. Connect hevy-mcp to your client
The hosted Cloudflare endpoint is the fastest way to start. It runs remotely, so your client does not need Node.js, Bun, Docker, or a local server process.
Connect to the hosted endpoint
Production URL:
https://mcp.hevy-mcp.dev/mcpThe endpoint uses Streamable HTTP. Send your Hevy API key as a bearer token on every request.
Codex
Codex CLI, the Codex desktop app, and the IDE extension share the same MCP configuration. Make your Hevy API key available in the environment that starts Codex, then add the hosted server:
export HEVY_API_KEY=your-hevy-api-key
codex mcp add hevy \
--url https://mcp.hevy-mcp.dev/mcp \
--bearer-token-env-var HEVY_API_KEYCodex stores the environment variable name, not the key itself, in its MCP
configuration. Restart Codex or begin a new session, then run codex mcp list
to verify the server is configured.
Other Streamable HTTP clients
Clients that accept a remote MCP URL and fixed headers commonly use this shape:
{
"mcpServers": {
"hevy": {
"url": "https://mcp.hevy-mcp.dev/mcp",
"headers": {
"Authorization": "Bearer your-hevy-api-key"
}
}
}
}Exact configuration keys vary by client. The hosted server requires support for
Streamable HTTP and a fixed Authorization header.
Treat the bearer value like a password. The Worker validates it with Hevy for
each request, does not store it, and forwards it to Hevy only as the requiredapi-key header.
Run locally instead
Choose local stdio if you prefer to run the server on your own machine or your client cannot attach a fixed authorization header to remote MCP requests.
Codex
codex mcp add hevy \
--env HEVY_API_KEY=your-hevy-api-key \
-- npx -y hevy-mcpClaude Desktop or Cursor
Add this mcpServers entry to your client configuration:
{
"mcpServers": {
"hevy": {
"command": "npx",
"args": ["-y", "hevy-mcp"],
"env": {
"HEVY_API_KEY": "your-hevy-api-key"
}
}
}
}Google Antigravity
There are two ways to configure the Hevy MCP server for Google Antigravity (agy):
Option A: Automatic Plugin Installation (Recommended)
This utilizes the built-in plugin system:
Install the plugin:
agy plugin install https://github.com/chrisdoc/hevy-mcpProvide the
HEVY_API_KEYin your host shell environment so the CLI child process can inherit it:Persistent: Save the environment variable
HEVY_API_KEYin your system/shell configurations:macOS / Linux: Add it to your shell profile configurations (e.g.,
~/.zshrcor~/.bashrc):export HEVY_API_KEY="your-actual-api-key"Windows: Add it to your User or System Environment Variables. In PowerShell, you can run:
[Environment]::SetEnvironmentVariable("HEVY_API_KEY", "your-actual-api-key", "User")
Temporary (Session-only): If you do not want to persist the key, export it in your active terminal session before running
agy:export HEVY_API_KEY="your-actual-api-key"
Option B: Manual Configuration (No Plugin)
If you prefer configuring it statically via the global configuration file:
Open your global MCP configuration file:
Location:
~/.gemini/config/mcp_config.json
Add the
hevyconfiguration block under themcpServerskey. Make sure to merge this entry with any existing servers you have configured rather than replacing the entire file contents:{ "mcpServers": { "hevy": { "command": "npx", "args": ["-y", "hevy-mcp"], "env": { "HEVY_API_KEY": "your-actual-api-key" } } } }
Common local configuration locations:
Claude Desktop on macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonClaude Desktop on Windows:
%APPDATA%\Claude\claude_desktop_config.jsonCursor:
~/.cursor/mcp.json
Restart or reconnect the client after saving the file.
Any stdio MCP client
Configure your client to launch this command with HEVY_API_KEY in the child
process environment:
npx -y hevy-mcpnpx requires Node.js 20 or newer. Restart or reconnect your client after
saving its configuration.
Requires Bun:
{
"mcpServers": {
"hevy": {
"command": "bunx",
"args": ["hevy-mcp@latest"],
"env": {
"HEVY_API_KEY": "your-hevy-api-key"
}
}
}
}Official images support linux/amd64 and linux/arm64. Keep stdin open with
-i because the container runs the stdio MCP server:
export HEVY_API_KEY=your-hevy-api-key
docker run -i --rm -e HEVY_API_KEY ghcr.io/chrisdoc/hevy-mcp:latestFor an MCP client, store the key in a protected environment file and configure the client to launch Docker:
{
"mcpServers": {
"hevy": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"--env-file",
"/absolute/path/to/hevy-mcp.env",
"ghcr.io/chrisdoc/hevy-mcp:latest"
]
}
}
}Pin an exact image tag such as ghcr.io/chrisdoc/hevy-mcp:X.Y.Z when you need
reproducible upgrades.
You can also add the npm server to supported clients with
add-mcp:
npx add-mcp hevy-mcp --env "HEVY_API_KEY=your-hevy-api-key"3. Ask your first question
Try one of these after restarting or reconnecting your MCP client:
“Give me a training summary for the last four weeks.”
“What routines do I have saved on Hevy?”
“Show my three most recent workouts.”
“Find exercise templates containing squat.”
“Which Hevy account is connected?”
Your assistant should ask for approval before mutation tools when the client supports tool confirmations.
How it works
Hosted: Your AI assistant → Streamable HTTP → Cloudflare Worker → Hevy API
Local: Your AI assistant → MCP over stdio → local hevy-mcp → Hevy APIThe hosted endpoint creates a fresh MCP server and Hevy client for each request. It validates the supplied key with Hevy, keeps no shared user session, and does not persist the key. The local server follows the same tool contract but runs on your machine and receives the key through its child-process environment.
In either mode, read tools retrieve data; mutation tools create or replace data only when your assistant calls them.
Guided prompts
These server-provided MCP prompts coordinate common multi-step workflows:
Prompt | Arguments | Workflow |
| Optional | Calls |
| Required | Loads a routine, collects actual completed-set data and an end time, then creates a workout without inventing results. |
With MCP SDK v1.29.0, clients invokinganalyze-workout-progress with its
default value must send arguments: {}. Omitting the entire arguments
object is rejected by that SDK version before the default is applied.
Tools
hevy-mcp registers 22 tools. Read-only tools are safe for exploration; create
and update tools are exposed with MCP mutation annotations so compatible clients
can request confirmation.
Category | Tool | Description |
Training analysis |
| Summarize 1-12 weeks of workout activity and body-measurement trends in one call. |
Workouts |
| List workouts in Hevy API order, not by start time, with exercise and timing details. |
Workouts |
| Get complete details for one workout by ID. |
| Workouts | get-workout-events | List workout update and delete events since a timestamp. |
| Workouts | create-workout | Create a completed workout in Hevy. |
| Workouts | update-workout | Patch workout metadata by ID; is_private is required, while other omitted fields and all exercises remain unchanged. |
| Workouts | replace-workout-exercises | Replace all exercises and sets; is_private is required and updated, while other workout metadata remains unchanged. |
| Routines | search-routines | Search routine titles and return compact metadata for discovery. |
| Routines | get-routines | List custom and default workout routines. |
| Routines | get-routine | Get one routine and its exercise configuration by ID. |
| Routines | create-routine | Create a reusable workout routine. |
| Routines | update-routine | Replace an existing routine's content. |
| Routine folders | get-routine-folder | Get one routine folder's metadata by ID. |
| Routine folders | create-routine-folder | Create a routine folder. |
| Exercise templates | get-exercise-template | Get complete metadata for one exercise template by ID. |
| Exercise templates | search-exercise-templates | Search the full exercise catalog by title substring. |
| Exercise templates | create-exercise-template | Create a custom exercise template. |
| Exercise history | get-exercise-history | Get past performed sets for one exercise template. |
| Body measurements | get-body-measurements | List dated body measurements. |
| Body measurements | get-body-measurement | Get the body measurement entry for one date. |
| Body measurements | create-body-measurement | Create a dated body measurement. |
| Body measurements | update-body-measurement | Update the body measurement for an existing date. |
create-routine and update-routine require a top-level routine envelope with a non-empty exercises array; each exercise must contain at least one set, and fields use snake_case at every level:
{
"routine": {
"title": "Full Body A",
"folder_id": 123,
"notes": "First four exercises are the minimum viable workout",
"exercises": [
{
"exercise_template_id": "30E293E3",
"superset_id": null,
"rest_seconds": 120,
"notes": "Controlled active ROM",
"sets": [
{
"type": "normal",
"rep_range": {
"start": 6,
"end": 10
}
}
]
}
]
}
}The Hevy API currently exposes no delete endpoints for workouts, routines, routine folders, exercise templates, or body measurements, so there are no corresponding delete tools.
Resources
Name | URI | Description |
|
| Authenticated Hevy user profile. |
|
| Total number of workouts in the account. |
|
| Full formatted exercise template catalog. |
|
| Full formatted list of Hevy routine folders. |
Hosted Cloudflare endpoint
The production MCP server is live at:
https://mcp.hevy-mcp.dev/mcpIt is the quickest way to use hevy-mcp: there is nothing to install or keep
running locally, and it exposes the same 22 tools as the npm package and Docker
image.
The Cloudflare Worker uses stateless Streamable HTTP at POST /mcp.
Clients must send their Hevy API key as a fixed authorization header:
{
"mcpServers": {
"hevy": {
"url": "https://mcp.hevy-mcp.dev/mcp",
"headers": {
"Authorization": "Bearer your-hevy-api-key"
}
}
}
}The bearer value is your Hevy API key, not an OAuth token. The Worker validates
the key with Hevy on each request, does not store it, and forwards it upstream
only as Hevy's required api-key header.
OAuth for Claude.ai and other remote MCP clients
The hosted production Worker is deployed with an OAUTH_KV namespace binding,
so it exposes a full OAuth 2.1 layer for clients that cannot send a fixed
header, such as Claude.ai custom connectors. Self-hosted Workers can opt in by
following the OAUTH_KV setup in CONTRIBUTING.md:
RFC 8414 / RFC 9728 discovery metadata under
/.well-known/Client ID Metadata Documents (CIMD), with dynamic client registration (
/register) as a fallback, and PKCE token exchange (/token)An
/authorizepage where you paste your Hevy API key once; the key is validated with Hevy and stored encrypted inside the OAuth grant
Add the Worker URL ending in /mcp as a Claude.ai custom connector and
complete the authorization flow in the browser. Direct
Authorization: Bearer <hevy-api-key> requests keep working unchanged — the
OAuth layer is purely additive — and rotating your Hevy API key invalidates
every OAuth grant created with it.
OAuth access tokens last seven days and refresh tokens last 30 days. This reduces KV writes from frequent hourly refreshes while preserving automatic refresh for supported clients.
The endpoint does not expose legacy SSE or a GET event stream. Without the
opt-in OAuth layer, clients that require OAuth discovery, dynamic
registration, CIMD, or token refresh are not compatible unless they can send
the fixed custom header above.
Self-host the Worker
A clean clone can deploy the portable TypeScript Wrangler configuration with
npx wrangler deploy --x-new-config and receive a workers.dev URL. OAuth
requires your own OAUTH_KV namespace; custom domains, routes, and
observability destinations are optional account-owned settings. See
CONTRIBUTING.md for setup and
for the distinction between self-hosting and the maintainer-only named
environments.
See CONTRIBUTING.md to deploy the Cloudflare Worker for self-hosted Streamable HTTP.
Advanced configuration
Setting | Default | Scope | Notes |
| None; required | Local stdio or HTTP | Hevy API key from the Hevy app. Never pass it in a URL. |
|
| Local stdio | Positive Hevy API timeout in milliseconds. Invalid values fall back to 60 seconds. |
| Disabled | Local Node | Set to exactly |
| None | Non-loopback HTTP | Required when |
|
| Local HTTP | Maximum established sessions, including sessions currently initializing; excess requests receive |
|
| Local HTTP | Maximum concurrent session initializations; excess requests receive |
|
| Local HTTP | Idle sessions are evicted after 30 minutes; each session request resets the timer. |
|
| Local HTTP | Stalled request bodies receive |
| Enabled | Local Node | Set to exactly |
| Enabled | Local Node | Set to exactly |
|
| Local stdio | Changes the root for the npm update-check cache at |
| Packaged Sentry SaaS project DSN | Optional local Node telemetry | Sentry project DSN override. An empty value disables Sentry export. The Worker does not import Node telemetry. |
|
| Optional local Node telemetry | Overrides the release label attached to local Sentry error events. |
| N/A | Local stdio CLI | Print supported options and exit. |
| N/A | Local stdio CLI | Print the installed version and exit. |
The local Node executable uses stdio by default. Opt into local Streamable HTTP with:
HEVY_API_KEY=your-hevy-api-key npx hevy-mcp --transport http --host 127.0.0.1 --port 3000The local MCP endpoint is http://127.0.0.1:3000/mcp; non-loopback binds
require the separate HEVY_MCP_HTTP_BEARER_TOKEN environment variable. A
Docker deployment must publish the port explicitly:
docker run --rm -p 3000:3000 -e HEVY_API_KEY -e HEVY_MCP_HTTP_BEARER_TOKEN \\
ghcr.io/chrisdoc/hevy-mcp:latest --transport http --host 0.0.0.0 --port 3000This Node HTTP mode is distinct from the stateless Cloudflare Worker HTTP endpoint described above: the Node server owns stateful client sessions, while the Worker is designed for hosted deployment and does not import Node code.
Cache behavior
search-exercise-templates and hevy://exercise-templates share a
server-scoped in-memory catalog cache:
Entries live for five minutes, and the cache holds at most one catalog.
Concurrent catalog requests share an in-flight fetch when possible.
search-exercise-templatesacceptsrefresh: trueto invalidate the cache.Each hosted Worker request gets a fresh cache, preventing cross-key sharing.
Local Node telemetry and privacy
The local Node package enables project telemetry by default. It is local Node
behavior only; the Cloudflare Worker does not import Node telemetry. Set
HEVY_MCP_TELEMETRY=0 before launching the Node process to disable all project
telemetry. The scoped Node lifecycle Layer reads this process-launch setting;
importing the package remains side-effect-free. Only the literal value 0 opts
out: an unset value, an empty value, 1, false, and every other value remain
enabled. The master setting takes precedence over SENTRY_DSN and packaged or
runtime OTEL_COLLECTOR_TOKEN credentials, so the disabled path creates no
telemetry exporters or periodic metric readers and makes no telemetry network
requests. SENTRY_DSN remains a Sentry-only setting; when telemetry is enabled,
an empty value disables only Sentry export.
When enabled, actionable errors are sent to the Sentry project configured by
SENTRY_DSN; Sentry performance tracing is disabled. Exception messages and
stacks are bounded and scrubbed before export. Set
HEVY_MCP_TELEMETRY_DIAGNOSTICS=0 to keep structural traces and metrics while
suppressing those details. Traces and metrics continue to be sent to the
collector at
https://otel.chrisdoc.dev/v1/traces and
https://otel.chrisdoc.dev/v1/metrics, which forward to Honeycomb. Metrics
export every 30 seconds.
The API key is never exported and is not used to derive a user identity. A per-failure diagnostic ID and OTel trace ID may be attached to actionable errors for support correlation. Structured telemetry contains only bounded service, release, transport, tool, outcome, error, count, retry, duration, session, cache, workflow, API method, normalized endpoint, and status fields.
Exception messages and stacks are treated as diagnostic details: they are
length-limited, scrubbed for credentials, URLs, and local home paths, and
removed entirely when HEVY_MCP_TELEMETRY_DIAGNOSTICS=0. Prompts, tool
arguments, tool results, request bodies, API keys, raw identifiers/queries,
exact dates, workout/routine/folder/template/body-measurement content,
names/titles/descriptions/notes, measurement values, arbitrary client
metadata, and unnormalized endpoint paths remain prohibited.
Security and mutations
Keep
HEVY_API_KEYout of source control, URLs, logs, and screenshots.Local clients provide the key through the child process environment.
Hosted clients send the key only in the
Authorization: Bearerheader. The Worker validates each key with Hevy, does not store it, and sends it upstream only as Hevy'sapi-keyheader.Browser requests must come from an exact allowlisted origin. The default allowlist includes Claude.ai, ChatGPT, VS Code for the Web, and github.dev; self-hosted deployments can override it with
MCP_ALLOWED_ORIGINS.Local development can copy
.dev.vars.exampleto.dev.varsto disable Origin validation for MCP Inspector. PR preview Workers use the same development-only setting because their browser origins are dynamic. Never setMCP_DISABLE_ORIGIN_CHECK=trueon a production Worker.Create operations can produce duplicates when retried. Update operations replace existing records. Review tool inputs and use client confirmations.
Troubleshooting
The server does not appear: restart or reconnect your MCP client after changing its configuration.
npxfails: confirm that Node.js 20 or newer is installed, then runnpx -y hevy-mcp --versionin a terminal.Codex cannot see the server: run
codex mcp list, then start a new Codex session after confirming thehevyentry exists.Hevy API returns 401: the key is invalid, expired, revoked, or misconfigured. Verify or create an active key at Hevy's API settings, then restart the client.
Hosted authentication fails: confirm the key belongs to a Hevy PRO account and is sent as
Authorization: Bearer <HEVY_API_KEY>.Local authentication fails: confirm the key is active and available to the MCP child process as
HEVY_API_KEY.Need diagnostics: set
HEVY_MCP_DEBUG=1. Diagnostic output goes to stderr and does not interfere with MCP messages on stdout.
If you find a bug or have a feature request, open an issue.
Contributing
Contributions are welcome. Developer setup, testing lanes, generated-client workflows, Cloudflare Worker deployment, and pull request rules are documented in CONTRIBUTING.md.
Use mise for the pinned Node.js and pnpm versions, then run the deterministic unit lane. It does not need a live Hevy API key:
MISE_AUTO_INSTALL=false mise install
MISE_AUTO_INSTALL=false mise exec -- pnpm install
MISE_AUTO_INSTALL=false mise exec -- pnpm run test:unitLicense and acknowledgements
License: MIT
Credits: Model Context Protocol and Hevy Fitness
Available Tools
23 toolscreate-body-measurementA
Create a body measurement entry for a given date. All measurement fields are optional; null values are treated as omitted, since the Hevy API does not support clearing individual fields. Returns 409 if an entry already exists for that date — use update-body-measurement instead.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | The date of the body measurement (YYYY-MM-DD). Must be unique — returns 409 if an entry already exists for this date. | |
| hips | No | Hips circumference in centimeters | |
| waist | No | Waist circumference in centimeters | |
| neckCm | No | Neck circumference in centimeters | |
| abdomen | No | Abdomen circumference in centimeters | |
| chestCm | No | Chest circumference in centimeters | |
| leftCalf | No | Left calf circumference in centimeters | |
| weightKg | No | Body weight in kilograms | |
| leftThigh | No | Left thigh circumference in centimeters | |
| rightCalf | No | Right calf circumference in centimeters | |
| fatPercent | No | Body fat percentage | |
| leanMassKg | No | Lean body mass in kilograms | |
| rightThigh | No | Right thigh circumference in centimeters | |
| shoulderCm | No | Shoulder circumference in centimeters | |
| leftBicepCm | No | Left bicep circumference in centimeters | |
| rightBicepCm | No | Right bicep circumference in centimeters | |
| leftForearmCm | No | Left forearm circumference in centimeters | |
| rightForearmCm | No | Right forearm circumference in centimeters |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that null values are omitted (not cleared) and 409 error for duplicates, adding context beyond annotations which already indicate non-read-only and non-idempotent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler; front-loaded with purpose, followed by key behavioral notes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers creation semantics, duplicate handling, and null behavior; missing return value mention but acceptable given no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline 3; description adds value by explaining that null values are treated as omitted, which is not in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Create' and the resource 'a body measurement entry for a given date', and distinguishes from update-body-measurement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when not to use (409 if entry exists) and provides alternative 'use update-body-measurement instead', plus guidance on null values.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create-exercise-templateB
Create a custom exercise template with title, type, equipment, and muscle groups.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| muscleGroup | Yes | ||
| exerciseType | Yes | ||
| otherMuscles | No | ||
| equipmentCategory | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description does not disclose behavioral traits such as whether authentication is required, whether creation is idempotent, or what happens to the response. Annotations provide no hints (readOnlyHint=false, no other hints), so the description bears the full burden but fails to add context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that is front-loaded and contains no unnecessary words. Every part earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 5 parameters (4 required) and no output schema, the description is too minimal. It lacks information about what a template is, the return format, error conditions, or how this fits into the broader exercise template workflow.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With schema description coverage at 0%, the description only names parameters (title, type, equipment, muscle groups) without adding semantics beyond the schema property names. It does not explain the meaning of each parameter, constraints beyond schema, or defaults like otherMuscles.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool creates a custom exercise template and lists the key fields (title, type, equipment, muscle groups). This verb+resource combination distinguishes it from sibling tools that create other entities like workouts or routines.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives such as searching for existing templates or updating templates. There is no mention of prerequisites or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create-routineA
Create a new workout routine in your Hevy account. Requires a title and at least one exercise with sets. Optionally assign to a folder. Returns the full routine details including the new routine ID.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | No | ||
| title | Yes | ||
| folderId | No | ||
| exercises | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations set readOnlyHint=false and destructiveHint=false, so description must clarify behavior. Description explains it creates a new routine and returns full details with new routine ID, which is sufficient. No contradictions; no extra safety warnings needed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, no fluff. The first sentence states purpose and requirements; the second confirms return value. Efficiently structured for quick understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complex nested schema (exercises with many sub-properties) and no output schema, the description is high-level but incomplete. It misses details about notes, supersetId, restSeconds, and set sub-properties (distance, duration, etc.). The description covers only the essentials, leaving gaps for an AI agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so description must compensate. It mentions required title, exercises with sets, and optional folderId. However, it does not elaborate on other parameters like notes or nested set properties (reps, weight, type, etc.), which are in the schema but undocumented in the description. Only partial value added.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it creates a workout routine, specifies resource type (Hevy account), and differentiates from sibling tools like create-workout and create-routine-folder. The verb 'Create' and resource 'workout routine' are explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides usage context: requires title and at least one exercise with sets, and optional folder. It implies when to use this tool (when creating a routine) but does not explicitly exclude scenarios or mention alternatives. Sibling tools are distinct, so no confusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create-routine-folderA
Create a new routine folder in your Hevy account. Requires a name for the folder. Returns the full folder details including the new folder ID.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate mutation (readOnlyHint=false) but description adds context by stating it returns full folder details including the new ID. However, no discussion of side effects, permissions, or limits beyond what annotations imply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, no unnecessary words. Front-loaded with the purpose, then key requirement, then return value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple create tool with one parameter, the description covers purpose, input requirement, and output. The lack of an output schema is compensated by mentioning return of full folder details. Minor gap: no mention of potential errors or constraints.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema describes name as a required string with minLength 1, but description merely restates that a name is needed without adding semantic details like naming conventions or uniqueness constraints. With 0% schema description coverage, the description should compensate but does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool creates a new routine folder in Hevy, with a specific verb and resource. It distinguishes from sibling tools like create-routine and create-workout by focusing on folder creation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives, such as creating a routine directly or when folders are needed. The description only mentions the required name parameter.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create-workoutA
Create a new workout in your Hevy account. Requires title, start/end times, and at least one exercise with sets. Returns the complete workout details upon successful creation including the newly assigned workout ID.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| endTime | Yes | ||
| exercises | No | ||
| isPrivate | No | ||
| startTime | Yes | ||
| description | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate write operation (readOnlyHint=false), non-destructive, non-idempotent. Description confirms creation and return of details, adding that a workout ID is assigned. However, no discussion of auth requirements, rate limits, or side effects like overwriting or conflicts.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, each serving a clear purpose: first states action and requirements, second states return value. No extraneous text. Efficient and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Description covers creation intent and returns but omits error conditions, prerequisites (e.g., exercise template existence), or validation constraints. Moderate complexity with 6 parameters and nested exercises array warrants more guidance for safe invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema_description_coverage, description should compensate. It mentions required fields (title, startTime, endTime, exercises) but ignores all optional parameters like isPrivate, description, and lacks details on exercising input format (though schema provides structure). Incomplete coverage of 6 parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Create a new workout' with specific verb and resource. Includes requirements (title, start/end times, exercises) and return value (workout ID). Clearly distinguishes from sibling tools like get-workout, update-workout, or create-routine.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description implies usage when creating a new workout but provides no explicit guidance on when to use vs alternatives. No mention of prerequisites (e.g., need for exercise templates) or when not to use (e.g., if editing an existing workout).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-body-measurementARead-only
Get a single body measurement by date. Returns all measurement fields for the specified date.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | The date of the body measurement (YYYY-MM-DD) |
Output Schema
| Name | Required | Description |
|---|---|---|
| bodyMeasurement | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, and the description adds that it returns all measurement fields for the specified date. This adds useful context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences that are front-loaded and concise. Every sentence serves a purpose with no waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, one parameter, and presence of an output schema, the description covers the core behavior. No additional information is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with the date parameter fully described. The description confirms 'by date' but does not add significant new meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the tool gets a single body measurement by date, using a specific verb and resource. It distinguishes from the sibling 'get-body-measurements' by explicitly saying 'single'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use (when you need a measurement for a specific date) but does not explicitly mention alternatives or when not to use. The context is clear enough for a simple tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-body-measurementsBRead-only
Get a paginated list of body measurements for the authenticated user. Returns measurements including weight, body fat, and various circumference measurements.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| pageSize | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| bodyMeasurements | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the description's mention of pagination adds useful context beyond the safety profile. However, it does not disclose other behavioral details like default ordering or response limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences front-load the action and resource, with no wasted words. It effectively communicates the core functionality.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While an output schema exists, the description does not cover parameter semantics, which are essential for correct tool usage. The lack of parameter information makes the tool underspecified for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description mentions pagination qualitatively but fails to explain the two parameters ('page' and 'pageSize') or their constraints (e.g., max pageSize=10). With 0% schema description coverage, this is a critical gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves a paginated list of body measurements for the authenticated user, specifying included metrics (weight, body fat, circumference). This distinguishes it from siblings like 'get-body-measurement' (singular) and mutation tools like 'create-body-measurement'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for listing measurements but provides no explicit guidance on when to use this versus alternative listing tools (e.g., no comparison to search tools). No when-not-to conditions 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.
get-exercise-historyARead-only
Get past sets for a specific exercise template, optionally filtered by start and end dates.
| Name | Required | Description | Default |
|---|---|---|---|
| endDate | No | ISO 8601 end date for filtering history | |
| startDate | No | ISO 8601 start date for filtering history | |
| exerciseTemplateId | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| exerciseHistory | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description does not reveal behavioral details beyond what annotations provide. The readOnlyHint=true annotation already indicates a safe read operation, so the description adds no extra context about pagination, ordering, authentication, or potential limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence of 13 words, front-loading the core purpose. Every word is necessary, with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema (not shown), the description need not detail return values. For a simple query tool with a required parameter and two optional filters, the description is sufficiently complete. Minor improvement would be mentioning ordering or default range.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 67% (startDate and endDate have descriptions, exerciseTemplateId has none). The description's phrase 'specific exercise template' implies exerciseTemplateId's role, but does not detail its format or source. Overall, marginal added value over schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get' and the resource 'past sets for a specific exercise template', with optional date filtering. It distinguishes from sibling tools like 'get-exercise-template' which retrieves template metadata, and 'get-workout' which retrieves workout details, not set history.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives, such as when to fetch sets from a workout versus historical data. No exclusions or prerequisites mentioned, leaving the agent to infer usage from sibling tool names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-exercise-templateARead-only
Get complete details of a specific exercise template by its ID, including name, category, equipment, muscle groups, and notes.
| Name | Required | Description | Default |
|---|---|---|---|
| exerciseTemplateId | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| exerciseTemplate | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true. Description adds that it returns 'complete details' with specific fields. No contradictions. Additional behavioral context like error handling or ID format not provided, but acceptable given annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, front-loaded with purpose, lists included fields concisely. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-ID tool with output schema present, description covers purpose and returned fields. Lacks details like error behavior or ID format, but these are secondary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 0% description coverage for the single parameter exerciseTemplateId. Description does not explain its meaning beyond the name and the fact it's an ID. No format, example, or additional context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states verb 'get', resource 'exercise template', scope 'by its ID', and lists specific fields returned (name, category, equipment, muscle groups, notes). Clearly distinguishes from siblings like get-exercise-templates (list) and search-exercise-templates.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implicitly clear: use when you have an ID and need full details. No explicit when-not-to-use or alternatives, but context from siblings and name makes it obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-exercise-templatesARead-only
Get a paginated list of exercise templates (default and custom) with details like name, category, equipment, and muscle groups. Useful for browsing or searching available exercises.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| pageSize | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| exerciseTemplates | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation is already present, and the description adds context about pagination but does not elaborate on behavioral details like authorization or rate limits. Given annotations cover the safety profile, the description provides adequate but not exceptional transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise with two sentences, front-loading the main action. It efficiently conveys the tool's purpose without unnecessary verbiage.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the basic purpose and result, but lacks details on pagination behavior or error handling. Since an output schema exists, return values are documented elsewhere, yet some operational context is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description must compensate but only mentions 'paginated list' without explaining page and pageSize parameters. It does not add meaning beyond the schema, leaving agents to infer parameter semantics from names alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves a paginated list of exercise templates, specifying types (default/custom) and example details. It distinguishes itself from sibling tools like get-exercise-template (singular) and search-exercise-templates by focusing on browsing a list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description indicates it's useful for browsing or searching, providing clear usage context. However, it does not explicitly mention when not to use it or compare with search-exercise-templates, lacking full guidance on alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-routineARead-only
Get a routine by its ID using the direct endpoint. Returns all details for the specified routine.
| Name | Required | Description | Default |
|---|---|---|---|
| routineId | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| routine | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the description's mention of 'Returns all details' adds some context. However, it does not disclose any additional behavioral traits such as authentication requirements or response structure beyond the output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no wasted words. The purpose is front-loaded, making it easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-ID tool with one parameter and an output schema, the description is largely complete. It could mention that the output schema documents the returned details, but this is not necessary given the context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description only refers to 'by its ID' without elaborating on the routineId parameter's format, example values, or source. This provides minimal value beyond the schema's type and minLength.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get' and the resource 'routine by its ID', and specifies that it returns all details. This accurately distinguishes it from sibling tools like 'get-routines' (plural) and 'get-routine-folder'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when a specific routine ID is known, but does not explicitly mention when not to use it or suggest alternatives like 'get-routines' for listing. The context is clear but lacks exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-routine-folderARead-only
Get complete details of a specific routine folder by its ID, including name, creation date, and associated routines.
| Name | Required | Description | Default |
|---|---|---|---|
| folderId | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| routineFolder | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, indicating a safe read operation. The description adds value by specifying the returned data (name, creation date, associated routines), going beyond annotations. No behavioral contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that immediately states the tool's purpose. It is concise with no redundant words or unnecessary details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one parameter, no nested objects) and the presence of an output schema, the description is fairly complete. It mentions key return fields, though it could elaborate on the structure of 'associated routines'.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has one parameter (folderId) with 0% documentation. The description only says 'by its ID', adding minimal meaning. It fails to explain parameter constraints (e.g., expected format, example values) or how it relates to folder ID semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it retrieves complete details of a specific routine folder by ID, listing included fields (name, creation date, associated routines). This distinguishes it from sibling tools like 'get-routine-folders' (which lists all folders) and 'get-routine' (which retrieves a routine).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when you have a folder ID and need details, but it does not explicitly state when to use this tool versus alternatives, nor does it provide conditions or exclusions. No mention of prerequisites or when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-routine-foldersARead-only
Get a paginated list of your routine folders, including both default and custom folders. Useful for organizing and browsing your workout routines.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| pageSize | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| routineFolders | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the read-only behavior is covered. The description adds pagination context but does not disclose other traits like rate limits or response format beyond what the output schema provides.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description consists of two concise sentences, front-loading the primary function and adding a brief usage note with no redundant or unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description adequately covers the tool's purpose. It mentions default and custom folders and pagination, but lacks details on parameter usage and edge cases like empty results, which would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, yet the description does not explain the 'page' and 'pageSize' parameters, leaving their purpose and behavior undocumented. Common pagination parameters may be inferred, but the description should add value here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Get a paginated list') and resource ('your routine folders'), and distinguishes from siblings like 'get-routine-folder' (singular) and 'create-routine-folder' by specifying it returns both default and custom folders.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for organizing and browsing routines but does not explicitly state when to use this tool versus alternatives like 'get-routine-folder' or provide exclusions. No when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-routinesARead-only
Get a paginated list of your workout routines, including custom and default routines. Useful for browsing or searching your available routines.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| pageSize | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| routines | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, indicating a safe read operation. The description adds that the list is paginated and includes custom and default routines, which is useful context. However, it does not disclose pagination details (e.g., page numbering, sorting) or authentication requirements. Given the annotations, the description adds moderate value but could say more about behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences: the first states the function, the second adds a use case. Every word is necessary; no repetition or fluff. It is appropriately sized and front-loaded with the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (two optional parameters, output schema exists, annotations present), the description covers the main purpose and usage context. It mentions that custom and default routines are included. While it could mention sorting or folder context, the output schema likely provides return value details, so completeness is high but not maximal.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 0%, but the description does not explain the parameters 'page' and 'pageSize' at all. It only mentions 'paginated list' without linking to the parameters. The description fails to compensate for the lack of schema descriptions, leaving the agent to infer parameter usage from the schema defaults and constraints alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get a paginated list of your workout routines, including custom and default routines.' It uses a specific verb ('Get'), resource ('routines'), and scope ('paginated list, including custom and default'). It distinguishes itself from siblings like 'get-routine' (singular) and 'get-routine-folders' by focusing on listing all routines.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says 'Useful for browsing or searching your available routines,' which provides a clear use case. While it does not explicitly state when not to use it (e.g., for a specific routine, use get-routine), the context is clear and the sibling tools imply alternatives. No exclusions are given, but the guidance is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-user-infoARead-only
Get the authenticated user's account info, including user ID, display name, and public profile URL. Useful for verifying which account the API key belongs to.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| user | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already set readOnlyHint=true. The description reinforces this by describing a read operation and adds context about returned fields and purpose. No additional behavioral traits needed; no contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no wasted words. The first sentence states the core action and outputs; the second provides a concrete use case. Well-structured and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool (zero parameters, output schema exists), the description covers everything needed: purpose, output fields, and use case. It is complete and leaves no gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist, and schema coverage is 100%. The description does not need to add parameter details; it correctly focuses on the output. Baseline score of 4 for zero-parameter tools is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get the authenticated user's account info' and lists specific fields (user ID, display name, public profile URL). It is unambiguous and distinct from sibling tools, which are all about body measurements, exercises, routines, and workouts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear use case: 'Useful for verifying which account the API key belongs to.' While it does not explicitly mention when not to use or alternatives, the context makes it obvious as there are no sibling tools for user info.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-workoutARead-only
Get complete details of a specific workout by ID. Returns all workout information including title, description, start/end times, and detailed exercise data.
| Name | Required | Description | Default |
|---|---|---|---|
| workoutId | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| workout | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, so description adds limited behavioral context beyond stating what data is returned. No mention of error handling, auth, or other constraints, but with annotations this is acceptable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with core action, no fluff. Efficiently states purpose and return contents.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple single-parameter tool with an output schema, the description covers the main return fields. Could mention error behavior (e.g., 404 if ID not found) but overall adequate given low complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, yet description only says 'by ID' without explaining format, source, or constraints for workoutId. The parameter name is somewhat self-explanatory but description should compensate more.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Get' and resource 'workout', specifying retrieval by ID. It clearly distinguishes from siblings like 'get-workouts' (plural) which lists workouts, not a single one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies usage when needing full details of a specific workout, but lacks explicit when-not-to-use or mention of alternatives like 'get-workouts' or 'get-workout-count'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-workout-countARead-only
Get the total number of workouts on the account. Useful for pagination or statistics.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, making the safe read nature clear. The description adds that it returns a count, but no further behavioral context (e.g., response format, pagination details) beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that perfectly conveys the purpose and use cases with zero waste. Front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters, an output schema existing, and annotations covering safety, the description is fully complete for an agent. It adds the needed context for pagination/statistics use cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist, so baseline is 4. The description doesn't add parameter info (unnecessary) and remains clear about the tool's function.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it returns the total number of workouts on the account, distinguishing from sibling tools like get-workouts (list) and get-workout (single). The verb 'get' and noun 'total number of workouts' specify exactly what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly mentions usefulness for pagination or statistics, providing clear context for when to use. Does not explicitly exclude other scenarios or compare to siblings, but the guidance is helpful enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-workout-eventsARead-only
Retrieve a paged list of workout events (updates or deletes) since a given date. Events are ordered from newest to oldest. The intention is to allow clients to keep their local cache of workouts up to date without having to fetch the entire list of workouts.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| since | No | 1970-01-01T00:00:00Z | |
| pageSize | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| events | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint=true, and the description confirms it is a read operation. The description adds ordering (newest to oldest) and paging behavior, which is valuable beyond the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise with three sentences. The first sentence states the core function, the second adds ordering, and the third explains the intent. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the existence of an output schema and the context of sibling tools, the description adequately explains the tool's purpose and behavior for cache synchronization. It could include more parameter details but is complete for the intended use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not detail individual parameters. It implicitly references 'since' and paging but lacks specifics on defaults, formats, or constraints that would help the agent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves a paged list of workout events (updates or deletes) since a given date, ordered newest to oldest. It differentiates from siblings like get-workout and get-workouts by focusing on incremental cache updates.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states the intended use case: allow clients to keep their local cache up to date without fetching entire list. It does not explicitly exclude other uses, but the guidance is clear and contextually appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-workoutsARead-only
Get a paginated list of workouts. Returns workout details including title, description, start/end times, and exercises performed. Results are ordered from newest to oldest.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| pageSize | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| workouts | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true (safe read). The description adds context about pagination behavior and ordering (newest first), which goes beyond annotations and helps the agent understand the tool's behavior. However, it does not mention potential edge cases like empty lists or error handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the main purpose. No wasted words, but could be slightly more concise by merging the second and third parts. Overall well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema (which describes return values), the description provides sufficient context about what the workout details include (title, description, times, exercises). It does not mention pagination metadata, but the output schema likely covers that. Missing any mention of scope (e.g., all user's workouts) is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% (no parameter descriptions in schema). The description only says 'paginated list', implying page and pageSize parameters, but does not explain their constraints (e.g., page is a positive integer, pageSize max 10). The agent must infer from schema defaults and constraints, which is insufficient for a 0% coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns a paginated list of workouts with ordering from newest to oldest. This distinguishes it from sibling tools like 'get-workout' (single workout) and 'get-workout-count' (count only). The verb 'Get' and resource 'list of workouts' are specific and clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool vs alternatives (e.g., get-workout for a single workout, get-workout-count for counts). The context is implied by tool names, but the description does not explicitly state usage boundaries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search-exercise-templatesARead-only
Search exercise templates by name with optional muscle group filter. Fetches all templates from the Hevy API on first call, caches the catalog in memory with a bounded TTL cache, and reuses it for subsequent searches. Use refresh:true to force a re-fetch.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Case-insensitive substring to match against exercise template titles | |
| refresh | No | Set to true to invalidate the catalog cache and re-fetch all templates from the API | |
| primaryMuscleGroup | No | Optional filter to restrict results to a specific primary muscle group |
Output Schema
| Name | Required | Description |
|---|---|---|
| exerciseTemplates | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses caching behavior: first call fetches all templates, caches with bounded TTL, and reuse. It also explains the refresh parameter. This adds value beyond annotations (readOnlyHint). However, it does not specify TTL duration or cache limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, front-loaded with the core purpose, and every sentence adds value. No wasted words or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the schema covers all parameters, annotations provide readOnlyHint, and an output schema exists, the description provides sufficient context about caching behavior and refresh mechanism. No obvious gaps for a search tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds minimal value: it mentions the muscle group filter and refresh behavior, but these are also described in the schema. No new parameter semantics are introduced.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the purpose: 'Search exercise templates by name with optional muscle group filter.' It uses a specific verb (search) and resource (exercise templates), and distinguishes from sibling tools that fetch by ID or list all.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage through context (search by name, optional filter) but does not explicitly advise when to use this tool over siblings like get-exercise-templates. No when-not or alternative guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update-body-measurementADestructiveIdempotent
Update an existing body measurement entry for a given date. Only the fields you provide are sent and updated; null values are treated as omitted, since the Hevy API does not support clearing individual fields. Requires at least one measurement field. Returns 404 if no entry exists for the date.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | The date of the body measurement to update (YYYY-MM-DD). Must already exist — returns 404 otherwise. | |
| hips | No | Hips circumference in centimeters | |
| waist | No | Waist circumference in centimeters | |
| neckCm | No | Neck circumference in centimeters | |
| abdomen | No | Abdomen circumference in centimeters | |
| chestCm | No | Chest circumference in centimeters | |
| leftCalf | No | Left calf circumference in centimeters | |
| weightKg | No | Body weight in kilograms | |
| leftThigh | No | Left thigh circumference in centimeters | |
| rightCalf | No | Right calf circumference in centimeters | |
| fatPercent | No | Body fat percentage | |
| leanMassKg | No | Lean body mass in kilograms | |
| rightThigh | No | Right thigh circumference in centimeters | |
| shoulderCm | No | Shoulder circumference in centimeters | |
| leftBicepCm | No | Left bicep circumference in centimeters | |
| rightBicepCm | No | Right bicep circumference in centimeters | |
| leftForearmCm | No | Left forearm circumference in centimeters | |
| rightForearmCm | No | Right forearm circumference in centimeters |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds context beyond annotations: the API doesn't support clearing fields, so null values are omitted. This explains the idempotent behavior (sending same fields multiple times yields same result) and potential destructive nature (updating fields). The 404 response is also disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, with three sentences that cover purpose, behavior, and caveats. No unnecessary words or repetition. Well-structured and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 18 parameters and no output schema, the description covers the essential behavioral aspects: partial update semantics, null handling, required date, and 404 error. Missing success response format, but this is acceptable without an output schema. Adequate for agent decision-making.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so every parameter is described. The description adds valuable overall behavior: only provided fields are sent and updated, and at least one measurement field must be provided (not enforced in schema beyond date). This clarifies how to construct requests correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it updates an existing body measurement entry for a given date, specifying the resource and action. It implicitly distinguishes from sibling tools like create-body-measurement by emphasizing 'existing' but does not explicitly contrast.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear guidance: null values are treated as omitted (cannot clear fields), requires at least one measurement field, and returns 404 if date doesn't exist. This tells the agent how to use the tool correctly and what to expect.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update-routineADestructiveIdempotent
Update an existing routine by ID. You can modify the title, notes, and exercise configurations. Returns the updated routine with all changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | No | ||
| title | Yes | ||
| exercises | No | ||
| routineId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true; the description adds the return value but no additional behavioral context (e.g., partial vs full update, authorization needs, rate limits).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler; first sentence states purpose, second sentence clarifies return value. Efficient and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complex nested 'exercises' parameter and no output schema, the description provides only the most basic field names. It does not guide the agent on constructing the exercise array, leaving gaps for a tool with high parameter complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema coverage, the description only names 'title, notes, and exercise configurations' but fails to explain the complex nested structure of the 'exercises' parameter or mention the required 'routineId' parameter explicitly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the action ('Update an existing routine by ID'), the resource ('routine'), and the modifiable fields, distinguishing it from sibling tools like create-routine and get-routine.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies use for modifying existing routines, but lacks explicit when-not-to-use or alternatives among siblings. However, the tool name and description make the context clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update-workoutADestructiveIdempotent
Update an existing workout by ID. You can modify the title, description, start/end times, privacy setting, and exercise data. Returns the updated workout with all changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| endTime | Yes | ||
| exercises | No | ||
| isPrivate | No | ||
| startTime | Yes | ||
| workoutId | Yes | ||
| description | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate destructiveHint=true and idempotentHint=true. The description mentions returns but does not elaborate on side effects, required permissions, or partial update behavior. It neither contradicts nor significantly extends the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, front-loaded with action, no filler. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description includes return value info. It adequately covers parameters and behavior for a straightforward update tool. Lacks error handling or prerequisite details, but sufficient for typical use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description adds meaning by enumerating modifiable fields (title, description, start/end times, privacy, exercises). It helps the agent understand what each parameter group does, though it does not detail subfields like exercise parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ("Update an existing workout"), the resource (workout), and lists the modifiable fields. It distinguishes from siblings like create-workout (create vs update) and get-workout (read vs write).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use when modifying an existing workout but does not explicitly state when to use alternatives (e.g., update-routine) or any prerequisites. No guidance on when not to use this tool.
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.
15 tool updates
v1.28.0- Changed
get-body-measurement1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "bodyMeasurement": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "abdomen": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "chestCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "date": { + "type": "string" + }, + "fatPercent": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "hips": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "leanMassKg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "leftBicepCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "leftCalf": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "leftForearmCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "leftThigh": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "neckCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rightBicepCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rightCalf": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rightForearmCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rightThigh": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "shoulderCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "waist": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "weightKg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "date", + "weightKg", + "leanMassKg", + "fatPercent", + "neckCm", + "shoulderCm", + "chestCm", + "leftBicepCm", + "rightBicepCm", + "leftForearmCm", + "rightForearmCm", + "abdomen", + "waist", + "hips", + "leftThigh", + "rightThigh", + "leftCalf", + "rightCalf" + ], + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "bodyMeasurement" + ], + "type": "object" +}
- Changed
get-body-measurements1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "bodyMeasurements": { + "items": { + "additionalProperties": false, + "properties": { + "abdomen": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "chestCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "date": { + "type": "string" + }, + "fatPercent": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "hips": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "leanMassKg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "leftBicepCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "leftCalf": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "leftForearmCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "leftThigh": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "neckCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rightBicepCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rightCalf": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rightForearmCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rightThigh": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "shoulderCm": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "waist": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "weightKg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "date", + "weightKg", + "leanMassKg", + "fatPercent", + "neckCm", + "shoulderCm", + "chestCm", + "leftBicepCm", + "rightBicepCm", + "leftForearmCm", + "rightForearmCm", + "abdomen", + "waist", + "hips", + "leftThigh", + "rightThigh", + "leftCalf", + "rightCalf" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "bodyMeasurements" + ], + "type": "object" +}
- Changed
get-exercise-history1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "exerciseHistory": { + "items": { + "additionalProperties": false, + "properties": { + "customMetric": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "distance": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "duration": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "exerciseTemplateId": { + "type": "string" + }, + "reps": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rpe": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "setType": { + "type": "string" + }, + "weight": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "workoutEndTime": { + "type": "string" + }, + "workoutId": { + "type": "string" + }, + "workoutStartTime": { + "type": "string" + }, + "workoutTitle": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "exerciseHistory" + ], + "type": "object" +}
- Changed
get-exercise-template1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "exerciseTemplate": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isCustom": { + "type": "boolean" + }, + "primaryMuscleGroup": { + "type": "string" + }, + "secondaryMuscleGroups": { + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "exerciseTemplate" + ], + "type": "object" +}
- Changed
get-exercise-templates1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "exerciseTemplates": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isCustom": { + "type": "boolean" + }, + "primaryMuscleGroup": { + "type": "string" + }, + "secondaryMuscleGroups": { + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "exerciseTemplates" + ], + "type": "object" +}
- Changed
get-routine1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "routine": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "createdAt": { + "type": "string" + }, + "exercises": { + "items": { + "additionalProperties": false, + "properties": { + "exerciseTemplateId": { + "type": "string" + }, + "index": { + "type": "number" + }, + "name": { + "type": "string" + }, + "notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "restSeconds": { + "anyOf": [ + { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + { + "type": "null" + } + ] + }, + "sets": { + "items": { + "additionalProperties": false, + "properties": { + "customMetric": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "distance": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "duration": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "index": { + "type": "number" + }, + "repRange": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "end": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "start": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + }, + "reps": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rpe": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "type": { + "type": "string" + }, + "weight": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "supersetId": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "folderId": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "routine" + ], + "type": "object" +}
- Changed
get-routine-folder1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "routineFolder": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "createdAt": { + "type": "string" + }, + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "routineFolder" + ], + "type": "object" +}
- Changed
get-routine-folders1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "routineFolders": { + "items": { + "additionalProperties": false, + "properties": { + "createdAt": { + "type": "string" + }, + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "routineFolders" + ], + "type": "object" +}
- Changed
get-routines1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "routines": { + "items": { + "additionalProperties": false, + "properties": { + "createdAt": { + "type": "string" + }, + "exercises": { + "items": { + "additionalProperties": false, + "properties": { + "exerciseTemplateId": { + "type": "string" + }, + "index": { + "type": "number" + }, + "name": { + "type": "string" + }, + "notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "restSeconds": { + "anyOf": [ + { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + { + "type": "null" + } + ] + }, + "sets": { + "items": { + "additionalProperties": false, + "properties": { + "customMetric": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "distance": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "duration": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "index": { + "type": "number" + }, + "repRange": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "end": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "start": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + }, + "reps": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rpe": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "type": { + "type": "string" + }, + "weight": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "supersetId": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "folderId": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "routines" + ], + "type": "object" +}
- Changed
get-user-info1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "user": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "description": "The user ID.", + "type": "string" + }, + "name": { + "description": "The user's display name.", + "type": "string" + }, + "url": { + "description": "The user's public profile URL.", + "type": "string" + } + }, + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "user" + ], + "type": "object" +}
- Changed
get-workout1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "workout": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "createdAt": { + "type": "string" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "duration": { + "type": "string" + }, + "endTime": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "exercises": { + "items": { + "additionalProperties": false, + "properties": { + "exerciseTemplateId": { + "type": "string" + }, + "index": { + "type": "number" + }, + "name": { + "type": "string" + }, + "notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "sets": { + "items": { + "additionalProperties": false, + "properties": { + "customMetric": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "distance": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "duration": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "index": { + "type": "number" + }, + "reps": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rpe": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "type": { + "type": "string" + }, + "weight": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "supersetsId": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "id": { + "type": "string" + }, + "startTime": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "title": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": [ + "duration" + ], + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "workout" + ], + "type": "object" +}
- Changed
get-workout-count1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "count": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "count" + ], + "type": "object" +}
- Changed
get-workout-events1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "events": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "type": { + "description": "Indicates the type of the event (updated)", + "type": "string" + }, + "workout": { + "additionalProperties": false, + "properties": { + "created_at": { + "description": "ISO 8601 timestamp of when the workout was created.", + "type": "string" + }, + "description": { + "description": "The workout description.", + "type": "string" + }, + "end_time": { + "description": "ISO 8601 timestamp of when the workout was recorded to have ended.", + "type": "string" + }, + "exercises": { + "items": { + "additionalProperties": false, + "properties": { + "exercise_template_id": { + "description": "The id of the exercise template. This can be used to fetch the exercise template.", + "type": "string" + }, + "index": { + "description": "Index indicating the order of the exercise in the workout.", + "type": "number" + }, + "notes": { + "description": "Notes on the exercise", + "type": "string" + }, + "sets": { + "items": { + "additionalProperties": false, + "properties": { + "custom_metric": { + "anyOf": [ + { + "description": "Custom metric logged for the set (Currently only used to log floors or steps for stair machine exercises)", + "type": "number" + }, + { + "type": "null" + } + ] + }, + "distance_meters": { + "anyOf": [ + { + "description": "Number of meters logged for the set", + "type": "number" + }, + { + "type": "null" + } + ] + }, + "duration_seconds": { + "anyOf": [ + { + "description": "Number of seconds logged for the set", + "type": "number" + }, + { + "type": "null" + } + ] + }, + "index": { + "description": "Index indicating the order of the set in the workout.", + "type": "number" + }, + "reps": { + "anyOf": [ + { + "description": "Number of reps logged for the set", + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rpe": { + "anyOf": [ + { + "description": "RPE (Relative perceived exertion) value logged for the set", + "type": "number" + }, + { + "type": "null" + } + ] + }, + "type": { + "description": "The type of set. This can be one of 'normal', 'warmup', 'dropset', 'failure'", + "type": "string" + }, + "weight_kg": { + "anyOf": [ + { + "description": "Weight lifted in kilograms.", + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "supersets_id": { + "anyOf": [ + { + "description": "The id of the superset that the exercise belongs to. A value of null indicates the exercise is not part of a superset.", + "type": "number" + }, + { + "type": "null" + } + ] + }, + "title": { + "description": "Title of the exercise", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "id": { + "description": "The workout ID.", + "type": "string" + }, + "routine_id": { + "description": "The ID of the routine that this workout belongs to.", + "type": "string" + }, + "start_time": { + "description": "ISO 8601 timestamp of when the workout was recorded to have started.", + "type": "string" + }, + "title": { + "description": "The workout title.", + "type": "string" + }, + "updated_at": { + "description": "ISO 8601 timestamp of when the workout was last updated.", + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "type", + "workout" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "deleted_at": { + "description": "A date string indicating when the workout was deleted", + "type": "string" + }, + "id": { + "description": "The unique identifier of the deleted workout", + "type": "string" + }, + "type": { + "description": "Indicates the type of the event (deleted)", + "type": "string" + } + }, + "required": [ + "type", + "id" + ], + "type": "object" + } + ] + }, + "type": "array" + } + }, + "required": [ + "events" + ], + "type": "object" +}
- Changed
get-workouts1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "workouts": { + "items": { + "additionalProperties": false, + "properties": { + "createdAt": { + "type": "string" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "duration": { + "type": "string" + }, + "endTime": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "exercises": { + "items": { + "additionalProperties": false, + "properties": { + "exerciseTemplateId": { + "type": "string" + }, + "index": { + "type": "number" + }, + "name": { + "type": "string" + }, + "notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "sets": { + "items": { + "additionalProperties": false, + "properties": { + "customMetric": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "distance": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "duration": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "index": { + "type": "number" + }, + "reps": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "rpe": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "type": { + "type": "string" + }, + "weight": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "supersetsId": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "id": { + "type": "string" + }, + "startTime": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "title": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": [ + "duration" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "workouts" + ], + "type": "object" +}
- Changed
search-exercise-templates1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "exerciseTemplates": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isCustom": { + "type": "boolean" + }, + "primaryMuscleGroup": { + "type": "string" + }, + "secondaryMuscleGroups": { + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "exerciseTemplates" + ], + "type": "object" +}
1 tool update
v1.26.3- Changed
search-exercise-templates1 field changed- changed
Input schema / properties / refresh / descriptionPrevious value: -"Set to true to bust the in-memory cache and re-fetch all templates from the API"New value: +"Set to true to invalidate the catalog cache and re-fetch all templates from the API"
3 tool updates
v1.25.17- Removed
create-webhook-subscription - Removed
delete-webhook-subscription - Removed
get-webhook-subscription
1 tool update
v1.25.8- Added
get-user-info
25 tool updates
v1.23.8- Added
create-body-measurement - Added
create-exercise-template - Changed
create-routine19 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - removed
Input schema / properties / exercises / items / additionalPropertiesRemoved value: -false - added
Input schema / properties / exercises / items / properties / restSeconds / maximumAdded value: +9007199254740991 - removed
Input schema / properties / exercises / items / properties / sets / items / additionalPropertiesRemoved value: -false - added
Input schema / properties / exercises / items / properties / sets / items / properties / distanceAdded value: +{ + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Input schema / properties / exercises / items / properties / sets / items / properties / distanceMeters / maximumAdded value: +9007199254740991 - added
Input schema / properties / exercises / items / properties / sets / items / properties / distanceMeters / minimumAdded value: +-9007199254740991 - added
Input schema / properties / exercises / items / properties / sets / items / properties / durationAdded value: +{ + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Input schema / properties / exercises / items / properties / sets / items / properties / durationSeconds / maximumAdded value: +9007199254740991 - added
Input schema / properties / exercises / items / properties / sets / items / properties / durationSeconds / minimumAdded value: +-9007199254740991 - added
Input schema / properties / exercises / items / properties / sets / items / properties / repRangeAdded value: +{ + "properties": { + "end": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "start": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" +} - added
Input schema / properties / exercises / items / properties / sets / items / properties / reps / anyOfAdded value: +[ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } +] - removed
Input schema / properties / exercises / items / properties / sets / items / properties / reps / typeRemoved value: -"integer" - added
Input schema / properties / exercises / items / properties / sets / items / properties / weightAdded value: +{ + "type": "number" +} - added
Input schema / properties / exercises / items / properties / supersetId / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Input schema / properties / exercises / items / properties / supersetId / typeRemoved value: -[ - "number", - "null" -] - added
Input schema / properties / folderId / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Input schema / properties / folderId / typeRemoved value: -[ - "number", - "null" -] - changed
Input schema / requiredPrevious value: -[ - "title", - "exercises" -]New value: +[ + "title" +]
- Changed
create-routine-folder4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / nameAdded value: +{ + "minLength": 1, + "type": "string" +} - removed
Input schema / properties / titleRemoved value: -{ - "minLength": 1, - "type": "string" -} - changed
Input schema / requiredPrevious value: -[ - "title" -]New value: +[ + "name" +]
- Added
create-webhook-subscription - Changed
create-workout17 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / description / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "string" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / exercises / items / additionalPropertiesRemoved value: -false - changed
Input schema / properties / exercises / items / properties / notes / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "string" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / exercises / items / properties / sets / items / additionalPropertiesRemoved value: -false - changed
Input schema / properties / exercises / items / properties / sets / items / properties / customMetric / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "number" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - added
Input schema / properties / exercises / items / properties / sets / items / properties / distanceAdded value: +{ + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] +} - changed
Input schema / properties / exercises / items / properties / sets / items / properties / distanceMeters / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "integer" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } +] - added
Input schema / properties / exercises / items / properties / sets / items / properties / durationAdded value: +{ + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] +} - changed
Input schema / properties / exercises / items / properties / sets / items / properties / durationSeconds / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "integer" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } +] - changed
Input schema / properties / exercises / items / properties / sets / items / properties / reps / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "integer" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } +] - changed
Input schema / properties / exercises / items / properties / sets / items / properties / rpe / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "number" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - added
Input schema / properties / exercises / items / properties / sets / items / properties / weightAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] +} - changed
Input schema / properties / exercises / items / properties / sets / items / properties / weightKg / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "number" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - added
Input schema / properties / exercises / items / properties / supersetId / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Input schema / properties / exercises / items / properties / supersetId / typeRemoved value: -[ - "number", - "null" -] - changed
Input schema / requiredPrevious value: -[ - "title", - "startTime", - "endTime", - "exercises" -]New value: +[ + "title", + "startTime", + "endTime" +]
- Added
delete-webhook-subscription - Added
get-body-measurement - Added
get-body-measurements - Added
get-exercise-history - Changed
get-exercise-template1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
get-exercise-templates3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / page / maximumAdded value: +9007199254740991 - changed
Input schema / properties / pageSize / defaultPrevious value: -20New value: +5
- Changed
get-routine1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
get-routine-folder3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / folderId / minLengthAdded value: +1 - changed
Input schema / properties / folderId / typePrevious value: -"integer"New value: +"string"
- Changed
get-routine-folders2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / page / maximumAdded value: +9007199254740991
- Changed
get-routines2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / page / maximumAdded value: +9007199254740991
- Added
get-webhook-subscription - Changed
get-workout1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
get-workout-count1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
get-workout-events2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / page / maximumAdded value: +9007199254740991
- Changed
get-workouts1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Added
search-exercise-templates - Added
update-body-measurement - Changed
update-routine17 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - removed
Input schema / properties / exercises / items / additionalPropertiesRemoved value: -false - added
Input schema / properties / exercises / items / properties / restSeconds / maximumAdded value: +9007199254740991 - removed
Input schema / properties / exercises / items / properties / sets / items / additionalPropertiesRemoved value: -false - added
Input schema / properties / exercises / items / properties / sets / items / properties / distanceAdded value: +{ + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Input schema / properties / exercises / items / properties / sets / items / properties / distanceMeters / maximumAdded value: +9007199254740991 - added
Input schema / properties / exercises / items / properties / sets / items / properties / distanceMeters / minimumAdded value: +-9007199254740991 - added
Input schema / properties / exercises / items / properties / sets / items / properties / durationAdded value: +{ + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Input schema / properties / exercises / items / properties / sets / items / properties / durationSeconds / maximumAdded value: +9007199254740991 - added
Input schema / properties / exercises / items / properties / sets / items / properties / durationSeconds / minimumAdded value: +-9007199254740991 - added
Input schema / properties / exercises / items / properties / sets / items / properties / repRangeAdded value: +{ + "properties": { + "end": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "start": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" +} - added
Input schema / properties / exercises / items / properties / sets / items / properties / reps / anyOfAdded value: +[ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } +] - removed
Input schema / properties / exercises / items / properties / sets / items / properties / reps / typeRemoved value: -"integer" - added
Input schema / properties / exercises / items / properties / sets / items / properties / weightAdded value: +{ + "type": "number" +} - added
Input schema / properties / exercises / items / properties / supersetId / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Input schema / properties / exercises / items / properties / supersetId / typeRemoved value: -[ - "number", - "null" -] - changed
Input schema / requiredPrevious value: -[ - "routineId", - "title", - "exercises" -]New value: +[ + "routineId", + "title" +]
- Changed
update-workout17 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / description / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "string" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / exercises / items / additionalPropertiesRemoved value: -false - changed
Input schema / properties / exercises / items / properties / notes / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "string" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / exercises / items / properties / sets / items / additionalPropertiesRemoved value: -false - changed
Input schema / properties / exercises / items / properties / sets / items / properties / customMetric / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "number" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - added
Input schema / properties / exercises / items / properties / sets / items / properties / distanceAdded value: +{ + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] +} - changed
Input schema / properties / exercises / items / properties / sets / items / properties / distanceMeters / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "integer" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } +] - added
Input schema / properties / exercises / items / properties / sets / items / properties / durationAdded value: +{ + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] +} - changed
Input schema / properties / exercises / items / properties / sets / items / properties / durationSeconds / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "integer" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } +] - changed
Input schema / properties / exercises / items / properties / sets / items / properties / reps / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "integer" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } +] - changed
Input schema / properties / exercises / items / properties / sets / items / properties / rpe / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "number" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - added
Input schema / properties / exercises / items / properties / sets / items / properties / weightAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] +} - changed
Input schema / properties / exercises / items / properties / sets / items / properties / weightKg / anyOfPrevious value: -[ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "number" - } - ] - }, - { - "type": "null" - } -]New value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - added
Input schema / properties / exercises / items / properties / supersetId / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Input schema / properties / exercises / items / properties / supersetId / typeRemoved value: -[ - "number", - "null" -] - changed
Input schema / requiredPrevious value: -[ - "workoutId", - "title", - "startTime", - "endTime", - "exercises" -]New value: +[ + "workoutId", + "title", + "startTime", + "endTime" +]
15 tool updates
v1.0.0- First observed
create-routine - First observed
create-routine-folder - First observed
create-workout - First observed
get-exercise-template - First observed
get-exercise-templates - First observed
get-routine - First observed
get-routine-folder - First observed
get-routine-folders - First observed
get-routines - First observed
get-workout - First observed
get-workout-count - First observed
get-workout-events - First observed
get-workouts - First observed
update-routine - First observed
update-workout
TDQS
Scored across 23 tools
Every tool has a distinct purpose and clear naming: singular vs plural separates detail views from list views, and each resource type has its own verb-noun pair. Even similar tools like get-exercise-templates and search-exercise-templates are distinguishable by their retrieval mode.
Tool names consistently follow a verb-noun pattern (get, create, update, search) with snake_case and predictable singular/plural distinctions. The naming is uniform across workouts, routines, folders, exercise templates, and body measurements.
23 tools is on the heavy side, but the count is structured across several coherent subdomains (workouts, routines, templates, measurements). It feels somewhat large but not bloated or redundant.
The set covers read and create/update operations broadly, but there are no delete operations for any resource type, and exercise templates lack update/delete. Those are significant lifecycle gaps for a CRUD-oriented API, likely causing agent failures when cleanup or correction is needed.
Maintenance
Related MCP Connectors
Create Hevy routines and analyze your training from chat. Unofficial; BYO Hevy PRO API key.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Model Context Protocol server for the Apideck Unified API. Connect any MCP-compatible agent framework to 100+ accounting systems, HRIS platforms, file storage providers, and more through one integration. More information https://www.apideck.com/mcp-server
- mcpOAuthnet.todoist
Official Todoist MCP server for AI assistants to manage tasks, projects, and workflows.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP server that connects AI clients to the Hevy workout tracking app, allowing users to manage routines and exercises. It enables reading workout history and logging new fitness sessions through simple natural language commands.-
- AlicenseNot gradedqualityCmaintenancePython MCP server for the Hevy fitness app. Gives Claude full access to your Hevy data. Log workouts, manage routines, track body measurements, browse exercises, and more. Covers all 25 endpoints of the official Hevy API.MIT
- AlicenseAqualityDmaintenanceAn MCP server that interfaces with the Hevy fitness tracking API, enabling AI assistants to manage workouts, routines, exercise templates, and more via natural language.2658,400 npmMIT
- AlicenseNot gradedqualityCmaintenanceA Model Context Protocol (MCP) server that provides AI assistants with access to the Hevy fitness tracking API. This allows you to log workouts, manage routines, browse exercises, and track your fitness progress directly through AI chat interfaces.9 npmMIT