Skip to main content
Glama

pxtk

Standalone commands and local MCP tools for Paradox modding. Look up game documentation and mod definitions, inspect dependencies, and check saved mod files with the Toolkit language server and Tiger. VS Code is optional. This project has its own repository and package; it shares its game knowledge and core tools with the Paradox Modding Toolkit.

Install

Download px-lsp-cli-0.1.0.tgz from the GitHub releases and install it with pnpm add -g ./px-lsp-cli-0.1.0.tgz. Then run pxtk --version and pxtk --help. Node 22.22.2 or newer is required. This initial release is distributed on GitHub; it is not published to npm.

For a source build:

Requires Node 22.22.2 or newer and pnpm. From this repository:

git clone https://github.com/JDeffner/paradox-toolkit-cli.git
cd paradox-toolkit-cli
pnpm install --frozen-lockfile
pnpm run compile
pnpm pxtk --help
pnpm pack --pack-destination .local/artifacts

Install the resulting tarball with pnpm add -g <tarball> to get the pxtk command. The package contains its own compiled LSP, per-game data, and licenses. It does not install the game or Tiger, and it makes no model API calls. The commands above build locally and do not publish anything.

Related MCP server: ACE-MCP

Configure a mod

For an existing mod, run pxtk init --game ck3 --mod <existing-mod> --json to preview its configuration. Apply the same request with --write --expect <previewToken> after reviewing it. For a new mod, use the new-mod workflow. init preserves existing configuration.

You can also create .px-toolkit/pxtk.json in the mod/project folder:

{
  "game": "ck3",
  "gamePath": null,
  "logsPath": null,
  "tigerPath": null,
  "parents": [],
  "language": "english"
}

Set the paths to your game data, generated script documentation and Tiger executable. A game installation root is accepted and normalized to its game folder. Omit gamePath for Steam discovery; null disables discovery. The selected game must be explicit. Profiles currently include ck3, vic3 and eu5; capabilities follow each profile, including whether Tiger is supported.

The nearest .px-toolkit/pxtk.json is found by walking upward from the current directory. Relative paths in that file use its project folder. An explicitly selected config outside .px-toolkit uses the config's own folder. The mod defaults to that folder. Keep local paths in an ignored config.

Flags override environment variables, which override the config. Supported variables are PX_GAME_ID and PX_<GAME>_GAME_PATH, _LOGS_PATH, _MOD_PATH, _TIGER_PATH, _TIGER_CONFIG, and _USER_DATA_PATH. Repeat --parent <folder> in dependency load order, base first. Explicit configuration errors are reported; they do not trigger discovery of another installation.

The CLI also reads portable .px-toolkit/project.json, localization.json, schema.json and playset.json. Each artifact falls back independently to the game's legacy config folder. Invalid project rules are reported. Structural and Tiger validation use the mod's diagnostic suppression rules; Tiger also respects inline suppressions. Editor machinePaths settings are private to VS Code and are not read by the CLI.

Localization defaults supply the language when neither a flag nor pxtk.json selects one. Create and loc set share the editor's placement rules: existing entries stay in place, configured destinations win for new keys, and meaningful siblings and established layouts guide automatic placement. A mod prefix alone does not select a file. New vanilla overrides require a replace folder. Generated localization files require their source workflow.

Commands

pxtk status --json
pxtk search add_gold --json
pxtk inspect add_gold --kind effect --json
pxtk read events/mymod_events.txt --start-line 1 --line-count 100 --json
pxtk impact my_effect --kind scripted_effect --json
pxtk validate --json
pxtk validate --write-baseline .px-toolkit/before-change.json --json
pxtk validate --baseline .px-toolkit/before-change.json --json

Use --limit (1 to 200, default 20) to bound returned matches or findings. Totals and truncation flags describe each list. --timeout bounds each server request and Tiger process. Run pxtk --help for all flags.

Status reports actual loaded sources and missing capabilities. Search returns identifiers and definitions. Inspect accepts an exact name and asks for a kind when meanings conflict. Impact describes callers from the editable mod and outgoing dependencies; read-only callers are outside its coverage. Its override list inherits the LSP catalog's 2000-entry cap.

Validation checks the selected mod's supported saved files and runs Tiger against the selected game. It reports structural diagnostics, Tiger findings, and tool failures separately. Baselines preserve occurrence counts while ignoring line movement, so moving code does not make an existing error new. Create a baseline as a JSON file in an existing directory inside the editable mod. An existing file is never replaced. Comparison rejects a different game version, validator, schema, documentation, dependency content, or configuration. A clean static report does not establish in-game behavior.

Validation's complete means structural checks and Tiger completed without a known compatibility rejection. compatibility.status: "unknown" means support for this game version is not certified. An explicit Tiger warning about a newer unsupported game sets compatibility.status: "unsupported", complete: false, and exit 2. Findings remain visible, but baseline creation and comparison are refused. Missing or failed Tiger also makes validation incomplete. Relative baseline paths resolve from the configured mod, including when the command runs elsewhere.

Exit codes: 0 completed without new errors; 1 new errors, no match, or ambiguity; 2 invalid configuration, unavailable validation, cancellation, or execution failure. Warnings remain in the report and do not set exit 1.

MCP and skills

Start the local stdio MCP server with:

pxtk mcp --config <config-file>

Only MCP messages go to stdout. Query tools are pxtk_status, pxtk_search, pxtk_inspect, pxtk_read, pxtk_impact, and pxtk_playsets. Validation uses pxtk_validate; its optional writeBaseline argument creates a baseline. Preparation tools are pxtk_new, pxtk_init, pxtk_create, pxtk_loc, pxtk_logs, pxtk_format, and pxtk_image; their explicit write mode changes mod files. pxtk_launch previews or starts the game with start and a preview token. These 15 tools declare input descriptions and output schemas. Indexed operations start a fresh LSP session and reuse its disk cache. Requests are serialized.

With pxtk on PATH, run one of these registrations from the configured mod folder. The syntax follows the installed clients' mcp add --help:

$configPath = (Resolve-Path .px-toolkit/pxtk.json).Path
# Codex CLI:
codex mcp add paradox-toolkit -- pxtk mcp --config "$configPath"
# Or Claude Code, local to this project:
claude mcp add --transport stdio --scope local paradox-toolkit -- pxtk mcp --config "$configPath"

plugins/paradox-toolkit contains Codex and Claude plugin manifests, the stdio connection configuration, and a portable Agent Skill. Install the CLI on PATH before loading the plugin. Clients supporting plain Agent Skills can load its skills/paradox-toolkit directory directly. This toolkit skill complements the separate Paradox AI Modding scripting, GUI and playtest skills.

For a local Claude plugin session, run claude --plugin-dir <absolute-path-to-plugins/paradox-toolkit> from the mod folder. That plugin includes its own MCP registration, so use it instead of the separate registration above. For Codex, copy the portable skills/paradox-toolkit directory to your project's .agents/skills/paradox-toolkit alongside the MCP registration. These setup instructions do not certify client behavior; verify tool discovery and a pxtk_status call in your client.

Write-capable tools retain write annotations even when called in preview mode. A noninteractive Codex session with approval disabled can reject such a preview unless that individual tool has explicit approval. Grant permission for the needed tool through the client's controls; a successful read call does not verify writer access.

MCP baseline creation is an explicit write request. Call pxtk_validate with these arguments before edits, then compare after edits:

{ "writeBaseline": ".px-toolkit/before-change.json" }
{ "baseline": ".px-toolkit/before-change.json" }

Do not add write: true to these validation calls. writeBaseline authorizes creation directly; it is mutually exclusive with baseline and never replaces an existing file.

Boundaries

Commands read saved files. They cannot see an editor's unsaved buffers. Read queries reject concurrent input changes. Utility writers check their source snapshots before applying edits. Game installations and dependency mods are reference inputs. Normal operations also maintain an LSP cache and temporary validator configuration.

Prepare mod content

Preparation writers show a preview until you add --write. Inspect its files and use its previewToken with --expect when applying the same options. Application recomputes the proposal from current saved files. Files are staged before writing. New files use exclusive creation; updates replace one file atomically. A batch is not a filesystem transaction: a write failure reports which files completed. Save editor buffers before applying disk edits.

For example, from a configured mod folder in PowerShell:

$createArgs = @("create", "event", "mymod.1", "--prefix", "mymod", "--json")
$preview = pxtk @createArgs | ConvertFrom-Json
if ($LASTEXITCODE -ne 0) { throw "Preview failed." }
$preview.data.files | Format-List file, action, content, contentTruncated
# Review the proposed files, then apply the same request and returned token.
pxtk @createArgs --write --expect $preview.data.previewToken

The equivalent calls to pxtk_create use these arguments. Replace <previewToken> with data.previewToken from the first response after inspecting data.files:

{ "kind": "event", "name": "mymod.1", "prefix": "mymod" }
{ "kind": "event", "name": "mymod.1", "prefix": "mymod", "write": true, "expect": "<previewToken>" }
pxtk init --game ck3 --mod <existing-mod> --json
pxtk create
pxtk create event mymod.1 --prefix mymod --json
pxtk loc get mymod_1_t --json
pxtk loc set mymod_1_t --value "A new title" --json
pxtk loc check --language german --json
pxtk format events/mymod_events.txt --check
pxtk format events/mymod_events.txt --json

Init creates .px-toolkit/pxtk.json for an existing mod and never replaces configuration. It saves the game, relative mod root and language; supply installation paths through environment variables or local configuration. Create lists supported kinds from the selected profile. CK3 and Victoria 3 expose their existing scaffold templates; EU5 currently exposes scripted effects and triggers, under its selected stage root. No unverified event template is supplied for EU5. Use --stage only for a stage listed by that game profile.

Create appends to compatible files and rejects duplicate mod definitions, localization keys and mismatched headers. Generated script and localization files have a UTF-8 BOM. Localization set preserves existing comments, versions, line endings and sibling entries. It updates an existing mod entry, places vanilla overrides in localization/replace, and puts new keys with their siblings. Use --file to resolve multiple mod destinations. Check reports the selected language's indexed missing keys and untranslated values; dynamic references can remain unknown. Formatting changes only leading indentation in script and GUI files. It does not format localization.

Create a new mod

new prepares a mod in an absent or empty destination. Its parent folder must exist. Metadata paths and starter folders come from the selected game profile. This PowerShell example keeps the scratch mod under .local/:

New-Item -ItemType Directory -Force .local/mods | Out-Null
$newArgs = @("new", ".local/mods/research-mod", "--name", "Research Mod", "--game", "ck3", "--json")
$preview = pxtk @newArgs | ConvertFrom-Json
if ($LASTEXITCODE -ne 0) { throw "Preview failed." }
$preview.data | ConvertTo-Json -Depth 8
# Review metadata, folders and nextSteps before applying.
pxtk @newArgs --write --expect $preview.data.previewToken

The destination is relative to the CLI or MCP process working directory. The resolver reuses the explicit or nearest project configuration but changes the editable mod to the destination. pxtk_new accepts output, name, optional supportedVersion, and the same write/expect preview flow. Configure the MCP server's game before calling it. New-mod creation requires a preview token to apply, rejects links and nonempty destinations, and creates the descriptor or metadata, .px-toolkit/pxtk.json, and profile-derived folders. It does not register the mod in a launcher or change launcher playsets. Follow the returned nextSteps, which depend on the profile's descriptor format. An unknown installed version defaults to *; review the declared version before distribution.

For pxtk_new, preview with the first argument object below. After inspecting that response, replace <previewToken> in the second object with its data.previewToken:

{ "output": ".local/mods/research-mod", "name": "Research Mod" }
{
  "output": ".local/mods/research-mod",
  "name": "Research Mod",
  "write": true,
  "expect": "<previewToken>"
}

Prepare images

pxtk image inspect art/icon.png --json
pxtk image convert art/icon.png --to dds --dds auto --output gfx/interface/icon.dds --json
pxtk image convert art --to dds --output gfx/interface/prepared --json
pxtk image convert art/icon.png --to png --width 128 --height 128 --fit contain --output prepared/icon.png --json
pxtk image convert art/icon.png --to jpeg --background "#ffffff" --output prepared/icon.jpg --json

Inputs can be DDS, TGA, PNG, JPEG or WebP. Outputs can be DDS, PNG, JPEG or WebP. Folder batches preserve subfolders, report unsupported files and reject output collisions. Destinations must be new files inside the editable mod. Source files remain unchanged.

Resize modes are contain (default, transparent padding), cover (crop to fill), inside (keep the image within the bounds), and fill (stretch). JPEG requires a background when pixels are transparent. DDS auto selects BC3 for transparency and BC1 otherwise; BGRA8 is also available. BC1 rejects transparent pixels. DDS output has one mip level, and existing mipmaps are not copied. Assets that require a complete mip chain need a converter that generates that chain before use in the game. Cubemaps, texture arrays, volumes and animated inputs are unsupported. The operation applies EXIF orientation and does not copy image metadata. Inspection reports dimensions, format, alpha channel and mip count.

The CLI uses Sharp for headless common-format decoding, encoding and resizing. Package installation supplies its native runtime; optional platform dependencies must be enabled. The toolkit's DDS and TGA codecs remain shared with the editor. There is no VS Code or external image-editor requirement. Limits are 200 images, 16 megapixels per image, 64 MiB per input file, and 256 MiB of compressed inputs per batch.

Launch a playset

List saved launcher playsets, ordered mods and profile presets without an editable mod:

pxtk playsets --game ck3 --json
pxtk launch --game ck3 --playset "<exact-ID-or-unique-name>" --arg=-debug_mode --json

Launch previews the executable, working folder, literal arguments and engine load settings. Review them, then repeat the same request with --start --expect <previewToken>. Launch uses --start, not --write. Extra arguments can also follow --; put CLI options before it. --preset <id> accepts only a preset returned by playsets. The installed launcher-settings.json supplies the executable and base arguments; the working folder is the executable's folder, and the game profile supplies SteamAppId.

For pxtk_launch, preview with the first object, then use its data.previewToken in the second after review:

{ "playset": "<exact-ID-or-unique-name>", "args": ["-debug_mode"] }
{
  "playset": "<exact-ID-or-unique-name>",
  "args": ["-debug_mode"],
  "start": true,
  "expect": "<previewToken>"
}

Installed launcher metadata and an existing engine load file are required. Listing or selecting saved playsets also requires the launcher database and saved playsets. Without --playset, launch preserves the current engine load file, which can differ from the launcher's active database playset. An explicit playset loads enabled mods in saved order and applies disabled DLC. It preserves unrelated load settings and enabledUGC, backs up a changed load file before writing, and restores it after a startup failure only if no later edit would be overwritten. The launcher database and active selection remain unchanged. Registered .mod archives have path checks; metadata-format archives are unsupported. The mod's .px-toolkit/playset.json remains a separate indexing overlay.

Use --user-data-path, config userDataPath, or PX_<GAME>_USER_DATA_PATH to inspect another user-data folder. Launch requires that folder to match the canonical location from launcher metadata's gameDataPath. Engine user-directory redirection is unsupported. A stale token or an already-running game rejects startup before changing load settings.

Windows launch has process-fixture coverage. Linux launch fixtures run in an isolated process namespace; a normal desktop can refuse launch with process_probe_failed if any same-user process is unreadable. This preserves duplicate-game protection. Real Linux game startup has not been tested; macOS startup is unsupported. The returned process state is a one-second observation. An initial exit with code 0 reports exited; running does not prove the mod loaded or gameplay works. Once started, the game remains open when the CLI or MCP caller disconnects.

Read playtest errors

$checkpointArgs = @("logs", "checkpoint", "--output", ".px-toolkit/before-playtest.json", "--json")
$preview = pxtk @checkpointArgs | ConvertFrom-Json
if ($LASTEXITCODE -ne 0) { throw "Preview failed." }
$preview.data.files | Format-List file, content
pxtk @checkpointArgs --write --expect $preview.data.previewToken
# Reproduce the behavior in the game.
pxtk logs --since .px-toolkit/before-playtest.json --json

Logs reads error.log from the profile's runtime log folder, which can differ from script_docs. Use --file to select a saved log. Checkpoints record file identity, a complete-line byte offset and a prefix hash. Rotation, truncation or rewriting resets the read and is reported. Incomplete final lines wait until a later read. Records spanning the checkpoint retain preceding context. Duplicate messages are grouped with occurrence counts and source locations; unparsed records remain visible. Checkpoint output files are created exclusively. The command reads at most 32 MiB and does not launch or control the game.

Focus queries and validation

pxtk inspect <identifier> --kind <kind> --examples --templates --json
pxtk impact <identifier> --kind <kind> --json
pxtk validate events/mymod_events.txt --json

Inspect's optional lists contain sourced examples and templates measured from documentation, harvested skeletons or indexed definitions. Empty template lists mean no supported template was found. Impact reports exact standard-LSP reference sites separately from callers grouped by definition, plus override candidates, ordering rules and the winner. Dynamic reference forms can be missed.

