MCPInstall

unity-package-management

Adds, removes, upgrades, and discovers Unity (UPM) packages from outside the Editor, with the Pipeline package commands first and a C script as the fallback. Use for package installs, verifying package IDs and versions, or choosing which packages a game needs.

Installs
51
Last 24h
—
Trending rank
—
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/unity-technologies/unity-agent-plugin --skill unity-package-management
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads unity-package-management automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

Unity Package Management (Pipeline commands first, C# script as the fallback)

Add, remove, upgrade, and discover UPM (Unity Package Manager) packages with the package commands of the project's Pipeline package, run through unity command. Only when no Editor can answer those commands, fall back to UnityEditor.PackageManager.Client driven headless from a script (see Fallback). Do not hand-edit Packages/manifest.json: the Package Manager resolves dependencies and compatible versions correctly, whereas manual edits routinely break resolution.

This complements the unity-cli skill (editor install, project creation, build/test), which documents unity command, unity status and unity pipeline install.

Use the package commands first

The Pipeline package registers a package command group: add, remove, list, resolve, search and status. They need a running Editor whose project has com.unity.pipeline (add it with unity pipeline install, then unity open, then wait with unity status --until-ready). Each command's parameters come from the Editor, so read them before the first call. Don't guess a parameter name.

unity status --until-ready --project-path "<project-path>"
unity command package --project-path "<project-path>"                  # the package commands this Editor has
unity command --query package --format json --project-path "<project-path>"   # each command's parameter schema
unity command package search --project-path "<project-path>"           # then pass the parameters the schema lists
unity command package add --project-path "<project-path>"              # add one or more packages by id
unity command package list --project-path "<project-path>"             # confirm what is installed

Pass a command's parameters after its name, as the schema names them (unity command <group> <command> --<parameter> <value>). Add every package you need in one package add call when the schema accepts several ids. Pin a version the way the schema describes when a minimum is required (the @<version> id form belongs to the C# fallback below). Use package status or package list to verify, and package remove to drop a package. Treat a non-zero exit as a failure and read its message.

If unity command package reports no such group, the project's Pipeline package predates it: run unity pipeline upgrade, or use the fallback below.

When to use

  • Add / remove / upgrade one or more packages in an existing or freshly-created project.
  • Set up a project's packages non-interactively in CI (fallback script when no Editor is running).
  • Verify a package id exists, or find its available versions, before depending on it.
  • Decide which packages a game actually needs — see references/select-packages.md.

Choosing what to install

Install what the project actually needs, not everything; prefer packages the chosen template already provides (URP templates already include the render pipeline, Input System, etc.). The genre / look / platform / monetization → package mapping, plus how to search the registry, is in references/select-packages.md. Produce a deduplicated list of package ids and read it back to the user before installing.

Fallback: no Editor to ask (the C# Client API)

Use this section only when package add can't run: no Editor is open and you don't want one open, the project has no Pipeline package, or the command group is missing and an upgrade isn't wanted. It installs through Client.AddAndRemove from a script the Editor runs in batch mode.

The -quit problem — why NOT unity run for installs

Client.Add / Client.AddAndRemove are asynchronous: they return a Request that only completes on later EditorApplication.update ticks (the UPM child process marshals its result back on the Editor's main-loop pump, so a blocking while (!req.IsCompleted) busy-wait deadlocks it). The Editor must stay alive after -executeMethod returns, until the request finishes.

unity run cannot be used for the installer: its default path injects -quit (see the reserved flags in the unity-cli skill). With -quit, the Editor quits the instant the method returns — before UPM resolves — so packages never install and the callback never runs.

Solution: launch the Editor binary directly in -batchmode without -quit. The Editor stays alive, EditorApplication.update keeps ticking, the poll callback runs, and it calls EditorApplication.Exit(code) itself when done — which both quits and sets the process exit code.

The installer script

Write this to Assets/Editor/ProjectBootstrap/PackageInstaller.cs. It must live under an Editor/ folder (or an Editor-only assembly) because it uses UnityEditor.

using System.Linq;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using UnityEngine;

namespace ProjectBootstrap
{
    // Installs (and optionally removes) a fixed set of packages via the PackageManager
    // Client API, headless-safe.
    public static class PackageInstaller
    {
        // EDIT this list to match the package selection (see references/select-packages.md).
        static readonly string[] PackagesToAdd =
        {
            "com.unity.inputsystem",
            "com.unity.cinemachine",
            "com.unity.render-pipelines.universal",
            // "com.unity.package@1.2.3"  // pin a version with @ when a minimum is required
        };

        // Optionally drop packages in the same resolution pass (e.g. a template default you don't want).
        static readonly string[] PackagesToRemove = { };

        const double TimeoutSeconds = 600; // UPM resolution + downloads can be slow

        static AddAndRemoveRequest _request;
        static double _deadline;

        // Invoke with: -executeMethod ProjectBootstrap.PackageInstaller.Install  (NO -quit)
        public static void Install()
        {
            if (PackagesToAdd.Length == 0 && PackagesToRemove.Length == 0)
            {
                Debug.Log("[PackageInstaller] Nothing to do.");
                EditorApplication.Exit(0);
                return;
            }

            Debug.Log($"[PackageInstaller] Adding: {string.Join(", ", PackagesToAdd)}");
            _request = Client.AddAndRemove(packagesToAdd: PackagesToAdd, packagesToRemove: PackagesToRemove);
            _deadline = EditorApplication.timeSinceStartup + TimeoutSeconds;
            EditorApplication.update += Poll;
        }

        static void Poll()
        {
            if (_request == null) return;

            if (!_request.IsCompleted)
            {
                if (EditorApplication.timeSinceStartup > _deadline)
                {
                    EditorApplication.update -= Poll;
                    Debug.LogError("[PackageInstaller] Timed out waiting for UPM.");
                    EditorApplication.Exit(2);
                }
                return;
            }

            EditorApplication.update -= Poll;

            if (_request.Status == StatusCode.Success)
            {
                var names = _request.Result.Select(p => $"{p.name}@{p.version}");
                Debug.Log($"[PackageInstaller] Resolved: {string.Join(", ", names)}");
                EditorApplication.Exit(0);
            }
            else
            {
                Debug.LogError($"[PackageInstaller] Failed: {_request.Error?.message}");
                EditorApplication.Exit(1);
            }
        }
    }
}

AddAndRemove installs the whole set in a single UPM resolution pass — faster and less error-prone than one Client.Add per package.

Add / remove / upgrade with one script:

  • Add: list the id in PackagesToAdd.
  • Remove: list the id in PackagesToRemove.
  • Upgrade / pin: add the id with @<version> (e.g. com.unity.cinemachine@2.9.7). Without a version, resolution picks the latest compatible release.

Discovering / verifying packages

To confirm an id exists or list its versions before adding it, search the registry. The in-Editor Client.SearchAll() / Client.Search("<id>") calls are also async, so they use the same poll-and-Exit pattern and the same headless run as the installer. Write Assets/Editor/ProjectBootstrap/PackageSearch.cs:

using System.Linq;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using UnityEngine;

namespace ProjectBootstrap
{
    public static class PackageSearch
    {
        const double TimeoutSeconds = 120;
        static SearchRequest _request;
        static double _deadline;

        // Invoke with: -executeMethod ProjectBootstrap.PackageSearch.SearchAll  (NO -quit)
        public static void SearchAll()
        {
            _request = Client.SearchAll();                 // or Client.Search("com.unity.cinemachine")
            _deadline = EditorApplication.timeSinceStartup + TimeoutSeconds;
            EditorApplication.update += Poll;
        }

        static void Poll()
        {
            if (_request == null) return;
            if (!_request.IsCompleted)
            {
                if (EditorApplication.timeSinceStartup > _deadline)
                {
                    EditorApplication.update -= Poll;
                    Debug.LogError("[PackageSearch] Timed out.");
                    EditorApplication.Exit(2);
                }
                return;
            }
            EditorApplication.update -= Poll;

            if (_request.Status == StatusCode.Success)
            {
                foreach (var p in _request.Result.OrderBy(p => p.name))
                    Debug.Log($"[PackageSearch] {p.name}@{p.versions.latestCompatible}  {p.displayName}");
                Debug.Log($"[PackageSearch] {_request.Result.Length} packages found.");
                EditorApplication.Exit(0);
            }
            else
            {
                Debug.LogError($"[PackageSearch] Failed: {_request.Error?.message}");
                EditorApplication.Exit(1);
            }
        }
    }
}

_request.Result is a PackageInfo[]; each entry exposes name, displayName, description, and versions (.latest, .latestCompatible, .all). For a terminal-only check without the Editor (a known id, not free-text search), query the registry directly — see references/select-packages.md.

Run it headless (direct Editor invocation, no -quit)

Resolve the Editor binary from the version, then run it in batch mode. The script owns quitting via EditorApplication.Exit, so do not pass -quit:

VERSION="<version>"          # e.g. 6000.0.47f1 (or an installed version)
PROJECT="<project-path>"
METHOD="ProjectBootstrap.PackageInstaller.Install"   # or ...PackageSearch.SearchAll

# Install directory of that editor (Hub layout), via the unity CLI
ED=$(unity editors path "$VERSION" --format json | python3 -c "import sys,json;print(json.load(sys.stdin)['data']['path'])")

# Resolve the executable per-OS (handles both "dir containing Unity.app" and the ".app" itself)
case "$(uname)" in
  Darwin) if [ -d "$ED/Unity.app" ]; then UNITY_BIN="$ED/Unity.app/Contents/MacOS/Unity";
          elif [[ "$ED" == *.app ]]; then UNITY_BIN="$ED/Contents/MacOS/Unity";
          else UNITY_BIN="$ED/Unity"; fi ;;
  Linux)  UNITY_BIN="$ED/Editor/Unity" ;;
  *)      UNITY_BIN="$ED/Editor/Unity.exe" ;;   # Windows (Git Bash / MSYS); use Editor\Unity.exe in PowerShell
esac

"$UNITY_BIN" -batchmode -projectPath "$PROJECT" -executeMethod "$METHOD" -logFile -
echo "Exit code: $?"   # 0 = success, 1 = UPM error, 2 = timeout

-logFile - streams the Editor log (including the [PackageInstaller] / [PackageSearch] lines) to stdout so you can watch resolution progress and read any UPM error. If unity editors path output shape differs on your build, get the directory from unity editors --installed --format json instead.

Verify

# Every requested id should appear as a dependency
cat "<project-path>/Packages/manifest.json"

Confirm the run exited 0 and each package from the list is present in manifest.json. If a package fails to resolve, _request.Error.message is logged; read it and check the id/version against the registry. The Editor's own log (including the [PackageInstaller] lines) is the stdout you streamed with -logFile - above — read it there, not via unity logs (which shows the CLI's own log, not the Editor's).

Import & save headlessly (generate .meta files)

After a script or tool writes new .cs/asset files, Unity must import them so it generates the .meta file each asset needs — and every .cs/asset MUST be committed together with its .meta. Merely opening the project once (unity open "<project-path>") imports and generates them; use this method when you need it headless (in a script or CI).

Unlike the package installer, this is synchronous — it finishes before returning — so it's safe to run via unity run (its injected -quit is harmless; the method also calls EditorApplication.Exit for a clean exit code). Write Assets/Editor/ProjectBootstrap/ProjectSaver.cs:

using UnityEditor;
using UnityEngine;

namespace ProjectBootstrap
{
    public static class ProjectSaver
    {
        // Invoke with: -executeMethod ProjectBootstrap.ProjectSaver.SaveAll
        public static void SaveAll()
        {
            AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
            AssetDatabase.SaveAssets();
            Debug.Log("[ProjectSaver] Assets imported and saved.");
            EditorApplication.Exit(0);
        }
    }
}
unity run "<project-path>" --editor-version <version> \
  -- -executeMethod ProjectBootstrap.ProjectSaver.SaveAll

Notes

  • These editor scripts are a bootstrap convenience. Leave them in Assets/Editor/ProjectBootstrap/ (they do nothing unless invoked) or delete them after setup — your call; mention it to the user.
  • All scripts live under Editor/ because they use UnityEditor; they never ship in a build.
  • Monetization / backend packages (com.unity.purchasing, com.unity.services.levelplay, the UGS packages) install through this same mechanism, but do the actual integration via the dedicated skills: implement-in-app-purchases, levelplay-unity-integration, build-live-game.

FAQ

What does the unity-package-management skill do?

Adds, removes, upgrades, and discovers Unity (UPM) packages from outside the Editor, with the Pipeline package commands first and a C script as the fallback. Use for package installs, verifying package IDs and versions, or choosing which packages a game needs.

How do I install unity-package-management?

Run npx skills add https://github.com/unity-technologies/unity-agent-plugin --skill unity-package-management in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/unity-package-management/ (personal) or .claude/skills/unity-package-management/ (project).

Which AI agents can use unity-package-management?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is unity-package-management safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains unity-package-management?

