How to Contribute to the Unity MCP Project: A Complete Developer Guide

To contribute to the Unity MCP project, fork the CoplayDev/unity-mcp repository, create a feature branch off beta, implement parallel changes in both the Python MCP layer (Server/src/services/tools/) and the Unity C# layer (MCPForUnity/Editor/Tools/), add comprehensive tests for both codebases, and submit a pull request targeting the beta branch.

The Unity MCP (Model Context Protocol) bridge enables AI assistants to control the Unity Editor through a dual-layer architecture. Contributors to the CoplayDev/unity-mcp repository must maintain domain symmetry by implementing every feature in both Python (the MCP server side) and C# (the Unity Editor side). This guide walks you through the complete contribution workflow based on the project's CONTRIBUTING.md and CLAUDE.md specifications.

Understanding the Unity MCP Architecture

The repository contains two parallel codebases that communicate via the MCP protocol. Before contributing, understand where your changes must reside:

  • Python MCP Tools (Server/src/services/tools/) – Exposed to AI assistants via the @mcp_for_unity_tool decorator. These handle protocol-level communication and forward commands to Unity.

  • CLI Commands (Server/src/cli/commands/) – Python Click interfaces for terminal-based development workflows.

  • Resources (Server/src/services/resources/) – Read-only state exposed via @mcp_for_unity_resource decorators.

  • Unity Editor Tools (MCPForUnity/Editor/Tools/) – C# implementations using the [McpForUnityTool] attribute that actually execute operations within the Unity Editor.

  • Compatibility Shims (MCPForUnity/Runtime/Helpers/) – Version-specific adapters for Unity API changes.

Any functional change requires updates to both the Python tool definition and its corresponding C# handler to maintain protocol compatibility.

Setting Up Your Development Environment

Start by forking the repository and configuring your local workspace to track the upstream beta branch.

  1. Fork the repository on GitHub, then clone your fork:
git clone https://github.com/<your-username>/unity-mcp.git
cd unity-mcp
  1. Add the upstream remote and create your feature branch:
git remote add upstream https://github.com/CoplayDev/unity-mcp.git
git fetch upstream
git checkout -b feat/your-feature-name upstream/beta

The project uses the beta branch as the active development target. Never open pull requests against main unless specifically requested by maintainers.

Implementing a New Tool (Parallel Implementation)

When adding functionality, you must create mirrored implementations in both languages. The following example demonstrates registering a new tool called manage_example.

Python MCP Tool Implementation

Create your tool definition in Server/src/services/tools/manage_example.py. The @mcp_for_unity_tool decorator registers the function with the MCP server:


# Server/src/services/tools/manage_example.py

from services.registry import mcp_for_unity_tool

@mcp_for_unity_tool(
    description="Demonstrates a simple example tool.",
    group="core",
)
async def manage_example(ctx, action: str) -> dict:
    unity = await get_unity_instance_from_context(ctx)
    params = {"action": action}
    return await send_with_unity_instance(
        async_send_command_with_retry, unity, "manage_example", params
    )

Key components include:

  • @mcp_for_unity_tool – Registers the function with metadata for AI assistants.
  • get_unity_instance_from_context – Retrieves the active Unity connection from the request context.
  • send_with_unity_instance – Forwards the command to the Unity Editor process with automatic retry logic.

C# Unity Editor Implementation

Create the counterpart in MCPForUnity/Editor/Tools/ManageExample.cs. The [McpForUnityTool] attribute maps this class to the Python tool:

// MCPForUnity/Editor/Tools/ManageExample.cs
using UnityEngine;
using UnityEditor;
using McpForUnity;

[McpForUnityTool("manage_example", AutoRegister = true, Group = "core")]
public static class ManageExample
{
    public static object HandleCommand(JObject @params)
    {
        var p = new ToolParams(@params);
        string action = p.RequireString("action");
        Debug.Log($"Example tool received action: {action}");
        return new SuccessResponse("Done.", new { echo = action });
    }
}

Critical elements:

  • [McpForUnityTool] – Maps the C# handler to the Python tool name (must match exactly).

  • HandleCommand – The entry point that receives JSON parameters from the Python side.

  • ToolParams – Helper class for type-safe parameter extraction.

  • SuccessResponse – Standardized response format for the MCP protocol.

Testing Your Changes

Every contribution requires tests for both the Python and C# implementations.

Python Tests

Add asynchronous pytest cases in Server/tests/:


# Server/tests/test_manage_example.py

import pytest
from services.tools.manage_example import manage_example

@pytest.mark.asyncio
async def test_example_action():
    ctx = make_test_context()
    resp = await manage_example(ctx, action="demo")
    assert resp["status"] == "success"
    assert resp["data"]["echo"] == "demo"

Unity Edit-Mode Tests

Add NUnit tests in the Unity test project:

// TestProjects/UnityMCPTests/Assets/Tests/ManageExampleTests.cs
using NUnit.Framework;
using UnityEngine;
using UnityEditor;
using McpForUnity.Editor.Tools;

public class ManageExampleTests
{
    [Test]
    public void HandlesCommand()
    {
        var result = ManageExample.HandleCommand(
            JObject.FromObject(new { action = "ping" })
        );
        Assert.IsTrue(result is SuccessResponse);
    }
}

Local Verification and Submission

Before pushing, verify your changes pass the full validation suite.

Run Python tests using uv:

cd Server
uv run pytest tests/ -v

Verify Unity compilation across supported versions:

tools/check-unity-versions.sh

This script ensures your C# changes compile against all supported Unity Editor versions.

When ready to submit:

  1. Push your branch: git push origin feat/your-feature-name
  2. Open a pull request on GitHub targeting the beta branch
  3. Complete the PR template checklist (verify branch origin, test coverage, documentation updates, and removal of dead code)

Summary

  • Fork and branch off beta (not main) when starting work on CoplayDev/unity-mcp.
  • Maintain domain symmetry by implementing every tool in both Server/src/services/tools/ (Python) and MCPForUnity/Editor/Tools/ (C#).
  • Use the correct decorators and attributes: @mcp_for_unity_tool for Python and [McpForUnityTool] for C#.
  • Test both layers: Python tests in Server/tests/ and Unity Edit-mode tests in TestProjects/UnityMCPTests/Assets/Tests/.
  • Validate locally using uv run pytest and tools/check-unity-versions.sh before submitting your PR.

Frequently Asked Questions

What branch should I target for pull requests?

Always target the beta branch. The beta branch serves as the active development line for the Unity MCP project, while main typically represents the latest stable release. The maintainers will merge beta into main when preparing releases.

Do I need to implement both Python and C# code for every contribution?

Yes. The architecture requires domain symmetry—every Python tool in Server/src/services/tools/ must have a corresponding C# implementation in MCPForUnity/Editor/Tools/. The Python layer handles MCP protocol communication, while the C# layer executes the actual Unity Editor operations.

How do I handle Unity version compatibility?

Place version-specific compatibility code in MCPForUnity/Runtime/Helpers/ using the existing shim pattern (e.g., Unity*Compat.cs files). The repository maintains support for multiple Unity versions, and the tools/check-unity-versions.sh script validates compilation across these versions.

What testing framework does the project use?

The Python codebase uses pytest with pytest-asyncio for asynchronous test support, located in Server/tests/. The Unity codebase uses NUnit for Edit-mode and Play-mode tests, located in TestProjects/UnityMCPTests/Assets/Tests/. Both test suites must pass before a pull request can be merged.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →