Skip to main content
Glama

balanceit-mcp

A stdio MCP server that drives your own balance.it account through its recipe autobalancer.

Balance IT formulates home-prepared canine and feline diets. This server acts as your signed-in account. It exposes the calorie calculator, the food catalogue, and the recipe builder as MCP tools.

Use your own account credentials. Read and respect the Balance IT terms of service before you automate anything against the site. This project has no affiliation with Balance IT.

What it does

The server exposes six tools over the Model Context Protocol.

Tool

Kind

Latency

Purpose

calculate_calories

HTTP

under 500 ms

Return the daily maintenance calories for a pet.

search_foods

HTTP

under 500 ms

Search the curated m* and USDA n* food entries.

list_catalogue

Browser

5 to 8 s, then cached 7 days

Return the full ingredient catalogue for one species and life stage.

generate_recipe

Browser

45 to 90 s

Fill the pet profile, choose ingredients, and wait for the built options.

get_recipe

Browser

5 to 10 s

Read the macros and the gram weights for one recipe option.

session_status

Local

instant

Report whether a usable session is on disk.

Every tool returns structured JSON. Two of the tools call the site JSON endpoints directly. The other three drive a Chrome browser through Playwright. The /recipes page and the build flow render only inside a logged-in browser session.

A dead session produces a distinct session_expired error with a remedy hint. The site answers an unauthenticated request with HTTP 200 and an empty array. A caller cannot otherwise tell a dead session from an empty result.

Related MCP server: cookwith-mcp

Requirements

  • Node.js 20 or later.

  • Google Chrome. Playwright launches it through channel: 'chrome'.

  • A Balance IT account of your own.

  • A logged-in balance.it browser session, exported as a Playwright storageState file.

Install

npm install
npm run build

Configuration

Session state

The server reads its session from ~/.config/balanceit/state.json. It creates that file with mode 0600, inside a directory with mode 0700.

Export a session yourself. Sign in to balance.it in a Playwright Chromium context. Then write context.storageState({ path }) to the configuration path above. The export must hold the _balance_session and aws-waf-token cookies on the balance.it domain.

Set BALANCEIT_STATE_SEED to seed the session from an export that sits elsewhere. On first run the server copies that file to the configuration path, and it applies mode 0600. The server ignores the variable once the configuration file exists.

Re-export the session when a tool returns session_expired. The session cookies expire after a few days.

Environment variables

Variable

Purpose

BALANCEIT_EMAIL

Your balance.it account email.

BALANCEIT_PASSWORD

Your balance.it account password.

BALANCEIT_STATE_SEED

Path to a storageState export used to seed the session.

The server reads the credentials from the environment only. It never writes them to disk. It never logs them. It never puts them in an error message.

The credentials are documented for a future automatic sign-in. The current code does not use them, because it authenticates from the exported session.

MCP client

Add the server to your MCP client configuration. Replace /path/to/balanceit-mcp with the path to your own clone.

{
  "mcpServers": {
    "balanceit": {
      "command": "node",
      "args": ["/path/to/balanceit-mcp/dist/index.js"]
    }
  }
}

Usage

Run the browser tools from a foreground shell. Playwright with channel: 'chrome' does not launch Chrome from a backgrounded shell on macOS. The Node process then stays alive, logs nothing, and looks like a hang.

generate_recipe

generate_recipe takes a pet profile and a list of food_id values. It returns one option list, plus three fields for verification.

  • submitted_food_ids lists the identifiers read from the hidden form inputs at submit time. This is what balance.it received.

  • typeahead_added lists the subset that the typeahead added rather than a chip click.

  • missing_from_first_option lists each requested ingredient that the first built option does not appear to contain. An empty list is the normal case. A non-empty list means that the site optimizer substituted or skipped the ingredient on that option. Call get_recipe on each option when you need per-option certainty.

The tool rejects a bad food_id before it opens a browser. A malformed identifier fails immediately. A well-formed identifier that search_foods does not return fails after the resolve pass.

