What Is the McpServer Component in Unity C#? A Complete Technical Guide

The McpServer component is a TCP-based runtime bridge that enables bidirectional communication between the Unity Editor and external MCP (Model Context Protocol) clients, handling command dispatch, resource fetching, and thread-safe Unity API execution.

The McpServer class, located in the UnityMCP.Editor.Core namespace within the isuzu-shiranui/unitymcp repository, serves as the central nervous system for the Unity MCP package. It manages the connection lifecycle, routes incoming JSON commands to registered handlers, and ensures all Unity API interactions occur on the main thread.

Core Responsibilities of the McpServer Component

The McpServer component fulfills four primary architectural responsibilities to maintain stable communication between the Unity Editor and TypeScript-based MCP servers.

Connection Management (TCP/UDP)

The server maintains a persistent TCP connection using a TcpClient instance stored in the client field. It spawns a background thread (clientThread) that executes the RunClient method to handle incoming network traffic. For automatic server discovery, the component optionally listens for UDP broadcasts on a configurable broadcastPort.

Reconnection logic implements exponential back-off through the reconnectDelay and maxReconnectDelay fields. When a connection drops, the TryConnect method (lines 334-398 in McpServer.cs) waits progressively longer intervals before attempting to reconnect, preventing aggressive polling that could overwhelm the network stack.

Command Handling and Dispatch

Incoming commands follow a "prefix.action" naming convention (e.g., scene.createObject). The server stores command handlers in a Dictionary<string, HandlerRegistration> called commandHandlers. When the ExecuteCommand method (lines 800-885) receives a JSON payload, it:

  1. Parses the command string to extract the prefix
  2. Looks up the corresponding IMcpCommandHandler implementation
  3. Queues execution on the main thread via ExecuteOnMainThread
  4. Raises the CommandExecuted event upon completion

This architecture allows developers to extend the server with custom functionality by implementing the IMcpCommandHandler interface and registering instances via RegisterHandler.

Resource Handling

Resource handlers provide read-only access to Unity project data, such as asset lists or scene hierarchies. The resourceHandlers dictionary stores implementations of IMcpResourceHandler. The ProcessResourceRequest method (lines 668-748) handles resource queries by:

  • Validating the requested resource name exists in the dictionary
  • Queuing the fetch operation on the main thread
  • Waiting up to 5 seconds for the handler to return data
  • Serializing the result as a JSON response

This pattern ensures that resource-intensive queries (like scanning the entire AssetDatabase) never block the network thread.

Thread-Safe Unity Main Thread Execution

Unity's API is not thread-safe; all calls must originate from the main thread. The McpServer solves this through a lock-protected Queue<Action> named mainThreadQueue. Background threads enqueue actions using ExecuteOnMainThread (lines 889-896), while EditorApplication.update periodically invokes ProcessMainThreadQueue (lines 664-682) to drain the queue on the main thread.

This producer-consumer pattern allows the TCP client thread to remain responsive while ensuring Unity API calls (like instantiating GameObjects or modifying scenes) execute safely.

McpServer Lifecycle and Event Model

Understanding the initialization sequence and event system is crucial for debugging connection issues and implementing reactive UI components.

Initialization and Construction

The constructor (lines 94-112 in McpServer.cs) initializes the server configuration by reading McpSettings.instance, which provides the host address, TCP port, and UDP discovery settings. It also registers the ProcessMainThreadQueue method with EditorApplication.update to enable the main thread action processing loop.

public McpServer(int port = 0)
{
    // Loads settings from McpSettings.asset
    this.port = port > 0 ? port : McpSettings.instance.port;
    // Registers main thread queue processing
    EditorApplication.update += ProcessMainThreadQueue;
}

Starting the Server

The Start method (lines 146-173) creates a CancellationTokenSource to coordinate graceful shutdown, spawns the clientThread that runs RunClient, and optionally starts the UDP broadcast listener if discovery is enabled in settings.

Connection Events

The McpServer exposes four key events that implement the standard .NET EventHandler pattern:

  • Connected: Raised in OnConnected (line 480) immediately after TryConnect successfully establishes the TCP socket.
  • Disconnected: Raised in OnDisconnected (lines 571-579) when the connection drops, the cancellation token triggers, or an unrecoverable network error occurs.
  • CommandExecuted: Raised in OnCommandExecuted (lines 848-850) after ExecuteCommand completes, providing the prefix, action, and result payload.
  • ResourceFetched: Raised in OnResourceFetched (lines 448-452) when FetchResourceData successfully retrieves resource data.

These events enable decoupled architectures where UI components or logging systems can react to server state changes without modifying the core server code.

Shutdown and Disposal

The Stop method (lines 184-206) initiates graceful shutdown by canceling the token, closing sockets, and joining the client thread. Dispose (lines 271-280) ensures cleanup of unmanaged resources and removes the EditorApplication.update callback to prevent memory leaks in the editor.

Implementing Custom Handlers

Extending the McpServer requires implementing the handler interfaces and registering instances before calling Start.

Command Handlers (IMcpCommandHandler)

Command handlers process actions that modify the Unity state or execute editor operations. The interface requires:

public interface IMcpCommandHandler
{
    string CommandPrefix { get; }
    string Description { get; }
    JObject Execute(string action, JObject parameters);
}

The Execute method receives the action suffix (the part after the prefix) and a JSON parameter object. It must return a JSON object containing at least a status field.

Resource Handlers (IMcpResourceHandler)

Resource handlers provide read-only data access. The interface contract is:

public interface IMcpResourceHandler
{
    string ResourceName { get; }
    string ResourceUri { get; }
    string Description { get; }
    JObject FetchResource(JObject parameters);
}

Registration occurs via RegisterResourceHandler, which stores the instance in the resourceHandlers dictionary keyed by ResourceName.

Practical Example: Asset List Resource

Here is a complete resource handler implementation that exposes the project's prefab assets:

using UnityEditor;
using UnityMCP.Editor.Core;
using Newtonsoft.Json.Linq;
using System.Linq;

public class AssetListResource : IMcpResourceHandler
{
    public string ResourceName => "assetList";
    public string ResourceUri => null;
    public string Description => "Provides a list of all prefab assets in the project";

    public JObject FetchResource(JObject parameters)
    {
        var guids = AssetDatabase.FindAssets("t:Prefab");
        var paths = guids.Select(guid => AssetDatabase.GUIDToAssetPath(guid)).ToArray();

        return new JObject
        {
            ["status"] = "success",
            ["count"] = paths.Length,
            ["assets"] = new JArray(paths)
        };
    }
}

Register this during server initialization:

server.RegisterResourceHandler(new AssetListResource());

When the TypeScript MCP client sends {"type":"resource","command":"assetList.get","id":"42"}, the server will execute FetchResource on the main thread and return the JSON array of prefab paths.

Key Source Files and Architecture

The McpServer component is distributed across several files in the jp.shiranui-isuzu.unity-mcp package:

File Role
Editor/Core/McpServer.cs Central server implementation containing TCP client management, the RunClient loop, ExecuteCommand, ProcessResourceRequest, and the main thread queue processing.
Editor/Core/McpServiceManager.cs High-level façade that manages a singleton McpServer instance for the editor session, handling automatic startup and shutdown.
Editor/Settings/McpSettings.cs ScriptableObject storing host, port, UDP discovery settings, and per-handler enable states, editable via the Unity Settings window.
Editor/Core/IMcpCommandHandler.cs Interface defining the contract for command handlers (CommandPrefix, Execute).
Editor/Core/IMcpResourceHandler.cs Interface defining the contract for resource handlers (ResourceName, FetchResource).
Samples~/UnityMCPHandlerSamples/Editor/ Example implementations demonstrating custom handler registration and usage patterns.

These files collectively implement the Model Context Protocol server-side runtime, enabling external AI assistants and tools to interact with the Unity Editor through a structured JSON-RPC-like interface over TCP.

Summary

  • The McpServer component (UnityMCP.Editor.Core.McpServer) acts as the TCP bridge between the Unity Editor and external MCP clients, managing connection state, command routing, and resource access.
  • Connection management uses a background thread with exponential back-off reconnection logic, optional UDP discovery, and graceful cancellation token-based shutdown.
  • Command and resource handlers follow an interface-based plugin architecture (IMcpCommandHandler, IMcpResourceHandler) allowing developers to extend functionality by registering custom implementations.
  • Thread safety is enforced through a lock-protected main thread action queue (mainThreadQueue), ensuring all Unity API calls execute on the editor's main thread while network operations remain asynchronous.
  • Event-driven architecture exposes Connected, Disconnected, CommandExecuted, and ResourceFetched events for reactive UI updates and logging without coupling to the server internals.

Frequently Asked Questions

What is the primary purpose of the McpServer component in Unity C#?

The McpServer component serves as the runtime host that enables the Unity Editor to communicate with external Model Context Protocol (MCP) clients over TCP. It handles incoming JSON commands, routes them to registered handlers, manages resource requests, and ensures all Unity API interactions occur safely on the main thread, effectively turning the Editor into an MCP-compatible server.

How does McpServer handle thread safety with Unity APIs?

The component implements a producer-consumer pattern using a Queue<Action> named mainThreadQueue protected by a lock object. Background network threads enqueue actions via ExecuteOnMainThread, while EditorApplication.update periodically calls ProcessMainThreadQueue to execute these actions on Unity's main thread. This design prevents cross-thread access violations while maintaining responsive network I/O.

What is the difference between command handlers and resource handlers in McpServer?

Command handlers implement IMcpCommandHandler and process actions that may modify Unity state, such as creating GameObjects or modifying scenes; they follow a "prefix.action" naming convention and return JSON results via the Execute method. Resource handlers implement IMcpResourceHandler and provide read-only access to project data like asset lists or scene hierarchies through the FetchResource method, with built-in timeout handling up to 5 seconds.

How do I configure the McpServer connection settings in Unity?

Configuration is managed through the McpSettings ScriptableObject located at Editor/Settings/McpSettings.cs. You can edit these settings via Unity's Preferences window to adjust the TCP host, port number, enable UDP discovery for automatic server detection, and toggle individual handler registrations. The McpServer constructor automatically reads these settings during initialization, or you can pass a custom port parameter to the constructor for programmatic configuration.

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 →