|
| 1 | +# MCP Client Configurators |
| 2 | + |
| 3 | +This guide explains how MCP client configurators work in this repo and how to add a new one. |
| 4 | + |
| 5 | +It covers: |
| 6 | + |
| 7 | +- **Typical JSON-file clients** (Cursor, VSCode GitHub Copilot, Windsurf, Kiro, Trae, Antigravity, etc.). |
| 8 | +- **Special clients** like **Claude CLI** and **Codex** that require custom logic. |
| 9 | +- **How to add a new configurator class** so it shows up automatically in the MCP for Unity window. |
| 10 | + |
| 11 | +## Quick example: JSON-file configurator |
| 12 | + |
| 13 | +For most clients you just need a small class like this: |
| 14 | + |
| 15 | +```csharp |
| 16 | +using System; |
| 17 | +using System.Collections.Generic; |
| 18 | +using System.IO; |
| 19 | +using MCPForUnity.Editor.Models; |
| 20 | + |
| 21 | +namespace MCPForUnity.Editor.Clients.Configurators |
| 22 | +{ |
| 23 | + public class MyClientConfigurator : JsonFileMcpConfigurator |
| 24 | + { |
| 25 | + public MyClientConfigurator() : base(new McpClient |
| 26 | + { |
| 27 | + name = "My Client", |
| 28 | + windowsConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".myclient", "mcp.json"), |
| 29 | + macConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".myclient", "mcp.json"), |
| 30 | + linuxConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".myclient", "mcp.json"), |
| 31 | + }) |
| 32 | + { } |
| 33 | + |
| 34 | + public override IList<string> GetInstallationSteps() => new List<string> |
| 35 | + { |
| 36 | + "Open My Client and go to MCP settings", |
| 37 | + "Open or create the mcp.json file at the path above", |
| 38 | + "Click Configure in MCP for Unity (or paste the manual JSON snippet)", |
| 39 | + "Restart My Client" |
| 40 | + }; |
| 41 | + } |
| 42 | +} |
| 43 | +``` |
| 44 | + |
| 45 | +--- |
| 46 | + |
| 47 | +## How the configurator system works |
| 48 | + |
| 49 | +At a high level: |
| 50 | + |
| 51 | +- **`IMcpClientConfigurator`** (`MCPForUnity/Editor/Clients/IMcpClientConfigurator.cs`) |
| 52 | + - Contract for all MCP client configurators. |
| 53 | + - Handles status detection, auto-configure, manual snippet, and installation steps. |
| 54 | + |
| 55 | +- **Base classes** (`MCPForUnity/Editor/Clients/McpClientConfiguratorBase.cs`) |
| 56 | + - **`McpClientConfiguratorBase`** |
| 57 | + - Common properties and helpers. |
| 58 | + - **`JsonFileMcpConfigurator`** |
| 59 | + - For JSON-based config files (most clients). |
| 60 | + - Implements `CheckStatus`, `Configure`, and `GetManualSnippet` using `ConfigJsonBuilder`. |
| 61 | + - **`CodexMcpConfigurator`** |
| 62 | + - For Codex-style TOML config files. |
| 63 | + - **`ClaudeCliMcpConfigurator`** |
| 64 | + - For CLI-driven clients like Claude Code (register/unregister via CLI, not JSON files). |
| 65 | + |
| 66 | +- **`McpClient` model** (`MCPForUnity/Editor/Models/McpClient.cs`) |
| 67 | + - Holds the per-client configuration: |
| 68 | + - `name` |
| 69 | + - `windowsConfigPath`, `macConfigPath`, `linuxConfigPath` |
| 70 | + - Status and several **JSON-config flags** (used by `JsonFileMcpConfigurator`): |
| 71 | + - `IsVsCodeLayout` – VS Code-style layout (`servers` root, `type` field, etc.). |
| 72 | + - `SupportsHttpTransport` – whether the client supports HTTP transport. |
| 73 | + - `EnsureEnvObject` – ensure an `env` object exists. |
| 74 | + - `StripEnvWhenNotRequired` – remove `env` when not needed. |
| 75 | + - `HttpUrlProperty` – which property holds the HTTP URL (e.g. `"url"` vs `"serverUrl"`). |
| 76 | + - `DefaultUnityFields` – key/value pairs like `{ "disabled": false }` applied when missing. |
| 77 | + |
| 78 | +- **Auto-discovery** (`McpClientRegistry`) |
| 79 | + - `McpClientRegistry.All` uses `TypeCache.GetTypesDerivedFrom<IMcpClientConfigurator>()` to find configurators. |
| 80 | + - A configurator appears automatically if: |
| 81 | + - It is a **public, non-abstract class**. |
| 82 | + - It has a **public parameterless constructor**. |
| 83 | + - No extra registration list is required. |
| 84 | + |
| 85 | +--- |
| 86 | + |
| 87 | +## Typical JSON-file clients |
| 88 | + |
| 89 | +Most MCP clients use a JSON config file that defines one or more MCP servers. Examples: |
| 90 | + |
| 91 | +- **Cursor** – `JsonFileMcpConfigurator` (global `~/.cursor/mcp.json`). |
| 92 | +- **VSCode GitHub Copilot** – `JsonFileMcpConfigurator` with `IsVsCodeLayout = true`. |
| 93 | +- **Windsurf** – `JsonFileMcpConfigurator` with Windsurf-specific flags (`HttpUrlProperty = "serverUrl"`, `DefaultUnityFields["disabled"] = false`, etc.). |
| 94 | +- **Kiro**, **Trae**, **Antigravity (Gemini)** – JSON configs with project-specific paths and flags. |
| 95 | + |
| 96 | +All of these follow the same pattern: |
| 97 | + |
| 98 | +1. **Subclass `JsonFileMcpConfigurator`.** |
| 99 | +2. **Provide a `McpClient` instance** in the constructor with: |
| 100 | + - A user-friendly `name`. |
| 101 | + - OS-specific config paths. |
| 102 | + - Any JSON behavior flags as needed. |
| 103 | +3. **Override `GetInstallationSteps`** to describe how users open or edit the config. |
| 104 | +4. Rely on **base implementations** for: |
| 105 | + - `CheckStatus` – reads and validates the JSON config; can auto-rewrite to match Unity MCP. |
| 106 | + - `Configure` – writes/rewrites the config file. |
| 107 | + - `GetManualSnippet` – builds a JSON snippet using `ConfigJsonBuilder`. |
| 108 | + |
| 109 | +### JSON behavior controlled by `McpClient` |
| 110 | + |
| 111 | +`JsonFileMcpConfigurator` relies on the fields on `McpClient`: |
| 112 | + |
| 113 | +- **HTTP vs stdio** |
| 114 | + - `SupportsHttpTransport` + `EditorPrefs.UseHttpTransport` decide whether to configure |
| 115 | + - `url` / `serverUrl` (HTTP), or |
| 116 | + - `command` + `args` (stdio with `uvx`). |
| 117 | +- **URL property name** |
| 118 | + - `HttpUrlProperty` (default `"url"`) selects which JSON property to use for HTTP urls. |
| 119 | + - Example: Windsurf and Antigravity use `"serverUrl"`. |
| 120 | +- **VS Code layout** |
| 121 | + - `IsVsCodeLayout = true` switches config structure to a VS Code compatible layout. |
| 122 | +- **Env object and default fields** |
| 123 | + - `EnsureEnvObject` / `StripEnvWhenNotRequired` control an `env` block. |
| 124 | + - `DefaultUnityFields` adds client-specific fields if they are missing (e.g. `disabled: false`). |
| 125 | + |
| 126 | +All of this logic is centralized in **`ConfigJsonBuilder`**, so most JSON-based clients **do not need to override** `GetManualSnippet`. |
| 127 | + |
| 128 | +--- |
| 129 | + |
| 130 | +## Special clients |
| 131 | + |
| 132 | +Some clients cannot be handled by the generic JSON configurator alone. |
| 133 | + |
| 134 | +### Codex (TOML-based) |
| 135 | + |
| 136 | +- Uses **`CodexMcpConfigurator`**. |
| 137 | +- Reads and writes a **TOML** config (usually `~/.codex/config.toml`). |
| 138 | +- Uses `CodexConfigHelper` to: |
| 139 | + - Parse the existing TOML. |
| 140 | + - Check for a matching Unity MCP server configuration. |
| 141 | + - Write/patch the Codex server block. |
| 142 | +- The `CodexConfigurator` class: |
| 143 | + - Only needs to supply a `McpClient` with TOML config paths. |
| 144 | + - Inherits the Codex-specific status and configure behavior from `CodexMcpConfigurator`. |
| 145 | + |
| 146 | +### Claude Code (CLI-based) |
| 147 | + |
| 148 | +- Uses **`ClaudeCliMcpConfigurator`**. |
| 149 | +- Configuration is stored **internally by the Claude CLI**, not in a JSON file. |
| 150 | +- `CheckStatus` and `Configure` are implemented in the base class using `claude mcp ...` commands: |
| 151 | + - `CheckStatus` calls `claude mcp list` to detect if `UnityMCP` is registered. |
| 152 | + - `Configure` toggles register/unregister via `claude mcp add/remove UnityMCP`. |
| 153 | +- The `ClaudeCodeConfigurator` class: |
| 154 | + - Only needs a `McpClient` with a `name`. |
| 155 | + - Overrides `GetInstallationSteps` with CLI-specific instructions. |
| 156 | + |
| 157 | +### Claude Desktop (JSON with restrictions) |
| 158 | + |
| 159 | +- Uses **`JsonFileMcpConfigurator`**, but only supports **stdio transport**. |
| 160 | +- `ClaudeDesktopConfigurator`: |
| 161 | + - Sets `SupportsHttpTransport = false` in `McpClient`. |
| 162 | + - Overrides `Configure` / `GetManualSnippet` to: |
| 163 | + - Guard against HTTP mode. |
| 164 | + - Provide clear error text if HTTP is enabled. |
| 165 | + |
| 166 | +--- |
| 167 | + |
| 168 | +## Adding a new MCP client (typical JSON case) |
| 169 | + |
| 170 | +This is the most common scenario: your MCP client uses a JSON file to configure servers. |
| 171 | + |
| 172 | +### 1. Choose the base class |
| 173 | + |
| 174 | +- Use **`JsonFileMcpConfigurator`** if your client reads a JSON config file. |
| 175 | +- Consider **`CodexMcpConfigurator`** only if you are integrating a TOML-based client like Codex. |
| 176 | +- Consider **`ClaudeCliMcpConfigurator`** only if your client exposes a CLI command to manage MCP servers. |
| 177 | + |
| 178 | +### 2. Create the configurator class |
| 179 | + |
| 180 | +Create a new file under: |
| 181 | + |
| 182 | +```text |
| 183 | +MCPForUnity/Editor/Clients/Configurators |
| 184 | +``` |
| 185 | + |
| 186 | +Name it something like: |
| 187 | + |
| 188 | +```text |
| 189 | +MyClientConfigurator.cs |
| 190 | +``` |
| 191 | + |
| 192 | +Inside, follow the existing pattern (e.g. `CursorConfigurator`, `WindsurfConfigurator`, `KiroConfigurator`): |
| 193 | + |
| 194 | +- **Namespace** must be: |
| 195 | + - `MCPForUnity.Editor.Clients.Configurators` |
| 196 | +- **Class**: |
| 197 | + - `public class MyClientConfigurator : JsonFileMcpConfigurator` |
| 198 | +- **Constructor**: |
| 199 | + - Public, **parameterless**, and call `base(new McpClient { ... })`. |
| 200 | + - Set at least: |
| 201 | + - `name = "My Client"` |
| 202 | + - `windowsConfigPath = ...` |
| 203 | + - `macConfigPath = ...` |
| 204 | + - `linuxConfigPath = ...` |
| 205 | + - Optionally set flags: |
| 206 | + - `IsVsCodeLayout = true` for VS Code-style config. |
| 207 | + - `HttpUrlProperty = "serverUrl"` if your client expects `serverUrl`. |
| 208 | + - `EnsureEnvObject` / `StripEnvWhenNotRequired` based on env handling. |
| 209 | + - `DefaultUnityFields = { { "disabled", false }, ... }` for client-specific defaults. |
| 210 | + |
| 211 | +Because the constructor is parameterless and public, **`McpClientRegistry` will auto-discover this configurator** with no extra registration. |
| 212 | + |
| 213 | +### 3. Add installation steps |
| 214 | + |
| 215 | +Override `GetInstallationSteps` to tell users how to configure the client: |
| 216 | + |
| 217 | +- Where to find or create the JSON config file. |
| 218 | +- Which menu path opens the MCP settings. |
| 219 | +- Whether they should rely on the **Configure** button or copy-paste the manual JSON. |
| 220 | + |
| 221 | +Look at `CursorConfigurator`, `VSCodeConfigurator`, `KiroConfigurator`, `TraeConfigurator`, or `AntigravityConfigurator` for phrasing. |
| 222 | + |
| 223 | +### 4. Rely on the base JSON logic |
| 224 | + |
| 225 | +Unless your client has very unusual behavior, you typically **do not need to override**: |
| 226 | + |
| 227 | +- `CheckStatus` |
| 228 | +- `Configure` |
| 229 | +- `GetManualSnippet` |
| 230 | + |
| 231 | +The base `JsonFileMcpConfigurator`: |
| 232 | + |
| 233 | +- Detects missing or mismatched config. |
| 234 | +- Optionally rewrites config to match Unity MCP. |
| 235 | +- Builds a JSON snippet with **correct HTTP vs stdio settings**, using `ConfigJsonBuilder`. |
| 236 | + |
| 237 | +Only override these methods if your client has constraints that cannot be expressed via `McpClient` flags. |
| 238 | + |
| 239 | +### 5. Verify in Unity |
| 240 | + |
| 241 | +After adding your configurator class: |
| 242 | + |
| 243 | +1. Open Unity and the **MCP for Unity** window. |
| 244 | +2. Your client should appear in the list, sorted by display name (`McpClient.name`). |
| 245 | +3. Use **Check Status** to verify: |
| 246 | + - Missing config files show as `Not Configured`. |
| 247 | + - Existing files with matching server settings show as `Configured`. |
| 248 | +4. Click **Configure** to auto-write the config file. |
| 249 | +5. Restart your MCP client and confirm it connects to Unity. |
| 250 | + |
| 251 | +--- |
| 252 | + |
| 253 | +## Adding a custom (non-JSON) client |
| 254 | + |
| 255 | +If your MCP client doesnt store configuration as a JSON file, you likely need a custom base class. |
| 256 | + |
| 257 | +### Codex-style TOML client |
| 258 | + |
| 259 | +- Subclass **`CodexMcpConfigurator`**. |
| 260 | +- Provide TOML paths via `McpClient` (similar to `CodexConfigurator`). |
| 261 | +- Override `GetInstallationSteps` to describe how to open/edit the TOML. |
| 262 | + |
| 263 | +The Codex-specific status and configure logic is already implemented in the base class. |
| 264 | + |
| 265 | +### CLI-managed client (Claude-style) |
| 266 | + |
| 267 | +- Subclass **`ClaudeCliMcpConfigurator`**. |
| 268 | +- Provide a `McpClient` with a `name`. |
| 269 | +- Override `GetInstallationSteps` with the CLI flow. |
| 270 | + |
| 271 | +The base class: |
| 272 | + |
| 273 | +- Locates the CLI binary using `MCPServiceLocator.Paths`. |
| 274 | +- Uses `ExecPath.TryRun` to call `mcp list`, `mcp add`, and `mcp remove`. |
| 275 | +- Implements `Configure` as a toggle between register and unregister. |
| 276 | + |
| 277 | +Use this only if the client exposes an official CLI for managing MCP servers. |
| 278 | + |
| 279 | +--- |
| 280 | + |
| 281 | +## Summary |
| 282 | + |
| 283 | +- **For most MCP clients**, you only need to: |
| 284 | + - Create a `JsonFileMcpConfigurator` subclass in `Editor/Clients/Configurators`. |
| 285 | + - Provide a `McpClient` with paths and flags. |
| 286 | + - Override `GetInstallationSteps`. |
| 287 | +- **Special cases** like Codex (TOML) and Claude Code (CLI) have dedicated base classes. |
| 288 | +- **No manual registration** is needed: `McpClientRegistry` auto-discovers all configurators with a public parameterless constructor. |
| 289 | + |
| 290 | +Following these patterns keeps all MCP client integrations consistent and lets users configure everything from the MCP for Unity window with minimal friction. |
0 commit comments