gemini-cli - ✅(Solved) Fix gemini mcp list reports Google first-party MCP servers as "Disconnected" due to unsupported ping() method [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
google-gemini/gemini-cli#25599Fetched 2026-04-18 05:57:28
View on GitHub
Comments
0
Participants
1
Timeline
2
Reactions
0
Participants
Timeline (top)
labeled ×2

Root Cause

Root cause: testMCPConnection() in list.ts calls client.ping() after client.connect(). Google's MCP servers return -32601: Method not supported for ping, and the catch block reports DISCONNECTED:

PR fix notes

PR #25619: fix(cli): handle optional ping in mcp list

Description (problem / solution / changelog)

Fixes #25599

Summary

  • align gemini mcp list connection checks with the shared MCP default timeout instead of a hardcoded 5s timeout
  • treat ping() as best-effort in mcp list so servers that return MethodNotFound after a successful MCP initialize handshake are still reported as connected
  • add focused regression tests for both the timeout behavior and the unsupported ping() case

Verification

  • reproduced the issue against https://run.googleapis.com/mcp, where gemini mcp list reported Disconnected before the fix
  • verified the patched local CLI reports cloud-run: https://run.googleapis.com/mcp (http) - Connected

Reproduced: <img width="724" height="120" alt="Image" src="https://github.com/user-attachments/assets/4e4b746c-642f-4c5e-8605-fd1469d11581" />

Resolved: <img width="573" height="77" alt="Image" src="https://github.com/user-attachments/assets/7bf63afa-b655-4cc3-8139-dbfbeea75744" />

Changed files

  • packages/cli/src/commands/mcp/list.test.ts (modified, +55/-1)
  • packages/cli/src/commands/mcp/list.ts (modified, +17/-3)

Code Example

mkdir -p /tmp/gemini-test/.gemini
cat > /tmp/gemini-test/.gemini/settings.json << 'EOF'
{
  "mcpServers": {
    "cloud-run": {
      "httpUrl": "https://run.googleapis.com/mcp",
      "authProviderType": "google_credentials",
      "oauth": { "scopes": ["https://www.googleapis.com/auth/cloud-platform"] }
    }
  }
}
EOF

HOME=/tmp/gemini-test gemini mcp list

---

Configured MCP servers:

✗ cloud-run: https://run.googleapis.com/mcp (http) - Disconnected

---

const transport = new StreamableHTTPClientTransport(
  new URL('https://run.googleapis.com/mcp'), { requestInit: { headers } }
);
const client = new Client({ name: 'test', version: '1.0' });

await client.connect(transport, { timeout: 5000 });  // ✅ succeeds (152ms)
await client.ping();                                   // ❌ McpError -32601: Method not supported
await client.listTools();                              // ✅ succeeds (5 tools returned)

---

// list.ts lines 129-141
try {
  await client.connect(transport, { timeout: 5000 }); // ✅ succeeds
  await client.ping();                                  // ❌ -32601
  await client.close();
  return MCPServerStatus.CONNECTED;
} catch {
  await transport.close();
  return MCPServerStatus.DISCONNECTED;  // ← false negative
}

---

Gemini CLI version: 0.38.1
Platform: macOS (arm64)
Node.js: v25.9.0

---

try {
   await client.connect(transport, { timeout: 5000 });
-  await client.ping();
+  try {
+    await client.ping();
+  } catch {
+    // ping is optional per MCP spec — some servers (e.g. Google first-party)
+    // don't implement it. A successful connect() is sufficient.
+  }
   await client.close();
   return MCPServerStatus.CONNECTED;
 } catch {
RAW_BUFFERClick to expand / collapse

What happened?

gemini mcp list reports Google first-party MCP servers (Cloud Run, GKE, Developer Knowledge) as ✗ Disconnected, even though they connect successfully and all tools are discoverable.

Reproduction:

mkdir -p /tmp/gemini-test/.gemini
cat > /tmp/gemini-test/.gemini/settings.json << 'EOF'
{
  "mcpServers": {
    "cloud-run": {
      "httpUrl": "https://run.googleapis.com/mcp",
      "authProviderType": "google_credentials",
      "oauth": { "scopes": ["https://www.googleapis.com/auth/cloud-platform"] }
    }
  }
}
EOF

HOME=/tmp/gemini-test gemini mcp list

Output:

Configured MCP servers:

✗ cloud-run: https://run.googleapis.com/mcp (http) - Disconnected

But the server is fully functional. Using the MCP SDK directly:

const transport = new StreamableHTTPClientTransport(
  new URL('https://run.googleapis.com/mcp'), { requestInit: { headers } }
);
const client = new Client({ name: 'test', version: '1.0' });

await client.connect(transport, { timeout: 5000 });  // ✅ succeeds (152ms)
await client.ping();                                   // ❌ McpError -32601: Method not supported
await client.listTools();                              // ✅ succeeds (5 tools returned)

Root cause: testMCPConnection() in list.ts calls client.ping() after client.connect(). Google's MCP servers return -32601: Method not supported for ping, and the catch block reports DISCONNECTED:

// list.ts lines 129-141
try {
  await client.connect(transport, { timeout: 5000 }); // ✅ succeeds
  await client.ping();                                  // ❌ -32601
  await client.close();
  return MCPServerStatus.CONNECTED;
} catch {
  await transport.close();
  return MCPServerStatus.DISCONNECTED;  // ← false negative
}

Notably, connectToMcpServer() in mcp-client.ts — the code path used when Gemini CLI actually connects to MCP servers for tool discovery — does not call ping(). It connects and proceeds directly to tool discovery, which works perfectly with these servers. This means the diagnostic command (gemini mcp list) reports servers as broken that the CLI itself has no trouble using.

What did you expect to happen?

gemini mcp list should report the server as ✓ Connected since the MCP initialize handshake succeeds and tools are discoverable. The ping method is optional per the MCP spec — a server shouldn't be marked Disconnected just because it doesn't implement ping.

Client information

<details> <summary>Client Information</summary>
Gemini CLI version: 0.38.1
Platform: macOS (arm64)
Node.js: v25.9.0
</details>

Login information

Google ADC (gcloud auth application-default login). Using authProviderType: google_credentials in the server config, which uses GoogleCredentialProvider to obtain Bearer tokens via google-auth-library.

Anything else we need to know?

Affected servers

All Google first-party MCP servers using the ESF StatelessServer backend:

  • https://run.googleapis.com/mcp (Cloud Run)
  • https://container.googleapis.com/mcp (GKE)
  • https://developerknowledge.googleapis.com/mcp (Developer Knowledge)

Suggested fix

Make ping() optional in testMCPConnection(). A successful connect() (which completes the MCP initialize handshake) is sufficient proof of connectivity:

 try {
   await client.connect(transport, { timeout: 5000 });
-  await client.ping();
+  try {
+    await client.ping();
+  } catch {
+    // ping is optional per MCP spec — some servers (e.g. Google first-party)
+    // don't implement it. A successful connect() is sufficient.
+  }
   await client.close();
   return MCPServerStatus.CONNECTED;
 } catch {

Secondary: timeout discrepancy

testMCPConnection() uses a hardcoded 5-second timeout ({ timeout: 5000 }), while connectToMcpServer() in mcp-client.ts uses MCP_DEFAULT_TIMEOUT_MSEC (10 minutes). This could cause additional false "Disconnected" reports for slower-starting servers that the CLI would connect to successfully during normal use.

extent analysis

TL;DR

The gemini mcp list command reports Google first-party MCP servers as disconnected due to a false negative caused by the ping() method being mandatory in the connection test, even though it's optional per the MCP spec.

Guidance

  • The issue arises from the testMCPConnection() function in list.ts requiring a successful ping() after connect(), which Google's MCP servers do not support, leading to a false "Disconnected" status.
  • To fix this, make the ping() call optional by wrapping it in a try-catch block that ignores the error if ping() fails, as suggested in the provided diff.
  • Additionally, consider reviewing the timeout values used in testMCPConnection() and connectToMcpServer() to ensure consistency and prevent potential false negatives due to timeout discrepancies.
  • Verify the fix by running gemini mcp list after applying the suggested changes and checking if the servers are reported as connected.

Example

The suggested fix in the issue body provides a clear example of how to modify the testMCPConnection() function to make the ping() call optional:

 try {
   await client.connect(transport, { timeout: 5000 });
-  await client.ping();
+  try {
+    await client.ping();
+  } catch {
+    // ping is optional per MCP spec — some servers (e.g. Google first-party)
+    // don't implement it. A successful connect() is sufficient.
+  }
   await client.close();
   return MCPServerStatus.CONNECTED;
 } catch {

Notes

The provided fix assumes that a successful connect() is sufficient to consider an MCP server connected, which aligns with the MCP spec. However, it's essential to review the spec and the specific requirements of your application to ensure this fix does not introduce any security or functionality issues.

Recommendation

Apply the workaround by making the ping() call optional in testMCPConnection(), as this directly addresses the root cause of the issue and aligns with the MCP specification, allowing for a more accurate status report of MCP servers.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING