or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mdconfiguration.mdextensions.mdindex.mdinteractive-commands.mdmcp-integration.mdthemes.md

extensions.mddocs/

0

# Extension System

1

2

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.

3

4

## Capabilities

5

6

### Extension Structure

7

8

Extensions are directory-based packages with a manifest file and optional context files.

9

10

```bash { .api }

11

extension-name/

12

├── gemini-extension.json # Extension manifest (required)

13

├── GEMINI.md # Default context file

14

└── [additional files] # Any other extension files

15

```

16

17

### Extension Manifest

18

19

Every extension must include a `gemini-extension.json` manifest file.

20

21

```typescript { .api }

22

interface ExtensionConfig {

23

/** Extension name (must match directory name) */

24

name: string;

25

26

/** Semantic version */

27

version: string;

28

29

/** Context file name(s) to load */

30

contextFileName?: string | string[];

31

32

/** MCP servers provided by this extension */

33

mcpServers?: Record<string, MCPServerConfig>;

34

35

/** Tools to exclude when this extension is active */

36

excludeTools?: string[];

37

}

38

```

39

40

**Usage Examples:**

41

42

```json

43

{

44

"name": "weather-extension",

45

"version": "1.2.0",

46

"contextFileName": "WEATHER.md",

47

"mcpServers": {

48

"weather-api": {

49

"command": "node",

50

"args": ["{{extensionPath}}/weather-server.js"],

51

"description": "Weather data provider"

52

}

53

},

54

"excludeTools": ["web_search"]

55

}

56

```

57

58

### Extension Types

59

60

Extensions can be installed in different locations depending on their scope and trust level.

61

62

```typescript { .api }

63

enum ExtensionType {

64

/** User extensions in ~/.gemini/extensions/ */

65

User = 'user',

66

67

/** Workspace extensions in project directory (when folder trusted) */

68

Workspace = 'workspace',

69

70

/** Development extensions via symlink */

71

Linked = 'linked'

72

}

73

74

interface Extension {

75

/** Full path to extension directory */

76

path: string;

77

78

/** Extension configuration from manifest */

79

config: ExtensionConfig;

80

81

/** List of context files to load */

82

contextFiles: string[];

83

84

/** Installation metadata (for installed extensions) */

85

installMetadata?: ExtensionInstallMetadata;

86

}

87

```

88

89

### Variable Substitution

90

91

Extensions support variable substitution in configuration values:

92

93

```typescript { .api }

94

interface ExtensionVariables {

95

/** Path to the extension directory */

96

'{{extensionPath}}': string;

97

98

/** Platform-specific path separator */

99

'{{/}}': string;

100

'{{pathSeparator}}': string;

101

102

/** Environment variables */

103

'{{ENV_VAR_NAME}}': string;

104

}

105

```

106

107

**Usage Examples:**

108

109

```json

110

{

111

"mcpServers": {

112

"local-server": {

113

"command": "python",

114

"args": ["{{extensionPath}}/server.py"],

115

"env": {

116

"DATA_PATH": "{{extensionPath}}/data",

117

"API_KEY": "{{API_KEY}}"

118

}

119

}

120

}

121

}

122

```

123

124

## Extension Management API

125

126

### Loading Extensions

127

128

```typescript { .api }

129

/**

130

* Load all available extensions from user and workspace directories

131

* @param workspaceDir - Optional workspace directory to scan

132

* @returns Array of loaded extensions

133

*/

134

function loadExtensions(workspaceDir?: string): Extension[];

135

136

/**

137

* Load extension configuration from directory

138

* @param extensionPath - Path to extension directory

139

* @returns Extension configuration or null if invalid

140

*/

141

function loadExtensionConfig(extensionPath: string): Extension | null;

142

```

143

144

### Installing Extensions

145

146

```typescript { .api }

147

interface ExtensionInstallMetadata {

148

/** Installation source (URL, path, etc.) */

149

source: string;

150

151

/** Installation method */

152

method: 'git' | 'local' | 'npm' | 'download';

153

154

/** Installation timestamp */

155

installedAt: string;

156

157

/** Installed version */

158

version: string;

159

160

/** Installation scope */

161

scope: 'user' | 'workspace';

162

}

163

164

/**

165

* Install extension from various sources

166

* @param installMetadata - Installation information

167

* @param cwd - Optional working directory

168

* @returns Path to installed extension

169

*/

170

function installExtension(

171

installMetadata: ExtensionInstallMetadata,

172

cwd?: string

173

): Promise<string>;

174

```

175

176

**Usage Examples:**

177

178

```typescript

179

// Install from GitHub repository

180

await installExtension({

181

source: 'https://github.com/user/gemini-weather-ext',

182

method: 'git',

183

scope: 'user'

184

});

185

186

// Install from local directory

187

await installExtension({

188

source: './my-extension',

189

method: 'local',

190

scope: 'workspace'

191

});

192

193

// Install from npm package

194

await installExtension({

195

source: 'gemini-ext-calculator',

196

method: 'npm',

197

scope: 'user'

198

});

199

```

200

201

### Managing Extensions

202

203

```typescript { .api }

204

/**

205

* Uninstall extension by name

206

* @param extensionName - Name of extension to remove

207

* @param cwd - Optional working directory

208

*/

209

function uninstallExtension(

210

extensionName: string,

211

cwd?: string

212

): Promise<void>;

213

214

interface ExtensionUpdateInfo {

215

/** Extension that was updated */

216

extension: Extension;

217

218

/** Previous version */

219

previousVersion: string;

220

221

/** New version */

222

newVersion: string;

223

224

/** Whether update was successful */

225

success: boolean;

226

227

/** Error message if update failed */

228

error?: string;

229

}

230

231

/**

232

* Update extension to latest version

233

* @param extension - Extension to update

234

* @param cwd - Optional working directory

235

* @returns Update result information

236

*/

237

function updateExtension(

238

extension: Extension,

239

cwd?: string

240

): Promise<ExtensionUpdateInfo>;

241

242

/**

243

* Enable extension in specified scopes

244

* @param name - Extension name

245

* @param scopes - Setting scopes where extension should be enabled

246

*/

247

function enableExtension(

248

name: string,

249

scopes: SettingScope[]

250

): void;

251

252

/**

253

* Disable extension in specified scope

254

* @param name - Extension name

255

* @param scope - Setting scope to disable extension in

256

* @param cwd - Optional working directory

257

*/

258

function disableExtension(

259

name: string,

260

scope: SettingScope,

261

cwd?: string

262

): void;

263

```

264

265

### Development Extensions

266

267

```typescript { .api }

268

/**

269

* Link local extension for development

270

* Creates symlink to enable live development

271

* @param extensionPath - Path to local extension directory

272

* @param cwd - Optional working directory

273

*/

274

function linkExtension(

275

extensionPath: string,

276

cwd?: string

277

): Promise<void>;

278

279

/**

280

* Create new extension template

281

* @param extensionName - Name for new extension

282

* @param options - Template options

283

*/

284

function createExtensionTemplate(

285

extensionName: string,

286

options: {

287

includeServer?: boolean;

288

language?: 'typescript' | 'javascript' | 'python';

289

template?: 'minimal' | 'full';

290

}

291

): Promise<string>;

292

```

293

294

## Extension Integration

295

296

### Context Loading

297

298

Extensions can provide context files that are automatically loaded:

299

300

```typescript { .api }

301

interface ContextFile {

302

/** File path */

303

path: string;

304

305

/** File content */

306

content: string;

307

308

/** Source extension */

309

extensionName: string;

310

}

311

312

/**

313

* Load context files from all active extensions

314

* @param extensions - Active extensions

315

* @returns Array of context files

316

*/

317

function loadExtensionContextFiles(

318

extensions: Extension[]

319

): Promise<ContextFile[]>;

320

```

321

322

### MCP Server Integration

323

324

Extensions can provide MCP servers that integrate with the tool system:

325

326

```typescript { .api }

327

/**

328

* Merge MCP servers from extensions with user settings

329

* @param settings - Current settings

330

* @param extensions - Active extensions

331

* @returns Combined MCP server configuration

332

*/

333

function mergeMcpServers(

334

settings: Settings,

335

extensions: Extension[]

336

): Record<string, MCPServerConfig>;

337

338

/**

339

* Filter allowed MCP servers based on settings

340

* @param mcpServers - All available MCP servers

341

* @param settings - Current settings

342

* @returns Filtered server configuration

343

*/

344

function allowedMcpServers(

345

mcpServers: Record<string, MCPServerConfig>,

346

settings: Settings

347

): Record<string, MCPServerConfig>;

348

```

349

350

## Extension Configuration

351

352

### User Settings Integration

353

354

Extensions can be configured through the settings system:

355

356

