ROM Manager
CLI or API | MCP | Agent
Version: 2.0.1
Documentation — Installation, deployment, and usage across the API, CLI, and MCP interfaces, plus the integrated A2A agent server, are maintained in the official documentation.
⚠️ Back up your ROMs before working with this tool. Conversion and the
--delete/clean_origin_filesoptions are destructive to source files.
Table of Contents
- Overview
- Key Features
- Architecture
- Usage (CLI or API)
- MCP
- Agent
- Environment Variables
- Security & Governance
- External Binary Dependencies
- Installation
- Deployment (agent_server.py)
- Documentation
- Contributing
- License
Overview
ROM Manager is a production-grade ROM converter/organizer with an integrated
Model Context Protocol (MCP) server and Agent-to-Agent (A2A) agent. It extracts
archives, auto-renames ROMs via a known game-code registry, converts ISO/WBFS
images to CHD (chdman) or RVZ (dolphin-tool), generates missing .cue
sheets, and cleans up source files — in parallel.
It also speaks to RomM (CONCEPT:ROM-003) — a self-hosted
ROM library server — through a full REST client, so one rom-manager tool
manages both the files on disk (local conversion) and the web library (RomM).
The local conversion pipeline needs no service URL or credentials; the RomM
client is configured via ROMM_* environment variables.
Key Features
- Real conversion pipeline: parallel extract → rename → convert (CHD/RVZ) → cleanup.
- Full RomM REST client (
CONCEPT:ROM-003): complete coverage of the RomM API (roms, platforms, collections, saves, states, firmware, users, tasks, search, config, feeds, devices, …) with Basic/OAuth2 auth — one unified CLI and one action-routed MCP tool per resource group. - Consolidated Action-Routed MCP Tools: togglable domains (
conversion,game-codes,romm-*) minimize token overhead and IDE tool bloat. - Integrated Graph Agent: built-in Pydantic-AI agent (AG-UI / ACP).
- Native Telemetry & Tracing: OpenTelemetry exports out of the box.
- Lazy native deps: archive backends are optional extras, imported only when used.
Architecture
ROM Manager keeps a single, well-factored pipeline behind three entry surfaces
(CLI, MCP server, A2A agent). The orchestrator (RomManager) composes focused
responsibility layers and shells out to external conversion binaries:
flowchart LR
subgraph Entry["Entry Surfaces"]
CLI["CLI<br/>rom-manager"]
MCP["MCP Server<br/>rom-manager-mcp<br/>(CONCEPT:ROM-001/002)"]
AGENT["A2A Agent<br/>rom-manager-agent"]
end
CLI --> RM
MCP --> API["api_client.Api<br/>(facade)"]
AGENT --> MCP
API --> RM
subgraph Pipeline["RomManager orchestrator"]
RM["RomManager"] --> ARCH["archives.py<br/>extract + cue"]
RM --> NAME["naming.py<br/>game-code rename"]
RM --> CONV["conversion.py<br/>command + runner seam"]
end
ARCH --> P7Z["7z / patool"]
CONV --> CHDMAN["chdman (CHD)"]
CONV --> DOLPHIN["dolphin-tool (RVZ)"]
NAME --> CODES["game_codes.py<br/>(PSX registry, DATA)"]
| Layer | Module | Responsibility |
|---|---|---|
| Orchestrator | rom_manager/rom_manager.py |
Pipeline composition + CLI (RomManager, rom_manager()). |
| Archives | rom_manager/archives.py |
Archive detection, extraction, .cue generation. |
| Conversion | rom_manager/conversion.py |
chdman/dolphin-tool command building + runner seam. |
| Naming | rom_manager/naming.py |
Game-code lookup + in-place rename. |
| Data | rom_manager/game_codes.py |
Verbatim PSX serial→title registry (DATA). |
| Facade | rom_manager/api_client.py |
Api wrapper consumed by MCP tools/agent. |
Usage (CLI or API)
This package wraps a local ROM conversion pipeline (rom_manager.rom_manager.RomManager).
Use it via the CLI or the rom_manager.api_client.Api facade.
rom-manager --directory "/games/PSX/" --iso chd --verbose
| Flag | Long | Description |
|---|---|---|
-c |
--cpu-count |
Limit max CPUs for parallel processing |
-d |
--directory |
Directory to process ROMs |
-i |
--iso |
Conversion target: rvz or chd |
-f |
--force |
Force overwrite of existing .chd files |
-v |
--verbose |
Display all output messages |
-x |
--delete |
Delete original files after processing |
Detailed API usage is in docs/usage.md.
RomM web library (CONCEPT:ROM-003)
The same rom-manager command manages a running RomM server. Set ROMM_URL and
credentials (ROMM_USERNAME/ROMM_PASSWORD or ROMM_TOKEN), then use
rom-manager <resource> <action> [positionals] [--flag value …]:
rom-manager roms list --platform_ids 7 --limit 50 # list/search ROMs
rom-manager roms get 123 # positional id
rom-manager platforms list
rom-manager saves add --rom_id 5 --file_path ./game.srm
rom-manager tasks run scan # trigger a library scan
rom-manager stats # server statistics
Resources map 1:1 to RommApi methods. The on-disk converter is reachable as
before (bare flags) or via the explicit rom-manager convert … alias. From
Python, use rom_manager.get_romm_client() → RommApi.
MCP
This server utilizes dynamic Action-Routed tools to optimize token overhead and maximize IDE compatibility.
Available MCP Tools
The table below is auto-generated from the MCP server — do not edit by hand.
Condensed action-routed tools (default — MCP_TOOL_MODE=condensed)
| MCP Tool | Toggle Env Var | Description |
|---|---|---|
rom_conversion |
CONVERSIONTOOL |
Manage ROM conversion operations (CONCEPT:ROM-001). |
rom_game_codes |
GAME_CODESTOOL |
Manage ROM game code lookup and naming operations (CONCEPT:ROM-002). |
romm_collections |
ROMMTOOL |
|
romm_config |
ROMMTOOL |
|
romm_devices |
ROMMTOOL |
|
romm_feeds |
ROMMTOOL |
|
romm_firmware |
ROMMTOOL |
|
romm_platforms |
ROMMTOOL |
|
romm_roms |
ROMMTOOL |
|
romm_saves |
ROMMTOOL |
|
romm_screenshots |
ROMMTOOL |
|
romm_search |
ROMMTOOL |
|
romm_states |
ROMMTOOL |
|
romm_system |
ROMMTOOL |
|
romm_tasks |
ROMMTOOL |
|
romm_users |
ROMMTOOL |
Verbose 1:1 API-mapped tools (MCP_TOOL_MODE=verbose or both)
8 per-operation tools — one per public API method (click to expand)
| MCP Tool | Toggle Env Var | Description |
|---|---|---|
rom_manager_convert |
APITOOL |
Run the full parallel conversion pipeline over a directory (CONCEPT:ROM-001). |
rom_manager_generate_cue |
APITOOL |
Generate a missing .cue sheet for .bin tracks in a directory. |
rom_manager_list_files |
APITOOL |
List ROM/archive files under a directory matching extensions. |
rom_manager_list_game_codes |
APITOOL |
List known game codes, optionally filtered by a code prefix. |
rom_manager_lookup_game_code |
APITOOL |
Look up a single game code -> name in the PSX code registry. |
rom_manager_process_directory |
APITOOL |
Run the full parallel conversion pipeline over a directory (CONCEPT:ROM-001). |
rom_manager_process_file |
APITOOL |
Process a single ROM file through the conversion pipeline (CONCEPT:ROM-001). |
rom_manager_rename_by_game_code |
APITOOL |
Rename a file in-place using the embedded game code, if recognised. |
16 action-routed tool(s) (default) · 8 verbose 1:1 tool(s). Each is enabled unless its <DOMAIN>TOOL toggle is set false; MCP_TOOL_MODE selects the surface (condensed default · verbose 1:1 · both). Auto-generated — do not edit.
Dynamic Tool Selection
Each domain is gated by an environment toggle (default True). Set a toggle to
False to omit that tool from the registered surface.
Running the MCP server
# stdio (default)
rom-manager-mcp
# Streamable HTTP
rom-manager-mcp --transport streamable-http --host 0.0.0.0 --port 8000
Install the slim
[mcp]extra. The examples below installrom-manager[mcp]— the MCP-server extra that pulls only the FastMCP / FastAPI tooling (agent-utilities[mcp]). It deliberately excludes the heavy agent runtime (the epistemic-graph engine,pydantic-ai,dspy,llama-index,tree-sitter), souvx/container installs are dramatically smaller and faster. Use the full[agent]extra only when you need the integrated Pydantic AI agent (see Installation).
stdio client config
{
"mcpServers": {
"rom-manager": {
"command": "uvx",
"args": ["--from", "rom-manager[mcp]", "rom-manager-mcp"],
"env": { "ROM_DIRECTORY": "/games", "CONVERSIONTOOL": "True", "GAME_CODESTOOL": "True" }
}
}
}
Docker
docker run --rm -it -v /games:/games -e ROM_DIRECTORY=/games \
-p 8000:8000 -e TRANSPORT=streamable-http knucklessg1/rom-manager:mcp
The
:mcptag is the slim MCP-server image (built fromdocker/Dockerfile --target mcp, installingrom-manager[mcp]). The default:latesttag is the full agent image (--target agent,rom-manager[agent]) which also bundles the Pydantic AI agent and the epistemic-graph engine — use it when you runrom-manager-agent(the agent), not just the MCP server. See Container images.
Additional Deployment Options
rom-manager can also run as a local container (Docker / Podman / uv) or be
consumed from a remote deployment. The
Deployment guide has full, copy-paste
mcp_config.json for all four transports — stdio, streamable-http,
local container / uv, and remote URL:
- Local container / uv — launch the server from
mcp_config.jsonviauvx,docker run, orpodman run, or point at a local streamable-http container byurl. - Remote URL — connect to a server deployed behind Caddy at
http://rom-manager-mcp.arpa/mcpusing the"url"key.
Agent
ROM Manager ships a Pydantic-AI agent (rom-manager-agent) that calls the MCP
tool surface and exposes an AG-UI web interface. Its identity lives in
rom_manager/agent_data/IDENTITY.md.
rom-manager-agent --web
Environment Variables
Package environment variables
| Variable | Example | Description |
|---|---|---|
HOST |
0.0.0.0 |
|
PORT |
8000 |
|
TRANSPORT |
stdio |
options: stdio, streamable-http, sse |
AUTH_TYPE |
none |
Authentication mode for the MCP server (none for this local tool). |
FASTMCP_LOG_LEVEL |
ERROR |
FastMCP internal log verbosity (the server pins this to ERROR at startup). |
NO_COLOR |
1 |
Disable ANSI colour output in child tooling. |
TERM |
dumb |
Force a dumb terminal so progress bars / colour codes do not corrupt stdio. |
ENABLE_OTEL |
True |
|
OTEL_EXPORTER_OTLP_ENDPOINT |
http://localhost:8080/api/public/otel |
|
OTEL_EXPORTER_OTLP_PUBLIC_KEY |
pk-... |
|
OTEL_EXPORTER_OTLP_SECRET_KEY |
sk-... |
|
OTEL_EXPORTER_OTLP_PROTOCOL |
http/protobuf |
|
EUNOMIA_TYPE |
none |
options: none, embedded, remote |
EUNOMIA_POLICY_FILE |
mcp_policies.json |
|
EUNOMIA_REMOTE_URL |
http://eunomia-server:8000 |
|
ROM_DIRECTORY |
./roms |
Default directory of ROMs to process when none is supplied. |
ROM_ISO_TYPE |
chd |
Conversion target: chd (chdman) or rvz (dolphin-tool) |
ROM_VERBOSE |
False |
|
ROM_FORCE |
False |
|
ROMM_URL |
http://localhost:3000 |
any RomM (roms, platforms, ...) command or MCP tool. |
ROMM_USERNAME |
admin |
Credentials: Basic/OAuth username+password, or a pre-minted bearer token. |
ROMM_PASSWORD |
changeme |
|
ROMM_TOKEN |
— | |
ROMM_AUTH_MODE |
basic |
Auth mode: basic (default, no expiry) or oauth (password grant via /api/token). |
ROMM_SCOPES |
roms.read roms.write platforms.read |
Space-separated OAuth scopes (defaults to RomM's full read+write set). |
ROMM_SSL_VERIFY |
True |
|
AUDIENCE |
http://localhost:3000 |
Target audience for the exchanged token (defaults to ROMM_URL). |
DELEGATED_SCOPES |
roms.read |
Scopes requested for the delegated token. |
CONVERSIONTOOL |
True |
MCP tools table (condensed action-routed surface). |
GAME_CODESTOOL |
True |
|
ROMMTOOL |
True |
Master switch for the RomM remote-library tools. |
Inherited agent-utilities variables (apply to every connector)
| Variable | Example | Description |
|---|---|---|
MCP_TOOL_MODE |
condensed |
Tool surface: condensed |
MCP_ENABLED_TOOLS |
— | Comma-separated tool allow-list |
MCP_DISABLED_TOOLS |
— | Comma-separated tool deny-list |
MCP_ENABLED_TAGS |
— | Comma-separated tag allow-list |
MCP_DISABLED_TAGS |
— | Comma-separated tag deny-list |
MCP_CLIENT_AUTH |
— | Outbound MCP auth (oidc-client-credentials for fleet calls) |
OIDC_CLIENT_ID |
— | OIDC client id (service-account auth) |
OIDC_CLIENT_SECRET |
— | OIDC client secret (service-account auth) |
DEBUG |
False |
Verbose logging |
PYTHONUNBUFFERED |
1 |
Unbuffered stdout (recommended in containers) |
MCP_URL |
http://localhost:8000/mcp |
URL of the MCP server the agent connects to |
PROVIDER |
openai |
LLM provider for the agent |
MODEL_ID |
gpt-4o |
Model id for the agent |
ENABLE_WEB_UI |
True |
Serve the AG-UI web interface |
31 package + 14 inherited variable(s). Auto-generated from .env.example + the shared agent-utilities set — do not edit.
All settings are optional — ROM Manager runs with sensible defaults and requires
no credentials. Copy .env.example to .env to override.
Application Variables
| Variable | Default | Description |
|---|---|---|
ROM_DIRECTORY |
. (cwd) |
Default directory of ROMs to process when none is supplied. |
ROM_ISO_TYPE |
chd |
Conversion target: chd (chdman) or rvz (dolphin-tool). |
ROM_VERBOSE |
False |
Emit verbose conversion output. |
ROM_FORCE |
False |
Force overwrite of existing converted files. |
CONVERSIONTOOL |
True |
Toggle registration of the conversion MCP tool domain (CONCEPT:ROM-001). |
GAME_CODESTOOL |
True |
Toggle registration of the game-codes MCP tool domain (CONCEPT:ROM-002). |
ROMMTOOL |
True |
Toggle registration of the RomM MCP tool domains (CONCEPT:ROM-003). |
CPU count and "delete originals" are exposed as CLI flags (
--cpu-count/--delete) and MCP action params (cpu_count/clean_origin_files) rather than environment variables.
RomM Variables (CONCEPT:ROM-003)
Required only when using RomM (roms, platforms, … commands / romm_* tools).
| Variable | Default | Description |
|---|---|---|
ROMM_URL |
— | Base URL of the RomM instance (e.g. http://host:3000). Required for RomM. |
ROMM_USERNAME / ROMM_PASSWORD |
— | Basic or OAuth password-grant credentials. |
ROMM_TOKEN |
— | Pre-minted OAuth2 bearer token (takes precedence over username/password). |
ROMM_AUTH_MODE |
basic |
basic (no expiry) or oauth (password grant via /api/token, auto-refresh). |
ROMM_SCOPES |
RomM full set | Space-separated OAuth scopes requested when minting a token. |
ROMM_SSL_VERIFY |
True |
Verify TLS certificates. |
MCP / Framework Variables (agent-utilities)
| Variable | Default | Description |
|---|---|---|
HOST |
0.0.0.0 |
Bind host for HTTP/SSE transports. |
PORT |
8000 |
Bind port for HTTP/SSE transports. |
TRANSPORT |
stdio |
MCP transport: stdio, streamable-http, or sse. |
AUTH_TYPE |
none |
MCP authentication mode (this local tool needs none). |
FASTMCP_LOG_LEVEL |
ERROR |
FastMCP internal log verbosity (pinned at startup). |
ENABLE_OTEL |
True |
Enable OpenTelemetry export of traces/metrics. |
EUNOMIA_TYPE |
none |
Eunomia authorization mode: none, embedded, or remote. |
EUNOMIA_POLICY_FILE |
mcp_policies.json |
Path to the Eunomia policy file when embedded. |
Terminal Variables
These are set automatically by the server to keep stdio transport clean; you do not normally set them yourself.
| Variable | Default | Description |
|---|---|---|
NO_COLOR |
1 |
Disable ANSI colour codes in child tooling output. |
TERM |
dumb |
Force a dumb terminal so progress output does not corrupt the stdio channel. |
Security & Governance
- No credentials: ROM Manager is a local tool with no service URL/token.
- Eunomia policies & OpenTelemetry: inherited from the
agent-utilitiesmiddleware (see.env.example). - Destructive-op safety: the agent recommends backing up ROMs before
clean_origin_files/delete operations.
External Binary Dependencies
Conversion actions shell out to native tools (the Python package installs fine without them):
chdman(CHD) —apt install mame-tools(Ubuntu) or MAME tools on Windows.dolphin-tool(RVZ) — see the Dolphin emulator docs.7z/ archive backends (extraction) —apt install p7zip-full; pair with therom-manager[native]extra (patool).
Installation
Pick the extra that matches what you want to run:
| Extra | Installs | Use when |
|---|---|---|
rom-manager (core) |
CLI converter + Api facade (no server tooling) |
You only use the CLI / Python API |
rom-manager[mcp] |
Slim MCP server (agent-utilities[mcp] — FastMCP/FastAPI) |
You run the MCP server (smallest server install / image) |
rom-manager[agent] |
Full agent runtime (agent-utilities[agent,logfire] — Pydantic AI + the epistemic-graph engine) |
You run the integrated agent |
rom-manager[native] |
+ patool (archive extraction backends) |
You convert archived ROMs locally |
rom-manager[all] |
Everything (mcp + agent + native + otel) |
Development / all surfaces |
pip install rom-manager # core CLI + Api
pip install "rom-manager[mcp]" # + slim MCP server
pip install "rom-manager[agent]" # + A2A agent (Pydantic AI + epistemic-graph engine)
pip install "rom-manager[native]" # + patool (archive extraction)
pip install "rom-manager[all]" # everything
Container images (:mcp vs :agent)
One multi-stage docker/Dockerfile builds two right-sized images, selected by --target:
| Image tag | Build target | Contents | Entrypoint |
|---|---|---|---|
knucklessg1/rom-manager:mcp |
--target mcp |
rom-manager[mcp] — slim, no engine/pydantic-ai/dspy/llama-index/tree-sitter |
rom-manager-mcp |
knucklessg1/rom-manager:latest |
--target agent (default) |
rom-manager[agent] — full agent runtime + epistemic-graph engine |
rom-manager-agent |
docker build --target mcp -t knucklessg1/rom-manager:mcp docker/ # slim MCP server
docker build --target agent -t knucklessg1/rom-manager:latest docker/ # full agent
docker/mcp.compose.yml runs the slim :mcp server; docker/agent.compose.yml runs the
agent (:latest) with a co-located :mcp sidecar.
Knowledge-graph database (epistemic-graph)
The full agent ([agent] / :latest) embeds the epistemic-graph engine (pulled in
transitively via agent-utilities[agent]). For production — or to share one knowledge graph
across multiple agents — run epistemic-graph as its own database container and point the
agent at it instead of embedding it. Deployment recipes (single-node + Raft HA), connection
config, and the full database architecture (with diagrams) are documented in the
epistemic-graph deployment guide.
The slim [mcp] server and the core CLI do not require the database.
Deployment (agent_server.py)
rom-manager-agent (entry point rom_manager.agent_server:agent_server) starts a
Pydantic-AI A2A agent that auto-discovers the MCP tool surface from
mcp_config.json and can expose an AG-UI web interface.
# Local: web UI on the default host/port, OTEL enabled
rom-manager-agent --web --otel \
--provider openai --model-id gpt-4o-mini \
--host 0.0.0.0 --port 8080
Container deployment (compose):
# docker/agent.compose.yml (excerpt)
services:
rom-manager-agent:
image: knucklessg1/rom-manager:latest
command: ["rom-manager-agent", "--web"]
environment:
ROM_DIRECTORY: /games
TRANSPORT: streamable-http
HOST: 0.0.0.0
PORT: 8080
ENABLE_OTEL: "True"
AUTH_TYPE: none
volumes:
- /srv/roms:/games
ports:
- "8080:8080"
The MCP server (rom-manager-mcp) deploys the same way; see
docs/deployment.md for the full compose/Swarm recipes.
Documentation
Contributing
Contributions are welcome. Run pre-commit run --all-files before opening a PR.
Preserve the real conversion pipeline — wrap RomManager, do not break it.
License
MIT © Knuckles-Team
Deploy with agent-os-genesis
This package can be provisioned for you — skill-guided — by the agent-os-genesis
universal skill (its single-package deploy mode): it picks your install method, seeds
secrets to OpenBao/Vault (or .env), trusts your enterprise CA, registers the MCP
server, and verifies it — the same machinery that stands up the whole Agent OS, narrowed
to just this package. Ask your agent to "deploy rom-manager with agent-os-genesis".
| Install mode | Command |
|---|---|
| Bare-metal, prod (PyPI) | uvx rom-manager-mcp · or uv tool install rom-manager |
| Bare-metal, dev (editable) | uv pip install -e ".[all]" · or pip install -e ".[all]" |
| Container, prod | deploy knucklessg1/rom-manager:latest via docker-compose / swarm / podman / podman-compose / kubernetes |
| Container, dev (editable) | deploy docker/compose.dev.yml (source-mounted at /src; edits live on restart) |
Secrets are read-existing + seeded via vault_sync — you are only prompted for what's missing.
Metadata
Release files for rom-manager 2.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rom_manager-2.0.1.tar.gz | 133.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rom_manager-2.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 266.0 kB
Release files / rom_manager-2.0.1.tar.gz
| Download URL | rom_manager-2.0.1.tar.gz |
|---|---|
| Size | 133.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
51d5462ecb9a25d2b37af795d4cd8e9155738d486bfb205544448a3867f23506
|
|
BLAKE2b-256 checksum How to use checksums |
520403420879be5353a35e57655b4b1b7a56675f0fa714b0c13ada500e6cca11
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / rom_manager-2.0.1-py3-none-any.whl
| Download URL | rom_manager-2.0.1-py3-none-any.whl |
|---|---|
| Size | 132.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
97daef888667d22a0c613afd571f18f046829dbbdef7612c62f22e17dad517b3
|
|
BLAKE2b-256 checksum How to use checksums |
f3ec6cb13d7dbaa9c395cc1d29248704fb98cda4438f493e1139076343b017d3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|