Contract notes

These details describe how the site behaves. Keep them so that later maintenance does not have to rediscover them.

  • The /recipes page returns an empty body to a plain fetch. Use the browser tools for any DOM content.

  • The two JSON endpoints are /r/api/v1/pets/vet_approvals/auto_calculate_calories and /r/api/v1/foods/search/<QUERY>. Both work with a plain fetch, the persisted cookie header, a normal desktop user agent, and X-Requested-With: XMLHttpRequest.

  • foods/search takes the query as a path segment. The ?q= form returns 404.

  • On tab 2 of /recipes, the ingredient chips sit inside seven collapsed accordions. Each chip is present in the DOM but not visible. Playwright times out on a click against a hidden chip. Click the accordion header (.ingredients-box > a) first.

  • The one-pot toggle #one_pot_cooking is hidden by CSS. Toggle the visible label[for=one_pot_cooking] instead.

  • A food that has no chip is added through the tab-2 typeahead (input.food-typeahead.tt-input). This is the common case when one_pot_cooking is true.

  • Each typeahead suggestion carries a class of the form li-<category>-<food_id>, such as li-protein-n13326. Match that class to find the exact suggestion, then click it with the mouse.

  • A .tt-suggestion click reports success without registering the food when it targets the wrong suggestion. Do not click "the first suggestion". Match the li-<category>-<food_id> class.

  • Every registered selection appears as a hidden <input name="<category>_foods[]" value="<food_id>">. The pre-submit invariant is that every requested identifier is present as such an input.

  • Typing a saved pet name by hand reads as an edit to that pet record. The site then raises an update gate. Select the pet from the #pet_name typeahead instead, which sets the hidden pet_id and raises no gate.

  • A recipe build is asynchronous. After the submit navigation lands on /recipes/<recipe_id>, poll until the option cards render or the "N of N complete" status reaches parity.

Repository layout

src/
  index.ts    MCP server entry and tool registration
  session.ts  storageState persistence and Cookie header derivation
  http.ts     the two pure-fetch tools, SessionError, and UpstreamError
  browser.ts  Playwright flows for catalogue, generate, and detail scrape
scripts/
  smoke.ts    live check against the site

Tests

This repository has no offline test suite. scripts/smoke.ts runs against the live site, and it needs a valid session.

npm run smoke

The smoke run calls calculate_calories for a spayed female and an intact female. It asserts that each result falls inside the reported calorie bracket. It checks that search_foods('chicken') returns m4. It then builds a recipe. It repeats the build for the same pet name, which exercises the saved-pet gate. It reads the first option back. It asserts that a malformed food_id is rejected.

The reference profile for the run is an adult dog of 22 kg.

Set SMOKE_SKIP_RECIPE=1 to skip the slow browser leg.

SMOKE_SKIP_RECIPE=1 npm run smoke

Development

npm run dev     # run the server from source through tsx
npm run build   # compile TypeScript into dist/
npm start       # run the compiled server

Licence

Licensed under the PolyForm Noncommercial License 1.0.0. Copyright 2026 Seraphine Renard.

Install Server
F
license - not found
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    An MCP server for the Open Food Facts API that allows users to search, read, and contribute to a global food database. It enables looking up nutrition data by barcode or name and managing product information through natural language.
    Last updated
    10
    50
    3
    MIT
  • A
    license
    -
    quality
    D
    maintenance
    MCP server for meal planning and grocery list generation, enabling recipe storage, meal plan creation, and automated grocery lists with ignored ingredients.
    Last updated
    2
    MIT

View all related MCP servers

Related MCP Connectors

  • A MCP server built for developers enabling Git based project management with project and personal…

  • MCP server for generating rough-draft project plans from natural-language prompts.

  • An MCP server that integrates with Discord to provide AI-powered features.

View all MCP Connectors

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/seraphinerenard/balanceit-mcp'

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