Skip to main content
Glama
rjenks
by rjenks

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
PF2E_MCP_DBNoOverride the full path to the SQLite database file. Useful for a throwaway build, a shared read-only database, or to keep everything inside a checkout while developing.
PF2E_MCP_CACHENoOverride the directory for the extracted release cache. Useful for a throwaway build or to keep everything inside a checkout while developing.

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
rules_searchA

Full-text search over PF2e rules content. Returns compact summaries (id/name/pack/type/level/category) -- call rules_get_entry with an id for the full description and raw data of a specific result.

`include_legacy` (default False): excludes pre-Remaster/OGL-flagged
content unless set -- but `is_remaster: false` does NOT mean "retired,"
just "not (yet) reprinted under ORC" (54% of backgrounds, 38% of
ancestries are legacy-flagged and still fully playable), so set this
True whenever the user wants the full catalog. See
`licensing.legacy_filter_sql`.
rules_get_entryA

Fetch a single PF2e entry's full detail (description, traits, raw data) by id, exact name, or slug. Provide exactly one of the three.

rules_relatedA

Cross-reference traversal for a feat: what it requires (its own parsed prerequisites) and what requires it (other feats naming it as a prerequisite, directly or as one option in an OR-list). Also includes: grants/granted_by (structured GrantItem relationships -- e.g. Animist's Shaman practice grants Spirit Familiar, so Spirit Familiar's own granted_by would list Shaman); stat_modifiers (structured ActiveEffectLike changes the item makes, e.g. Druid's Leaf Order upgrading Diplomacy to trained). All exact data sourced from the item's own rule elements, not a guess from description prose.

rules_explainA

Explain a rules topic (e.g. a condition or general rule) by full-text searching content most likely to hold rules text (conditions, actions, glossary entries) and returning descriptions inline, since the point is a direct answer rather than a lookup requiring a follow-up call.

rules_data_versionA

Report which foundryvtt/pf2e release the current rules database was built from.

rules_list_variant_rulesA

Browse the optional/variant character-building and subsystem rules ingested from GM Core's "Subsystems and Variant Rules" section (what Pathbuilder and most tables call "optional rules") -- Free Archetype, Ancestry Paragon, Proficiency without Level, Gradual Attribute Boosts, Automatic Bonus Progression, Stamina, Mythic Characters, and several GM-facing downtime/encounter subsystems (Chases, Influence, etc.). Returns compact summaries; call rules_get_entry with an id/name for the full official rule text and book/page citation.

`category` filters to 'character-building' (affects what a character
gets at creation/level-up -- ask about these when starting a new
character) or 'subsystem' (GM-facing, doesn't change character
creation) -- omit to see both. Only Free Archetype and Ancestry Paragon
currently have mechanical support elsewhere in this server (extra feat
slots in build_get_level_up_choices, feat-count checks in
build_validate_build, both via their `variant_rules` parameter) -- the
rest are reference text only for now.
rules_list_subclass_option_groupsA

List every subclass-style choice-group tag found in the ingested data -- e.g. 'animist-apparition', 'sorcerer-bloodline', 'druid-order', 'witch-patron', 'cleric-doctrine', 'barbarian-instinct' -- one tag family per class that has this kind of choice (order/practice/ doctrine/patron/instinct/mystery/muse/racket/style/...). Each of these is a real level-1-or-later pick with mechanical consequences (e.g. a Druid Order or Animist Practice can outright grant a bonus feat), but nothing else in this server can enumerate them -- build_list_classes only returns a class's flat level-1 baseline, with no concept of sub-choices. Call rules_list_subclass_options with one of the tags returned here to get its actual member options, their full mechanical description text, and a structured grants field for anything each option automatically grants (e.g. Shaman practice granting Spirit Familiar) -- sourced from exact GrantItem data, not parsed from prose.

rules_list_subclass_optionsA

List every option in a subclass-style choice group by its exact tag (see rules_list_subclass_option_groups for valid values -- tag matching is exact, not fuzzy, since e.g. Inventor's two groups ('weapon-innovation-modification'/'armor-innovation-modification') don't share a class-name prefix the way most others do, so guessing a class-name-based filter would silently miss real groups). Returns full entries (with description, plus grants -- anything the option automatically grants, e.g. Shaman practice granting Spirit Familiar -- and stat_modifiers -- numeric/proficiency changes, e.g. an order's skill training -- both sourced from structured GrantItem/ ActiveEffectLike data, not parsed from prose) rather than summaries, since the point of this tool is seeing what each option actually does in one call.

build_list_ancestriesA

List playable ancestries, optionally filtered by name substring.

`include_legacy` (default False): excludes pre-Remaster/OGL-flagged
ancestries unless set -- but 38% of ancestries are legacy-flagged and
still fully playable (not reprinted under ORC yet isn't the same as
retired), so set this True whenever the user wants the full catalog,
not just what's been individually remastered. See `_legacy_filter_sql`.
build_list_backgroundsA

List backgrounds, optionally filtered by name substring.

`trained_skills` (`{"fixed": [skill slugs], "lore": [Lore skill names]}`)
and `granted_items` (`[{level, name, uuid}]`, `level` always null for a
background -- granted at character creation) come straight from the
background item's own structured `system.trainedSkills`/`system.items`
fields, the same mechanism `build_list_classes` already exposes for
classes -- e.g. Field Medic: trained_skills `{"fixed": ["medicine"],
"lore": ["Warfare Lore"]}`, granted_items `[{"name": "Battle
Medicine", ...}]`.

`include_legacy` (default False): excludes pre-Remaster/OGL-flagged
backgrounds unless set -- 54% of all backgrounds are legacy-flagged and
still fully playable, the single largest exclusion of any pack this
filter touches. See `_legacy_filter_sql`.
build_list_classesA

List classes, optionally filtered by name substring. Includes each class's level-1 initial proficiency baseline (HP, Perception, saves, trained skills formula, weapon/armor proficiencies) -- sourced directly from the class item's own data rather than requiring the caller to recall or look this up externally. Proficiency ranks in the returned perception/fortitude/reflex/will/class_dc/attacks/defenses fields use this project's 0/2/4/6/8 convention (untrained/trained/ expert/master/legendary), the same as a character's proficiencies dict elsewhere -- ready to drop into a draft character directly.

Note this is the class's own *baseline* only -- doctrine/subclass
choices (e.g. Cleric's Warpriest doctrine granting expert Fortitude and
martial weapons) and later automatic class features (e.g. Champion's
Weapon Expertise at level 5) can raise these further; this call doesn't
know about either, only what every member of the class starts with at
level 1.

**`trained_skills.additional` is the class's own flat baseline ONLY --
it does NOT include the Intelligence-modifier bonus to additional
trained skills that every class gets at character creation** ("...
becomes trained in a number of skills equal to [class value] plus your
Intelligence modifier" -- Player Core, Skills step of character
creation). This is a genuinely easy value to miscount: confirmed live
building a level-10 Magus with Int 14 (+2) where only 2 additional
skills were picked instead of the correct 4. The caller is responsible
for adding `max(0, ability_mod(character's Int score))` to this value
themselves before presenting a skill count to the user; `validate_build`
now includes a floor check for this specifically (see
`_validate_trained_skill_count`) but it's a warning after the fact, not
a substitute for getting the count right when first proposing it.

`trained_skills.choice`, when present, is a class's "trained in X **or**
Y" pattern (e.g. Fighter's Acrobatics-or-Athletics) that `fixed` alone
can't represent -- sourced from the class item's own ChoiceSet rule
element (see `item_choice_sets`), not from `fixed` being silently
incomplete.

`include_legacy` (default False): excludes pre-Remaster/OGL-flagged
classes unless set -- currently a no-op (every class chassis has been
reprinted under ORC, so all 29 are is_remaster:1), kept for API
consistency with the other `list_*` tools and in case a future release
adds a class before its own remaster reprint. See `_legacy_filter_sql`.
build_list_equipmentA

Browse the equipment pack (weapons, armor, shields, gear) by name substring, item type, and/or maximum price. A fresh level-1 character has STARTING_WEALTH_GP (15) gold pieces to spend using the standard "starting money" method -- returned alongside results as a reminder, not a per-call lookup, since it's a fixed constant.

`include_legacy` (default False): excludes pre-Remaster/OGL-flagged
equipment unless set. See `_legacy_filter_sql`.
build_list_available_featsA

The main token-saving discovery tool: returns only feats of the requested category at or below the target level (character's current level if unspecified) whose prerequisites the character already meets, instead of the caller reasoning over the full feat list or raw rules text. Split into two buckets:

- "available": prerequisites confirmed satisfied (or none required).
- "unconfirmed": at least one prerequisite couldn't be automatically
  verified (freeform text the parser can't structure -- roughly 16% of
  all feats per the Phase 0 parsing spike). Never silently included in
  "available" -- surface these to the user for manual confirmation.

Feats that definitely fail a prerequisite, or that the character
already has, are omitted entirely.

"class" and "ancestry" feats are further restricted to the character's
own class/ancestry (matched via the feat's trait list, e.g. a Fighter
class feat carries the "fighter" trait) -- category alone only narrows
to "any class feat from any class".

"archetype" is a special case: the source data has no "archetype"
category value at all (confirmed against the real data -- every
archetype/dedication feat is stored as category "class" or "skill",
with "archetype" appearing only as a trait). This matches actual PF2e
rules: archetype feats are taken using ordinary class or skill feat
slots, not a separate slot type. This function queries for the
"archetype" trait within those two categories instead. It does not
filter further to one specific chosen archetype (e.g. "only Alchemist
archetype feats") -- that gating already happens naturally through each
feat's own prerequisite (e.g. "Alchemist Dedication"), checked the same
way as any other prerequisite.

Every returned entry also carries `rarity` and a best-effort `pfs`
legality status (not authoritative -- see pfs.py module docstring),
so a PFS-bound build can be steered away from restricted picks without
a separate lookup per feat.

`include_legacy` (default False): excludes pre-Remaster/OGL-flagged
feats unless set. See `_legacy_filter_sql`.
build_list_ability_boost_optionsA

Eligible ability score boosts for the given source, respecting ancestry flaws and boosts already recorded in character.abilities.breakdown (Pathbuilder's own per-level boost history field -- see the plan's Pathbuilder-schema findings). Does not yet cross-check the "can't take two free boosts in the same ability at the same tier" rule beyond what's already recorded in breakdown for this source; full multi-source interaction (e.g. voluntary ancestry flaws freeing up a boost) is left to validate_build.

build_list_skill_increase_optionsA

Which of the 16 core skills are legal to raise one rank right now, given the character's current level and current rank in each (the trained/expert/master/legendary level-3/7/15 caps are a fixed core rule, independent of class). Does not consult skillIncreaseLevels itself -- call build_get_level_up_choices to confirm a skill-increase choice is actually available at the target level before offering these.

build_check_prerequisiteB

Narrow single-feat eligibility check -- use when sanity-checking one user-proposed choice rather than re-running full discovery.

build_validate_buildA

Structured validation, not prose -- returns errors (definite rule violations) and warnings (things that couldn't be auto-verified and need human confirmation). Covers: duplicate feats, prerequisites of every taken feat still being satisfied (important after e.g. a hypothetical ancestry swap mid-build), skill ranks not exceeding the fixed level-3/7/15 expert/master/legendary caps, whether the number of ancestry-category feats taken fits the character's actual budget for their level, and (new) the archetype "one dedication feat at a time" rule -- a level-ordered check that no dedication feat was taken while an earlier, different dedication still needed two other archetype feats first (see _validate_dedication_exclusivity; this is validation this project does that Foundry's own reference implementation doesn't attempt either -- confirmed nothing in its source enforces it), and (new) a warning for any fixed (non-player-choice) trained skill or Lore the character's background/class grants but that isn't actually trained on the character (see _validate_fixed_trained_skills -- deliberately scoped to just the fixed/unconditional grants, not the player's free "additional" choices, since those can't be cleanly told apart from later Skill Increases without risking a false positive at higher levels), (new) a warning if the character's total count of trained-or-better skills/lores is below the level-1 minimum implied by class fixed+additional skills, background fixed/lore/choice skills, and the character's Intelligence modifier if positive -- a floor check, not an identity check, so it stays valid at any level (see _validate_trained_skill_count; this exists specifically because the Intelligence-modifier bonus to a class's additional trained-skill count is a universal core rule not baked into list_classes' additional field, and is easy to silently drop), and (new) a warning for any save/Perception/weapon/ armor/class-DC proficiency rank that's lower than what the character's class baseline plus its granted class features/taken feats up to their level should produce (see _validate_proficiency_ranks). Does NOT yet check ability-boost-tier double-ups across sources, or spellcasting proficiency specifically (tradition-dependent -- see _validate_proficiency_ranks's docstring for why that one key is skipped).

`variant_rules` (see rules_list_variant_rules / get_level_up_choices)
changes the ancestry-feat budget when `'ancestry-paragon'` is included
(2 feats at level 1, one more at every odd level, instead of the
class's normal 1/5/9/13/17 schedule), and adds a soft, non-blocking
note about archetype-trait feat count when `'free-archetype'` is
included -- that one is a warning rather than an error because this
server doesn't track class/skill-feat-slot usage at all, so it can't
tell a normal-slot archetype feat apart from a free-archetype bonus
slot with certainty; only ancestry feats get a hard budget check, since
'ancestry' is otherwise never used as a normal class/skill/general feat
slot. The **Ancestral Paragon** general feat (a real, always-available
pick independent of any variant rule) adds +1 to the ancestry budget on
its own if taken.

`pfs_legal_only=True` adds a warning for any taken feat whose
best-effort PFS status (see pfs.py) isn't 'legal' -- not authoritative,
see that module's docstring.
build_calculate_derived_statsA

Deterministic PF2e math: AC, saves, Perception, skill totals, HP, class DC, and spell DC/attack per casting tradition the character has trained. Never left to model arithmetic -- proficiency stacking (untrained = ability mod only, no level) is easy to get wrong.

AC uses the character's worn armor (Pathbuilder's `armor` list) if
present, else the unarmored baseline, and includes the armor's potency
rune if any. Does not yet include a raised shield's bonus -- see
pf2e_math.armor_ac docstring.

HP's `attributes.ancestryhp`/`attributes.classhp` and AC's
`proficiencies.unarmored` fall back to a lookup against this project's
own ingested `ancestry_boosts`/`class_progression` data (via the
character's `ancestry`/`class` fields) when the caller doesn't supply
them explicitly -- previously a caller-side omission here silently
produced a plausible-looking-but-wrong result (confirmed live: HP
understated by ~90 points, AC by 12, for a real level-10 character
built without these three fields) rather than an error, since Python's
dict.get default masked the difference between "explicitly 0" and
"never set." The explicit-value case is preserved -- these fallbacks
only apply when the key is genuinely absent, not when it's present and
zero (e.g. a real Wizard's `classhp` isn't 0, but nothing in this
system produces a *correct* 0 for these three fields either, so
treating "key absent" as the signal to fall back is safe in practice).
build_list_available_spellsA

Spells of the given tradition at or below the highest rank the character can currently access, plus (new) the character's actual spell slot counts by rank for their level, when their class has one.

Rank cap resolution, in order: an explicitly-passed `max_rank` always
wins (needed for a caster archetype/dedication, where `character.class`
itself isn't the caster and so has no row in `class_spell_slots` at
all); otherwise the character class's own real slot table (see
`_class_spell_slots`) if it has one -- this replaces the standard
full-caster `ceil(level/2)` heuristic with the class's actual
progression, which matters for Magus/Summoner specifically (both delayed
relative to full casters, and non-monotonic -- they only ever hold 2
active ranks at once); if neither applies (the character's class isn't
a recognized caster at all), falls back to the `ceil(level/2)`
heuristic same as before, since a caller may still be probing a
non-standard tradition/dedication combination this project can't
resolve on its own.

`spell_slots` in the result is the real per-rank slot table when the
class has one, else `None` (honestly "not known," not a guess) --
resolves the previous "spell slots aren't modeled at all" gap for every
class with real ingested data.

Cantrips are stored in the source data with `level: 1` (they
auto-heighten to half the caster's level) rather than rank 0, so they'd
otherwise be indistinguishable from true 1st-rank slotted spells --
each result is tagged `is_cantrip` to keep that mechanical distinction
visible (cantrips are at-will, leveled spells consume slots).

`include_legacy` (default False): excludes pre-Remaster/OGL-flagged
spells unless set. See `_legacy_filter_sql`.
build_get_level_up_choicesA

What unlocks at target_level for the character's class: which feat categories/skill increases become available (from the class's structured level-gate arrays) plus any automatically-granted class features (no choice required). Ability boosts are always at 5/10/15/20 per core PF2e rules, not class-specific data.

`variant_rules` is a list of slugs for optional/variant rules this
build is using -- see rules_list_variant_rules for the full catalog and
rules_get_entry for each one's official text. Only two currently change
what this function reports (the rest are recognized as valid slugs but
don't affect the computed unlocks yet):

- `'ancestry-paragon'` (GM Core p.194): 2 ancestry feats at level 1
  instead of 1, then one more at every odd level (3, 5, 7, 9, ...)
  instead of the class's normal 1/5/9/13/17 schedule. Reflected in
  `unlocks.ancestry_feat_count`.
- `'free-archetype'` (GM Core p.84): one bonus archetype-only feat at
  every even level. Reflected in `unlocks.archetype_feat` -- when true,
  call build_list_available_feats(feat_category='archetype') for that
  slot specifically, in addition to whatever the normal class-feat slot
  allows this level.
build_to_pathbuilder_exportA

Wrap the working character representation as a Pathbuilder-compatible export. The working schema already follows Pathbuilder's build shape (per the user's decision -- see the plan's Pathbuilder-schema findings), so this is a normalize/strip pass rather than a full transform: drop any internal-only keys (none introduced in Phase 1) and wrap in the {success, build} envelope real exports use.

build_render_character_sheetA

Write a print-ready, fully self-contained HTML character sheet and return a summary of what went onto it.

The rendered file has no external dependencies of any kind -- fonts are
inlined as base64 WOFF2, all ornament is generated inline SVG, and there
is no stylesheet, script, or image fetched at view time -- so it can be
sent to a player as a single attachment and printed unchanged. Open it and
use the browser's own Print dialog (enable background graphics).

The HTML is written to `output_path` and deliberately not returned: a
real sheet runs to 150 KB or more, which would swamp a tool response.

Sections rendered, each only when the character data supports it:
core statistics (attributes, skills, AC and shield, saves, HP,
Perception, strikes, spell DC, conditions tracker); one spellcasting
page per entry in `spellCasters`, with every spell's complete rules text
and traits; features, led by a deity block where there is one (see below)
and then ancestry, heritage, background, level-appropriate auto-granted
class features, any detected subclass, and every feat; equipment with item
rules text; a notes page showing how each number was derived; and a licence
attribution page listing only the sourcebooks actually quoted.

The deity block distinguishes three cases, reported as `deity.status`:

* `none` -- the character follows no deity, including when the export
  writes its own placeholder ("Not set", an empty string, a dash). No
  block is rendered.
* `resolved` -- the recorded name matched the rules data. Renders every
  mechanical field the game defines (divine font, sanctification, skill,
  favored weapon, primary and alternate domains, divine attribute, and the
  deity's cleric spells resolved to names by rank) followed by its full
  descriptive text: title, areas of concern, edicts, anathema, iconography.
  Pantheons, covenants and philosophies resolve here too, labelled as such.
* `unrecognized` -- a name is recorded but isn't in the database, i.e. a
  home-game or non-standard pantheon. Renders a labelled block with ruled
  lines for the standard fields to be filled in by hand. This is *not*
  treated as a defect in the character data and is deliberately kept out
  of `unresolved`.

Everything is derived from `character` plus this project's ingested rules
data -- there is no authored commentary, so a sheet is exactly as complete
as the character export it came from. Two things follow from that worth
knowing before you call it:

* A character with no `spellCasters` block gets no spell pages, even if
  the class is a caster. Pathbuilder exports populate it; hand-written
  character JSON often doesn't.
* Class features come from the ingested `class_progression.granted_items`
  filtered to the character's level, because exports record only choices.
  A subclass (cleric doctrine, druid order) is recovered by matching the
  class's tagged option names against the character's free-text
  `specials`, which is best-effort -- check `subclass` in the result.

`paper` accepts 'letter' (default) or 'a4'; it sets the @page size, and
content reflows rather than being scaled.

`logo_path` embeds an image top-left on page 1 in place of the sheet's own
spiral mark -- intended for the Pathfinder logo from Paizo's Community Use
Package, which the Community Use FAQ permits on free fan material. Accepts
PNG, SVG, JPEG, GIF or WebP (not EPS or AI, which browsers can't display).
The bytes are embedded verbatim and scaled by height with automatic width,
so the logo is never recoloured, cropped or distorted -- the policy forbids
altering a logo's colour, typography, design or proportions, and permits
proportional resizing. Section headings keep the spiral, so the sheet still
has a mark of its own. Omit to use the spiral everywhere.

`symbol_dir` points at a directory of deity symbol images named after the
deity ("Pharasma.png"), such as Paizo's Community Use "Pathfinder Religious
Symbols" pack -- underscores in place of spaces are matched too, so
"Sun_Wukong.png" resolves. When the character's deity resolves and a
matching file exists, the symbol is embedded beside the deity block's stat
table, again scaled by height only. A missing symbol is not an error: the
block simply renders without one.

Returns a dict with the output `path` and `bytes`, the `sections` written,
counts of what was rendered, the detected `subclass`, the sourcebooks
quoted under each licence, and -- importantly -- `unresolved` names and
`warnings`. An item the export calls "Repair Kit" where the rules data has
"Repair Toolkit" is reported there rather than guessed at or dropped
silently, so treat a non-empty `unresolved` as something to fix in the
character data.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rjenks/pf2e-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server