summaryrefslogtreecommitdiff
path: root/packages/cli/src/config/config.ts
diff options
context:
space:
mode:
authorJack Wotherspoon <[email protected]>2025-08-06 11:52:29 -0400
committerGitHub <[email protected]>2025-08-06 15:52:29 +0000
commitca4c745e3b620e3ac4eca24b610cc7b936c0a50d (patch)
treeeb1b9cfb46bd4fa2e7f9631828b0704df1050eb7 /packages/cli/src/config/config.ts
parentb38f377c9a2672e88dd15119b38d908c0f00b54a (diff)
feat(mcp): add `gemini mcp` commands for `add`, `remove` and `list` (#5481)
Diffstat (limited to 'packages/cli/src/config/config.ts')
-rw-r--r--packages/cli/src/config/config.ts323
1 files changed, 168 insertions, 155 deletions
diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts
index beba9602..7175c033 100644
--- a/packages/cli/src/config/config.ts
+++ b/packages/cli/src/config/config.ts
@@ -10,6 +10,7 @@ import { homedir } from 'node:os';
import yargs from 'yargs/yargs';
import { hideBin } from 'yargs/helpers';
import process from 'node:process';
+import { mcpCommand } from '../commands/mcp.js';
import {
Config,
loadServerHierarchicalMemory,
@@ -72,173 +73,185 @@ export async function parseArguments(): Promise<CliArgs> {
const yargsInstance = yargs(hideBin(process.argv))
.scriptName('gemini')
.usage(
- '$0 [options]',
- 'Gemini CLI - Launch an interactive CLI, use -p/--prompt for non-interactive mode',
+ 'Usage: gemini [options] [command]\n\nGemini CLI - Launch an interactive CLI, use -p/--prompt for non-interactive mode',
)
- .option('model', {
- alias: 'm',
- type: 'string',
- description: `Model`,
- default: process.env.GEMINI_MODEL,
- })
- .option('prompt', {
- alias: 'p',
- type: 'string',
- description: 'Prompt. Appended to input on stdin (if any).',
- })
- .option('prompt-interactive', {
- alias: 'i',
- type: 'string',
- description:
- 'Execute the provided prompt and continue in interactive mode',
- })
- .option('sandbox', {
- alias: 's',
- type: 'boolean',
- description: 'Run in sandbox?',
- })
- .option('sandbox-image', {
- type: 'string',
- description: 'Sandbox image URI.',
- })
- .option('debug', {
- alias: 'd',
- type: 'boolean',
- description: 'Run in debug mode?',
- default: false,
- })
- .option('all-files', {
- alias: ['a'],
- type: 'boolean',
- description: 'Include ALL files in context?',
- default: false,
- })
- .option('all_files', {
- type: 'boolean',
- description: 'Include ALL files in context?',
- default: false,
- })
- .deprecateOption(
- 'all_files',
- 'Use --all-files instead. We will be removing --all_files in the coming weeks.',
- )
- .option('show-memory-usage', {
- type: 'boolean',
- description: 'Show memory usage in status bar',
- default: false,
- })
- .option('show_memory_usage', {
- type: 'boolean',
- description: 'Show memory usage in status bar',
- default: false,
- })
- .deprecateOption(
- 'show_memory_usage',
- 'Use --show-memory-usage instead. We will be removing --show_memory_usage in the coming weeks.',
+ .command('$0', 'Launch Gemini CLI', (yargsInstance) =>
+ yargsInstance
+ .option('model', {
+ alias: 'm',
+ type: 'string',
+ description: `Model`,
+ default: process.env.GEMINI_MODEL,
+ })
+ .option('prompt', {
+ alias: 'p',
+ type: 'string',
+ description: 'Prompt. Appended to input on stdin (if any).',
+ })
+ .option('prompt-interactive', {
+ alias: 'i',
+ type: 'string',
+ description:
+ 'Execute the provided prompt and continue in interactive mode',
+ })
+ .option('sandbox', {
+ alias: 's',
+ type: 'boolean',
+ description: 'Run in sandbox?',
+ })
+ .option('sandbox-image', {
+ type: 'string',
+ description: 'Sandbox image URI.',
+ })
+ .option('debug', {
+ alias: 'd',
+ type: 'boolean',
+ description: 'Run in debug mode?',
+ default: false,
+ })
+ .option('all-files', {
+ alias: ['a'],
+ type: 'boolean',
+ description: 'Include ALL files in context?',
+ default: false,
+ })
+ .option('all_files', {
+ type: 'boolean',
+ description: 'Include ALL files in context?',
+ default: false,
+ })
+ .deprecateOption(
+ 'all_files',
+ 'Use --all-files instead. We will be removing --all_files in the coming weeks.',
+ )
+ .option('show-memory-usage', {
+ type: 'boolean',
+ description: 'Show memory usage in status bar',
+ default: false,
+ })
+ .option('show_memory_usage', {
+ type: 'boolean',
+ description: 'Show memory usage in status bar',
+ default: false,
+ })
+ .deprecateOption(
+ 'show_memory_usage',
+ 'Use --show-memory-usage instead. We will be removing --show_memory_usage in the coming weeks.',
+ )
+ .option('yolo', {
+ alias: 'y',
+ type: 'boolean',
+ description:
+ 'Automatically accept all actions (aka YOLO mode, see https://www.youtube.com/watch?v=xvFZjo5PgG0 for more details)?',
+ default: false,
+ })
+ .option('telemetry', {
+ type: 'boolean',
+ description:
+ 'Enable telemetry? This flag specifically controls if telemetry is sent. Other --telemetry-* flags set specific values but do not enable telemetry on their own.',
+ })
+ .option('telemetry-target', {
+ type: 'string',
+ choices: ['local', 'gcp'],
+ description:
+ 'Set the telemetry target (local or gcp). Overrides settings files.',
+ })
+ .option('telemetry-otlp-endpoint', {
+ type: 'string',
+ description:
+ 'Set the OTLP endpoint for telemetry. Overrides environment variables and settings files.',
+ })
+ .option('telemetry-log-prompts', {
+ type: 'boolean',
+ description:
+ 'Enable or disable logging of user prompts for telemetry. Overrides settings files.',
+ })
+ .option('telemetry-outfile', {
+ type: 'string',
+ description: 'Redirect all telemetry output to the specified file.',
+ })
+ .option('checkpointing', {
+ alias: 'c',
+ type: 'boolean',
+ description: 'Enables checkpointing of file edits',
+ default: false,
+ })
+ .option('experimental-acp', {
+ type: 'boolean',
+ description: 'Starts the agent in ACP mode',
+ })
+ .option('allowed-mcp-server-names', {
+ type: 'array',
+ string: true,
+ description: 'Allowed MCP server names',
+ })
+ .option('extensions', {
+ alias: 'e',
+ type: 'array',
+ string: true,
+ description:
+ 'A list of extensions to use. If not provided, all extensions are used.',
+ })
+ .option('list-extensions', {
+ alias: 'l',
+ type: 'boolean',
+ description: 'List all available extensions and exit.',
+ })
+ .option('ide-mode-feature', {
+ type: 'boolean',
+ description: 'Run in IDE mode?',
+ })
+ .option('proxy', {
+ type: 'string',
+ description:
+ 'Proxy for gemini client, like schema://user:password@host:port',
+ })
+ .option('include-directories', {
+ type: 'array',
+ string: true,
+ description:
+ 'Additional directories to include in the workspace (comma-separated or multiple --include-directories)',
+ coerce: (dirs: string[]) =>
+ // Handle comma-separated values
+ dirs.flatMap((dir) => dir.split(',').map((d) => d.trim())),
+ })
+ .option('load-memory-from-include-directories', {
+ type: 'boolean',
+ description:
+ 'If true, when refreshing memory, GEMINI.md files should be loaded from all directories that are added. If false, GEMINI.md files should only be loaded from the primary working directory.',
+ default: false,
+ })
+ .check((argv) => {
+ if (argv.prompt && argv.promptInteractive) {
+ throw new Error(
+ 'Cannot use both --prompt (-p) and --prompt-interactive (-i) together',
+ );
+ }
+ return true;
+ }),
)
- .option('yolo', {
- alias: 'y',
- type: 'boolean',
- description:
- 'Automatically accept all actions (aka YOLO mode, see https://www.youtube.com/watch?v=xvFZjo5PgG0 for more details)?',
- default: false,
- })
- .option('telemetry', {
- type: 'boolean',
- description:
- 'Enable telemetry? This flag specifically controls if telemetry is sent. Other --telemetry-* flags set specific values but do not enable telemetry on their own.',
- })
- .option('telemetry-target', {
- type: 'string',
- choices: ['local', 'gcp'],
- description:
- 'Set the telemetry target (local or gcp). Overrides settings files.',
- })
- .option('telemetry-otlp-endpoint', {
- type: 'string',
- description:
- 'Set the OTLP endpoint for telemetry. Overrides environment variables and settings files.',
- })
- .option('telemetry-log-prompts', {
- type: 'boolean',
- description:
- 'Enable or disable logging of user prompts for telemetry. Overrides settings files.',
- })
- .option('telemetry-outfile', {
- type: 'string',
- description: 'Redirect all telemetry output to the specified file.',
- })
- .option('checkpointing', {
- alias: 'c',
- type: 'boolean',
- description: 'Enables checkpointing of file edits',
- default: false,
- })
- .option('experimental-acp', {
- type: 'boolean',
- description: 'Starts the agent in ACP mode',
- })
- .option('allowed-mcp-server-names', {
- type: 'array',
- string: true,
- description: 'Allowed MCP server names',
- })
- .option('extensions', {
- alias: 'e',
- type: 'array',
- string: true,
- description:
- 'A list of extensions to use. If not provided, all extensions are used.',
- })
- .option('list-extensions', {
- alias: 'l',
- type: 'boolean',
- description: 'List all available extensions and exit.',
- })
- .option('ide-mode-feature', {
- type: 'boolean',
- description: 'Run in IDE mode?',
- })
- .option('proxy', {
- type: 'string',
- description:
- 'Proxy for gemini client, like schema://user:password@host:port',
- })
- .option('include-directories', {
- type: 'array',
- string: true,
- description:
- 'Additional directories to include in the workspace (comma-separated or multiple --include-directories)',
- coerce: (dirs: string[]) =>
- // Handle comma-separated values
- dirs.flatMap((dir) => dir.split(',').map((d) => d.trim())),
- })
- .option('load-memory-from-include-directories', {
- type: 'boolean',
- description:
- 'If true, when refreshing memory, GEMINI.md files should be loaded from all directories that are added. If false, GEMINI.md files should only be loaded from the primary working directory.',
- default: false,
- })
+ // Register MCP subcommands
+ .command(mcpCommand)
.version(await getCliVersion()) // This will enable the --version flag based on package.json
.alias('v', 'version')
.help()
.alias('h', 'help')
.strict()
- .check((argv) => {
- if (argv.prompt && argv.promptInteractive) {
- throw new Error(
- 'Cannot use both --prompt (-p) and --prompt-interactive (-i) together',
- );
- }
- return true;
- });
+ .demandCommand(0, 0); // Allow base command to run with no subcommands
yargsInstance.wrap(yargsInstance.terminalWidth());
- const result = yargsInstance.parseSync();
+ const result = await yargsInstance.parse();
+
+ // Handle case where MCP subcommands are executed - they should exit the process
+ // and not return to main CLI logic
+ if (result._.length > 0 && result._[0] === 'mcp') {
+ // MCP commands handle their own execution and process exit
+ process.exit(0);
+ }
// The import format is now only controlled by settings.memoryImportFormat
// We no longer accept it as a CLI argument
- return result as CliArgs;
+ return result as unknown as CliArgs;
}
// This function is now a thin wrapper around the server's implementation.