Skip to main content
Glama
Bazni
by Bazni
README.md
# exercise-mcp

MCP server over [hasaneyldrm/exercises-dataset](https://github.com/hasaneyldrm/exercises-dataset)
— 1,324 exercises, 10 languages, animation GIFs.

Tools: `list_facets`, `search_exercises`, `get_exercise`, `build_workout`.

```
lib/server.js     data loading + tool definitions (shared)
server.js         stdio (default) / --http express entrypoint
api/mcp.js        Vercel serverless entrypoint
scripts/trim-data.js  drop unused languages: 17 MB -> 1.7 MB
```

## Setup

```bash
npm install
npm run build            # downloads + trims the dataset into data/

node server.js            # stdio; prints "exercise-mcp ready (1324 exercises)"
```

Point `EXERCISES_JSON=data/exercises.min.json` at the trimmed file for any
deployed environment.

## Local (Claude Desktop / Claude Code)

```bash
claude mcp add exercise-db -- node /absolute/path/to/exercise-mcp/server.js
```

Desktop — `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{ "mcpServers": { "exercise-db": { "command": "node", "args": ["/abs/path/server.js"] } } }
```

Local servers do **not** reach claude.ai or the mobile apps.

## Railway (recommended)

Commit `data/exercises.min.json`, push, then `railway up`. `railway.json` sets
the start command and `/health` check; the server binds `0.0.0.0:$PORT`.

Set `MCP_TOKEN` in the Railway variables to require
`Authorization: Bearer <token>` on `/mcp`.

Connector URL: `https://<project>.up.railway.app/mcp`

## Vercel

Works, with caveats — see `vercel.json`. Deploy the repo as-is; the function
lives at `/api/mcp` and `includeFiles` ships the trimmed dataset into the bundle.

- The dataset parses on cold start (~1.5 s for the full file, ~80 ms trimmed),
  then stays in module scope while the instance is warm. Trim before deploying.
- Stateless only: `GET`/`DELETE` return 405, which is correct for the stateless
  Streamable HTTP profile the SDK serves with `sessionIdGenerator: undefined`.
- Do not put the endpoint behind Vercel's edge cache; MCP responses are per-request.

Connector URL: `https://<project>.vercel.app/api/mcp`

## Adding it to Claude

Settings → Connectors → **Add custom connector** → paste the URL. Claude reaches
your server from Anthropic's cloud, so it must be publicly resolvable — localhost
and private networks won't work.

## Notes

- Search returns 5-field rows and `get_exercise` returns one language, because raw
  records are ~13 KB each and would flood the model's context.
- `image` / `gif_url` are repo-relative; the server rewrites them to absolute
  `raw.githubusercontent.com` URLs. Override with `MEDIA_BASE` if self-hosting media.
- Licence: metadata and instruction text MIT; GIFs and thumbnails are
  © [Gym visual](https://gymvisual.com/), redistributed with permission. Keep the
  attribution, and get your own media licence before shipping a product.