Skip to content

fix(core): handle non-compliant mcpbridge responses from Xcode 26.3#18376

Merged
bdmorgan merged 2 commits intogoogle-gemini:mainfrom
peterfriese:fix/xcode-mcp-bridge-response
Feb 5, 2026
Merged

fix(core): handle non-compliant mcpbridge responses from Xcode 26.3#18376
bdmorgan merged 2 commits intogoogle-gemini:mainfrom
peterfriese:fix/xcode-mcp-bridge-response

Conversation

@peterfriese
Copy link
Copy Markdown
Contributor

@peterfriese peterfriese commented Feb 5, 2026

Summary

Provides a fix for #18371

Details

Xcode 26.3's xcrun mcpbridge returns tool results as an unparsed JSON string within the content field, failing to provide the expected structuredContent. This behavior breaks strict MCP clients like gemini-cli.

This PR introduces XcodeMcpBridgeFixTransport, a transport wrapper that intercepts JSON-RPC messages from the Xcode bridge. It detects responses with missing structuredContent and attempts to parse the content string as JSON to backfill the missing field.

Key Changes:

  • Added XcodeMcpBridgeFixTransport in packages/core/src/tools/xcode-mcp-fix-transport.ts.
  • Updated createTransport in packages/core/src/tools/mcp-client.ts to wrap the transport specifically when the command is xcrun and arguments include mcpbridge.
  • Added unit tests in packages/core/src/tools/xcode-mcp-fix-transport.test.ts.

Related Issues

Fixes #18371

How to Validate

  1. Unit Tests:
    Run the new test suite to verify the fix logic:

    npm test packages/core/src/tools/xcode-mcp-fix-transport.test.ts
  2. Live Verification (MacOS with Xcode 26.3+):

    • Open a project in Xcode (e.g., HelloWorld).
    • Configure Gemini CLI to use the Xcode MCP server:
      "xcode": {
        "command": "xcrun",
        "args": ["mcpbridge"],
        "enabled": true
      }
    • Run the CLI and attempt to use a tool:
      # Example usage in CLI
      > use xcode
      > XcodeListWindows
    • Expected Result: The tool call succeeds and returns the window list. Without this fix, it would fail or return raw JSON text.

Pre-Merge Checklist

