Skip to main content
Glama
VM233
by VM233

VM Unity MCP

VM Unity MCP is an independently maintained Unity Editor bridge for structured, queue-safe MCP automation. It provides route-specific tools for Unity assets, scenes, UI Toolkit, packages, builds, tests, diagnostics, and project-defined workflows.

This project was originally derived from AnkleBreaker Studio's Unity MCP Plugin and retains its license and attribution requirements. Powered by AnkleBreaker MCP.

Installation

VM Unity MCP is the Editor half of the connection. For a first-time setup, follow the companion server's complete installation and MCP host configuration guide. That guide covers Node.js, Codex, the ChatGPT desktop app, Claude Desktop, multiple projects, reconnects, and the final health check. This README covers the Unity package itself.

Requirements

  • Unity 2021.3.18f1 or newer.

  • Unity MCP Server 9.x for VM Unity MCP 10.x. The current matching releases are server 9.2.3 and package 10.1.1.

  • Git available to Unity Package Manager.

The bridge and server negotiate their supported version ranges. A mismatched major release fails with incompatible_stack; do not work around that error by switching routes or bypassing the server.

Add the package

In Unity, open Window > Package Manager, choose Add package from git URL..., and enter the current compatible release tag:

https://github.com/VM233/VMUnityMCP.git#v10.1.1

For an immutable project pin, resolve that release tag and replace it with the release's full 40-character commit SHA.

Keep this Git URL in Packages/manifest.json and let Package Manager maintain Packages/packages-lock.json. Do not edit Library/PackageCache or turn the package into an embedded copy.

Configure and verify the bridge

After package import finishes:

  1. Use Project Settings > Unity MCP for team-owned context and tool defaults.

  2. Use Preferences > Unity MCP for local bridge startup, ports, response limits, histories, and enabled categories.

  3. Leave automatic ports enabled unless a fixed port is required. The bridge listens on 127.0.0.1; its initial automatic range is 7890-7899.

  4. Configure the companion server with the exact Unity project root in UNITY_MCP_PROJECT_PATH, then restart or reconnect the MCP host.

  5. Call unity_mcp_health and confirm the intended project and a compatible server/plugin stack. Then use unity_tools_search and unity_tools_get to confirm the project-bound typed catalog is available.

Projects using VMFramework can install the optional VMFramework MCP package after this base connection works. It joins the same catalog and does not need a second server entry.

Related MCP server: Agent Bridge for Unity

Capability model

The public MCP surface is generated from live Editor metadata rather than a hand-maintained README list. This prevents installed Unity packages, Unity versions, and the currently selected project from producing stale concrete tools.

The built-in catalog comes from one typed descriptor registry. Each descriptor owns execution, deferred dispatch, description, profile, input schema, and output schema. Optional package assemblies contribute typed providers without making the core assembly depend on those packages, and reading metadata does not initialize the HTTP listener.

Area

Contract

Discovery

_meta/capabilities reports package/version-gated integrations. Paginated _meta/tools is the only canonical Unity/package/project catalog.

Client binding

One companion-server stdio connection binds to one project and publishes that project's complete typed catalog in its first successful tool list.

Built-in tools

Every available route has one typed name, full input/output schemas, module/capability/operation metadata, effects, and preconditions.

Project extensions

Every valid project/package tool is cataloged at project-tools/call/<toolName> and is published as an ordinary typed tool. Typed DTOs generate the schema and nominal data-product bindings.

Multi-instance safety

Each connection has one immutable normalized absolute projectPath/build/catalog binding. projectName is display metadata only, so same-name checkouts remain independent; agent ids only own and schedule queue work.

Long work

Builds, tests, workspace refresh/package operations, package tests, snapshots, Addressables builds, execute-code, and long project tools use persistent jobs or tickets; owned cancel routes are cooperative.

Optional integrations

Localization, Shader Graph, VFX Graph, Addressables, Timeline, Cinemachine, Build Profiles, and Unity 6.4+ Project Auditor publish only when their capability is available.

Common asset-authoring composition is intentionally available without arbitrary Editor code: create folders, copy assets, and create Prefab Variants; inspect a Prefab hierarchy; apply one atomic Prefab transaction; then create or update framework-owned configuration through a project/package tool. Localization entry upsert and removal are concrete tools when Unity Localization is installed. Project code should not retain one-off Editor builders that mirror checked-in asset values; temporary migrations are removed after asset readback succeeds.

Successful asset/delete operations save asset changes produced by Unity deletion callbacks before returning. Dependent configuration such as Addressables entries is therefore persisted together with the deletion instead of remaining only in the current Editor session.

Filename-changing asset/rename and asset/move operations keep Sprite asset identity coherent as well as preserving the .meta GUID. Single Sprite names follow the filename. Multiple Sprite names that use the previous filename as their prefix are migrated to the new prefix while retaining every Sprite ID, so AnimationClip and Prefab references remain valid.

Major route families include:

  • scene workspaces, GameObjects, components, Prefabs, materials, importers, and serialized assets;

  • UI Toolkit authoring, static audits, runtime inspection, screenshots, and visual comparison;

  • Animator, Audio Mixer, VFX Graph, Shader Graph, Timeline, Cinemachine, Addressables, Localization, Physics 2D/3D, terrain, lighting, and navigation;

  • Console, compilation, debugger, Profiler, testing, builds, packages, jobs, queue diagnostics, and Editor execution.

Shader Graph inspection treats the graph's GraphData node, property, and edge references as authoritative. Texture properties report authoring flags that can change generated shader declarations, while scalar graph-object edits validate the existing field and type, synchronously import, verify readback, and roll back on failure.

Use live tool metadata for exact names and schemas. Do not copy a tool list from this README into a client manifest.

Programmatic UI Toolkit audits

Editor integrations can consume the same USS and UXML analysis used by the MCP tools through the typed UIToolkitAuditor API. This avoids coupling Project Auditor, CI, or package integrations to MCP request and response dictionaries:

using System;
using UnityMCP.Editor;

UIToolkitAuditReport ussReport = UIToolkitAuditor.AuditUssStyles(
    Array.Empty<string>(), includeSuppressed: false,
    maxFindings: UIToolkitAuditor.MaximumFindingCount);
UIToolkitAuditReport uxmlReport = UIToolkitAuditor.AuditUxmlLayouts(
    Array.Empty<string>(), includeSuppressed: false,
    maxFindings: UIToolkitAuditor.MaximumFindingCount);

An empty path collection audits every asset in the project-owned scope. Specific project-relative paths audit only those targets while retaining the configured UXML, USS, runtime-source, PanelSettings/TSS, and suppression indexes. Each immutable finding supplies AssetPath, Line, RuleId, Message, and suppression state. Reports separately expose source/configuration errors and whether the requested finding limit truncated the result.

Initial-style no-op detection uses Unity's own USS importer and computed initial style instead of a plugin-maintained property list. It therefore covers the engine's current non-inherited longhand and shorthand properties; inherited properties remain parent-cascade owned and are not treated as element-local defaults.

The shared scope and policy remain authoritative in ProjectSettings/UnityMCPUIToolkitAudit.json; programmatic consumers do not maintain a second configuration.

Project Auditor reports

On Unity 6.4 or newer, unity_project_auditor_audit starts a new Project Auditor analysis through Unity's public API and returns the resulting issues. It uses the saved Project Auditor rule settings, but it does not read the Project Auditor window's previous report or its current UI filters.

The typed request can restrict analyzed categories and can filter returned issues by exact descriptor ID or resolved severity. Results are sorted by asset path, line, descriptor ID, and description before applying offset and limit; the default page size is 100 and the maximum is 500. Each issue includes its descriptor ID, category, severity, log level, description, source location, and optional custom properties. Registered project analyzers and rules supplied by packages such as com.unity.project-auditor-rules flow through the same report; that rules package is not required for the tool to be available.

Project extensions

Project-specific workflows can live in an Editor assembly in the project or in another package:

using System.ComponentModel;
using UnityMCP.Editor;

// Keep each public type in its own source file in production code.
[MCPDataProduct("example.content-ref")]
public sealed class ContentReference
{
    [MCPRequired, MCPJsonProperty("id"), MCPMinLength(1)]
    [Description("Registered content id.")]
    public string Id { get; set; }
}

public sealed class AddContentRequest
{
    [MCPRequired, MCPJsonProperty("id"), MCPMinLength(1)]
    [Description("Content id to create.")]
    public string Id { get; set; }
}

public sealed class AddContentResult
{
    [MCPRequired, MCPJsonProperty("content")]
    [Description("Authoritative reference to the created content.")]
    public ContentReference Content { get; set; }
}

public static class ProjectMcpTools
{
    [MCPProjectTool("example/add-content",
        Description = "Create and register one example content asset.",
        ModuleId = "example",
        Capability = "content",
        WhenToUse = "Use when the project needs one registered content asset.",
        SearchTerms = new[] { "content", "authoring", "register" },
        SideEffects = MCPProjectToolSideEffect.WritesAssets,
        ErrorCodes = new[] { "content_id_conflict" },
        MutatesAssets = true)]
    public static AddContentResult AddContent(AddContentRequest request)
    {
        return new AddContentResult
        {
            Content = new ContentReference { Id = request.Id }
        };
    }
}

The request and result types are the only schema authority for typed tools. Do not add InputSchemaJson or OutputSchemaJson to them. A tool that deliberately uses Dictionary<string, object> must instead declare complete exact input and output schemas; open or opaque executable contracts are rejected.

Apply the same MCPDataProduct id to the shared reference type returned by a producer and accepted by a consumer. The companion server validates that every occurrence has the same structure and reports the exact producer-result and consumer-input JSON pointers. Both tools are already ordinary advertised tools; the server does not insert a generic executor between them.

Declare exactly one operation kind: ReadOnly, MutatesAssets, MutatesRuntime, or MutatesProjectFiles. Use MutatesProjectFiles for writes to project-owned files outside Unity's Assets database, such as generated reports or repository configuration; discovery exposes it as the exact writesProjectFiles side effect. Add RequiresPlayMode, Dangerous, LongRunning, or MayReloadDomain when applicable. Strict schemas should describe every property and reject unknown business arguments. The bridge recursively enforces the supported JSON Schema subset before invocation, including allOf/anyOf/oneOf, not, const, nested objects, and array items. Declared output schemas are also enforced before success. Use SideEffects for the concrete effect classes, ErrorCodes for domain failures, and CleanupToolName only when the operation produces a token owned by that cleanup tool.

These booleans are authoring inputs, not public response fields. Discovery serializes positive capabilities as a sorted tags array, for example ["dangerous", "longRunning"]; absence means false. Concrete effects such as writesAssets, writesProjectFiles, changesRuntimeState, or reloadsDomain are reported once in sideEffects. Empty tags/effects, empty cleanup names, valid-state aliases, and standard project-tool error codes are omitted. Canonical descriptors include only tool-specific extra errorCodes.

LongRunning=true and an explicit runAsJob=true both return a persistent Job. Class-based tools can implement IMCPPersistentProjectTool to yield a MCPProjectToolJobStep between Editor updates. Every continuation value must be returned in the step state; the bridge does not retain the tool instance.

Transaction-capable tools publish one semantically neutral descriptor with scope, atomicity, isolation, durability, rollbackKind, and commitEvidence. Project-tool packages set the matching MCPProjectToolAttribute fields as one complete contract; partial declarations are rejected. These fields describe framework guarantees and evidence, not consumer gameplay meaning.

The canonical client workflow is the same for built-in and project tools:

  1. Search the bound project catalog by intent, module, capability, operation kind, effects, or preconditions.

  2. Get one exact typed name to inspect its complete published schema.

  3. Call that typed tool directly with its business arguments.

For the example above, the Editor route remains project-tools/call/example/add-content; clients never send a generic toolName + args envelope. A different Unity project uses a different MCP connection, so one project's tools cannot leak into another project.

Project-tool packages can reuse MCPSettingsManager.ResolvePrimaryResultLimit(...) for a single primary collection. It preserves the shared Unity MCP user preference while keeping explicit values and package-specific hard caps authoritative. Domain-specific packages should own their own Project Settings and Preferences rather than adding unrelated fields to Unity MCP.

Configuration

Default precedence is:

  1. explicit tool argument;

  2. team-owned Project Settings;

  3. local Preferences;

  4. built-in default.

Team settings are stored in ProjectSettings/UnityMCPSettings.json and edited under Project Settings > Unity MCP:

  • project context;

  • additional namespaces for editor/execute-code;

  • default Physics query dimension;

  • screenshot output directory.

Operator settings are edited under Preferences > Unity MCP:

  • bridge startup and manual/automatic ports;

  • MPPM startup;

  • optional primary-result-limit override;

  • optional Prefab YAML diff detail;

  • Action and Job history sizes;

  • locally enabled tool categories.

Safety caps, paths/selectors, mutation operations, overwrite/save/discard choices, build/test targets, raw diagnostic expansion, and destructive confirmation remain explicit or invariant.

The full ownership matrix and authoritative built-in route audit are in Documentation~/configuration.md.

Response and safety conventions

  • Tool metadata publishes an outputSchema for every route. The companion server exposes the actual result through MCP structuredContent; the text block remains a short human-readable summary. Shared persistent Job fields include semantic descriptions so clients can compose status, cancellation, and cleanup without relying on route-specific prose.

  • Successful bridge responses may omit redundant success=true; errors keep a stable error code and retryability.

  • Transported type descriptors keep the complete fullType, fullTypeName, or fullName identifier and omit matching short type, component, typeName, name, or fallback title aliases. Distinct names and custom titles remain; request selectors still accept simple or complete names.

  • Project-tool success envelopes are unwrapped without compacting the validated result object. Required empty collections, counts, flags, and nested members therefore retain the exact shape declared by the tool's outputSchema. The same preservation applies when that envelope is nested in a persistent Job snapshot returned by jobs/get.

  • Published inputSchema and outputSchema objects are transported without response compaction. Business properties named tags or sideEffects and JSON Schema keywords such as readOnly therefore retain their declared schema shapes.

  • editor/execute-code reports invalid submissions and compiler diagnostics as non-retryable structured errors. Compilation failures use execute_code_compilation_failed and return userCodeExecuted=false, so callers can distinguish invalid C# from bridge or runtime failures.

  • editor/execute-code always returns a persistent Job. Poll jobs/get; use jobs/cancel before execution or between incremental steps; and use jobs/cleanup only when the Job reports an available cleanup contract. Idempotency keys are project-scoped recovery capabilities: an exact retry after an MCP reconnect returns the original Job and access token, while reusing a key with different arguments is rejected.

  • jobs/cancel reports success when the target accepts cancellation, including workflows that reach canceled immediately. Read the terminal outcome through jobs/get; cancellation acceptance is not returned as a command failure.

  • asset/refresh, packages/update-git, and packages/resolve use one serialized durable workspace-job state machine. Package targets require a full commit SHA. A terminal success proves exact manifest, lockfile, and registered-package state when applicable, one AssetDatabase refresh invocation, a clean compilation with no compiler errors, and the subsequent assembly reload. Poll by jobId, or use the original requestId plus jobType after a transport response is lost.

  • asset/transaction is also a serialized durable workspace Job. It validates the complete virtual operation sequence, captures every affected asset/meta baseline before mutation, persists prepare/apply/save/publish/rollback phases, and verifies restored or committed bytes after synchronous import. Its only terminal states are committed, rolled_back, rollback_failed, and outcome_uncertain; retained recovery artifacts require explicit cleanup.

  • Unity Undo is not transaction rollback. Each eligible synchronous MCP request owns a distinct Undo group only when Unity records an actual undoable change. undo/perform and undo/redo require the exact request or action identity; undo/history reports those records, and reload invalidates unprovable groups. Domain reload resumes this same identity and never reissues the mutation.

  • Durable refresh, build, Test Runner, package-test, memory-snapshot, Addressables, and Unity-package-import Jobs return jobId, jobType, and a durable jobAccessToken. The originating agent can poll normally; after an MCP reconnect, pass the token to jobs/get or jobs/cancel. jobs/list and public history snapshots never return the token.

  • A domain reload may legitimately change the live catalog revision while the Job remains active. An already negotiated client may still call the built-in jobs/get, jobs/cancel, and jobs/cleanup lifecycle contracts with its complete prior stack identity; their current input contracts and Job owner capabilities are validated before dispatch. No other stale-catalog command is admitted.

  • jobs/get and testing/get-job report a successful snapshot read independently from the observed job outcome. Inspect status and error for failed or canceled jobs; those outcomes do not turn polling into a queue-command failure or overwrite the business status. Package-test starts return jobId plus jobType="package-test"; poll that identity through jobs/get.

  • testing/get-package-job is the specialized inspection and terminal-state cleanup route for the current package-test workflow. It accepts the same jobId and access token, but is not a second public job identity or the normal polling path.

  • Job capability and positive state flags use the same presence-only tags contract (incrementalJob, cleanupDeclared, cleanupAvailable, cancellationRequested, and reused). Fields that do not yet have a value are omitted; status, timestamps, progress, results, and errors remain explicit runtime facts.

  • The transport applies that rule uniformly to specialized build, test, package-test, import, refresh, and profiler workflows. Poll-route aliases, status-derived booleans, idle compilation diagnostics, and false lifecycle markers are omitted. Business facts whose false value is meaningful—such as valid, visible, found, or fileExists—remain explicit.

  • Editor process activity uses presence tags (playing, paused, compiling, updating, changingPlayMode, and idle). Every editor/state snapshot also carries authoritative isPlaying, isPaused, and isChangingPlayMode booleans, so clients can safely distinguish Edit, Play, Pause, and a transition without interpreting an omitted tag. The composite isPlayingOrWillChangePlaymode alias and successful wait-configuration echoes are not sent.

  • Execute-code uses compact Unity value strings by default. Pass unityStructFormat="structured" for typed objects with stable fields.

  • Completed pagination aliases and exact duplicate counts are removed on the wire. A sole empty primary collection is preserved so a zero-match result cannot disappear from a completed ticket.

  • Prefab mutations return semantic results without YAML diffs initially. Request includePrefabFileDiff=true or enable the personal preference when line detail is needed.

  • prefab-asset/add-component accepts an optional properties map and applies it before the first save. Success is returned only after serialized readback confirms both the new component and its requested initial values; use prefab-asset/configure-component for idempotent ensure/update work or ObjectReference wiring. Pass createPathIfMissing=true when the component's semantic GameObject path does not exist yet; the path and component are then created and configured in one rollback-capable transaction.

  • All Prefab asset mutations use one authoring-session owner. Serialized views close before save, the isolated authoring root unloads before YAML normalization, import, or persistent readback, and only the adopted product can commit. Failures restore the exact original bytes through the same atomic file publisher and synchronously re-adopt them before returning.

  • When referenceAssetPath contains more than one compatible object, Prefab reference routes require referenceSubAssetName or the lossless decimal string referenceSubAssetLocalId. Ambiguous paths fail with bounded candidate details instead of silently assigning the first imported subasset.

  • Sprite sheet slicing replaces the complete Sprite name-fileID mapping and reserializes importer metadata. Renaming or shrinking a sheet therefore does not leave stale subasset names or removed frames in the texture .meta file.

  • The pixel-sprite importer preset preserves an existing Single/Multiple Sprite mode. Use texture/set-import, a reference importer, or a slicing route when changing that structural mode is intentional.

  • Potentially large raw graph, stack, serialized, and metadata diagnostics are opt-in.

  • Mutating requests validate expectedProjectPath before dispatch; project names never select or reject a target. Stable idempotency keys, non-reused ticket identities, and persistent queue snapshots protect reload-sensitive workflows. The allocator high-water survives even when replay-safe read ticket payloads are intentionally discarded.

  • Ping and queue health publish the Editor-loop pulse and its age separately from focus/application activity. While the bridge listener is alive, queue submission first atomically persists the request identity and payload even if the Editor loop is temporarily stalled; queueReady and editorLoopAdvancing report when execution can progress. A durable workspace job continues while the Editor is unfocused and waits through imports, compilation, and domain reload. Other MCP mutations remain durably queued until the workspace job reaches a terminal state.

  • MCP-owned durable state uses one path-keyed publication owner. Writers publish complete immutable text or binary snapshots through private files, disk flush, and atomic replacement; target and backup adoption is serialized with readers, deletes, and bounded operating-system lease handoff. Queue, Job, refresh, build, import, package-test, history, Addressables, and instance-registry state therefore share one failure-closed persistence contract.

  • HTTP listener startup is transactional: partial binds and registrations are rolled back before retry. Shutdown publishes stopped state first, closes the exact listener generation, and tolerates clients disconnecting while a response is in flight. Project paths compare case-insensitively on Windows and preserve casing on Linux and macOS.

  • Use unity_wait_editor_idle after compilation, package changes, refreshes, or domain reloads before issuing dependent work.

Development and validation

The package contains EditMode regression tests for route authority, metadata, schemas, configuration precedence, queue/reload behavior, response compaction, and tool families. Use the persistent testing/run-package-tests workflow when testing a Git package inside a consumer project. With VM Unity MCP and no testNames, categories, or groupNames, this workflow runs the curated VMUnityMCP.PackageSmoke category. Request categories: ["VMUnityMCP.FullRegression"] only when the complete integration suite is warranted; exact names, fixture groups, and other categories remain available for focused validation. The start response contains a jobId and jobType="package-test" plus a jobAccessToken; poll that identity with jobs/get, supplying the token after an MCP reconnect, until a terminal status reports manifestRestored or the explicit manifestRestoreFailed outcome. The workflow refuses to replace a malformed pre-existing testables value and leaves externally changed manifest bytes untouched during restoration. A modified manifest is adopted only when the requested test assemblies enter Unity's loaded or compiled product; restoration completes only after the exact original bytes are back and every test assembly declared by that package has left both products. The workflow persists one resolve issuance across reloads and never overlaps a second void Client.Resolve() operation for the same transition. Each modified or original manifest publication also requests one clean compilation after that resolve, so package test assemblies enter or leave the compiled product even when Package Manager emits no separate update signal.

When tool metadata changes, synchronize and test the companion Node server, then reconnect the MCP client before judging its cached concrete tool list.

See LICENSE for the complete terms and attribution.

F
license - not found
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
2dRelease cycle
5Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • pub.dev MCP — package registry for Dart & Flutter.

  • A paid remote MCP for Unity-MCP, built to return verdicts, receipts, usage logs, and audit-ready JSO

  • Maven Central MCP — Java/JVM artifact registry

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/VM233/VMUnityMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server