JustGains: workouts, programs, routes, training analytics and food diary.
Speak like a friendly coach. Act before replying; keep tool names, codes, IDs and integration details out of replies. Explain methods only when asked. Cards already show exercises, sets and food: add brief coaching or confirmation, not a duplicate list. Explain failures or sign-in needs plainly with a next step.
Call search_exercises before create_workout/update_workout; never invent exercise codes. generate_workout works without sign-in. Account reads and writes require a connected account. Workout previews are interactive when the host supports MCP Apps.
For routine food logging, call log_my_food directly in one request. Do not call search_foods, browse the web or research nutrition first. Include every eaten food/drink, stated counts and units, quantityGrams and rounded estimatedMacros for each whole portion. Mark guessed weights portionEstimated=true and disclose assumptions. Never log plans or hypothetical meals. The API resolves the local date and prefers reliable cached catalog nutrition; fallback estimates are visibly marked. Confirm success briefly without a verification call. Saved meals and phone sync are separate.
Read get_my_food_diary only for an explicit diary request or a dependency on past entries. Use recentEntryId only for an explicit repeat. Correct saved food with diaryEntryId and expectedUpdatedAt from the latest result; retain serving counts and never add a duplicate. Keep requestId on retries. Remove only requested foods with remove_my_food and exact IDs/freshness tokens from the latest result; read the diary only if unavailable. Partial removal is a portion correction. Stale corrections need a fresh read.
Discoverability
3 pass · 1 partial3 passed · 1 partial58/100
Client listings and public setup information.
mcp.json or server-card.json
Either mcp.json or an MCP Server Card declaring this endpoint passes.
The MCP Server Card declares this server's exact endpoint.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Generate and persist a workout from a natural-language description, such as "30 minute leg workout with dumbbells". Returns its workout ID, title, coaching summary and exercises/sets in a preview card. Works without sign-in; a connected account owns the saved workout.
The description explains the capability, when to use it, and what to expect.
Inputs87/100
Input documentation gives an agent enough context to populate the arguments.
prompt
Description of the workout to generate (e.g., "20 minute leg workout with dumbbells")
Clear enough to supply this argument.
muscleGroups
Muscle group codes to focus on, for example CHEST. If the code is unknown, describe the target muscles in prompt instead.
Clear enough to supply this argument.
equipment
Codes of available equipment, as used by JustGains exercises. If codes are unknown, describe the available equipment in prompt instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"timestamp"
],
"properties": {
"error": {
"type": "boolean",
"description": "Whether the operation failed."
},
"title": {
"type": "string",
"description": "Workout title."
},
"summary": {
"type": "string",
"description": "Coaching summary of the generated workout."
},
"workout": {
"description": "Workout preview with workoutTitle, workoutData (exercises and sets), equipmentList, muscleUsage and creatorProfile; may be null when unavailable."
},
"timestamp": {
"type": "string",
"description": "ISO-8601 time this result was produced."
},
"workoutId": {
"type": "string",
"description": "Persisted workout ID for follow-up previews and edits."
},
"errorMessage": {
"type": "string",
"description": "Explanation when the operation failed."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "generate_workout",
"title": "Generate a workout",
"description": "Generate and persist a workout from a natural-language description, such as \"30 minute leg workout with dumbbells\". Returns its workout ID, title, coaching summary and exercises/sets in a preview card. Works without sign-in; a connected account owns the saved workout.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"prompt"
],
"properties": {
"prompt": {
"type": "string",
"description": "Description of the workout to generate (e.g., \"20 minute leg workout with dumbbells\")"
},
"equipment": {
"type": "array",
"items": {
"type": "string"
},
"description": "Codes of available equipment, as used by JustGains exercises. If codes are unknown, describe the available equipment in prompt instead."
},
"muscleGroups": {
"type": "array",
"items": {
"type": "string"
},
"description": "Muscle group codes to focus on, for example CHEST. If the code is unknown, describe the target muscles in prompt instead."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"timestamp"
],
"properties": {
"error": {
"type": "boolean",
"description": "Whether the operation failed."
},
"title": {
"type": "string",
"description": "Workout title."
},
"summary": {
"type": "string",
"description": "Coaching summary of the generated workout."
},
"workout": {
"description": "Workout preview with workoutTitle, workoutData (exercises and sets), equipmentList, muscleUsage and creatorProfile; may be null when unavailable."
},
"timestamp": {
"type": "string",
"description": "ISO-8601 time this result was produced."
},
"workoutId": {
"type": "string",
"description": "Persisted workout ID for follow-up previews and edits."
},
"errorMessage": {
"type": "string",
"description": "Explanation when the operation failed."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Read the signed-in user's training progress over a date range or trailing days (default 30). Returns the resolved range, daily XP/volume/steps and a summary of XP, lifted volume, workout days, active days and best day. Requires a connected JustGains account.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
startDate
First day of the progress window, in YYYY-MM-DD form. Omit to derive it from days and endDate.
Clear enough to supply this argument.
endDate
End of the window (YYYY-MM-DD). Defaults to today.
Clear enough to supply this argument.
days
Alternatively, the number of most recent days to include (e.g. 7, 30, 90).
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"authenticated",
"timestamp"
],
"properties": {
"days": {
"type": "array",
"items": {},
"description": "Daily training records with XP, volume and activity values."
},
"error": {
"type": "boolean",
"description": "Whether the operation failed."
},
"range": {
"type": "object",
"required": [
"startDate",
"endDate"
],
"properties": {
"endDate": {
"type": "string",
"description": "Last included calendar date."
},
"startDate": {
"type": "string",
"description": "First included calendar date."
}
},
"description": "Resolved progress window in YYYY-MM-DD dates.",
"additionalProperties": false
},
"summary": {
"description": "Aggregate progress: totalGains (XP), totalRawVolumeLb (lifted pounds), workoutDays, activeDays and bestDay."
},
"timestamp": {
"type": "string",
"description": "ISO-8601 time this result was produced."
},
"errorMessage": {
"type": "string",
"description": "Explanation when the operation failed."
},
"authenticated": {
"type": "boolean",
"description": "Whether the request used a connected JustGains account."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "get_progress",
"title": "Your progress",
"description": "Read the signed-in user's training progress over a date range or trailing days (default 30). Returns the resolved range, daily XP/volume/steps and a summary of XP, lifted volume, workout days, active days and best day. Requires a connected JustGains account.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"days": {
"type": "number",
"description": "Alternatively, the number of most recent days to include (e.g. 7, 30, 90)."
},
"endDate": {
"type": "string",
"description": "End of the window (YYYY-MM-DD). Defaults to today."
},
"startDate": {
"type": "string",
"description": "First day of the progress window, in YYYY-MM-DD form. Omit to derive it from days and endDate."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"authenticated",
"timestamp"
],
"properties": {
"days": {
"type": "array",
"items": {},
"description": "Daily training records with XP, volume and activity values."
},
"error": {
"type": "boolean",
"description": "Whether the operation failed."
},
"range": {
"type": "object",
"required": [
"startDate",
"endDate"
],
"properties": {
"endDate": {
"type": "string",
"description": "Last included calendar date."
},
"startDate": {
"type": "string",
"description": "First included calendar date."
}
},
"description": "Resolved progress window in YYYY-MM-DD dates.",
"additionalProperties": false
},
"summary": {
"description": "Aggregate progress: totalGains (XP), totalRawVolumeLb (lifted pounds), workoutDays, activeDays and bestDay."
},
"timestamp": {
"type": "string",
"description": "ISO-8601 time this result was produced."
},
"errorMessage": {
"type": "string",
"description": "Explanation when the operation failed."
},
"authenticated": {
"type": "boolean",
"description": "Whether the request used a connected JustGains account."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Search the JustGains exercise library by name (optionally filtered by muscle group or equipment). Returns exercise codes and supported measurements to use when building or updating a workout.
The description explains the capability, when to use it, and what to expect.
Inputs81/100
Explain what happens when this optional value is omitted.
query
Exercise name to search, e.g. "bench press", "romanian deadlift".
Clear enough to supply this argument.
limit
Number of matching exercises to return.
Explain what happens when this optional value is omitted.
muscleGroup
Muscle group code, for example CHEST. Omit to search all muscle groups.
Clear enough to supply this argument.
equipment
JustGains equipment code. If unknown, include the equipment name in query instead.
Declare the result fields and their types in the output schema.
View output schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"exercises",
"timestamp"
],
"properties": {
"exercises": {
"type": "array",
"items": {},
"description": "Matching exercises with exerciseCode, exerciseName, measurements, isWeightPerSide and equipment."
},
"timestamp": {
"type": "string",
"description": "ISO-8601 time this result was produced."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "search_exercises",
"title": "Search exercises",
"description": "Search the JustGains exercise library by name (optionally filtered by muscle group or equipment). Returns exercise codes and supported measurements to use when building or updating a workout.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query"
],
"properties": {
"limit": {
"type": "number",
"description": "Number of matching exercises to return."
},
"query": {
"type": "string",
"description": "Exercise name to search, e.g. \"bench press\", \"romanian deadlift\"."
},
"equipment": {
"type": "string",
"description": "JustGains equipment code. If unknown, include the equipment name in query instead."
},
"muscleGroup": {
"type": "string",
"description": "Muscle group code, for example CHEST. Omit to search all muscle groups."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"exercises",
"timestamp"
],
"properties": {
"exercises": {
"type": "array",
"items": {},
"description": "Matching exercises with exerciseCode, exerciseName, measurements, isWeightPerSide and equipment."
},
"timestamp": {
"type": "string",
"description": "ISO-8601 time this result was produced."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description82/100
Create a workout in the signed-in user's JustGains account, saved under their own creator profile. Provide a title and an ordered list of exercises (by code from search_exercises, or by name to auto-resolve); each exercise can include sets with reps/weight/RPE. Use this for precise, user-specified workouts (use generate_workout for AI-generated ones).
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
title
Workout title.
Clear enough to supply this argument.
description
Workout overview or coaching notes shown alongside the exercise list.
Clear enough to supply this argument.
exercises › items › exercise
Exercise code (e.g. BARBELL.BENCH.PRESS) from search_exercises, or a name to auto-resolve.
Clear enough to supply this argument.
exercises › items › sets › items › reps
Repetitions prescribed for this set.
Clear enough to supply this argument.
exercises › items › sets › items › weight
Load for this set, in unit. Uses kilograms when unit is omitted.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"timestamp"
],
"properties": {
"error": {
"type": "boolean",
"description": "Whether the operation failed."
},
"title": {
"type": "string",
"description": "Workout title."
},
"workout": {
"description": "Workout preview with workoutTitle, workoutData (exercises and sets), equipmentList, muscleUsage and creatorProfile; may be null when unavailable."
},
"timestamp": {
"type": "string",
"description": "ISO-8601 time this result was produced."
},
"workoutId": {
"type": "string",
"description": "Persisted workout ID for follow-up previews and edits."
},
"unresolved": {
"type": "array",
"items": {
"type": "string"
},
"description": "Exercise names that could not be matched; inspect this list for partial resolution."
},
"errorMessage": {
"type": "string",
"description": "Explanation when the operation failed."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "create_workout",
"title": "Save a workout",
"description": "Create a workout in the signed-in user's JustGains account, saved under their own creator profile. Provide a title and an ordered list of exercises (by code from search_exercises, or by name to auto-resolve); each exercise can include sets with reps/weight/RPE. Use this for precise, user-specified workouts (use generate_workout for AI-generated ones).",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"title",
"exercises"
],
"properties": {
"title": {
"type": "string",
"description": "Workout title."
},
"exercises": {
"type": "array",
"items": {
"type": "object",
"required": [
"exercise"
],
"properties": {
"sets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"rpe": {
"type": "number",
"description": "Rating of perceived exertion for the set."
},
"reps": {
"type": "number",
"description": "Repetitions prescribed for this set."
},
"type": {
"enum": [
"normal",
"warmup",
"dropset",
"myorep",
"failure"
],
"type": "string",
"description": "Training purpose or technique of this set. Omitted sets use the normal type."
},
"unit": {
"type": "string",
"description": "Weight unit: kg (default) or lb."
},
"weight": {
"type": "number",
"description": "Load for this set, in unit. Uses kilograms when unit is omitted."
},
"distance": {
"type": "number",
"description": "Distance prescribed for the set, in distanceUnit."
},
"distanceUnit": {
"type": "string",
"description": "Unit for distance: km, mi or meters. Defaults to km."
},
"durationSeconds": {
"type": "number",
"description": "Time prescribed for the set in seconds."
}
}
},
"description": "Sets for this exercise (reps/weight/RPE/etc)."
},
"notes": {
"type": "string",
"description": "Exercise-specific coaching cues or instructions saved with the workout."
},
"exercise": {
"type": "string",
"description": "Exercise code (e.g. BARBELL.BENCH.PRESS) from search_exercises, or a name to auto-resolve."
}
}
},
"description": "Ordered exercises."
},
"description": {
"type": "string",
"description": "Workout overview or coaching notes shown alongside the exercise list."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"timestamp"
],
"properties": {
"error": {
"type": "boolean",
"description": "Whether the operation failed."
},
"title": {
"type": "string",
"description": "Workout title."
},
"workout": {
"description": "Workout preview with workoutTitle, workoutData (exercises and sets), equipmentList, muscleUsage and creatorProfile; may be null when unavailable."
},
"timestamp": {
"type": "string",
"description": "ISO-8601 time this result was produced."
},
"workoutId": {
"type": "string",
"description": "Persisted workout ID for follow-up previews and edits."
},
"unresolved": {
"type": "array",
"items": {
"type": "string"
},
"description": "Exercise names that could not be matched; inspect this list for partial resolution."
},
"errorMessage": {
"type": "string",
"description": "Explanation when the operation failed."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description77/100
Update an existing workout in the user's JustGains account. Provide the workoutId plus any of: new title, new description, or a replacement list of exercises. Call show_workout first if you need the current exercises before modifying them.
Describe the returned information so the agent knows whether it will answer the request.
Inputs90/100
Input documentation gives an agent enough context to populate the arguments.
workoutId
The UUID of the workout to update.
Clear enough to supply this argument.
title
New workout title. Omit to keep the current one.
Clear enough to supply this argument.
description
New workout description. Omit to keep the current one.
Clear enough to supply this argument.
exercises › items › exercise
Exercise code (e.g. BARBELL.BENCH.PRESS) from search_exercises, or a name to auto-resolve.
Clear enough to supply this argument.
exercises › items › sets › items › reps
Repetitions prescribed for this set.
Clear enough to supply this argument.
exercises › items › sets › items › weight
Load for this set, in unit. Uses kilograms when unit is omitted.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"timestamp"
],
"properties": {
"error": {
"type": "boolean",
"description": "Whether the operation failed."
},
"title": {
"type": "string",
"description": "Workout title."
},
"workout": {
"description": "Workout preview with workoutTitle, workoutData (exercises and sets), equipmentList, muscleUsage and creatorProfile; may be null when unavailable."
},
"timestamp": {
"type": "string",
"description": "ISO-8601 time this result was produced."
},
"workoutId": {
"type": "string",
"description": "Persisted workout ID for follow-up previews and edits."
},
"unresolved": {
"type": "array",
"items": {
"type": "string"
},
"description": "Exercise names that could not be matched; inspect this list for partial resolution."
},
"errorMessage": {
"type": "string",
"description": "Explanation when the operation failed."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "update_workout",
"title": "Edit a workout",
"description": "Update an existing workout in the user's JustGains account. Provide the workoutId plus any of: new title, new description, or a replacement list of exercises. Call show_workout first if you need the current exercises before modifying them.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"workoutId"
],
"properties": {
"title": {
"type": "string",
"description": "New workout title. Omit to keep the current one."
},
"exercises": {
"type": "array",
"items": {
"type": "object",
"required": [
"exercise"
],
"properties": {
"sets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"rpe": {
"type": "number",
"description": "Rating of perceived exertion for the set."
},
"reps": {
"type": "number",
"description": "Repetitions prescribed for this set."
},
"type": {
"enum": [
"normal",
"warmup",
"dropset",
"myorep",
"failure"
],
"type": "string",
"description": "Training purpose or technique of this set. Omitted sets use the normal type."
},
"unit": {
"type": "string",
"description": "Weight unit: kg (default) or lb."
},
"weight": {
"type": "number",
"description": "Load for this set, in unit. Uses kilograms when unit is omitted."
},
"distance": {
"type": "number",
"description": "Distance prescribed for the set, in distanceUnit."
},
"distanceUnit": {
"type": "string",
"description": "Unit for distance: km, mi or meters. Defaults to km."
},
"durationSeconds": {
"type": "number",
"description": "Time prescribed for the set in seconds."
}
}
},
"description": "Sets for this exercise (reps/weight/RPE/etc)."
},
"notes": {
"type": "string",
"description": "Exercise-specific coaching cues or instructions saved with the workout."
},
"exercise": {
"type": "string",
"description": "Exercise code (e.g. BARBELL.BENCH.PRESS) from search_exercises, or a name to auto-resolve."
}
}
},
"description": "If provided, REPLACES the workout's exercise list."
},
"workoutId": {
"type": "string",
"description": "The UUID of the workout to update."
},
"description": {
"type": "string",
"description": "New workout description. Omit to keep the current one."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"timestamp"
],
"properties": {
"error": {
"type": "boolean",
"description": "Whether the operation failed."
},
"title": {
"type": "string",
"description": "Workout title."
},
"workout": {
"description": "Workout preview with workoutTitle, workoutData (exercises and sets), equipmentList, muscleUsage and creatorProfile; may be null when unavailable."
},
"timestamp": {
"type": "string",
"description": "ISO-8601 time this result was produced."
},
"workoutId": {
"type": "string",
"description": "Persisted workout ID for follow-up previews and edits."
},
"unresolved": {
"type": "array",
"items": {
"type": "string"
},
"description": "Exercise names that could not be matched; inspect this list for partial resolution."
},
"errorMessage": {
"type": "string",
"description": "Explanation when the operation failed."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description90/100
List the signed-in user's most recent workouts (title, date, duration, total volume, sets, reps, exercise count). Use to discuss recent training, consistency, and volume trends.
The description explains the capability, when to use it, and what to expect.
Inputs64/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Number of recent workout records to return.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Get the CURRENT user's workout-log history (workouts they actually performed and recorded). Use this whenever the user asks about THEIR OWN workouts - 'my last workout', 'what did I do this week', 'how much did I bench Monday', 'show my recent sessions', 'workouts in March', 'last summer's training'. For any historical timeframe, pass `since` and/or `until` (ISO-8601). The tool will paginate deeper automatically until the requested window is covered (or `maxLogs` is reached). For RANKED questions ('what was my best workout', 'longest session ever', 'highest-volume day'), set `rankBy` ('volume' | 'duration') and `topN`. The tool then sweeps the window, computes the metric per log, and returns the top N logs sorted by that metric instead of newest-first. Returns logs with id, title, date, exercise count, and a per-exercise summary of sets/reps/weight; when ranking, each log also carries totalVolumeKg/totalVolumeDisplay and durationSeconds. Returns an error if the user is not signed in.
The description explains the capability, when to use it, and what to expect.
Inputs86/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page
Page of recent logs to read, starting at 1. Date-window scans ignore this value.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
pageSize
Number of logs per page, or the result cap for a date-filtered request.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
since
Optional ISO-8601 lower-bound: only logs with createdAt >= since are returned.
Clear enough to supply this argument.
until
Optional ISO-8601 upper-bound: only logs with createdAt <= until are returned.
Clear enough to supply this argument.
maxLogs
Maximum number of logs to scan in a date window.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
rankBy
How to order results. 'recent' (default) is newest-first by createdAt. 'volume' ranks by total tonnage (sum of weight×reps across all sets). 'duration' ranks by `WorkoutLogDuration` (seconds). Set this for 'best workout', 'highest-volume day', 'longest session' questions.
Clear enough to supply this argument.
topN
Number of highest-ranked logs to return when ranking by volume or duration.
Explain what happens when this optional value is omitted.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_my_workout_logs",
"title": "Your logged workouts",
"description": "Get the CURRENT user's workout-log history (workouts they actually performed and recorded). Use this whenever the user asks about THEIR OWN workouts - 'my last workout', 'what did I do this week', 'how much did I bench Monday', 'show my recent sessions', 'workouts in March', 'last summer's training'. For any historical timeframe, pass `since` and/or `until` (ISO-8601). The tool will paginate deeper automatically until the requested window is covered (or `maxLogs` is reached). For RANKED questions ('what was my best workout', 'longest session ever', 'highest-volume day'), set `rankBy` ('volume' | 'duration') and `topN`. The tool then sweeps the window, computes the metric per log, and returns the top N logs sorted by that metric instead of newest-first. Returns logs with id, title, date, exercise count, and a per-exercise summary of sets/reps/weight; when ranking, each log also carries totalVolumeKg/totalVolumeDisplay and durationSeconds. Returns an error if the user is not signed in.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Page of recent logs to read, starting at 1. Date-window scans ignore this value."
},
"topN": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Number of highest-ranked logs to return when ranking by volume or duration."
},
"since": {
"type": "string",
"description": "Optional ISO-8601 lower-bound: only logs with createdAt >= since are returned."
},
"until": {
"type": "string",
"description": "Optional ISO-8601 upper-bound: only logs with createdAt <= until are returned."
},
"rankBy": {
"enum": [
"recent",
"volume",
"duration"
],
"type": "string",
"description": "How to order results. 'recent' (default) is newest-first by createdAt. 'volume' ranks by total tonnage (sum of weight×reps across all sets). 'duration' ranks by `WorkoutLogDuration` (seconds). Set this for 'best workout', 'highest-volume day', 'longest session' questions."
},
"maxLogs": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Maximum number of logs to scan in a date window."
},
"pageSize": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Number of logs per page, or the result cap for a date-filtered request."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Get the CURRENT user's workout-program enrollments and progress. Use whenever the user asks about programs they are following: 'what programs am I on', 'what's my next workout', 'how far through PPL am I', 'show my active programs'. Returns each enrolled program's title, engagement status, last completed day, remaining workouts, the next scheduled workout id (if any), and the program id. Errors if the user is not signed in.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_my_workout_programs",
"title": "Your programs",
"description": "Get the CURRENT user's workout-program enrollments and progress. Use whenever the user asks about programs they are following: 'what programs am I on', 'what's my next workout', 'how far through PPL am I', 'show my active programs'. Returns each enrolled program's title, engagement status, last completed day, remaining workouts, the next scheduled workout id (if any), and the program id. Errors if the user is not signed in.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Get the CURRENT user's recorded history for a SINGLE exercise (by exerciseCode), plus their personal best. Use when the user asks 'show my bench press progression', 'how heavy have I squatted', 'what's my best deadlift', 'when did I last do pull-ups'. You usually want to call search_exercises FIRST to resolve a name to a code. For ANY HISTORICAL TIMEFRAME ('my bench in 2024', 'squats last summer'), pass `since` and/or `until` (ISO-8601). The tool sweeps deeper pages automatically and returns only sessions in the window: DO NOT page manually. Use `maxSessions` to cap the scan. Returns history items (workout id, completed-at, sets) sorted newest-first by default, plus a personalBest summary if any has been recorded. Requires sign-in.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
exerciseCode
Uppercase exercise code, e.g. 'BARBELL-BENCH-PRESS'. Use search_exercises if unsure.
Clear enough to supply this argument.
page
Page of recent exercise sessions, starting at 1. Date-window scans ignore this value.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
pageSize
Number of exercise sessions per page.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
since
Optional ISO-8601 lower bound: only sessions completed at or after this time are returned.
Clear enough to supply this argument.
until
Optional ISO-8601 upper bound: only sessions completed at or before this time are returned.
Clear enough to supply this argument.
maxSessions
Maximum number of sessions returned from a date-window scan.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_my_exercise_history",
"title": "Read exercise history",
"description": "Get the CURRENT user's recorded history for a SINGLE exercise (by exerciseCode), plus their personal best. Use when the user asks 'show my bench press progression', 'how heavy have I squatted', 'what's my best deadlift', 'when did I last do pull-ups'. You usually want to call search_exercises FIRST to resolve a name to a code. For ANY HISTORICAL TIMEFRAME ('my bench in 2024', 'squats last summer'), pass `since` and/or `until` (ISO-8601). The tool sweeps deeper pages automatically and returns only sessions in the window: DO NOT page manually. Use `maxSessions` to cap the scan. Returns history items (workout id, completed-at, sets) sorted newest-first by default, plus a personalBest summary if any has been recorded. Requires sign-in.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"exerciseCode"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Page of recent exercise sessions, starting at 1. Date-window scans ignore this value."
},
"since": {
"type": "string",
"description": "Optional ISO-8601 lower bound: only sessions completed at or after this time are returned."
},
"until": {
"type": "string",
"description": "Optional ISO-8601 upper bound: only sessions completed at or before this time are returned."
},
"pageSize": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Number of exercise sessions per page."
},
"maxSessions": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Maximum number of sessions returned from a date-window scan."
},
"exerciseCode": {
"type": "string",
"description": "Uppercase exercise code, e.g. 'BARBELL-BENCH-PRESS'. Use search_exercises if unsure."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Search the workout-program catalog. Returns paginated programs with title, description, total weeks/days, rating, creator, and a public link. Use when the user asks about available programs ('show me programs for hypertrophy', 'find a beginner program', 'what programs do you have'). Optional filters: search keyword, creatorId.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Explain what happens when this optional value is omitted.
search
Optional keyword to filter program titles/descriptions
Clear enough to supply this argument.
creatorId
Creator profile ID, such as creatorProfile.creatorProfileId from get_my_profile for your own programs. Omit if only a creator name is known.
Clear enough to supply this argument.
page
Page of matching programs to read, starting at 1.
Clear enough to supply this argument.
pageSize
Number of matching programs per page.
Explain what happens when this optional value is omitted.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "search_workout_programs",
"title": "Find a program",
"description": "Search the workout-program catalog. Returns paginated programs with title, description, total weeks/days, rating, creator, and a public link. Use when the user asks about available programs ('show me programs for hypertrophy', 'find a beginner program', 'what programs do you have'). Optional filters: search keyword, creatorId.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Page of matching programs to read, starting at 1."
},
"search": {
"type": "string",
"description": "Optional keyword to filter program titles/descriptions"
},
"pageSize": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Number of matching programs per page."
},
"creatorId": {
"type": "string",
"description": "Creator profile ID, such as creatorProfile.creatorProfileId from get_my_profile for your own programs. Omit if only a creator name is known."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Get a workout program (template) by id, including its weeks and days. Use after search_workout_programs or get_my_workout_programs to dig into a specific program. Set includeData=false for a lightweight summary that omits per-day workout content.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
workoutProgramId
Program ID returned by search_workout_programs or get_my_workout_programs.
Clear enough to supply this argument.
includeData
Include the full week/day breakdown (default true).
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_workout_program",
"title": "Read a workout program",
"description": "Get a workout program (template) by id, including its weeks and days. Use after search_workout_programs or get_my_workout_programs to dig into a specific program. Set includeData=false for a lightweight summary that omits per-day workout content.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"workoutProgramId"
],
"properties": {
"includeData": {
"type": "boolean",
"description": "Include the full week/day breakdown (default true)."
},
"workoutProgramId": {
"type": "string",
"description": "Program ID returned by search_workout_programs or get_my_workout_programs."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Update the CURRENT user's enrollment on a workout program. Use to start, abandon, or complete a program: 'start this program', 'I'm done with PPL', 'abandon the cut program'. Requires the program id (use search_workout_programs to find it). Action must be one of: start | abandon | complete. This only changes the user's enrollment status; it never charges, purchases or subscribes to anything. Returns the program ID, enrollment status, next workout, remaining workouts, progress and start/end dates.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
workoutProgramId
Program ID returned by search_workout_programs or get_my_workout_programs.
Clear enough to supply this argument.
action
Enrollment transition requested by the user. Changes program progress, without purchasing a subscription.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "set_my_program_engagement",
"title": "Start or finish a program",
"description": "Update the CURRENT user's enrollment on a workout program. Use to start, abandon, or complete a program: 'start this program', 'I'm done with PPL', 'abandon the cut program'. Requires the program id (use search_workout_programs to find it). Action must be one of: start | abandon | complete. This only changes the user's enrollment status; it never charges, purchases or subscribes to anything. Returns the program ID, enrollment status, next workout, remaining workouts, progress and start/end dates.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"workoutProgramId",
"action"
],
"properties": {
"action": {
"enum": [
"start",
"abandon",
"complete"
],
"type": "string",
"description": "Enrollment transition requested by the user. Changes program progress, without purchasing a subscription."
},
"workoutProgramId": {
"type": "string",
"description": "Program ID returned by search_workout_programs or get_my_workout_programs."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Create a brand-new multi-week/multi-day workout PROGRAM for the user and save it to their account. You write the FULL program out as plain text in `programText`: a title, then each week and day with that day's exercises and their sets × reps (add weight or RPE when relevant). Rest days can be written as 'Rest'. The text is parsed into a structured program (real exercises are matched automatically) and saved. Use this whenever the user asks you to build / create / make / design a training PROGRAM, a multi-week or multi-day plan (PPL, full-body split, 5x5, a cut block, etc.). For a single one-off workout use generate_workout instead. If the user pasted their own program, pass it through verbatim.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
programText
The complete program written as plain text: a title line, then each week and day with the day's exercises and sets × reps (e.g. 'Week 1, Day 1 Push: Barbell Bench Press 4x6, Overhead Press 3x8 ...'). Include rest days. Be specific and complete, this is what gets parsed.
Clear enough to supply this argument.
programTitle
Optional explicit program title. If omitted, a title is taken/derived from the text.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_workout_program",
"title": "Create a workout program",
"description": "Create a brand-new multi-week/multi-day workout PROGRAM for the user and save it to their account. You write the FULL program out as plain text in `programText`: a title, then each week and day with that day's exercises and their sets × reps (add weight or RPE when relevant). Rest days can be written as 'Rest'. The text is parsed into a structured program (real exercises are matched automatically) and saved. Use this whenever the user asks you to build / create / make / design a training PROGRAM, a multi-week or multi-day plan (PPL, full-body split, 5x5, a cut block, etc.). For a single one-off workout use generate_workout instead. If the user pasted their own program, pass it through verbatim.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"programText"
],
"properties": {
"programText": {
"type": "string",
"description": "The complete program written as plain text: a title line, then each week and day with the day's exercises and sets × reps (e.g. 'Week 1, Day 1 Push: Barbell Bench Press 4x6, Overhead Press 3x8 ...'). Include rest days. Be specific and complete, this is what gets parsed."
},
"programTitle": {
"type": "string",
"description": "Optional explicit program title. If omitted, a title is taken/derived from the text."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Generate a real, road-and-path-snapped ROUTE (a plannable run / ride / walk / hike path) starting and ending at the user's location, and save it to their Routes tab. Use when the user asks you to build / make / plan a route, a running loop, a bike ride, etc. Use startLat/startLng from the app-data block's current location when present, or coordinates the user explicitly gives; NEVER guess them. If neither is available, OMIT startLat/startLng and the route starts from the user's last known training location (the start of their most recent GPS activity or saved route). Before calling, make sure you know the activity type and the distance they want (ask if they haven't said). The generated route follows actual streets and paths and lands close to the requested distance.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
startLat
Start latitude. Only pass a real value (app-data current location or user-given); omit to fall back to the user's last known training location.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
startLng
Start longitude. Only pass a real value; omit to fall back to the user's last known training location.
Clear enough to supply this argument.
distanceKm
Requested route length in kilometers, including the return leg for a loop.
Clear enough to supply this argument.
activityType
What the route is for. 'ride' uses cycling roads; the rest use walking/running paths.
Clear enough to supply this argument.
routeShape
loop = a circuit back to the start (default); out_and_back = straight out to a turnaround point and back the same way.
Clear enough to supply this argument.
direction
Optional compass direction to head in. Omit for a sensible random direction.
Clear enough to supply this argument.
name
Short friendly route name, e.g. '5K Morning Loop'. Omit to auto-name.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"timestamp"
],
"properties": {
"name": {
"type": "string",
"description": "Saved route name."
},
"error": {
"type": "boolean",
"description": "Whether route creation failed."
},
"isLoop": {
"type": "boolean",
"description": "Whether the route returns to its starting point."
},
"routeId": {
"type": "string",
"description": "Saved route ID for opening the route in JustGains."
},
"timestamp": {
"type": "string",
"description": "ISO-8601 time the connector produced the result."
},
"distanceKm": {
"type": "number",
"description": "Actual route length in kilometers."
},
"activityType": {
"type": "string",
"description": "Activity for which the route was planned."
},
"errorMessage": {
"type": "string",
"description": "Reason route creation failed."
},
"locationSource": {
"type": "string",
"description": "How the starting location was chosen."
},
"estimatedMinutes": {
"type": "number",
"description": "Estimated duration in minutes, when available."
},
"measurementSystem": {
"type": "string",
"description": "Display unit preference for the route card."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "create_route",
"title": "Plan a route",
"description": "Generate a real, road-and-path-snapped ROUTE (a plannable run / ride / walk / hike path) starting and ending at the user's location, and save it to their Routes tab. Use when the user asks you to build / make / plan a route, a running loop, a bike ride, etc. Use startLat/startLng from the app-data block's current location when present, or coordinates the user explicitly gives; NEVER guess them. If neither is available, OMIT startLat/startLng and the route starts from the user's last known training location (the start of their most recent GPS activity or saved route). Before calling, make sure you know the activity type and the distance they want (ask if they haven't said). The generated route follows actual streets and paths and lands close to the requested distance.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"distanceKm",
"activityType"
],
"properties": {
"name": {
"type": "string",
"description": "Short friendly route name, e.g. '5K Morning Loop'. Omit to auto-name."
},
"startLat": {
"type": "number",
"description": "Start latitude. Only pass a real value (app-data current location or user-given); omit to fall back to the user's last known training location."
},
"startLng": {
"type": "number",
"description": "Start longitude. Only pass a real value; omit to fall back to the user's last known training location."
},
"direction": {
"enum": [
"north",
"northeast",
"east",
"southeast",
"south",
"southwest",
"west",
"northwest"
],
"type": "string",
"description": "Optional compass direction to head in. Omit for a sensible random direction."
},
"distanceKm": {
"type": "number",
"description": "Requested route length in kilometers, including the return leg for a loop."
},
"routeShape": {
"enum": [
"loop",
"out_and_back"
],
"type": "string",
"description": "loop = a circuit back to the start (default); out_and_back = straight out to a turnaround point and back the same way."
},
"activityType": {
"enum": [
"run",
"ride",
"walk",
"hike"
],
"type": "string",
"description": "What the route is for. 'ride' uses cycling roads; the rest use walking/running paths."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"timestamp"
],
"properties": {
"name": {
"type": "string",
"description": "Saved route name."
},
"error": {
"type": "boolean",
"description": "Whether route creation failed."
},
"isLoop": {
"type": "boolean",
"description": "Whether the route returns to its starting point."
},
"routeId": {
"type": "string",
"description": "Saved route ID for opening the route in JustGains."
},
"timestamp": {
"type": "string",
"description": "ISO-8601 time the connector produced the result."
},
"distanceKm": {
"type": "number",
"description": "Actual route length in kilometers."
},
"activityType": {
"type": "string",
"description": "Activity for which the route was planned."
},
"errorMessage": {
"type": "string",
"description": "Reason route creation failed."
},
"locationSource": {
"type": "string",
"description": "How the starting location was chosen."
},
"estimatedMinutes": {
"type": "number",
"description": "Estimated duration in minutes, when available."
},
"measurementSystem": {
"type": "string",
"description": "Display unit preference for the route card."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Get the CURRENT user's bodyweight log (entries plus summary: current, lowest, highest). Use whenever the user asks about their bodyweight: 'what do I weigh now', 'how much have I lost', 'show my weight trend', 'when did I last weigh in', 'what was my lightest'. For ANY HISTORICAL TIMEFRAME ('what did I weigh in March', 'last summer', 'between Jan 1 and Feb 14'), pass `since` and/or `until` (ISO-8601). Summary stats (current/lowest/highest) are returned for BOTH the full history and, when a window is set, the windowed slice. Optional `limit` truncates the entry list. Requires sign-in.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Number of bodyweight entries to return.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
since
Inclusive timestamp at the start of the bodyweight history window, in ISO-8601 form.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
until
Optional ISO-8601 upper bound: only entries recorded at or before this time are included.
Explain what happens when this optional value is omitted.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_my_weight_history",
"title": "Your bodyweight",
"description": "Get the CURRENT user's bodyweight log (entries plus summary: current, lowest, highest). Use whenever the user asks about their bodyweight: 'what do I weigh now', 'how much have I lost', 'show my weight trend', 'when did I last weigh in', 'what was my lightest'. For ANY HISTORICAL TIMEFRAME ('what did I weigh in March', 'last summer', 'between Jan 1 and Feb 14'), pass `since` and/or `until` (ISO-8601). Summary stats (current/lowest/highest) are returned for BOTH the full history and, when a window is set, the windowed slice. Optional `limit` truncates the entry list. Requires sign-in.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"limit": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Number of bodyweight entries to return."
},
"since": {
"type": "string",
"description": "Inclusive timestamp at the start of the bodyweight history window, in ISO-8601 form."
},
"until": {
"type": "string",
"description": "Optional ISO-8601 upper bound: only entries recorded at or before this time are included."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description87/100
Record a new bodyweight entry for the CURRENT user. Pass `weightKg` (kilograms) OR `weightLbs` (pounds), the tool converts lbs → kg before storage. If the user spoke in pounds, prefer `weightLbs` so the round-trip is exact. `recordedAt` is optional ISO-8601 (defaults to now). Valid stored range: 25kg–500kg (≈55–1100 lbs); the API rejects values outside this.
The description explains the capability, when to use it, and what to expect.
Inputs83/100
Input documentation gives an agent enough context to populate the arguments.
weightKg
Bodyweight in kilograms. Supply this or weightLbs according to the user’s stated unit.
Clear enough to supply this argument.
weightLbs
Bodyweight in pounds. Supply this or weightKg according to the user’s stated unit.
Clear enough to supply this argument.
recordedAt
Optional ISO-8601 timestamp. Defaults to now (UTC).
Clear enough to supply this argument.
notes
Optional notes the user mentioned (mood, time of day, etc.).
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "log_my_weight",
"title": "Log bodyweight",
"description": "Record a new bodyweight entry for the CURRENT user. Pass `weightKg` (kilograms) OR `weightLbs` (pounds), the tool converts lbs → kg before storage. If the user spoke in pounds, prefer `weightLbs` so the round-trip is exact. `recordedAt` is optional ISO-8601 (defaults to now). Valid stored range: 25kg–500kg (≈55–1100 lbs); the API rejects values outside this.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"notes": {
"type": "string",
"description": "Optional notes the user mentioned (mood, time of day, etc.)."
},
"weightKg": {
"type": "number",
"description": "Bodyweight in kilograms. Supply this or weightLbs according to the user’s stated unit."
},
"weightLbs": {
"type": "number",
"description": "Bodyweight in pounds. Supply this or weightKg according to the user’s stated unit."
},
"recordedAt": {
"type": "string",
"description": "Optional ISO-8601 timestamp. Defaults to now (UTC)."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Read the CURRENT user's food diary, daily totals, targets, local date/timezone and last 30 days of foods (up to 100 entries). Call when the user wants to see their diary, when a request depends on a past day ('same as yesterday'), or to find entries to correct or remove that no recent food result returned. Routine logging does not need it: log_my_food resolves the local date and checks recent entries on the backend. Never infer that a planned meal was eaten.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
entryDate
YYYY-MM-DD local diary date; defaults to the user's today.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"success"
],
"properties": {
"data": {
"type": "object",
"properties": {
"day": {
"type": "object",
"description": "Diary day containing date, meal slots and entries, nutrition totals and targets.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"entries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Entries saved or corrected by this meal request."
},
"message": {
"type": "string",
"description": "Human-readable outcome of the food action."
},
"removed": {
"type": "boolean",
"description": "Whether diary entries were removed."
},
"updated": {
"type": "boolean",
"description": "Whether existing entries were corrected."
},
"replayed": {
"type": "boolean",
"description": "Whether this request had already been applied."
},
"timezone": {
"type": "string",
"description": "User’s timezone, when reading the diary."
},
"localDate": {
"type": "string",
"description": "Current local diary date in YYYY-MM-DD form, when reading the diary."
},
"recentEntries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Recent saved foods for explicit repeats."
},
"removedEntries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Entries removed by the requested deletion."
}
},
"description": "Food result returned by the API, including portions and nutrition when available.",
"additionalProperties": {}
},
"error": {
"type": "string",
"description": "User-facing explanation when the food action failed."
},
"success": {
"type": "boolean",
"description": "Whether the food action succeeded; false means the error must be surfaced."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "get_my_food_diary",
"title": "Read food diary",
"description": "Read the CURRENT user's food diary, daily totals, targets, local date/timezone and last 30 days of foods (up to 100 entries). Call when the user wants to see their diary, when a request depends on a past day ('same as yesterday'), or to find entries to correct or remove that no recent food result returned. Routine logging does not need it: log_my_food resolves the local date and checks recent entries on the backend. Never infer that a planned meal was eaten.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"entryDate": {
"type": "string",
"description": "YYYY-MM-DD local diary date; defaults to the user's today."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"success"
],
"properties": {
"data": {
"type": "object",
"properties": {
"day": {
"type": "object",
"description": "Diary day containing date, meal slots and entries, nutrition totals and targets.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"entries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Entries saved or corrected by this meal request."
},
"message": {
"type": "string",
"description": "Human-readable outcome of the food action."
},
"removed": {
"type": "boolean",
"description": "Whether diary entries were removed."
},
"updated": {
"type": "boolean",
"description": "Whether existing entries were corrected."
},
"replayed": {
"type": "boolean",
"description": "Whether this request had already been applied."
},
"timezone": {
"type": "string",
"description": "User’s timezone, when reading the diary."
},
"localDate": {
"type": "string",
"description": "Current local diary date in YYYY-MM-DD form, when reading the diary."
},
"recentEntries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Recent saved foods for explicit repeats."
},
"removedEntries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Entries removed by the requested deletion."
}
},
"description": "Food result returned by the API, including portions and nutrition when available.",
"additionalProperties": {}
},
"error": {
"type": "string",
"description": "User-facing explanation when the food action failed."
},
"success": {
"type": "boolean",
"description": "Whether the food action succeeded; false means the error must be surfaced."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Search the cached food catalog and matching recent diary entries. This never waits on an external nutrition provider. Use only when the user asks to find or compare foods. For logging, call log_my_food directly with estimates instead. Results contain up to five identity-checked candidates and three possible variants; missing results do not prevent logging an estimate. Preserve brand and raw/cooked preparation.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query
Food name to find or compare, including brand and preparation when known.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Log foods the CURRENT user actually ate in one call. Call this directly: do not search_foods, browse, research nutrition, or read the diary first. Send every food/drink with quantityGrams and a quick estimatedMacros fallback for the whole portion; round estimates rather than researching exact numbers. The API checks recent foods and the cached catalog, prefers reliable nutrition, and labels estimate fallbacks. Preserve brand and raw/cooked preparation. Use servingQuantity/servingUnit for counts and portionEstimated=true for guessed weights. Briefly disclose assumptions; do not ask for missing flavor or grams. Use a new requestId per meal and keep it unchanged on retries. Follow-up corrections reuse diaryEntryId and expectedUpdatedAt from the last result, keep the serving count, and omit grams to recalculate a corrected catalog serving. Only read the diary for a past-day reference, an explicit repeat, or a correction/removal whose ID is unavailable. Use recentEntryId only for an explicit repeat. After success, give a short confirmation; do not call another tool to verify the save or repeat the card. Never log plans or hypothetical meals. Returns saved entries, updated/replayed flags, the diary day and daily totals; the card confirms the saved meal, not device sync.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
requestId
Meal request identifier generated for this save. Reuse it on retries to prevent duplicate logging.
Clear enough to supply this argument.
entryDate
Local diary date in YYYY-MM-DD form; defaults to the user’s today.
Clear enough to supply this argument.
mealSlot
Meal of the day to which these eaten foods belong.
Clear enough to supply this argument.
loggedAt
When the food was eaten, expressed as an ISO-8601 timestamp with its UTC offset.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
items › items › diaryEntryId
For a correction only: the existing diary entry to replace, never a new UUID. Omit for a new food.
Clear enough to supply this argument.
items › items › expectedUpdatedAt
Required with diaryEntryId: copy updatedAt (or createdAt when updatedAt is absent) from a fresh diary read. A stale correction fails without adding a duplicate; reread before retrying.
Clear enough to supply this argument.
items › items › assumptionNote
Assumed variety, brand or serving weight, shown with the saved food. Omit when confirmed.
Clear enough to supply this argument.
items › items › name
Food identity including preparation, e.g. cooked brown rice.
Clear enough to supply this argument.
items › items › brand
Brand stated by the user, or an assumed brand disclosed in assumptionNote.
Clear enough to supply this argument.
items › items › quantityGrams
Total weight of the eaten portion in grams. Mark guessed weights with portionEstimated; a known catalog serving can replace them.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
items › items › servingQuantity
Number of portions in servingUnit, such as 2 slices or 1 bottle.
Clear enough to supply this argument.
items › items › servingUnit
Catalog serving label, or a display unit when grams are supplied.
Clear enough to supply this argument.
items › items › recentEntryId
An entry from the user's recent diary when they explicitly mean the same food/portion. Omit grams to reuse its portion.
Clear enough to supply this argument.
items › items › portionEstimated
Whether the portion weight was estimated rather than supplied by the user.
Clear enough to supply this argument.
items › items › estimatedMacros › kcal
Estimated energy in kilocalories for the entire eaten portion, not per 100 grams.
Clear enough to supply this argument.
items › items › estimatedMacros › proteinG
Estimated grams of protein in the entire eaten portion.
Clear enough to supply this argument.
items › items › estimatedMacros › carbG
Estimated grams of carbohydrate in the entire eaten portion.
Clear enough to supply this argument.
items › items › estimatedMacros › fatG
Estimated grams of fat in the entire eaten portion.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"success"
],
"properties": {
"data": {
"type": "object",
"properties": {
"day": {
"type": "object",
"description": "Diary day containing date, meal slots and entries, nutrition totals and targets.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"entries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Entries saved or corrected by this meal request."
},
"message": {
"type": "string",
"description": "Human-readable outcome of the food action."
},
"removed": {
"type": "boolean",
"description": "Whether diary entries were removed."
},
"updated": {
"type": "boolean",
"description": "Whether existing entries were corrected."
},
"replayed": {
"type": "boolean",
"description": "Whether this request had already been applied."
},
"timezone": {
"type": "string",
"description": "User’s timezone, when reading the diary."
},
"localDate": {
"type": "string",
"description": "Current local diary date in YYYY-MM-DD form, when reading the diary."
},
"recentEntries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Recent saved foods for explicit repeats."
},
"removedEntries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Entries removed by the requested deletion."
}
},
"description": "Food result returned by the API, including portions and nutrition when available.",
"additionalProperties": {}
},
"error": {
"type": "string",
"description": "User-facing explanation when the food action failed."
},
"success": {
"type": "boolean",
"description": "Whether the food action succeeded; false means the error must be surfaced."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "log_my_food",
"title": "Log food",
"description": "Log foods the CURRENT user actually ate in one call. Call this directly: do not search_foods, browse, research nutrition, or read the diary first. Send every food/drink with quantityGrams and a quick estimatedMacros fallback for the whole portion; round estimates rather than researching exact numbers. The API checks recent foods and the cached catalog, prefers reliable nutrition, and labels estimate fallbacks. Preserve brand and raw/cooked preparation. Use servingQuantity/servingUnit for counts and portionEstimated=true for guessed weights. Briefly disclose assumptions; do not ask for missing flavor or grams. Use a new requestId per meal and keep it unchanged on retries. Follow-up corrections reuse diaryEntryId and expectedUpdatedAt from the last result, keep the serving count, and omit grams to recalculate a corrected catalog serving. Only read the diary for a past-day reference, an explicit repeat, or a correction/removal whose ID is unavailable. Use recentEntryId only for an explicit repeat. After success, give a short confirmation; do not call another tool to verify the save or repeat the card. Never log plans or hypothetical meals. Returns saved entries, updated/replayed flags, the diary day and daily totals; the card confirms the saved meal, not device sync.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"requestId",
"mealSlot",
"items"
],
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Food identity including preparation, e.g. cooked brown rice."
},
"brand": {
"type": "string",
"description": "Brand stated by the user, or an assumed brand disclosed in assumptionNote."
},
"servingUnit": {
"type": "string",
"description": "Catalog serving label, or a display unit when grams are supplied."
},
"diaryEntryId": {
"type": "string",
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
"description": "For a correction only: the existing diary entry to replace, never a new UUID. Omit for a new food."
},
"quantityGrams": {
"type": "number",
"maximum": 10000,
"description": "Total weight of the eaten portion in grams. Mark guessed weights with portionEstimated; a known catalog serving can replace them.",
"exclusiveMinimum": 0
},
"recentEntryId": {
"type": "string",
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
"description": "An entry from the user's recent diary when they explicitly mean the same food/portion. Omit grams to reuse its portion."
},
"assumptionNote": {
"type": "string",
"maxLength": 500,
"description": "Assumed variety, brand or serving weight, shown with the saved food. Omit when confirmed."
},
"estimatedMacros": {
"type": "object",
"required": [
"kcal",
"proteinG",
"carbG",
"fatG"
],
"properties": {
"fatG": {
"type": "number",
"minimum": 0,
"description": "Estimated grams of fat in the entire eaten portion."
},
"kcal": {
"type": "number",
"minimum": 0,
"description": "Estimated energy in kilocalories for the entire eaten portion, not per 100 grams."
},
"carbG": {
"type": "number",
"minimum": 0,
"description": "Estimated grams of carbohydrate in the entire eaten portion."
},
"proteinG": {
"type": "number",
"minimum": 0,
"description": "Estimated grams of protein in the entire eaten portion."
}
},
"description": "Estimated nutrition totals for the whole portion (not per 100g). Reliable catalog values take precedence when available; otherwise these values are saved and marked as estimated.",
"additionalProperties": {}
},
"servingQuantity": {
"type": "number",
"maximum": 100,
"description": "Number of portions in servingUnit, such as 2 slices or 1 bottle.",
"exclusiveMinimum": 0
},
"portionEstimated": {
"type": "boolean",
"description": "Whether the portion weight was estimated rather than supplied by the user."
},
"expectedUpdatedAt": {
"type": "string",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
"description": "Required with diaryEntryId: copy updatedAt (or createdAt when updatedAt is absent) from a fresh diary read. A stale correction fails without adding a duplicate; reread before retrying."
}
},
"additionalProperties": {}
},
"maxItems": 30,
"minItems": 1
},
"loggedAt": {
"type": "string",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
"description": "When the food was eaten, expressed as an ISO-8601 timestamp with its UTC offset."
},
"mealSlot": {
"enum": [
"BREAKFAST",
"LUNCH",
"DINNER",
"SNACK"
],
"type": "string",
"description": "Meal of the day to which these eaten foods belong."
},
"entryDate": {
"type": "string",
"description": "Local diary date in YYYY-MM-DD form; defaults to the user’s today."
},
"requestId": {
"type": "string",
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
"description": "Meal request identifier generated for this save. Reuse it on retries to prevent duplicate logging."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"success"
],
"properties": {
"data": {
"type": "object",
"properties": {
"day": {
"type": "object",
"description": "Diary day containing date, meal slots and entries, nutrition totals and targets.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"entries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Entries saved or corrected by this meal request."
},
"message": {
"type": "string",
"description": "Human-readable outcome of the food action."
},
"removed": {
"type": "boolean",
"description": "Whether diary entries were removed."
},
"updated": {
"type": "boolean",
"description": "Whether existing entries were corrected."
},
"replayed": {
"type": "boolean",
"description": "Whether this request had already been applied."
},
"timezone": {
"type": "string",
"description": "User’s timezone, when reading the diary."
},
"localDate": {
"type": "string",
"description": "Current local diary date in YYYY-MM-DD form, when reading the diary."
},
"recentEntries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Recent saved foods for explicit repeats."
},
"removedEntries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Entries removed by the requested deletion."
}
},
"description": "Food result returned by the API, including portions and nutrition when available.",
"additionalProperties": {}
},
"error": {
"type": "string",
"description": "User-facing explanation when the food action failed."
},
"success": {
"type": "boolean",
"description": "Whether the food action succeeded; false means the error must be surfaced."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Remove foods the CURRENT user asks to delete from their diary, e.g. 'remove those crackers', 'I did not eat that', or 'delete breakfast'. Identify the exact saved entries from the user's request and the latest food result (log, removal or diary read); call get_my_food_diary for the relevant day only if no recent result has them. Pass their diaryEntryId and expectedUpdatedAt exactly as that result gives them. Remove only requested entries; ask which one if the target is ambiguous. For an entire meal, pass all entries in that meal, not the whole day. Removing one pack from a two-pack entry is a portion correction with log_my_food, not removal of the entire row. The API removes the batch atomically, updates day totals and syncs deletion to mobile. Repeating the same IDs is safe. This removes diary entries, never catalog foods. Do not call unless the user requested removal.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
items › items › diaryEntryId
Exact saved entry ID from get_my_food_diary.
Clear enough to supply this argument.
items › items › expectedUpdatedAt
Copy updatedAt, or createdAt if absent, from the latest diary read.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"success"
],
"properties": {
"data": {
"type": "object",
"properties": {
"day": {
"type": "object",
"description": "Diary day containing date, meal slots and entries, nutrition totals and targets.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"entries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Entries saved or corrected by this meal request."
},
"message": {
"type": "string",
"description": "Human-readable outcome of the food action."
},
"removed": {
"type": "boolean",
"description": "Whether diary entries were removed."
},
"updated": {
"type": "boolean",
"description": "Whether existing entries were corrected."
},
"replayed": {
"type": "boolean",
"description": "Whether this request had already been applied."
},
"timezone": {
"type": "string",
"description": "User’s timezone, when reading the diary."
},
"localDate": {
"type": "string",
"description": "Current local diary date in YYYY-MM-DD form, when reading the diary."
},
"recentEntries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Recent saved foods for explicit repeats."
},
"removedEntries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Entries removed by the requested deletion."
}
},
"description": "Food result returned by the API, including portions and nutrition when available.",
"additionalProperties": {}
},
"error": {
"type": "string",
"description": "User-facing explanation when the food action failed."
},
"success": {
"type": "boolean",
"description": "Whether the food action succeeded; false means the error must be surfaced."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "remove_my_food",
"title": "Remove food",
"description": "Remove foods the CURRENT user asks to delete from their diary, e.g. 'remove those crackers', 'I did not eat that', or 'delete breakfast'. Identify the exact saved entries from the user's request and the latest food result (log, removal or diary read); call get_my_food_diary for the relevant day only if no recent result has them. Pass their diaryEntryId and expectedUpdatedAt exactly as that result gives them. Remove only requested entries; ask which one if the target is ambiguous. For an entire meal, pass all entries in that meal, not the whole day. Removing one pack from a two-pack entry is a portion correction with log_my_food, not removal of the entire row. The API removes the batch atomically, updates day totals and syncs deletion to mobile. Repeating the same IDs is safe. This removes diary entries, never catalog foods. Do not call unless the user requested removal.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"items"
],
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"required": [
"diaryEntryId",
"expectedUpdatedAt"
],
"properties": {
"diaryEntryId": {
"type": "string",
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
"description": "Exact saved entry ID from get_my_food_diary."
},
"expectedUpdatedAt": {
"type": "string",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
"description": "Copy updatedAt, or createdAt if absent, from the latest diary read."
}
},
"additionalProperties": {}
},
"maxItems": 30,
"minItems": 1
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"success"
],
"properties": {
"data": {
"type": "object",
"properties": {
"day": {
"type": "object",
"description": "Diary day containing date, meal slots and entries, nutrition totals and targets.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"entries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Entries saved or corrected by this meal request."
},
"message": {
"type": "string",
"description": "Human-readable outcome of the food action."
},
"removed": {
"type": "boolean",
"description": "Whether diary entries were removed."
},
"updated": {
"type": "boolean",
"description": "Whether existing entries were corrected."
},
"replayed": {
"type": "boolean",
"description": "Whether this request had already been applied."
},
"timezone": {
"type": "string",
"description": "User’s timezone, when reading the diary."
},
"localDate": {
"type": "string",
"description": "Current local diary date in YYYY-MM-DD form, when reading the diary."
},
"recentEntries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Recent saved foods for explicit repeats."
},
"removedEntries": {
"type": "array",
"items": {
"type": "object",
"description": "Saved diary entry, with its ID, timestamps, portion, macroSnapshot and food artwork.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Entries removed by the requested deletion."
}
},
"description": "Food result returned by the API, including portions and nutrition when available.",
"additionalProperties": {}
},
"error": {
"type": "string",
"description": "User-facing explanation when the food action failed."
},
"success": {
"type": "boolean",
"description": "Whether the food action succeeded; false means the error must be surfaced."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Fetch the CURRENT user's full profile snapshot: name, email, bio, measurement system, timezone, plus private meta (age/birth date, height, gender, experience level, fitness goals, injury tracking, baseline weight). Use whenever the user asks 'what's my profile', 'how old am I', 'what's my height', 'what experience level am I set as', 'what goals do I have'. Pair with `update_my_profile` if they want to change any of these.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_my_profile",
"title": "Your profile",
"description": "Fetch the CURRENT user's full profile snapshot: name, email, bio, measurement system, timezone, plus private meta (age/birth date, height, gender, experience level, fitness goals, injury tracking, baseline weight). Use whenever the user asks 'what's my profile', 'how old am I', 'what's my height', 'what experience level am I set as', 'what goals do I have'. Pair with `update_my_profile` if they want to change any of these.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description90/100
Patch the CURRENT user's profile. Only the fields you supply are changed. Top-level: bio, measurementSystem ('metric' | 'imperial'), userTimezone (IANA), autoStopAbandonedWorkoutsSeconds (0–86400). Private meta (under privateMeta.* keys): birthDate (ISO-8601), heightCm, gender ('Male'|'Female'|'MTF'|'FTM'), experienceLevel ('Beginner'|'Intermediate'|'Advanced'), fitnessGoals (string array). Use when the user asks to change any of these. Confirm before destructive replacements (e.g., overwriting fitnessGoals).
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
bio
Public biography shown on the user’s creator profile.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
measurementSystem
Preferred unit system for displaying measurements.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
userTimezone
IANA timezone used for the user’s local dates, for example America/New_York.
Clear enough to supply this argument.
autoStopAbandonedWorkoutsSeconds
Idle time in seconds used to automatically stop an abandoned workout.
Resolve the mismatch between this description and its schema constraints.
privateMeta › birthDate
User’s birth date in ISO-8601 form.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
privateMeta › heightCm
Height in cm.
Clear enough to supply this argument.
privateMeta › gender
User’s self-reported gender for their private profile.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
privateMeta › experienceLevel
User’s self-reported training experience.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
privateMeta › fitnessGoals
Fitness goals that replace the previously saved goals. Confirm a replacement with the user.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Get the CURRENT user's recovery analytics: last workout date, days since last workout, and per-muscle-group weekly target / completed set counts / target percentage / last-worked date. Use for 'am I recovered enough to train chest', 'what muscles am I behind on', 'have I hit my weekly back volume', 'when did I last train shoulders'. For HISTORICAL questions ('how was my recovery the week of June 1, 2024'), pass `asOfDate` (ISO-8601). The whole calculation anchors to that date, week boundaries, days-since-last-workout, and recency buckets all shift back accordingly.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
asOfDate
Optional ISO-8601 anchor date: recovery data is computed as if 'now' were this date. Use for retrospective recovery questions like 'how was my recovery during the week of June 1, 2024'.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_my_recovery_analytics",
"title": "Read muscle recovery",
"description": "Get the CURRENT user's recovery analytics: last workout date, days since last workout, and per-muscle-group weekly target / completed set counts / target percentage / last-worked date. Use for 'am I recovered enough to train chest', 'what muscles am I behind on', 'have I hit my weekly back volume', 'when did I last train shoulders'. For HISTORICAL questions ('how was my recovery the week of June 1, 2024'), pass `asOfDate` (ISO-8601). The whole calculation anchors to that date, week boundaries, days-since-last-workout, and recency buckets all shift back accordingly.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"asOfDate": {
"type": "string",
"description": "Optional ISO-8601 anchor date: recovery data is computed as if 'now' were this date. Use for retrospective recovery questions like 'how was my recovery during the week of June 1, 2024'."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Bundle a one-call snapshot of the CURRENT user's recent training: count of workout logs in the last `days` (default 7), per-muscle-group recovery data, weight delta vs `days` ago, and the most recent log id. Use for "how was my week", "quick recap", "how am I doing". For HISTORICAL questions ('how was my week ending June 1, 2024'), pass `endDate` (ISO-8601), the window becomes (endDate - days, endDate) instead of anchoring to today. Saves the agent from chaining get_my_workout_logs + get_my_recovery_analytics + get_my_weight_history.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
days
Length of the training recap in days. The API defaults to 7 and clamps it to 1 through 60.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
endDate
Optional ISO-8601 anchor date, the window ends at this date instead of now. Use for retrospective summaries like 'how was my week ending Mar 30, 2024'.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "summarize_my_week",
"title": "Your training week",
"description": "Bundle a one-call snapshot of the CURRENT user's recent training: count of workout logs in the last `days` (default 7), per-muscle-group recovery data, weight delta vs `days` ago, and the most recent log id. Use for \"how was my week\", \"quick recap\", \"how am I doing\". For HISTORICAL questions ('how was my week ending June 1, 2024'), pass `endDate` (ISO-8601), the window becomes (endDate - days, endDate) instead of anchoring to today. Saves the agent from chaining get_my_workout_logs + get_my_recovery_analytics + get_my_weight_history.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"days": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Length of the training recap in days. The API defaults to 7 and clamps it to 1 through 60."
},
"endDate": {
"type": "string",
"description": "Optional ISO-8601 anchor date, the window ends at this date instead of now. Use for retrospective summaries like 'how was my week ending Mar 30, 2024'."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Analyze the CURRENT user's workout consistency over a window: longest streak, current streak (the same rule as the app: up to two rest days keep a streak alive), distinct training days, total logs, and average workouts per week. Use for 'how's my consistency', 'what's my streak', 'how often have I trained lately'. Default window 60 days, max 365. For HISTORICAL consistency questions ('how consistent was I in 2024'), pass `endDate` (ISO-8601), the window becomes (endDate: days, endDate). Current-streak only counts when the window ends today/yesterday. Returns the window, distinct training days, log count, workouts per week, current/longest streaks and most recent training day.
The description explains the capability, when to use it, and what to expect.
Inputs85/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
days
Length of the consistency analysis window in days.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
endDate
Optional ISO-8601 anchor date, the window ends here instead of today. Use for retrospective consistency like 'how consistent was I in 2024'.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "analyze_my_consistency",
"title": "Your streaks",
"description": "Analyze the CURRENT user's workout consistency over a window: longest streak, current streak (the same rule as the app: up to two rest days keep a streak alive), distinct training days, total logs, and average workouts per week. Use for 'how's my consistency', 'what's my streak', 'how often have I trained lately'. Default window 60 days, max 365. For HISTORICAL consistency questions ('how consistent was I in 2024'), pass `endDate` (ISO-8601), the window becomes (endDate: days, endDate). Current-streak only counts when the window ends today/yesterday. Returns the window, distinct training days, log count, workouts per week, current/longest streaks and most recent training day.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"days": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Length of the consistency analysis window in days."
},
"endDate": {
"type": "string",
"description": "Optional ISO-8601 anchor date, the window ends here instead of today. Use for retrospective consistency like 'how consistent was I in 2024'."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Compare the CURRENT user's last `windowDays` (default 7) against the prior `windowDays`. Use for 'am I training more than last week', 'did I lose weight faster this week', 'is this week better'. Returns workout-count delta and weight delta between the two windows. For HISTORICAL comparisons ('how did the week of June 1, 2024 compare to the week before'), pass `endDate` (ISO-8601). The current window becomes (endDate - windowDays, endDate) and the prior window slides back to match.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
windowDays
Length in days of each adjacent comparison period. The API defaults to 7 and clamps it to 1 through 30.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
endDate
Optional ISO-8601 anchor: current window ends at this date instead of now. Prior window slides back by `windowDays` accordingly.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "compare_my_weeks",
"title": "Compare your weeks",
"description": "Compare the CURRENT user's last `windowDays` (default 7) against the prior `windowDays`. Use for 'am I training more than last week', 'did I lose weight faster this week', 'is this week better'. Returns workout-count delta and weight delta between the two windows. For HISTORICAL comparisons ('how did the week of June 1, 2024 compare to the week before'), pass `endDate` (ISO-8601). The current window becomes (endDate - windowDays, endDate) and the prior window slides back to match.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"endDate": {
"type": "string",
"description": "Optional ISO-8601 anchor: current window ends at this date instead of now. Prior window slides back by `windowDays` accordingly."
},
"windowDays": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Length in days of each adjacent comparison period. The API defaults to 7 and clamps it to 1 through 30."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Cross-exercise leaderboard for the CURRENT user. Use whenever the user asks about their TOP / MOST / HEAVIEST exercises across the board: 'what's my most used exercise', 'top 3 lifts', 'heaviest exercises', 'what do I lift the most'. Scans the user's workout logs (default 365 days, capped at `maxLogsScanned`) and returns three rankings in one call: byFrequency (session + set count), byMaxWeight (peak single-set weight), and byVolume (total tonnage). Each entry includes the exerciseCode + name so the agent can drill into a specific lift via get_my_exercise_history. For HISTORICAL questions ('most-used in 2024', 'top lifts last summer'), pass `since`/`until` (ISO-8601). Use `topN` to widen/narrow each list (default 5, max 25). Requires sign-in.
The description explains the capability, when to use it, and what to expect.
Inputs80/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
topN
Number of exercises to return in each ranking.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
since
Inclusive ISO-8601 timestamp at the start of the workout-log scan.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
until
Inclusive ISO-8601 timestamp at the end of the workout-log scan.
Clear enough to supply this argument.
maxLogsScanned
Maximum number of workout logs to scan; increase for longer histories.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
lookbackDays
Days of history to scan when neither since nor until is supplied.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_my_top_exercises",
"title": "Your top lifts",
"description": "Cross-exercise leaderboard for the CURRENT user. Use whenever the user asks about their TOP / MOST / HEAVIEST exercises across the board: 'what's my most used exercise', 'top 3 lifts', 'heaviest exercises', 'what do I lift the most'. Scans the user's workout logs (default 365 days, capped at `maxLogsScanned`) and returns three rankings in one call: byFrequency (session + set count), byMaxWeight (peak single-set weight), and byVolume (total tonnage). Each entry includes the exerciseCode + name so the agent can drill into a specific lift via get_my_exercise_history. For HISTORICAL questions ('most-used in 2024', 'top lifts last summer'), pass `since`/`until` (ISO-8601). Use `topN` to widen/narrow each list (default 5, max 25). Requires sign-in.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"topN": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Number of exercises to return in each ranking."
},
"since": {
"type": "string",
"description": "Inclusive ISO-8601 timestamp at the start of the workout-log scan."
},
"until": {
"type": "string",
"description": "Inclusive ISO-8601 timestamp at the end of the workout-log scan."
},
"lookbackDays": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Days of history to scan when neither since nor until is supplied."
},
"maxLogsScanned": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Maximum number of workout logs to scan; increase for longer histories."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
Loading score analytics…
Put your MCP to the test
A few tasks worth trying with this server, chosen from its reviewed tools. These have not been run.
01Search exercisesSearch the JustGains exercise library by name (optionally filtered by muscle group or equipment).
02Search workout programsSearch the workout-program catalog.
03Find a foodSearch the cached food catalog and matching recent diary entries.
04Get workout historyList the signed-in user's most recent workouts (title, date, duration, total volume, sets, reps, exercise count).
05Get exercise detailsGet detailed information about a specific exercise by its code.
Want to run these tasks against your MCP server with us?
JustGains setup, tools, quality score, publishing readiness, and alternatives.
How do I add JustGains to Claude, ChatGPT, or Cursor?
Add JustGains to Claude, ChatGPT, or Cursor by connecting its remote MCP URL in each client's MCP settings. In Claude, add a custom connector. In ChatGPT, add an MCP app. In Cursor, add an MCP server under Settings. The MCP URL is https://justgains.com/mcp.
Is JustGains MCP ready for ChatGPT and Claude?
As of November 10, 2026, JustGains scores 100/100 on Manufact's MCP publishing checklist. The scan meets ChatGPT publishing checks and meets Claude publishing checks. Passing these checks does not guarantee marketplace approval.
How clear is JustGains's MCP tool documentation?
As of November 10, 2026, JustGains scores 87/100 in Manufact's review of tool titles, descriptions, input and output schemas, and behavior annotations. The review covers 29 of 29 discovered tools. The quality score measures documentation clarity; runtime behavior and marketplace readiness require separate checks.
Not your MCP?
Review any public or OAuth MCP server for protocol compatibility, tool documentation, and ChatGPT and Claude publishing readiness. No account required.