Strength training plans for 26 weeks, plus set, meal and progress logging in Almost Fire.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Use this when the person asks to remove a food they logged by mistake. Give its entry id from get_nutrition. Comes back with an Undo. Do not use for a food they still ate; log the right amount instead.
A new random id for this change (a UUID). Send the same one again only to retry this exact change.
The server marks this tool as destructive. Running it may delete or overwrite data on the server or in any account you connected with your headers.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http strength-training https://strength.almostfire.com/api/mcp
Use this when the person asks to remove a food they logged by mistake. Give its entry id from get_nutrition. Comes back with an Undo. Do not use for a food they still ate; log the right amount instead.
| Argument | Type | Description |
|---|---|---|
| entryId* | string | |
| idempotencyKey* | string | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
{
"type": "object",
"required": [
"entryId",
"idempotencyKey"
],
"properties": {
"entryId": {
"type": "string"
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
}
},
"additionalProperties": false
}Use this when the person asks to remove a set they logged by mistake. Give its setId. Comes back with an Undo. Do not use to change a set's numbers; use edit_set.
| Argument | Type | Description |
|---|---|---|
| setId* | string | |
| idempotencyKey* | string | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
{
"type": "object",
"required": [
"setId",
"idempotencyKey"
],
"properties": {
"setId": {
"type": "string"
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
}
},
"additionalProperties": false
}Use this when the person corrects a set they already logged. Give its setId from get_today or get_session and only the values they change; null keeps the rest. Comes back with an Undo. Do not use to log a new set; use log_set.
| Argument | Type | Description |
|---|---|---|
| rir | number | null | |
| load | number | null | |
| reps | integer | null | |
| setId* | string | |
| loadUnit | string | null | |
| idempotencyKey* | string | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
{
"type": "object",
"required": [
"setId",
"idempotencyKey"
],
"properties": {
"rir": {
"type": [
"number",
"null"
],
"maximum": 10,
"minimum": 0
},
"load": {
"type": [
"number",
"null"
],
"minimum": 0
},
"reps": {
"type": [
"integer",
"null"
],
"maximum": 9007199254740991,
"minimum": 1
},
"setId": {
"type": "string"
},
"loadUnit": {
"enum": [
"kg",
"lb",
"label",
null
],
"type": [
"string",
"null"
]
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
}
},
"additionalProperties": false
}Use this when the person asks what they've eaten or how their calories and protein are going, and before removing a logged food. Reads a day's food (date null is today): every entry with its id, the totals against the day's targets, their usual foods and saved recipes, and the weight trend. Do not use to log food; use log_foods.
| Argument | Type | Description |
|---|---|---|
| date | string | null |
{
"type": "object",
"properties": {
"date": {
"type": [
"string",
"null"
],
"format": "date"
}
},
"additionalProperties": false
}Use this when the person asks how they're progressing, in numbers. Reads their Progress page: training volume by week, bests, each lift's estimated max and trend, sessions done, bodyweight and cardio, as the app shows them. Do not use for a graph; use show_progress_chart.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}Use this when the person asks what's coming up this week or next, or what they did on other days. Lists their sessions between two ISO times (from, to), each with its id, day, time and status. Do not use for today's session; use get_today.
| Argument | Type | Description |
|---|---|---|
| to* | string | |
| from* | string |
{
"type": "object",
"required": [
"from",
"to"
],
"properties": {
"to": {
"type": "string",
"format": "date-time"
},
"from": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": false
}Use this when you need one session in full, by its id from get_today or get_schedule. Reads its exercises (slots) with each target, the exercises each slot allows, and the sets logged. Do not use to list sessions; use get_schedule.
| Argument | Type | Description |
|---|---|---|
| sessionId* | string |
{
"type": "object",
"required": [
"sessionId"
],
"properties": {
"sessionId": {
"type": "string"
}
},
"additionalProperties": false
}Use this when the person asks what's on today or how today's session is going, and before logging a set. Reads today's session (or the next one) in their Almost Fire account with every exercise, its target and the sets logged, this week's sessions and training volume, and their food and weight so far today. Do not use for another day's session; use get_schedule and get_session.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}Use this when the person asks how their week went or what changes next week. Reads the Sunday review of a program week (null is the latest): sessions, volume, new bests, the pace, each change Stoke made to next week with its reason, and what was kept and why. Those changes follow fixed rules: explain each from its reason, never invent another. Do not use for today's session; use get_today.
| Argument | Type | Description |
|---|---|---|
| week | integer | null |
{
"type": "object",
"properties": {
"week": {
"type": [
"integer",
"null"
],
"maximum": 26,
"minimum": 1
}
},
"additionalProperties": false
}Use this when the person wants a different exercise in a session (a busy machine, a sore joint, missing kit). Lists the swaps that train the same movement in that slot and week, best first, by sessionId and slot. Nothing changes; swap with swap_exercise. Do not use to explain how an exercise is done; use show_exercise.
| Argument | Type | Description |
|---|---|---|
| slot* | string | |
| sessionId* | string |
{
"type": "object",
"required": [
"sessionId",
"slot"
],
"properties": {
"slot": {
"type": "string"
},
"sessionId": {
"type": "string"
}
},
"additionalProperties": false
}Use this when the person tells you about cardio they did: a run, a ride, the rower, a walk. Record cardio the person did, with the numbers they give: minutes always; distance, heart rate, level, incline, energy and intervals only when given. Never invent them. effort is a talk test: easy (could hold a conversation), steady (short sentences), hard (a few words). Give sessionId to count it in that session (it fills the session's planned cardio when it is the same exercise), or null for cardio on its own. Null startedAt is just finished. Cardio counts as minutes, never kilograms. Applied immediately with Undo. Do not use for a lifting set; use log_set.
| Argument | Type | Description |
|---|---|---|
| kcal | number | null | |
| level | number | null | |
| effort | string | null | |
| incline | number | null | |
| minutes* | number | |
| intervals | any | |
| sessionId | string | null | |
| startedAt | string | null | |
| distanceKm | number | null | |
| exerciseKey* | string | |
| avgHeartRate | integer | null | |
| maxHeartRate | integer | null | |
| idempotencyKey* | string | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
{
"type": "object",
"required": [
"exerciseKey",
"minutes",
"idempotencyKey"
],
"properties": {
"kcal": {
"type": [
"number",
"null"
],
"maximum": 10000,
"minimum": 0
},
"level": {
"type": [
"number",
"null"
],
"maximum": 100,
"minimum": 0
},
"effort": {
"enum": [
"easy",
"steady",
"hard",
null
],
"type": [
"string",
"null"
]
},
"incline": {
"type": [
"number",
"null"
],
"maximum": 40,
"minimum": -10
},
"minutes": {
"type": "number",
"maximum": 1440,
"minimum": 0.5
},
"intervals": {
"anyOf": [
{
"type": "object",
"required": [
"work",
"easy",
"rounds"
],
"properties": {
"easy": {
"type": "integer",
"maximum": 3600,
"minimum": 0
},
"work": {
"type": "integer",
"maximum": 3600,
"minimum": 5
},
"rounds": {
"type": "integer",
"maximum": 60,
"minimum": 1
}
},
"additionalProperties": false
},
{
"type": "null"
}
]
},
"sessionId": {
"type": [
"string",
"null"
]
},
"startedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"distanceKm": {
"type": [
"number",
"null"
],
"maximum": 1000,
"minimum": 0
},
"exerciseKey": {
"type": "string"
},
"avgHeartRate": {
"type": [
"integer",
"null"
],
"maximum": 250,
"minimum": 30
},
"maxHeartRate": {
"type": [
"integer",
"null"
],
"maximum": 250,
"minimum": 30
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
}
},
"additionalProperties": false
}Use this when the person has agreed what they ate and wants it logged. One entry per food: from a photo read (read_meal_photo's logItems, with their corrections), a saved food or recipe by id and grams (from search_foods), or an estimate with a name, serving, quantity and its numbers per serving. eatenAt null is now. Comes back with an Undo. Do not use before they've agreed the foods and amounts, or for a meal they're only planning.
| Argument | Type | Description |
|---|---|---|
| items* | array | |
| eatenAt | string | null | |
| idempotencyKey* | string | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
{
"type": "object",
"required": [
"items",
"idempotencyKey"
],
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"fat": {
"type": [
"number",
"null"
],
"maximum": 1000,
"minimum": 0
},
"kcal": {
"type": [
"number",
"null"
],
"maximum": 5000,
"minimum": 0
},
"name": {
"type": [
"string",
"null"
]
},
"carbs": {
"type": [
"number",
"null"
],
"maximum": 1000,
"minimum": 0
},
"grams": {
"type": [
"number",
"null"
],
"maximum": 5000,
"minimum": 1
},
"foodId": {
"type": [
"string",
"null"
]
},
"tweaks": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"required": [
"foodId"
],
"properties": {
"grams": {
"type": [
"number",
"null"
],
"maximum": 5000,
"minimum": 0
},
"foodId": {
"type": "string"
},
"swapTo": {
"type": [
"string",
"null"
]
}
},
"additionalProperties": false
},
"maxItems": 30,
"minItems": 1
},
{
"type": "null"
}
]
},
"foodKey": {
"type": [
"string",
"null"
],
"pattern": "^usda:\\d+$"
},
"protein": {
"type": [
"number",
"null"
],
"maximum": 1000,
"minimum": 0
},
"serving": {
"type": [
"string",
"null"
]
},
"quantity": {
"type": [
"number",
"null"
],
"maximum": 50,
"minimum": 0.05
},
"certainty": {
"enum": [
"EXACT",
"GOOD",
"ROUGH",
null
],
"type": [
"string",
"null"
]
}
},
"additionalProperties": false
},
"maxItems": 30,
"minItems": 1
},
"eatenAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
}
},
"additionalProperties": false
}Use this when the person tells you a set they did. Give the session and slot from get_today or get_session, and the load and reps they said. Never invent a number. loadUnit kg or lb as they said it (label for a machine's own numbers); rir only if they say it. setNumber null logs the next set. Comes back with an Undo. Do not use to correct a set already logged; use edit_set.
| Argument | Type | Description |
|---|---|---|
| rir | number | null | |
| load* | number | |
| reps* | integer | |
| slot* | string | |
| loadUnit | string | null | |
| sessionId* | string | |
| setNumber | integer | null | |
| idempotencyKey* | string | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
{
"type": "object",
"required": [
"sessionId",
"slot",
"load",
"reps",
"idempotencyKey"
],
"properties": {
"rir": {
"type": [
"number",
"null"
],
"maximum": 10,
"minimum": 0
},
"load": {
"type": "number",
"minimum": 0
},
"reps": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
},
"slot": {
"type": "string"
},
"loadUnit": {
"enum": [
"kg",
"lb",
"label",
null
],
"type": [
"string",
"null"
]
},
"sessionId": {
"type": "string"
},
"setNumber": {
"type": [
"integer",
"null"
],
"maximum": 30,
"minimum": 1
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
}
},
"additionalProperties": false
}Use this when the person tells you their weight. Give the weight and unit, and when (null is now). Targets follow the smoothed trend, never one reading. Comes back with an Undo. Do not use to set a weight goal.
| Argument | Type | Description |
|---|---|---|
| unit | string | null | |
| weight* | number | |
| measuredAt | string | null | |
| idempotencyKey* | string | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
{
"type": "object",
"required": [
"weight",
"idempotencyKey"
],
"properties": {
"unit": {
"enum": [
"kg",
"lb",
null
],
"type": [
"string",
"null"
]
},
"weight": {
"type": "number",
"maximum": 900,
"minimum": 20
},
"measuredAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
}
},
"additionalProperties": false
}Use this when someone asks for a strength, gym, weightlifting or muscle-building program or workout plan, at a gym or at home. Builds all 26 weeks from Almost Fire's plan engine, the one the app uses: the split for their days, each session's exercises with sets, reps, rest and effort, a lighter week to end each block, and gentler swaps for anything they protect. No account needed. Ask how many days they can train first; fill the rest from what they've said and leave the others null. Do not use for running or race plans, sport-specific conditioning, diet plans or injury rehab.
| Argument | Type | Description |
|---|---|---|
| goal | string | null | strength, muscle or fat_loss; null when they haven't said. |
| split | string | null | full, upper_lower, ppl or body_part; auto or null picks the one that suits their days. |
| style | any | How they like to train: supersets, straight sets, heavy, pump, machines, free weights, a finisher. |
| protect | any | Areas to go easy on (a sore knee, a shoulder): the plan picks gentler options there. |
| equipment | string | null | commercial (a full gym), home (a home gym with a rack) or dumbbells only. |
| loveLifts | any | Lifts they want in. |
| skipLifts | any | Lifts they don't want. |
| daysPerWeek* | integer | Training days a week. |
| sessionMinutes | integer | null | How long a session can be. |
| buildPriorities | any | Up to two areas to build most. |
{
"type": "object",
"required": [
"daysPerWeek"
],
"properties": {
"goal": {
"enum": [
"strength",
"muscle",
"fat_loss",
null
],
"type": [
"string",
"null"
],
"description": "strength, muscle or fat_loss; null when they haven't said."
},
"split": {
"enum": [
"auto",
"full",
"upper_lower",
"ppl",
"body_part",
null
],
"type": [
"string",
"null"
],
"description": "full, upper_lower, ppl or body_part; auto or null picks the one that suits their days."
},
"style": {
"anyOf": [
{
"type": "array",
"items": {
"enum": [
"supersets",
"straight",
"heavy",
"pump",
"machines",
"free",
"finisher"
],
"type": "string"
},
"maxItems": 7
},
{
"type": "null"
}
],
"description": "How they like to train: supersets, straight sets, heavy, pump, machines, free weights, a finisher."
},
"protect": {
"anyOf": [
{
"type": "array",
"items": {
"enum": [
"shoulder",
"elbow",
"wrist",
"lowerBack",
"hip",
"knee",
"ankle",
"other"
],
"type": "string"
},
"maxItems": 8
},
{
"type": "null"
}
],
"description": "Areas to go easy on (a sore knee, a shoulder): the plan picks gentler options there."
},
"equipment": {
"enum": [
"commercial",
"home",
"dumbbells",
null
],
"type": [
"string",
"null"
],
"description": "commercial (a full gym), home (a home gym with a rack) or dumbbells only."
},
"loveLifts": {
"anyOf": [
{
"type": "array",
"items": {
"enum": [
"squat",
"deadlift",
"bench",
"legpress",
"split",
"shoulderpress",
"pulldown",
"clean"
],
"type": "string"
},
"maxItems": 8
},
{
"type": "null"
}
],
"description": "Lifts they want in."
},
"skipLifts": {
"anyOf": [
{
"type": "array",
"items": {
"enum": [
"squat",
"deadlift",
"bench",
"legpress",
"split",
"shoulderpress",
"pulldown",
"clean"
],
"type": "string"
},
"maxItems": 8
},
{
"type": "null"
}
],
"description": "Lifts they don't want."
},
"daysPerWeek": {
"type": "integer",
"maximum": 7,
"minimum": 1,
"description": "Training days a week."
},
"sessionMinutes": {
"type": [
"integer",
"null"
],
"maximum": 150,
"minimum": 20,
"description": "How long a session can be."
},
"buildPriorities": {
"anyOf": [
{
"type": "array",
"items": {
"enum": [
"legs",
"glutes",
"chest",
"back",
"shoulders",
"arms",
"core",
"even"
],
"type": "string"
},
"maxItems": 2
},
{
"type": "null"
}
],
"description": "Up to two areas to build most."
}
},
"additionalProperties": false
}Use this when the person asks to move a session to another day or time. Give its sessionId and the new start and end as ISO times. Comes back with an Undo. Do not use to skip a session; use update_session.
| Argument | Type | Description |
|---|---|---|
| end* | string | |
| start* | string | |
| sessionId* | string | |
| idempotencyKey* | string | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
{
"type": "object",
"required": [
"sessionId",
"start",
"end",
"idempotencyKey"
],
"properties": {
"end": {
"type": "string",
"format": "date-time"
},
"start": {
"type": "string",
"format": "date-time"
},
"sessionId": {
"type": "string"
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
}
},
"additionalProperties": false
}Use this when the person wants to log a meal from a photo but hasn't attached one, or the app can't hand you their photo. Opens the Almost Fire camera in the chat: they take or choose a photo there, Stoke reads each food with its grams and calories, and Log saves it. Do not use when they've attached a photo; use read_meal_photo.
| Argument | Type | Description |
|---|---|---|
| note | string | null | Anything they said about the meal, for the read. |
{
"type": "object",
"properties": {
"note": {
"type": [
"string",
"null"
],
"description": "Anything they said about the meal, for the read."
}
},
"additionalProperties": false
}Use this when the person attaches a photo of food they ate or will eat. Reads it as the Almost Fire camera does: a plate or bowl comes back as each food with its grams, calories, macros and how sure the read is; a packet as its label per 100 g; a pot on a kitchen scale as its grams. Nothing is logged: read it back, take their corrections, then call log_foods with its logItems (or they tap Log on the card). Do not use for a photo that isn't food, or to judge anyone's body.
| Argument | Type | Description |
|---|---|---|
| note | string | null | Anything they said about it ("half the rice", "oat flat white"). |
| photo* | object | The photo they attached. |
{
"type": "object",
"required": [
"photo"
],
"properties": {
"note": {
"type": [
"string",
"null"
],
"description": "Anything they said about it (\"half the rice\", \"oat flat white\")."
},
"photo": {
"type": "object",
"required": [
"download_url",
"file_id"
],
"properties": {
"file_id": {
"type": "string"
},
"file_name": {
"type": [
"string",
"null"
]
},
"mime_type": {
"type": [
"string",
"null"
]
},
"download_url": {
"type": "string",
"format": "uri"
}
},
"description": "The photo they attached.",
"additionalProperties": false
}
},
"additionalProperties": false
}The Almost Fire camera card's photo, read as read_meal_photo reads one. Only the card calls it.
| Argument | Type | Description |
|---|---|---|
| note | string | null | |
| image* | string | The photo, base64. |
| mimeType* | string |
{
"type": "object",
"required": [
"image",
"mimeType"
],
"properties": {
"note": {
"type": [
"string",
"null"
]
},
"image": {
"type": "string",
"pattern": "^[A-Za-z0-9+/=]+$",
"description": "The photo, base64."
},
"mimeType": {
"type": "string",
"pattern": "^image\\/(jpeg|png|webp|heic|heif|gif)$"
}
},
"additionalProperties": false
}Use this when the person says how they feel before or after training, or tells you about pain or swelling. Record the person’s reported readiness and symptoms. symptoms.pec is pain anywhere (sharp means sharp pain or pulling) and symptoms.knee is swelling anywhere, whatever the body part. After a session they may also report feel, strength, effort (1–10 for the whole session), more (sets they could have added), areas and soreness (muscle, joint, sharp, swelling); also set pec or knee from soreness as the phone does: joint is knee ache, sharp is pec sharp, swelling is knee swollen, muscle leaves both clear. A morning check-in has no session: readiness is how they feel today (1 Flat, 2 Meh, 3 Okay, 4 Good, 5 On fire), morning is true, and behind lists what they say is behind it (sleep, work, sore, stress, family, sick, travel); log their weight with log_weight. How they feel the morning after a session is next (clear or worse) on that session’s check-in. Never infer medical clearance. Do not use to diagnose pain or to log their weight; use log_weight for weight.
| Argument | Type | Description |
|---|---|---|
| note | string | null | |
| symptoms* | object | |
| readiness | integer | null | |
| sessionId | string | null | |
| idempotencyKey* | string | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
{
"type": "object",
"required": [
"symptoms",
"idempotencyKey"
],
"properties": {
"note": {
"type": [
"string",
"null"
]
},
"symptoms": {
"type": "object",
"properties": {
"pec": {
"enum": [
"",
"clear",
"sore",
"sharp",
null
],
"type": [
"string",
"null"
]
},
"feel": {
"enum": [
"rough",
"fine",
"great",
null
],
"type": [
"string",
"null"
]
},
"knee": {
"enum": [
"",
"clear",
"ache",
"swollen",
null
],
"type": [
"string",
"null"
]
},
"more": {
"enum": [
"none",
"one",
"two",
null
],
"type": [
"string",
"null"
]
},
"next": {
"enum": [
"",
"clear",
"worse",
null
],
"type": [
"string",
"null"
]
},
"after": {
"enum": [
"",
"clear",
"worse",
null
],
"type": [
"string",
"null"
]
},
"areas": {
"anyOf": [
{
"type": "array",
"items": {
"enum": [
"pec",
"knee",
"shoulder",
"back",
"elbow",
"other"
],
"type": "string"
},
"maxItems": 6
},
{
"type": "null"
}
]
},
"behind": {
"anyOf": [
{
"type": "array",
"items": {
"enum": [
"sleep",
"work",
"sore",
"stress",
"family",
"sick",
"travel"
],
"type": "string"
},
"maxItems": 7
},
{
"type": "null"
}
]
},
"effort": {
"type": [
"integer",
"null"
],
"maximum": 10,
"minimum": 1
},
"morning": {
"type": [
"boolean",
"null"
],
"const": true
},
"soreness": {
"enum": [
"muscle",
"joint",
"sharp",
"swelling",
null
],
"type": [
"string",
"null"
]
},
"strength": {
"enum": [
"flat",
"normal",
"strong",
null
],
"type": [
"string",
"null"
]
}
},
"additionalProperties": false
},
"readiness": {
"type": [
"integer",
"null"
],
"maximum": 5,
"minimum": 1
},
"sessionId": {
"type": [
"string",
"null"
]
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
}
},
"additionalProperties": false
}Use this when the person wants to keep, save or start a plan make_plan made, or presses Save on its card. Saves the plan to their Almost Fire account, free: the first time it asks them to sign in, which makes their account. Send the answers make_plan used, so the saved plan is the one they saw. The card then opens their plan page in Almost Fire, where their first week starts. emailWeekly true also emails them each week's sessions on Monday mornings, until they start in the app. Do not use before make_plan has shown them a plan, or to change the plan of someone who already trains in Almost Fire.
| Argument | Type | Description |
|---|---|---|
| goal | string | null | strength, muscle or fat_loss; null when they haven't said. |
| split | string | null | full, upper_lower, ppl or body_part; auto or null picks the one that suits their days. |
| style | any | How they like to train: supersets, straight sets, heavy, pump, machines, free weights, a finisher. |
| protect | any | Areas to go easy on (a sore knee, a shoulder): the plan picks gentler options there. |
| equipment | string | null | commercial (a full gym), home (a home gym with a rack) or dumbbells only. |
| loveLifts | any | Lifts they want in. |
| skipLifts | any | Lifts they don't want. |
| daysPerWeek* | integer | Training days a week. |
| emailWeekly | boolean | null | true only when the person said yes, in this chat, to an email of each week's sessions on Monday mornings. Null otherwise; never assume it. |
| idempotencyKey | string | null | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
| sessionMinutes | integer | null | How long a session can be. |
| buildPriorities | any | Up to two areas to build most. |
{
"type": "object",
"required": [
"daysPerWeek"
],
"properties": {
"goal": {
"enum": [
"strength",
"muscle",
"fat_loss",
null
],
"type": [
"string",
"null"
],
"description": "strength, muscle or fat_loss; null when they haven't said."
},
"split": {
"enum": [
"auto",
"full",
"upper_lower",
"ppl",
"body_part",
null
],
"type": [
"string",
"null"
],
"description": "full, upper_lower, ppl or body_part; auto or null picks the one that suits their days."
},
"style": {
"anyOf": [
{
"type": "array",
"items": {
"enum": [
"supersets",
"straight",
"heavy",
"pump",
"machines",
"free",
"finisher"
],
"type": "string"
},
"maxItems": 7
},
{
"type": "null"
}
],
"description": "How they like to train: supersets, straight sets, heavy, pump, machines, free weights, a finisher."
},
"protect": {
"anyOf": [
{
"type": "array",
"items": {
"enum": [
"shoulder",
"elbow",
"wrist",
"lowerBack",
"hip",
"knee",
"ankle",
"other"
],
"type": "string"
},
"maxItems": 8
},
{
"type": "null"
}
],
"description": "Areas to go easy on (a sore knee, a shoulder): the plan picks gentler options there."
},
"equipment": {
"enum": [
"commercial",
"home",
"dumbbells",
null
],
"type": [
"string",
"null"
],
"description": "commercial (a full gym), home (a home gym with a rack) or dumbbells only."
},
"loveLifts": {
"anyOf": [
{
"type": "array",
"items": {
"enum": [
"squat",
"deadlift",
"bench",
"legpress",
"split",
"shoulderpress",
"pulldown",
"clean"
],
"type": "string"
},
"maxItems": 8
},
{
"type": "null"
}
],
"description": "Lifts they want in."
},
"skipLifts": {
"anyOf": [
{
"type": "array",
"items": {
"enum": [
"squat",
"deadlift",
"bench",
"legpress",
"split",
"shoulderpress",
"pulldown",
"clean"
],
"type": "string"
},
"maxItems": 8
},
{
"type": "null"
}
],
"description": "Lifts they don't want."
},
"daysPerWeek": {
"type": "integer",
"maximum": 7,
"minimum": 1,
"description": "Training days a week."
},
"emailWeekly": {
"type": [
"boolean",
"null"
],
"description": "true only when the person said yes, in this chat, to an email of each week's sessions on Monday mornings. Null otherwise; never assume it."
},
"idempotencyKey": {
"type": [
"string",
"null"
],
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
},
"sessionMinutes": {
"type": [
"integer",
"null"
],
"maximum": 150,
"minimum": 20,
"description": "How long a session can be."
},
"buildPriorities": {
"anyOf": [
{
"type": "array",
"items": {
"enum": [
"legs",
"glutes",
"chest",
"back",
"shoulders",
"arms",
"core",
"even"
],
"type": "string"
},
"maxItems": 2
},
{
"type": "null"
}
],
"description": "Up to two areas to build most."
}
},
"additionalProperties": false
}Use this when the person tells you a food they ate without a photo, before log_foods. Find the person's own foods before anything else, by name or by kind: the words they used ("protein powder", "milk", "my usual bread"), not a brand you guess. mine is their saved foods that fit, each with an id, macros per 100 g, their usual grams (lastGrams), match (name: its name holds the words; kind: it is that kind of food, so "protein powder" finds their whey; word: only the last of their words, the one that says what it is, fits, so it is a different food of that sort, never theirs unless they say so) and lastEatenAt. When none fits by name, recent lists the saved foods they logged lately: read it too, because their food is often named by brand (a protein powder called Impact Lean Whey, a milk called Light Start). list is at most three plain foods from the food list, each with a foodKey; logging one saves it as a new food of theirs. Use their own food (mine or recent) when it is the same thing, or the kind of food they named (their milk for "milk", their whey for "protein powder"); a food that only sounds alike or shares a word is not it (corn flour is not corn, dark soy sauce is not dark chocolate). "My most recent" or "my usual" means the one they ate latest. Use list, an estimate or create_food only when none of theirs is it, and say it's new. Search before estimating, and log what it finds by grams. A recipe has recipe set: its foods and their grams, serves, cookedGrams and gramsLeft, what's left of the pot. Do not use to read a photo; use read_meal_photo.
| Argument | Type | Description |
|---|---|---|
| query* | string |
{
"type": "object",
"required": [
"query"
],
"properties": {
"query": {
"type": "string"
}
},
"additionalProperties": false
}Use this when someone asks how to do an exercise, which muscles it works, or what to do instead. Shows it on the body map with its equipment, its cues and swaps that train the same thing. No account needed. Do not use to diagnose pain or to give rehab exercises.
| Argument | Type | Description |
|---|---|---|
| exercise* | string | The exercise's name ("Romanian deadlift") or Almost Fire key ("rdl"). |
{
"type": "object",
"required": [
"exercise"
],
"properties": {
"exercise": {
"type": "string",
"description": "The exercise's name (\"Romanian deadlift\") or Almost Fire key (\"rdl\")."
}
},
"additionalProperties": false
}Use this when the person asks to see their progress on a graph. Draws one of their Progress graphs from their records: lift_max or lift_volume per session for one exercise (key), weekly_volume, body_weight (90 days), cardio_distance, cardio_pace or cardio_heart_rate, daily_kcal or daily_protein (30 days). Training volume is the number that matters most. Do not use for sleep or heart-rate numbers, which stay in the Almost Fire app.
| Argument | Type | Description |
|---|---|---|
| key | string | null | The exercise key for lift_max, lift_volume and the cardio graphs; null otherwise. |
| note | string | null | One line on what the graph shows, in your words. |
| metric* | string |
{
"type": "object",
"required": [
"metric"
],
"properties": {
"key": {
"type": [
"string",
"null"
],
"description": "The exercise key for lift_max, lift_volume and the cardio graphs; null otherwise."
},
"note": {
"type": [
"string",
"null"
],
"description": "One line on what the graph shows, in your words."
},
"metric": {
"enum": [
"lift_max",
"lift_volume",
"weekly_volume",
"body_weight",
"cardio_distance",
"cardio_pace",
"cardio_heart_rate",
"daily_kcal",
"daily_protein"
],
"type": "string"
}
},
"additionalProperties": false
}Use this when the person asks to swap the exercise in a session. Give the sessionId and slot, and the exerciseKey they chose, or a same-movement one from list_alternatives when they leave it to you. The new exercise brings its own rules, and loads never carry over between exercises. untilWeek null swaps that session only; a week keeps the swap for that day through that program week. Comes back with an Undo. Do not use to move a session; use move_session.
| Argument | Type | Description |
|---|---|---|
| slot* | string | |
| sessionId* | string | |
| untilWeek | integer | null | |
| exerciseKey* | string | |
| idempotencyKey* | string | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
{
"type": "object",
"required": [
"sessionId",
"slot",
"exerciseKey",
"idempotencyKey"
],
"properties": {
"slot": {
"type": "string"
},
"sessionId": {
"type": "string"
},
"untilWeek": {
"type": [
"integer",
"null"
],
"maximum": 26,
"minimum": 1
},
"exerciseKey": {
"type": "string"
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
}
},
"additionalProperties": false
}Use this when the person wants to take back a change made here (a logged set, meal, weigh-in or any other) while its Undo is open. Give the undo.id the change came back with. Do not use for a change they made in the Almost Fire app itself.
| Argument | Type | Description |
|---|---|---|
| undoId* | string | The undo.id a change came back with. |
| idempotencyKey* | string | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
{
"type": "object",
"required": [
"undoId",
"idempotencyKey"
],
"properties": {
"undoId": {
"type": "string",
"description": "The undo.id a change came back with."
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
}
},
"additionalProperties": false
}Use this when the person doesn't want one of the changes the Sunday review made to next week. Give the change's index from get_weekly_review. Next week goes back to the program's target for that change. Do not use for a change they made themselves; use undo.
| Argument | Type | Description |
|---|---|---|
| week* | integer | |
| index* | integer | |
| idempotencyKey* | string | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
{
"type": "object",
"required": [
"week",
"index",
"idempotencyKey"
],
"properties": {
"week": {
"type": "integer",
"maximum": 26,
"minimum": 1
},
"index": {
"type": "integer",
"maximum": 200,
"minimum": 0
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
}
},
"additionalProperties": false
}Use this when the person starts, finishes or skips a session, or says how it felt. status IN_PROGRESS starts it, DONE finishes it and SKIPPED skips it; feeling is 1 to 5; notes and gym as they say. Null leaves a field as it is. Comes back with an Undo. Do not use to move a session to another day; use move_session.
| Argument | Type | Description |
|---|---|---|
| gym | string | null | |
| notes | string | null | |
| status | string | null | |
| feeling | string | null | |
| sessionId* | string | |
| idempotencyKey* | string | A new random id for this change (a UUID). Send the same one again only to retry this exact change. |
{
"type": "object",
"required": [
"sessionId",
"idempotencyKey"
],
"properties": {
"gym": {
"type": [
"string",
"null"
]
},
"notes": {
"type": [
"string",
"null"
]
},
"status": {
"enum": [
"PLANNED",
"IN_PROGRESS",
"DONE",
"SKIPPED",
null
],
"type": [
"string",
"null"
]
},
"feeling": {
"type": [
"string",
"null"
]
},
"sessionId": {
"type": "string"
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$",
"description": "A new random id for this change (a UUID). Send the same one again only to retry this exact change."
}
},
"additionalProperties": false
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 8, 2026.