The 'uloop' CLI Architecture
Relevant source files
The following files were used as context for generating this wiki page:
- Packages/src/Cli~/src/cli.ts
- Packages/src/Cli~/src/skills/skills-manager.ts
- Packages/src/Cli~/src/execute-tool.ts
- Packages/src/Cli~/package.json
- Packages/src/Cli~/scripts/generate-bundled-skills.ts
- README.md
- Packages/src/Editor/Api/McpTools/ExecuteDynamicCode/SKILL.md
- Packages/src/Cli~/src/tests/cli-e2e.test.ts
The uloop CLI is a standalone command-line tool that provides direct communication with a running Unity Editor instance equipped with the uLoopMCP package. It is designed to function independently of a Model Context Protocol (MCP) server, offering a scriptable and terminal-based interface to Unity's core functionalities like compilation, testing, and log retrieval.
A key feature of the uloop CLI is its integration with "Skills," which are discoverable command definitions that allow LLM-powered tools (like Claude Code) to automatically operate Unity. This dual-purpose design makes uloop a powerful utility for both human developers and AI agents, enabling complex, automated development loops directly from the command line.
Sources: README.md, Packages/src/Cli~/src/cli.ts
Core Architecture
The uloop CLI acts as a client that sends JSON-RPC requests over a TCP socket to a server running inside the Unity Editor. Its architecture is centered around a dynamic command system, where available tools are fetched from Unity and cached locally.
This diagram illustrates the high-level interaction between the user/agent, the uloop CLI, and the Unity Editor.
Command Lifecycle
The execution of a uloop command follows a specific lifecycle, from parsing user input to communicating with Unity and handling the response.
1. Entry Point and Parsing
The CLI's entry point is cli.ts, which uses the commander library to define the program structure and parse command-line arguments. It registers a set of built-in commands and then dynamically registers tool-based commands.
Sources: Packages/src/Cli~/src/cli.ts:21-25
2. Dynamic Command Registration
A core feature of the CLI is its ability to dynamically create commands based on tool definitions fetched from Unity. These definitions are stored in a local cache file at .uloop/tools.json.
When the CLI starts, it reads this cache and registers a command for each tool found. If a user tries to run a command that isn't registered, the CLI automatically triggers a sync operation to fetch the latest tools from Unity, updates the cache, and then attempts to execute the command again.
This flow is visualized below:
Sources: Packages/src/Cli~/src/cli.ts:511-533
3. Tool Execution
Once a command is parsed, the executeToolCommand function in execute-tool.ts is called. This function is responsible for:
- Finding the Unity project root to locate configuration files.
- Determining the correct TCP port to connect to.
- Establishing a TCP connection to the Unity Editor's server.
- Constructing a JSON-RPC request payload with the tool name and parameters.
- Sending the request and awaiting a response.
- Parsing the JSON response and printing it to standard output.
The following sequence diagram shows the tool execution process for uloop compile:
4. Error Handling
The CLI includes specific error handling for common Unity states that can prevent a connection. If the Unity server is busy (e.g., compiling, domain reloading), it may not respond. The CLI detects these states and provides user-friendly error messages instead of a generic connection failure.
| State | Error Message |
|---|---|
UNITY_COMPILING | ⏳ Unity is compiling scripts. |
UNITY_DOMAIN_RELOAD | ⏳ Unity is reloading (Domain Reload in progress). |
UNITY_SERVER_STARTING | ⏳ Unity server is starting. |
UNITY_NO_RESPONSE | ⏳ Unity is busy (no response received). |
ECONNREFUSED | Error: Cannot connect to Unity. |
Sources: Packages/src/Cli~/src/cli.ts:245-276
Built-in Commands
The CLI includes several built-in commands for managing the tool and its environment. These are distinct from the dynamic tool commands fetched from Unity.
| Command | Description | Source File |
|---|---|---|
list | Lists all available tools callable from the CLI. | cli.ts:32-37 |
sync | Fetches the latest tool definitions from Unity and updates the local cache. | cli.ts:39-44 |
skills | Manages "Skills" for LLM tool integration (install, list, uninstall). | cli.ts:63-64 |
completion | Generates and installs shell completion scripts (bash, zsh, powershell). | cli.ts:46-52 |
update | Updates the uloop-cli package to the latest version via npm. | cli.ts:54-58 |
fix | Cleans up stale lock files (compiling.lock, etc.) in the Temp directory. | cli.ts:60-61 |
Sources: Packages/src/Cli~/src/cli.ts:30-65
The Skills System
The "Skills" system is a key architectural component that makes uloop commands discoverable and usable by LLM agents, particularly within environments like Claude Code. A Skill is essentially a detailed, machine-readable documentation file (SKILL.md) for a CLI command.
Sources: README.md, Packages/src/Cli~/src/skills/skills-manager.ts
SKILL.md Format
Each skill is defined in a SKILL.md file. This file uses a YAML frontmatter block to define metadata, followed by a Markdown body for human-readable documentation.
| Frontmatter Key | Type | Description |
|---|---|---|
name | string | The unique identifier for the skill (e.g., uloop-compile). |
description | string | A concise description of what the tool does and when to use it. |
internal | boolean | If true, the skill is excluded from installation. |
Example from execute-dynamic-code:
---
name: uloop-execute-dynamic-code
description: Execute C# code dynamically in Unity Editor via uloop CLI. Use for editor automation...
---
# uloop execute-dynamic-code
Execute C# code dynamically in Unity Editor.
...
Sources: Packages/src/Editor/Api/McpTools/ExecuteDynamicCode/SKILL.md:1-5, Packages/src/Cli~/src/tests/skills-manager.test.ts:10-19, Packages/src/Cli~/scripts/generate-bundled-skills.ts:23-46
Skill Discovery and Bundling
To make skills easily accessible, a build script (generate-bundled-skills.ts) runs during the CLI's build process. This script scans the project for SKILL.md files, parses them, and bundles their content into a single TypeScript file: src/skills/bundled-skills.ts. This avoids filesystem I/O at runtime and packages all skill definitions within the distributable CLI bundle.
The bundling process is as follows:
Skill Management (skills command)
The uloop skills subcommand allows users to manage how these bundled skills are exposed to LLM tools.
uloop skills list: Shows all available skills.uloop skills install: Copies the skill definitions to a location where the LLM tool (e.g., Claude Code's.claude/skills/directory) can discover them.uloop skills uninstall: Removes the skill definitions from the LLM tool's directory.
This mechanism allows the LLM to know which commands are available and how to use them, effectively bridging the gap between natural language instructions and CLI execution.
Sources: README.md, Packages/src/Cli~/src/tests/cli-e2e.test.ts:258-301
Conclusion
The uloop CLI features a robust and extensible architecture. Its dynamic command system allows it to adapt to the tools available in any Unity project, while the sync mechanism ensures it stays up-to-date. The innovative "Skills" system abstracts CLI commands into a format that AI agents can understand and utilize, positioning uloop as a critical component for automating Unity development workflows. This dual focus on both human and AI interaction makes it a versatile and forward-looking tool.
Sources: Packages/src/Cli~/src/cli.ts, README.md