Supplying files to validate focuses structural checks. Tiger still checks the whole mod, and all its findings remain visible. The scope field states both scopes, and baseline compatibility includes the selected file set. This is not a full structural workspace pass.

Formatting, scaffolding, logs, initialization, new-mod creation, source reading and image preparation do not start the LSP. Localization and indexed queries use a fresh session and reuse its cache.

Inspect excerpts preserve file, line, contextStart, and context, with limits of 18 lines and 500 characters per line. truncated, omittedBefore, omittedAfter, and clippedLines identify missing text. Pass an excerpt's continuation object to pxtk_read to start reading the whole file. For CLI paging:

$page = pxtk read events/mymod_events.txt --line-count 100 --max-chars 16000 --json | ConvertFrom-Json
$page.data.text
if ($page.data.next) {
  pxtk read $page.data.file --start-line $page.data.next.startLine --start-column $page.data.next.startColumn --source-hash $page.data.sourceHash --json
}

Follow next.startLine and next.startColumn with the returned sourceHash until next is null. Concatenate text for lossless decoded content; context is display text. Positions are one-based UTF-16 columns, including CR characters in CRLF endings. Reading preserves line endings and strips a UTF-8 BOM; encoding is reported. The default page has at most 100 source lines and 16,000 characters, with maxima of 200 and 64,000. Files are limited to 16 MiB and supported text types under the canonical mod, dependency, or game-data roots. Binary files and links escaping these roots are rejected. A saved edit rejects hashed continuation with source_changed; restart the read.

Source labels identify generated dumps, bundled snapshots, or wiki data. They do not certify a documentation/game patch match. The toolkit's per-mod playset.json adds parents after the configured list, matching the LSP. Saved launcher playsets are used only by playsets and launch; they do not select indexed dependencies. An existing Tiger configuration controls Tiger dependency loading and suppressions; it takes precedence over generated dependency blocks.

The CLI, MCP and JSON result contract is documented in PROTOCOL.md. Developer checks live in test/; the real CK3 exercise is scripts/test-pxtk-real.ts.

The release audit records tested behavior, fixed defects, remaining limits and possible CLI additions from the editor Toolkit. The first release has automated CLI and MCP coverage; it does not certify gameplay or every game and platform combination.

Development

pnpm run compile
pnpm run typecheck
pnpm run lint
pnpm test
pnpm pack --pack-destination .local/artifacts
pnpm test:package .local/artifacts/px-lsp-cli-0.1.0.tgz

The package test installs the archive in an isolated folder and runs research, writing, image inspection and failure checks. For real CK3 validation, copy dev-paths.example.json to ignored dev-paths.json, configure the game-data folder and Tiger executable, and run pnpm test:real. The equivalent environment variables are PX_CK3_GAME_PATH, PX_CK3_LOGS_PATH and PX_CK3_TIGER_PATH. Game files remain read-only; generated mods and reports stay under .local/.

Shared Toolkit packages

The required server and protocol changes are not yet published on npm. This repository pins their package archives in vendor/toolkit-core/ so a fresh checkout can build without a second repository or machine-specific links. The manifest records the source revision, versions and SHA-256 checksums. Both archives include their matching src/ trees and licenses. The recorded upstream commit can be local until the Toolkit publishes it; the source archives here remain available with this release. These are upstream dependency snapshots, not a separate implementation of the game rules.

To refresh them from a Toolkit checkout with committed shared-core changes and installed build dependencies:

pnpm core:import <toolkit-checkout>
pnpm install

Then run the development checks above and review the archive manifest and lockfile changes. Maintain fixes in the Toolkit source. When matching core versions are published, registry dependencies can replace the archives. CLI releases bundle the core, game data and licenses; users do not need either source checkout.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI clients to perform local code search, indexing, and analysis across Java, JavaScript/TypeScript, .NET/C#, and Python projects through the MCP protocol.
    1
    Apache 2.0
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables MCP clients to inspect and operate MCreator workspaces through MCreator's Java APIs, supporting elements, generators, resources, and builds.
    -
  • A
    license
    C
    quality
    C
    maintenance
    Enables MCP clients to inspect, validate, test, export, and query Godot projects, including live state from an open editor via a bridge addon.
    20
    35 npm
    MIT