feat: consolidate remote MCP servers to use url in config (#13762)

This commit is contained in:
Jack Wotherspoon
2025-12-02 20:01:33 -05:00
committed by GitHub
parent 145fb246a6
commit bdbbe9232d
9 changed files with 801 additions and 271 deletions

View File

@@ -107,6 +107,7 @@ describe('mcp add command', () => {
expect(mockSetValue).toHaveBeenCalledWith(SettingScope.User, 'mcpServers', {
'sse-server': {
url: 'https://example.com/sse-endpoint',
type: 'sse',
headers: { 'X-API-Key': 'your-key' },
},
});
@@ -122,7 +123,8 @@ describe('mcp add command', () => {
'mcpServers',
{
'http-server': {
httpUrl: 'https://example.com/mcp',
url: 'https://example.com/mcp',
type: 'http',
headers: { Authorization: 'Bearer your-token' },
},
},

View File

@@ -69,6 +69,7 @@ async function addMcpServer(
case 'sse':
newServer = {
url: commandOrUrl,
type: 'sse',
headers,
timeout,
trust,
@@ -79,7 +80,8 @@ async function addMcpServer(
break;
case 'http':
newServer = {
httpUrl: commandOrUrl,
url: commandOrUrl,
type: 'http',
headers,
timeout,
trust,

View File

@@ -20,6 +20,7 @@ import {
MCPServerStatus,
getErrorMessage,
MCPOAuthTokenStorage,
mcpServerRequiresOAuth,
} from '@google/gemini-cli-core';
import { appEvents, AppEvent } from '../../utils/events.js';
import { MessageType, type HistoryItemMcpStatus } from '../types.js';
@@ -47,12 +48,23 @@ const authCommand: SlashCommand = {
const mcpServers = config.getMcpClientManager()?.getMcpServers() ?? {};
if (!serverName) {
// List servers that support OAuth
const oauthServers = Object.entries(mcpServers)
// List servers that support OAuth from two sources:
// 1. Servers with oauth.enabled in config
// 2. Servers detected as requiring OAuth (returned 401)
const configuredOAuthServers = Object.entries(mcpServers)
.filter(([_, server]) => server.oauth?.enabled)
.map(([name, _]) => name);
if (oauthServers.length === 0) {
const detectedOAuthServers = Array.from(
mcpServerRequiresOAuth.keys(),
).filter((name) => mcpServers[name]); // Only include configured servers
// Combine and deduplicate
const allOAuthServers = [
...new Set([...configuredOAuthServers, ...detectedOAuthServers]),
];
if (allOAuthServers.length === 0) {
return {
type: 'message',
messageType: 'info',
@@ -63,7 +75,7 @@ const authCommand: SlashCommand = {
return {
type: 'message',
messageType: 'info',
content: `MCP servers with OAuth authentication:\n${oauthServers.map((s) => ` - ${s}`).join('\n')}\n\nUse /mcp auth <server-name> to authenticate.`,
content: `MCP servers with OAuth authentication:\n${allOAuthServers.map((s) => ` - ${s}`).join('\n')}\n\nUse /mcp auth <server-name> to authenticate.`,
};
}
@@ -220,7 +232,8 @@ const listAction = async (
const tokenStorage = new MCPOAuthTokenStorage();
for (const serverName of serverNames) {
const server = mcpServers[serverName];
if (server.oauth?.enabled) {
// Check auth status for servers with oauth.enabled OR detected as requiring OAuth
if (server.oauth?.enabled || mcpServerRequiresOAuth.has(serverName)) {
const creds = await tokenStorage.getCredentials(serverName);
if (creds) {
if (creds.token.expiresAt && creds.token.expiresAt < Date.now()) {