Gemini CLI Setup: GEMINI.md Context, MCP Servers, Extensions
Google's Gemini CLI is an open-source coding agent for the terminal. Three mechanisms decide what it knows and what it can do: context files (GEMINI.md), which give it instructions; MCP servers, which give it tools; and extensions, which package context, MCP servers, commands, and more into something you can install and share. This guide covers all three, following the project's own documentation in the google-gemini/gemini-cli repository, with the exact file locations, settings keys, and commands.
It replaces three shorter posts that covered these topics separately, some with commands that do not exist. For how Claude Code handles the same ideas (CLAUDE.md, MCP, plugins), see Claude Code Directory Structure; for MCP itself, see Claude Code MCP and Plugins.
Context files: how GEMINI.md is loaded
Context files, named GEMINI.md by default, hold instructions you would otherwise repeat in every prompt: conventions, commands, persona, style. The CLI loads them hierarchically, concatenates all of them, and sends the result with every prompt:
- Global:
~/.gemini/GEMINI.md, default instructions for every project. - Workspace:
GEMINI.mdfiles in your configured workspace directories and their parent directories. - Just-in-time: when a tool accesses a file or directory, the CLI scans that directory and its ancestors, up to a trusted root, for
GEMINI.mdfiles, so component-specific instructions load only when needed.
The footer shows how many context files are loaded. /memory show prints the full concatenated context, which is the fastest way to see what the model is actually told, and /memory reload rescans after you edit files.
Large context files can be split with imports: a line such as @./components/instructions.md inside GEMINI.md pulls another file in, with relative or absolute paths. If your repository already has an AGENTS.md for other agents, point Gemini CLI at it:
1{2 "context": {3 "fileName": ["AGENTS.md", "CONTEXT.md", "GEMINI.md"]4 }5}Quick reference
- Everything in context files costs tokens on every prompt, so keep them to what the model cannot infer from the code.
- Just-in-time loading means instructions for
packages/billing/can live inpackages/billing/GEMINI.mdand stay out of unrelated sessions. - The memory tool can also save persistent notes; check
/memory showto see what has accumulated.
Remember this
GEMINI.md files load globally, per workspace, and just in time; /memory show shows exactly what the model receives.
Pointing at files and keeping others out
Inside a prompt, @path shares a file or directory with the model, for example @src/auth/session.ts explain the token refresh. To keep paths out of that and other tools, add a .geminiignore file at the project root. It follows .gitignore conventions: # comments, globs (*, ?, []), a trailing / for directories, a leading / to anchor to the file's location, and ! to negate:
1# keep generated and secret files out2/dist/3apikeys.txt4*.md5!README.mdTwo limits from the docs are worth knowing. Paths in .geminiignore are excluded from tools that respect it, such as @ references; they are still visible to other services, so it is not an access control. And changes take effect only after you restart the session.
Quick reference
- Treat
.geminiignoreas noise reduction, not security. For secrets, keep them out of the working tree or use a sandbox. - Gemini CLI also has trusted folders and a sandbox mode for limiting what shell commands can touch; see its sandbox docs.
- Shell commands with
!(for example!npm test) run in your shell and their output can enter context; they are not filtered by.geminiignore.
Remember this
@path adds files deliberately; .geminiignore keeps paths out of supporting tools until the next restart, but it is not a security boundary.
MCP servers in settings.json
Gemini CLI connects to MCP servers listed under mcpServers in settings.json: the user file ~/.gemini/settings.json or the project file .gemini/settings.json. Each server needs one of command (stdio), url (SSE), or httpUrl (streamable HTTP):
1{2 "mcpServers": {3 "github": {4 "command": "npx",5 "args": ["-y", "@modelcontextprotocol/server-github"],6 "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "$GITHUB_TOKEN" },7 "timeout": 30000,8 "trust": false,9 "includeTools": ["get_issue", "list_pull_requests"]10 },11 "docs-search": {12 "httpUrl": "https://mcp.example.com/mcp/",13 "headers": { "Authorization": "Bearer $DOCS_TOKEN" }14 }15 }16}Or add them from the terminal, which writes the same settings (user or project scope with -s):
1gemini mcp add -e API_KEY=123 my-stdio-server /path/to/server arg12gemini mcp add --transport http docs-search https://mcp.example.com/mcp/In a session, /mcp lists connected servers with their tools, prompts, and resources. Discovered tools get fully qualified names in the form mcp_{serverName}_{toolName}.
Quick reference
envvalues can reference shell variables with$VARor${VAR}; an undefined variable becomes an empty string, so a missing token fails quietly.- The default request timeout is 600,000 ms (10 minutes); set
timeoutlower for servers that should fail fast. - Remote servers can use OAuth; the CLI discovers the authorisation server and runs the browser flow.
Remember this
Declare servers under mcpServers (or with gemini mcp add), pick one transport key, and pass only the env vars each server needs.
Limiting what MCP servers can do
An MCP server is third-party code with access to whatever you give it. Gemini CLI provides several controls:
- Tool filtering.
includeToolsis an allowlist for a server's tools;excludeToolsremoves tools and wins if a tool is in both. Expose only the tools a task needs. - Server allow and deny lists. The global
mcp.allowedandmcp.excludedsettings decide which configured servers connect at all. - Confirmations.
trustdefaults tofalse, so tool calls ask for confirmation. Settingtrust: truebypasses all confirmations for that server; reserve it for servers you wrote. - Environment redaction. When spawning servers, the CLI redacts sensitive variables inherited from your shell, such as
GEMINI_API_KEY,GOOGLE_API_KEY, and anything matching*TOKEN*,*SECRET*,*PASSWORD*,*KEY*,*AUTH*, or*CREDENTIAL*. A server receives a secret only if you list it explicitly in itsenv.
One naming rule matters for policies: do not use underscores in server names. The policy parser splits fully qualified names on the first underscore after mcp_, so my_server breaks wildcard rules silently; use my-server.
Quick reference
- Redaction protects against accidental leakage, not a malicious server you deliberately gave a token to.
- If two servers share a name and expose the same tool name, the last one registered overwrites the other.
- Permission rules for MCP tools are set in the CLI's policy engine, which has special syntax for MCP names.
Remember this
Allowlist tools, keep trust off for third-party servers, pass secrets explicitly, and avoid underscores in server names.
Extensions: package and share a setup
An extension bundles prompts (a context file), MCP servers, custom commands, themes, hooks, sub-agents, and agent skills into one installable unit. Install and manage them from the terminal:
1gemini extensions install https://github.com/gemini-cli-extensions/workspace2gemini extensions list3gemini extensions update4gemini extensions new ./my-extension mcp-server # start from a template5gemini extensions link ./my-extension # develop without reinstallingInstallation copies the extension into ~/.gemini/extensions; gemini extensions update pulls changes. Management commands are not available inside interactive sessions (use /extensions list there), and changes apply after you restart the CLI.
Each extension has a gemini-extension.json manifest at its root:
1{2 "name": "my-extension",3 "version": "1.0.0",4 "description": "Internal service tools",5 "mcpServers": {6 "my-server": {7 "command": "node",8 "args": ["${extensionPath}/my-server.js"],9 "cwd": "${extensionPath}"10 }11 },12 "contextFileName": "GEMINI.md",13 "excludeTools": ["run_shell_command(rm -rf)"]14}Use ${extensionPath} for portability, split executables and arguments into command and args, and keep name lowercase with dashes, matching the directory name. Extension MCP servers support every option except trust, and a server with the same name in your settings.json takes precedence.
Quick reference
excludeToolsin a manifest can restrict specific commands for tools that support it, such as blockingrm -rfinrun_shell_command; this is separate from an MCP server's ownexcludeTools.- An extension runs with your permissions; review its manifest and MCP servers before installing, as you would any package.
- Browse published extensions in the gallery at geminicli.com/extensions.
Remember this
Extensions are a manifest plus files; install from GitHub, develop with link, and review MCP servers before trusting one.
Hands-on: context, one MCP server, one extension
- In a repository, write a short
GEMINI.mdwith your test command and two conventions. Startgeminiand run/memory showto confirm it loaded. - Add a
.geminiignorewith/dist/, restart, and confirm@dist/no longer shares files. - Run
gemini mcp addfor one MCP server you trust, withincludeToolslimited to two tools insettings.json, and check/mcp. - Ask a question that needs one of those tools and approve the confirmation.
- Scaffold an extension with
gemini extensions new ./my-ext context, add aGEMINI.mdto it,gemini extensions link ./my-ext, restart, and confirm its context appears in/memory show.
Pass criterion: you can show the concatenated context, the filtered tool list for your server, and the linked extension's context, and explain which of them is sent with every prompt.
Quick reference
- If
/mcpshows the server but no tools, checkincludeToolsspelling against the server's real tool names. - If a token-based server fails, confirm the variable is set in your shell; undefined variables expand to empty strings.
- Unlink the practice extension when you are done.
Remember this
Context, a filtered MCP server, and a linked extension cover most of what a team setup needs.
Key takeaway
Gemini CLI's configuration has three layers. GEMINI.md files load globally, per workspace and its ancestors, and just in time as tools touch directories, and are concatenated into every prompt; /memory show shows the result and .geminiignore keeps paths out of supporting tools. MCP servers are declared under mcpServers in ~/.gemini/settings.json or .gemini/settings.json (or added with gemini mcp add), filtered with includeTools and excludeTools, and protected by confirmations and environment redaction. Extensions package all of it behind a gemini-extension.json manifest and install with gemini extensions install.
Keep context lean, allowlist tools, leave trust off for third-party servers, and review extensions like any dependency. For a comparison with Claude Code's equivalents, see Claude Code Permissions and Claude Code Hooks.
Practice (30 min): complete the five steps above in a repository you use.
References
- Gemini CLI docs: Provide context with GEMINI.md files — checked Oct 17, 2026
- Gemini CLI docs: Ignoring files (.geminiignore) — checked Oct 17, 2026
- Gemini CLI docs: MCP servers with Gemini CLI — checked Oct 17, 2026
- Gemini CLI docs: Extension reference — checked Oct 17, 2026
Shoaib Hossain
Author, Core Concept LearningRelated Articles
Explore this topic