-
Notifications
You must be signed in to change notification settings - Fork 611
feat: Add OpenCode (opencode.ai) client configurator #498
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: Add OpenCode (opencode.ai) client configurator #498
Conversation
- 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
Reviewer's GuideAdds 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 flowsequenceDiagram
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
Class diagram for OpenCodeConfigurator MCP client integrationclassDiagram
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
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Note Other AI code review bot(s) detectedCodeRabbit 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. 📝 WalkthroughWalkthroughAdds 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
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
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
📜 Recent review detailsConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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)
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. Comment |
There was a problem hiding this 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 rethrowingInvalidOperationExceptionwith onlyex.Messagedrops the original stack trace and type; consider either usingthrow;after setting status, or including the original exception as an inner exception so callers can diagnose failures more easily. ConfigureandGetManualSnippetduplicate the construction of the MCP JSON object (type/url/enabled); consider extracting a small helper method to build thisJObjectso 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>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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
📒 Files selected for processing (2)
MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.csMCPForUnity/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 URLhttps://opencode.ai/config.jsonis 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.jsonis the officially documented global config location. Using the sameBuildConfigPath()for all OS platforms is appropriate.
MCPForUnity/Editor/Clients/Configurators/OpenCodeConfigurator.cs
Outdated
Show resolved
Hide resolved
- 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
|
Hey @akshay-kiddopia , thanks for making this PR!!! Can you help me with a couple of things?
|
|
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 |
|
@akshay-kiddopia any feedback? |
Hey, sorry wasn't active last few days. This is how my json looks like at /Users/username/.config/opencode/opencode.json |
Summary by Sourcery
Add configurator to integrate Unity MCP with the OpenCode (opencode.ai) client via its custom configuration file.
New Features:
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.