Skip to main content
Glama
README.md
# cronometer-mcp

<!-- mcp-name: io.github.cphoskins/cronometer -->

An [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that provides access to your [Cronometer](https://cronometer.com/) nutrition data. Pull detailed food logs, daily macro/micro summaries, manage diary entries, fasting, biometrics, and recurring foods — all from Claude, Cursor, or any MCP-compatible client.

**Requires a Cronometer Gold account** (or any paid tier that supports web login).

## Features

- **Food log** — individual food entries with full macro and micronutrient breakdown
- **Daily nutrition** — daily calorie, protein, carb, fat, and fiber totals
- **Micronutrients** — detailed vitamin/mineral breakdown with period averages
- **Diary management** — add/remove food entries, copy entire days, mark days complete
- **Recurring foods** — create, list, and delete repeat items that auto-log on selected days
- **Macro targets** — read/write daily targets, create templates, set weekly schedules
- **Fasting** — view history and stats, cancel or delete fasts
- **Biometrics** — log and remove weight, blood glucose, heart rate, body fat
- **Raw CSV export** — servings, daily summary, exercises, biometrics, or notes
- **Sync to disk** — download JSON exports and generate a markdown food log

## Quick Start

### 1. Install

```bash
pip install cronometer-mcp
```

Or install from source:

```bash
git clone https://github.com/cphoskins/cronometer-mcp.git
cd cronometer-mcp
pip install -e .
```

### 2. Set credentials

```bash
export CRONOMETER_USERNAME="your@email.com"
export CRONOMETER_PASSWORD="your-password"
```

Or add them to a `.env` file in your project root (if your MCP client supports it).

### 3. Configure your MCP client

#### Claude Code (`.mcp.json`)

```json
{
  "mcpServers": {
    "cronometer": {
      "command": "cronometer-mcp",
      "env": {
        "CRONOMETER_USERNAME": "your@email.com",
        "CRONOMETER_PASSWORD": "your-password"
      }
    }
  }
}
```

#### Claude Desktop (`claude_desktop_config.json`)

```json
{
  "mcpServers": {
    "cronometer": {
      "command": "cronometer-mcp",
      "env": {
        "CRONOMETER_USERNAME": "your@email.com",
        "CRONOMETER_PASSWORD": "your-password"
      }
    }
  }
}
```

If you installed from source with `pip install -e .`, you can also use the full Python path:

```json
{
  "command": "/path/to/venv/bin/python",
  "args": ["-m", "cronometer_mcp.server"]
}
```

## Available Tools

### Food Log & Nutrition

| Tool | Description |
|------|-------------|
| `get_food_log` | Individual food entries with macros + micros for a date range |
| `get_daily_nutrition` | Daily macro totals (calories, protein, carbs, fat, fiber) |
| `get_micronutrients` | Detailed vitamin/mineral breakdown with period averages |
| `export_raw_csv` | Raw CSV export for any data type (servings, exercises, biometrics, etc.) |

### Food Search & Diary Management

| Tool | Description |
|------|-------------|
| `search_foods` | Search the Cronometer food database |
| `list_diary_groups` | List this account's diary groups and the values `diary_group` accepts |
| `get_food_details` | Get full nutrition info and serving measure IDs for a food |
| `add_food_entry` | Add a food entry to the diary |
| `remove_food_entry` | Remove a food entry from the diary |
| `copy_day` | Copy all diary entries from one date to another |
| `set_day_complete` | Mark a diary day as complete or incomplete |

### Recurring Foods (Repeat Items)

| Tool | Description |
|------|-------------|
| `get_repeated_items` | List all recurring food entries |
| `add_repeat_item` | Add a recurring food entry that auto-logs on selected days |
| `delete_repeat_item` | Delete a recurring food entry |

### Macro Targets & Templates

| Tool | Description |
|------|-------------|
| `get_macro_targets` | Get daily macro targets (or full weekly schedule with `target_date="all"`) |
| `set_macro_targets` | Update daily macro targets (partial updates supported) |
| `list_macro_templates` | List all saved macro target templates |
| `create_macro_template` | Create a new saved macro target template |
| `set_weekly_macro_schedule` | Assign a template to days of the week as the recurring default |

### Fasting

| Tool | Description |
|------|-------------|
| `get_fasting_history` | View all fasts or fasts within a date range |
| `get_fasting_stats` | Aggregate fasting statistics (total hours, longest, averages) |
| `cancel_active_fast` | Cancel an in-progress fast while preserving the recurring schedule |
| `delete_fast` | Delete a fast entry |

### Biometrics

| Tool | Description |
|------|-------------|
| `get_recent_biometrics` | Get recently logged biometric entries |
| `add_biometric` | Log weight (lbs), blood glucose (mg/dL), heart rate (bpm), or body fat (%) |
| `remove_biometric` | Remove a biometric entry |

### Sync

| Tool | Description |
|------|-------------|
| `sync_cronometer` | Download JSON exports + generate food-log.md to disk |

### Tool Parameters

All date parameters use `YYYY-MM-DD` format. Most tools default to today or the last 7 days when dates are omitted.

Key parameter patterns:
- `diary_group` — a diary group **name** (case-insensitive) or a **0-based index**.
  Cronometer Gold gives every account 8 diary group slots and lets you rename and
  enable them freely, so the names are account-specific and are *not* always
  Breakfast/Lunch/Dinner/Snacks. Call `list_diary_groups` to see yours. On an
  untouched account the four standard meals are indices `1`–`4` (index `0` is a
  slot that ships disabled). Unknown names, disabled groups, and out-of-range
  indices are rejected rather than silently defaulting — Cronometer itself
  accepts a bad index without complaint and the entry becomes unreachable.
- `days_of_week` — `"all"`, `"weekdays"`, `"weekends"`, or comma-separated day numbers (`0`=Sun through `6`=Sat)
- `measure_id` — pass `0` to use the universal gram-based measure (works for all food sources)
- `target_date` — pass `"all"` on `get_macro_targets` to get the full weekly schedule

### Sync Output

The `sync_cronometer` tool saves files to `~/.local/share/cronometer-mcp/` by default. Override with the `CRONOMETER_DATA_DIR` environment variable:

```bash
export CRONOMETER_DATA_DIR="/path/to/your/project/data/cronometer"
```

Output files:
- `exports/servings_{start}_{end}.json`
- `exports/daily_summary_{start}_{end}.json`
- `exports/servings_latest.json`
- `exports/daily_summary_latest.json`
- `food-log.md`

## How It Works

Cronometer does not have a public API for individual users. This server uses the same GWT-RPC (Google Web Toolkit Remote Procedure Call) protocol that the Cronometer web app uses internally:

1. Fetches the login page to get an anti-CSRF token
2. POSTs credentials to authenticate
3. Calls GWT-RPC `authenticate` to get a user ID
4. Calls GWT-RPC `generateAuthorizationToken` for short-lived export tokens
5. Downloads CSV exports using the token
6. Calls GWT-RPC methods directly for diary edits, fasting, biometrics, macro targets, and repeat items

Session cookies are persisted to `~/.local/share/cronometer-mcp/.session_cookies` so that subsequent invocations reuse the session without re-authenticating (Cronometer has aggressive login rate limiting).

### GWT Magic Values

The GWT protocol uses a permutation hash and header value that are baked into each Cronometer web deploy. These values are hardcoded in the client and **may break when Cronometer pushes a new build**.

Current values (as of February 2026):
- Permutation: `7B121DC5483BF272B1BC1916DA9FA963`
- Header: `2D6A926E3729946302DC68073CB0D550`

If authentication starts failing with GWT errors, these values likely need updating. You can find the current values by:

1. Opening Cronometer in your browser
2. Going to Developer Tools → Network tab
3. Looking for requests to `cronometer.com/cronometer/app`
4. Checking the `x-gwt-permutation` header and the payload structure

You can override them via the `CronometerClient` constructor:

```python
from cronometer_mcp import CronometerClient

client = CronometerClient(
    gwt_permutation="NEW_PERMUTATION_HASH",
    gwt_header="NEW_HEADER_VALUE",
)
```

## Python API

You can also use the client directly in Python:

```python
from datetime import date, timedelta
from cronometer_mcp import CronometerClient

client = CronometerClient()  # reads from env vars

# Get today's food log
foods = client.get_food_log()

# Get last 7 days of daily summaries
start = date.today() - timedelta(days=7)
summaries = client.get_daily_summary(start)

# Raw CSV export
csv_text = client.export_raw("exercises", start, date.today())

# Copy a day's diary entries
client.copy_day(date(2026, 3, 1), date(2026, 3, 8))

# Add a recurring food entry (every weekday)
client.add_repeat_item(
    food_source_id=12345,
    measure_id=0,        # universal gram-based measure
    quantity=200,
    food_name="Oatmeal",
    diary_group=1,       # 0-based wire index; 1 == Breakfast on a default account
    days_of_week=[1, 2, 3, 4, 5],
)

# Diary groups are user-configured - check what this account actually has
for g in client.diary_groups:
    print(g["wire_index"], g["name"], g["enabled"])

# Log a biometric
client.add_biometric("weight", 218.5, date.today())
```

## License

MIT

TDQS

A3.6/5.0

Scored across 27 tools

Disambiguation4/5

The tools are largely organized into clear subdomains: food logging, nutrition summaries, macro targets, fasting, biometrics, repeated items, and diary management. A few boundaries could still trip up an agent, such as cancel_active_fast vs. delete_fast and creating vs. applying macro templates, but the descriptions and complementary parameters make most selections clear.

Naming Consistency4/5

Tool names consistently follow a verb_noun style with snake_case throughout, which makes the set predictable. The main inconsistency is vocabulary: get_ vs. list_, remove_ vs. delete_ vs. cancel_, and create_macro_template vs. add_food_entry, but these are minor style deviations rather than pattern-breaking names.

Tool Count2/5

27 top-level tools is above the 25+ threshold and will burden an agent during tool selection, even though most tools individually earn their place. The set covers many Cronometer subdomains, but it would be more usable split into smaller servers or with some related operations consolidated.

Completeness3/5

The server covers food logging, nutrition retrieval, macro targets, fasting stats, biometrics, repeated items, and diary operations with read/create/delete paths for most entities. However, there are notable lifecycle gaps: no start_fast operation, no update/edit path for food entries or repeated items, and no direct exercise or note logging outside raw CSV exports.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive