Skip to content

Conversation

@akshay-kiddopia
Copy link

@akshay-kiddopia akshay-kiddopia commented Dec 30, 2025

  • Support for OpenCode's custom config format at ~/.config/opencode/opencode.json
  • Uses "mcp" object with "type": "remote" for HTTP transport
  • Auto-configures and preserves existing MCP servers in config

Summary by Sourcery

Add configurator to integrate Unity MCP with the OpenCode (opencode.ai) client via its custom configuration file.

New Features:

  • Introduce an OpenCode MCP client configurator that reads and writes ~/.config/opencode/opencode.json using the client's custom MCP schema.
  • Automatically create or update the OpenCode MCP entry with a remote HTTP endpoint while preserving other configuration.
  • Provide a manual configuration snippet and installation steps for setting up Unity MCP within OpenCode.

Summary by CodeRabbit

  • New Features
    • Added OpenCode integration for MCP: automatic configuration, per-OS config path handling, status validation (Configured/NotConfigured/IncorrectPath/Error) with optional auto-rewrite, and manual configuration snippet.
    • Provides user-facing installation and step-by-step setup guidance for integrating Unity MCP with OpenCode.

✏️ Tip: You can customize this high-level summary in your review settings.

  - Support for OpenCode's custom config format at ~/.config/opencode/opencode.json
  - Uses "mcp" object with "type": "remote" for HTTP transport
  - Auto-configures and preserves existing MCP servers in config
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Dec 30, 2025

Reviewer's Guide

Adds an OpenCode (opencode.ai) MCP client configurator that reads/writes OpenCode’s custom ~/.config/opencode/opencode.json format, auto-detects and configures the Unity MCP HTTP endpoint, and provides a manual configuration snippet and installation steps.

Sequence diagram for OpenCodeConfigurator automatic configuration flow

sequenceDiagram
    actor User
    participant UnityEditor
    participant OpenCodeConfigurator
    participant FileSystem
    participant HttpEndpointUtility
    participant OpenCodeApp
    participant UnityMcpServer

    User->>UnityEditor: Click Configure for OpenCode
    UnityEditor->>OpenCodeConfigurator: Configure()

    OpenCodeConfigurator->>OpenCodeConfigurator: GetConfigPath()
    OpenCodeConfigurator->>FileSystem: Ensure directory exists
    FileSystem-->>OpenCodeConfigurator: Directory ready

    OpenCodeConfigurator->>FileSystem: Read opencode.json (if exists)
    FileSystem-->>OpenCodeConfigurator: Existing JSON or empty

    OpenCodeConfigurator->>HttpEndpointUtility: GetMcpRpcUrl()
    HttpEndpointUtility-->>OpenCodeConfigurator: httpUrl

    OpenCodeConfigurator->>OpenCodeConfigurator: Build mcp.unityMCP entry
    OpenCodeConfigurator->>FileSystem: Write updated opencode.json
    FileSystem-->>OpenCodeConfigurator: Write success

    OpenCodeConfigurator->>OpenCodeConfigurator: client.SetStatus(Configured)
    OpenCodeConfigurator-->>UnityEditor: Return

    User->>OpenCodeApp: Start OpenCode
    OpenCodeApp->>FileSystem: Load ~/.config/opencode/opencode.json
    FileSystem-->>OpenCodeApp: Config with mcp.unityMCP

    OpenCodeApp->>UnityMcpServer: Connect via HTTP using url
    UnityMcpServer-->>OpenCodeApp: MCP responses
Loading

Class diagram for OpenCodeConfigurator MCP client integration