It is published by unity-technologies in unity-technologies/unity-agent-plugin. It has 51 recorded installs.

More from unity-technologies/unity-agent-plugin

View all →

unity-cli

unity-technologies/unity-agent-plugin

Controls the Unity Editor and projects from the command line, driving a running Editor to edit scenes and assets or run C. Use when asked to install or manage Editors, licenses, or projects, set up version control, build, test, configure the Unity MCP server, or run any unity command.

Backend & APIs54 installs

urp-postprocessing

unity-technologies/unity-agent-plugin

Sets up, configures, and debugs URP post-processing with the Volume framework. Use for bloom, tonemapping, color adjustments, depth of field, vignette, or other Volume overrides.

52 installs

ui-ugui

unity-technologies/unity-agent-plugin

Open the skill to read its SKILL.md instructions.

ui-uitk

unity-technologies/unity-agent-plugin

Open the skill to read its SKILL.md instructions.

new-unity-project

unity-technologies/unity-agent-plugin

Open the skill to read its SKILL.md instructions.

50 installs

localization

unity-technologies/unity-agent-plugin

Sets up and configures Unity Localization, including locales, String and Asset Tables, and CJK fonts. Use when the user asks to add languages, translate UI text, or mentions i18n or multilingual support.

Popular media & creative skills

View category →

hyperframes

heygen-com/hyperframes

Read first to make, edit, animate or render any video with HyperFrames (HTML rendered to video), including launch films, explainers, music videos, charts, maps, vertical clips, title cards, captions and overlays. Holds the render contract, the work loop and what each kind of video needs.

Media & Creative1.2M installs

media-use

heygen-com/hyperframes

Get or make any media for a HyperFrames video - music, sound effects, images, icons, logos, voiceover, avatar and generated video, transcripts, cutouts, colour grades and looks - with HeyGen or free local tools, and mix placed audio. Also for footage that looks dark, flat or dull, or should be stylized or hidden.

Media & Creative1.1M installs

hyperframes-registry

heygen-com/hyperframes

About 450 ready-made HyperFrames blocks and components installed as editable source - transitions, overlays, titles, kinetic type, captions, charts, map overlays, 3D, camera moves. Use it before hand-building any named visual (CRT scanlines, glitch, film grain, a chart); also for hyperframes add and catalog.

Media & Creative1M installs

hyperframes-creative

heygen-com/hyperframes

Non-animation creative direction for HyperFrames videos. Use for design spec (frame.md / design.md) handling, palettes, typography, narration, beat planning, audio-reactive visuals, composition patterns, and brand / style decisions. For atomic motion patterns and scene blueprints, use hyperframes-animation.

Media & Creative916.5K installs

ai-video-generation

101-skills/superpowers

Generate AI videos with Google Veo, Seedance 2.0, HappyHorse, Wan, Grok and 40+ models via inference.sh CLI. Models: Veo 3.1, Veo 3, Seedance 2.0, HappyHorse 1.0, Wan 2.5, Grok Imagine Video, OmniHuman, Fabric, HunyuanVideo. Capabilities: text-to-video, image-to-video, reference-to-video, video editing, lipsync, avatar animation, video upscaling, foley sound. Use for: social media videos, marketing content, explainer videos, product demos, AI avatars. Triggers: video generation, ai video, text to video, image to video, veo, animate image, video from image, ai animation, video generator, generate video, t2v, i2v, ai video maker, create video with ai, runway alternative, pika alternative, sora alternative, kling alternative, seedance, happyhorse

Media & Creative881.5K installs

ai-image-generation

101-skills/superpowers

Generate AI images with GPT-Image-2, FLUX, Gemini, Grok, Seedream, Reve and 50+ models via inference.sh CLI. Models: GPT-Image-2, FLUX Dev LoRA, FLUX.2 Klein LoRA, Gemini 3 Pro Image, Grok Imagine, Seedream 4.5, Reve, ImagineArt. Capabilities: text-to-image, image-to-image, inpainting, LoRA, image editing, upscaling, text rendering. Use for: AI art, product mockups, concept art, social media graphics, marketing visuals, illustrations. Triggers: flux, image generation, ai image, text to image, stable diffusion, generate image, ai art, midjourney alternative, dall-e alternative, text2img, t2i, image generator, ai picture, create image with ai, generative ai, ai illustration, grok image, gemini image, gpt image, openai image, chatgpt image

Media & Creative880.3K installs