Tool tree
gradeNot graded
get_board_stateAnswer
Read the full game board: scene, map grid with legend, all tokens with positions and HP, combat status, active Heroic Effort boosts, party loot, and the recent story log. Call this first, and again whenever you need fresh eyes on the table.
View tool JSON
{
"name": "get_board_state",
"kind": "answer",
"impl": "imperative",
"description": "Read the full game board: scene, map grid with legend, all tokens with positions and HP, combat status, active Heroic Effort boosts, party loot, and the recent story log. Call this first, and again whenever you need fresh eyes on the table.",
"inputSchema": {
"type": "object",
"properties": {},
"required": []
}
}get_character_sheetAnswer
Read a character sheet: HP, AC, ability scores, conditions, inventory. Defaults to the first player character.
View tool JSON
{
"name": "get_character_sheet",
"kind": "answer",
"impl": "imperative",
"description": "Read a character sheet: HP, AC, ability scores, conditions, inventory. Defaults to the first player character.",
"inputSchema": {
"type": "object",
"properties": {
"tokenId": {
"type": "string",
"description": "Token id or name, e.g. \"Brannok\""
}
},
"required": []
}
}get_fitness_logAnswer
Read the session workout log: total reps, reps per exercise, challenges completed, dice rewards earned, unspent boosts, and any challenge in progress. Use it to pace the player — vary muscle groups and scale reps to how they are doing.
View tool JSON
{
"name": "get_fitness_log",
"kind": "answer",
"impl": "imperative",
"description": "Read the session workout log: total reps, reps per exercise, challenges completed, dice rewards earned, unspent boosts, and any challenge in progress. Use it to pace the player — vary muscle groups and scale reps to how they are doing.",
"inputSchema": {
"type": "object",
"properties": {},
"required": []
}
}get_questAnswer
Read the run: which of the five beats the party is on, its objective, what is already done, what is still ahead, and whether a hero is down. Call this when you are unsure what the party should be doing — this is the destination the whole session is driving toward.
View tool JSON
{
"name": "get_quest",
"kind": "answer",
"impl": "imperative",
"description": "Read the run: which of the five beats the party is on, its objective, what is already done, what is still ahead, and whether a hero is down. Call this when you are unsure what the party should be doing — this is the destination the whole session is driving toward.",
"inputSchema": {
"type": "object",
"properties": {},
"required": []
}
}advance_questAction
REFUSED while combat is running or the beat's own monster still stands — a beat is cleared over the body, not around it. Mark the current beat achieved and move the run to the next one. This pays out the milestone loot, swaps the map when the next beat is elsewhere, and on the final beat spawns the boss. Call it the moment the party has actually done what the objective asked — never before, and never twice for the same beat. Advancing past the last beat wins the run.
View tool JSON
{
"name": "advance_quest",
"kind": "act",
"impl": "imperative",
"description": "REFUSED while combat is running or the beat's own monster still stands — a beat is cleared over the body, not around it. Mark the current beat achieved and move the run to the next one. This pays out the milestone loot, swaps the map when the next beat is elsewhere, and on the final beat spawns the boss. Call it the moment the party has actually done what the objective asked — never before, and never twice for the same beat. Advancing past the last beat wins the run.",
"inputSchema": {
"type": "object",
"properties": {
"summary": {
"type": "string",
"description": "One line on how the party pulled it off, in DM voice"
}
},
"required": []
}
}roll_diceAction
Roll dice on the table, visibly, with animation. Formula like "d20", "2d6+3". Any earned Heroic Effort boosts (bonus, advantage, or a set die) apply automatically to a single d20 and are consumed. Rolls are public — no fudging. PACED: after two rolls with nothing staked this refuses once and asks you to offer a Heroic Effort or an Oath for the roll first — so stake something roughly every other roll and you will never see it.
View tool JSON
{
"name": "roll_dice",
"kind": "act",
"impl": "imperative",
"description": "Roll dice on the table, visibly, with animation. Formula like \"d20\", \"2d6+3\". Any earned Heroic Effort boosts (bonus, advantage, or a set die) apply automatically to a single d20 and are consumed. Rolls are public — no fudging. PACED: after two rolls with nothing staked this refuses once and asks you to offer a Heroic Effort or an Oath for the roll first — so stake something roughly every other roll and you will never see it.",
"inputSchema": {
"type": "object",
"properties": {
"formula": {
"type": "string",
"description": "Dice formula, e.g. \"d20\" or \"2d6+3\""
},
"reason": {
"type": "string",
"description": "What the roll is for, e.g. \"Brannok attacks the goblin\""
}
},
"required": [
"formula"
]
}
}narrateAction
Speak as the Dungeon Master: describe rooms, voice NPCs, react to rolls. Text is posted to the story log the player reads. Keep it vivid and under ~60 words per call.
View tool JSON
{
"name": "narrate",
"kind": "act",
"impl": "imperative",
"description": "Speak as the Dungeon Master: describe rooms, voice NPCs, react to rolls. Text is posted to the story log the player reads. Keep it vivid and under ~60 words per call.",
"inputSchema": {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "Narration text"
},
"speaker": {
"type": "string",
"description": "Optional speaker label, default \"DM\""
}
},
"required": [
"text"
]
}
}set_sceneAction
Retitle the scene and set its mood line. It CANNOT change the map: each quest beat owns its map and only advance_quest moves the party between them — because that is the call that pays the milestone. Passing a different mapId is refused and points you at advance_quest.
View tool JSON
{
"name": "set_scene",
"kind": "act",
"impl": "imperative",
"description": "Retitle the scene and set its mood line. It CANNOT change the map: each quest beat owns its map and only advance_quest moves the party between them — because that is the call that pays the milestone. Passing a different mapId is refused and points you at advance_quest.",
"inputSchema": {
"type": "object",
"properties": {
"mapId": {
"type": "string",
"enum": [
"dungeon",
"forest",
"crypt"
],
"description": "Which battle map"
},
"title": {
"type": "string",
"description": "Scene title"
},
"mood": {
"type": "string",
"description": "One-line mood, shown under the title"
}
},
"required": []
}
}reveal_areaAction
Clear fog of war in a circle. Use when the party gains sight of a new area.
View tool JSON
{
"name": "reveal_area",
"kind": "act",
"impl": "imperative",
"description": "Clear fog of war in a circle. Use when the party gains sight of a new area.",
"inputSchema": {
"type": "object",
"properties": {
"x": {
"type": "number",
"description": "Grid x (0-21)"
},
"y": {
"type": "number",
"description": "Grid y (0-13)"
},
"radius": {
"type": "number",
"description": "Cells, default 3, max 10"
}
},
"required": [
"x",
"y"
]
}
}move_tokenAction
Move a token to a grid cell (walls are rejected). The move animates on the board. Moving a PC also reveals fog around them.
View tool JSON
{
"name": "move_token",
"kind": "act",
"impl": "imperative",
"description": "Move a token to a grid cell (walls are rejected). The move animates on the board. Moving a PC also reveals fog around them.",
"inputSchema": {
"type": "object",
"properties": {
"tokenId": {
"type": "string",
"description": "Token id or name"
},
"x": {
"type": "number",
"description": "Grid x (0-21)"
},
"y": {
"type": "number",
"description": "Grid y (0-13)"
}
},
"required": [
"tokenId",
"x",
"y"
]
}
}attackAction
Make one attack and resolve it: rolls to hit against the target's AC, applies damage, and lifts the fog around whatever was hit. REACH IS ENFORCED HERE — a melee attack must be adjacent (or within the attacker's reach) and will be REFUSED with the exact cell to move to if it is not; ranged and spell attacks work out to the attacker's range. Use this for every swing, shot and spell instead of rolling dice and adjusting HP by hand: it is what keeps the board honest, and any Heroic Effort boost the player earned is spent on the roll automatically.
View tool JSON
{
"name": "attack",
"kind": "act",
"impl": "imperative",
"description": "Make one attack and resolve it: rolls to hit against the target's AC, applies damage, and lifts the fog around whatever was hit. REACH IS ENFORCED HERE — a melee attack must be adjacent (or within the attacker's reach) and will be REFUSED with the exact cell to move to if it is not; ranged and spell attacks work out to the attacker's range. Use this for every swing, shot and spell instead of rolling dice and adjusting HP by hand: it is what keeps the board honest, and any Heroic Effort boost the player earned is spent on the roll automatically.",
"inputSchema": {
"type": "object",
"properties": {
"attackerId": {
"type": "string",
"description": "Who is attacking — token id or name"
},
"targetId": {
"type": "string",
"description": "Who they are attacking — token id or name"
},
"kind": {
"type": "string",
"enum": [
"melee",
"ranged",
"spell"
],
"description": "melee needs adjacency; ranged and spell work at the attacker's range"
},
"damage": {
"type": "number",
"description": "Damage on a hit. Omit for a sensible default (more on a critical)."
},
"reason": {
"type": "string",
"description": "What the attack is, in DM voice — \"Brannok brings the longsword down\""
}
},
"required": [
"attackerId",
"targetId"
]
}
}move_partyAction
Move the WHOLE party to a grid cell in one call — use this whenever the players travel: through a door, into the next room, across the hall, following something. The leader lands on the cell, companions take open cells beside them, and the fog lifts around all of them. Walls are rejected. Prefer this over repeated move_token calls: if you describe the party going somewhere, call this in the same turn or the board will contradict you.
View tool JSON
{
"name": "move_party",
"kind": "act",
"impl": "imperative",
"description": "Move the WHOLE party to a grid cell in one call — use this whenever the players travel: through a door, into the next room, across the hall, following something. The leader lands on the cell, companions take open cells beside them, and the fog lifts around all of them. Walls are rejected. Prefer this over repeated move_token calls: if you describe the party going somewhere, call this in the same turn or the board will contradict you.",
"inputSchema": {
"type": "object",
"properties": {
"x": {
"type": "number",
"description": "Grid x (0-21)"
},
"y": {
"type": "number",
"description": "Grid y (0-13)"
},
"who": {
"type": "string",
"description": "Omit to move everyone. A token id or name moves only that hero."
}
},
"required": [
"x",
"y"
]
}
}add_tokenAction
Spawn a creature or object on the board. Eleven creature arts plus a chest: goblin, skeleton, dragon, wolf, ooze, spider, wraith, ogre, rat, warden (a carved stone guardian), knight, wizard, villager. NEVER use "knight" or "wizard" for an enemy — those are the player's own heroes, and the board would look like the party is fighting itself. Pick the one that actually fits what you are describing, and vary it — a hall of identical goblins looks like a bug, not an encounter.
View tool JSON
{
"name": "add_token",
"kind": "act",
"impl": "imperative",
"description": "Spawn a creature or object on the board. Eleven creature arts plus a chest: goblin, skeleton, dragon, wolf, ooze, spider, wraith, ogre, rat, warden (a carved stone guardian), knight, wizard, villager. NEVER use \"knight\" or \"wizard\" for an enemy — those are the player's own heroes, and the board would look like the party is fighting itself. Pick the one that actually fits what you are describing, and vary it — a hall of identical goblins looks like a bug, not an encounter.",
"inputSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Display name, e.g. \"Snaggle the Goblin\""
},
"kind": {
"type": "string",
"enum": [
"monster",
"npc",
"object"
],
"description": "What it is"
},
"art": {
"type": "string",
"enum": [
"knight",
"wizard",
"goblin",
"skeleton",
"dragon",
"wolf",
"ooze",
"spider",
"wraith",
"ogre",
"rat",
"warden",
"wight",
"chest",
"villager"
],
"description": "Token art. VARY IT — do not spawn two of the same art in one scene if another fits."
},
"x": {
"type": "number",
"description": "Grid x"
},
"y": {
"type": "number",
"description": "Grid y"
},
"hp": {
"type": "number",
"description": "Hit points (also max HP unless maxHp given)"
},
"maxHp": {
"type": "number",
"description": "Max hit points"
},
"scale": {
"type": "number",
"description": "How big it draws, 1-2.5. Leave it at 1 for ordinary creatures; use 2 for a boss you want to read as one from across the room."
}
},
"required": [
"name"
]
}
}remove_tokenAction
Remove a token from the board (defeated monster, opened chest). Clearing monsters and objects is immediate; removing a PLAYER CHARACTER requires the player's approval — that call waits for their ✓.
View tool JSON
{
"name": "remove_token",
"kind": "act",
"impl": "imperative",
"description": "Remove a token from the board (defeated monster, opened chest). Clearing monsters and objects is immediate; removing a PLAYER CHARACTER requires the player's approval — that call waits for their ✓.",
"inputSchema": {
"type": "object",
"properties": {
"tokenId": {
"type": "string",
"description": "Token id or name"
}
},
"required": [
"tokenId"
]
}
}start_combatAction
Begin initiative. Registers the combat tools. Every combatant comes out of the fog. MONSTERS ACT ON THEIR OWN TURN: if a monster wins initiative it closes and attacks the nearest hero immediately, and the result comes back in monstersActed — narrate it, then hand the turn to the player. You never need to make a monster swing; the turn order does it.
View tool JSON
{
"name": "start_combat",
"kind": "act",
"impl": "imperative",
"description": "Begin initiative. Registers the combat tools. Every combatant comes out of the fog. MONSTERS ACT ON THEIR OWN TURN: if a monster wins initiative it closes and attacks the nearest hero immediately, and the result comes back in monstersActed — narrate it, then hand the turn to the player. You never need to make a monster swing; the turn order does it.",
"inputSchema": {
"type": "object",
"properties": {
"order": {
"type": "array",
"items": {
"type": "string"
},
"description": "Optional initiative order (token ids or names)"
}
},
"required": []
}
}end_combatAction
End combat and clear initiative. The combat-only tools unregister.
View tool JSON
{
"name": "end_combat",
"kind": "act",
"impl": "imperative",
"description": "End combat and clear initiative. The combat-only tools unregister.",
"inputSchema": {
"type": "object",
"properties": {},
"required": []
}
}award_lootAction
Grant treasure to the party: items and/or gold. Shows up in the party panel and story log.
View tool JSON
{
"name": "award_loot",
"kind": "act",
"impl": "imperative",
"description": "Grant treasure to the party: items and/or gold. Shows up in the party panel and story log.",
"inputSchema": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "string"
},
"description": "Item names"
},
"gold": {
"type": "number",
"description": "Gold pieces"
}
},
"required": []
}
}propose_challengeAction
HEROIC EFFORT — stake a real exercise against the dice. Offer this before a roll that matters: the player does the reps, the reward auto-applies to their next d20. Always optional. Effort and reward scale together — five push-ups is worth +2, ten is worth +5, twenty-five buys a natural 20 — so ask bigger when you want to pay bigger. OFFER OFTEN: about every second exchange, not once a session. ALWAYS check get_fitness_log first: offer ONLY from its availableExercises list for mode "reps", and ONLY from its availableHolds list for mode "hold" — those are the sets this player can actually do, and the two lists are not interchangeable. The call resolves when the player finishes or declines (or returns "pending" if they take longer than 90s — check back with get_fitness_log).
View tool JSON
{
"name": "propose_challenge",
"kind": "act",
"impl": "imperative",
"description": "HEROIC EFFORT — stake a real exercise against the dice. Offer this before a roll that matters: the player does the reps, the reward auto-applies to their next d20. Always optional. Effort and reward scale together — five push-ups is worth +2, ten is worth +5, twenty-five buys a natural 20 — so ask bigger when you want to pay bigger. OFFER OFTEN: about every second exchange, not once a session. ALWAYS check get_fitness_log first: offer ONLY from its availableExercises list for mode \"reps\", and ONLY from its availableHolds list for mode \"hold\" — those are the sets this player can actually do, and the two lists are not interchangeable. The call resolves when the player finishes or declines (or returns \"pending\" if they take longer than 90s — check back with get_fitness_log).",
"inputSchema": {
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": [
"reps",
"hold"
],
"description": "reps = counted repetitions (default) · hold = a timed hold, e.g. a plank or a stretch"
},
"exercise": {
"type": "string",
"enum": [
"push-ups",
"crunches",
"jumping jacks",
"squats",
"sit-ups",
"lunges",
"high knees",
"mountain climbers",
"burpees",
"plank",
"side plank",
"high plank",
"wall sit",
"squat hold",
"dead hang",
"hollow hold",
"glute bridge"
],
"description": "A rep exercise for mode \"reps\", or a hold for mode \"hold\""
},
"reps": {
"type": "number",
"description": "Repetition count for mode \"reps\" (1-100). Keep it achievable: 5-25 for most people."
},
"seconds": {
"type": "number",
"description": "Hold length in seconds for mode \"hold\" (5-300). 20-45s is a real hold for most people."
},
"reward": {
"type": "string",
"enum": [
"bonus+2",
"bonus+3",
"bonus+5",
"bonus+8",
"advantage",
"set10",
"nat20"
],
"description": "What it buys. PRICE LIST — 5 reps/20s → bonus+2 · 8/25s → bonus+3 · 10/30s → bonus+5 · 12/40s → advantage · 15/45s → bonus+8 · 20/60s → set10 (next d20 is a 10) · 25/90s → nat20 (next d20 is a natural 20). Ask bigger, pay bigger. OMIT this and the size of your ask picks the right one."
},
"reason": {
"type": "string",
"description": "Why fate demands sweat right now, in DM voice"
}
},
"required": [
"exercise"
]
}
}propose_task_listAction
A TASK LIST instead of a single ask: put 2-3 small pieces of effort on the table at once, each worth its own flat bonus, and let the player tick off whatever they actually do. Five push-ups (+2), a twenty-second plank (+2) and five squats (+2) means the whole card is +6 — but two out of three is +4 and that is a real result. Reach for this when you want the best odds of getting SOMETHING: a player who would decline one big ask will usually take part of a list. Bonuses add up, so this never pays advantage or a natural 20 — use propose_challenge for those. Modes per item: "reps", "hold", or "oath" (a real-world task, amount in minutes).
View tool JSON
{
"name": "propose_task_list",
"kind": "act",
"impl": "imperative",
"description": "A TASK LIST instead of a single ask: put 2-3 small pieces of effort on the table at once, each worth its own flat bonus, and let the player tick off whatever they actually do. Five push-ups (+2), a twenty-second plank (+2) and five squats (+2) means the whole card is +6 — but two out of three is +4 and that is a real result. Reach for this when you want the best odds of getting SOMETHING: a player who would decline one big ask will usually take part of a list. Bonuses add up, so this never pays advantage or a natural 20 — use propose_challenge for those. Modes per item: \"reps\", \"hold\", or \"oath\" (a real-world task, amount in minutes).",
"inputSchema": {
"type": "object",
"properties": {
"items": {
"type": "array",
"minItems": 2,
"maxItems": 4,
"description": "2-3 items. Each: {exercise, mode, amount}. For mode \"oath\", put the task itself in \"exercise\", e.g. {\"exercise\":\"clear the sink\",\"mode\":\"oath\",\"amount\":10}.",
"items": {
"type": "object",
"properties": {
"exercise": {
"type": "string",
"description": "Exercise name for reps/hold, or the task itself for an oath"
},
"mode": {
"type": "string",
"enum": [
"reps",
"hold",
"oath"
],
"description": "reps · hold (seconds) · oath (minutes)"
},
"amount": {
"type": "number",
"description": "Reps, or seconds for a hold, or minutes for an oath"
}
},
"required": [
"exercise"
]
}
},
"reason": {
"type": "string",
"description": "Why, in character — what is at stake on this roll"
}
},
"required": [
"items"
]
}
}propose_oathAction
OATH — the other way to pay. Stake something real in the room that this app cannot see: clearing the sink, twenty minutes of study, ten pages of reading, practising an instrument, one dreaded email. The table LOCKS for the minutes agreed — the board freezes, you wait, and the player confirms on their honour when they return. It pays exactly the same dice rewards as a Heroic Effort, and you must treat it as an equal, never a consolation prize. Reach for it when a player cannot or would rather not exercise, when they mention something they are avoiding, or simply to vary what the table asks of them. Keep the minutes honest: 5-25 for most things.
View tool JSON
{
"name": "propose_oath",
"kind": "act",
"impl": "imperative",
"description": "OATH — the other way to pay. Stake something real in the room that this app cannot see: clearing the sink, twenty minutes of study, ten pages of reading, practising an instrument, one dreaded email. The table LOCKS for the minutes agreed — the board freezes, you wait, and the player confirms on their honour when they return. It pays exactly the same dice rewards as a Heroic Effort, and you must treat it as an equal, never a consolation prize. Reach for it when a player cannot or would rather not exercise, when they mention something they are avoiding, or simply to vary what the table asks of them. Keep the minutes honest: 5-25 for most things.",
"inputSchema": {
"type": "object",
"properties": {
"label": {
"type": "string",
"description": "The actual commitment, in their words: \"clear the sink\", \"read 10 pages of the textbook\""
},
"kind": {
"type": "string",
"description": "chores · study · reading · practice · admin · tidy"
},
"minutes": {
"type": "number",
"description": "How long the table waits (1-60). Match it to the real job."
},
"reward": {
"type": "string",
"enum": [
"bonus+2",
"bonus+3",
"bonus+5",
"bonus+8",
"advantage",
"set10",
"nat20"
],
"description": "Same rewards as a Heroic Effort"
},
"reason": {
"type": "string",
"description": "Why the fates accept this, in DM voice"
}
},
"required": [
"label",
"minutes",
"reward"
]
}
}start_warmupAction
Offer the guided warm-up: twenty standing stretches, head to ankle, each with a cue and a self-advancing timer. CALL IT WITH NO PLAN and a card appears asking the player to pick 90 seconds, 3 minutes, 5 minutes, or skip — that is what you want almost every time, at the very top of a run. Say one warm line inviting them to stand up, then WAIT for them to choose; do not pick for them. Pass a plan only if the player has already named one out loud. Finishing grants +2 on the first roll.
View tool JSON
{
"name": "start_warmup",
"kind": "act",
"impl": "imperative",
"description": "Offer the guided warm-up: twenty standing stretches, head to ankle, each with a cue and a self-advancing timer. CALL IT WITH NO PLAN and a card appears asking the player to pick 90 seconds, 3 minutes, 5 minutes, or skip — that is what you want almost every time, at the very top of a run. Say one warm line inviting them to stand up, then WAIT for them to choose; do not pick for them. Pass a plan only if the player has already named one out loud. Finishing grants +2 on the first roll.",
"inputSchema": {
"type": "object",
"properties": {
"plan": {
"type": "string",
"enum": [
"90s",
"3min",
"5min",
"10min"
],
"description": "Omit this to show the choice card, which is the normal use"
}
},
"required": []
}
}