hevy-mcp: Model Context Protocol Server for Hevy Fitness API

July 9, 2026 ยท View on GitHub

License: MIT Build and Test Codecov npm version

A Model Context Protocol (MCP) server implementation that interfaces with the Hevy fitness tracking app and its API. This server enables AI assistants like Claude Desktop and Cursor to access and manage workout data, routines, and exercise templates through the Hevy API (requires PRO subscription).


๐Ÿ“‹ Table of Contents


๐Ÿš€ Features

  • Workout Management: Fetch, create, and update workouts.
  • Routine Management: Access and manage workout routines.
  • Exercise Templates: Browse available exercise templates with in-memory caching.
  • Folder Organization: Manage routine folders.

๐Ÿ Quick Start

Pick the workflow that fits your setup:

ScenarioCommandRequirements
One-off stdio runHEVY_API_KEY=sk_live... npx -y hevy-mcp or HEVY_API_KEY=sk_live... bunx hevy-mcp@latestNode.js โ‰ฅ 24, Hevy API key
Local developmentnpm install && npm run build && npm start.env with HEVY_API_KEY

๐Ÿ› ๏ธ Prerequisites

  • Node.js: v24 or higher (strongly recommended to use the exact version pinned in .nvmrc).
  • npm: v10 or higher.
  • Bun (optional): If you want to launch with bunx.
  • Hevy API key: Required for all operations (available with Hevy PRO).

๐Ÿ“ฆ Installation

Run via npx or bunx

You can launch the server directly without cloning. Both launchers are covered by nightly smoke tests:

# npm launcher
HEVY_API_KEY=your_hevy_api_key_here npx -y hevy-mcp

# bun launcher
HEVY_API_KEY=your_hevy_api_key_here bunx hevy-mcp@latest

Manual Installation

# Clone the repository
git clone https://github.com/chrisdoc/hevy-mcp.git
cd hevy-mcp

# Install dependencies
npm install

# Create .env and add your keys
cp .env.sample .env
# Edit .env and add your HEVY_API_KEY

๐Ÿ”— Integration

Claude Desktop Configuration

To use this server with Claude Desktop, add the following to your claude_desktop_config.json:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json

{
	"mcpServers": {
		"hevy-mcp": {
			"command": "npx",
			"args": ["-y", "hevy-mcp"],
			"env": {
				"HEVY_API_KEY": "sk_live_your_key_here"
			}
		}
	}
}

If you prefer Bun, swap the launcher fields:

{
	"command": "bunx",
	"args": ["hevy-mcp@latest"]
}

Cursor Configuration

Add this server under "mcpServers" in ~/.cursor/mcp.json:

{
	"mcpServers": {
		"hevy-mcp": {
			"command": "npx",
			"args": ["-y", "hevy-mcp"],
			"env": {
				"HEVY_API_KEY": "your-api-key-here"
			}
		}
	}
}

If you prefer Bun, swap the launcher fields:

{
	"command": "bunx",
	"args": ["hevy-mcp@latest"]
}

Other MCP Clients (via add-mcp)

For a generic setup flow across MCP clients, use add-mcp:

npx add-mcp hevy-mcp --env "HEVY_API_KEY=secret"

This bootstraps the hevy-mcp entry in your client config without manual JSON edits.


โœจ Why hevy-mcp?

  • ๐Ÿš€ High Performance: Built with the Oxc toolchain (oxlint/oxfmt) for near-instant linting and formatting.
  • ๐Ÿ›ก๏ธ Type Safety: Fully type-safe implementation using Zod and Kubb-generated API clients.
  • ๐Ÿ“‰ Observability: Built-in Sentry monitoring for error tracking, lifecycle and tool tracing, and stdio parse diagnostics.
  • โšก Optimized: Includes in-memory caching for exercise templates to reduce API latency.

โš™๏ธ Configuration

Supply your Hevy API key via the HEVY_API_KEY environment variable (in .env or system environment).

โš ๏ธ CLI API key arguments (--hevy-api-key=..., --hevyApiKey=..., hevy-api-key=...) are still accepted for backward compatibility, but are deprecated and insecure. Use HEVY_API_KEY instead.

Set HEVY_MCP_API_TIMEOUT to override the default 30-second Hevy API request timeout. Its value is in milliseconds.

# Example .env
HEVY_API_KEY=your_hevy_api_key_here
# Optional: customize Hevy API request timeout (milliseconds)
HEVY_MCP_API_TIMEOUT=30000

๐Ÿง  Exercise Template Cache Behavior