classDiagram
    class McpClientConfiguratorBase {
        +McpClient client
        +string CurrentOsPath()
        +string GetConfigPath()
        +McpStatus CheckStatus(bool attemptAutoRewrite)
        +void Configure()
        +string GetManualSnippet()
        +IList~string~ GetInstallationSteps()
    }

    class McpClient {
        +string name
        +string windowsConfigPath
        +string macConfigPath
        +string linuxConfigPath
        +McpStatus status
        +void SetStatus(McpStatus status, string message)
    }

    class McpStatus {
        <<enumeration>>
        NotConfigured
        Configured
        IncorrectPath
        Error
    }

    class HttpEndpointUtility {
        +string GetMcpRpcUrl()
    }

    class OpenCodeConfigurator {
        -const string ServerName
        +OpenCodeConfigurator()
        +string GetConfigPath()
        +McpStatus CheckStatus(bool attemptAutoRewrite)
        +void Configure()
        +string GetManualSnippet()
        +IList~string~ GetInstallationSteps()
        -static string BuildConfigPath()
    }

    McpClientConfiguratorBase <|-- OpenCodeConfigurator
    McpClientConfiguratorBase o-- McpClient
    McpClientConfiguratorBase --> McpStatus
    McpClientConfiguratorBase --> HttpEndpointUtility
    McpClient --> McpStatus
Loading

File-Level Changes

Change Details Files
Introduce OpenCode MCP client configurator that integrates with OpenCode’s custom JSON config file and HTTP-based MCP transport.
  • Create OpenCodeConfigurator deriving from McpClientConfiguratorBase with per‑OS config path resolution to ~/.config/opencode/opencode.json using the current user’s home directory.
  • Implement CheckStatus to read and parse the OpenCode config, inspect the "mcp" section for the unityMCP entry, compare its URL with the expected HTTP endpoint, and optionally auto-rewrite incorrect configs.
  • Implement Configure to create the config directory/file if missing, preserve existing config content, ensure an "mcp" object exists, upsert the unityMCP entry with type "remote" and enabled=true, then write the file back as pretty-printed JSON.
  • Implement GetManualSnippet to generate a minimal JSON snippet containing only the mcp.unityMCP remote configuration for manual setup.
  • Implement GetInstallationSteps to return concise instructions for installing OpenCode, running configuration, and restarting so it detects the Unity MCP server.
MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs
MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs.meta

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 30, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds a new OpenCodeConfigurator that reads/writes OpenCode's JSON config at ~/.config/opencode/opencode.json to register Unity's MCP endpoint (mcp.unityMCP), supports status checks, auto-rewrite configuration, and provides manual snippet and installation steps.

Changes

Cohort / File(s) Summary
New Configurator Class
MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs
New class implementing MCP configurator for OpenCode: builds per-OS config path, reads/parses JSON, checks mcp.unityMCP against HttpEndpointUtility.GetMcpRpcUrl(), conditionally auto-rewrites, writes config (with $schema and mcp.unityMCP { type:"remote", url, enabled:true }), and exposes manual snippet and installation steps.
Unity Metadata
MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs.meta
Adds .meta entry for the new source file (guid and fileFormatVersion).

Sequence Diagram(s)

sequenceDiagram
  participant Configurator as OpenCodeConfigurator
  participant Util as HttpEndpointUtility
  participant FS as FileSystem
  participant JSON as JSON Parser/Writer

  Note right of Configurator: CheckStatus / Configure flows
  Configurator->>Util: GetMcpRpcUrl()
  Util-->>Configurator: mcpRpcUrl
  Configurator->>FS: Read ~/.config/opencode/opencode.json
  alt file exists
    FS-->>Configurator: file content
    Configurator->>JSON: Parse
    JSON-->>Configurator: object
    Configurator->>Configurator: verify mcp.unityMCP and url
    alt mismatch & attemptAutoRewrite
      Configurator->>Configurator: Prepare mcp.unityMCP object
      Configurator->>JSON: Serialize
      JSON-->>Configurator: json text
      Configurator->>FS: Ensure dir & Write file
      FS-->>Configurator: write success
      Configurator-->>Configurator: status = Configured
    else matching
      Configurator-->>Configurator: status = Configured
    end
  else file missing or error
    Configurator->>Configurator: build base config with $schema and mcp section
    Configurator->>JSON: Serialize
    JSON-->>Configurator: json text
    Configurator->>FS: Create dir & Write file
    FS-->>Configurator: write success or error
    alt write success
      Configurator-->>Configurator: status = Configured
    else
      Configurator-->>Configurator: status = Error/IncorrectPath
    end
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • msanatan

Poem

🐰 I hopped to ~/.config with a curious cheer,

I nudged open opencode.json, tidy and clear,
I wrote unityMCP, remote and bright,
Now Unity and OpenCode converse at night,
Hooray — a rabbit's small config delight! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: adding a new OpenCode client configurator to the MCP for Unity project.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 51fb16c and 1ab182d.

📒 Files selected for processing (1)
  • MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs
🚧 Files skipped from review as they are similar to previous changes (1)
  • MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Sourcery review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • In Configure, wrapping all exceptions and rethrowing InvalidOperationException with only ex.Message drops the original stack trace and type; consider either using throw; after setting status, or including the original exception as an inner exception so callers can diagnose failures more easily.
  • Configure and GetManualSnippet duplicate the construction of the MCP JSON object (type/url/enabled); consider extracting a small helper method to build this JObject so the format stays consistent if it ever changes.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `Configure`, wrapping all exceptions and rethrowing `InvalidOperationException` with only `ex.Message` drops the original stack trace and type; consider either using `throw;` after setting status, or including the original exception as an inner exception so callers can diagnose failures more easily.
- `Configure` and `GetManualSnippet` duplicate the construction of the MCP JSON object (type/url/enabled); consider extracting a small helper method to build this `JObject` so the format stays consistent if it ever changes.

## Individual Comments

### Comment 1
<location> `MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs:118-119` </location>
<code_context>
+                    config["mcp"] = new JObject();
+                }
+
+                var mcpSection = config["mcp"] as JObject;
+                string httpUrl = HttpEndpointUtility.GetMcpRpcUrl();
+
+                mcpSection[ServerName] = new JObject
</code_context>

<issue_to_address>
**issue (bug_risk):** Guard against `config["mcp"]` not being a `JObject` to avoid a potential null dereference.

If `config["mcp"]` exists but isn’t a `JObject`, `as JObject` returns `null` and `mcpSection[ServerName] = ...` will throw. Validate `mcpSection` and either create a new `JObject` or fail more gracefully, e.g.:

```csharp
var mcpSection = config["mcp"] as JObject;
if (mcpSection == null)
{
    mcpSection = new JObject();
    config["mcp"] = mcpSection;
}

mcpSection[ServerName] = new JObject { ... };
```
</issue_to_address>

### Comment 2
<location> `MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs:131-137` </location>
<code_context>
+
+                client.SetStatus(McpStatus.Configured);
+            }
+            catch (Exception ex)
+            {
+                throw new InvalidOperationException($"Failed to configure OpenCode: {ex.Message}");
+            }
+        }
</code_context>

<issue_to_address>
**suggestion:** Preserve the original exception as an inner exception when wrapping it.

Using only `ex.Message` discards the original stack trace and context, which makes diagnosing issues much harder. Instead, pass the original exception as the inner exception:

```csharp
catch (Exception ex)
{
    throw new InvalidOperationException("Failed to configure OpenCode.", ex);
}
```

This keeps a clear user-facing message while preserving the root cause for logging and debugging.

```suggestion
                client.SetStatus(McpStatus.Configured);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("Failed to configure OpenCode.", ex);
            }
        }
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b866a4c and 51fb16c.

📒 Files selected for processing (2)
  • MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs
  • MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs.meta
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-10-13T13:27:23.040Z
Learnt from: msanatan
Repo: CoplayDev/unity-mcp PR: 316
File: TestProjects/UnityMCPTests/Assets/Tests/EditMode/Resources.meta:1-8
Timestamp: 2025-10-13T13:27:23.040Z
Learning: UnityMcpBridge is a legacy project kept for backwards compatibility; MCPForUnity is the only active Unity plugin project. GUID collisions between UnityMcpBridge and MCPForUnity are acceptable.

Applied to files:

  • MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs.meta
📚 Learning: 2025-12-29T15:23:11.613Z
Learnt from: msanatan
Repo: CoplayDev/unity-mcp PR: 491
File: MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs:78-115
Timestamp: 2025-12-29T15:23:11.613Z
Learning: In MCPForUnity, prefer relying on the established testing process to catch UI initialization issues instead of adding defensive null checks for UI elements in editor windows. This means during reviews, verify that tests cover UI initialization paths and that code avoids repetitive null-check boilerplate in Editor Windows. If a UI element can be null, ensure there is a well-tested fallback or that its initialization is guaranteed by design, rather than sprinkling null checks throughout editor code.

Applied to files:

  • MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs
🧬 Code graph analysis (1)
MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs (3)
MCPForUnity/Editor/Models/McpClient.cs (2)
  • McpClient (5-55)
  • SetStatus (42-54)
MCPForUnity/Editor/Clients/McpClientConfiguratorBase.cs (2)
  • CurrentOsPath (50-57)
  • UrlsEqual (59-79)
MCPForUnity/Editor/Helpers/HttpEndpointUtility.cs (2)
  • HttpEndpointUtility (12-85)
  • GetMcpRpcUrl (38-41)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Sourcery review
🔇 Additional comments (7)
MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs.meta (1)

1-2: LGTM!

Standard Unity metadata file with proper format and unique GUID.

MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs (6)

34-34: LGTM!

Correctly delegates to the base class method to retrieve the OS-specific path.


36-86: LGTM!

The status checking logic correctly handles various configuration states, performs URL validation, and implements auto-rewrite functionality with proper exception handling.


139-155: LGTM!

The manual snippet generation correctly constructs the JSON structure matching the auto-configuration format, making it easy for users to manually configure if needed.


157-163: LGTM!

Clear, actionable installation steps that guide users through the OpenCode setup process.


109-109: The schema URL https://opencode.ai/config.json is correct and matches the official OpenCode configuration documentation.


28-32: No issues found. The Windows path implementation is correct—OpenCode intentionally uses Unix-style paths across all platforms, and ~/.config/opencode/opencode.json is the officially documented global config location. Using the same BuildConfigPath() for all OS platforms is appropriate.

  - Support for OpenCode's custom config format at ~/.config/opencode/opencode.json
  - Uses 'mcp' object with 'type': 'remote' for HTTP transport
  - Auto-configures and preserves existing MCP servers in config
@msanatan
Copy link
Contributor

Hey @akshay-kiddopia , thanks for making this PR!!! Can you help me with a couple of things?

  • What does the OpenCode JSON look like?
  • Can you share a screenshot/video of it working on your local?

@msanatan
Copy link
Contributor

Here's an example MCP configurator for a JSON schema: https://github.com/CoplayDev/unity-mcp/blob/main/MCPForUnity/Editor/Clients/Configurators/AntigravityConfigurator.cs

Yours looks much more complex! Sharing the format of the MCP config file may help determine if there are tweaks we can make to the configurator to simplify your addition

@msanatan
Copy link
Contributor

msanatan commented Jan 7, 2026

@akshay-kiddopia any feedback?

@akshay-kiddopia
Copy link
Author

akshay-kiddopia commented Jan 8, 2026

@akshay-kiddopia any feedback?

Hey, sorry wasn't active last few days.
The issue was that format of Open Code is different than others.

This is how my json looks like at /Users/username/.config/opencode/opencode.json

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "mgrep": {
      "type": "local",
      "command": [
        "mgrep",
        "mcp"
      ],
      "enabled": true
    },
    "unityMCP": {
      "type": "remote",
      "url": "http://localhost:8080/mcp",
      "enabled": true
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants