AI Automation & Agents  

How to build a custom extension (plugin) for Gemini CLI?

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:

  • Add domain knowledge (internal docs, API reference)

  • Expose custom tools via MCP (Model Context Protocol) for the agent to call

  • Provide prebuilt prompts, flows, and slash commands for common tasks

  • Ship integrations for your product (databases, monitoring, cloud services)

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

  • Decide what your extension will add: tools, prompts, commands, or a combination.

  • Identify side effects: will tools write to systems, modify infra, or send emails?

  • Determine auth: how will the MCP server authenticate requests (API keys, OAuth, Workload Identity Federation)?

Step 2 — Scaffold repo

Create a GitHub repo with:

  • gemini-extension.json

  • GEMINI.md

  • mcp/ (MCP server code)

  • prompts/ directory with example prompts

  • README.md describing install/use

Step 3 — Implement MCP server

  • Expose a manifest endpoint (/mcp/manifest or as required by your MCP implementation).

  • Implement run endpoints for tools (/mcp/run/<tool_name>).

  • Include an OpenAPI-style description for tools (input/output schemas).

  • Add authentication hooks.

Step 4 — Add extension manifest and docs

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

  • How to set environment variables

  • Required Google Cloud / provider roles (if any)

  • Security considerations

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

  • Unit tests for MCP server tool handlers (simulate inputs/outputs).

  • Integration tests that spin up a local MCP server and assert Gemini CLI can discover tools (or mock Gemini UI responses).

  • Security scanning for dependencies.

  • Add a GitHub Action that builds, tests, and optionally publishes a release artifact.

Step 8 — Packaging & release

  • Use semantic versioning.

  • Publish to GitHub with release notes.

  • Optionally register your extension with a public registry (if Gemini or community registry exists) or advertise via README.

Example: "TodoManager" extension (concise design)

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

Files:

  • gemini-extension.json — registers todo-mcp at URL https://mcp.example.com

  • GEMINI.md — includes sample prompts (e.g., “Create a todo to buy groceries for tomorrow”)

  • MCP server exposes tools:

    • create_todo(title, due_date, tags)

    • list_todos(filter)

    • complete_todo(id)

Operational notes:

  • Use JWTs for auth; provide setup in README to generate short-lived tokens.

  • Rate limits: 50 calls/minute.

  • Traces logged with OpenTelemetry for debugging.

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

  • Local MCP smoke test: Start the MCP server and curl the manifest endpoint to ensure tool definitions are correct.

  • Simulate tool calls: Hit /mcp/run/<tool> endpoints directly to verify outputs.

  • Use the Gemini CLI /mcp desc (or equivalent) to confirm the agent sees the tools.

  • Add verbose logging in MCP server to inspect incoming requests and returned payloads.

  • Write end-to-end tests that start Gemini CLI in a test harness (if possible) to validate flows.

  • Trace requests with OpenTelemetry and link traces back to GitHub actions for CI debugging.

UX & human guidance (GEMINI.md best practices)

  • Keep GEMINI.md short and structured: Purpose → Tools → Example prompts → Safety notes.

  • Provide canonical prompts that users can copy-paste. Example:

Prompt: "Create a new todo with title 'Buy groceries' due tomorrow and tag 'errand'. If created, reply with the todo id only."
  • Describe tool side effects and latency expectations (e.g., “This tool makes network calls and may take up to 2s”).

  • Include a “Troubleshooting” section for common installation and auth problems.

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

  • Public repos leaking secrets — use .env.example and secret stores.

  • Missing input schemas — tools without clear inputs cause hallucinations; use strict schemas.

  • No versioning — breaking changes will hurt adopters; follow semver.

  • Insufficient docs — poor on-boarding reduces installs; include quickstart and examples.

  • Unprotected side effects — always require confirmation or minimize autonomy for destructive actions.

Advanced ideas

  • Serverless MCP servers: deploy tool endpoints as Cloud Functions or Cloud Run with autoscaling.

  • Adapters for third-party models: let your extension route certain tool calls to alternative models.

  • Telemetry & metrics: collect usage data (which prompts, which tools used) for continuous improvement.

  • Multi-tenant MCP with per-team contexts: support multiple backends with tenant isolation.

  • Auto-generated SDKs: generate small SDKs for common languages to help teams call your MCP directly.

Quick checklist before releasing

  • gemini-extension.json complete and valid

  • GEMINI.md clear with example prompts

  • MCP server secure and authenticated

  • Unit + integration tests passing

  • CI builds and publishes artifacts/deploys

  • README includes installation and troubleshooting

  • Changelog and versioned releases

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:

  • A working Node.js MCP server (server.js)

  • A local JSON database (todos.json)

  • Full metadata (gemini-extension.json)

  • Integration instructions in README.md

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