(Note: this is only relevant on macOS, since it's not possible to run Xcode on any other platform).

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (New xcode-mcp-fix-transport.test.ts added)
  • Noted breaking changes (None)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @peterfriese, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a compatibility issue with Xcode 26.3's xcrun mcpbridge where its JSON-RPC responses are non-compliant, specifically by embedding JSON data as a string within the content field instead of providing it directly in the structuredContent field. The changes introduce a new transport wrapper that acts as an interceptor, automatically parsing and correcting these malformed responses to ensure proper functionality with strict Model Context Protocol (MCP) clients like gemini-cli.

Highlights

  • New Transport Wrapper for Xcode MCP Bridge: Introduced XcodeMcpBridgeFixTransport, a new transport layer designed to intercept and correct non-compliant JSON-RPC responses specifically from Xcode's mcpbridge utility.
  • Conditional Application of the Fix: The XcodeMcpBridgeFixTransport is now conditionally applied within the createTransport function. It wraps the standard StdioClientTransport only when the command executed is xcrun mcpbridge, ensuring the fix is targeted where needed.
  • Automatic Structured Content Backfilling: The new transport wrapper automatically detects responses where the structuredContent field is missing but the content field contains a stringified JSON. It then parses this string and populates the structuredContent field, making the response compliant.
  • Improved Debugging for Wrapped Transports: The stderr debug logging mechanism in mcp-client.ts has been updated to correctly unwrap the XcodeMcpBridgeFixTransport when it's in use, ensuring that debug output from the underlying StdioClientTransport is still captured and logged.
  • Comprehensive Unit Test Coverage: New unit tests have been added for the XcodeMcpBridgeFixTransport to validate its behavior across various scenarios, including correctly fixing non-compliant responses, passing through compliant responses untouched, and gracefully handling unparsable content.
Changelog
  • packages/core/src/tools/mcp-client.ts
    • Imported XcodeMcpBridgeFixTransport to enable its use in the client.
    • Modified the transport variable from const to let to allow for its reassignment with the new wrapper.
    • Added conditional logic to wrap the StdioClientTransport with XcodeMcpBridgeFixTransport when the command is xcrun and includes mcpbridge.
    • Updated the stderr debug logging to correctly access the underlying transport's stderr when XcodeMcpBridgeFixTransport is active.
  • packages/core/src/tools/xcode-mcp-fix-transport.test.ts
    • Added a new test file to provide unit test coverage for the XcodeMcpBridgeFixTransport.
    • Implemented tests to verify that non-compliant responses are correctly fixed by populating structuredContent.
    • Included tests to ensure that compliant responses with existing structuredContent are passed through without modification.
    • Added tests to confirm that responses with non-JSON content are ignored and not altered.
  • packages/core/src/tools/xcode-mcp-fix-transport.ts
    • Added a new file defining the XcodeMcpBridgeFixTransport class.
    • Implemented the Transport interface, acting as a wrapper around an existing transport.
    • Included logic to intercept incoming JSON-RPC messages and identify responses missing structuredContent.
    • Added functionality to attempt parsing the content field as JSON and, if successful, assign it to structuredContent.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-cli gemini-cli bot added the area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality label Feb 5, 2026
@peterfriese peterfriese marked this pull request as ready for review February 5, 2026 16:23
@peterfriese peterfriese requested a review from a team as a code owner February 5, 2026 16:23
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a fix for non-compliant responses from Xcode's mcpbridge by wrapping the transport and parsing the content to populate the missing structuredContent field. The approach is well-isolated and includes good unit test coverage. My review includes a suggestion to improve encapsulation and type safety by avoiding the use of an any cast to access a private property, which will make the code more maintainable.

extends EventEmitter
implements Transport
{
constructor(private readonly transport: Transport) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

To improve encapsulation and type safety, consider making the transport property public. The mcp-client.ts file needs to access this property to attach a debug listener to the underlying transport's stderr. Making it public allows for direct, type-safe access from the consuming module and avoids the use of any casting, which makes the code more robust and maintainable.

Suggested change
constructor(private readonly transport: Transport) {
constructor(public readonly transport: Transport) {

Comment on lines +1946 to +1950
const underlyingTransport =
transport instanceof XcodeMcpBridgeFixTransport
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
(transport as any).transport
: transport;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Following the change to make XcodeMcpBridgeFixTransport.transport public, this logic can be simplified to access the property directly. This removes the need for an any cast and the associated eslint-disable comment, leading to more maintainable and type-safe code.

      const underlyingTransport =
        transport instanceof XcodeMcpBridgeFixTransport
          ? transport.transport
          : transport;

@bdmorgan bdmorgan added this pull request to the merge queue Feb 5, 2026
Merged via the queue into google-gemini:main with commit 1cae5ab Feb 5, 2026
26 checks passed
@jacob314
Copy link
Copy Markdown
Contributor

jacob314 commented Feb 6, 2026

/patch preview

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 6, 2026

Patch workflow(s) dispatched successfully!

📋 Details:

  • Channels: preview
  • Commit: 1cae5ab158461b6997b0f365d450c8179b739553
  • Workflows Created: 1

🔗 Track Progress:

@jacob314
Copy link
Copy Markdown
Contributor

jacob314 commented Feb 6, 2026

/patch stable

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 6, 2026

Patch workflow(s) dispatched successfully!

📋 Details:

  • Channels: stable
  • Commit: 1cae5ab158461b6997b0f365d450c8179b739553
  • Workflows Created: 1

🔗 Track Progress:

sidwan02 pushed a commit to sidwan02/gemini-cli-gemma that referenced this pull request Feb 6, 2026
@skeshive
Copy link
Copy Markdown
Contributor

skeshive commented Feb 6, 2026

/patch

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 6, 2026

Patch workflow(s) dispatched successfully!

📋 Details:

  • Channels: stable,preview
  • Commit: 1cae5ab158461b6997b0f365d450c8179b739553
  • Workflows Created: 2

🔗 Track Progress:

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 6, 2026

🚀 Patch PR Created!

📋 Patch Details:

📝 Next Steps:

  1. Review and approve the hotfix PR: #18463
  2. Once merged, the patch release will automatically trigger
  3. You'll receive updates here when the release completes

🔗 Track Progress:

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 6, 2026

🚀 Patch PR Created!

📋 Patch Details:

📝 Next Steps:

  1. Review and approve the hotfix PR: #18464
  2. Once merged, the patch release will automatically trigger
  3. You'll receive updates here when the release completes

🔗 Track Progress:

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 6, 2026

🚀 Patch Release Started!

📋 Release Details:

  • Environment: prod
  • Channel: stable → publishing to npm tag latest
  • Version: v0.27.2
  • Hotfix PR: Merged ✅
  • Release Branch: release/v0.27.2-pr-18376

⏳ Status: The patch release is now running. You'll receive another update when it completes.

🔗 Track Progress:

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 6, 2026

🚀 Patch Release Started!

📋 Release Details:

  • Environment: prod
  • Channel: preview → publishing to npm tag preview
  • Version: v0.28.0-preview.3
  • Hotfix PR: Merged ✅
  • Release Branch: release/v0.28.0-preview.3-pr-18376

⏳ Status: The patch release is now running. You'll receive another update when it completes.

🔗 Track Progress:

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 6, 2026

Patch Release Complete!

📦 Release Details:

  • Version: 0.27.3
  • NPM Tag: latest
  • Channel: stable
  • Dry Run: false

🎉 Status: Your patch has been successfully released and published to npm!

📝 What's Available:

🔗 Links:

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 6, 2026

Patch Release Complete!

📦 Release Details:

🎉 Status: Your patch has been successfully released and published to npm!

📝 What's Available:

🔗 Links:

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

Labels

area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

xcrun mcpbridge returns unparsed JSON string in content field instead of structuredContent

4 participants