mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-12 12:54:07 -07:00
feat(admin): Introduce remote admin settings & implement secureModeEnabled/mcpEnabled (#15935)
This commit is contained in:
@@ -933,6 +933,21 @@ their corresponding top-level category object in your `settings.json` file.
|
|||||||
- **Description:** Hooks that execute before tool selection. Can filter or
|
- **Description:** Hooks that execute before tool selection. Can filter or
|
||||||
prioritize available tools dynamically.
|
prioritize available tools dynamically.
|
||||||
- **Default:** `[]`
|
- **Default:** `[]`
|
||||||
|
|
||||||
|
#### `admin`
|
||||||
|
|
||||||
|
- **`admin.secureModeEnabled`** (boolean):
|
||||||
|
- **Description:** If true, disallows yolo mode from being used.
|
||||||
|
- **Default:** `false`
|
||||||
|
|
||||||
|
- **`admin.extensions.enabled`** (boolean):
|
||||||
|
- **Description:** If false, disallows extensions from being installed or
|
||||||
|
used.
|
||||||
|
- **Default:** `true`
|
||||||
|
|
||||||
|
- **`admin.mcp.enabled`** (boolean):
|
||||||
|
- **Description:** If false, disallows MCP servers from being used.
|
||||||
|
- **Default:** `true`
|
||||||
<!-- SETTINGS-AUTOGEN:END -->
|
<!-- SETTINGS-AUTOGEN:END -->
|
||||||
|
|
||||||
#### `mcpServers`
|
#### `mcpServers`
|
||||||
|
|||||||
@@ -1069,7 +1069,7 @@ describe('Approval mode tool exclusion logic', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow(
|
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow(
|
||||||
'Cannot start in YOLO mode when it is disabled by settings',
|
'Cannot start in YOLO mode since it is disabled by your admin',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2412,3 +2412,134 @@ describe('Policy Engine Integration in loadCliConfig', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('loadCliConfig secureModeEnabled', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.resetAllMocks();
|
||||||
|
vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
|
||||||
|
vi.stubEnv('GEMINI_API_KEY', 'test-api-key');
|
||||||
|
vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
|
||||||
|
vi.mocked(isWorkspaceTrusted).mockReturnValue({
|
||||||
|
isTrusted: true,
|
||||||
|
source: undefined,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.unstubAllEnvs();
|
||||||
|
vi.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if YOLO mode is attempted when secureModeEnabled is true', async () => {
|
||||||
|
process.argv = ['node', 'script.js', '--yolo'];
|
||||||
|
const argv = await parseArguments({} as Settings);
|
||||||
|
const settings: Settings = {
|
||||||
|
admin: {
|
||||||
|
secureModeEnabled: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow(
|
||||||
|
'Cannot start in YOLO mode since it is disabled by your admin',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if approval-mode=yolo is attempted when secureModeEnabled is true', async () => {
|
||||||
|
process.argv = ['node', 'script.js', '--approval-mode=yolo'];
|
||||||
|
const argv = await parseArguments({} as Settings);
|
||||||
|
const settings: Settings = {
|
||||||
|
admin: {
|
||||||
|
secureModeEnabled: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow(
|
||||||
|
'Cannot start in YOLO mode since it is disabled by your admin',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set disableYoloMode to true when secureModeEnabled is true', async () => {
|
||||||
|
process.argv = ['node', 'script.js'];
|
||||||
|
const argv = await parseArguments({} as Settings);
|
||||||
|
const settings: Settings = {
|
||||||
|
admin: {
|
||||||
|
secureModeEnabled: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
||||||
|
expect(config.isYoloModeDisabled()).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('loadCliConfig mcpEnabled', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.resetAllMocks();
|
||||||
|
vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
|
||||||
|
vi.stubEnv('GEMINI_API_KEY', 'test-api-key');
|
||||||
|
vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.unstubAllEnvs();
|
||||||
|
vi.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
const mcpSettings = {
|
||||||
|
mcp: {
|
||||||
|
serverCommand: 'mcp-server',
|
||||||
|
allowed: ['serverA'],
|
||||||
|
excluded: ['serverB'],
|
||||||
|
},
|
||||||
|
mcpServers: { serverA: { url: 'http://a' } },
|
||||||
|
};
|
||||||
|
|
||||||
|
it('should enable MCP by default', async () => {
|
||||||
|
process.argv = ['node', 'script.js'];
|
||||||
|
const argv = await parseArguments({} as Settings);
|
||||||
|
const settings: Settings = { ...mcpSettings };
|
||||||
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
||||||
|
expect(config.getMcpEnabled()).toBe(true);
|
||||||
|
expect(config.getMcpServerCommand()).toBe('mcp-server');
|
||||||
|
expect(config.getMcpServers()).toEqual({ serverA: { url: 'http://a' } });
|
||||||
|
expect(config.getAllowedMcpServers()).toEqual(['serverA']);
|
||||||
|
expect(config.getBlockedMcpServers()).toEqual(['serverB']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should disable MCP when mcpEnabled is false', async () => {
|
||||||
|
process.argv = ['node', 'script.js'];
|
||||||
|
const argv = await parseArguments({} as Settings);
|
||||||
|
const settings: Settings = {
|
||||||
|
...mcpSettings,
|
||||||
|
admin: {
|
||||||
|
mcp: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
||||||
|
expect(config.getMcpEnabled()).toBe(false);
|
||||||
|
expect(config.getMcpServerCommand()).toBeUndefined();
|
||||||
|
expect(config.getMcpServers()).toEqual({});
|
||||||
|
expect(config.getAllowedMcpServers()).toEqual([]);
|
||||||
|
expect(config.getBlockedMcpServers()).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should enable MCP when mcpEnabled is true', async () => {
|
||||||
|
process.argv = ['node', 'script.js'];
|
||||||
|
const argv = await parseArguments({} as Settings);
|
||||||
|
const settings: Settings = {
|
||||||
|
...mcpSettings,
|
||||||
|
admin: {
|
||||||
|
mcp: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
||||||
|
expect(config.getMcpEnabled()).toBe(true);
|
||||||
|
expect(config.getMcpServerCommand()).toBe('mcp-server');
|
||||||
|
expect(config.getMcpServers()).toEqual({ serverA: { url: 'http://a' } });
|
||||||
|
expect(config.getAllowedMcpServers()).toEqual(['serverA']);
|
||||||
|
expect(config.getBlockedMcpServers()).toEqual(['serverB']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -505,11 +505,19 @@ export async function loadCliConfig(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Override approval mode if disableYoloMode is set.
|
// Override approval mode if disableYoloMode is set.
|
||||||
if (settings.security?.disableYoloMode) {
|
if (settings.security?.disableYoloMode || settings.admin?.secureModeEnabled) {
|
||||||
if (approvalMode === ApprovalMode.YOLO) {
|
if (approvalMode === ApprovalMode.YOLO) {
|
||||||
debugLogger.error('YOLO mode is disabled by the "disableYolo" setting.');
|
if (settings.admin?.secureModeEnabled) {
|
||||||
|
debugLogger.error(
|
||||||
|
'YOLO mode is disabled by "secureModeEnabled" setting.',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
debugLogger.error(
|
||||||
|
'YOLO mode is disabled by the "disableYolo" setting.',
|
||||||
|
);
|
||||||
|
}
|
||||||
throw new FatalConfigError(
|
throw new FatalConfigError(
|
||||||
'Cannot start in YOLO mode when it is disabled by settings',
|
'Cannot start in YOLO mode since it is disabled by your admin',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
approvalMode = ApprovalMode.DEFAULT;
|
approvalMode = ApprovalMode.DEFAULT;
|
||||||
@@ -628,6 +636,8 @@ export async function loadCliConfig(
|
|||||||
|
|
||||||
const ptyInfo = await getPty();
|
const ptyInfo = await getPty();
|
||||||
|
|
||||||
|
const mcpEnabled = settings.admin?.mcp?.enabled ?? true;
|
||||||
|
|
||||||
return new Config({
|
return new Config({
|
||||||
sessionId,
|
sessionId,
|
||||||
embeddingModel: DEFAULT_GEMINI_EMBEDDING_MODEL,
|
embeddingModel: DEFAULT_GEMINI_EMBEDDING_MODEL,
|
||||||
@@ -646,12 +656,17 @@ export async function loadCliConfig(
|
|||||||
excludeTools,
|
excludeTools,
|
||||||
toolDiscoveryCommand: settings.tools?.discoveryCommand,
|
toolDiscoveryCommand: settings.tools?.discoveryCommand,
|
||||||
toolCallCommand: settings.tools?.callCommand,
|
toolCallCommand: settings.tools?.callCommand,
|
||||||
mcpServerCommand: settings.mcp?.serverCommand,
|
mcpServerCommand: mcpEnabled ? settings.mcp?.serverCommand : undefined,
|
||||||
mcpServers: settings.mcpServers,
|
mcpServers: mcpEnabled ? settings.mcpServers : {},
|
||||||
allowedMcpServers: argv.allowedMcpServerNames ?? settings.mcp?.allowed,
|
mcpEnabled,
|
||||||
blockedMcpServers: argv.allowedMcpServerNames
|
allowedMcpServers: mcpEnabled
|
||||||
? undefined
|
? (argv.allowedMcpServerNames ?? settings.mcp?.allowed)
|
||||||
: settings.mcp?.excluded,
|
: undefined,
|
||||||
|
blockedMcpServers: mcpEnabled
|
||||||
|
? argv.allowedMcpServerNames
|
||||||
|
? undefined
|
||||||
|
: settings.mcp?.excluded
|
||||||
|
: undefined,
|
||||||
blockedEnvironmentVariables:
|
blockedEnvironmentVariables:
|
||||||
settings.security?.environmentVariableRedaction?.blocked,
|
settings.security?.environmentVariableRedaction?.blocked,
|
||||||
enableEnvironmentVariableRedaction:
|
enableEnvironmentVariableRedaction:
|
||||||
@@ -660,7 +675,8 @@ export async function loadCliConfig(
|
|||||||
geminiMdFileCount: fileCount,
|
geminiMdFileCount: fileCount,
|
||||||
geminiMdFilePaths: filePaths,
|
geminiMdFilePaths: filePaths,
|
||||||
approvalMode,
|
approvalMode,
|
||||||
disableYoloMode: settings.security?.disableYoloMode,
|
disableYoloMode:
|
||||||
|
settings.security?.disableYoloMode || settings.admin?.secureModeEnabled,
|
||||||
showMemoryUsage: settings.ui?.showMemoryUsage || false,
|
showMemoryUsage: settings.ui?.showMemoryUsage || false,
|
||||||
accessibility: {
|
accessibility: {
|
||||||
...settings.ui?.accessibility,
|
...settings.ui?.accessibility,
|
||||||
|
|||||||
@@ -1718,6 +1718,74 @@ const SETTINGS_SCHEMA = {
|
|||||||
mergeStrategy: MergeStrategy.CONCAT,
|
mergeStrategy: MergeStrategy.CONCAT,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
admin: {
|
||||||
|
type: 'object',
|
||||||
|
label: 'Admin',
|
||||||
|
category: 'Admin',
|
||||||
|
requiresRestart: false,
|
||||||
|
default: {},
|
||||||
|
description: 'Settings configured remotely by enterprise admins.',
|
||||||
|
showInDialog: false,
|
||||||
|
mergeStrategy: MergeStrategy.REPLACE,
|
||||||
|
properties: {
|
||||||
|
secureModeEnabled: {
|
||||||
|
type: 'boolean',
|
||||||
|
label: 'Secure Mode Enabled',
|
||||||
|
category: 'Admin',
|
||||||
|
requiresRestart: false,
|
||||||
|
default: false,
|
||||||
|
description: 'If true, disallows yolo mode from being used.',
|
||||||
|
showInDialog: false,
|
||||||
|
mergeStrategy: MergeStrategy.REPLACE,
|
||||||
|
},
|
||||||
|
extensions: {
|
||||||
|
type: 'object',
|
||||||
|
label: 'Extensions Settings',
|
||||||
|
category: 'Admin',
|
||||||
|
requiresRestart: false,
|
||||||
|
default: {},
|
||||||
|
description: 'Extensions-specific admin settings.',
|
||||||
|
showInDialog: false,
|
||||||
|
mergeStrategy: MergeStrategy.REPLACE,
|
||||||
|
properties: {
|
||||||
|
enabled: {
|
||||||
|
type: 'boolean',
|
||||||
|
label: 'Extensions Enabled',
|
||||||
|
category: 'Admin',
|
||||||
|
requiresRestart: false,
|
||||||
|
default: true,
|
||||||
|
description:
|
||||||
|
'If false, disallows extensions from being installed or used.',
|
||||||
|
showInDialog: false,
|
||||||
|
mergeStrategy: MergeStrategy.REPLACE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mcp: {
|
||||||
|
type: 'object',
|
||||||
|
label: 'MCP Settings',
|
||||||
|
category: 'Admin',
|
||||||
|
requiresRestart: false,
|
||||||
|
default: {},
|
||||||
|
description: 'MCP-specific admin settings.',
|
||||||
|
showInDialog: false,
|
||||||
|
mergeStrategy: MergeStrategy.REPLACE,
|
||||||
|
properties: {
|
||||||
|
enabled: {
|
||||||
|
type: 'boolean',
|
||||||
|
label: 'MCP Enabled',
|
||||||
|
category: 'Admin',
|
||||||
|
requiresRestart: false,
|
||||||
|
default: true,
|
||||||
|
description: 'If false, disallows MCP servers from being used.',
|
||||||
|
showInDialog: false,
|
||||||
|
mergeStrategy: MergeStrategy.REPLACE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
} as const satisfies SettingsSchema;
|
} as const satisfies SettingsSchema;
|
||||||
|
|
||||||
export type SettingsSchemaType = typeof SETTINGS_SCHEMA;
|
export type SettingsSchemaType = typeof SETTINGS_SCHEMA;
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ describe('BuiltinCommandLoader', () => {
|
|||||||
getEnableExtensionReloading: () => false,
|
getEnableExtensionReloading: () => false,
|
||||||
getEnableHooks: () => false,
|
getEnableHooks: () => false,
|
||||||
isSkillsSupportEnabled: vi.fn().mockReturnValue(false),
|
isSkillsSupportEnabled: vi.fn().mockReturnValue(false),
|
||||||
|
getMcpEnabled: vi.fn().mockReturnValue(true),
|
||||||
getSkillManager: vi.fn().mockReturnValue({
|
getSkillManager: vi.fn().mockReturnValue({
|
||||||
getAllSkills: vi.fn().mockReturnValue([]),
|
getAllSkills: vi.fn().mockReturnValue([]),
|
||||||
}),
|
}),
|
||||||
@@ -179,6 +180,7 @@ describe('BuiltinCommandLoader', () => {
|
|||||||
const mockConfigWithMessageBus = {
|
const mockConfigWithMessageBus = {
|
||||||
...mockConfig,
|
...mockConfig,
|
||||||
getEnableHooks: () => false,
|
getEnableHooks: () => false,
|
||||||
|
getMcpEnabled: () => true,
|
||||||
} as unknown as Config;
|
} as unknown as Config;
|
||||||
const loader = new BuiltinCommandLoader(mockConfigWithMessageBus);
|
const loader = new BuiltinCommandLoader(mockConfigWithMessageBus);
|
||||||
const commands = await loader.loadCommands(new AbortController().signal);
|
const commands = await loader.loadCommands(new AbortController().signal);
|
||||||
@@ -198,6 +200,7 @@ describe('BuiltinCommandLoader profile', () => {
|
|||||||
getEnableExtensionReloading: () => false,
|
getEnableExtensionReloading: () => false,
|
||||||
getEnableHooks: () => false,
|
getEnableHooks: () => false,
|
||||||
isSkillsSupportEnabled: vi.fn().mockReturnValue(false),
|
isSkillsSupportEnabled: vi.fn().mockReturnValue(false),
|
||||||
|
getMcpEnabled: vi.fn().mockReturnValue(true),
|
||||||
getSkillManager: vi.fn().mockReturnValue({
|
getSkillManager: vi.fn().mockReturnValue({
|
||||||
getAllSkills: vi.fn().mockReturnValue([]),
|
getAllSkills: vi.fn().mockReturnValue([]),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -6,8 +6,12 @@
|
|||||||
|
|
||||||
import { isDevelopment } from '../utils/installationInfo.js';
|
import { isDevelopment } from '../utils/installationInfo.js';
|
||||||
import type { ICommandLoader } from './types.js';
|
import type { ICommandLoader } from './types.js';
|
||||||
import type { SlashCommand } from '../ui/commands/types.js';
|
import {
|
||||||
import type { Config } from '@google/gemini-cli-core';
|
CommandKind,
|
||||||
|
type SlashCommand,
|
||||||
|
type CommandContext,
|
||||||
|
} from '../ui/commands/types.js';
|
||||||
|
import type { MessageActionReturn, Config } from '@google/gemini-cli-core';
|
||||||
import { startupProfiler } from '@google/gemini-cli-core';
|
import { startupProfiler } from '@google/gemini-cli-core';
|
||||||
import { aboutCommand } from '../ui/commands/aboutCommand.js';
|
import { aboutCommand } from '../ui/commands/aboutCommand.js';
|
||||||
import { authCommand } from '../ui/commands/authCommand.js';
|
import { authCommand } from '../ui/commands/authCommand.js';
|
||||||
@@ -77,7 +81,25 @@ export class BuiltinCommandLoader implements ICommandLoader {
|
|||||||
...(this.config?.getEnableHooks() ? [hooksCommand] : []),
|
...(this.config?.getEnableHooks() ? [hooksCommand] : []),
|
||||||
await ideCommand(),
|
await ideCommand(),
|
||||||
initCommand,
|
initCommand,
|
||||||
mcpCommand,
|
...(this.config?.getMcpEnabled() === false
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
name: 'mcp',
|
||||||
|
description:
|
||||||
|
'Manage configured Model Context Protocol (MCP) servers',
|
||||||
|
kind: CommandKind.BUILT_IN,
|
||||||
|
autoExecute: false,
|
||||||
|
subCommands: [],
|
||||||
|
action: async (
|
||||||
|
_context: CommandContext,
|
||||||
|
): Promise<MessageActionReturn> => ({
|
||||||
|
type: 'message',
|
||||||
|
messageType: 'error',
|
||||||
|
content: 'MCP disabled by your admin.',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [mcpCommand]),
|
||||||
memoryCommand,
|
memoryCommand,
|
||||||
modelCommand,
|
modelCommand,
|
||||||
...(this.config?.getFolderTrust() ? [permissionsCommand] : []),
|
...(this.config?.getFolderTrust() ? [permissionsCommand] : []),
|
||||||
|
|||||||
@@ -277,3 +277,26 @@ export interface ConversationInteraction {
|
|||||||
language?: string;
|
language?: string;
|
||||||
isAgentic?: boolean;
|
isAgentic?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface GeminiCodeAssistSetting {
|
||||||
|
secureModeEnabled?: boolean;
|
||||||
|
mcpSetting?: McpSetting;
|
||||||
|
cliFeatureSetting?: CliFeatureSetting;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface McpSetting {
|
||||||
|
mcpEnabled?: boolean;
|
||||||
|
allowedMcpConfigs?: McpConfig[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface McpConfig {
|
||||||
|
mcpServer?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CliFeatureSetting {
|
||||||
|
extensionsSetting?: ExtensionsSetting;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExtensionsSetting {
|
||||||
|
extensionsEnabled?: boolean;
|
||||||
|
}
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ import type { PolicyEngineConfig } from '../policy/types.js';
|
|||||||
import { HookSystem } from '../hooks/index.js';
|
import { HookSystem } from '../hooks/index.js';
|
||||||
import type { UserTierId } from '../code_assist/types.js';
|
import type { UserTierId } from '../code_assist/types.js';
|
||||||
import type { RetrieveUserQuotaResponse } from '../code_assist/types.js';
|
import type { RetrieveUserQuotaResponse } from '../code_assist/types.js';
|
||||||
|
import type { GeminiCodeAssistSetting } from '../code_assist/types.js';
|
||||||
import { getCodeAssistServer } from '../code_assist/codeAssist.js';
|
import { getCodeAssistServer } from '../code_assist/codeAssist.js';
|
||||||
import type { Experiments } from '../code_assist/experiments/experiments.js';
|
import type { Experiments } from '../code_assist/experiments/experiments.js';
|
||||||
import { AgentRegistry } from '../agents/registry.js';
|
import { AgentRegistry } from '../agents/registry.js';
|
||||||
@@ -356,6 +357,7 @@ export interface ConfigParameters {
|
|||||||
disabledSkills?: string[];
|
disabledSkills?: string[];
|
||||||
experimentalJitContext?: boolean;
|
experimentalJitContext?: boolean;
|
||||||
onModelChange?: (model: string) => void;
|
onModelChange?: (model: string) => void;
|
||||||
|
mcpEnabled?: boolean;
|
||||||
onReload?: () => Promise<{ disabledSkills?: string[] }>;
|
onReload?: () => Promise<{ disabledSkills?: string[] }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,6 +391,7 @@ export class Config {
|
|||||||
private readonly toolDiscoveryCommand: string | undefined;
|
private readonly toolDiscoveryCommand: string | undefined;
|
||||||
private readonly toolCallCommand: string | undefined;
|
private readonly toolCallCommand: string | undefined;
|
||||||
private readonly mcpServerCommand: string | undefined;
|
private readonly mcpServerCommand: string | undefined;
|
||||||
|
private readonly mcpEnabled: boolean;
|
||||||
private mcpServers: Record<string, MCPServerConfig> | undefined;
|
private mcpServers: Record<string, MCPServerConfig> | undefined;
|
||||||
private userMemory: string;
|
private userMemory: string;
|
||||||
private geminiMdFileCount: number;
|
private geminiMdFileCount: number;
|
||||||
@@ -491,6 +494,7 @@ export class Config {
|
|||||||
private readonly experimentalJitContext: boolean;
|
private readonly experimentalJitContext: boolean;
|
||||||
private contextManager?: ContextManager;
|
private contextManager?: ContextManager;
|
||||||
private terminalBackground: string | undefined = undefined;
|
private terminalBackground: string | undefined = undefined;
|
||||||
|
private remoteAdminSettings: GeminiCodeAssistSetting | undefined;
|
||||||
|
|
||||||
constructor(params: ConfigParameters) {
|
constructor(params: ConfigParameters) {
|
||||||
this.sessionId = params.sessionId;
|
this.sessionId = params.sessionId;
|
||||||
@@ -512,6 +516,7 @@ export class Config {
|
|||||||
this.toolCallCommand = params.toolCallCommand;
|
this.toolCallCommand = params.toolCallCommand;
|
||||||
this.mcpServerCommand = params.mcpServerCommand;
|
this.mcpServerCommand = params.mcpServerCommand;
|
||||||
this.mcpServers = params.mcpServers;
|
this.mcpServers = params.mcpServers;
|
||||||
|
this.mcpEnabled = params.mcpEnabled ?? true;
|
||||||
this.allowedMcpServers = params.allowedMcpServers ?? [];
|
this.allowedMcpServers = params.allowedMcpServers ?? [];
|
||||||
this.blockedMcpServers = params.blockedMcpServers ?? [];
|
this.blockedMcpServers = params.blockedMcpServers ?? [];
|
||||||
this.allowedEnvironmentVariables = params.allowedEnvironmentVariables ?? [];
|
this.allowedEnvironmentVariables = params.allowedEnvironmentVariables ?? [];
|
||||||
@@ -894,6 +899,14 @@ export class Config {
|
|||||||
return this.terminalBackground;
|
return this.terminalBackground;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getRemoteAdminSettings(): GeminiCodeAssistSetting | undefined {
|
||||||
|
return this.remoteAdminSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
setRemoteAdminSettings(settings: GeminiCodeAssistSetting): void {
|
||||||
|
this.remoteAdminSettings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
shouldLoadMemoryFromIncludeDirectories(): boolean {
|
shouldLoadMemoryFromIncludeDirectories(): boolean {
|
||||||
return this.loadMemoryFromIncludeDirectories;
|
return this.loadMemoryFromIncludeDirectories;
|
||||||
}
|
}
|
||||||
@@ -1125,6 +1138,10 @@ export class Config {
|
|||||||
return this.mcpServers;
|
return this.mcpServers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMcpEnabled(): boolean {
|
||||||
|
return this.mcpEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
getMcpClientManager(): McpClientManager | undefined {
|
getMcpClientManager(): McpClientManager | undefined {
|
||||||
return this.mcpClientManager;
|
return this.mcpClientManager;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1608,6 +1608,57 @@
|
|||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {}
|
"items": {}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"admin": {
|
||||||
|
"title": "Admin",
|
||||||
|
"description": "Settings configured remotely by enterprise admins.",
|
||||||
|
"markdownDescription": "Settings configured remotely by enterprise admins.\n\n- Category: `Admin`\n- Requires restart: `no`\n- Default: `{}`",
|
||||||
|
"default": {},
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"secureModeEnabled": {
|
||||||
|
"title": "Secure Mode Enabled",
|
||||||
|
"description": "If true, disallows yolo mode from being used.",
|
||||||
|
"markdownDescription": "If true, disallows yolo mode from being used.\n\n- Category: `Admin`\n- Requires restart: `no`\n- Default: `false`",
|
||||||
|
"default": false,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"extensions": {
|
||||||
|
"title": "Extensions Settings",
|
||||||
|
"description": "Extensions-specific admin settings.",
|
||||||
|
"markdownDescription": "Extensions-specific admin settings.\n\n- Category: `Admin`\n- Requires restart: `no`\n- Default: `{}`",
|
||||||
|
"default": {},
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"title": "Extensions Enabled",
|
||||||
|
"description": "If false, disallows extensions from being installed or used.",
|
||||||
|
"markdownDescription": "If false, disallows extensions from being installed or used.\n\n- Category: `Admin`\n- Requires restart: `no`\n- Default: `true`",
|
||||||
|
"default": true,
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"mcp": {
|
||||||
|
"title": "MCP Settings",
|
||||||
|
"description": "MCP-specific admin settings.",
|
||||||
|
"markdownDescription": "MCP-specific admin settings.\n\n- Category: `Admin`\n- Requires restart: `no`\n- Default: `{}`",
|
||||||
|
"default": {},
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"title": "MCP Enabled",
|
||||||
|
"description": "If false, disallows MCP servers from being used.",
|
||||||
|
"markdownDescription": "If false, disallows MCP servers from being used.\n\n- Category: `Admin`\n- Requires restart: `no`\n- Default: `true`",
|
||||||
|
"default": true,
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"$defs": {
|
"$defs": {
|
||||||
|
|||||||
Reference in New Issue
Block a user