Skip to content

macOS Sandbox Prevents Local MCP Server Startup from External CWD #3261

@ahundt

Description

@ahundt

What happened?

MCP Server Fails to Connect When Gemini CLI is Run from Different Directory (macOS Sandbox Issue)

Problem Description

When attempting to use a locally installed MCP server (specifically, @browsermcp/mcp) with the Gemini CLI on macOS, the server fails to start or connect successfully if the gemini CLI is invoked from a directory different from the MCP server's root directory. This occurs even when the cwd (current working directory) is explicitly set in the settings.json configuration for the MCP server, pointing to a local directory outside the default sandbox scope. The issue is resolved by disabling the macOS Seatbelt sandbox.

Environment

  • Operating System: macOS Sonoma 14.7
  • Gemini CLI Version: 0.1.9
  • MCP Server: @browsermcp/mcp (Node.js-based)

Steps to Reproduce

  1. Ensure @browsermcp/mcp is set up:

    • Clone or ensure the @browsermcp/mcp project is available (e.g., at ~/path/to/mcp-browser/mcp).
    • Install its dependencies: cd ~/path/to/mcp-browser/mcp && npm install
    • Build the server: cd ~/path/to/mcp-browser/mcp && npm run build:server
    • Confirm package.json and tsconfig.json are standard and correctly configured.
  2. Configure gemini CLI settings.json:

    • Ensure your settings.json (e.g., ~/.gemini/settings.json or ~/path/to/another/directory/.gemini/settings.json) contains the following MCP server configuration, where ~/path/to/mcp-browser/mcp is a local directory outside the typical sandboxed locations:
    "mcpServers": {
      "mcp-browser-server": {
        "type": "stdio",
        "command": "npm",
        "args": ["run", "start:mcp"],
        "cwd": "~/path/to/mcp-browser/mcp",
        "trust": true
      }
    }

    (Note: Replace ~/path/to/mcp-browser/mcp with the actual absolute path to your locally installed MCP server directory.)

  3. Test Case 1: Run gemini from the MCP server's directory (Works)

    cd ~/path/to/mcp-browser/mcp
    gemini -c true -s -m gemini-2.5-flash
    # Once CLI loads:
    /mcp desc

    Expected Result: The mcp-browser-server should show as connected with tools cached (e.g., "19 tools cached").

  4. Test Case 2: Run gemini from a different directory (Fails)

    cd ~/path/to/another/directory # Or any other directory
    gemini -c true -s -m gemini-2.5-flash
    # Once CLI loads:
    /mcp desc

Observed Behavior (Failure Case)

When running gemini from a directory different from the MCP server's cwd:

  • The gemini CLI reports a connection error:
    failed to start or connect to MCP server 'mcp-browser-server' {"command":"npm","cwd":"~/path/to/mcp-browser/mcp","trust":true};
    McpError: MCP error -32000: Connection closed
    Make sure it is available in the sandbox
    
  • /mcp desc shows:
    mcp-browser-server - Disconnected (0 tools cached)
    No tools available
    
  • During initial debugging, the server would output non-JSON console logs (e.g., [MCP Server]...) before crashing, leading to "SyntaxError: Unexpected token 'M'". This symptom later disappeared, suggesting the server process might not even be starting to the point of printing logs.

Expected Behavior

The locally installed mcp-browser-server should start and connect successfully, listing its tools, regardless of the gemini CLI's current working directory, as the cwd is explicitly set in the settings.json for the MCP server.

Diagnostic Steps Taken & Findings

  1. package.json and tsconfig.json Review: Confirmed that the MCP server's build and run configurations (npm run start:mcp -> node dist/index.js, outDir: "dist") are standard and correct.
  2. settings.json cwd Confirmation: Verified that the gemini CLI's settings.json correctly specifies the cwd for the mcp-browser-server. Debug logs from gemini -d confirm that gemini is reading and attempting to use this cwd setting.
  3. process.cwd() Logging in MCP Server: Adding console.log(process.cwd()) to the MCP server's main entry point (src/index.ts) did not produce output in the failure case. This indicates the server process is not fully initializing or executing its code when launched from a different directory.
  4. Crucial Finding: macOS Sandbox: The issue is resolved by disabling the macOS Seatbelt sandbox (e.g., by running export SEATBELT_PROFILE=none before launching gemini). This strongly indicates that the default permissive-open Seatbelt profile applied by the Gemini CLI is too restrictive for the operations of a locally installed MCP server.

Root Cause (Identified)

The primary root cause appears to be macOS Seatbelt sandbox restrictions. The default permissive-open profile, while allowing file opening, likely blocks other necessary operations for the locally installed Node.js-based MCP server, such as:

  • Specific file system access required by Node.js or its dependencies when launched from a non-native cwd (i.e., a local directory outside the default sandbox scope).
  • Potential process execution if the MCP server or its tools spawn child processes.

The cwd setting in settings.json, while correctly read by gemini, does not seem to fully mitigate these sandbox-related issues when the gemini CLI itself is launched from a different directory.

Proposed Solution/Request

  1. Default Sandbox Profile for Locally Installed MCP Servers: It would be greatly appreciated if the Gemini CLI's default macOS Seatbelt profile could be enhanced to allow locally installed MCP servers (like @browsermcp/mcp) to function correctly by default in a non-destructive manner. This would involve granting necessary permissions for standard server operation, such as:
    • Binding to specified network ports (e.g., 9002).
    • Reading files within their own installation directory (cwd).
    • Executing their own Node.js process and any necessary child processes for core functionality.
      This would significantly improve the out-of-the-box experience for users setting up local MCP servers.
  2. Sandbox Extension to Configured Paths: Please consider extending the sandbox's allowed locations to include paths explicitly specified in the MCP server's configuration (e.g., the cwd in settings.json). This would allow the sandbox to remain secure while accommodating the need for MCP servers to operate from local directories outside the default sandboxed areas.
  3. Documentation/Guidance: Please provide clear documentation or guidance on how users can further customize Seatbelt profiles for their MCP servers, or how to identify and address specific denied operations if custom server behavior requires additional permissions.
  4. cwd Behavior Investigation: Please investigate why the cwd setting, despite being correctly passed, does not prevent the sandbox-related failures when the gemini CLI is launched from a different directory. This might indicate a subtle interaction between process spawning, cwd, and sandbox enforcement.

What did you expect to happen?

Expected Behavior

The locally installed mcp-browser-server should start and connect successfully, listing its tools, regardless of the gemini CLI's current working directory, as the cwd is explicitly set in the settings.json for the MCP server.

Client information

Details
$ gemini /about

╭───────────────────────────────────────────────────────────────────╮
│                                                                   │
│ About Gemini CLI                                                  │
│                                                                   │
│ CLI Version            0.1.9                                      │
│ Git Commit             34935d6                                    │
│ Model                  gemini-2.5-flash                           │
│ Sandbox                no sandbox                                 │
│ OS                     darwin                                     │
│ Auth Method            OAuth                                      │
│                                                                   │```

</details>


### Login information

google account

### Anything else we need to know?

_No response_

Metadata

Metadata

Assignees

No one assigned

    Labels

    Stalearea/coreIssues related to User Interface, OS Support, Core Functionalitypriority/p2Important but can be addressed in a future release.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions