POB-MCP

Cargar, inspeccionar y optimizar builds de Path of Exile 2 usando el motor de cálculo real de Path of Building.

Documentación

pob-mcp

License: MIT Python 3.12+ PRs welcome Support on Ko-fi

pob-mcp es un servidor MCP. Permite que un LLM cargue, inspeccione, modifique y mejore builds de Path of Exile 2. Utiliza el motor de cálculo real de https://github.com/PathOfBuildingCommunity/PathOfBuilding-PoE2. No reimplementa ese motor.

pob-mcp ejecuta una copia real y sin interfaz gráfica de PoB (un programa Lua) como proceso en segundo plano. Se comunica con ese proceso mediante un pequeño protocolo JSON-RPC. Cada estadística que obtienes es un número que el propio PoB calculó.

Cómo funciona

MCP client (Claude Desktop, Cursor, ...)
        |  MCP over stdio
        v
   pob-mcp (Python)  -- tools_*.py, optimizer/
        |  JSON-RPC over stdio
        v
   lua/pob_bridge.lua  (running under `luajit`)
        |  dofile()
        v
   Path of Building - PoE2's own Lua source (Launch.lua, Main.lua, ...)

lua/pob_bridge.lua es un fork del propio src/HeadlessWrapper.lua de PoB, que PoB usa para su suite de pruebas. pob-mcp no depende directamente de ese archivo. Las copias instaladas de PoB omiten HeadlessWrapper.lua (ver manifest.cfg), así que pob-mcp incluye su propia versión. Esto significa que pob-mcp funciona de la misma manera tanto con un checkout de git de PathOfBuilding-PoE2 como con una versión de lanzamiento instalada.

Antes de empezar

Necesitas cuatro cosas:

  1. Una forma de instalar un paquete de Python. Recomendamos uv — es la vía más rápida y lo que el resto de este README muestra primero. ¿No quieres otra herramienta en tu máquina? Un pip normal y un entorno virtual también funcionan bien; consulta los comandos alternativos más abajo.
  2. LuaJIT, una compilación compatible con 5.1. Ponlo en tu PATH como luajit, o apunta a él con POB_MCP_LUAJIT. Lo necesitas por separado de PoB: el runtime propio de PoB solo incluye lua51.dll/SimpleGraphic.dll para su aplicación gráfica. No incluye un intérprete de línea de comandos que puedas ejecutar por sí solo.
    • Windows: instálalo con Scoop (scoop install luajit), Chocolatey (choco install luajit), o una compilación portable.
    • macOS: brew install luajit.
    • Linux: apt install luajit, el equivalente para tu distribución, o compílalo desde el código fuente.
  3. Una instalación de Path of Building - PoE2. Puede ser un checkout de git (este repositorio, o tu propio clon) o una versión de lanzamiento instalada. Consulta "Apunta pob-mcp a una instalación de PoB" más abajo.
  4. zlib. pob-mcp lo necesita para leer y escribir códigos de build, y para calcular datos de Joyas Atemporales. En Windows, ya lo tienes: PoB incluye zlib1.dll (en runtime/ para un checkout, o junto a todo lo demás para una versión de lanzamiento instalada). En Linux y macOS, instala el paquete zlib/libz de tu sistema si no lo tienes ya (la mayoría de los sistemas lo tienen). Si pob-mcp no puede encontrar zlib, todo sigue funcionando excepto los códigos de build pegados o compartidos y los cálculos de Joyas Atemporales. Carga y exporta builds como archivos .xml en su lugar.

Apunta pob-mcp a una instalación de PoB

pob-mcp necesita saber dónde tu instalación de Path of Building - PoE2 guarda su código fuente Lua, porque es contra lo que el proceso puente se ejecuta. Hay dos formas de apuntar hacia allí. Ten en cuenta que las dos tienen diseños diferentes en disco — pob-mcp detecta automáticamente cuál estás usando.

  • Modo checkout de desarrollo. Establece POB_MCP_SOURCE_DIR a un checkout de git de PathOfBuilding-PoE2 — ya sea su carpeta raíz, o su carpeta src directamente. Este diseño mantiene el código fuente Lua bajo src/, y mantiene el runtime nativo (DLLs de LuaJIT, zlib, las bibliotecas Lua incluidas) en una carpeta runtime/ separada junto a él.
  • Modo de lanzamiento. Establece POB_MCP_INSTALL_DIR a la carpeta raíz de una versión de lanzamiento instalada. En Windows, esto suele ser %APPDATA%\Path of Building Community (PoE2). Una versión de lanzamiento instalada pone todo en una sola carpeta — Launch.lua, Modules/, zlib1.dll, las bibliotecas lua/ incluidas — en lugar de dividirlo. (Verificamos esto contra una instalación real. No lo adivinamos solo desde la configuración de empaquetado del repositorio).

Si no estableces ninguna de las dos variables, pob-mcp verifica algunas ubicaciones de instalación comunes para tu sistema operativo, y te da un error claro si no puede encontrar una. En Windows, esto ya encuentra una copia instalada normalmente mediante el instalador sin ninguna configuración de tu parte.

Instala pob-mcp

git clone <this repo, or wherever you put pob-mcp> pob-mcp
cd pob-mcp
uv sync

¿No quieres usar uv? No lo necesitas. pob-mcp es un paquete normal de Python — un pip simple también funciona:

git clone <this repo, or wherever you put pob-mcp> pob-mcp
cd pob-mcp
python -m venv .venv
.venv/bin/pip install -e .        # Windows: .venv\Scripts\pip install -e .

Ejecútalo por sí solo (para pruebas)

POB_MCP_SOURCE_DIR=/path/to/PathOfBuilding-PoE2 uv run pob-mcp
# or, against an installed release:
POB_MCP_INSTALL_DIR="C:\Users\you\AppData\Roaming\Path of Building Community (PoE2)" uv run pob-mcp

Con una instalación simple de pip, lo mismo se ve así:

POB_MCP_SOURCE_DIR=/path/to/PathOfBuilding-PoE2 .venv/bin/pob-mcp   # Windows: .venv\Scripts\pob-mcp.exe

Esto inicia el servidor MCP a través de stdio. No verás mucho que pase — los servidores MCP hablan con clientes MCP, no directamente contigo. Consulta "Comprueba que funciona", más abajo, para una forma de probarlo sin un cliente completo.

Úsalo con Claude Desktop, Cursor u otro cliente MCP

Añade una entrada a la configuración del servidor MCP de tu cliente. Para Claude Desktop, esto es claude_desktop_config.json. Para Cursor, es mcp.json.

{
  "mcpServers": {
    "pob-mcp": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/pob-mcp", "run", "pob-mcp"],
      "env": {
        "POB_MCP_SOURCE_DIR": "/absolute/path/to/PathOfBuilding-PoE2"
      }
    }
  }
}

Para el modo de lanzamiento, usa POB_MCP_INSTALL_DIR en su lugar. Apúntalo a la carpeta raíz de tu versión de lanzamiento instalada — en Windows, normalmente %APPDATA%\Path of Building Community (PoE2):

{
  "mcpServers": {
    "pob-mcp": {
      "command": "uv",
      "args": ["--directory", "C:\\path\\to\\pob-mcp", "run", "pob-mcp"],
      "env": {
        "POB_MCP_INSTALL_DIR": "C:\\Users\\you\\AppData\\Roaming\\Path of Building Community (PoE2)"
      }
    }
  }
}

Reinicia tu cliente después de editar su configuración. No necesitas cerrar Path of Building en sí. pob-mcp solo lee datos del juego desde la carpeta de instalación. Nunca escribe en ella, así que funciona bien junto a la aplicación.

Con una instalación simple de pip (sin uv), apunta command directamente al ejecutable que pip creó en tu entorno virtual — no se necesita args:

{
  "mcpServers": {
    "pob-mcp": {
      "command": "C:\\path\\to\\pob-mcp\\.venv\\Scripts\\pob-mcp.exe",
      "env": {
        "POB_MCP_INSTALL_DIR": "C:\\Users\\you\\AppData\\Roaming\\Path of Building Community (PoE2)"
      }
    }
  }
}

(En macOS/Linux, eso es /path/to/pob-mcp/.venv/bin/pob-mcp.)

Variables de entorno

VariableQué hace
POB_MCP_SOURCE_DIRRuta a un checkout de git de PathOfBuilding-PoE2 (su carpeta raíz o src/)
POB_MCP_INSTALL_DIRRuta a la carpeta raíz de una versión de lanzamiento instalada
POB_MCP_LUAJITRuta a un ejecutable de luajit, si no está en PATH
POB_MCP_ZLIB_PATHRuta o nombre para cargar zlib, si pob-mcp no puede encontrarlo por sí solo
POB_MCP_BUILDS_DIRRuta a tu carpeta de Builds de PoB, para list_local_builds
POB_MCP_LOG_LEVELNivel de registro para el lado de Python (por defecto INFO); la salida del puente se registra en DEBUG

Qué puedes hacer con él

Una vez que tu cliente esté conectado, empieza con load_build. Luego usa las otras herramientas para inspeccionar, cambiar y mejorar el build. Cada herramienta que cambia el build también devuelve su stats actualizado, así que no necesitas una llamada separada a get_stats para ver el efecto de un cambio. La descripción completa de cada herramienta (parámetros, comportamiento, casos límite) aparece en tu cliente MCP — las listas de abajo son solo nombres y un resumen de una línea, para ayudarte a encontrar la correcta.

Una nota sobre los ids: las gemas y las clases se identifican por un id interno, no por su nombre mostrado. El id de gema de Fireball, por ejemplo, es "Metadata/Items/Gems/SkillGemFireball", y select_class toma un id de clase interno, no un índice simple basado en 0. Usa list_gems y list_classes para buscarlos en lugar de adivinar — un id de gema incorrecto no genera un error, simplemente falla silenciosamente al resolverse, así que la gema no hace nada.

Cargar un build (3 herramientas)
HerramientaQué hace
load_buildCarga un build desde un código de exportación de PoB, un enlace de pobb.in/Maxroll/poe.ninja/poe2db.tw/Pastebin.com/Rentry.co, una ruta local de .xml, o texto XML sin procesar
new_buildInicia un build nuevo y en blanco (clase por defecto, sin objetos ni habilidades)
list_local_buildsLista los archivos .xml en tu carpeta de Builds de PoB
Inspeccionar un build (13 herramientas)
HerramientaQué hace
get_statsObtiene estadísticas calculadas (vida, ES, maná, resistencias, DPS, EHP, etc.) del motor real de PoB
list_stat_keysLista cada clave de estadística disponible desde get_stats para este build
get_characterObtiene clase, ascendencia y nivel
list_classesLista cada clase y sus ascendencias, para usar con select_class
get_tree_stateObtiene los ids de nodos del árbol pasivo asignados y su cantidad
node_infoObtiene detalles de un nodo del árbol pasivo
search_treeBusca en el árbol pasivo por nombre, texto de estadística, tipo o ascendencia
get_itemsLista cada ranura de equipo/joya y lo que contiene
get_skillsLista los grupos de habilidades/engastes y sus gemas
list_gemsBusca el id interno de una gema, para usar con add_gem
get_configObtiene los valores actuales de las opciones de configuración
list_config_optionsLista cada opción de configuración que PoB soporta
sanity_checkEjecuta comprobaciones de sanidad defensivas (resistencias sin límite, vida baja, etc.)
Cambiar un build (13 herramientas)
HerramientaQué hace
alloc_node / dealloc_nodeAsigna o desasigna un nodo del árbol pasivo (ruta auto-calculada)
node_path_costObtiene el costo de puntos para alcanzar un nodo, sin asignarlo
select_classCambia clase y/o ascendencia
equip_item_raw / unequip_itemEquipa texto de objeto en bruto del juego en una ranura, o elimina lo que hay
add_socket_groupCrea un nuevo grupo de habilidades/engastes vacío
set_main_skillEstablece qué grupo de engastes se usa para los cálculos de DPS
add_gem / remove_gem / set_gemAñade, elimina o edita el nivel/calidad/estado habilitado de una gema
list_valid_supportsLista las gemas de soporte que PoB considera válidas para una habilidad
set_configEstablece una opción de configuración
Gestionar especificaciones de árbol y conjuntos de equipo (12 herramientas)

Un build puede contener varias especificaciones de árbol pasivo con nombre y varios conjuntos de equipo con nombre, y cambiar entre ellos. Una vez que cambias uno, cada otra herramienta (get_tree_state, get_items, etc.) actúa sobre aquel al que cambiaste.

HerramientaQué hace
list_specsLista las especificaciones de árbol pasivo del build
select_specCambia la especificación de árbol pasivo activa
create_specCrea una nueva especificación de árbol pasivo en blanco
copy_specDuplica una especificación de árbol pasivo
rename_specRenombra una especificación de árbol pasivo
delete_specElimina una especificación de árbol pasivo (un build siempre necesita al menos una)
list_item_setsLista los conjuntos de equipo del build
select_item_setCambia el conjunto de equipo activo
create_item_setCrea un nuevo conjunto de equipo vacío
copy_item_setDuplica un conjunto de equipo
rename_item_setRenombra un conjunto de equipo
delete_item_setElimina un conjunto de equipo (un build siempre necesita al menos uno)
Mejorar un build (1 herramienta)
HerramientaQué hace
optimize_buildEjecuta una búsqueda dirigida por objetivos (damage/defence/balanced) sobre el árbol pasivo, gemas de soporte y objetos únicos locales, puntuando cada cambio candidato contra el motor real de PoB
Comparar o exportar (2 herramientas)
HerramientaQué hace
compare_buildsCompara dos builds lado a lado, sin tocar el build cargado en esta sesión
export_buildExporta el build cargado como XML o un código compartible

Lo que esto no hace (a propósito)

Estas son decisiones, no errores:

  • El optimizador nunca cambia las opciones de configuración (buffs, maldiciones, estadísticas de enemigos, modificadores de mapas). Si pudiera, podría aumentar su propia puntuación asumiendo un escenario poco realista. Llama tú mismo a set_config primero si quieres optimizar para un escenario específico.
  • La búsqueda de objetos y joyas solo usa la base de datos local de PoB. El alcance de items de optimize_build prueba objetos de la base de datos única incluida de PoB, para la misma ranura. No consulta precios de sitios de comercio, ni busca opciones de creación de objetos raros.
  • El optimizador no busca joyas por sí solo. Emparejar una joya con el enchufe correcto aún no es lo suficientemente fiable. Puedes probar una joya específica manualmente: usa list_uniques_for_slot y luego equip_item_raw.
  • El optimizador es una búsqueda codiciosa, no un solucionador perfecto. Solo añade nodos del árbol — nunca elimina ni reemplaza los existentes — y solo intercambia una gema u objeto a la vez. Puede quedarse atascado en una respuesta buena pero no óptima que una búsqueda más amplia podría superar.
  • pob-mcp no puede importar un perfil de personaje en vivo de poe.ninja. Puede importar un pob-link de poe.ninja igual que cualquier otro sitio compatible, pero un perfil de personaje en vivo es diferente: necesita la API oficial de personajes, y esta versión aún no se comunica con esa API. Exporta el personaje a un código o enlace de PoB primero, y usa eso en su lugar.
  • pob-mcp no vigila tu carpeta de Builds para detectar cambios. list_local_builds lista lo que hay allí cuando lo llamas. No envía actualizaciones cuando algo cambia. Para una sesión impulsada por LLM, llamar a la herramienta de nuevo es más simple y funciona igual de bien.

Comprueba que funciona

Las pruebas automatizadas (ejecutadas con uv run pytest) vienen en dos grupos:

  • Pruebas que no tocan PoB en absoluto (test_importers.py, test_optimizer_goals.py, test_optimizer_moves.py, test_locate.py). Estas se ejecutan en cualquier lugar — no necesitas LuaJIT ni una instalación de PoB.
  • test_bridge_protocol.py ejecuta un proceso de puente real de principio a fin: inicia una nueva build, busca en el árbol, asigna y desasigna nodos, guarda y recarga, lista opciones de configuración y ejecuta una verificación de cordura. Si no puede encontrar POB_MCP_SOURCE_DIR, POB_MCP_INSTALL_DIR, o un ejecutable de luajit, se omite a sí mismo y te dice por qué. Configura esas variables de entorno para ejecutarlo realmente.

Para probar el puente manualmente, sin un cliente MCP completo:

cd /path/to/PathOfBuilding-PoE2/src
luajit /absolute/path/to/pob-mcp/lua/pob_bridge.lua

Luego escribe (o introduce mediante tubería) solicitudes JSON-RPC, una por línea:

{"id": 1, "method": "new_build", "params": {}}
{"id": 2, "method": "get_stats", "params": {}}

Cada una debería imprimir de vuelta una línea {"id": ..., "result": {...}}.

Dónde están las cosas

pob-mcp/
  lua/
    json.lua          # self-contained JSON codec for the bridge protocol
    pob_bridge.lua     # the headless PoB bridge + JSON-RPC loop
  src/pob_mcp/
    server.py          # MCP server entrypoint, tool registration
    bridge.py           # subprocess + JSON-RPC client for pob_bridge.lua
    locate.py           # finds a PoB install + luajit
    sites.py            # pobb.in/Maxroll/poe.ninja/etc. URL -> build code
    importers.py         # unifies code/URL/file/XML into one load_build path
    tools_*.py            # MCP tool definitions, grouped by area
    optimizer/             # goal-directed build search
  tests/