Skip to main content

Overview

Hevy HTTP MCP uses bearer token authentication to protect the MCP endpoint from unauthorized access. Every request to /mcp must include your MCP_API_KEY in the Authorization header.

How Authentication Works

The server implements a custom authentication handler that:
  1. Checks for the Authorization header in incoming requests
  2. Extracts the token (supports both Bearer <token> format and raw token)
  3. Validates the token against the configured MCP_API_KEY
  4. Returns appropriate error responses for missing or invalid tokens

Authentication Flow

Here’s the authentication implementation from the server:
authentication: async (ctx) => {
  const authHeader =
    ctx.request.headers.get("Authorization") ??
    ctx.request.headers.get("authorization");

  if (!authHeader) {
    return {
      response: new Response(
        JSON.stringify({ error: "Missing Authorization header" }),
        { status: 401, headers: { "Content-Type": "application/json" } },
      ),
    };
  }

  // Accept "Bearer <key>" or just the raw key
  const token = authHeader.startsWith("Bearer ")
    ? authHeader.slice(7)
    : authHeader;

  if (token !== config.mcpApiKey) {
    return {
      response: new Response(
        JSON.stringify({ error: "Invalid API key" }),
        { status: 403, headers: { "Content-Type": "application/json" } },
      ),
    };
  }

  return {
    authInfo: {
      token,
      clientId: "mcp-client",
      scopes: ["hevy:read", "hevy:write"],
    },
  };
}

Authorization Header Formats

The server accepts two formats for the Authorization header:

Response Codes

401 Unauthorized
error
Returned when the Authorization header is missing from the request.
{ "error": "Missing Authorization header" }
403 Forbidden
error
Returned when the provided API key doesn’t match the configured MCP_API_KEY.
{ "error": "Invalid API key" }
200 OK
success
Authentication successful. The request proceeds to the MCP tool handler.

Testing Authentication

You can test authentication using curl:

Valid Request

curl -X POST http://localhost:3000/mcp \
  -H "Authorization: Bearer your_mcp_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"method": "tools/list"}'

Missing Header

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{"method": "tools/list"}'

# Response: {"error": "Missing Authorization header"}

Invalid Key

curl -X POST http://localhost:3000/mcp \
  -H "Authorization: Bearer wrong_key" \
  -H "Content-Type: application/json" \
  -d '{"method": "tools/list"}'

# Response: {"error": "Invalid API key"}

Security Considerations

Your MCP_API_KEY provides full access to all Hevy MCP tools. Protect it like a password.

Key Management

  • Generate strong keys: Use at least 32 characters of random data
    openssl rand -hex 32
    
  • Never commit keys: The .env file is gitignored by default. Keep it that way.
  • Rotate regularly: Change your MCP_API_KEY periodically or if compromised
  • Use environment variables: Never hardcode keys in client configurations that might be shared

Network Security

This server uses HTTP, not HTTPS. For production deployments, place it behind a reverse proxy (nginx, Caddy) with TLS enabled.
  • Local development: Binding to 127.0.0.1 (default) only accepts connections from your machine
  • Remote access: If using HOST=0.0.0.0, ensure you’re behind a firewall or VPN
  • Production: Always use HTTPS in production environments to encrypt the Authorization header in transit

Access Scopes

When authentication succeeds, the server assigns these scopes to the authenticated client:
scopes: ["hevy:read", "hevy:write"]
This indicates the client has both read and write access to all Hevy tools. Currently, there’s no granular scope restriction—a valid MCP_API_KEY grants full access.

Hevy API Key Security

Your HEVY_API_KEY is never exposed to MCP clients. It’s only used server-side when making requests to api.hevyapp.com.
The authentication system creates a security boundary:
  1. Client → MCP Server: Authenticated with MCP_API_KEY
  2. MCP Server → Hevy API: Authenticated with HEVY_API_KEY
This two-tier authentication ensures:
  • Clients never see your Hevy API credentials
  • You can revoke MCP client access without changing your Hevy API key
  • Multiple clients can share one MCP server with a single MCP_API_KEY

Build docs developers (and LLMs) love