search-exercise-templates now uses a shared in-memory async cache for the full exercise template catalog:

  • TTL: 5 minutes per cached catalog entry.
  • Memory bound: max 1 catalog entry (LRU bounded cache).
  • In-flight de-duplication: concurrent requests share the same active fetch when possible.
  • Manual refresh: set refresh: true in the tool input to invalidate the cached catalog and force a re-fetch from the Hevy API.

This cache currently applies to search-exercise-templates only. Paginated get-exercise-templates requests still call the API directly to keep paging behavior explicit and avoid cross-page invalidation complexity.

๐Ÿ“ก Sentry Monitoring

hevy-mcp includes Sentry monitoring to observe errors and usage in production. It initializes @sentry/node with tracing enabled and PII collection disabled by default. Recent observability changes also add:

  • lifecycle spans around server build, run, and stdio connect
  • per-tool execution spans plus captured handler exceptions
  • stdio parse diagnostics, including leading UTF-8 BOM stripping and invalid JSON context
  • a deterministic pseudonymous Sentry user ID derived from HEVY_API_KEY, so the raw key is never sent to Sentry

โš ๏ธ Migration Note (v1.18.0)

As of v1.18.0, hevy-mcp removed both HTTP/SSE transport and Docker support.

The supported path is stdio via npx hevy-mcp.


๐Ÿ› ๏ธ Available MCP Tools

CategoryTools
Workoutsget-workouts, get-workout, create-workout, update-workout, get-workout-count, get-workout-events
Routinesget-routines, get-routine, create-routine, update-routine
Templatesget-exercise-templates, get-exercise-template, search-exercise-templates, create-exercise-template, get-exercise-history
Foldersget-routine-folders, get-routine-folder, create-routine-folder
Body Measurementsget-body-measurements, get-body-measurement, create-body-measurement, update-body-measurement
Userget-user-info

Delete operations are currently unsupported: The upstream Hevy OpenAPI spec does not expose DELETE endpoints for workouts, routines, routine folders, exercise templates, or body measurements, so hevy-mcp does not provide delete tools for these resources.


๐Ÿ‘จโ€๐Ÿ’ป Development & Contributing

Quick Commands

  • Build: npm run build
  • Lint/Format: npm run check (uses oxlint/oxfmt)
  • Type Check: npm run check:types
  • Unit Tests: npx vitest run --exclude tests/integration/**
  • Full Test Suite: npm test (requires HEVY_API_KEY)
  • Changeset Check: npm run check:changeset

For a detailed senior engineer guide, please refer to AGENTS.md.

Pull Request Checks

  • Conventional Commits: CI lints commit messages on pull requests, so use prefixes such as feat:, fix:, docs:, ci:, chore:, refactor:, test:, or style:.
  • Type Checking: CI runs npm run check:types on pull requests and pushes to main; run this locally before opening a PR.
  • Changesets: Contributor pull requests targeting main must include a changeset. Dependabot PRs and automated changeset-release/main release PRs are handled by automation and skip this check.

API Client Generation

The API client is automatically generated from the OpenAPI spec using Kubb:

npm run build:client

Versioning & Releases

This project uses Changesets to manage versioning, changelogs, releases, and pull request validation.

  1. Routine Release Cadence: Merge the automated changeset-release/main ("Version Packages") Pull Request on a regular cadence (weekly is a good default) instead of ad-hoc frequent merges.
  2. Urgent Release Exception: Security fixes and high-impact, user-facing bug fixes can be released immediately outside the routine cadence.
  3. Use Bump Changesets Only for User-Facing Runtime Changes: If your change is user-facing/runtime-visible, run:
    npx changeset
    
    Follow the prompts to choose patch, minor, or major, then write a short summary. This creates a markdown file under .changeset/.
  4. Use Empty Changesets for Internal-Only Work: Docs, CI, test-only, refactor, and chore changes should use an empty changeset:
    npx changeset --empty
    
  5. Validate Before Opening a PR: Contributor pull requests targeting main are checked for a changeset in CI. Dependabot PRs and automated changeset-release/main release PRs are handled separately. You can run the same validation locally with:
    npm run check:changeset
    
  6. Automated Releases:
    • Pushing changesets to main triggers a GitHub Action that automatically creates or updates a "Version Packages" Pull Request.
    • When this Pull Request is merged, the package is automatically built, published to npm (via OIDC Trusted Publishing), and a GitHub Release is created.

๐Ÿ“„ License & Acknowledgements


Contributions are welcome! Please open an issue or PR for any major changes.