Skip to content

Add headless JSON-RPC API for programmatic PoB access#9505

Open
ianderse wants to merge 1 commit intoPathOfBuildingCommunity:devfrom
ianderse:dev
Open

Add headless JSON-RPC API for programmatic PoB access#9505
ianderse wants to merge 1 commit intoPathOfBuildingCommunity:devfrom
ianderse:dev

Conversation

@ianderse
Copy link

@ianderse ianderse commented Mar 2, 2026

Changes/Additions to the headless/API layer to provide support for a WIP Path of Building MCP. Open to comments or suggestions!

Description of the problem being solved:

Changes

  1. Fix: save_build ascendancy class sync and gem persistence
  • Sync spec.curAscendClassName from live class data before saving, so the output XML always reflects the current ascendancy rather than a stale name from a previously-loaded file.
  • Re-process all socket groups before saving so gems added or modified via add_gem / set_gem_level / set_gem_quality are fully resolved and written correctly to the output XML.
  • Fix get_build_info to read className/ascendClassName from the correct fields (build.spec.curClassName / curAscendClassName) instead of non-existent build.buildClassName / build.buildAscendName.
  1. Fix: Extend set_config to support enemy resistance and condition toggles
  • Added enemy stat overrides: enemyFireResist, enemyColdResist, enemyLightningResist, enemyChaosResist, enemyArmour, enemyEvasion
  • Added charge toggles: usePowerCharges, useFrenzyCharges, useEnduranceCharges
  • Added condition flags: conditionFortify, conditionLeeching, conditionShockedGround
  • Added buff/enemy modifiers: buffOnslaught, enemyIsBoss

Steps taken to verify a working solution:

  1. Installed the MCP server backed by this API and connected it to Claude Code. Confirmed PoB starts in headless mode via the lua_start command triggered by the MCP in Claude Code
  2. Created a build from scratch via the API (new_build → set_tree → set_config → get_stats) and confirmed stats were calculated correctly.
  3. Loaded and modified an existing build (load_build_xml → set_gem_level / set_config → save_build) and verified the output XML reflected the changes.
  4. Directed Claude Code to create a new build and update an existing build through natural language — both completed successfully with correct PoB output.

Link to a build that showcases this PR:

https://github.com/ianderse/pob-mcp

Screenshots:

Only affects the headless layer, no changes to the main application necessary

- stdio JSON-RPC server (API/Server.lua) with ping, version, quit
- Handlers layer (API/Handlers.lua) dispatching to BuildOps
- BuildOps (API/BuildOps.lua) exposing: stats, tree get/set/delta,
  build info, level, config, skills/gems CRUD, items, save/export,
  node search, calc_with what-if
- set_config extended with enemy resistance/armour/evasion overrides,
  charge toggles, condition flags, buff and boss modifiers
- save_build syncs curAscendClassName and re-processes socket groups
  before serialising so gem edits and ascendancy changes persist correctly
- HeadlessWrapper: POB_API_STDIO/--stdio flag starts server, includes
  robust script-dir detection and utf8 fallback for external luajit runs
@tinycrops
Copy link
Contributor

I'm doing this too at github.com/tinycrops/assistant-poe but I'm not build an mcp. i've never used mcp. i don't see the need for mcp. it was just a good idea some developer at anthropic had before the models were as smart as they are now.

I would love to be shown why I'm wrong though.

@tinycrops
Copy link
Contributor

do you want to create an official poe app together? i need to get a client api key from them to get access to their api and do analytics. I'm doing a data analytics hackathon as well on devpost called ZerveHack

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants