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

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 (owned by the calling user, or any character for an admin with Admin Mode on).
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

NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / characterId / description
      Previous value: -"`_id` of the character to level (must belong to the calling user)."New value: +"`_id` of the character to level (owned by the calling user, or any character for an admin with Admin Mode on)."
  2. 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`."
  3. 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"
      +]
  4. First observed

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only declare the mutation/idempotency/safety profile, but the description goes well beyond them by enumerating exactly what mutates: level bump or new class entry with `multiclassGrants`, feature snapshotting and subclass cascade, ability bumps, HP/hit dice growth, use-counter resize, spell-slot pool reconciliation, `core.class` rewrite, XP flooring, and a level-up note. It also discloses error behavior (specific reason as a tool error) and the partial-apply semantics of `allowIncomplete`.

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 first sentence front-loads the core action well, but the body is a dense run-on paragraph stitched with semicolons that would be far more scannable as a short list. Almost every clause carries real information, so it is not padding, but the wall-of-text structure taxes comprehension for a 14-parameter tool.

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?

An output schema exists, yet the description still usefully notes the returned character plus a `summary`. It covers prerequisites, error recovery, partial-apply, multiclass entry, and every major side effect, leaving no significant gap for an agent to fill in.

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 100%, so the schema already documents each field and a baseline of 3 would be defensible. The description adds cross-parameter conditional meaning, though: which picks are required in which cases (abilityChoices for every surfaced `choice`, multiclass proficiency maps only when entering a class, grown choices demanding only delta counts), which the schema's per-field docs do not fully tie together.

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') and immediately distinguishes itself from siblings by naming the prerequisite tool (`vault_get_levelup_options`) and the fallback (`vault_record_pc_classes`). An agent can tell this apart from `vault_build_pc`, `vault_update_character`, and `vault_record_pc_classes` without opening any schema.

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 and prerequisites: read `vault_get_levelup_options` first, record classes via `vault_record_pc_classes` before leveling a class-less character, and fix-and-retry on invalid drafts with `allowIncomplete: true` as a named escape hatch. It also states when-not to use the escape ('never as a shortcut past picks you can supply').

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