Open-source AI agent providing terminal access to Gemini models with extensible tool support and developer-focused features
The Gemini CLI provides a comprehensive plugin architecture that enables custom functionality through extensions and integrates with the Model Context Protocol (MCP) for external tool connectivity.
Extensions are directory-based packages with a manifest file and optional context files.
extension-name/
├── gemini-extension.json # Extension manifest (required)
├── GEMINI.md # Default context file
└── [additional files] # Any other extension filesEvery extension must include a gemini-extension.json manifest file.
interface ExtensionConfig {
/** Extension name (must match directory name) */
name: string;
/** Semantic version */
version: string;
/** Context file name(s) to load */
contextFileName?: string | string[];
/** MCP servers provided by this extension */
mcpServers?: Record<string, MCPServerConfig>;
/** Tools to exclude when this extension is active */
excludeTools?: string[];
}Usage Examples:
{
"name": "weather-extension",
"version": "1.2.0",
"contextFileName": "WEATHER.md",
"mcpServers": {
"weather-api": {
"command": "node",
"args": ["{{extensionPath}}/weather-server.js"],
"description": "Weather data provider"
}
},
"excludeTools": ["web_search"]
}Extensions can be installed in different locations depending on their scope and trust level.
enum ExtensionType {
/** User extensions in ~/.gemini/extensions/ */
User = 'user',
/** Workspace extensions in project directory (when folder trusted) */
Workspace = 'workspace',
/** Development extensions via symlink */
Linked = 'linked'
}
interface Extension {
/** Full path to extension directory */
path: string;
/** Extension configuration from manifest */
config: ExtensionConfig;
/** List of context files to load */
contextFiles: string[];
/** Installation metadata (for installed extensions) */
installMetadata?: ExtensionInstallMetadata;
}Extensions support variable substitution in configuration values:
interface ExtensionVariables {
/** Path to the extension directory */
'{{extensionPath}}': string;
/** Platform-specific path separator */
'{{/}}': string;
'{{pathSeparator}}': string;
/** Environment variables */
'{{ENV_VAR_NAME}}': string;
}Usage Examples:
{
"mcpServers": {
"local-server": {
"command": "python",
"args": ["{{extensionPath}}/server.py"],
"env": {
"DATA_PATH": "{{extensionPath}}/data",
"API_KEY": "{{API_KEY}}"
}
}
}
}/**
* Load all available extensions from user and workspace directories
* @param workspaceDir - Optional workspace directory to scan
* @returns Array of loaded extensions
*/
function loadExtensions(workspaceDir?: string): Extension[];
/**
* Load extension configuration from directory
* @param extensionPath - Path to extension directory
* @returns Extension configuration or null if invalid
*/
function loadExtensionConfig(extensionPath: string): Extension | null;interface ExtensionInstallMetadata {
/** Installation source (URL, path, etc.) */
source: string;
/** Installation method */
method: 'git' | 'local' | 'npm' | 'download';
/** Installation timestamp */
installedAt: string;
/** Installed version */
version: string;
/** Installation scope */
scope: 'user' | 'workspace';
}
/**
* Install extension from various sources
* @param installMetadata - Installation information
* @param cwd - Optional working directory
* @returns Path to installed extension
*/
function installExtension(
installMetadata: ExtensionInstallMetadata,
cwd?: string
): Promise<string>;Usage Examples:
// Install from GitHub repository
await installExtension({
source: 'https://github.com/user/gemini-weather-ext',
method: 'git',
scope: 'user'
});
// Install from local directory
await installExtension({
source: './my-extension',
method: 'local',
scope: 'workspace'
});
// Install from npm package
await installExtension({
source: 'gemini-ext-calculator',
method: 'npm',
scope: 'user'
});/**
* Uninstall extension by name
* @param extensionName - Name of extension to remove
* @param cwd - Optional working directory
*/
function uninstallExtension(
extensionName: string,
cwd?: string
): Promise<void>;
interface ExtensionUpdateInfo {
/** Extension that was updated */
extension: Extension;
/** Previous version */
previousVersion: string;
/** New version */
newVersion: string;
/** Whether update was successful */
success: boolean;
/** Error message if update failed */
error?: string;
}
/**
* Update extension to latest version
* @param extension - Extension to update
* @param cwd - Optional working directory
* @returns Update result information
*/
function updateExtension(
extension: Extension,
cwd?: string
): Promise<ExtensionUpdateInfo>;
/**
* Enable extension in specified scopes
* @param name - Extension name
* @param scopes - Setting scopes where extension should be enabled
*/
function enableExtension(
name: string,
scopes: SettingScope[]
): void;
/**
* Disable extension in specified scope
* @param name - Extension name
* @param scope - Setting scope to disable extension in
* @param cwd - Optional working directory
*/
function disableExtension(
name: string,
scope: SettingScope,
cwd?: string
): void;/**
* Link local extension for development
* Creates symlink to enable live development
* @param extensionPath - Path to local extension directory
* @param cwd - Optional working directory
*/
function linkExtension(
extensionPath: string,
cwd?: string
): Promise<void>;
/**
* Create new extension template
* @param extensionName - Name for new extension
* @param options - Template options
*/
function createExtensionTemplate(
extensionName: string,
options: {
includeServer?: boolean;
language?: 'typescript' | 'javascript' | 'python';
template?: 'minimal' | 'full';
}
): Promise<string>;Extensions can provide context files that are automatically loaded:
interface ContextFile {
/** File path */
path: string;
/** File content */
content: string;
/** Source extension */
extensionName: string;
}
/**
* Load context files from all active extensions
* @param extensions - Active extensions
* @returns Array of context files
*/
function loadExtensionContextFiles(
extensions: Extension[]
): Promise<ContextFile[]>;Extensions can provide MCP servers that integrate with the tool system:
/**
* Merge MCP servers from extensions with user settings
* @param settings - Current settings
* @param extensions - Active extensions
* @returns Combined MCP server configuration
*/
function mergeMcpServers(
settings: Settings,
extensions: Extension[]
): Record<string, MCPServerConfig>;
/**
* Filter allowed MCP servers based on settings
* @param mcpServers - All available MCP servers
* @param settings - Current settings
* @returns Filtered server configuration
*/
function allowedMcpServers(
mcpServers: Record<string, MCPServerConfig>,
settings: Settings
): Record<string, MCPServerConfig>;Extensions can be configured through the settings system:
interface ExtensionSettings {
/** Globally disabled extensions */
disabled?: string[];
/** Extension-specific configuration */
config?: Record<string, Record<string, any>>;
}Usage Examples:
{
"extensions": {
"disabled": ["old-extension"],
"config": {
"weather-extension": {
"defaultLocation": "San Francisco",
"units": "metric"
}
}
}
}interface ExtensionValidation {
/** Validation result */
valid: boolean;
/** Validation errors */
errors: string[];
/** Validation warnings */
warnings: string[];
/** Missing dependencies */
missingDependencies?: string[];
}
/**
* Validate extension configuration
* @param extension - Extension to validate
* @returns Validation results
*/
function validateExtension(
extension: Extension
): Promise<ExtensionValidation>;gemini extensions install <source> # Install extension from source
gemini extensions uninstall <name> # Remove extension by name
gemini extensions list # Show installed extensions
gemini extensions update [name] # Update extension(s)
gemini extensions enable <name> # Enable extension
gemini extensions disable <name> # Disable extension
gemini extensions link <path> # Link local extension for development
gemini extensions new <name> # Create new extension templateExtensions can be installed from various sources:
# GitHub repository
gemini extensions install https://github.com/user/gemini-ext-weather
# Local directory
gemini extensions install ./my-extension
# npm package (if supported)
gemini extensions install npm:gemini-ext-calculator
# Archive URL
gemini extensions install https://example.com/extension.zip{
"name": "hello-world",
"version": "1.0.0",
"contextFileName": "HELLO.md"
}<!-- HELLO.md -->
# Hello World Extension
This extension provides a simple greeting capability.
## Commands Available
Use "hello" to get a friendly greeting.{
"name": "file-processor",
"version": "2.1.0",
"contextFileName": ["PROCESSOR.md", "EXAMPLES.md"],
"mcpServers": {
"file-processor": {
"command": "python",
"args": ["{{extensionPath}}/processor_server.py"],
"env": {
"PROCESSOR_CONFIG": "{{extensionPath}}/config.json"
},
"description": "Advanced file processing tools",
"includeTools": ["process_file", "batch_process"],
"trust": false
}
},
"excludeTools": ["basic_file_edit"]
}The CLI provides templates for common extension patterns:
# Create minimal extension
gemini extensions new my-extension --template minimal
# Create full-featured extension with MCP server
gemini extensions new my-server --template full --language typescript
# Create Python-based extension
gemini extensions new py-tools --language pythoninterface ExtensionError {
/** Extension name or path */
extension: string;
/** Error type */
type: 'load' | 'validate' | 'install' | 'mcp';
/** Error message */
message: string;
/** Suggested resolution */
suggestion?: string;
}Extensions include debug information for troubleshooting:
interface ExtensionDebugInfo {
/** Extension metadata */
extension: Extension;
/** Context files loaded */
contextFiles: string[];
/** MCP servers started */
mcpServers: string[];
/** Variables resolved */
resolvedVariables: Record<string, string>;
/** Load time metrics */
loadTime: number;
}Install with Tessl CLI
npx tessl i tessl/npm-google--gemini-cli