umdgencli-mcp
by quickstraw
README.md
# UMDGenCLI MCP Server
An MCP (Model Context Protocol) server that lets AI agents drive
[UMDGenCLI](https://github.com/quickstraw/UMDGenCLI) — the command-line tool for
creating and editing PSP UMD images (ISO / CSO / DAX). Every major function of
UMDGenCLI is exposed as a dedicated tool, so agents can build compilations,
save images, convert formats, patch, extract, and inspect without learning the
CLI syntax.
## Requirements
- Node.js 18+ (developed and tested on Node 22 / Windows)
- The UMDGenCLI executable (`umdgen-win-x64.exe` / `umdgen-win-x86.exe` /
`umdgen.exe`), from the [GitHub Releases page](https://github.com/quickstraw/UMDGenCLI/releases)
## Setup
```powershell
npm install
npm run build # compiles TypeScript into dist/
```
## Installing from npm (other PCs)
The server is published as the `umdgencli-mcp` npm package. On any machine with
Node.js, install it globally (or use `npx`), then point an MCP client at the
`umdgen-mcp` binary with the `UMDGENCLI_PATH` env var set to that machine's
UMDGenCLI executable:
```powershell
npm install -g umdgencli-mcp
```
```json
{
"mcpServers": {
"umdgencli": {
"command": "umdgen-mcp",
"env": {
"UMDGENCLI_PATH": "C:\\tools\\umdgen.exe",
"UMDGENCLI_CWD": "C:\\workspace\\psp-images"
}
}
}
}
```
No local build or install step is needed — the published package contains the
compiled server (`dist/`). The UMDGenCLI executable itself is not bundled; it
must exist on the target machine (it's self-contained, so no .NET runtime is
needed there either).
## Configuration
The server is configured entirely through environment variables:
| Variable | Required | Default | Description |
|---|---|---|---|
| `UMDGENCLI_PATH` | **yes** | — | Path to the UMDGenCLI executable. The server refuses to start without it. |
| `UMDGENCLI_STATE_FILE` | no | `<cwd>/.umdgen-mcp/umdgen.state` | Path of the persistent compilation state file. UMDGenCLI keeps the in-memory compilation (folder/file tree + volume metadata) in this file between invocations, so a compilation can be built up across many tool calls. |
| `UMDGENCLI_CWD` | no | server working directory | Working directory for the CLI subprocess. Relative paths in tool arguments (source files, output images) resolve against this. |
The server starts the CLI as a subprocess per tool call with `--state <file>`
prepended automatically. Call `umdgen_reset_session` to discard the current
compilation, and `umdgen_get_session` to see the active configuration.
## Registering with an MCP client
### Claude Desktop (`claude_desktop_config.json`)
```json
{
"mcpServers": {
"umdgencli": {
"command": "node",
"args": ["H:\\path\\to\\UMDGenCLI MCP\\dist\\server.js"],
"env": {
"UMDGENCLI_PATH": "H:\\path\\to\\umdgen.exe",
"UMDGENCLI_CWD": "H:\\workspace\\psp-images"
}
}
}
}
```
### Kilo (`kilo.json`)
```json
{
"mcp": {
"umdgencli": {
"type": "stdio",
"command": "node",
"args": ["H:/path/to/UMDGenCLI MCP/dist/server.js"],
"env": {
"UMDGENCLI_PATH": "H:/path/to/umdgen.exe",
"UMDGENCLI_CWD": "H:/workspace/psp-images"
}
}
}
}
```
### Cursor / generic
Any client that supports `stdio` MCP servers works the same way: run
`node <path-to-repo>/dist/server.js` with the environment variables above.
## Tools
All tools are prefixed with `umdgen_` (per MCP naming conventions, to avoid
collisions with tools from other MCP servers). All tools return the CLI's
stdout/stderr plus the process exit code; a non-zero exit code is surfaced as
an error result (`isError: true`). Every tool carries MCP annotations
(`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`) so
clients can show accurate approval prompts — e.g. `umdgen_set_version` is
marked destructive when patching in place, and `umdgen_reset_session` /
`umdgen_new_compilation` discard unsaved work. Outputs longer than 25,000
characters are truncated with a message telling the agent how to narrow the
result.
### Session & environment
| Tool | Description |
|---|---|
| `umdgen_get_session` | Show executable path, state file, working directory |
| `umdgen_reset_session` | Delete the state file and start a fresh compilation |
| `umdgen_get_version` | Print the UMDGenCLI version |
| `umdgen_get_help` | Show help (optionally for one command) |
| `umdgen_run_raw` | Escape hatch: run any command with raw arguments |
### Compilation building
| Tool | CLI equivalent |
|---|---|
| `umdgen_new_compilation` | `new` (label, padding, pad, no-pathtables, date) |
| `umdgen_open_image` | `open <image>` |
| `umdgen_add_file` | `add-file <src...> [--to <dir>]` |
| `umdgen_add_folder` | `add-folder <src...> [--to <dir>]` |
| `umdgen_new_folder` | `new-folder <name> [--to <dir>]` |
| `umdgen_rename_item` | `rename <path> <newname>` |
| `umdgen_delete_items` | `delete <path...>` |
| `umdgen_hide_items` / `umdgen_unhide_items` | `hide` / `unhide <path...>` |
| `umdgen_dummy_items` | `dummy <path...>` |
| `umdgen_dummy_search` | `dummy-search [image]` |
| `umdgen_optimize_image` | `optimize [image]` |
| `umdgen_relink_files` / `umdgen_relink_source` | `relink` / `relink-source` |
| `umdgen_move_lba` | `move-lba <file> <lba>` |
| `umdgen_set_label` | `set-label <label>` |
| `umdgen_set_date` | `set-date <yyyy-MM-dd>` |
| `umdgen_gen_umddata` | `gen-umddata [path]` |
### Display
| Tool | CLI equivalent |
|---|---|
| `umdgen_list_contents` | `list [image]` |
| `umdgen_show_tree` | `tree [image]` |
| `umdgen_show_props` | `props [image]` |
### Image operations
| Tool | CLI equivalent |
|---|---|
| `umdgen_image_info` | `info <image>` |
| `umdgen_dump_sfo` | `sfo <image>` |
| `umdgen_set_version` | `set-version <image> <version> [--out]` |
| `umdgen_save_image` | `save <out>` (+ format, level, nc, padding, pad) |
| `umdgen_extract_image` | `extract <image> <outdir> [paths...]` |
| `umdgen_convert_image` | `convert <in> <out>` (+ format, level, nc) |
| `umdgen_batch_convert` | `batch <outdir> <iso\|cso\|dax> <images...>` |
| `umdgen_apply_ppf` | `ppf-apply <image> <patch.ppf> [--file] [--out]` |
| `umdgen_export_iml` / `umdgen_import_iml` | `iml-export` / `iml-import` |
| `umdgen_create_image` | `create <dir> <out>` (one-shot build from a folder) |
| `umdgen_verify_image` | `verify <image>` |
## Agent workflow example
```
umdgen_get_session # confirm executable + state file
umdgen_reset_session # start clean
umdgen_new_compilation { label: "GAME001", padding: "umd" }
umdgen_new_folder { name: "PSP_GAME" }
umdgen_new_folder { name: "SYSDIR", to: "PSP_GAME" }
umdgen_add_file { src: ["EBOOT.BIN"], to: "PSP_GAME/SYSDIR" }
umdgen_add_file { src: ["PARAM.SFO"], to: "PSP_GAME" }
umdgen_list_contents # review the compilation
umdgen_save_image { out: "GAME001.iso", padding: "umd" }
umdgen_image_info { image: "GAME001.iso" } # inspect the result
umdgen_convert_image { input: "GAME001.iso", output: "GAME001.cso" }
```
## Notes
- **Paths**: relative paths in tool arguments resolve against
`UMDGENCLI_CWD` (or the server's working directory). Agents should prefer
absolute paths for source files and outputs.
- **`add-file` reads source data at save time**: the on-disk source files must
still exist when `save_image` runs.
- **`iml-import` only relocates existing files**: open the image (or build the
compilation) first, then import the IML to apply the listed LBA layout.
- **`set-version` and `ppf-apply` require raw ISOs**; CSO/DAX inputs are
rejected by UMDGenCLI itself.
- **`--padding umd`** reproduces UMDGen v4.00's output byte-for-byte; the
default is no padding.
## Tests
`test/run-tests.mjs` is an end-to-end suite that spawns the server over stdio,
builds a compilation from generated fixtures (including a valid PARAM.SFO),
and exercises every tool against a real UMDGenCLI executable:
```powershell
$env:UMDGENCLI_PATH = "H:\path\to\umdgen.exe"
node test\run-tests.mjs
```
## Evaluation
`test/evaluation.xml` contains 10 read-only, independent, verifiable questions
designed to measure how well an agent can use the server with no other
context. The corpus is deterministic:
```powershell
$env:UMDGENCLI_PATH = "H:\path\to\umdgen.exe"
npm run eval:fixtures # builds test/eval/work/eval1.iso, eval2.iso, eval2.cso
npm run eval:verify # solves all 10 questions through the server; asserts answers
```
To run the questions through an LLM harness (requires Python 3.10+ and an
`ANTHROPIC_API_KEY`), point it at the server with the working directory set to
`test/eval/work` so the relative image paths in the questions resolve. Any
standard MCP evaluation harness works — for example the one shipped with the
`mcp-builder` skill (install its dependencies with `pip install anthropic mcp`
first) — run against this server as:
```powershell
python evaluation.py `
-t stdio -c node -a dist/server.js `
-e UMDGENCLI_PATH=H:\path\to\umdgen.exe `
-e UMDGENCLI_CWD=test/eval/work `
test/evaluation.xml
```
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues