Content
# Intervals.icu MCP
Minimal local stdio MCP server for [Intervals.icu](https://intervals.icu), generated from the official OpenAPI spec. Exposes every API operation as an MCP tool. Works with Claude Desktop, mcphost (Ollama / OpenRouter), Cline, and any other MCP client that speaks stdio; this repo is fully self-contained.
## Files
```bash
|____spec/intervals-openapi-spec.json # the Intervals.ICU API spec
|____README.md # that's me!
|____config.js.example # example config.js file
|____package.json # npm package dependency file
|____mcp-stdio.mjs # the MCP server
```
## Requirements
- Node.js ≥ 18
- An Intervals.icu API key — get it from <https://intervals.icu/settings> (bottom of the page, "Developer settings")
## Install
Clone the repo and store it anywhere on your machine. Copy `config.js.example` to `config.js` and set `INTERVALS_TOKEN` to your Intervals.icu API key.
```bash
cp config.js.example config.js
npm install
```
## Test it
```bash
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node mcp-stdio.mjs | python3 -mjson.tool | grep "name\"" | head
```
You should see on stderr:
```bash
[intervals-mcp] ready · 147 tools loaded
"name": "updateLastSeenMessageId",
"name": "updateMessage",
"name": "deleteMessage",
"name": "showWorkout",
"name": "updateWorkout",
"name": "deleteWorkout",
"name": "getRecord",
"name": "updateWellness",
"name": "updateWellnessBulk",
"name": "uploadWellness",
```
Press Ctrl-C to exit. The server is now ready to be driven by an MCP client.
## Shrinking the tool surface (for small/local models)
The full spec generates 147 tools. Smaller models (`qwen2.5:7b`, `llama3.1:8b`, ...) struggle to pick the right one out of so many. Edit `config.js` to filter:
```js
export const METHODS = ["GET"]; // read-only server
export const TAGS = ["Activity", "Wellness"]; // only these OpenAPI tags
export const INCLUDE = ["getActivities", "getWellness"]; // exact allow-list
export const EXCLUDE = ["someNoisyTool"];
export const DESCRIPTION_STYLE = "short"; // terse one-liners (vs "full")
```
Filters apply in order: `METHODS` → `TAGS` → `INCLUDE` → `EXCLUDE`. Restart the server after editing. Claude can handle all 147 tools comfortably; for Ollama/mcphost/Tome with small models, keep it under ~20 tools.
## Claude Desktop
Edit Claude Desktop config file (create it if missing):
- MacOS - `~/Library/Application Support/Claude/claude_desktop_config.json`
- Linux - `~/.config/Claude/claude_desktop_config.json`
- Windows - `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"intervals-icu": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/local/mcp-stdio.mjs"],
"env": { "INTERVALS_TOKEN": "your_api_key_here" }
}
}
}
```
The `env` block is optional if you already set `INTERVALS_TOKEN` in `config.js`. Restart Claude Desktop. The Intervals.icu tools are now available.
## Ollama / OpenRouter (via mcphost)
[mcphost](https://github.com/mark3labs/mcphost) is a small CLI that bridges any MCP server to Ollama or OpenRouter models.
> Model suggestion for Ollama:
- qwen3 or qwen2.5-coder:32b (if your machine can run it)
- llama3.1:8b — surprisingly solid at tool calls
- mistral-small3.1 / mistral-nemo — trained for function calling
> Model suggestion for OpenRouter:
- anthropic/claude-3.5-sonnet, openai/gpt-4o-mini, google/gemini-2.0-flash
```bash
# install
go install github.com/mark3labs/mcphost@latest
# config: ~/.config/mcphost.intervals.json
{
"mcpServers": {
"intervals-icu": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/local/mcp-stdio.mjs"],
"env": { "INTERVALS_TOKEN": "your_api_key_here" }
}
}
}
# run with Ollama
mcphost -m ollama:qwen2.5 --config ~/.config/mcphost.intervals.json
# or OpenRouter
mcphost -m openrouter:anthropic/claude-3.5-sonnet
```
> If you'd rather a Desktop app instead of CLI, you can use [Tome](https://github.com/runebookai/tome), which offers pretty straightforward configuration for adding MCP servers.
## Authentication
Intervals.icu uses HTTP Basic auth. The server sends:
```
Authorization: Basic base64("API_KEY:${INTERVALS_TOKEN}")
```
This matches the official `curl -u "API_KEY:TOKEN"` style. If your token already contains a colon (e.g. `myuser:mytoken`), it is used verbatim.
## Troubleshooting
- **`INTERVALS_TOKEN is not set`** — set it in `config.js` or export it as an environment variable.
- **`HTTP 401`** — token is wrong or expired. Regenerate at <https://intervals.icu/settings>.
- **Tool not found in Claude** — restart Claude Desktop fully after editing the config file.