mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-22 11:04:42 -07:00
a060e6149a
Co-authored-by: Allen Hutchison <adh@google.com>
170 lines
4.8 KiB
TypeScript
170 lines
4.8 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import type { CommandModule } from 'yargs';
|
|
import { debugLogger } from '@google/gemini-cli-core';
|
|
import {
|
|
McpServerEnablementManager,
|
|
canLoadServer,
|
|
normalizeServerId,
|
|
} from '../../config/mcp/mcpServerEnablement.js';
|
|
import { loadSettings } from '../../config/settings.js';
|
|
import { exitCli } from '../utils.js';
|
|
import { getMcpServersFromConfig } from './list.js';
|
|
|
|
const GREEN = '\x1b[32m';
|
|
const YELLOW = '\x1b[33m';
|
|
const RED = '\x1b[31m';
|
|
const RESET = '\x1b[0m';
|
|
|
|
interface Args {
|
|
name: string;
|
|
session?: boolean;
|
|
}
|
|
|
|
async function handleEnable(args: Args): Promise<void> {
|
|
const manager = McpServerEnablementManager.getInstance();
|
|
const name = normalizeServerId(args.name);
|
|
|
|
// Check settings blocks
|
|
const settings = loadSettings();
|
|
|
|
// Get all servers including extensions
|
|
const servers = await getMcpServersFromConfig();
|
|
const normalizedServerNames = Object.keys(servers).map(normalizeServerId);
|
|
if (!normalizedServerNames.includes(name)) {
|
|
debugLogger.log(
|
|
`${RED}Error:${RESET} Server '${args.name}' not found. Use 'gemini mcp' to see available servers.`,
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Check if server is from an extension
|
|
const serverKey = Object.keys(servers).find(
|
|
(key) => normalizeServerId(key) === name,
|
|
);
|
|
const server = serverKey ? servers[serverKey] : undefined;
|
|
if (server?.extension) {
|
|
debugLogger.log(
|
|
`${RED}Error:${RESET} Server '${args.name}' is provided by extension '${server.extension.name}'.`,
|
|
);
|
|
debugLogger.log(
|
|
`Use 'gemini extensions enable ${server.extension.name}' to manage this extension.`,
|
|
);
|
|
return;
|
|
}
|
|
|
|
const result = await canLoadServer(name, {
|
|
adminMcpEnabled: settings.merged.admin?.mcp?.enabled ?? true,
|
|
allowedList: settings.merged.mcp?.allowed,
|
|
excludedList: settings.merged.mcp?.excluded,
|
|
});
|
|
|
|
if (
|
|
!result.allowed &&
|
|
(result.blockType === 'allowlist' || result.blockType === 'excludelist')
|
|
) {
|
|
debugLogger.log(`${RED}Error:${RESET} ${result.reason}`);
|
|
return;
|
|
}
|
|
|
|
if (args.session) {
|
|
manager.clearSessionDisable(name);
|
|
debugLogger.log(`${GREEN}✓${RESET} Session disable cleared for '${name}'.`);
|
|
} else {
|
|
await manager.enable(name);
|
|
debugLogger.log(`${GREEN}✓${RESET} MCP server '${name}' enabled.`);
|
|
}
|
|
|
|
if (result.blockType === 'admin') {
|
|
debugLogger.log(
|
|
`${YELLOW}Warning:${RESET} MCP servers are disabled by administrator.`,
|
|
);
|
|
}
|
|
}
|
|
|
|
async function handleDisable(args: Args): Promise<void> {
|
|
const manager = McpServerEnablementManager.getInstance();
|
|
const name = normalizeServerId(args.name);
|
|
|
|
// Get all servers including extensions
|
|
const servers = await getMcpServersFromConfig();
|
|
const normalizedServerNames = Object.keys(servers).map(normalizeServerId);
|
|
if (!normalizedServerNames.includes(name)) {
|
|
debugLogger.log(
|
|
`${RED}Error:${RESET} Server '${args.name}' not found. Use 'gemini mcp' to see available servers.`,
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Check if server is from an extension
|
|
const serverKey = Object.keys(servers).find(
|
|
(key) => normalizeServerId(key) === name,
|
|
);
|
|
const server = serverKey ? servers[serverKey] : undefined;
|
|
if (server?.extension) {
|
|
debugLogger.log(
|
|
`${RED}Error:${RESET} Server '${args.name}' is provided by extension '${server.extension.name}'.`,
|
|
);
|
|
debugLogger.log(
|
|
`Use 'gemini extensions disable ${server.extension.name}' to manage this extension.`,
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (args.session) {
|
|
manager.disableForSession(name);
|
|
debugLogger.log(
|
|
`${GREEN}✓${RESET} MCP server '${name}' disabled for this session.`,
|
|
);
|
|
} else {
|
|
await manager.disable(name);
|
|
debugLogger.log(`${GREEN}✓${RESET} MCP server '${name}' disabled.`);
|
|
}
|
|
}
|
|
|
|
export const enableCommand: CommandModule<object, Args> = {
|
|
command: 'enable <name>',
|
|
describe: 'Enable an MCP server',
|
|
builder: (yargs) =>
|
|
yargs
|
|
.positional('name', {
|
|
describe: 'MCP server name to enable',
|
|
type: 'string',
|
|
demandOption: true,
|
|
})
|
|
.option('session', {
|
|
describe: 'Clear session-only disable',
|
|
type: 'boolean',
|
|
default: false,
|
|
}),
|
|
handler: async (argv) => {
|
|
await handleEnable(argv as Args);
|
|
await exitCli();
|
|
},
|
|
};
|
|
|
|
export const disableCommand: CommandModule<object, Args> = {
|
|
command: 'disable <name>',
|
|
describe: 'Disable an MCP server',
|
|
builder: (yargs) =>
|
|
yargs
|
|
.positional('name', {
|
|
describe: 'MCP server name to disable',
|
|
type: 'string',
|
|
demandOption: true,
|
|
})
|
|
.option('session', {
|
|
describe: 'Disable for current session only',
|
|
type: 'boolean',
|
|
default: false,
|
|
}),
|
|
handler: async (argv) => {
|
|
await handleDisable(argv as Args);
|
|
await exitCli();
|
|
},
|
|
};
|