Skip to main content
Glama

Embers: Tabletop RPG Toolkit

Level up a player character

vault_level_up_pc

Advance a character one level in a class, in one call, from a flat draft of choices, for a ruleset with guided level-up (vault answers an error naming the ruleset otherwise). A class-less character (no Class entries) is rejected — record its existing classes with vault_record_pc_classes first. Vault validates every pick against the plan's pools (prerequisites enforced; grown choices demand only their delta counts) and mutates the character: the class entry's stored level bumps (or a new class entry lands with the class's multiclassGrants), the level's features snapshot onto the sheet (a subclass picked through the class's subclass-choice ability lands as its own entry and cascades its features), ability-score increases bake, HP and hit dice grow per the hitPoints choice, use-counters resize (spent uses stay spent), the combined multiclass spell-slot pool reconciles, core.class updates to " , ...", XP floors at the new level's minimum (or your exact xp), and a level-up note records the choices; the engine applies every rule behind those changes. Read vault_get_levelup_options first — required: characterId, classRuleId, hitPoints. Supply abilityChoices for every feature choice the plan surfaced (including the subclass pick and grown choice lists), the sub-pick maps for anything the picked options themselves carry, multiclassSkillProficiencies/multiclassToolProficiencies when entering a class, and optional exact xp. The updated character and a summary of what changed are returned. On an invalid draft vault returns the specific reason as a tool error — fix the draft and retry; if a surfaced pick genuinely cannot be satisfied, allowIncomplete: true applies the level and skips the shortfall instead.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
xpNoThe character's total XP after this level-up, for tables tracking exact XP. Must be >= the plan's `xp.minimumForNewTotal`; omit to let vault floor the stored XP at that minimum.
hitPointsYesHow the level's hit points are gained: `method` is one of the schema's methods (the plan's `hitPoints` fields carry what each one uses); `value` is a die the PLAYER rolled, for a method that takes one.
characterIdYes`_id` of the character to level (must belong to the calling user).
classRuleIdYesRequired. The base Class rule to advance one level — a held class entry (its stored level bumps) or a class the character doesn't hold yet (multiclass: a new class entry is stamped). From the chooser's `classEntries[].classRuleId` / `multiclassOptions[]._id`.
abilityChoicesNoruleChoice picks, keyed by the OWNING rule's `_id`: a gained feature's choice (the class's subclass-choice ability — value = the picked subclass `_id`; a choice among feats — value = the picked feat `_id`) AND a grown held rule's choice (`growth[]` entries — supply the NEW picks only, the delta count). A picked option's own sub-choices (a feat's skill picks, its abilityScoreBump) go in the other maps keyed by the picked option's `_id`, exactly as in `vault_build_pc`. Pools are prerequisite-filtered; an unqualified pick rejects the draft.
allowIncompleteNoSanctioned partial apply: `true` lets vault accept UNDER-filled pick families — the level lands and only what was picked is granted; the shortfall is simply skipped (the player can edit the sheet later). Overfilled, duplicate, out-of-pool, and prerequisite-failing picks still reject. Use it as the escape when a surfaced pick cannot be satisfied; never as a shortcut past picks you can supply.
abilityBumpPicksNoAbility-score-increase picks for a gained rule carrying an `abilityScoreBump`: `{ option, lines }` keyed by the granting rule's `_id`, same shape as `vault_build_pc`. The engine applies whatever the increase changes elsewhere on the sheet.
spellChoicePicksNoPicks for spellChoices blocks on gained/grown rules, keyed `"<ruleId>:<blockIndex>"` (authored index — the projected array may hold nulls; count them). Grown blocks demand only the DELTA count ("learn N more spells").
preparedSpellPicksNo"Prepare N more" picks for rules whose preparedSpells count grew, keyed by the granting rule's `_id`. The pool is the character's UNPREPARED granted leveled spells plus any picked this level-up; send exactly the plan's surfaced count.
castingAbilityPicksNoSpellcasting-ability picks for blocks surfacing `castingAbilityOptions`, keyed like spellChoicePicks.
spellListChoicePicksNoPicks for a NEWLY gained rule's spellListChoices — `{ category, picks, castingAbility? }` keyed `"<ruleId>:<blockIndex>"`, exactly as in `vault_build_pc`.
proficiencyChoicePicksNoPicks for proficiencyChoices grants on gained/grown rules, keyed `"<ruleId>:<grantIndex>"` — same keying and rules as `vault_build_pc`. Grown grants demand only the DELTA count the plan surfaced. An EXPERTISE grant picks from the pool the rule authoring guide describes (vault_get_authoring_guide, entityType .rule., proficiencyChoices); vault rejects picks that do not fit.
multiclassToolProficienciesNoTool picks for the entered class's `multiclassGrants.toolChoices` (multiclass only): exactly `count` names from its (group-expanded) options.
multiclassSkillProficienciesNoSkill picks for the entered class's `multiclassGrants.skillChoices` (multiclass only): exactly `count` names from its options.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changed
    • changedInput schema / properties / abilityBumpPicks / description
      Previous value: -"Ability-score-increase picks for a gained rule carrying an `abilityScoreBump` (the ASI feat picked at level 4+): `{ option, lines }` keyed by the granting rule's `_id`, same shape as `vault_build_pc`. A Constitution increase raises HP retroactively for every level already held."New value: +"Ability-score-increase picks for a gained rule carrying an `abilityScoreBump`: `{ option, lines }` keyed by the granting rule's `_id`, same shape as `vault_build_pc`. The engine applies whatever the increase changes elsewhere on the sheet."
    • changedInput schema / properties / abilityChoices / description
      Previous value: -"ruleChoice picks, keyed by the OWNING rule's `_id`: a gained feature's choice (a Fighting Style; the class's subclass-choice ability at level 3 — value = the picked subclass `_id`; an ASI ability — value = the picked feat `_id`) AND a grown held rule's choice (`growth[]` entries, e.g. new invocations — supply the NEW picks only, the delta count). A picked option's own sub-choices (a feat's skill picks, its abilityScoreBump) go in the other maps keyed by the picked option's `_id`, exactly as in `vault_build_pc`. Pools are prerequisite-filtered; an unqualified pick rejects the draft."New value: +"ruleChoice picks, keyed by the OWNING rule's `_id`: a gained feature's choice (the class's subclass-choice ability — value = the picked subclass `_id`; a choice among feats — value = the picked feat `_id`) AND a grown held rule's choice (`growth[]` entries — supply the NEW picks only, the delta count). A picked option's own sub-choices (a feat's skill picks, its abilityScoreBump) go in the other maps keyed by the picked option's `_id`, exactly as in `vault_build_pc`. Pools are prerequisite-filtered; an unqualified pick rejects the draft."
    • changedInput schema / properties / classRuleId / description
      Previous value: -"Required. The base Class rule to advance one level — a held class entry (its stored level bumps) or a class the character doesn't hold yet (multiclass: a second class entry is stamped at level 1). From the chooser's `classEntries[].classRuleId` / `multiclassOptions[]._id`."New value: +"Required. The base Class rule to advance one level — a held class entry (its stored level bumps) or a class the character doesn't hold yet (multiclass: a new class entry is stamped). From the chooser's `classEntries[].classRuleId` / `multiclassOptions[]._id`."
    • changedInput schema / properties / hitPoints / description
      Previous value: -"How the level's hit points are gained: `{method:'average'}` takes the fixed average (the plan's `hitPoints.average`); `{method:'roll', value}` records a die the PLAYER rolled — value must be 1..the class's hit die. The Constitution modifier is added server-side either way."New value: +"How the level's hit points are gained: `method` is one of the schema's methods (the plan's `hitPoints` fields carry what each one uses); `value` is a die the PLAYER rolled, for a method that takes one."
    • changedInput schema / properties / proficiencyChoicePicks / description
      Previous value: -"Picks for proficiencyChoices grants on gained/grown rules, keyed `\"<ruleId>:<grantIndex>\"` — same keying and rules as `vault_build_pc`. Grown grants demand only the DELTA count the plan surfaced. An EXPERTISE grant's pool is the character's proficient skills MINUS those that already carry Expertise (narrowed to the grant's own options for mode 'specific'); when that pool is at/below the count, vault auto-grants and expects NO picks."New value: +"Picks for proficiencyChoices grants on gained/grown rules, keyed `\"<ruleId>:<grantIndex>\"` — same keying and rules as `vault_build_pc`. Grown grants demand only the DELTA count the plan surfaced. An EXPERTISE grant picks from the pool the rule authoring guide describes (vault_get_authoring_guide, entityType .rule., proficiencyChoices); vault rejects picks that do not fit."
    • changedInput schema / properties / spellListChoicePicks / description
      Previous value: -"Picks for a NEWLY gained rule's spellListChoices (the Magic Initiate shape) — `{ category, picks, castingAbility? }` keyed `\"<ruleId>:<blockIndex>\"`, exactly as in `vault_build_pc`."New value: +"Picks for a NEWLY gained rule's spellListChoices — `{ category, picks, castingAbility? }` keyed `\"<ruleId>:<blockIndex>\"`, exactly as in `vault_build_pc`."
  2. Changed17 schema fields changed
    • addedInput schema / $schema
      Added value: +"http://json-schema.org/draft-07/schema#"
    • addedInput schema / additionalProperties
      Added value: +{}
    • addedInput schema / properties / abilityBumpPicks
      Added value: +{
      +  "additionalProperties": {
      +    "additionalProperties": {},
      +    "properties": {
      +      "lines": {
      +        "items": {
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "type": "array"
      +      },
      +      "option": {
      +        "maximum": 9007199254740991,
      +        "minimum": 0,
      +        "type": "integer"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "description": "Ability-score-increase picks for a gained rule carrying an `abilityScoreBump` (the ASI feat picked at level 4+): `{ option, lines }` keyed by the granting rule's `_id`, same shape as `vault_build_pc`. A Constitution increase raises HP retroactively for every level already held.",
      +  "propertyNames": {
      +    "type": "string"
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / abilityChoices
      Added value: +{
      +  "additionalProperties": {
      +    "items": {
      +      "type": "string"
      +    },
      +    "type": "array"
      +  },
      +  "description": "ruleChoice picks, keyed by the OWNING rule's `_id`: a gained feature's choice (a Fighting Style; the class's subclass-choice ability at level 3 — value = the picked subclass `_id`; an ASI ability — value = the picked feat `_id`) AND a grown held rule's choice (`growth[]` entries, e.g. new invocations — supply the NEW picks only, the delta count). A picked option's own sub-choices (a feat's skill picks, its abilityScoreBump) go in the other maps keyed by the picked option's `_id`, exactly as in `vault_build_pc`. Pools are prerequisite-filtered; an unqualified pick rejects the draft.",
      +  "propertyNames": {
      +    "type": "string"
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / allowIncomplete
      Added value: +{
      +  "description": "Sanctioned partial apply: `true` lets vault accept UNDER-filled pick families — the level lands and only what was picked is granted; the shortfall is simply skipped (the player can edit the sheet later). Overfilled, duplicate, out-of-pool, and prerequisite-failing picks still reject. Use it as the escape when a surfaced pick cannot be satisfied; never as a shortcut past picks you can supply.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / castingAbilityPicks
      Added value: +{
      +  "additionalProperties": {
      +    "enum": [
      +      "strength",
      +      "dexterity",
      +      "constitution",
      +      "intelligence",
      +      "wisdom",
      +      "charisma"
      +    ],
      +    "type": "string"
      +  },
      +  "description": "Spellcasting-ability picks for blocks surfacing `castingAbilityOptions`, keyed like spellChoicePicks.",
      +  "propertyNames": {
      +    "type": "string"
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / characterId
      Added value: +{
      +  "description": "`_id` of the character to level (must belong to the calling user).",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / classRuleId
      Added value: +{
      +  "description": "Required. The base Class rule to advance one level — a held class entry (its stored level bumps) or a class the character doesn't hold yet (multiclass: a second class entry is stamped at level 1). From the chooser's `classEntries[].classRuleId` / `multiclassOptions[]._id`.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / hitPoints
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "How the level's hit points are gained: `{method:'average'}` takes the fixed average (the plan's `hitPoints.average`); `{method:'roll', value}` records a die the PLAYER rolled — value must be 1..the class's hit die. The Constitution modifier is added server-side either way.",
      +  "properties": {
      +    "method": {
      +      "enum": [
      +        "average",
      +        "roll"
      +      ],
      +      "type": "string"
      +    },
      +    "value": {
      +      "exclusiveMinimum": 0,
      +      "maximum": 9007199254740991,
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "method"
      +  ],
      +  "type": "object"
      +}
    • addedInput schema / properties / multiclassSkillProficiencies
      Added value: +{
      +  "description": "Skill picks for the entered class's `multiclassGrants.skillChoices` (multiclass only): exactly `count` names from its options.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / multiclassToolProficiencies
      Added value: +{
      +  "description": "Tool picks for the entered class's `multiclassGrants.toolChoices` (multiclass only): exactly `count` names from its (group-expanded) options.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / preparedSpellPicks
      Added value: +{
      +  "additionalProperties": {
      +    "items": {
      +      "description": "Mongo `_id` reference (24-character hex string).",
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "type": "array"
      +  },
      +  "description": "\"Prepare N more\" picks for rules whose preparedSpells count grew, keyed by the granting rule's `_id`. The pool is the character's UNPREPARED granted leveled spells plus any picked this level-up; send exactly the plan's surfaced count.",
      +  "propertyNames": {
      +    "type": "string"
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / proficiencyChoicePicks
      Added value: +{
      +  "additionalProperties": {
      +    "items": {
      +      "type": "string"
      +    },
      +    "type": "array"
      +  },
      +  "description": "Picks for proficiencyChoices grants on gained/grown rules, keyed `\"<ruleId>:<grantIndex>\"` — same keying and rules as `vault_build_pc`. Grown grants demand only the DELTA count the plan surfaced. An EXPERTISE grant's pool is the character's proficient skills MINUS those that already carry Expertise (narrowed to the grant's own options for mode 'specific'); when that pool is at/below the count, vault auto-grants and expects NO picks.",
      +  "propertyNames": {
      +    "type": "string"
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / spellChoicePicks
      Added value: +{
      +  "additionalProperties": {
      +    "items": {
      +      "description": "Mongo `_id` reference (24-character hex string).",
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "type": "array"
      +  },
      +  "description": "Picks for spellChoices blocks on gained/grown rules, keyed `\"<ruleId>:<blockIndex>\"` (authored index — the projected array may hold nulls; count them). Grown blocks demand only the DELTA count (\"learn N more spells\").",
      +  "propertyNames": {
      +    "type": "string"
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / spellListChoicePicks
      Added value: +{
      +  "additionalProperties": {
      +    "additionalProperties": {},
      +    "properties": {
      +      "castingAbility": {
      +        "enum": [
      +          "strength",
      +          "dexterity",
      +          "constitution",
      +          "intelligence",
      +          "wisdom",
      +          "charisma"
      +        ],
      +        "type": "string"
      +      },
      +      "category": {
      +        "type": "string"
      +      },
      +      "picks": {
      +        "additionalProperties": {
      +          "items": {
      +            "description": "Mongo `_id` reference (24-character hex string).",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "description": "Picks for a NEWLY gained rule's spellListChoices (the Magic Initiate shape) — `{ category, picks, castingAbility? }` keyed `\"<ruleId>:<blockIndex>\"`, exactly as in `vault_build_pc`.",
      +  "propertyNames": {
      +    "type": "string"
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / xp
      Added value: +{
      +  "description": "The character's total XP after this level-up, for tables tracking exact XP. Must be >= the plan's `xp.minimumForNewTotal`; omit to let vault floor the stored XP at that minimum.",
      +  "maximum": 9007199254740991,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedInput schema / required
      Added value: +[
      +  "characterId",
      +  "classRuleId",
      +  "hitPoints"
      +]
  3. First observed

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only give readOnly=false/destructive=false/idempotent=false, so the description carries most of the burden — and it delivers: it discloses validation against plan pools, prerequisite enforcement, delta-count semantics, the full mutation set (level bump, feature snapshot, HP/hit-dice growth, counter resize, spell-slot reconcile, class string, XP floor), and error/retry behavior. The one gap is no explicit warning about reversibility/undo of these mutations, which matters for a non-idempotent write.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded, but the bulk is one dense run-on paragraph with nested em-dash lists that is hard to parse and would benefit from segmentation. Most content earns its place, but the wall-of-text structure costs readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 14-parameter mutation tool with nested objects and an output schema (so return values needn't be restated), the description covers prerequisites, mutation semantics, parameter wiring, and error handling. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is already 100%, so the baseline is 3, but the description genuinely adds invocation-level meaning beyond the schema: which maps each pick family belongs to, that grown choices demand only their delta counts, prerequisite-filtered pools, and that sub-picks are keyed by the picked option's _id 'exactly as in vault_build_pc'. This is more than the schema alone conveys.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Advance a character one level in a class, in one call, from a flat draft of choices') and scopes it (single level, one call, flat draft). It clearly differentiates from siblings by naming vault_get_levelup_options as the required prerequisite and vault_record_pc_classes as the fix for class-less characters.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use: 'Read vault_get_levelup_options first'; explicit exclusion: class-less characters are rejected and must be recorded via vault_record_pc_classes first; and an explicit escape hatch with its condition ('if a surfaced pick genuinely cannot be satisfied, allowIncomplete: true'). This covers use, alternatives, and when-not.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources