ach-mcp
README.md
# Ach MCP
An in-editor **MCP (Model Context Protocol) server** that exposes Unity
convenience tools to AI assistants such as Claude. The server runs entirely
inside the Unity Editor in C# (no separate process, no external bridge) and
speaks MCP over HTTP.
## Tools
| Tool | What it does |
|------|--------------|
| `get_console_logs` | Read Console entries — Debug logs, warnings, errors, and script **compile errors**. Filterable by severity. Closes the "did my change work?" loop. |
| `execute_menu_item` | Run any Editor menu item by path (e.g. `GameObject/Create Empty`, `Assets/Refresh`). One tool that unlocks most built-in and custom actions. |
| `get_scene_hierarchy` | Dump the GameObject tree of the open scene(s) as JSON — names, active state, tag, layer, and component types. |
| `take_screenshot` | Render the Game or Scene view camera to a PNG and return it inline. Lets the assistant *see* the result. |
## Requirements
- Unity **2021.3+**
- `com.unity.nuget.newtonsoft-json` (declared as a package dependency, installed automatically)
## Installation
Add the package to your project's `Packages/manifest.json`:
```json
{
"dependencies": {
"com.achieveone.ach-mcp": "https://github.com/achieveonepark/ach-mcp.git"
}
}
```
Or use **Window ▸ Package Manager ▸ + ▸ Add package from git URL** and paste the
repository URL.
## Usage
1. Open **Tools ▸ Ach MCP ▸ Control Panel**.
2. Set a **Port** (default `8790`) and click **Start**. Enable **Auto-start on
load** to have it come up with the editor.
3. In the **AI Client Setup** section, click **Configure** next to a client (or
**Configure Detected** to do all installed ones at once). Restart the client.
Once connected, ask the assistant to call the tools, e.g. *"check the Unity
console for errors"*, *"show me the scene hierarchy"*, or *"take a screenshot of
the game view."*
## One-click client setup
The control panel writes this server into each client's config file, resolving
the correct location for **macOS / Windows / Linux** automatically. Existing
configs are merged (your other servers are preserved) and backed up once as
`*.ach-mcp.bak` before the first change.
| Client | Transport | Config file |
|--------|-----------|-------------|
| Claude Code | HTTP (native) | `~/.claude.json` |
| Claude Desktop | stdio via `mcp-remote` | macOS `~/Library/Application Support/Claude/…` · Windows `%APPDATA%\Claude\…` · Linux `~/.config/Claude/…` |
| Codex CLI | stdio via `mcp-remote` | `~/.codex/config.toml` |
| Cursor | HTTP (native) | `~/.cursor/mcp.json` |
| Windsurf | HTTP (native) | `~/.codeium/windsurf/mcp_config.json` |
Clients that don't support HTTP MCP directly are bridged through
[`mcp-remote`](https://www.npmjs.com/package/mcp-remote), invoked as
`npx -y mcp-remote <url>`. Those rows are marked *"mcp-remote"* and require
**Node.js (npx)** on your PATH.
### Manual configuration
If you'd rather edit config by hand, the server is a standard Streamable-HTTP
MCP endpoint:
```
http://127.0.0.1:8790/mcp
```
Native-HTTP client (Claude Code, Cursor, …):
```json
{ "mcpServers": { "ach-unity": { "type": "http", "url": "http://127.0.0.1:8790/mcp" } } }
```
stdio-only client (Claude Desktop, Codex):
```json
{ "mcpServers": { "ach-unity": { "command": "npx", "args": ["-y", "mcp-remote", "http://127.0.0.1:8790/mcp"] } } }
```
## How it works
- **Transport** — a loopback `HttpListener` (`127.0.0.1`, so no admin/urlacl is
needed) accepts JSON-RPC 2.0 POSTs at `/mcp` and returns a single JSON
response (Streamable HTTP).
- **Threading** — HTTP requests are served on background threads; every tool
marshals its Unity API calls onto the main thread via `MainThreadDispatcher`.
- **Lifecycle** — `McpServerManager` stops the listener before every domain
reload and on editor quit, so the port is always released.
## Adding your own tool
1. Implement `IMcpTool` in `Editor/Tools/`.
2. Declare `Name`, `Description`, and an `InputSchema` (JSON Schema).
3. Register it in `ToolRegistry`'s static constructor.
```csharp
internal sealed class MyTool : IMcpTool
{
public string Name => "my_tool";
public string Description => "What it does.";
public JObject InputSchema => new JObject { ["type"] = "object" };
public ToolResult Execute(JObject arguments)
{
var value = MainThreadDispatcher.Run(() => /* Unity API here */ 42);
return ToolResult.Ok("Result: " + value);
}
}
```
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues