Skip to content

Conversation

@dsarno
Copy link
Collaborator

@dsarno dsarno commented Jan 22, 2026

Description

Add support for the OpenCode CLI client (opencode.ai) with automatic MCP server configuration. This
allows Unity MCP to automatically configure itself for users of the OpenCode AI coding assistant.

Type of Change

  • New feature (non-breaking change that adds functionality)

Changes Made

  • Added OpenCodeConfigurator.cs implementing IClientConfigurator
  • Configures via ~/.config/opencode/opencode.json (XDG Base Directory standard)
  • Uses McpConfigurationHelper.EnsureConfigDirectoryExists() and WriteAtomicFile() for safe file
    operations
  • Supports both creating new config files and merging with existing configurations
  • Extracts BuildServerEntry() helper to avoid JSON construction duplication

Testing/Screenshots/Recordings

  • Tested configuration creation with no existing config file
  • Tested merging with existing opencode.json configurations
  • Verified atomic write prevents config corruption on failure

Related Issues

Fixes #498

Additional Notes

  • OpenCode is an open-source AI coding assistant CLI: https://opencode.ai
  • Config path follows XDG standard (~/.config/opencode/opencode.json)
  • Original implementation by @akshay-kiddopia, refactored using existing helper patterns

Summary by Sourcery

Add an OpenCode (opencode.ai) client configurator to integrate Unity MCP with the OpenCode CLI via its JSON config file.

New Features:

  • Introduce an OpenCode client configurator that reads and writes the opencode.json MCP configuration for Unity MCP integration.
  • Provide automatic and manual configuration support for registering the Unity MCP server in OpenCode, including installation steps metadata.

Summary by CodeRabbit

  • New Features

    • Added OpenCode integration to Unity MCP with setup instructions and a manual configuration snippet.
    • Exposes status checks and installation steps visible to users.
    • Automatically creates required config storage when missing.
  • Bug Fixes

    • Handles missing or malformed OpenCode configs and offers optional auto-correction for mismatched endpoints.

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

Add support for the OpenCode CLI client with automatic configuration.

- Create OpenCodeConfigurator implementing IClientConfigurator
- Configure via ~/.config/opencode/opencode.json (XDG standard path)
- Use McpConfigurationHelper for atomic file writes and directory creation
- Support both new config creation and merging with existing config

Co-Authored-By: akshay-kiddopia <akshay@kiddopia.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jan 22, 2026

Reviewer's Guide

Adds a new OpenCode (opencode.ai) MCP client configurator that reads/writes ~/.config/opencode/opencode.json, ensuring safe creation/merging of the OpenCode MCP configuration and exposing manual snippet and installation steps for Unity MCP integration.

Class diagram for new OpenCode MCP client configurator

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

    class McpStatus {
    }

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

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

    class McpConfigurationHelper {
        +static void EnsureConfigDirectoryExists(path string)
        +static void WriteAtomicFile(path string, contents string)
    }

    class HttpEndpointUtility {
        +static string GetMcpRpcUrl()
    }

    class JObject {
        +JToken Item[string key]
    }

    McpClientConfiguratorBase <|-- OpenCodeConfigurator
    OpenCodeConfigurator --> McpClient : uses
    OpenCodeConfigurator --> McpStatus : sets
    OpenCodeConfigurator ..> McpConfigurationHelper : calls
    OpenCodeConfigurator ..> HttpEndpointUtility : calls
    OpenCodeConfigurator ..> JObject : config_json
Loading

File-Level Changes

Change Details Files
Introduce OpenCode MCP client configurator implementing status detection, automatic configuration/merge, and manual configuration hints.
  • Create OpenCodeConfigurator derived from McpClientConfiguratorBase with platform-agnostic config path resolution to ~/.config/opencode/opencode.json using the user home directory.
  • Implement CheckStatus to read existing opencode.json, inspect the mcp.unityMCP entry, compare the configured URL to the expected Unity MCP RPC URL, and optionally auto-rewrite incorrect configs.
  • Implement Configure to ensure the config directory exists, load or initialize the JSON config (including $schema), merge/update the mcp section with the unityMCP server entry, and persist via atomic file write.
  • Provide GetManualSnippet to output the minimal JSON snippet for manually adding the unityMCP server entry in OpenCode config.
  • Provide GetInstallationSteps to guide users through installing OpenCode and enabling Unity MCP, and factor out BuildServerEntry helper to centralize the server JSON structure.
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 Jan 22, 2026

Caution

Review failed

The pull request is closed.

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 an OpenCodeConfigurator class to integrate OpenCode (opencode.ai) with Unity MCP. The configurator reads/writes the per-OS OpenCode config (~/.config/opencode/opencode.json), validates and optionally auto-corrects the MCP RPC URL, exposes status and manual snippet methods, and writes the MCP entry under mcp.unityMCP.

Changes

Cohort / File(s) Summary
OpenCode Configurator Implementation
MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs
New configurator deriving from McpClientConfiguratorBase. Resolves per-OS config path, loads/parses OpenCode JSON, checks status (Configured / NotConfigured / IncorrectPath / Error), compares MCP RPC URL with expected value, optionally auto-rewrites config, builds/writes mcp.unityMCP entry (type: "remote", url, enabled: true), provides manual snippet and installation steps, and creates config directory when needed.
Unity Metadata
MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs.meta
Added Unity .meta file (GUID and fileFormatVersion).

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Config as "OpenCodeConfigurator"
participant FS as "Filesystem"
participant JSON as "OpenCode JSON"
participant MCP as "Expected MCP RPC"
Config->>FS: Read config file (~/.config/opencode/opencode.json)
FS-->>Config: File contents / not found
alt file found
Config->>JSON: Parse JSON
JSON-->>Config: Parsed object / error
Config->>MCP: Compare configured RPC URL vs expected
alt URLs match
Config-->>Config: Status = Configured
else URLs differ
alt attemptAutoRewrite allowed
Config->>JSON: Update mcp.unityMCP entry
Config->>FS: Write updated JSON
FS-->>Config: Write success/failure
Config-->>Config: Update status accordingly
else
Config-->>Config: Status = IncorrectPath
end
end
else file missing
alt attemptAutoRewrite allowed
Config->>JSON: Create new config with mcp.unityMCP
Config->>FS: Write new file (create dir if needed)
FS-->>Config: Write success/failure
Config-->>Config: Update status accordingly
else
Config-->>Config: Status = NotConfigured
end
end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • msanatan

Poem

🐇 I hopped to a JSON by moonlit code,
Found MCP paths where configs flowed,
I nudged the URL and wrote with care,
Now Unity and OpenCode make a pair,
Hop, patch, and ship — a rabbit's ode. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding OpenCode client configurator support to the codebase.
Description check ✅ Passed The description fully covers all template sections including type of change, changes made, testing, related issues, and additional context with proper formatting.
Linked Issues check ✅ Passed The PR implementation fully addresses issue #498 requirements: adds OpenCodeConfigurator implementing config at ~/.config/opencode/opencode.json, handles file operations safely, supports creating/updating configs while preserving existing entries, and provides installation steps.
Out of Scope Changes check ✅ Passed All changes are scoped to adding OpenCode configurator support as specified in issue #498. The two files (OpenCodeConfigurator.cs and its .meta file) directly implement the required functionality with no extraneous modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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 1 issue, and left some high level feedback:

  • In both CheckStatus and Configure, JsonConvert.DeserializeObject<JObject>(File.ReadAllText(path)) is used without handling malformed JSON; consider catching JsonException separately and either backing up/overwriting the bad config or surfacing a clearer error state instead of treating all exceptions the same.
  • You currently deserialize and read the config file multiple times; consider refactoring the file read/deserialize logic into a small helper to avoid duplication and ensure consistent handling of missing/invalid config files.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In both `CheckStatus` and `Configure`, `JsonConvert.DeserializeObject<JObject>(File.ReadAllText(path))` is used without handling malformed JSON; consider catching `JsonException` separately and either backing up/overwriting the bad config or surfacing a clearer error state instead of treating all exceptions the same.
- You currently deserialize and read the config file multiple times; consider refactoring the file read/deserialize logic into a small helper to avoid duplication and ensure consistent handling of missing/invalid config files.

## Individual Comments

### Comment 1
<location> `MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs:81-97` </location>
<code_context>
+            return client.status;
+        }
+
+        public override void Configure()
+        {
+            string path = GetConfigPath();
+            McpConfigurationHelper.EnsureConfigDirectoryExists(path);
+
+            JObject config = File.Exists(path)
+                ? JsonConvert.DeserializeObject<JObject>(File.ReadAllText(path)) ?? new JObject()
+                : new JObject { ["$schema"] = SchemaUrl };
+
+            var mcpSection = config["mcp"] as JObject ?? new JObject();
+            config["mcp"] = mcpSection;
+
+            mcpSection[ServerName] = BuildServerEntry();
+
+            McpConfigurationHelper.WriteAtomicFile(path, JsonConvert.SerializeObject(config, Formatting.Indented));
+            client.SetStatus(McpStatus.Configured);
+        }
+
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Consider handling I/O/JSON errors in Configure similarly to CheckStatus

Here, any `IOException`, `UnauthorizedAccessException`, or JSON parsing error will propagate and may crash the editor, unlike in `CheckStatus`. Consider wrapping this method in a similar try/catch and setting `McpStatus.Error` with a message so the UI can show a clear failure state instead of an unhandled exception.

```suggestion
        public override void Configure()
        {
            try
            {
                string path = GetConfigPath();
                McpConfigurationHelper.EnsureConfigDirectoryExists(path);

                JObject config = File.Exists(path)
                    ? JsonConvert.DeserializeObject<JObject>(File.ReadAllText(path)) ?? new JObject()
                    : new JObject { ["$schema"] = SchemaUrl };

                var mcpSection = config["mcp"] as JObject ?? new JObject();
                config["mcp"] = mcpSection;

                mcpSection[ServerName] = BuildServerEntry();

                McpConfigurationHelper.WriteAtomicFile(path, JsonConvert.SerializeObject(config, Formatting.Indented));
                client.SetStatus(McpStatus.Configured);
            }
            catch (Exception ex)
            {
                client.SetStatus(McpStatus.Error, ex.Message);
            }
        }
```
</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

🤖 Fix all issues with AI agents
In `@MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs`:
- Around line 29-33: BuildConfigPath currently always uses
~/.config/opencode/opencode.json; update it to respect the XDG_CONFIG_HOME
environment variable by first reading
Environment.GetEnvironmentVariable("XDG_CONFIG_HOME") and, if non-empty, use
that directory as the base; otherwise fall back to
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) combined with
".config". Then combine the chosen base with "opencode" and "opencode.json" (use
Path.Combine) so BuildConfigPath returns either
$XDG_CONFIG_HOME/opencode/opencode.json or ~/.config/opencode/opencode.json.

- Add TryLoadConfig() helper to consolidate file read/parse logic
- Handle JsonException separately (log warning, return empty object to overwrite)
- Wrap Configure() in try/catch to prevent crashes, set McpStatus.Error on failure
- Respect XDG_CONFIG_HOME environment variable per XDG Base Directory spec

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dsarno dsarno merged commit 30d5bc2 into main Jan 22, 2026
2 of 3 checks passed
@dsarno dsarno deleted the pr-498-opencode branch January 22, 2026 03:46
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