akiojin/unity-mcp-server
If you are the rightful owner of unity-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
Unity Editor MCP is a protocol server that enables LLM-based clients to automate the Unity Editor, focusing on reliable, scriptable workflows with minimal configuration.
Unity Editor MCP
English |
Overview
Unity Editor MCP lets LLM-based clients automate the Unity Editor. It focuses on reliable, scriptable workflows with a simple interface and zero- or low-configuration setup.
Related Docs
- Video Capture Feature Plan:
docs/video-capture-plan.md
- Planned: C# Language Server (self-contained) RFC:
docs/RFCs/0001-csharp-lsp.md
C# Editing Policy (Important)
- All C# symbol/search/structured edits are performed via a self-contained C# Language Server (LSP) bundled in this repo; no Unity communication is involved.
- Existing
script_*
tools call the LSP under the hood, so edits are robust to Unity compilation/domain reload. - Risky line-based patch/pattern replace tools were removed.
For Contributors
Developer note: the LSP is self-contained and auto-provisioned by the MCP server (fixed-version by tag). No .NET SDK is required for end users.
Common usage (MCP tools)
- Symbols:
script_symbol_find { "name": "ClassName", "kind": "class" }
- References:
script_refs_find { "name": "MethodName" }
- Replace body (preflightβapply):
script_edit_structured { "operation": "replace_body", "path": "Packages/.../File.cs", "symbolName": "Class/Method", "newText": "{ /* ... */ }", "preview": true }
- then set
"preview": false
to apply if errors are empty
- Insert after class:
script_edit_structured { "operation": "insert_after", "path": "...", "symbolName": "ClassName", "kind": "class", "newText": "\nprivate void X(){}\n", "preview": false }
Run AssetDatabase.Refresh
in Unity manually only when needed.
Performance
- The server starts and keeps a persistent LSP process by default to avoid cold starts.
LLM Optimization Principles
- Prefer small responses: enable paging and set conservative limits.
- Use snippets: avoid full file reads; favor short context windows (1β2 lines).
- Scope aggressively: restrict by
Assets/
orPackages/
, kind, and exact names. - Favor summaries: rely on tool-side summarized payloads where available.
- Avoid previews unless necessary: apply directly when safe to reduce payload.
- Keep image/video resolutions minimal and avoid base64 unless immediately analyzed.
Suggested caps
- Search:
pageSizeβ€20
,maxBytesβ€64KB
,snippetContext=1β2
,maxMatchesPerFileβ€5
. - Hierarchy:
nameOnly=true
,maxObjects 100β500
(details: 10β50). - Script read: 30β40 lines around the target; set
maxBytes
. - Structured edits: responses are summarized (errors β€30, message β€200 chars; large text β€1000 chars).
Safe Structured Edit Playbook
- Locate symbols:
script_symbols_get
orscript_symbol_find
(preferkind
andexact
).- Use project-relative paths under
Assets/
orPackages/
only. - Use resultsβ container to build
namePath
likeOuter/Nested/Member
.
- Use project-relative paths under
- Inspect minimal code:
script_read
with 30β40 lines around the symbol. - Edit safely:
script_edit_structured
(insert_before/insert_after/replace_body).- Insert targets class/namespace (never method).
replace_body
must include braces and be self-contained.- Use
preview=true
only when risk is high; otherwise apply to avoid extra tokens.
- Optional refactor/remove:
script_refactor_rename
,script_remove_symbol
with preflight. - Verify: compile state and, if needed, targeted
script_read
again.
What It Can Do
- Editor automation: create/modify scenes, GameObjects, components, prefabs, materials
- UI automation: locate and interact with UI, validate UI state
- Input simulation: keyboard/mouse/gamepad/touch for playmode testing (Input System only)
- Visual capture: deterministic screenshots from Game/Scene/Explorer/Window views, optional analysis
- Code base awareness: safe structured edits and accurate symbol/search powered by the bundled C# LSP
- Project control: read/update selected project/editor settings; read logs, monitor compilation
UnityβMCP Connection
- Host/Port: Unity package opens a TCP server on
UNITY_HOST
/UNITY_PORT
(defaultlocalhost:6400
). - Flow: Open Unity project β package starts listening β your MCP client launches the Node server β Node connects to Unity.
- Config: See Configuration section (
project.root
,project.codeIndexRoot
,UNITY_MCP_CONFIG
). - Timeouts/Retry: Exponential backoff with
reconnectDelay
/maxReconnectDelay
/reconnectBackoffMultiplier
. - Troubleshooting: Ensure Unity is running, port 6400 is free, and host/port match.
Architecture
ββββββββββββββββββ JSON-RPC (MCP) ββββββββββββββββββββββββ
β MCP Client β ββββββββββββββββββββββββββββΆ β Node MCP Server β
β (Claude/Codex/ β ββββββββββββββββββββββββββββ β (@akiojin/unity- β
β Cursor β¦) β tool responses β mcp-server) β
ββββββββββββββββββ ββββββββββββ¬ββββββββββββ
TCPβ6400
βΌ
βββββββββββββββββββββ
β Unity Editor β
β (Package opens β
β TCP listener) β
βββββββββββββββββββββ
Sequence
sequenceDiagram
participant Client as MCP Client
participant Node as MCP Server (Node)
participant Unity as Unity Editor
Client->>Node: Connect / request (tool call)
Node->>Unity: JSON-RPC over TCP (command)
Unity-->>Node: Result / progress / logs
Node-->>Client: Response
alt Disconnect / timeout
Node->>Node: Exponential backoff
Node->>Unity: Reconnect
end
Directory Structure
UnityMCPServer/
: Unity project (Editor bridge, tools, samples)mcp-server/
: Node.js MCP server that exposes Unity toolsscripts/
: Helper scripts for local development
Setup
- Unity 2020.3 LTS or newer
- Node.js 18+ and npm
- Claude Desktop or another MCP-compatible client
Installation
- In Unity: Package Manager β Add from git URL β
https://github.com/akiojin/unity-mcp-server.git?path=UnityMCPServer/Packages/unity-mcp-server
- Configure MCP client (Claude Desktop example):
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
- Windows:
%APPDATA%\\Claude\\claude_desktop_config.json
- Add:
{ "mcpServers": { "unity-mcp-server": { "command": "npx", "args": ["@akiojin/unity-mcp-server@latest"] } } }
- macOS:
Usage Flow
- Open Unity project (TCP listener starts on port 6400)
- Start your MCP client and call tools (e.g., ping, scene, script tools)
Configuration (.unity/config.json)
Configuration is optional; defaults work without any config. When present, the server loads configuration in this order:
UNITY_MCP_CONFIG
(absolute path to a JSON file)- Nearest
./.unity/config.json
discovered by walking up from the current working directory ~/.unity/config.json
(user-global)
Notes:
- The server derives a fixed
WORKSPACE_ROOT
from the discovered.unity/config.json
location and uses it consistently (independent of laterprocess.cwd()
changes). - Relative paths in the config should be written relative to this workspace root.
~
and environment variable expansion are not applied to path values.
Common keys:
project.root
: Unity project root directory (containsAssets/
).project.codeIndexRoot
: Code Index output directory (default:<project.root>/Library/UnityMCP/CodeIndex
).
Examples:
{
"project": {
"root": "/absolute/path/to/UnityProject",
"codeIndexRoot": "/absolute/path/to/UnityProject/Library/UnityMCP/CodeIndex"
}
}
Team-friendly (relative) example β recommended when the repo layout is stable:
{
"project": {
"root": ".",
"codeIndexRoot": "./Library/UnityMCP/CodeIndex"
}
}
Tip: Prefer UNITY_MCP_CONFIG=/absolute/path/to/config.json
to make discovery explicit.
Configuration Keys
Key | Type | Default | Description | Allowed values |
---|---|---|---|---|
project.root | string | auto-detect (Unity connection or nearest directory with Assets/ ) | Unity project root directory. Relative paths resolve from process CWD. | β |
project.codeIndexRoot | string | <project.root>/Library/UnityMCP/CodeIndex | Code Index storage root. | β |
unity.host | string | process.env.UNITY_HOST or localhost | Hostname/IP of Unity Editor TCP server. | β |
unity.port | number | process.env.UNITY_PORT or 6400 | Port of Unity Editor TCP server. | β |
unity.reconnectDelay | number (ms) | 1000 | Initial delay before reconnect attempts. | β |
unity.maxReconnectDelay | number (ms) | 30000 | Maximum backoff delay between reconnect attempts. | β |
unity.reconnectBackoffMultiplier | number | 2 | Exponential backoff multiplier for reconnects. | β |
unity.commandTimeout | number (ms) | 30000 | Timeout for individual Unity commands. | β |
server.name | string | unity-mcp-server | Server name exposed via MCP. | β |
server.version | string | 0.1.0 | Server version string. | β |
server.description | string | MCP server for Unity Editor integration | Human-readable description. | β |
logging.level | string | process.env.LOG_LEVEL or info | Log verbosity for stderr logging. | debug |
logging.prefix | string | [Unity Editor MCP] | Log prefix used in stderr. | β |
search.defaultDetail | string | process.env.SEARCH_DEFAULT_DETAIL or compact | Default return detail for search; compact maps to snippets . | compact |
search.engine | string | process.env.SEARCH_ENGINE or naive | Search engine implementation. | naive (treesitter planned) |
GUID DB
- Storage root: Stored under your workspace at
./.unity/guid-db/
. - Version control: Commit
./.unity/guid-db/
to your VCS so history is preserved.
Screenshot System
- Capture Game View, Scene View, ExplorerοΌAI-framedοΌ, or a specific Editor window.
- Modes:
game
|scene
|explorer
|window
. - Options:
- Resolution:
width
/height
(or in explorer:camera.width
/camera.height
). - UI Overlay:
includeUI
for Game View. - Explorer framing:
explorerSettings.camera.*
(autoFrame, FOV, near/far clip, position/rotation, padding). - Display aids:
explorerSettings.display.*
(highlightTarget, showBounds, showColliders, showGizmos, backgroundColor, layers). - Target focus:
explorerSettings.target.*
(gameObject/tag/area/position, includeChildren). - Output: always saved to
<workspace>/.unity/capture/screenshot_<mode>_<timestamp>.png
. SetencodeAsBase64=true
only when you need inline analysis. - The Node server always includes
workspaceRoot
when commanding Unity; Unity prioritizes it and falls back to.unity/config.json
only if missing.
- Resolution:
- Analysis: optional UI detection and content summary.
Sequence
sequenceDiagram
participant Client as MCP Client
participant Node as MCP Server (Node)
participant Unity as Unity Editor
Client->>Node: Request screenshot (mode/options)
Node->>Unity: Capture command with parameters
Unity->>Unity: Configure camera/render settings
Unity-->>Node: Image data (file path or base64)
Node-->>Client: Return result (and optional analysis)
Input Simulation
- Supported: Unity Input System only (new Input System package).
- Not supported: Legacy Input Manager (Project Settings β Input Manager).
- Capabilities: simulate keyboard, mouse, gamepad, and touch input for playmode testing and UI interaction.
- Tip: Ensure your project uses Input System; otherwise simulated input will not affect gameplay.
C# Language Server (LSP)
The project bundles a self-contained C# Language Server (LSP). The MCP server auto-downloads and manages its lifecycle. script_*
tools talk to the LSP under the hood:
- Index: scans all
.cs
withdocumentSymbol
and persists to SQLite (Library/UnityMCP/CodeIndex) - Find symbols/references:
workspace/symbol
+ LSP extensions - Edits: rename/replace/insert/remove via LSP extensions
- Safety: structured edits, preview/apply options, no blind line-based patches
Operational details (auto-download/update, recovery): see docs/lsp-operations.md
.
Tests
- Script tools tests are consolidated in
tests/test-mcp-script-tools.md
(Japanese, MCP γγΌγ«εζ)γ - Additional indexing scenario:
tests/natural-language/indexing-incremental.md
.
Indexing Settings
- The MCP server can periodically refresh the SQLite index (incremental) when enabled.
- Configure via environment variables (or
.unity/config.json
overrides):INDEX_WATCH=true
to enable periodic updates (default: false)INDEX_WATCH_INTERVAL_MS=15000
polling interval (default: 15000)INDEX_CONCURRENCY=8
max concurrent LSP requests (default: 8)INDEX_RETRY=2
per-file documentSymbol retry attempts (default: 2)INDEX_REPORT_EVERY=500
progress log interval in files (default: 500)
Sequence
sequenceDiagram
participant Client as MCP Client
participant Node as MCP Server (Index/Tools)
participant LSP as C# LSP (self-contained)
participant Unity as Unity Editor
participant Index as Code Index
Client->>Node: Edit or search request
alt Edit flow
Node->>LSP: Edit request (replace/insert/rename)
LSP-->>Node: Workspace edits
Node->>Unity: Apply changes
Unity->>Unity: Refresh / compile
Node->>Index: Update SQLite index for changed files (incremental)
else Search flow
Node->>Index: Load symbols if present
Index-->>Node: Symbols / metadata
Node->>LSP: Query (workspace/symbol, references)
LSP-->>Node: Results
end
Node-->>Client: Result (edits confirmed or search hits)
Other Clients
Codex CLI
Configure MCP servers for Codex by creating a config file:
- macOS/Linux:
~/.codex/servers.json
- Windows:
%USERPROFILE%\.codex\servers.json
Example:
{
"mcpServers": {
"unity-mcp-server": {
"command": "npx",
"args": ["@akiojin/unity-mcp-server@latest"]
}
}
}
Troubleshooting (Short)
- Unity TCP not listening: reopen project; ensure port 6400 is free.
- Node.js cannot connect: Unity running? firewall? logs in Unity/Node terminals.
- C# types missing: refresh assets and wait until compilation completes.
- Technical notes are summarized in this README.
Note: Detailed design documents are referenced from docs/
. This README focuses on usage and repository structure.
Repository Structure (Workspace Root)
.unity/
config.json
: Workspace settings.project.root
points to the Unity project root. The server fixesWORKSPACE_ROOT
based on this.capture/
: Fixed output location for screenshots/videos (Git-ignored).
UnityMCPServer/
(Unity project)Packages/unity-mcp-server/**
: UPM package (source of truth)Assets/**
: samples/tests only (no implementation code)
mcp-server/
(Node MCP server)- Reads
./.unity/config.json
and fixesWORKSPACE_ROOT
. Always passes it to Unity for capture commands.
- Reads
csharp-lsp/
(Roslyn-based CLI)- Self-contained binary, invoked by the MCP server for symbol/search/edit operations.