This article guides you end-to-end to design, develop, test, and publish a custom Gemini CLI extension. You’ll learn extension structure (gemini-extension.json, GEMINI.md), how to bundle MCP servers/tools, add custom slash commands, run a local MCP server for development, link and install your extension into Gemini CLI, best practices for security, testing, and distribution, plus a working example you can adapt.

Pre-requisite

Before diving into building your own custom extension for the Gemini CLI, make sure you’ve completed the Gemini CLI Hands-On Codelab. That guide walks you through the basics of installing the Gemini CLI, setting up your environment, and using core commands to interact with Gemini models. It’s essential groundwork—you’ll need that understanding to follow along as we extend the CLI’s functionality with custom plugins. Once you’re comfortable running Gemini from the command line and understand how its command structure works, you’ll be ready to move on to creating your own extension.

Why build a Gemini CLI extension?

Gemini CLI is an open-source AI agent that runs in your terminal. Extensions are packaged add-ons that let Gemini CLI understand and interact with your specific tools, APIs, and domains. Use cases:

An extension makes your workflows reproducible and shareable across teams — instead of configuring settings manually, a single repo installs everything.

High-level architecture

A Gemini CLI extension typically bundles:

  1. gemini-extension.json — manifest describing the extension, MCP servers, commands, versioning, and install instructions.

  2. GEMINI.md — optional human + agent-facing guidance (context, recommended prompts, usage notes).

  3. One or more MCP servers (local or remote) — expose tools (APIs/actions/data) that the agent can invoke.

  4. Prompts / flows / example use cases — to speed onboarding.

  5. Optional UI or scripts (helper CLI commands) to aid devs.

At runtime, Gemini CLI reads the extension, registers MCP servers, makes tools discoverable to the agent, and adds slash commands and prompts to the CLI environment.

Anatomy of a minimal extension

1) gemini-extension.json (manifest)

A minimal manifest tells Gemini CLI where to find MCP servers, the extension name, version, and other metadata.

{
  "name": "example-org/gemini-extension-hello",
  "version": "0.1.0",
  "description": "Hello extension — exposes a sample MCP tool and demo prompts",
  "mcp_servers": [
    {
      "name": "hello-mcp",
      "url": "http://localhost:8080",
      "description": "Local MCP server exposing `say_hello` tool"
    }
  ],
  "commands": [
    {
      "name": "hello.run",
      "description": "Runs the hello flow",
      "usage": "gemini /hello.run"
    }
  ],
  "repository": "https://github.com/example-org/gemini-extension-hello"
}

2) GEMINI.md

This markdown file gives context that the agent uses (and that humans will read). Include example prompts, configuration notes, English descriptions of tools and side effects.

# Hello Extension

This extension exposes a `say_hello` tool for demo purposes.

## Example prompt for agent
> Use the `say_hello` tool if the user asks for a greeting. Provide concise greeting and ask a follow-up question.

## Tools
- `say_hello(name: string)` — returns a greeting string.

3) MCP server (tool provider)

MCP servers describe and expose tools via the Model Context Protocol. They run separately (can be local during dev or remote). They should provide a machine-readable tool manifest and endpoints for execution.

A tiny Node/Express + MCP pseudo-server (illustrative):

// server.js (very simplified pseudo code)
const express = require('express');
const app = express();
app.use(express.json());

app.get('/mcp/manifest', (req,res)=> {
  res.json({
    tools: [
      {
        name: "say_hello",
        description: "Return greeting for given name",
        inputs: [{name: "name", type: "string", required: true}]
      }
    ]
  });
});

app.post('/mcp/run/say_hello', (req,res) => {
  const {name} = req.body;
  res.json({result: `Hello, ${name}! 👋`});
});

app.listen(8080, ()=>console.log('MCP server running on 8080'));

Production MCP servers typically implement authentication, OpenTelemetry tracing, error handling, rate limiting, and provide a richer tool schema.

Step-by-step development workflow

Step 1 — Plan the extension

Step 2 — Scaffold repo

Create a GitHub repo with:

Step 3 — Implement MCP server

Step 4 — Add extension manifest and docs

Fill gemini-extension.json and GEMINI.md. Make docs clear about:

Step 5 — Local development: linking & testing

Gemini CLI usually supports a command to link a local extension (e.g., gemini extensions link ./path-to-extension), or you can install via the repo URL:

# Link a local extension for quick iteration
gemini extensions link ./my-extension

# OR install from GitHub
gemini extensions install https://github.com/your/repo

Restart Gemini CLI or reload extensions. Verify your MCP server is reachable and that tools appear using CLI commands like /mcp or /mcp desc.

Step 6 — Add custom slash commands (optional)

Your extension can register custom commands mapped to flows or helper scripts. For example, a hello.run command could trigger a flow that uses say_hello.

Define these in gemini-extension.json and ensure GEMINI.md documents usage.

Step 7 — Tests and CI

Step 8 — Packaging & release

Example: "TodoManager" extension (concise design)

Goal: Allow Gemini CLI to create, list, and complete todos stored in a backend.

Files:

Operational notes:

Security & governance

Extensions can invoke actions with side effects — follow these guardrails:

  1. Principle of least privilege: Give MCP servers only the permissions they need. Avoid embedding long-lived keys in public repos.

  2. Authentication: Use safe mechanisms (OAuth, short-lived JWTs, Workload Identity Federation) rather than hardcoded tokens.

  3. Consent & audit: If tools perform destructive actions (deployments, DB writes), require explicit human confirmation or an approval flow.

  4. Input validation: Never trust input from the agent. Validate schemas and sanitize strings before calling downstream systems.

  5. Rate limiting & circuit breakers: Protect downstream services from runaway agent behavior.

  6. Secrets management: Use environment variables and secret managers; avoid committing secrets to Git.

  7. Logging & observability: Log actions, include user context, and surface traces for debugging.

Testing & debugging tips

UX & human guidance (GEMINI.md best practices)

Prompt: "Create a new todo with title 'Buy groceries' due tomorrow and tag 'errand'. If created, reply with the todo id only."

Publishing & sharing

  1. Tag releases with semantic versions.

  2. Include install instructions in README:

# install from GitHub
gemini extensions install https://github.com/your-org/gemini-extension-todo
  1. Provide changelog and migration notes for breaking changes.

  2. Publish a demo or codelab (GitHub Pages, YouTube, blog) showing installation and sample flows.

  3. Consider registering the extension in any community registry or marketplace to increase discoverability.

Common pitfalls & how to avoid them

Advanced ideas

Quick checklist before releasing

Final thoughts

Gemini CLI extensions turn the terminal into a contextual, action-capable assistant that understands your product, APIs, and operational flows. Build extensions to speed developer onboarding, reduce manual steps, and create reproducible automation that’s discoverable by teams. Start small — expose a single safe, read-only tool (e.g., list_resources) — then iterate toward write-capable workflows once you’ve hardened auth and auditing.

Ready-to-download Gemini CLI extension project is attached.

This project includes:

You can unzip it, run npm install, and then npm start to start your Gemini CLI extension locally.