Skip to main content
Glama
AGENTS.md11.3 kB
# Agent Instructions for hevy-mcp **ALWAYS follow these instructions first and only fallback to search or additional context if the information here is incomplete or found to be in error.** ## Project Overview - **hevy-mcp** is a Model Context Protocol (MCP) server for the Hevy Fitness API, enabling AI agents to manage workouts, routines, exercise templates, and folders via the Hevy API. - The codebase is TypeScript (Node.js v20+), with a clear separation between tool implementations (`src/tools/`), generated API clients (`src/generated/`), and utility logic (`src/utils/`). - API client code is generated from the OpenAPI spec using [Kubb](https://kubb.dev/). **Do not manually edit generated files.** - **Type Safety:** The project uses Zod schema inference for type-safe tool parameters, eliminating manual type assertions and ensuring compile-time type safety. ## Working Effectively ### Bootstrap and Build Repository Run these commands in order to set up a working development environment (Corepack is bundled with Node.js v20+, so run `corepack use pnpm@10.22.0` once per machine if pnpm isn't available): 1. **Install dependencies:** ```bash pnpm install ``` - Takes approximately 30 seconds. NEVER CANCEL - set timeout to 60+ seconds. 2. **Build the project:** ```bash pnpm run build ``` - Takes approximately 3-5 seconds. TypeScript compilation via tsup. - Always build before running the server or testing changes. 3. **Run linting/formatting:** ```bash pnpm run check ``` - Takes less than 1 second. - **EXPECTED WARNING:** Biome schema version mismatch warning is normal and can be ignored. ### Testing Commands 4. **Run unit tests only:** ```bash pnpm vitest run --exclude tests/integration/** ``` - Takes approximately 1-2 seconds. NEVER CANCEL. - This is the primary testing command for development. 5. **Run integration tests (requires API key):** ```bash pnpm vitest run tests/integration ``` - **WILL FAIL** without valid `HEVY_API_KEY` in `.env` file (by design). - Integration tests require real API access and cannot run in sandboxed environments. 6. **Run all tests:** ```bash pnpm test ``` - Takes approximately 1-2 seconds for unit tests only (without API key). - **WILL FAIL** if `HEVY_API_KEY` is missing due to integration test failure (by design). ### API Client Generation 7. **Regenerate API client from OpenAPI spec:** ```bash pnpm run build:client ``` - Takes approximately 4-5 seconds. NEVER CANCEL. - **EXPECTED WARNINGS:** OpenAPI validation warnings about missing schemas are normal. - Always run this after updating `openapi-spec.json`. ### Server Operations 8. **Development server (with hot reload):** ```bash pnpm run dev ``` - **REQUIRES:** Valid `HEVY_API_KEY` in `.env` file or will exit immediately. - Server runs indefinitely until stopped. 9. **Production server:** ```bash pnpm start ``` - **REQUIRES:** Valid `HEVY_API_KEY` in `.env` file or will exit immediately. - Must run `pnpm run build` first. ## Commands That Do Not Work ### Known Failing Commands - **`pnpm run export-specs`**: Fails with network error (`ENOTFOUND api.hevyapp.com`) in sandboxed environments. - **`pnpm run check:types`**: May report TypeScript errors in source code due to strict type checking. The project builds successfully via `pnpm run build` (using tsup) despite these errors. Generated code in `src/generated/` is excluded from type checking. - **`pnpm run inspect`**: MCP inspector tool - may timeout in environments without proper MCP client setup. ## Environment Setup ### Required Environment Variables Create a `.env` file in the project root with: ```env HEVY_API_KEY=your_hevy_api_key_here ``` **CRITICAL:** Without this API key: - Servers will not start - Integration tests will fail (by design) - API client functionality cannot be tested ### Node.js Version - **Required:** Node.js v20+ (specified in `.nvmrc` as v22.14.0) - Use `node --version` to verify current version ## Validation After Changes ### Manual Testing Scenarios Always perform these validation steps after making changes: 1. **Build validation:** ```bash pnpm run build ``` - Must complete successfully without errors. 2. **Unit test validation:** ```bash pnpm vitest run --exclude tests/integration/** ``` - All unit tests must pass. 3. **Code style validation:** ```bash pnpm run check ``` - Must complete without errors (warnings about Biome schema are acceptable). - **EXPECTED:** Warnings about `any` usage in `webhooks.ts` are acceptable (API methods not yet available). 4. **Type checking validation:** ```bash npx tsc --noEmit ``` - Must complete without errors. - Verifies all type inference is working correctly. 5. **MCP tool functionality validation (if API key available):** - Start development server: `pnpm run dev` - Test MCP tool endpoints with a client - Verify tool responses are correctly formatted ### Critical Validation Notes - **ALWAYS** run unit tests after any source code changes - **ALWAYS** run build validation before committing changes - **ALWAYS** use type inference (`InferToolParams`) instead of manual type assertions - **DO NOT** attempt to fix TypeScript errors in `src/generated/` - these are auto-generated files - **DO NOT** commit `.env` files containing real API keys - **DO NOT** use `as any` or `as unknown` type assertions in tool handlers ## Project Structure and Key Files ### Source Code Organization ``` src/ ├── index.ts # Main entry point - register tools here ├── tools/ # MCP tool implementations │ ├── workouts.ts # Workout management tools │ ├── routines.ts # Routine management tools │ ├── templates.ts # Exercise template tools │ ├── folders.ts # Routine folder tools │ └── webhooks.ts # Webhook subscription tools ├── generated/ # Auto-generated API client (DO NOT EDIT) │ ├── client/ # Kubb-generated client code │ └── schemas/ # Zod validation schemas └── utils/ # Shared helper functions ├── tool-helpers.ts # Type inference utilities (InferToolParams) ├── error-handler.ts # Centralized error handling (withErrorHandling) ├── response-formatter.ts # MCP response utilities ├── formatters.ts # Data formatting helpers ├── hevyClient.ts # API client factory ├── hevyClientKubb.ts # Kubb client wrapper ├── config.ts # Configuration parsing └── httpServer.ts # HTTP server utilities (deprecated) ``` ### Testing Structure ``` tests/ ├── integration/ # Integration tests (require API key) └── unit tests are co-located with source files (*.test.ts) ``` ## Development Patterns ### Type-Safe Tool Implementation The project uses **Zod schema inference** for type-safe tool parameters. This eliminates manual type assertions and ensures types match schemas automatically. #### Pattern: Using Type Inference **Always** extract Zod schemas and use `InferToolParams` for type safety: ```typescript import type { InferToolParams } from "../utils/tool-helpers.js"; import { withErrorHandling } from "../utils/error-handler.js"; // 1. Define schema as const const getRoutinesSchema = { page: z.coerce.number().int().gte(1).default(1), pageSize: z.coerce.number().int().gte(1).lte(10).default(5), } as const; // 2. Infer types from schema type GetRoutinesParams = InferToolParams<typeof getRoutinesSchema>; // 3. Use inferred type in handler server.tool( "get-routines", "Description...", getRoutinesSchema, // Use the schema constant withErrorHandling(async (args: GetRoutinesParams) => { // args is fully typed - no manual assertions needed! const { page, pageSize } = args; // ... }, "get-routines"), ); ``` **Key Benefits:** - ✅ Single source of truth (Zod schema defines both validation and types) - ✅ No manual type assertions (`args as {...}`) - ✅ Automatic type updates when schemas change - ✅ Full IDE autocomplete and type checking **DO NOT:** - ❌ Use `args as { ... }` type assertions - ❌ Define parameter types separately from Zod schemas - ❌ Use `Record<string, unknown>` in handler signatures (use inferred types) ### Adding New MCP Tools 1. **Create new tool file** in `src/tools/` 2. **Define Zod schema** with `as const` assertion 3. **Infer parameter types** using `InferToolParams<typeof schema>` 4. **Implement handler** with typed parameters (no manual assertions) 5. **Wrap with error handling** using `withErrorHandling` from `src/utils/error-handler.ts` 6. **Format outputs** using helpers in `src/utils/formatters.ts` 7. **Register tools** in `src/index.ts` 8. **Add unit tests** co-located with implementation ### Working with Generated Code - **NEVER** edit files in `src/generated/` directly - Regenerate API client: `pnpm run build:client` - If OpenAPI spec changes, update `openapi-spec.json` first - Generated types are available in `src/generated/client/types/index.ts` ### Error Handling - Use centralized error handling from `src/utils/error-handler.ts` - Wrap handlers with `withErrorHandling(fn, "context-name")` - Follow existing error response patterns in tool implementations - Error responses automatically include `isError: true` flag ## Troubleshooting ### Common Issues 1. **Server won't start:** Check for `HEVY_API_KEY` in `.env` file 2. **Integration tests failing:** Expected without valid API key 3. **TypeScript errors in generated code:** Expected - ignore these 4. **Build failures:** Run `pnpm run check` to identify formatting/linting issues 5. **Network errors in export-specs:** Expected in sandboxed environments 6. **Type errors in tool handlers:** Use `InferToolParams<typeof schema>` instead of manual type assertions 7. **Linter warnings about `any`:** Expected in `webhooks.ts` where API methods don't exist yet (see TODOs) ### Performance Expectations - **Build time:** 3-5 seconds - **Unit test time:** 1-2 seconds - **Dependency installation:** 30 seconds - **API client generation:** 4-5 seconds - **Type checking:** < 1 second ## Key Utilities Reference ### Type Inference (`src/utils/tool-helpers.ts`) - **`InferToolParams<T>`**: Infers TypeScript types from Zod schema objects - **`createTypedToolHandler`**: Optional wrapper for automatic validation (MCP SDK already validates) ### Error Handling (`src/utils/error-handler.ts`) - **`withErrorHandling<TParams>(fn, context)`**: Wraps handlers with error handling while preserving parameter types - **`createErrorResponse(error, context?)`**: Creates standardized error responses ### Response Formatting (`src/utils/response-formatter.ts`) - **`createJsonResponse(data, options?)`**: Creates JSON-formatted MCP responses - **`createTextResponse(text)`**: Creates text-formatted MCP responses - **`createEmptyResponse(message)`**: Creates empty responses with messages --- **Remember:** Always reference these instructions first before searching for additional information or running exploratory commands.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/chrisdoc/hevy-mcp'

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