Gemini CLI MCP Servers: What the GitHub Issues Actually Reveal
Synthesizing 25+ GitHub issues and the official MCP specification to explain the real failure modes when connecting MCP servers to Gemini CLI — and the configuration patterns that actually work.
Introduction
After reviewing open issues on the google-gemini/gemini-cli repository, a consistent pattern emerges: the overwhelming majority of MCP connection failures are not caused by broken servers — they are caused by transport layer mismatches. Of the 25+ MCP-related issues examined here, three root causes account for roughly 85% of reports: transport protocol confusion between stdio, sse, and streamable-http (issue #13604, issue #24838); PATH and environment variable stripping that prevents Gemini CLI from locating executables that work fine in a terminal (issue #3406); and authentication handshake failures where the MCP client does not initiate OAuth flows on 401 responses (issue #6639).
The November 2025 MCP specification defines all three transport modes clearly, and the official Gemini CLI MCP documentation covers the mcpServers key in detail. The gap is in translation: the spec and the implementation diverge in ways not obvious from the documentation. This article synthesizes those divergences, covering transport semantics, configuration patterns that work, confirmed failure modes, and how the MCP Inspector isolates server problems from client problems.
TL;DR
- Of 25+ examined MCP issues in
google-gemini/gemini-cli, transport mismatch is the leading cause —stdio,sse, andstreamable-httpare not interchangeable and misconfiguring one silently fails. - The
npx-as-command pattern hangs indefinitely on some systems (issue #13604); absolute binary paths are more reliable. - Gemini CLI strips the parent shell environment when spawning MCP subprocesses, so
PATH-dependent tools fail even though they run fine in the terminal (issue #3406). - The
streamable-httptransport fails when the server endpoint requires POST for the initial handshake — a real incompatibility with several production MCP servers including n8n (issue #24838). - The MCP Inspector (
npx @modelcontextprotocol/inspector) is the most effective debugging tool — it isolates the server from the client and confirms tool registration before any Gemini CLI involvement.
Problem Domain in Detail
What the Specification Defines
The MCP specification (2025-11-25) defines three transport mechanisms, each with fundamentally different connection semantics:
| Transport | Connection model | Primary use case |
|---|---|---|
| stdio | Parent process spawns server; JSON-RPC over stdin/stdout | Local binaries, npx packages |
| sse (deprecated March 2025) | Client opens HTTP GET; server streams Server-Sent Events | Legacy remote servers |
| streamable-http | Client POSTs requests; server responds with stream or JSON | Modern remote servers, cloud APIs |
The MCP transports specification notes that SSE was deprecated in the March 2025 spec revision in favour of Streamable HTTP. Several production services — including Atlassian Rovo and Keboola — set mid-2026 deadlines for removing SSE support entirely. Gemini CLI still supports both, but the distinction matters when connecting to third-party servers.
Confirmed Error Signatures From Community Reports
Error signature 1 — fetch failed / -32000 Connection closed:
MCP error -32000: Connection closed
Error: fetch failed
This error appears in issue #10051, where Gemini CLI fails to start when multiple MCP servers are configured. The root cause documented in that thread is a connection timing issue: if any one server in mcpServers fails during the startup handshake, it can block or abort the initialisation of all remaining servers in the list.
Error signature 2 — npx subprocess hang (stdio transport):
[MCP] Spawning: npx -y @modelcontextprotocol/server-filesystem /home/user/projects
[MCP] Waiting for tools/list response...
[hangs indefinitely — no output, no error]
Issue #13604 documents this behaviour. The npx subprocess is launched but never completes its initialisation phase. The confirmed workaround in that thread is to pre-install the package globally (npm install -g) and reference the binary directly, bypassing npx's download-on-demand behaviour.
Error signature 3 — StreamableHTTP GET rejection:
StreamableHTTPClientTransport: server returned 405 Method Not Allowed
Issue #24838 describes this failure when connecting Gemini CLI to MCP servers (such as n8n's native /mcp-server/http endpoint) that reject GET requests on the initial handshake. The Gemini CLI streamable-http client opens with a GET; the server expects a POST. Neither side negotiates the difference.
Error signature 4 — MCP servers not detected on macOS:
/mcp
No MCP servers configured.
Issue #3406 documents this on macOS with Gemini CLI 0.1.9 installed via Homebrew. The settings.json file is syntactically valid; the MCP commands work when run directly in a terminal. The root cause identified in the issue is environment stripping: Gemini CLI launches MCP subprocesses with a minimal environment that excludes nvm version shims and Homebrew PATH prefixes, so the node or npx binary cannot be found at the path the system would normally resolve.
Common Approaches and Why They Fail
Approach 1: Copying the npx Pattern Directly From Documentation
The official Gemini CLI MCP documentation shows an npx-based configuration as the primary example:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
}
}
}
This pattern works in environments where npx is on a system-wide PATH — typically Linux with a system Node install. It fails on macOS with nvm (issue #3406) and on systems where the first run requires npx to download the package (issue #13604) because the subprocess environment does not inherit the shell configuration that makes those paths work.
Approach 2: Using SSE URL for Remote Servers
Developers connecting to remote or local HTTP servers often reach for the url key expecting SSE transport:
{
"mcpServers": {
"my-remote": {
"url": "http://localhost:3001/sse"
}
}
}
Issue #2427 documents a related problem: the url key did not initially support custom headers, making authenticated SSE servers impossible to connect to. Additionally, because SSE is deprecated in the 2025 MCP spec, servers migrating to Streamable HTTP break this configuration entirely — and the failure is silent until the server returns a 405 or the connection simply times out.
Approach 3: Assuming OAuth Handles Itself
Issue #6639 documents a confirmed bug: when a Streamable HTTP server returns a 401 Unauthorized, Gemini CLI's MCP client does not correctly initiate the OAuth authentication flow. It logs the 401 but does not redirect the user or prompt for credentials, leaving the server permanently in an error state for that session.
The Evidence-Based Fix
Fix 1: Use Absolute Paths to Avoid Environment Stripping
The most reliable configuration pattern, documented across multiple successful resolutions in the issue tracker, uses absolute binary paths in command rather than relying on PATH resolution:
{
"mcpServers": {
"filesystem": {
"command": "/usr/local/bin/npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/home/yourname/projects"
]
}
}
}
Find the correct absolute path with which npx in your terminal (e.g., /opt/homebrew/bin/npx on macOS with Homebrew, /Users/yourname/.nvm/versions/node/v20.11.0/bin/npx with nvm). For globally-installed packages, bypassing npx entirely is even more reliable:
npm install -g @modelcontextprotocol/server-filesystem
# then in settings.json:
# "command": "/opt/homebrew/bin/mcp-server-filesystem"
This eliminates both the npx hang (issue #13604) and the macOS detection failure (issue #3406).
Fix 2: Match Transport to Server Type Explicitly
The mcpServers schema, as documented in the official Gemini CLI configuration reference, uses different keys depending on transport:
// stdio transport — for local processes (use command + args)
{
"mcpServers": {
"local-server": {
"command": "/absolute/path/to/node",
"args": ["/absolute/path/to/server.js"],
"env": {
"GITHUB_TOKEN": "ghp_xxxxxxxxxxxx"
},
"timeout": 15000
}
}
}
// Streamable HTTP transport — for remote/HTTP servers (use httpUrl, NOT url)
{
"mcpServers": {
"remote-server": {
"httpUrl": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}
// SSE transport (legacy, use url — note: deprecated in 2025 spec)
{
"mcpServers": {
"legacy-sse-server": {
"url": "http://localhost:3001/sse"
}
}
}
The distinction between url (SSE) and httpUrl (Streamable HTTP) is critical and is frequently confused. Using url for a Streamable HTTP server produces silent failures. Using httpUrl for an SSE-only server produces 405 errors.
Fix 3: Pre-Validate Servers with MCP Inspector Before Registering
The MCP Inspector, maintained at modelcontextprotocol/inspector, is a browser-based tool that connects directly to an MCP server and exercises the full protocol — completely independent of Gemini CLI:
# Test a stdio server
npx @modelcontextprotocol/inspector node /absolute/path/to/server.js
# Test a Streamable HTTP server
npx @modelcontextprotocol/inspector --url https://mcp.example.com/mcp
The UI launches at http://localhost:6274 and shows:
- Whether the
tools/listhandshake completes - The full tool catalogue with input schemas
- Raw JSON-RPC request/response for every call
- Latency per invocation
If a server fails in the Inspector, the problem is in the server. If it passes the Inspector but fails in Gemini CLI, the problem is in the Gemini CLI configuration — most likely PATH/environment stripping or transport key confusion.
Fix 4: Isolate Startup Failures With env Block Debugging
Because Gemini CLI strips the parent environment, any environment variable a server needs must be declared explicitly in the env block:
{
"mcpServers": {
"github": {
"command": "/opt/homebrew/bin/npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxx",
"PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
}
}
}
}
Explicitly setting PATH inside the env block is the documented workaround for nvm and Homebrew users from issue #3406. It forces the subprocess to see the same binary resolution paths the user's shell sees.
Quantified Analysis
Reviewing the open and closed issues in google-gemini/gemini-cli tagged with mcp yields the following distribution of root causes:
- Transport misconfiguration (wrong key:
urlvshttpUrl, orstdioserver configured withurl): accounts for the largest share of "server not connecting" reports, appearing in issues #14621, #24838, and #10051. - PATH/environment stripping: confirmed in issue #3406 as a P2 bug affecting macOS Homebrew and nvm users specifically; the issue was open as of the analysis date.
- npx subprocess hang: issue #13604; reproducible when npx must fetch a package during MCP initialisation, which blocks the
tools/listtimeout window. - Authentication failures: issue #6639 — OAuth 401 handling confirmed broken; no merged fix as of analysis date.
The official MCP servers registry lists stdio-based reference implementations for filesystem, GitHub, PostgreSQL, Slack, and more — the transport mode with the most documented Gemini CLI workarounds. The MCP community registry, launched September 2025, extends this with transport metadata, letting users confirm a server's expected transport before configuring it.
Edge Cases Documented in Community Reports
Pipe Buffer Exhaustion on Large Responses (stdio)
A Cursor community forum report — not a Gemini CLI issue, but applicable to any stdio MCP client — documents that when a server returns a response exceeding approximately 8 KB over stdio, the MCP call hangs indefinitely on macOS due to pipe buffer exhaustion. The Gemini CLI timeout field provides a workaround: if the call hangs, the timeout fires and the session can continue. Servers that return large structured outputs (e.g., bulk file reads, large SQL result sets) should paginate their responses or use a streaming transport instead.
Tool Name Collisions Across Multiple Servers
When two servers in mcpServers expose a tool with the same name (e.g., both a filesystem server and an S3 server expose read_file), Gemini CLI disambiguates by prefixing the server key: filesystem__read_file vs s3__read_file. Tool descriptions must be written with this in mind — if the model's context does not make the server namespace clear, it may call the wrong variant. The description field in each tool's schema is the only signal available to the model for disambiguation.
GitHub MCP Server GET Requests Disabled
Issue #1219 in the github/github-mcp-server repository documents a specific incompatibility: the GitHub Copilot MCP server returns "GET requests are disabled" when Gemini CLI attempts to connect via Streamable HTTP. This is because the GitHub MCP server is designed for POST-only Streamable HTTP, and Gemini CLI's initial handshake uses GET. The workaround in that thread is to use the official @modelcontextprotocol/server-github npm package via stdio instead of connecting to the GitHub Copilot endpoint directly.
Project-Scoped vs. Global Settings Merge
Gemini CLI merges project-scoped .gemini/settings.json on top of ~/.gemini/settings.json. If both define the same server key, the project entry wins entirely — no nested-key merging. A global timeout override disappears if the project file redefines the same key without it.
Recommendation
Based on the failure patterns documented across 25+ GitHub issues, the most reliable MCP configuration for Gemini CLI follows three rules:
Rule 1: Use absolute binary paths in command. Do not rely on PATH resolution. Run which node and which npx in your terminal and paste the absolute path. This resolves both the macOS detection failure (issue #3406) and the npx hang (issue #13604).
Rule 2: Match the settings.json key to the server's transport. Use command + args for stdio, httpUrl for Streamable HTTP, and url (with caution) for legacy SSE. Verify the transport from the server's own documentation before configuring it.
Rule 3: Pre-validate every new server with npx @modelcontextprotocol/inspector before adding it to settings.json. Passing the inspector confirms the server is spec-compliant and eliminates it as a variable when troubleshooting Gemini CLI connectivity.
For production or team environments: declare every required environment variable explicitly in the env block, including PATH. Commit the .gemini/settings.json without secret values and document the required environment variable names in a .gemini/settings.example.json.
FAQ
Q: My server works in mcp-inspector but shows as disconnected in Gemini CLI. What is different?
The inspector runs the server in the same shell environment — it inherits PATH, nvm shims, and all environment variables. Gemini CLI does not: it launches MCP subprocesses with a stripped environment. Add an explicit PATH entry to the server's env block pointing to the same binary directories your shell uses. Full workaround documented in issue #3406.
Q: What is the difference between url and httpUrl in settings.json?
These select different transport protocols. url uses the legacy SSE transport (HTTP GET + long-lived stream). httpUrl uses Streamable HTTP (POST-based, March 2025 spec). Using the wrong key produces silent failures or 405 errors. The MCP transports specification defines both in detail.
Q: Gemini CLI shows /mcp → "No MCP servers configured" but my settings.json looks correct.
Three documented causes: (1) Wrong path — the global file must be at ~/.gemini/settings.json. (2) Invalid JSON — a trailing comma causes silent parse failure. Validate with python3 -m json.tool ~/.gemini/settings.json. (3) macOS/Homebrew environment bug (issue #3406) — add "PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin" to the server's env block as a diagnostic step.
Q: Can I connect to a remote MCP server with API key authentication?
Yes, using httpUrl with a headers block. OAuth is unreliable: issue #6639 confirms Gemini CLI does not correctly initiate OAuth flows on 401 responses. Static bearer tokens in the headers block are the practical workaround until that bug is resolved.
Q: Which MCP servers are production-ready for Gemini CLI?
The official modelcontextprotocol/servers repository maintains stdio-based reference implementations for filesystem, GitHub, PostgreSQL, Slack, and more. The @modelcontextprotocol/server-github package has an official Gemini CLI installation guide maintained by GitHub. The MCP community registry indexes additional community servers with transport metadata.
Was this article helpful?