# Unity API Verification Workflow with unity_reflect in MCP: A Complete Guide

> Master the Unity API verification workflow with unity_reflect in MCP. Explore type metadata, member signatures, and extension methods programmatically. Accelerate your development process today.

- Repository: [Coplay/unity-mcp](https://github.com/CoplayDev/unity-mcp)
- Tags: how-to-guide
- Published: 2026-07-06

---

**The `unity_reflect` MCP tool exposes Unity's reflection API to AI assistants through three core actions—`get_type`, `get_member`, and `search`—enabling programmatic verification of type metadata, member signatures, and extension methods across loaded assemblies with intelligent caching and ambiguity resolution.**

The `UnityReflect` class in the CoplayDev/unity-mcp repository provides a Model-Context Protocol (MCP) bridge that allows AI agents to inspect Unity's API surface without manual documentation lookups. According to the source code in [`MCPForUnity/Editor/Tools/UnityReflect.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/MCPForUnity/Editor/Tools/UnityReflect.cs), this Editor-side utility registers with the `[McpForUnityTool("unity_reflect", AutoRegister = false, Group = "docs")]` attribute and processes JSON-RPC requests to deliver accurate reflection data via the `HandleCommand` method.

## Core Actions and Request Routing

When an AI client issues a request containing an `action` field, `UnityReflect.HandleCommand` routes the payload to one of three high-level operations. Each action serves a distinct purpose in the Unity API verification workflow.

### get_type: Type Resolution and Metadata

The `get_type` action resolves type names—full or short—and returns comprehensive metadata including base classes, interfaces, and member inventories. The entry point `GetTypeInfo` first attempts resolution through `UnityTypeResolver.ResolveAny`, which handles Unity's editor/player type precedence. If that fails, the system falls back to scanning cached assemblies using common Unity namespace prefixes defined in the `NamespacePrefixes` collection.

When a short name like `Button` matches multiple types across different namespaces, the tool returns a `SuccessResponse` with `ambiguous: true` and a sorted list of candidate full names. This forces the caller to provide a fully-qualified name for subsequent member queries, preventing incorrect API assumptions.

### get_member: Detailed Member Inspection

The `get_member` action retrieves detailed information for specific type members via the `GetMemberInfo` entry point. The response includes the `member_type` classification (`method`, `property`, `field`, `event`, or `extension_method`), and for methods, an `overloads` array containing formatted signatures, parameter lists, return types, and `[Obsolete]` flags.

This action enables precise verification of method signatures before code generation, ensuring that AI assistants reference exact parameter types and generic constraints rather than approximations.

### search: Fuzzy Assembly Search

The `search` action performs fuzzy matching across loaded assemblies through the `SearchTypes` method. It respects the `scope` parameter—`unity`, `packages`, `project`, or `all`—via the `MatchesScope` classification logic. The algorithm ranks candidates by exact match, prefix matching, then substring containment, capping results at 25 entries to maintain performance.

## Internal Architecture and Caching Mechanisms

The `unity_reflect` tool implements several optimization strategies to minimize reflective enumeration overhead during a Unity session.

### Assembly Caching and Domain Reloads

The `GetAssemblyTypeCache` method builds a dictionary mapping `assemblyFullName` to `exportedTypes[]` on first use. This cache persists across requests but invalidates automatically after domain reloads via the `AssemblyReloadEvents.afterAssemblyReload` event. This ensures that newly compiled scripts or package additions are immediately available without manual cache clears.

### Generic Type Normalization

Before any type lookup, `NormalizeGenericName` converts human-readable generic syntax like `List<T>` or `Dictionary<TKey, TValue>` into CLR-compatible back-tick format (`List\`1`, `Dictionary\`2`). This normalization guarantees that generic type definitions are found even when the caller omits the ECMA-335 back-tick syntax required by `System.Type.GetType`.

### Extension Method Discovery

The `FindExtensionMethods` and `FindExtensionMethodInfos` methods scan static classes marked with `[Extension]` attributes in Unity assemblies. Results are cached per target type and presented as virtual members of the extended type, allowing the API verification workflow to surface LINQ-style extension methods that exist physically in separate static classes but logically belong to the target type's interface.

## Implementing the Unity API Verification Workflow

The following patterns demonstrate how to invoke the `unity_reflect` tool directly from C# tests or via the MCP bridge.

### Direct Invocation from Editor Tests

This pattern mirrors the MCP client behavior and matches the unit tests in [`TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/UnityReflectTests.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/UnityReflectTests.cs):

```csharp
using Newtonsoft.Json.Linq;
using MCPForUnity.Editor.Tools;

// Helper mimicking MCP JSON payload structure
static JObject InvokeReflect(string action, JObject extra = null)
{
    var payload = extra ?? new JObject();
    payload["action"] = action;
    var result = UnityReflect.HandleCommand(payload);
    return JObject.FromObject(result);
}

// Resolve Transform type and list members
var transformInfo = InvokeReflect("get_type", new JObject 
{ 
    ["class_name"] = "UnityEngine.Transform" 
});
Debug.Log(transformInfo.ToString());

// Get overloads for Physics.Raycast
var raycastInfo = InvokeReflect("get_member", new JObject
{
    ["class_name"] = "Physics",
    ["member_name"] = "Raycast"
});

// Search for NavMesh types in Unity scope
var searchResults = InvokeReflect("search", new JObject
{
    ["query"] = "NavMesh",
    ["scope"] = "unity"
});

```

### MCP Client JSON Payload

When sending over the bridge from an external MCP client, the payload structure follows this format:

```json
{
  "tool": "unity_reflect",
  "params": {
    "action": "get_type",
    "class_name": "Camera"
  }
}

```

The Python MCP server forwards this to Unity, where `HandleCommand` processes it and returns a JSON response with the type's full metadata.

### Handling Ambiguous Types and Generics

When resolving short names that exist in multiple namespaces, check the `ambiguous` flag and select from the `matches` array:

```csharp
var buttonInfo = InvokeReflect("get_type", new JObject 
{ 
    ["class_name"] = "Button" 
});

if ((bool)buttonInfo["data"]["ambiguous"])
{
    var candidates = buttonInfo["data"]["matches"] as JArray;
    var uiButton = candidates
        .First(c => c.ToString().Contains("UnityEngine.UI"));
    
    // Re-query with fully qualified name
    var resolved = InvokeReflect("get_type", new JObject 
    { 
        ["class_name"] = uiButton 
    });
}

```

Generic types require no special syntax from the caller due to automatic normalization:

```csharp
var listMetadata = InvokeReflect("get_type", new JObject 
{ 
    ["class_name"] = "List<T>" 
});
// Internal normalization converts to List`1 before lookup

```

## Error Handling and Response Contracts

All `unity_reflect` actions follow a consistent MCP response contract. Successful operations return `{ success: true, data: object }`, while validation failures or reflection exceptions return `{ success: false, error: string }` with the stack trace. This guarantees that MCP clients always receive well-formed JSON even when requesting non-existent types or members with insufficient permissions.

The exception handling in `GetTypeInfo`, `GetMemberInfo`, and `SearchTypes` wraps unexpected errors in `ErrorResponse` objects, preventing the Unity Editor from logging unhandled exceptions while still surfacing diagnostic information to the AI assistant.

## Summary

- **`UnityReflect`** is an MCP tool in [`MCPForUnity/Editor/Tools/UnityReflect.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/MCPForUnity/Editor/Tools/UnityReflect.cs) that exposes Unity reflection APIs via JSON-RPC.
- **Three actions** drive the workflow: `get_type` for type resolution, `get_member` for signature inspection, and `search` for fuzzy assembly queries.
- **Assembly caching** via `GetAssemblyTypeCache` persists across calls but invalidates on domain reloads to maintain accuracy.
- **Ambiguity detection** forces explicit namespace qualification when short names match multiple types, preventing API misuse.
- **Generic normalization** automatically converts friendly syntax like `List<T>` to CLR back-tick format (`List\`1`).
- **Extension methods** are discovered via `FindExtensionMethods` and surfaced as virtual members of target types.

## Frequently Asked Questions

### How does unity_reflect handle ambiguous type names?

When a short name like `Button` matches multiple types across namespaces, the tool returns `ambiguous: true` with a sorted `matches` array containing fully-qualified names. The caller must re-query with a specific full name from this list to resolve the ambiguity and retrieve accurate member data.

### What are the available search scopes in the unity_reflect tool?

The `search` action accepts four scope values: `unity` (core Unity assemblies), `packages` (installed Unity packages), `project` (user scripts), and `all` (everything loaded). The `MatchesScope` method classifies assemblies based on their origin, ensuring that searches respect the requested boundary and return relevant results.

### How does the tool discover extension methods for Unity types?

`FindExtensionMethods` scans static classes marked with `[Extension]` attributes across loaded assemblies and caches the results per target type. These methods appear as `extension_method` entries in `get_type` responses and can be queried directly via `get_member`, allowing the API verification workflow to surface helper methods that exist in separate static classes but operate on Unity objects.

### What happens to the reflection cache when Unity reloads scripts?

The assembly cache invalidates automatically via the `AssemblyReloadEvents.afterAssemblyReload` event. This ensures that `GetAssemblyTypeCache` rebuilds its dictionary of exported types after script compilation or domain reloads, preventing stale references to modified user code or newly installed packages.