Skip to main content
Glama
zloybest

UnityIndexMCP

by zloybest
README.md
# UnityIndexMCP

[![CI](https://github.com/zloybest/UnityIndexMCP/actions/workflows/ci.yml/badge.svg)](https://github.com/zloybest/UnityIndexMCP/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

UnityIndexMCP is a local, read-only [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server for Unity projects. It gives AI coding clients ranked code search, C# symbols, references, outlines, related Unity assets, and bounded snippets without sending project files to a hosted indexing service.

The lexical index supports C#, UXML, USS, shaders, assembly definitions, JSON, YAML, project settings, and package manifests. An optional .NET/Roslyn worker adds accurate C# symbol, reference, and implementation queries when Unity has generated a solution.

## Features

- Local SQLite/FTS5 index with live file watching
- Unity-aware discovery for `Assets`, `Packages`, and `ProjectSettings`
- Roslyn semantic analysis with graceful lexical fallback
- Bounded, ranked results designed to reduce agent context usage
- Multiple configurable Unity project roots
- Stdio transport with no network listener, telemetry, or write tools
- Windows, macOS, and Linux support wherever Node.js and .NET are available

## Requirements

- Node.js 22 or newer
- npm 9 or newer
- .NET 8 SDK for full semantic mode (optional, recommended)
- A Unity project with `Assets/` and `ProjectSettings/`
- A Unity-generated `.sln` or `.slnx` for full semantic mode

Unity 6 is the primary target. The lexical index can also work with older Unity projects that use the same project layout; Roslyn compatibility depends on the generated solution and installed SDKs.

## Install

Clone and build the server in a tools directory outside the Unity project:

```bash
git clone https://github.com/zloybest/UnityIndexMCP.git
cd UnityIndexMCP
npm ci
npm run build
npm run build:worker
```

`npm run build:worker` is optional. Without it, UnityIndexMCP continues in `degraded` semantic mode and all lexical tools remain available.

On Windows, stop connected MCP clients before rebuilding an existing worker; a running `dotnet` process locks `dist/worker/UnityCodeIndex.Worker.dll`.

## Configure a Unity project

Copy [`unity-index-mcp.config.example.json`](unity-index-mcp.config.example.json) to the root of the Unity project as `unity-index-mcp.config.json`. The portable minimum is:

```json
{
  "projectRoots": ["."]
}
```

Relative paths are resolved from the configuration file. If `solutionPath` is omitted, the server looks for a `.sln` or `.slnx` in the first project root. Each Unity project should normally use its own config and index database.

You may instead omit the config and set `UNITY_PROJECT_ROOT` to the Unity project directory. Use `UNITY_INDEX_CONFIG` when the MCP client starts outside the project directory:

```text
UNITY_INDEX_CONFIG=/absolute/path/to/MyGame/unity-index-mcp.config.json
```

### Configuration reference

| Setting | Default | Meaning |
|---|---:|---|
| `projectRoots` | required | Allowed Unity project directories |
| `solutionPath` | auto-detected | Unity-generated `.sln` or `.slnx` |
| `indexDbPath` | `.cache/unity-index/index.sqlite` | SQLite index, relative to the first project root |
| `semantic.enabled` | `true` | Enable the optional Roslyn worker |
| `semantic.workerPath` | `./dist/worker/UnityCodeIndex.Worker.dll` | Worker path, relative to the UnityIndexMCP install |
| `files.includePackages` | `true` | Index embedded/local package source |
| `files.includePackageCache` | `false` | Index Unity's generated package cache |
| `watch.enabled` | `true` | Incrementally index file changes |

See the example config for search, exclusions, logging, and other settings.

## Connect an MCP client

Use absolute paths in client configuration. Keep the server installation path and Unity project config path separate.

### Codex / ChatGPT desktop app

The quickest Codex CLI setup is:

```bash
codex mcp add unity-index \
  --env UNITY_INDEX_CONFIG=/absolute/path/to/MyGame/unity-index-mcp.config.json \
  -- node /absolute/path/to/UnityIndexMCP/dist/mcp/server.js
```

Or add the contents of [`codex-mcp-config.example.toml`](codex-mcp-config.example.toml) to `~/.codex/config.toml` (or `.codex/config.toml` in a trusted project), then restart the client. The ChatGPT desktop app, Codex CLI, and Codex IDE extension share that configuration; see the [official OpenAI MCP setup documentation](https://learn.chatgpt.com/docs/extend/mcp?surface=cli) for current client details.

### Claude Desktop and other JSON-configured clients

```json
{
  "mcpServers": {
    "unity-index": {
      "command": "node",
      "args": ["/absolute/path/to/UnityIndexMCP/dist/mcp/server.js"],
      "env": {
        "UNITY_INDEX_CONFIG": "/absolute/path/to/MyGame/unity-index-mcp.config.json"
      }
    }
  }
}
```

Restart the MCP client after changing its configuration. Call `index_status` first; initial indexing runs in the background.

## Tools

| Tool | Purpose |
|---|---|
| `index_status` | Index health, freshness, and semantic mode |
| `project_overview` | Project statistics, assemblies, and notable files |
| `refresh_index` | Full or incremental reindex |
| `search_text` | Ranked full-text search across supported files |
| `find_symbol` | C# declarations by name |
| `get_file_outline` | Compact type/member structure |
| `read_snippet` | Bounded source range within configured roots |
| `find_references` | C# references with Roslyn or lexical fallback |
| `find_implementations` | Implementations and derived types |
| `get_related_files` | Related code, UXML, USS, and configuration files |
| `find_examples` | Similar patterns and implementations |
| `impact_analysis` | Likely minimal file set for a described change |

[`AGENT_INSTRUCTIONS.md`](AGENT_INSTRUCTIONS.md) contains a reusable workflow prompt for clients that do not consume the server's MCP instructions.

## Semantic modes

| Mode | Behavior |
|---|---|
| `full` | Roslyn loaded the Unity solution; semantic references and implementations are available |
| `degraded` | The worker or solution is unavailable; lexical search, outlines, and heuristics remain available |
| `off` | Semantic indexing is disabled in configuration |

If the mode remains `degraded`, open the Unity project once, confirm its solution exists, build the worker, and verify `solutionPath` if auto-detection is not sufficient.

## Updating without breaking existing projects

The public product and solution are named UnityIndexMCP, but compatibility identifiers remain unchanged:

- npm package and executable: `unity-index-mcp`
- MCP server/config key: `unity-index`
- config files: `unity-index-mcp.config.json` and `.unity-index-mcp.json`
- environment variables: `UNITY_INDEX_CONFIG` and `UNITY_PROJECT_ROOT`
- worker assembly: `UnityCodeIndex.Worker.dll`

Existing client configurations that point at a checkout directory named `KebabIndex` continue to work because the local directory is not moved automatically. To update safely, stop MCP clients, pull changes, run `npm ci`, `npm run build`, and optionally `npm run build:worker`, then restart the clients. Existing per-project configs and SQLite indexes do not need migration.

## Development

```bash
npm ci
npm test -- --runInBand
npm run build
dotnet build UnityIndexMCP.sln -c Release
```

Integration tests use the repository's sample Unity project and do not require a Unity installation. See [CONTRIBUTING.md](CONTRIBUTING.md) before submitting a change.

## Security and privacy

UnityIndexMCP exposes only local stdio, has no write tools, makes no cloud calls, and restricts file reads to configured roots. The index stores source-derived text locally in the configured SQLite database, so exclude that database from source control and protect it like source code. See [SECURITY.md](SECURITY.md) for reporting vulnerabilities.

## Limitations

- Full semantic analysis requires a Unity-generated solution and the .NET worker.
- Scene and prefab YAML are lexically searchable but serialized object references are not semantically linked.
- UTF-8 is expected; UTF-16 and unusual encodings may not index correctly.
- Large projects may take several minutes to build their first index.
- Multiple roots share one database; identical root-relative paths can be ambiguous in tool output.

## License

[MIT](LICENSE). Unity is a trademark of Unity Technologies. This project is independent and is not affiliated with or endorsed by Unity Technologies.