# Unity MCP Architecture: Key Components of the Model Context Protocol Integration

> Discover the Unity MCP architecture. Learn about the C# server plugin and TypeScript client SDK that connect via TCP socket for seamless AI model integration in Unity.

- Repository: [いすず/unitymcp](https://github.com/isuzu-shiranui/unitymcp)
- Tags: architecture
- Published: 2026-03-04

---

**Unity MCP consists of a C# server plugin running inside the Unity editor and a TypeScript client SDK, connected via TCP socket to enable AI models to execute commands and access resources within Unity.**

Unity MCP (Model Context Protocol) is an open-source bridge that connects AI assistants to the Unity editor through a standardized protocol. Developed in the `isuzu-shiranui/unitymcp` repository, this system enables external AI models to invoke editor functions, query project state, and manipulate Unity objects programmatically. The architecture splits functionality between a Unity C# plugin that acts as the server and a TypeScript client that adapts MCP wire format for AI consumption.

## Unity MCP Runtime Architecture

Unity MCP operates through two tightly-coupled runtimes that communicate via JSON-RPC-style messages over TCP. The **Unity C# plugin** runs inside the editor as a server, while the **TypeScript client** runs externally as an SDK that AI models interact with.

| Runtime | Purpose | Principal Types |
|---------|---------|-----------------|
| **Unity C# plugin** | Listens on TCP socket, discovers handlers, executes commands on Unity main thread | `McpServer`, `IMcpCommandHandler`, `IMcpResourceHandler`, `McpServiceManager`, `McpHandlerDiscovery` |

| **TypeScript client** | Discovers handlers, adapts to MCP format, forwards calls via `UnityConnection` | `UnityConnection`, `HandlerDiscovery`, `HandlerAdapter`, `BaseCommandHandler`, `BaseResourceHandler`, `BasePromptHandler` |

## Unity C# Plugin Components

The C# side of Unity MCP runs within the Unity editor process and exposes editor functionality to external clients through a structured handler interface system.

### McpServer and TCP Listener

At the core of the Unity side sits **McpServer**, a Unity EditorWindow that initializes a `TcpListener` to accept incoming connections. This server receives JSON-RPC-style requests and routes them to appropriate handlers based on command prefixes. The server implementation ensures all handler execution occurs on Unity's main thread to prevent editor instability.

### Handler Interfaces

Unity MCP defines strict contracts for extensibility through two primary interfaces. **IMcpCommandHandler** handles tool-like invocations that perform actions, while **IMcpResourceHandler** provides read-only access to Unity editor state.

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

```

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

```

### Service Management and Discovery

**McpServiceManager** ([`Editor/Core/McpServiceManager.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/Editor/Core/McpServiceManager.cs)) functions as a lightweight dependency injection container, sharing singletons like logging and configuration between the server and handlers. **McpHandlerDiscovery** ([`Editor/Core/McpHandlerDiscovery.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/Editor/Core/McpHandlerDiscovery.cs)) scans all loaded assemblies at editor startup, instantiates concrete implementations of handler interfaces, and registers them automatically with the server without requiring manual configuration.

### Built-in C# Handlers

The repository ships with several default handlers located in `Editor/Handlers/`:

- **MenuItemCommandHandler.cs** – Executes Unity menu items programmatically
- **ConsoleCommandHandler.cs** – Reads from and writes to the Unity console
- **AssembliesResourceHandler.cs** – Reports loaded assemblies for introspection
- **PackagesResourceHandler.cs** – Lists installed Unity packages

## TypeScript Client Components

The TypeScript SDK provides the client-side implementation that AI models interact with, translating MCP protocol requests into TCP messages for the Unity server.

### UnityConnection and TCP Communication

**UnityConnection** ([`unity-mcp-ts/src/core/UnityConnection.ts`](https://github.com/isuzu-shiranui/unitymcp/blob/main/unity-mcp-ts/src/core/UnityConnection.ts)) encapsulates the TCP client functionality. It maintains the socket connection to Unity, performs JSON line-delimited framing, tracks request IDs for correlation, and exposes `sendRequest` and `setActiveClient` methods for handler implementations. The class operates as a singleton to ensure single connection management across the SDK.

### Handler Discovery and Registration

**HandlerDiscovery** ([`unity-mcp-ts/src/core/HandlerDiscovery.ts`](https://github.com/isuzu-shiranui/unitymcp/blob/main/unity-mcp-ts/src/core/HandlerDiscovery.ts)) walks the `handlers/` directory (or user-supplied directories), dynamically loads each module, and registers exported handler classes with the appropriate registry. **HandlerAdapter** ([`unity-mcp-ts/src/core/HandlerAdapter.ts`](https://github.com/isuzu-shiranui/unitymcp/blob/main/unity-mcp-ts/src/core/HandlerAdapter.ts)) bridges concrete handler implementations to the generic MCP wire format, ensuring protocol compliance without burdening handler authors.

### Base Handler Classes

The SDK provides abstract base classes that handle common plumbing including validation, schema generation, and request forwarding:

- **BaseCommandHandler.ts** – Foundation for tool-type handlers that execute actions
- **BaseResourceHandler.ts** – Foundation for data-provider handlers
- **BasePromptHandler.ts** – Foundation for reusable prompt templates

These classes require implementers only to define specific business logic while inheriting robust error handling and Unity communication patterns.

### Registries for Fast Lookup

Runtime maps store discovered handlers for O(1) access by name or prefix:

- **CommandRegistry.ts** – `Map<string, BaseCommandHandler>`
- **ResourceRegistry.ts** – `Map<string, BaseResourceHandler>`
- **PromptRegistry.ts** – `Map<string, BasePromptHandler>`

These registries reside in `unity-mcp-ts/src/core/` and enable the SDK to route incoming MCP requests to the correct handler without linear searches.

## Communication Flow Between Components

Unity MCP processes requests through a four-stage pipeline that maintains strict separation between the AI model interface and Unity editor execution:

1. **AI Model Emission** – Claude, ChatGPT, or other models emit tool/resource requests in MCP format
2. **TypeScript SDK Processing** – The SDK builds a JSON request containing `command`, `type`, `params`, and `id`, then transmits via `UnityConnection.sendRequest`
3. **Unity Execution** – The C# server receives the request, looks up the appropriate handler (command → `IMcpCommandHandler`, resource → `IMcpResourceHandler`), executes it on Unity's main thread, and returns a JSON response with `status`, `result`, and the original `id`

4. **Response Resolution** – The TypeScript client resolves the pending Promise and returns the result to the AI model

## Implementation Examples

### Creating a C# Command Handler

Implement `IMcpCommandHandler` to add custom Unity-side functionality. Place the file in an `Editor/` folder for automatic discovery.

```csharp
using Newtonsoft.Json.Linq;
using UnityMCP.Editor.Core;

namespace YourNamespace.Handlers
{
    internal sealed class YourCommandHandler : IMcpCommandHandler
    {
        public string CommandPrefix => "yourprefix";
        public string Description   => "Custom command for Unity";

        public JObject Execute(string action, JObject parameters)
        {
            if (action == "doSomething")
            {
                // Your Unity-side logic here
                return new JObject { ["success"] = true, ["msg"] = "Done!" };
            }

            return new JObject { ["success"] = false, ["error"] = $"Unknown action {action}" };
        }
    }
}

```

`McpHandlerDiscovery` automatically discovers this class at editor startup (see lines 24-28 in [`Editor/Core/McpHandlerDiscovery.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/Editor/Core/McpHandlerDiscovery.cs)).

### Creating a TypeScript Command Handler

Extend `BaseCommandHandler` to create client-side handlers that forward to Unity.

```typescript
import { BaseCommandHandler } from "../core/BaseCommandHandler.js";
import { IMcpToolDefinition } from "../core/interfaces/ICommandHandler.js";
import { JObject } from "../types/index.js";
import { z } from "zod";

export class YourCommandHandler extends BaseCommandHandler {
  public get commandPrefix() { return "yourprefix"; }
  public get description()   { return "Custom TypeScript command handler"; }

  public getToolDefinitions(): Map<string, IMcpToolDefinition> {
    const tools = new Map<string, IMcpToolDefinition>();
    tools.set("yourprefix_doSomething", {
      description: "Execute something in Unity",
      parameterSchema: {
        paramA: z.string().describe("First parameter"),
        paramB: z.number().optional().describe("Optional numeric value")
      },
      annotations: { title: "Do Something", readOnlyHint: true }
    });
    return tools;
  }

  protected async executeCommand(action: string, parameters: JObject): Promise<JObject> {
    // Forward the request to Unity via the shared connection
    return await this.sendUnityRequest(`${this.commandPrefix}.${action}`, parameters);
  }
}

```

The SDK loads this via `HandlerDiscovery` (lines 10-30 in [`HandlerDiscovery.ts`](https://github.com/isuzu-shiranui/unitymcp/blob/main/HandlerDiscovery.ts)) and registers it in `CommandRegistry`.

### Sending Requests from TypeScript

Use `UnityConnection` directly for ad-hoc communication with the Unity editor.

```typescript
import { UnityConnection } from "./core/UnityConnection.js";

async function askUnity() {
  const conn = UnityConnection.getInstance(); // singleton
  const request = {
    command: "yourprefix.doSomething",
    type: "tool",
    params: { paramA: "hello", paramB: 42 }
  };

  try {
    const response = await conn.sendRequest(request);
    console.log("Unity replied:", response);
  } catch (e) {
    console.error("Failed to talk to Unity:", e);
  }
}

```

The `sendRequest` method adds an `id`, writes newline-terminated JSON, and resolves when the server replies (see [`UnityConnection.ts`](https://github.com/isuzu-shiranui/unitymcp/blob/main/UnityConnection.ts) lines 107-125).

## Summary

- **Unity MCP** comprises a C# server plugin (`isuzu-shiranui/unitymcp`) and TypeScript client SDK communicating via TCP

- **C# components** include `McpServer`, handler interfaces (`IMcpCommandHandler`, `IMcpResourceHandler`), `McpServiceManager` for DI, and `McpHandlerDiscovery` for automatic registration

- **TypeScript components** include `UnityConnection` for TCP management, `HandlerDiscovery` for module loading, base handler classes for implementation templates, and typed registries for fast routing
- **Built-in handlers** cover common Unity editor operations like menu execution, console access, and package inspection
- **Extensibility** follows a dual-handler pattern where C# handlers execute in Unity and TypeScript handlers adapt MCP protocol, enabling AI models to control the editor through standardized tool calls

## Frequently Asked Questions

### What is the Model Context Protocol (MCP) in Unity?

MCP is a standardized protocol for connecting AI assistants to software tools. In Unity MCP, it provides a structured way for AI models like Claude to invoke Unity editor functions, read project state, and execute commands through a defined JSON-RPC interface over TCP sockets, rather than generating raw code snippets.

### How does Unity MCP ensure thread safety?

All C# handler execution occurs on Unity's main thread through the `McpServer` implementation, preventing race conditions with Unity's internal systems. The TypeScript client manages asynchronous communication through Promise-based request tracking, ensuring the AI client doesn't block while waiting for Unity operations to complete.

### Can I extend Unity MCP with custom functionality?

Yes. Implement `IMcpCommandHandler` or `IMcpResourceHandler` in C# for Unity-side logic, and the `McpHandlerDiscovery` class in [`Editor/Core/McpHandlerDiscovery.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/Editor/Core/McpHandlerDiscovery.cs) will automatically register your handler at startup. On the TypeScript side, extend `BaseCommandHandler` or `BaseResourceHandler` to create client-side adapters that translate MCP requests to your custom Unity commands.

### What are the key source files for modifying Unity MCP core behavior?

Critical files include [`Editor/Core/McpServiceManager.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/Editor/Core/McpServiceManager.cs) for dependency injection configuration, [`Editor/Core/McpHandlerDiscovery.cs`](https://github.com/isuzu-shiranui/unitymcp/blob/main/Editor/Core/McpHandlerDiscovery.cs) for registration logic, [`unity-mcp-ts/src/core/UnityConnection.ts`](https://github.com/isuzu-shiranui/unitymcp/blob/main/unity-mcp-ts/src/core/UnityConnection.ts) for transport-layer modifications, and [`unity-mcp-ts/src/core/HandlerAdapter.ts`](https://github.com/isuzu-shiranui/unitymcp/blob/main/unity-mcp-ts/src/core/HandlerAdapter.ts) for protocol adaptation logic. Built-in handler examples reside in `Editor/Handlers/` for reference implementations.