```typescript { .api }

357

interface ExtensionSettings {

358

/** Globally disabled extensions */

359

disabled?: string[];

360

361

/** Extension-specific configuration */

362

config?: Record<string, Record<string, any>>;

363

}

364

```

365

366

**Usage Examples:**

367

368

```json

369

{

370

"extensions": {

371

"disabled": ["old-extension"],

372

"config": {

373

"weather-extension": {

374

"defaultLocation": "San Francisco",

375

"units": "metric"

376

}

377

}

378

}

379

}

380

```

381

382

### Extension Validation

383

384

```typescript { .api }

385

interface ExtensionValidation {

386

/** Validation result */

387

valid: boolean;

388

389

/** Validation errors */

390

errors: string[];

391

392

/** Validation warnings */

393

warnings: string[];

394

395

/** Missing dependencies */

396

missingDependencies?: string[];

397

}

398

399

/**

400

* Validate extension configuration

401

* @param extension - Extension to validate

402

* @returns Validation results

403

*/

404

function validateExtension(

405

extension: Extension

406

): Promise<ExtensionValidation>;

407

```

408

409

## Extension CLI Commands

410

411

### Extension Management Commands

412

413

```bash { .api }

414

gemini extensions install <source> # Install extension from source

415

gemini extensions uninstall <name> # Remove extension by name

416

gemini extensions list # Show installed extensions

417

gemini extensions update [name] # Update extension(s)

418

gemini extensions enable <name> # Enable extension

419

gemini extensions disable <name> # Disable extension

420

gemini extensions link <path> # Link local extension for development

421

gemini extensions new <name> # Create new extension template

422

```

423

424

### Installation Sources

425

426

Extensions can be installed from various sources:

427

428

```bash

429

# GitHub repository

430

gemini extensions install https://github.com/user/gemini-ext-weather

431

432

# Local directory

433

gemini extensions install ./my-extension

434

435

# npm package (if supported)

436

gemini extensions install npm:gemini-ext-calculator

437

438

# Archive URL

439

gemini extensions install https://example.com/extension.zip

440

```

441

442

## Extension Development

443

444

### Minimal Extension Example

445

446

```json

447

{

448

"name": "hello-world",

449

"version": "1.0.0",

450

"contextFileName": "HELLO.md"

451

}

452

```

453

454

```markdown

455

<!-- HELLO.md -->

456

# Hello World Extension

457

458

This extension provides a simple greeting capability.

459

460

## Commands Available

461

462

Use "hello" to get a friendly greeting.

463

```

464

465

### Advanced Extension with MCP Server

466

467

```json

468

{

469

"name": "file-processor",

470

"version": "2.1.0",

471

"contextFileName": ["PROCESSOR.md", "EXAMPLES.md"],

472

"mcpServers": {

473

"file-processor": {

474

"command": "python",

475

"args": ["{{extensionPath}}/processor_server.py"],

476

"env": {

477

"PROCESSOR_CONFIG": "{{extensionPath}}/config.json"

478

},

479

"description": "Advanced file processing tools",

480

"includeTools": ["process_file", "batch_process"],

481

"trust": false

482

}

483

},

484

"excludeTools": ["basic_file_edit"]

485

}

486

```

487

488

### Extension Templates

489

490

The CLI provides templates for common extension patterns:

491

492

```bash

493

# Create minimal extension

494

gemini extensions new my-extension --template minimal

495

496

# Create full-featured extension with MCP server

497

gemini extensions new my-server --template full --language typescript

498

499

# Create Python-based extension

500

gemini extensions new py-tools --language python

501

```

502

503

## Error Handling and Debugging

504

505

### Extension Loading Errors

506

507

```typescript { .api }

508

interface ExtensionError {

509

/** Extension name or path */

510

extension: string;

511

512

/** Error type */

513

type: 'load' | 'validate' | 'install' | 'mcp';

514

515

/** Error message */

516

message: string;

517

518

/** Suggested resolution */

519

suggestion?: string;

520

}

521

```

522

523

### Debug Information

524

525

Extensions include debug information for troubleshooting:

526

527

```typescript { .api }

528

interface ExtensionDebugInfo {

529

/** Extension metadata */

530

extension: Extension;

531

532

/** Context files loaded */

533

contextFiles: string[];

534

535

/** MCP servers started */

536

mcpServers: string[];

537

538

/** Variables resolved */

539

resolvedVariables: Record<string, string>;

540

541

/** Load time metrics */

542

loadTime: number;

543

}

544

```