Cronometer MCP server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| PORT | No | Login server port, 8432 by default | 8432 |
| ISSUER | No | The public address of the server | |
| MCP_PORT | No | MCP server port, 8430 by default | 8430 |
| UPSTREAM | No | Where the MCP server is, http://127.0.0.1:8430 by default | http://127.0.0.1:8430 |
| CONFIG_DIR | No | Where the password, token and database are kept | |
| MCP_PUBLIC_URL | No | Public address, used to advertise the icon to clients | |
| CALL_TIMEOUT_MS | No | How long a call may go quiet before it is cut off, 120000 by default | 120000 |
| CRONOMETER_PASSWORD | Yes | Your Cronometer password | |
| CRONOMETER_USERNAME | Yes | Your Cronometer email | |
| CRONOMETER_ACCOUNT_TZ | Yes | The time zone your diary days are counted in | |
| CRONOMETER_TOTP_SECRET | No | Your two-factor secret, only if you have two-factor on. Needs the totp extra |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_food_logA | Get all diary entries for a given date. Returns every food entry logged for the day. Each "Serving" entry is enriched (best-effort) with the food's name, source, the serving measure (unit name and grams per unit), the number of servings, and that food's own nutrient profile scaled to the amount eaten. Non-food entries (exercise, biometrics) carry their own name. Note: the per-entry "nutrients" are each food's individual contribution, which is distinct from the day-level nutrition_summary aggregate below. Also returns a top-level energy_summary field with pre-computed values most relevant to the user:
Also returns a nutrition_summary field with consumed totals for every nutrient eaten that day:
Args: date: Date as YYYY-MM-DD (defaults to today). include_untracked: Leave true for everything eaten. False restricts the summary to nutrients with targets, matching the app's own summary. |
| add_food_entryA | Add a food entry to the Cronometer diary. Use search_foods to find food_id and measure_id, then get_food_details to confirm serving sizes and gram weights. Args: food_id: Numeric food ID from search_foods results. measure_id: Measure/unit ID from get_food_details. grams: Weight of the serving in grams. Real grams for recipes too: the conversion to Cronometer's batch units happens here. date: Date to log as YYYY-MM-DD (defaults to today). translation_id: Translation ID from search results (usually 0). diary_group: Meal slot -- one of "auto", "breakfast", "lunch", "dinner", "snacks" (case-insensitive, default "auto"). time: Time of day as HH:MM or HH:MM:SS. Defaults to now. Pass the real eating time when logging after the fact; an "auto" diary_group then follows that hour instead of the current one. |
| remove_food_entryA | Remove one or more food entries from the Cronometer diary. Use get_food_log to find entry IDs. Args: entry_ids: List of serving/entry IDs to remove. date: Date the entries belong to as YYYY-MM-DD (defaults to today). |
| mark_day_completeA | Mark a diary day as complete or incomplete. Args: date: Date to mark as YYYY-MM-DD. complete: True to mark complete, False for incomplete. |
| copy_dayA | Copy all diary entries from the previous day to the given date. Additive -- does not remove existing entries on the destination date. Args: date: Destination date as YYYY-MM-DD (defaults to today). |
| get_daily_nutritionA | Get daily nutrition totals for every nutrient eaten that day. The response has:
Report an untracked amount as a plain figure. It has no target, so never describe it as over, under or on track, and offer set_nutrient_target if a target would be useful. Args: date: Date as YYYY-MM-DD (defaults to today). include_untracked: Leave true for everything eaten. False restricts the response to nutrients with targets, matching the app's own summary. |
| get_nutrition_scoresA | Get nutrition scores with per-nutrient consumed amounts and category grades. Returns category scores (All Targets, Vitamins, Minerals, Electrolytes, Antioxidants, Immune Support, Metabolism, Bone Health) with the actual consumed amount and confidence level for each nutrient. This is Cronometer's own scoring, so it covers only nutrients with a target; scoring one without a target would have nothing to score against. Use it to see how close each nutrient is to its target, and get_daily_nutrition when you need everything that was actually eaten. Args: date: Date as YYYY-MM-DD (defaults to today). |
| search_foodsA | Search Cronometer's food database by name. Returns matching foods with their IDs and source information. Use the food_id and measure_id from results with add_food_entry, or pass food_id to get_food_details for full nutrition info. Args: query: Food name or keyword (e.g. "eggs", "chicken breast"). |
| get_food_detailsA | Get detailed food information including nutrition and serving sizes. Use this after search_foods to get the full nutrient profile and available measure_ids needed for add_food_entry. Args: food_id: Food ID from search_foods results. |
| add_custom_foodA | Create a custom food with any nutrients you have, from 1 to all 94. Amounts are for one whole serving, each in that nutrient's own unit. Call list_nutrients for the accepted names and their units. Only pass the nutrients you actually know: a nutrient you leave out stays blank in Cronometer, while passing 0 states the food contains none of it, and the app treats those differently. An unrecognised name is an error, so nothing is silently dropped from a food that then looks complete. Two label conveniences: energy_kj is converted to calories, salt_g to sodium. Pass either one or its underlying nutrient, not both. After creation, use the returned food_id with add_food_entry to log it. Args: name: Food name. nutrients: Nutrient name to amount per serving, e.g. {"energy": 250, "protein": 12.5, "vitamin_c": 30, "b12_cobalamin": 1.2}. serving_name: Name for the serving size (default "1 serving"). serving_grams: Weight of one serving in grams (default 100). label_type: "AMERICAN_2016" or "EUROPEAN". notes: Free-text note stored on the food. |
| get_recent_foodsA | Recently logged foods with how often each was logged. The fastest route for "log my usual": find the food here, then add_food_entry. Recipes are flagged so a whole batch is not logged as one portion by mistake. |
| get_streakA | Diary logging streaks: current run of fully logged days, and the record. Args: date: Day to count back from as YYYY-MM-DD (defaults to today). |
| get_profileA | The account profile: birthdate, gender, timezone and language. |
| create_recipeA | Create a recipe from ingredients, or update one by passing recipe_id. Cronometer sums the nutrients from the ingredients itself, so unlike add_custom_food you give foods and amounts, not nutrient values. Use search_foods to find each ingredient's food_id and measure_id first. Cronometer locks a recipe's serving type when it is created and it cannot be changed afterwards, so choose deliberately:
cooked_grams is the weight of the finished dish. Give it whenever the food was baked or simmered: nutrients are stored per 100 g, and a dish that lost water is denser than its raw ingredients, so without it a portion weighed off the plate logs too little. Updating with recipe_id replaces the whole ingredient list, so pass every ingredient, not only new ones. Recipes are removed with retire_custom_food, the same as custom foods. Args: name: Recipe name. ingredients: List of {"food_id": int, "grams": float, "measure_id": int (optional)}. servings: How many portions the batch makes. notes: Free-text note stored on the recipe. recipe_id: Existing recipe to update in place. serving_type: "weight" or "servings". Cannot be changed later. cooked_grams: Weight of the finished dish, if it lost water in cooking. |
| list_custom_foodsA | Every custom food and recipe you own, with no database results mixed in. Leave query empty for the whole library. This is the way to audit it: to find, say, every food whose name lost its Finnish characters, list them all and read the names, then fix each with update_custom_food. Retired foods are hidden by Cronometer's own library listing, so include_retired cannot bring them back; it only affects rows already returned. Args: query: Narrow the list by name. Empty lists everything. include_retired: Keep retired foods in the result when they appear. |
| list_recipesA | Every recipe you own, with its serving type. serving_type says which kind each one is: "weight" logs in grams everywhere, "servings" keeps an editable ingredient list but shows a 1 g serving in the mobile app. It is fixed at creation and cannot be changed. Args: include_retired: Keep retired recipes in the result when they appear. |
| find_entries_by_foodA | Every diary entry that references a food, with dates and amounts. Use before replacing or retiring a food, so its entries can be moved rather than left pointing at something retired. Cronometer cannot search entries by food, so this reads the diary one day at a time and the range costs a request per day. It defaults to the last 30 days; widen it deliberately. Args: food_id: The food to look for. start_date: First day as YYYY-MM-DD (defaults to 30 days back). end_date: Last day as YYYY-MM-DD (defaults to today). |
| update_custom_foodA | Edit one of your custom foods in place, keeping its diary entries. Only what you pass changes. Entries already logged stay attached to this same food and their nutrition follows the edit, so a typo or a wrong nutrient can be fixed without re-logging anything. Nutrients are merged into the existing profile, so correcting one value leaves the rest alone. Call list_nutrients for the accepted names. Args: food_id: The custom food to edit. name: New name. notes: New note text. nutrients: Nutrient name to amount per serving, merged in. measures: [{"measure_id": int, "name": str, "grams": float}] to fix a wrongly weighted measure. name and grams are each optional. Leave measure_id out to ADD a serving size instead, giving name and grams: that is how a food gets a per-piece measure such as "1 karkki" or "1 viipale" alongside plain grams, so it can be logged by the count as well as by weight. |
| update_recipeA | Edit one of your recipes in place, keeping its diary entries. Only what you pass changes, and the serving type never does: Cronometer fixes it at creation. Passing ingredients replaces the whole list, so send every ingredient rather than only the new ones. Args: food_id: The recipe to edit. name: New name. notes: New note text. ingredients: Full replacement list of {"food_id": int, "grams": float, "measure_id": int (optional)}. cooked_grams: New finished weight. Weight-based recipes only, and it needs the ingredients too, since the nutrition is recomputed. |
| retire_custom_foodA | Retire a custom food so it stops being offered for new entries. This is how Cronometer removes a food; there is no delete. Diary entries that already use it keep working. Pass retired=False to bring it back. Args: food_id: The custom food's ID. retired: True to retire, False to restore. |
| list_nutrientsA | Every nutrient add_custom_food accepts, with its unit and category. Read from the account's own catalog, so it stays right as Cronometer adds nutrients. Use the returned keys for the add_custom_food nutrients dict. |
| get_macro_targetsA | Get current macro targets including weekly schedule and templates. Returns the weekly macro schedule (which template applies to each day) and all saved macro target templates with their values. |
| get_fasting_historyA | Get fasting history from Cronometer. Returns fasts within the date range including status, timestamps, and duration. Args: start_date: Start date as YYYY-MM-DD (defaults to 30 days ago). end_date: End date as YYYY-MM-DD (defaults to today). |
| get_fasting_statsA | Get aggregate fasting statistics. Returns total fasting hours, longest fast, average fast duration, and completed fast count. |
| list_biometricsA | List the biometric metrics tracked in Cronometer. Returns every metric type the account can record (Weight, Body Fat, Heart Rate, Blood Glucose, Waist Size, Sleep, blood panels, body measurements, etc.). Use the metric_id and a unit_id from the results with get_biometrics. |
| get_biometricsA | Get a biometric time series such as weight or body fat from Cronometer. Returns the recorded values over the date range as a list of {day, value} points. Use list_biometrics to find metric_id and unit_id (e.g. Weight is metric_id 1, with unit_id 1 for kg or 2 for lbs). Args: metric_id: Numeric metric ID from list_biometrics. unit_id: Numeric unit ID from the metric's units in list_biometrics. start_date: Start date as YYYY-MM-DD (defaults to 30 days ago). end_date: End date as YYYY-MM-DD (defaults to today). |
| edit_food_entryA | Change the amount or time of an already logged food entry. Use get_food_log to find entry IDs. Args: entry_id: The serving ID of the entry to change. grams: New amount in grams. time: New time as HH:MM or HH:MM:SS. date: Date the entry is on as YYYY-MM-DD (defaults to today). |
| add_noteA | Add a note to a day in the Cronometer diary. Cronometer cannot delete notes, only rewrite them, so a note added here can be changed but only removed in the Cronometer app. Args: text: The note text. date: Date as YYYY-MM-DD (defaults to today). |
| edit_noteA | Replace the text of an existing diary note. Args: note_id: The note ID, from get_food_log. text: The replacement text. date: Date the note is on as YYYY-MM-DD (defaults to today). |
| add_biometricA | Record a biometric measurement, such as weight or body fat. Use list_biometrics to find metric IDs and their valid unit IDs. Correct a wrong value with edit_biometric, or drop the reading entirely with remove_biometric when the measurement never happened. Args: metric_id: Metric to record, from list_biometrics. unit_id: Unit the amount is in, from that metric's units. amount: The measured value. date: Date as YYYY-MM-DD (defaults to today). |
| edit_biometricB | Change the value of a recorded biometric. Args: biometric_id: The biometric ID, from get_food_log. amount: The corrected value, in the unit the entry already uses. date: Date the entry is on as YYYY-MM-DD (defaults to today). |
| remove_biometricA | Delete recorded biometrics, such as a reading from a misbehaving scale. Deleting is right when the measurement never happened or is impossible; edit_biometric is for a value that is merely wrong, since editing keeps the day's entry and its history. Args: biometric_ids: List of biometric IDs to remove, from get_food_log. date: Date the entries belong to as YYYY-MM-DD (defaults to today). |
| add_exerciseA | Log an exercise entry. A wrong entry can be corrected with edit_exercise or deleted outright with remove_exercise. Args: name: What the exercise was called. minutes: Duration in minutes. calories_burned: Calories burned, as a positive number. date: Date as YYYY-MM-DD (defaults to today). |
| edit_exerciseA | Change the duration or calorie burn of a logged exercise. Args: exercise_id: The exercise ID, from get_food_log. minutes: New duration in minutes. calories_burned: New burn, as a positive number. date: Date the entry is on as YYYY-MM-DD (defaults to today). |
| remove_exerciseA | Delete logged exercise entries. Use this for an entry that should not be there at all, such as a duplicate from a tracker sync. edit_exercise is for one whose duration or burn is merely wrong. Args: exercise_ids: List of exercise IDs to remove, from get_food_log. date: Date the entries belong to as YYYY-MM-DD (defaults to today). |
| add_fastA | Record a fast. Args: start: When the fast started, as YYYY-MM-DD HH:MM. end: When it ended, same format. Omit for an ongoing fast. goal_hours: Target length in hours. |
| edit_fastA | Change a recorded fast, including ending one that is still open. Args: fast_id: The fast ID, from get_fasting_history. start: New start as YYYY-MM-DD HH:MM. end: New end as YYYY-MM-DD HH:MM. goal_hours: New target length in hours. |
| delete_fastA | Remove a recorded fast. Args: fast_id: The fast ID, from get_fasting_history. |
| get_targetsB | Nutrient targets for the account, as shown beside the diary totals. |
| set_nutrient_targetA | Set a nutrient's daily target, its upper limit, or whether it is tracked. Giving a minimum or maximum makes it a custom target, replacing the default Cronometer works out from the profile. Setting visible turns tracking of that nutrient on or off, which is how a micronutrient starts showing up in the diary at all. Only what you pass changes: the rest of the nutrient's settings are read first and kept, so turning on visibility never disturbs an existing target. Going back to Cronometer's own default is done in the app, under Settings then Targets. Report the current value from get_targets before overwriting one, so it can be put back by hand if wanted. Args: nutrient: Nutrient name, e.g. "protein", "iodine", "choline", "biotin". Call list_nutrients for the accepted names. minimum: Daily target, in that nutrient's own unit. maximum: Upper limit, in that nutrient's own unit. visible: True to track the nutrient, False to hide it. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/rollecode/cronometer-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server