Skip to content

Preserve empty objects in MCP JSON config files#793

Merged
pushpak1300 merged 2 commits into
laravel:mainfrom
mwikala:preserve-empty-mcp-objects
May 12, 2026
Merged

Preserve empty objects in MCP JSON config files#793
pushpak1300 merged 2 commits into
laravel:mainfrom
mwikala:preserve-empty-mcp-objects

Conversation

@mwikala
Copy link
Copy Markdown
Contributor

@mwikala mwikala commented May 1, 2026

Summary

This fixes plain JSON MCP config updates so existing empty objects are preserved when Boost adds a server entry.

Previously, updating an existing opencode.json that contained an empty object such as "oauth": {} would rewrite it as "oauth": []. OpenCode validates its config schema on startup, so this prevented OpenCode from loading the config after Boost installed its MCP server entry.

The change keeps decoded plain JSON objects as objects while still supporting the existing array-based path used for new config creation.

Benefit to End Users

Users with an existing OpenCode MCP config can install Boost without making their OpenCode configuration invalid. Empty object fields such as oauth remain valid objects, allowing OpenCode to continue loading normally.

Backwards Compatibility

This should not break existing behavior because json_encode supports both arrays and decoded objects. New file creation still uses the existing array-based config path, and existing plain JSON files now retain their original object/array shapes more accurately.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

Thanks for submitting a PR!

Note that draft PRs are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface.

Pull requests that are abandoned in draft may be closed due to inactivity.

@mwikala mwikala marked this pull request as ready for review May 1, 2026 20:55
@pushpak1300 pushpak1300 merged commit 8224fbc into laravel:main May 12, 2026
21 checks passed
Copy link
Copy Markdown
Member

Simplification suggestion: The array|object union type on addServersToConfig exists solely because createNewFile() passes $this->baseConfig (typed array) directly. Moving the (object) cast one level up — to the call site in createNewFile — means addServersToConfig only ever receives an object, letting us drop the union type and the is_array branch inside the method entirely. The remaining isset(...) || !is_object(...) guard is still meaningful and correct: json_decode in object mode returns a PHP array for JSON arrays ([]), so a malformed file with "mcpServers": [] would reach !is_object and be safely replaced with a fresh stdClass. No other changes needed.

--- a/src/Install/Mcp/FileWriter.php
+++ b/src/Install/Mcp/FileWriter.php
@@ -406,18 +406,14 @@ protected function hasSingleQuotedStrings(string $content): bool
 
     protected function createNewFile(): bool
     {
-        $config = $this->baseConfig;
+        $config = (object) $this->baseConfig;
         $this->addServersToConfig($config);
 
         return $this->writeJsonConfig($config);
     }
 
-    protected function addServersToConfig(array|object &$config): void
+    protected function addServersToConfig(object &$config): void
     {
-        if (is_array($config)) {
-            $config = (object) $config;
-        }
-
         if (! isset($config->{$this->configKey}) || ! is_object($config->{$this->configKey})) {
             $config->{$this->configKey} = new stdClass;
         }

Verification:

$ vendor/bin/pest tests/Unit/Install/Mcp/FileWriterTest.php
OK (48 tests, 143 assertions)   ✓  preserves empty objects in existing plain JSON files  PASS

$ vendor/bin/pest tests/Unit/Install/Mcp/
OK (67 tests, 258 assertions)

All 48 FileWriterTest tests pass (including the new preserves empty objects in existing plain JSON files test) and the full tests/Unit/Install/Mcp/ suite (67 tests) passes as well.

Posted by a Claude Code routine on behalf of @pushpak1300.


Generated by Claude Code

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