← Files Unity EssentialsARCHIVED FILE
scripts/unity_mcp_advisor.py
8.36 KB · Oct 3, 2026 · 06:30 UTC
#!/usr/bin/env python3
"""Print practical Unity MCP setup guidance for a local Unity project."""
from __future__ import annotations
import argparse
import json
import os
from pathlib import Path
PROVIDERS = {"auto", "official", "coplaydev", "ivanmurzak", "codergamester"}
def read_unity_version(project: Path) -> str | None:
version_file = project / "ProjectSettings" / "ProjectVersion.txt"
if not version_file.exists():
return None
for line in version_file.read_text(encoding="utf-8", errors="replace").splitlines():
if line.startswith("m_EditorVersion:"):
return line.split(":", 1)[1].strip()
return None
def read_manifest(project: Path) -> dict:
manifest = project / "Packages" / "manifest.json"
if not manifest.exists():
return {}
try:
return json.loads(manifest.read_text(encoding="utf-8"))
except json.JSONDecodeError:
return {}
def read_packages_lock(project: Path) -> dict:
lock_file = project / "Packages" / "packages-lock.json"
if not lock_file.exists():
return {}
try:
return json.loads(lock_file.read_text(encoding="utf-8"))
except json.JSONDecodeError:
return {}
def major_version(version: str | None) -> int | None:
if not version:
return None
first = version.split(".", 1)[0]
try:
return int(first)
except ValueError:
return None
def relay_path() -> Path:
if os.name == "nt":
return Path.home() / ".unity" / "relay" / "relay_win.exe"
if os.uname().sysname == "Darwin":
return Path.home() / ".unity" / "relay"
return Path.home() / ".unity" / "relay" / "relay_linux"
def missing_unity_markers(project: Path) -> list[str]:
required = [
project / "Assets",
project / "Packages" / "manifest.json",
project / "ProjectSettings" / "ProjectVersion.txt",
]
return [path.relative_to(project).as_posix() for path in required if not path.exists()]
def classify_provider(text: str) -> str | None:
lowered = text.lower()
if "com.unity.ai.assistant" in lowered:
return "official"
if "coplaydev" in lowered or "coplay" in lowered:
return "coplaydev"
if "ivanmurzak" in lowered or "ai-game" in lowered:
return "ivanmurzak"
if "codergamester" in lowered:
return "codergamester"
if "unity-mcp" in lowered or "mcp-unity" in lowered:
return "unknown-unity-mcp"
return None
def detect_existing_mcp(project: Path) -> list[tuple[str, str]]:
evidence: list[tuple[str, str]] = []
manifest = read_manifest(project)
deps = manifest.get("dependencies", {})
for name, value in deps.items():
provider = classify_provider(f"{name} {value}")
if provider:
evidence.append((provider, f"Packages/manifest.json dependency: {name}"))
lock = read_packages_lock(project)
for name, data in lock.get("dependencies", {}).items():
provider = classify_provider(f"{name} {data}")
if provider:
evidence.append((provider, f"Packages/packages-lock.json dependency: {name}"))
packages_dir = project / "Packages"
if packages_dir.exists():
for child in packages_dir.iterdir():
provider = classify_provider(child.name)
if provider:
evidence.append((provider, f"embedded package/folder: Packages/{child.name}"))
for config in [project / ".mcp.json", project / ".cursor" / "mcp.json", project / ".vscode" / "mcp.json"]:
if config.exists():
evidence.append(("configured-mcp-client", str(config.relative_to(project))))
return evidence
def detect_provider(project: Path, requested: str) -> str:
if requested != "auto":
return requested
existing = detect_existing_mcp(project)
for provider, _reason in existing:
if provider in PROVIDERS:
return provider
version = read_unity_version(project)
manifest = read_manifest(project)
deps = manifest.get("dependencies", {})
if "com.unity.ai.assistant" in deps or (major_version(version) or 0) >= 6000:
return "official"
if any("CoplayDev/unity-mcp" in str(value) for value in deps.values()):
return "coplaydev"
if any("ivanmurzak" in str(value).lower() or "unity-mcp" in str(value).lower() for value in deps.values()):
return "ivanmurzak"
return "coplaydev"
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--project", required=True, help="Path to the Unity project root.")
parser.add_argument("--provider", choices=sorted(PROVIDERS), default="auto")
args = parser.parse_args()
project = Path(args.project).expanduser().resolve()
version = read_unity_version(project)
manifest = read_manifest(project)
deps = manifest.get("dependencies", {})
existing_mcp = detect_existing_mcp(project)
missing_markers = missing_unity_markers(project)
provider = "unresolved" if missing_markers else detect_provider(project, args.provider)
print(f"Project: {project}")
print(f"Unity version: {version or 'not found'}")
if existing_mcp:
print("Existing MCP evidence:")
seen = set()
for provider_name, reason in existing_mcp:
item = (provider_name, reason)
if item in seen:
continue
seen.add(item)
print(f"- {provider_name}: {reason}")
else:
print("Existing MCP evidence: none found")
if missing_markers:
print("Recommended provider: unresolved until the Unity project root is verified")
else:
print(f"Recommended provider: {provider}")
print()
if missing_markers:
print("Warning: this path is not a verified Unity project root.")
for marker in missing_markers:
print(f"- Missing {marker}")
print("Resolve the Unity project root before choosing or installing a Unity MCP provider.")
return 1
if provider == "official":
relay = relay_path()
print("Official Unity MCP checklist:")
print("- Install/enable the Unity AI Assistant package.")
print("- Open Unity and check Edit > Project Settings > AI > Unity MCP.")
print("- Confirm the bridge is Running.")
print(f"- Manual MCP command: {relay}")
print("- Manual MCP args: --mcp")
print("- Approve the Codex/client connection when Unity shows it as pending.")
if "com.unity.ai.assistant" not in deps:
print("- Note: com.unity.ai.assistant was not found in Packages/manifest.json.")
print("- Ask before installing/enabling the package.")
elif provider == "coplaydev":
print("CoplayDev/unity-mcp checklist:")
print("- Review https://github.com/CoplayDev/unity-mcp before installing.")
print("- Add the Unity package from its documented Package Manager git URL.")
print("- Start Unity, verify the MCP server status, then connect the MCP client.")
print("- Use this when official Unity MCP is unavailable or community tooling is preferred.")
print("- Ask before adding it if no existing CoplayDev MCP evidence was found.")
elif provider == "ivanmurzak":
print("IvanMurzak/Unity-MCP checklist:")
print("- Review https://github.com/IvanMurzak/Unity-MCP before installing.")
print("- Consider the CLI flow when you want generated skills or runtime MCP behavior.")
print("- Confirm project paths and requirements before installation.")
print("- Ask before adding it if no existing IvanMurzak MCP evidence was found.")
elif provider == "codergamester":
print("CoderGamester/mcp-unity checklist:")
print("- Review https://github.com/CoderGamester/mcp-unity before installing.")
print("- Confirm Node.js/server requirements and Unity package installation steps.")
print("- Use a low-risk scene or console read as the first connection test.")
print("- Ask before adding it if no existing CoderGamester MCP evidence was found.")
if not existing_mcp:
print()
print("No Unity MCP appears to be configured. Ask the user whether they want to add one, then guide them to a single provider.")
else:
print()
print("Use the existing MCP first. Do not add a second provider unless the user explicitly chooses to replace or compare providers.")
return 0
if __name__ == "__main__":
raise SystemExit(main())
SHA-256: b5e1182b726c83742f1ab3085d7ae4617b2fb91feb74d4d165bfb768e303848a