2026-02-17 13:57:27 -08:00
# Build Gemini CLI extensions
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
Gemini CLI extensions let you expand the capabilities of Gemini CLI by adding
custom tools, commands, and context. This guide walks you through creating your
first extension, from setting up a template to adding custom functionality and
linking it for local development.
2025-09-25 20:01:49 -04:00
## Prerequisites
2026-02-17 13:57:27 -08:00
Before you start, ensure you have the Gemini CLI installed and a basic
2026-01-26 15:14:38 -05:00
understanding of Node.js.
2026-02-17 13:57:27 -08:00
## Extension features
2026-01-26 15:14:38 -05:00
2026-02-17 13:57:27 -08:00
Extensions offer several ways to customize Gemini CLI. Use this table to decide
which features your extension needs.
2026-01-26 15:14:38 -05:00
| Feature | What it is | When to use it | Invoked by |
| :------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------- |
| * * [MCP server ](reference.md#mcp-servers )** | A standard way to expose new tools and data sources to the model. | Use this when you want the model to be able to _ do _ new things, like fetching data from an internal API, querying a database, or controlling a local application. We also support MCP resources (which can replace custom commands) and system instructions (which can replace custom context) | Model |
| * * [Custom commands ](../cli/custom-commands.md )** | A shortcut (like `/my-cmd` ) that executes a pre-defined prompt or shell command. | Use this for repetitive tasks or to save long, complex prompts that you use frequently. Great for automation. | User |
| * * [Context file (`GEMINI.md`) ](reference.md#contextfilename )** | A markdown file containing instructions that are loaded into the model's context at the start of every session. | Use this to define the "personality" of your extension, set coding standards, or provide essential knowledge that the model should always have. | CLI provides to model |
| * * [Agent skills ](../cli/skills.md )** | A specialized set of instructions and workflows that the model activates only when needed. | Use this for complex, occasional tasks (like "create a PR" or "audit security") to avoid cluttering the main context window when the skill isn't being used. | Model |
| * * [Hooks ](../hooks/index.md )** | A way to intercept and customize the CLI's behavior at specific lifecycle events (e.g., before/after a tool call). | Use this when you want to automate actions based on what the model is doing, like validating tool arguments, logging activity, or modifying the model's input/output. | CLI |
2026-02-16 14:58:48 -05:00
| * * [Custom themes ](reference.md#themes )** | A set of color definitions to personalize the CLI UI. | Use this to provide a unique visual identity for your extension or to offer specialized high-contrast or thematic color schemes. | User (via /theme) |
2025-09-25 20:01:49 -04:00
2025-12-01 11:38:48 -08:00
## Step 1: Create a new extension
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
The easiest way to start is by using a built-in template. We'll use the
`mcp-server` example as our foundation.
2025-09-25 20:01:49 -04:00
2025-10-09 08:17:37 -04:00
Run the following command to create a new directory called `my-first-extension`
with the template files:
2025-09-25 20:01:49 -04:00
```bash
gemini extensions new my-first-extension mcp-server
```
2026-02-17 13:57:27 -08:00
This creates a directory with the following structure:
2025-09-25 20:01:49 -04:00
```
my-first-extension/
2026-01-26 15:14:38 -05:00
├── example.js
2025-09-25 20:01:49 -04:00
├── gemini-extension.json
2026-01-26 15:14:38 -05:00
└── package.json
2025-09-25 20:01:49 -04:00
```
2025-12-01 11:38:48 -08:00
## Step 2: Understand the extension files
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
Your new extension contains several key files that define its behavior.
2025-09-25 20:01:49 -04:00
### `gemini-extension.json`
2026-02-17 13:57:27 -08:00
The manifest file tells Gemini CLI how to load and use your extension.
2025-09-25 20:01:49 -04:00
```json
{
2026-01-26 15:14:38 -05:00
"name": "mcp-server-example",
2025-09-25 20:01:49 -04:00
"version": "1.0.0",
"mcpServers": {
"nodeServer": {
"command": "node",
2026-01-26 15:14:38 -05:00
"args": ["${extensionPath}${/}example.js"],
2025-09-25 20:01:49 -04:00
"cwd": "${extensionPath}"
}
}
}
```
- `name` : The unique name for your extension.
- `version` : The version of your extension.
2026-02-17 13:57:27 -08:00
- `mcpServers` : Defines Model Context Protocol (MCP) servers to add new tools.
- `command` , `args` , `cwd` : Specify how to start your server. The
`${extensionPath}` variable is replaced with the absolute path to your
extension's directory.
2025-09-25 20:01:49 -04:00
2026-01-26 15:14:38 -05:00
### `example.js`
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
This file contains the source code for your MCP server. It uses the
`@modelcontextprotocol/sdk` to define tools.
2025-09-25 20:01:49 -04:00
2026-01-26 15:14:38 -05:00
```javascript
2025-09-25 20:01:49 -04:00
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp .js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio .js';
import { z } from 'zod';
const server = new McpServer({
name: 'prompt-server',
version: '1.0.0',
});
// Registers a new tool named 'fetch_posts'
server.registerTool(
'fetch_posts',
{
description: 'Fetches a list of posts from a public API.',
inputSchema: z.object({}).shape,
},
async () => {
const apiResponse = await fetch(
'https://jsonplaceholder.typicode.com/posts',
);
const posts = await apiResponse.json();
const response = { posts: posts.slice(0, 5) };
return {
content: [
{
type: 'text',
text: JSON.stringify(response),
},
],
};
},
);
const transport = new StdioServerTransport();
await server.connect(transport);
```
2026-01-26 15:14:38 -05:00
### `package.json`
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
The standard configuration file for a Node.js project. It defines dependencies
and scripts for your extension.
## Step 3: Add extension settings
Some extensions need configuration, such as API keys or user preferences. Let's
add a setting for an API key.
1. Open `gemini-extension.json` .
2. Add a `settings` array to the configuration:
```json
{
"name": "mcp-server-example",
"version": "1.0.0",
"settings": [
{
"name": "API Key",
"description": "The API key for the service.",
"envVar": "MY_SERVICE_API_KEY",
"sensitive": true
}
],
"mcpServers": {
// ...
}
}
```
When a user installs this extension, Gemini CLI will prompt them to enter the
"API Key". The value will be stored securely in the system keychain (because
`sensitive` is true) and injected into the MCP server's process as the
`MY_SERVICE_API_KEY` environment variable.
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
## Step 4: Link your extension
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
Link your extension to your Gemini CLI installation for local development.
2025-09-25 20:01:49 -04:00
1. **Install dependencies: **
```bash
cd my-first-extension
npm install
```
2026-01-26 15:14:38 -05:00
2. **Link the extension: **
2025-09-25 20:01:49 -04:00
2025-10-09 08:17:37 -04:00
The `link` command creates a symbolic link from the Gemini CLI extensions
2026-02-17 13:57:27 -08:00
directory to your development directory. Changes you make are reflected
immediately.
2025-09-25 20:01:49 -04:00
```bash
gemini extensions link .
```
2026-02-17 13:57:27 -08:00
Restart your Gemini CLI session to use the new `fetch_posts` tool. Test it by
asking: "fetch posts".
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
## Step 5: Add a custom command
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
Custom commands create shortcuts for complex prompts.
2025-09-25 20:01:49 -04:00
1. Create a `commands` directory and a subdirectory for your command group:
```bash
mkdir -p commands/fs
```
2. Create a file named `commands/fs/grep-code.toml` :
```toml
prompt = """
Please summarize the findings for the pattern `{{args}}` .
Search Results:
!{grep -r {{args}} .}
"""
```
2026-02-17 13:57:27 -08:00
This command, `/fs:grep-code` , takes an argument, runs the `grep` shell
command, and pipes the results into a prompt for summarization.
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
After saving the file, restart Gemini CLI. Run `/fs:grep-code "some pattern"` to
use your new command.
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
## Step 6: Add a custom `GEMINI.md`
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
Provide persistent context to the model by adding a `GEMINI.md` file to your
extension. This is useful for setting behavior or providing essential tool
information.
2025-09-25 20:01:49 -04:00
1. Create a file named `GEMINI.md` in the root of your extension directory:
```markdown
# My First Extension Instructions
2025-10-09 08:17:37 -04:00
You are an expert developer assistant. When the user asks you to fetch
posts, use the `fetch_posts` tool. Be concise in your responses.
2025-09-25 20:01:49 -04:00
```
2026-02-17 13:57:27 -08:00
2. Update your `gemini-extension.json` to load this file:
2025-09-25 20:01:49 -04:00
```json
{
"name": "my-first-extension",
"version": "1.0.0",
"contextFileName": "GEMINI.md",
"mcpServers": {
"nodeServer": {
"command": "node",
2026-01-26 15:14:38 -05:00
"args": ["${extensionPath}${/}example.js"],
2025-09-25 20:01:49 -04:00
"cwd": "${extensionPath}"
}
}
}
```
2026-02-17 13:57:27 -08:00
Restart Gemini CLI. The model now has the context from your `GEMINI.md` file in
every session where the extension is active.
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
## (Optional) Step 7: Add an Agent Skill
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
[Agent Skills ](../cli/skills.md ) bundle specialized expertise and workflows.
Skills are activated only when needed, which saves context tokens.
2026-01-16 11:37:28 -08:00
1. Create a `skills` directory and a subdirectory for your skill:
```bash
mkdir -p skills/security-audit
```
2. Create a `skills/security-audit/SKILL.md` file:
```markdown
---
name: security-audit
description:
Expertise in auditing code for security vulnerabilities. Use when the user
asks to "check for security issues" or "audit" their changes.
---
# Security Auditor
You are an expert security researcher. When auditing code:
1. Look for common vulnerabilities (OWASP Top 10).
2. Check for hardcoded secrets or API keys.
3. Suggest remediation steps for any findings.
```
2026-02-17 13:57:27 -08:00
Gemini CLI automatically discovers skills bundled with your extension. The model
activates them when it identifies a relevant task.
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
## Step 8: Release your extension
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
When your extension is ready, share it with others via a Git repository or
GitHub Releases. Refer to the [Extension Releasing Guide ](./releasing.md ) for
detailed instructions and learn how to list your extension in the gallery.
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
## Next steps
2025-09-25 20:01:49 -04:00
2026-02-17 13:57:27 -08:00
- [Extension reference ](reference.md ): Deeply understand the extension format,
commands, and configuration.
- [Best practices ](best-practices.md ): Learn strategies for building great
extensions.